(g++ 4.8.2) Why do I need to specify -pthread to link sem_post? - linux

In g++ 4.8.2 apparently one has to specify -pthread flag to include the reference to sem_post.
/usr/bin/ld: obj/loader.o: undefined reference to symbol 'sem_post##GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
Why is that? What if one wants to explicitly not have to link that library to ensure no threads are ever run?
Has anything changed?
Thanks!

Related

gcc dialog library not linking

I'm trying to develop a small utility using the dialog library in C (the dialog command in linux).
On fedora linux works fine, but if i try to compile it on debian with the command:
gcc -ldialog -lncurses -I/usr/include dialog_test.c
I get the following error:
vetinari#ankhmorpork:~/Projects/Other/test$ gcc -ldialog -I/usr/include dialog_test.c
/usr/bin/ld: /tmp/ccX6fPYB.o: warning: relocation against `dialog_vars' in read-only section `.text'
/usr/bin/ld: /tmp/ccX6fPYB.o: in function `main':
dialog_test.c:(.text+0x5c): undefined reference to `init_dialog'
/usr/bin/ld: dialog_test.c:(.text+0x79): undefined reference to `dialog_yesno'
/usr/bin/ld: dialog_test.c:(.text+0xae): undefined reference to `dialog_menu'
/usr/bin/ld: dialog_test.c:(.text+0xbc): undefined reference to `dialog_vars'
/usr/bin/ld: dialog_test.c:(.text+0xc5): undefined reference to `end_dialog'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
The dialog command works fine.
Anyone has any idea why it isn't working on debian?
(Answer for the wiki sake, in case someone comes by here later)
You have to put the libraries you want to link at the end of the gcc command, like this:
gcc dialog_test.c -ldialog -lncurses
The reason is explained here: The way the linker looks up symbols it has to first see the reference, and then the library prodiving the symbol
Additionally, the dialog library might have other dependencies than ncurses. There is explanation how to find out what to include and what to link here, in short: dialog-config should tell you about it.
In this specific case, what worked for me (ubuntu 20.04) was linking ncursesw instead of ncurses.
After that, I was left with an
undefined reference to `sqrt'
linker error, which can be solved by linking the match library using -lm.
So, in total, this command works:
gcc dialog_test.c -ldialog -lncursesw -lm

Question about compiling sources code with HDF5 and mpi

When I am trying to compile the source code by 'make', the first steps that creating the '.o' files are running fine, and all '.o' files could be compiled normally. However, when compiling the executable file:
mpifort -fopenmp -O3 -o MyEXE sth.o main.o -L/usr/local/share/fftw-3.3.8/lib -lfftw3_mpi -lfftw3 -lm -L/usr/local/share/mpich-3.2/lib -lmpi -lz -L/usr/local/share/hdf5-1.8.18/lib -lhdf5_fortran -lhdf5hl_fortran -lhdf5_hl -lhdf5 -fPIC
it gots the following error:
/usr/bin/ld: /usr/local/share/hdf5-1.8.18/lib/libhdf5.a(H5PL.o): undefined reference to symbol 'dlclose##GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libdl.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
How could I solve this problem? Some pages suggest that it is due to the '-ldl- flag when calling c++ compiler, but I couldn't find a way to make it suitable for my cases.
The pages were right. Your HDF5 library libhdf5.a uses the function dlclose, which is defined in the library libdl. To use it, you need to simply add -ldl at the end of your mpifort command line.

Is -fPIC implied on modern platforms

I want to check whether a shared library was compiled with the -fPIC flag. What are the possible ways (on Linux, x86_64) to check this?
Is -fPIC implied (thus making the check redundant?)
Yes, GCC wouldn't allow you to link shared library without -fPIC so you don't need to check anything:
$ gcc tmp.c -shared
/usr/bin/ld: /tmp/ccqQVR9Y.o: relocation R_X86_64_32 against `compare' can not be used when making a shared object; recompile with -fPIC
/tmp/ccqQVR9Y.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
$ gcc tmp.c -shared -fPIC
EDIT
Technically speaking you can compile shared library without -fPIC if none of it's functions calls other functions or accesses global variables. But in that case generated code would be the same as with -fPIC.
Some architectures (not necessarily "modern" ones) just don't have absolute addressing modes, all code is position independent there.

linux linker: '-lpng' inhibits '-lz'?

