I am trying to compile OpenVDB, but I get a linker error telling me:
"cannot find -ldl"
That is the only linker I am getting. I have no idea what library -ldl belongs to. The makefile doesn't help either, so I'm guessing it is a standard lib. I am using Mingw-w64 on windows.
The -ldl is a linker option to link to libdl library. This library is used to perform dynamic library loading (.dll in Window's world) through dlopen, dlsym... functions.
Since this library is not available on Windows, I think you could remove the -ldl from your makefile.
Since Window's equivatent functions are accessible by kernel.lib, you do not need to add specific instruction in makefile.
Related
I have written a small code that I want to compile with a combination of static and dynamic libs. The code uses functions from hdf5 and exodusII (a specialist CAE lib) as well as math, and of course good-old stdio.
To make the binary highly portable, I wanted to link hdf5 and exodusII statically into the code, but leave math and libc as shared, so that the code is optimised on different platforms.
I cannot work out what the correct method is to compile something like this. I already have tried:
gcc -lm -lc -fPIC test1.c /usr/lib/libexodus.a /usr/lib/libhdf5.a -Wl,-pie
This gives the error:
/usr/lib64/crt1.o: relocation R_X86_64_32S against '__libc_csu_fini' can not be used when making a shared object; recompile with -fPIC
/usr/lib64/crt1.o: could not read symbols: Bad value
I have also tried:
gcc -c test1.c (WORKS!)
ld /usr/lib/libhdf5.a /usr/lib/libexodus.a -lm -lc test1.o
Which gives a warning of not being able to find an entry symbol _start followed by a whole lot of undefined reference errors to the libexodus functions in test1.c. (I have checked libexodus.a with nm, and the functions being reported do actually exist in the archive.
I would really appreciate a hand in this. I am not overly experienced in using static libs, but for this application, I think it is the best choice, so long as I can work out a reliable way of compiling and linking.
The error was in the linking order. I have now learned that the linking order works like babushka dolls where the library at the top of the dependency tree comes first, and the most general library comes last.
For future reference, in the end, the working build command was as follows:
gcc test1.c -lexodus -lnetcdf -lhdf5_hl -hdf5 -lcurl -ldl -lm
What I don't really understand is that when I had built the exodus library as a shared library, I only had to link against the shared library, and the dependency libraries (-lnetcdf -lhdf5_hl -lhdf5 -lcurl) were not specified; however, with the static compilation of the exact same library, I now need to link all the libraries explicitly.
If someone has an answer to this behaviour, it would be helpful for my understanding and very appreciated, but as I can continue coding with this current build method, it is not an urgent matter.
I have 2 shared object libs and one executable.
1 of the libs that I compile has linkage error: Undefined _cxa_pure_virtual.
Why?
Usually we do not need to implement it. Any Ideas?
If I implement it both the libs compile and link OK, but the application that links to both has same linkage issue?
The lib in question is a C++ library and the __cxa_pure_virtual is needed by the C++ runtime. Suggest that you try first linking with g++ command instead of gcc.
Read more under this question: What is the purpose of cxa pure virtual
I'm trying to link some VTK libraries in my program...and It is not working like this
-ldl /usr/lib/libvtkIO.so, which is the way CMake does. But If I compile it manually using -L -lvtkIO, it works. What is the difference ?
Is dynamic versus static linking?
Thanks
CMake tries to use the full path to the library, rather than letting the linker search the library path(s). If you use ldd on the resulting binaries you will see they are linked to the same thing (dynamically in both cases). For things like VTK it is generally best to use CMake as it also tracks things like interface libraries for you.
I think you have misunderstood some of the arguments to the linker, -lvtkIO would link to a library in the library path called libvtkIO.so, -ldl would link to a library called libdl.so. The -L argument is used to add additional paths the linker should search for libraries.
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)
I am trying to link a C++ module using GCC, essentially like this:
gcc -c hello.c
g++ -c world.cpp
gcc -ohello -lstdc++ hello.o world.o
Note that I use -lstdc++ to link the C++ module in, so that I can use gcc instead of g++. The problem is that I'm getting the error:
undefined reference to `operator new(unsigned long)'
(Assuming that world.cpp contains at least one call to new.)
This error is fixed if I put -lstdc++ at the end of the linker line, like this:
gcc -ohello hello.o world.o -lstdc++
I am aware that this question has been asked many times here, but I have a special requirement. I am not directly calling GCC. I am using a build system for a different programming language (Mercury) which is calling GCC on my behalf, and I can't easily modify the way it calls GCC (though I can specify additional libraries using the LDFLAGS environment variable). So I have two additional requirements:
I cannot use g++ to link (only gcc) -- that is why I am doing the -lstdc++ trick above rather than simply linking with g++).
I don't think that I can control the order of the linker commands -- Mercury will put the .o files on the command-line after any libraries.
I understand the basic reason why the order is important, but what is baffling me is why did this break now? I just updated to Ubuntu 11.10 / GCC 4.6.1. I have been successfully compiling this program for years using precisely the above technique (putting -lstdc++ first). Only now has this error come up. An unrelated program of mine links against OpenGL using -lgl and that too broke when I upgraded and I had to move -lgl to the end of the command-line. I'm probably going to discover that dozens of my programs no longer compile. Why did this change? Is there something wrong with my new system or is that the way it is now? Note that these are ordinary shared libraries, not statically linked.
Is there anything I can do to make GCC go back to the old way, where the order of libraries doesn't matter? Is there any other way I can convince GCC to link libstdc++ properly without moving it after the .o files on the command-line?
If Mercury puts object files after libraries, Mercury is broken. Libraries belong after object files - always. You may sometimes get away with the reverse order, but not reliably. (Static libraries must go after the object files that reference symbols in the static library. Sometimes, a linker will note the symbols defined by a shared library even when none of the symbols are used; sometimes, the linker will only note the shared library symbols if the shared library provides at least one symbol.)