Is there a macro that I can #ifdef for to check if librt has been linked to, ie by -lrt with gcc?
No, gcc doesn't have such macro (I've dumped preprocessor macros to check). On Windows with Microsoft compiler you can use _VC_NODEFAULTLIB macro to detect builds without libc reference.
Related
My goal is to understand a GNU libraries autoconf build system. I am aware that libiconv can be build successfully using a crafted MS Visual Studio project with manully added source code files. So the question is more academical rather than practical. I took into account there is no official support of Windows platform for gnulib also.
Following the guide from INSTALL.windows to build libiconv, I faced with next compilation error when built iconv againts dynamic MSVC runtime(cl /MD or cl /MDd).
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_malloc.h(85): error C2375: 'rpl_free': redefinition; different linkage
D:\work\env\build-env\msvc2019\shared-debug-shared-runtime\iconv\srclib\string.h(599): note: see declaration of 'rpl_free'
Configure invocation:
/cygdrive/d/work/src/libiconv/configure --enable-relocatable --enable-static=no --enable-shared=yes --host=x86_64-w64-mingw32 --prefix=/iconv 'CFLAGS=/MDd /Z7 /Od /D_DEBUG /RTC1' 'CXXFLAGS=/MDd /Z7 /Od /D_DEBUG /RTC1'
Compiler invocation:
compile cl /nologo -DHAVE_CONFIG_H -DEXEEXT=\".exe\" -I. -I/cygdrive/d/work/src/libiconv/srclib -I.. -I../lib -DDEPENDS_ON_LIBICONV=1 -DDEPENDS_ON_LIBINTL=1 /D_WIN32_WINNT=_WIN32_WINNT_WIN7 /DWIN32 /D_WIN64 /D_UNICODE /D_CRT_SECURE_NO_WARNINGS /MDd /Z7 /Od /D_DEBUG /RTC1 /D_DLL -c -o stat.obj `cygpath -w '/cygdrive/d/work/src/libiconv/srclib/stat.c'`
stat.c
Configure generated iconv/srclib/string.h
/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */
_GL_EXTERN_C void free (void *);
#if 1
# if (1 && !defined free \
&& !(defined __cplusplus && defined GNULIB_NAMESPACE))
# define free rpl_free
_GL_EXTERN_C void free (void *);
# endif
#endif
WinSDK/include/ucrt/corecrt_malloc.h
_ACRTIMP _CRT_HYBRIDPATCHABLE
void __cdecl free(
_Pre_maybenull_ _Post_invalid_ void* _Block
);
WinSDK/include/ucrt/corecrt.h defines next
#ifndef _ACRTIMP
#if defined _CRTIMP && !defined _VCRT_DEFINED_CRTIMP
#define _ACRTIMP _CRTIMP
#elif !defined _CORECRT_BUILD && defined _DLL
#define _ACRTIMP __declspec(dllimport)
#else
#define _ACRTIMP
#endif
#endif
After research and investigation I found out that gnulib(as a part of GNU autoconf build system for libiconv) replaces unsatisfying function calls with its own implementation.
rpl_free is a replacement name to replace regular free() function from the C runtime as MSVC free function is not recognized as a POSIX compliant. It seems to me there is no option to tell to configure not to replace suck functions.
An hack with environment variable REPLACE_FREE=0 did the trick and I have turned off function replacement.
However, MSVC compiler still complaints on different linkage. I believe, MSVC runtime exports its API functions with __declspec(dllimport) for consumers when gnulib declares its free() function signature with no extra attributes.
I wonder, is there a 'paved-road' to build libiconv(or other GNU library that leverage gnulib) linked to dynamic MSVC runtime using original autoconf system? Can I achieve that with no gnulib m4 files alteration?
To answer your general question:
Yes, GNU projects with the GNU build system (Autoconf, optionally Automake, Libtool, and Gnulib) can in general be built with the MSVC compiler. The compile script translates compiler options in the traditional Unix style to compiler options for MSVC.
The experience with GNU libiconv, GNU gettext, and other packages, which all have essentially the same INSTALL.windows instructions, shows that this is well possible. But it often requires tweaks in the build system, to cope with dllimport/dllexport, issues related to backslashes, to file names in Cygwin syntax vs. native Windows syntax, and so on. In particular, note that on Windows, it is hairy to export variables from a shared library; exporting functions is much simpler.
You can typically ignore warnings from MSVC regarding the dllimport/dllexport of functions. This warning merely means that the compiler has added one or two extra instructions per function invocation.
Gnulib indeed overrides many libc functions, such as free(), so that the application source code does not get cluttered with workarounds. The precise reason for each override is documented. For the free() function, it is documented here. While Gnulib has ways to disable specific workarounds, in this case I would strongly advise against it: the effects of a wrong errno value can be severe malfunction of any application.
To answer your specific problem about GNU libiconv:
You have encountered a specific build problem; the README of the package tells you where to report bugs.
GNU packages have releases. The latest GNU libiconv release, version 1.16, does not have the problem. In general, before attempting to compile the newest sources from the git repository, it is advisable to use the newest release. This will be simpler, as it has usually been tested before the release.
I'm using the Windows version of Clang (LLVM) 8 under Windows.
I'm compiling a code which uses OpenMP.
Under the lib folder of Clang there are 2 files which are OpenMP related:
libomp.lib.
libiomp5md.dll.
My questions are:
When I compile the code I use the flags -Xclang -fopenmp for the compiler. In in GCC and ICC using the flags tell the compiler to link the OpenMP library automatically. What about Clang? Does it do it automatically or must I link with libomp.lib manually? Is there a way to trigger automatic linking to the OpenMP library?
Answer: This was answered in Michael Klemm's answer below - Use the clang driver both for compiling and linking and then the -fopenmp will work as in GCC.
When I link with libomp.lib manually (Defining as a library for the linker) the output exe requires libomp.dll while the supplied OpenMP Dynamic Library is libiomp5md.dll. Is that a bug or is it because I link manually?
Answer: The libomp.dll is supplied in the bin folder and not the lib folder.
What's the proper way to utilize OpenMP in Clang under Windows? The clang-cl driver doesn't work with /openmp or -openmp as the MSVC's cl compiler.
Answer: Currently it can be done either with clang -fopenmp ..., clang-cl -Xclang -fopenmp ... or clang-cl /clang:-fopenmp ... (Which is equivalent of -Xclang -fopenmp).
Remark
On Windows I use Windows Driver of Clang using clang-cl.
Adding clarity to what the OpenMP libraries actually are, and how to use them on Windows with clang-cl
libomp.dll and libiomp5md.dll ARE THE SAME FILES!
When compiling for Windows, you link against libomp.lib OR libiomp5md.lib which will link to the same-named DLL at runtime, i.e. libomp.dll OR libiomp5md.dll respectively.
If you load 2 files that use the "different-name DLL," the interpreter will crash and give you a nasty error like: OMP: Error #15: Initializing libiomp5md.dll, but found libomp.dll already initialized.
Why? Because the program has no idea they are the same DLL, they have different names, so it assumes they are different. And it crashes. For this reason only, you can choose to swap which OpenMP DLL you link to in your program.
If your program doesn't crash and give you an error, you can keep using the same link to OpenMP. Otherwise, to silence the error, link to the one that is loaded by another program already.
If using clang-cl.exe which is the "drop-in" Clang replacement for MSVC cl.exe you should pass a compiler argument such as -Xclang -fopenmp which will convert the argument over to "Clang language." Don't forget to still pass to the linker the OpenMP LIB you chose, because on Windows, it won't be automatic.
That's all I've learned as brief as possible about OpenMP linking on Windows.
To compile and link OpenMP code with clang on Windows, you will have to pass -fopenmp to both the compiler and the linker:
clang -fopenmp -o bla.obj -c bla.c
clang -fopenmp -o bla.exe bla.obj
I am using codelite IDE on windows,
in that when I was trying to compile socket program,
it shows:
warning: ignoring #pragma comment [-Wunknown-pragmas]
for include "WinSock2.h"
#pragma comment(lib,"ws2_32.lib")
First, some clarifications: codelite is not a compiler but an IDE
It uses toolchains (GNU, VC etc)
So when you are saying that "winsock library is not identified by codelite IDE" you actually means: the compiler warns about #pragma
Since you do not provide additional information here (such as the build log, the compiler you are using, codelite version etc) I will take a guess here and would say that you are mixingg the GNU toolchain with VC headers - try to use the WinAPI that comes with MinGW instead.
Looking at the WinSock2.h that comes with GCC for Windows I see only this pragma:
#pragma GCC system_header
Also, .lib libraries are meant to be used by VC but not by GCC
Eran
When running nvcc, it always uses the Visual C++ compiler (cl.exe). How can I make it use the GCC compiler?
Setting the CC environment-variable to gcc didn't fix it. I also couldn't find any option for this in the executeables help-output.
On Windows, NVCC only supports the Visual C++ compiler (cl.exe) for host compilation.
You can of course compile .cpp (non-CUDA) code using GCC and link the objects with objects generated by nvcc.
As I know, if I want to use pthread library in linux environment I must include pthread.h and compile the source code with -lpthread option.
But I don't understand why I should compile with -lpthread option. I think the option is redundant... because I already declared to include pthread.h header file so that gcc links pthread library. Why does gcc not link pthread library file automatically by reading #include?
Thanks in advance.
Well linking and compilation are two separate phases.
You include the header pthread.h so that the compiler understands the data types & symbol names, which you use in your source files but are defined/declared in the pthread library header file.
You link to the pthread libray using -lpthread so that the linker can actually find those symbols in the pthread library during the linking stage.
Having #include <pthread.h> in your code doesn't link in the library; it only includes the header for compilation. That allows the compiler to see the various structures, function declarations, etc. included. Having -lpthread actually causes the linking to be done by the linker. So the include tells the compiler what's available, and the -lpthread actually allows the program to call the functions within the library at runtime.
Because GCC doesn't do auto-linking of libraries triggered by header inclusion (as opposed to MSVC, or so I've been told).
The header file just declares what the pthread functions are and how they should be called. -lpthread links to the library itself, containing the actual functions.
The compiler has no idea how you're going to resolve the functions in pthread.h. You might want to use a static library, the one provided by the system, some compatible implementation - heck, you might implement them yourself in another source file. It's up to the linker, and doesn't concern the compiler.
By including the header files you tell the compiler which functions he's going to see. But if these functions are in an external library, like the pthread functions, you need to link this library to your program so it can actually access those functions. That's what -lpthread is doing.
Pthread.h header file is included in the posix thread program but you need
-lpthread while compiling because it links it with the library of pthread
NOTE: -lpthread -lpcap all are the switches with gcc compiler that can link particular library in our source code. (lpthread means "link pthread" library)