How to tell ld where to find libc - c++

So I created a static library with some basic assistance functions in C++ today. I built it with Clang 3.2 (SVN snapshot). However when I try to run a test program that links to it (prog.cpp), I get the following error:
~/Projects/CPP/AssisterLib> g++ prog.cpp -o program -static -L. -lassister
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../x86_64-suse-linux/bin/ld: cannot find -lm
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../x86_64-suse-linux/bin/ld: cannot find -lc
collect2: ld returned 1 exit status
I get the same error with G++ and Clang++. Apparently it can't find libc.a and libm.a, which are both in /usr/lib64 (provided by glibc-devel in OpenSUSE). Adding -L/usr/lib64 does nothing for the error.
Why can't ld find those libraries? Is there a flag that I'm missing?

The problem is likely the use of -static. I would conclude you do not have static version of the libm and libc installed. You can try removing -static to confirm.
The -static flag signals to the compiler that you want your executable to be entirely statically linked, and so it fails if not all the libraries have static versions available.

Related

Linking against a shared object - undefined reference that's present in the library [duplicate]

I am attempting to use the libtommath library. I'm using the NetBeans IDE for my project on Ubuntu linux. I have downloaded and built the library, I have done a 'make install' to put the resulting .a file into /usr/lib/ and the .h files into /usr/include
It appears to be finding the files appropriately (since I no longer get those errors, which I did before installing into the /usr directories).
However, when I create a simple main making a call to mp_init (which is in the library), I get the following error when I attempt to make my project:
mkdir -p build/Debug/GNU-Linux-x86
rm -f build/Debug/GNU-Linux-x86/main.o.d
gcc -c -g -MMD -MP -MF build/Debug/GNU-Linux-x86/main.o.d -o build/Debug/GNU-Linux-x86/main.o main.c
mkdir -p dist/Debug/GNU-Linux-x86
gcc -o dist/Debug/GNU-Linux-x86/cproj1 build/Debug/GNU-Linux-x86/main.o
build/Debug/GNU-Linux-x86/main.o: In function 'main':
/home/[[myusername]]/NetBeansProjects/CProj1/main.c:18: undefined reference to `mp_init'
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/GNU-Linux-x86/cproj1] Error 1
So, it looks like the linker can't find the function within the library, however it IS there, so I just don't know what could be causing this.
I get the same error if I type the gcc command directly and skip the makefile, I also made sure the static library got compiled with gcc as well.
Edited to Add:
I get these same errors if I do the compile directly and add the library with -l or -L:
$ gcc -l /usr/lib/libtommath.a main.c
/usr/bin/ld: cannot find -l/usr/lib/libtommath.a
collect2: ld returned 1 exit status
$ gcc -llibtommath.a main.c
/usr/bin/ld: cannot find -llibtommath.a
collect2: ld returned 1 exit status
$ gcc -Llibtommath.a main.c
/tmp/ccOxzclw.o: In function `main':
main.c:(.text+0x18): undefined reference to `mp_init'
collect2: ld returned 1 exit status
$ gcc -Llibtommath.a main.c
/tmp/ccOxzclw.o: In function `main':
main.c:(.text+0x18): undefined reference to `mp_init'
collect2: ld returned 1 exit status
I am very rusty on this stuff, so I'm not sure I'm using the right command here, in the -L examples are the libraries being found? If the library isn't being found how on earth do I get it to find the library? It's in /usr/lib, I've tried it with the .a file in the current directory, etc. Is there an environment variable I need to set? If so, how, etc.
I've tried a completely different library (GMP) and had the EXACT same problem. This has got to be some kind of Ubuntu environment issue? Anyone have any idea how to fix this?
The trick here is to put the library AFTER the module you are compiling. The problem is a reference thing. The linker resolves references in order, so when the library is BEFORE the module being compiled, the linker gets confused and does not think that any of the functions in the library are needed. By putting the library AFTER the module, the references to the library in the module are resolved by the linker.
Yes, It is required to add libraries after the source files/objects files. This command will solve the problem:
gcc -static -L/usr/lib -I/usr/lib main.c -ltommath
If the .c source files are converted .cpp (like as in parsec), then the extern needs to be followed by "C" as in
extern "C" void foo();

Installing Protobuf Development Libraries in MinGW

I installed Protobuf in MinGW from the sources on github.
When I try to compile my C++ program I get errors:
CMakeFiles/nxcore_interface.dir/main.cpp.o:main.cpp:(.rdata$.refptr._ZN6google8protobuf8internal13empty_string_E[.refptr._ZN6google8protobuf8internal13empty_string_E]+0x0): undefined reference to `google::protobuf::internal::empty_string_'
collect2: error: ld returned 1 exit status
I found something that indicates the development libs are not present:
Program with protocol-buffers don't compile with MinGW-w64: "undefined reference to google::protobuf:: ..."
I have included the -lprotobuf compiler flag.
After some searching I determined I need to use libprotobuf-dev but I am having trouble locating it.
Does anyone know where to get it, or is something else wrong?
You should compile your application with pkg-config.
g++ my_program.cpp `pkg-config --cflags --libs protobuf`
If you don't have pkg-config you should locate libraries path and set them with -L option. Eg:
g++ my_program.cpp -L/usr/local/protobuf/lib -lprotobuf