On ubuntu-13.04, I got an error when building an executable from shared libraries, using GCC-4.7.3 provided by the linux distribution.
I guess the problem is between libpng and zlib (the former uses the latter), but I don't know why.
First, my command is:
$ gfortran -o test_muesli_config_fml test_muesli_config_fml.o -fopenmp
-Wl,--rpath,/usr/local/lib/muesli /usr/local/lib/muesli/libfml.so -lstdc++
-Wl,--rpath,/usr/lib /usr/lib/liblapack.so -Wl,--rpath,/usr/lib /usr/lib/libblas.so
-lpng -lz -lpthread -lreadline -lhistory
which gives the following error:
/usr/local/lib/muesli/libfml.so: undefined reference to `gzwrite'
/usr/local/lib/muesli/libfml.so: undefined reference to `gzopen'
/usr/local/lib/muesli/libfml.so: undefined reference to `gzclose'
/usr/local/lib/muesli/libfml.so: undefined reference to `gzread'
collect2: error: ld returned 1 exit status
But note that -lz is present. After that, I added the linker option --trace-symbol= in order to get more information:
$ gfortran -o test_muesli_config_fml test_muesli_config_fml.o -fopenmp
-Wl,--rpath,/usr/local/lib/muesli /usr/local/lib/muesli/libfml.so -lstdc++
-Wl,--rpath,/usr/lib /usr/lib/liblapack.so -Wl,--rpath,/usr/lib /usr/lib/libblas.so
-lpng -lz -lpthread -lreadline -lhistory -Wl,--trace-symbol=gzwrite
which in turn gives the results:
/usr/local/lib/muesli/libfml.so: reference to gzwrite
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libz.so: definition of gzwrite
/usr/local/lib/muesli/libfml.so: undefined reference to `gzwrite'
/usr/local/lib/muesli/libfml.so: undefined reference to `gzopen'
/usr/local/lib/muesli/libfml.so: undefined reference to `gzclose'
/usr/local/lib/muesli/libfml.so: undefined reference to `gzread'
collect2: error: ld returned 1 exit status
so, gzwrite is found in libz.so but the linker don't use it!
By chance, I thought to remove the -lpng option (actually, the libpng library is not used) and my problem is solved! Why?
Secondly, I compile my whole code with another version of GCC-4.7.3 (compiled by myself -- I am used to test many versions of the compiler), and the error didn't occur, even using both -lpng and -lz!
Any idea?
In addition, a different try with another program (which USE libpng) leads to a successful build.
Edited on 2013-10-08
I'm pretty sure now that it is a bug in ubuntu-13.04: I've tried two other linux distros (Fedora 16 -- Ubuntu-10.04) and the linker behavior is standard, not as described above in the first part of my message.
I plan to report this problem on ubuntu community. Regards.
Edited on 2013-10-09
The bug has been reported to https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1237270
Two possible fixes (until ubuntu doesn't repair itself):
Try to compile in libpng.a and libz.a as a static library (it can be only a temporary solution, because static libs are evil in most cases).
Recompile libpng from the original source, and compile libz.a as static herein.

Android NDK r5b external build and supc++ link problem

I am attempting to cross-compile our C++ code base (using CMake) for the Android platform using the r5b NDK on Ubuntu 10.10. The compile phase succeeds, however during the final link phase for the .so there are many unresolved references to symbols that are in the libsupc++.a file (which I specify to link in). I have also tried -lsupc++ with no difference.
I tried to follow the command-line as closely as possible as generated by the official ndk-build system when building the test-gnustl-1 NDK test app.
Running the arm-linux-androideabi-nm tool on the arm-linux-androideabi/lib/libsupc++.a file shows the symbols as defined (T) referenced in the error output.
An example of a symbol defined in libsupc++ it cannot find is: __gxx_personality_v0
Here is my sample link line and a resulting sample of errors.
/home/user/android-ndk-r5b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-g++ -fPIC -Wall -Wextra -Wno-unused -Wno-multichar -fno-rtti -MMD -MP -MF -ffunction-sections -fexceptions -funwind-tables -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Wa,--noexecstack -DANDROID -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -O0 -DDEBUG -D_DEBUG -g --sysroot=/home/user/android-ndk-r5b/platforms/android-9/arch-arm -Wl,--gc-sections -Wl,-z,nocopyreloc -Wl,--no-undefined,-z,noexecstack -L/home/user/android-ndk-r5b/platforms/android-9/arch-arm/usr/lib -L/home/user/android-ndk-r5b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/arm-linux-androideabi/lib -Wl,-rpath-link=/home/user/android-ndk-r5b/platforms/android-9/arch-arm/usr/lib /home/user/android-ndk-r5b/sources/cxx-stl/gnu-libstdc++/libs/armeabi/libstdc++.a -lc -lsupc++ -shared -o ../../lib/Debug/libFoo.so CMakeFiles/Foo.dir/Foo.c.o CMakeFiles/Foo.dir/Bar.cpp.o CMakeFiles/Foo.dir/Baz.cpp.o
`CMakeFiles/Foo.dir/Foo.cpp.o: In function 'myFunc':
/home/user/myroj/src/native/modules/libFoo/Foo.cpp:292: undefined reference to '__cxa_end_cleanup'
CMakeFiles/Foo.dir/Foo.cpp.o:(.ARM.extab.text.myFunc+0x0): undefined reference to '__gxx_personality_v0'
...
/home/user/android-ndk-r5b/toolchains/android/sources/cxx-stl/gnu-libstdc++/include/bits/vector.tcc:350: undefined reference to '__cxa_begin_catch'
/home/user/android-ndk-r5b/toolchains/android/sources/cxx-stl/gnu-libstdc++/include/bits/vector.tcc:357: undefined reference to '__cxa_rethrow'
/home/user/android-ndk-r5b/toolchains/android/sources/cxx-stl/gnu-libstdc++/include/bits/stl_vector.h:1153: undefined reference to 'std::__throw_length_error(char const*)'
/home/user/android-ndk-r5b/toolchains/android/sources/cxx-stl/gnu-libstdc++/include/bits/stl_tree.h:199: undefined reference to 'std::_Rb_tree_decrement(std::_Rb_tree_node_base*)'
...
I tried to creating a simple hello-world app that makes use of exceptions and links in a simple .a file. I got the same errors until I linked in the libsupc++.a library directly instead of using '-lsupc++'. However, this same technique did not work on the larger project link step. The NDK docs also suggest '-lsupc++' is should be used when using external build tools.
I am out of ideas on how to resolve this linking issue. I have tried reordering the link line as many ways as I could think of. I know linking in general can be a fickle process.
Any help is greatly appreciated.
It turns out I needed to add -L/home/user/android-ndk-r5b/sources/cxx-stl/gnu-libstdc++/libs/armeabi" to the path and explicitly link "/home/user/android-ndk-r5b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/arm-linux-androideabi/lib/thumb/libsupc++.a" with all include libraries wrapped in a "--start-group --end-group" clause.
Hopefully this helps someone else too.

Resources