Windows library inclusion in CMake Project - c++

I have a growing project in CMake. It is time to link to a library, which at this time exists only in Windows, Linux functionality will have to wait. I am attempting to do this with preprocessor directives as recommended in an answer to this question:
// MyLibHeader.hpp
#ifdef WIN32
#include <windows.h>
#define ProcHandle HINSTANCE
#define LoadLib LoadLibraryA
#define LoadSym GetProcAddress
#else
// ... I'll fill these in with dlopen etc. when necessary
This is the first platform specific inclusion I have had to put in my code, and It seems there is more to it than this. This is generating this error:
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\include\intrin.h(944) : error C2733: second C linkage of overloaded function '_interlockedbittestandset' not allowed
The error is repeated four times, twice in intrin.h, and twice in winnt.h. So here's my question. Are there other includes or preprocessor steps I need to take to get this to work inside windows (up to now it has been a basic console application) and is there something in CMake I can leverage to make this easier.

From what I've been able to scrape up with some help and some google, one solution is indeed to comment out the duplicate definitions of _interlockedbittestandset in initrin.h
This may have been fixed in later versions of Visual Studio.

You could look at the source code of CMake, there is a C++ class that does cross platform library loading. It is a BSD style license so you could just copy the code. Works on lots of platforms. The code is here:
http://cmake.org/gitweb?p=cmake.git;a=blob;f=Source/kwsys/DynamicLoader.cxx;h=c4ee095519fe27742a0a9a9e392be4ce095af423;hb=HEAD

Related

How to get error.h in visual studio or equivalent?

I have large C++ project that I inherited and am trying to transfer it from Linux to Visual Studio on Windows. Managed to link required libraries, but one build error just baffles me.
In Linux, someone was including a header <error.h> everywhere, and I can't even find a documentation page to see what it is. First I thought is part of standard library, but I am now beginning to see it's a specific header for Linux OS.
So, how do I include it in Visual studio? I can't even find what it is and am tempted to just rearrange code to use stdexcept header, as the only thing these codes do is abort compilation and printout error messages by using some error(...) function from error.h.
error.h is a header from the GNU C Library. It is not specific to Linux, it is specific to glibc.
It is documented right here (search on the page for error.h).
The functions declared in error.h should not be used in portable code, so getting rid of code that uses them is not a bad idea. Alternatively, it is not difficult to implement them.

Error C2711 building DLL from a C++ project that uses tbb

I'm trying to build some dll to wrap some Computer Vision methods in a c++ software to use them a c# software, and I need to call some tbb (Threading Building Blocks) methods from the c++ methods to process some frame. I'm developing in CLR using Charset Unicode, in visual studio, and once I call the tbb header
#include <tbb/tbb.h>
The compiler give me the error:
error C2711: 'tbb::internal::concurrent_vector_base_v3::concurrent_vector_base_v3' try use #pragma unmanaged;
I've correctly imported and linked libraries and headers files, and the required dlls.
I've looked for some helps on Intel's forums but I found nothing.
This sounds like you're trying to build an application using CLR, but it doesn't like some of the code in tbb's header. Error C2711 happens when trying to compile code as managed that it is unable to manage (for example, using inline assembly).
If you don't need CLR, you should just be able to disable it (remove /clr) -- which should fix this warning. Otherwise, you can use #pragma unmanaged as recommended in the warning to disable it -- I'm guessing before the inclusion of the tbb/tbb.h header. Something like:
#pragma managed(push, off)
#include <tbb/tbb.h>
#pragma managed(pop)
This should tell the project that any code in tbb.h (such as potentially inline functions that use assembly) should not emit IL.
Possibly related are some answers to this question which describes how interfacing with native code in CLR projects is commonly done

FFTW _GNUC_ is not defined as a preprocessor macro

I have linked a FFTW library to the Unreal Engine project from this website. But now when I try to include the header file to my project, I get error:
'__GNUC__' is not defined as a preprocessor macro,
replacing with '0' for '#if/#elif'
I have no idea how to fix this. I don't want to mess with the code itself, because I think it is perfectly fine. Did I forget something when linking the library? I've also tried including the header file as a C library.
Any help would be appreciated.
IDE: Visual Studio 2017 Community
OS: Windows 10 Pro 64x
UE4 Version: 4.20
UnrealEngine seems to treat many warnings as errors, so this causes trouble when trying to use with 3rd party libraries that produce those warnings. Usually it's best to fix code to avoid the warning, but I would assume you can't for whatever reason.
In this particular case you could set:
bEnableUndefinedIdentifierWarnings = false;
Inside your *.Build.cs class constructor.
If this wasn't UnrealEngine, but still Visual Studio C++, you could also try putting this before code that causes the warning (e.g. before including header in which you get the warning):
#pragma warning(disable: 4668)
https://learn.microsoft.com/en-us/cpp/preprocessor/warning?view=vs-2019
Or disable it as compilation flag:
/wd4668
https://learn.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level?view=vs-2019
In general, if you get something you feel shouldn't be an error, search web if given error number (here C4668) is not usually a warning. If it is, then this allows quick hacks like above.