How to link libgomp statically when linking other libraries dynamically?

I am trying to build an image processing program written in C++ that depends on the following libraries using MinGW + MSYS (with GCC4.8.1) that I downloaded from www.mingw.org/ on a Windows 8 64bit computer
LibJPEG
BLAS and LAPACK
Armadillo
OpenMP
I have successfully compiled all the source code files (with -fopenmp flag of course), then I linked with the following statement:
g++ -o ./build/rspfitter {a list of .o files}
-L{paths to libraries} -ljpeg -lopenblas -lgomp -lpthread
The executable was correctly produced. However, it asks for the following dlls:
libgomp-1.dll
libpthread-2.dll
pthreadGC2.dll
I think it might a better idea to link libgomp and libpthread statically, so that I can minimize the number of dlls I need to deploy my program with (the above three dlls are not the only ones the program depends on). So I tried to link only libgomp and libpthread statically with the following command:
g++ -o ./build/rspfitter {a list of .o files}
-L{paths to libraries} -ljpeg -lopenblas -Wl,-static -lgomp -lpthread
But this time it fails with the following error message:
d:/mingw/bin/../lib/gcc/mingw32/4.8.1\libgomp.a(env.o):(.text.startup+0xbfe):
undefined reference to `_imp__pthread_attr_init'
d:/mingw/bin/../lib/gcc/mingw32/4.8.1\libgomp.a(env.o):(.text.startup+0xc13):
undefined reference to `_imp__pthread_attr_setdetachstate'
d:/mingw/bin/../lib/gcc/mingw32/4.8.1\libgomp.a(env.o):(.text.startup+0x3c):
undefined reference to `_imp__pthread_attr_setstacksize'
d:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe:
d:/mingw/bin/../lib/gcc/mingw32/4.8.1\libgomp.a(env.o): bad reloc
address 0x0 in section `.ctors'
d:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe:
final link failed: Invalid operation
Then I tried to execute the exact same compiling and linking commands using the MinGW + GCC 4.8.1 environment that was installed together with CodeLite. It fails again with different error messages:
./tmp/hshfitcmdline.o:hshfitcmdline.cpp:(.text.unlikely+0x105):
undefined reference to `_Unwind_Resume'
./tmp/hshfitcmdline.o:hshfitcmdline.cpp:(.text$_ZN9NormalMapD1Ev[__ZN9NormalMapD1Ev]+0xb4):
undefined reference to `_Unwind_Resume'
d:/mingw-4.8.1/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe:
./tmp/hshfitcmdline.o: bad reloc address 0xb4 in section
`.text$_ZN9NormalMapD1Ev[__ZN9NormalMapD1Ev]'
d:/mingw-4.8.1/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe:
final link failed: Invalid operation collect2.exe: error: ld returned
1 exit status make: *** [build/rspfitter] Error 1
I confirmed that the file "libgomp.a"/"libgomp.dll.a" was present on the [MinGW dir]/lib/gcc/mingw32/4.8.1/ for both installations of MinGW. However, they are of different sizes! In installation downloaded from MinGW.org, 'libgomp.a' is of 86kb, and "libgomp.dll.a" is of 87kb; In the CodeLite installation, however, the sizes are 74kB and 148Kb respectively.
Now I am wondering:
What could be the cause of the error messages given by the two MinGW systems? Could it be that the statically libraries that I downloaded from MinGW are corrputed? But dynamically linking was perfectly fine on both systems.
How on earth can I correctly link libgomp statically?
Thanks
To link libgomp statically you can do
ln -s `g++ --print-file-name=libgomp.a` && \
g++ foo.o -static-libgcc -static-libstdc++ -L. -o foo -fopenmp -ljpeg -lopenblas
However your executable will still depend on a pthread dll. The reason you are getting the error is that libc is still linking dynamically. To fix this you have to link libc statically as well
ln -s `g++ --print-file-name=libpthread.a` && \
ln -s `g++ --print-file-name=libc.a` && \
g++ foo.o -static-libgcc -static-libstdc++ -L. -o foo -fopenmp -ljpeg -lopenblas
However, if openblas or jpeg libraries depend on libc then there will likely still be undefined references.

C++: linker cannot find -lcrypto, but the library is in the path

I am compiling a C++ application using GNU g++. The project takes advantage of OpenSSL libraries.
Background
On my machine (a 64 bit CentOS quad core) I compile and link my files.
g++ -g -c -L/usr/local/lib/ -L/usr/lib64/
-I/usr/local/include/ -I/usr/local/ssl/include/
-lcrypto mysrc1.cpp mysrc2.cpp mysrc3.cpp
g++ -L/usr/local/lib/ -L/usr/lib64/ -lcrypto
*.o -o ./myapp.out
My application uses function MD5 which is contained in libcrypto.so. As you can see I specify to g++ the dirs where to search using the -L, -I options and which libraries to look for with the -l<lib-name> option. There are some trivial paths like /usr/local/lib which can be omitted of course, but I specified them because the makefile is parametric.
The problem
My problem is that I can successfully compile my stuff (first command), but linking fails (second command):
/usr/bin/ld: cannot find -lcrypto
collect2: ld returned 1 exit status
make: * [cppsims_par] Error 1
But I did check folders and everything... libcrypto.so is inside /usr/lib64/. What is going on?
It may help if you try strace to find why it failed the file lookup
strace -f -e trace=file g++ -L/usr/local/lib/ -L/usr/lib64/ -lcrypto
*.o -o ./myapp.out
I did find the problem and it is related to this question: ld cannot find an existing library
Actually I had no symlink libcrypto.so and the compiler was not able to find the library...
I had related issue, and resolved it after inspecting the trace.
I had
-L<my/path/to/lib> -llib_some_library
when it should have been
-L<my/path/to/lib> -lsome_library

unexplained linker error

I have the following files on my computer.
/lib64/libm.so.6
/usr/lib64/libm.so
but when I link with the following, I get errors
$ g++ -L/usr/lib64 -O3 -static -Wall -Wno-char-subscripts -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -IMSToolkit/include Comet.o Threading.o CometSearch.o CometPreprocess.o CometPostAnalysis.o CometMassSpecUtils.o CometWriteOut.o CometWriteSqt.o CometWritePepXML.o -LMSToolkit -lmstoolkitlite -o comet.exe
/usr/bin/ld: cannot find -lm
collect2: ld returned 1 exit status
$
Does anyone knows why?
Yes I do. You are trying to link a static exe with no shared libraries - the libraries you have are shared because of the .so extension - you need to install libm.a
Either remove the -static option or install the .a versions of the library