C++ Linux code breaks the Windows build because missing headers means the functions are undefined

I am developing a piece of software in C++ using Visual Studio on Windows. From the beginning, I would like to have it run on both Windows and Linux. Obviously, I won't compile the Linux binary on a Windows machine, but I still want to use Visual Studio to write the code.
When it comes to headers, I am selecting while file to use based on pre-processor definitions.
A very rudimentary and simple example:
#pragma once
#ifndef PLATFORM_TIMER_H
#define PLATFORM_TIMER_H
#ifdef _WIN32
#include "win32\win32_timer.h"
#elif __linux__
#include "linux\linux_timer.h"
#endif
#endif // PLATFORM_TIMER_H
For the header it works just fine. But the .cpp-file for the Linux implementation breaks the build on Windows. That's because the Linux .cpp-file will get compiled no matter what, even on Windows. And because the Windows machine is missing Linux-headers, the function it uses will be undefined.
Question 1: What is the "industry standard" to deal with this?
Question 2: Is it reasonable to wrap both the .h and .cpp-files in "#ifdef PLATFORM" so that the code will only be enabled on the correct OS?
But the .cpp-file for the Linux implementation breaks the build on Windows. That's because the Linux .cpp-file will get compiled no matter what, even on Windows.
Why are you compiling the Linux-specific file for a Windows build?
Question 1: What is the "industry standard" to deal with this?
If you're going to create separate source files for Windows-specific and Linux-specific code, then the whole point would be that you use only the appropriate one for the current platform when you build.
An alternative approach would be to have both implementations in the same source file, using conditional compilation to choose which parts to use. That's pretty conventional, too, especially where the parts that vary are smaller than whole functions.
Question 2: Is it reasonable to wrap both the .h and .cpp-files in "#ifdef PLATFORM" so that the code will only be enabled on the correct OS?
It would be strange to go to the trouble of creating separate, platform-specific source files and then use conditional compilation to include them all in every build. It could work, but it would not fall within my personal definition of "reasonable".
Any code specific to one operating system needs to have the proper #ifdef's set up, whether in header files or source files.

atlbase.h and different versions of VC CRT

I have a C++/CLI project created with Visual Studio 2010 that targets .NET Framework 3.5 and PlatformToolset v90. Initially it requests the VC CRT of version 9.0.21022.8, but if I include atlbase.h header then it requests the VC CRT of version 9.0.30729.6161.
Why does this happen? And how can I make it to target 9.0.30729.6161 without including atlbase.h?
I tried to define macroses _BIND_TO_CURRENT_CRT_VERSION=1 and _BIND_TO_CURRENT_VCLIBS_VERSION=1 but this didn't help.
The version is set by vc/include/crtassem.h, near the bottom you can see:
#ifndef _CRT_ASSEMBLY_VERSION
#if _BIND_TO_CURRENT_CRT_VERSION
#define _CRT_ASSEMBLY_VERSION "9.0.30729.6161"
#else
#define _CRT_ASSEMBLY_VERSION "9.0.21022.8"
#endif
#endif
So the rule is that you can explicitly override the version by #defining _CRT_ASSEMBLY_VERSION. Don't do that. As you noted in your question, #defining _BIND_TO_CURRENT_CRT_VERSION to 1 gets you the version string you want.
Having a problem with this in a C++/CLI project is possible. You can compile C++/CLI code without ever #including any of the CRT include files. So you'll end up with a default version which, ironically, is defaulted by the linker to its own version of the CRT. So a workaround is to explicitly put #include <crtassem.h> in one of your source code files. #including atlbase.h would do that too since it does include CRT headers but of course is the big hammer approach.
Additional troubleshooting is available from Project + Properties, C/C++, Advanced, Show Includes = Yes. You'll see a trace of all the #include files getting included in the Output window.
Beware that you'll now have the additional burden to ensure that the up-to-date version of msvcr90.dll gets deployed on the user's machine. Your program will fail to start if it is missing or old.