.so: undefined reference to 'min' - c

My c application linked .so library. But application says
library.so: undefined reference to 'min'
My compiler command like:
gcc -o test.o library.so -ldl -lpthread -lm
Is there any solution? Please help me

You need to pass -library to gcc instead of library.so ,also provide library.so's location
gcc -L/path/to/library.so -o test.o -llibrary -ldl -lpthread -lm

Related

Compiling CUDA code while linking a static library

I have C code main_code.c and helper_code.c. The former depends on some CUDA code cuda_code.cu and the latter on an external library mylib. For my external library mylib to work, I need to link it to my code with the -static flag:
g++ main_code.c helper_code.c -o main_code -static -L/usr/local/mylib/lib -lmylib -lmylib2
But main_code.c also depends on CUDA code- cuda_code.cu. I can link it with:
nvcc cuda_code.cu -c
g++ main_code.c -o main_code cuda_code.o -L/usr/local/cuda-10.0/lib64 -lcudart -lpthread
I want to compile my code together with the CUDA code and the external library mylib. However, linking mylib works only with the -static flag. A naive attempt would be the following but it does not work:
nvcc cuda_code.cu -c
g++ main_code.c helper_code.c -o main_code cuda_code.o -static -L/usr/local/mylib/lib -lmylib -lmylib2 -L/usr/local/cuda-10.0/lib64 -lcudart -lpthread
This gives the error:
/usr/bin/ld: cannot find -lcudart
which I'm assuming is because you cannot use the static flag while linking with CUDA (because it goes away when I remove the -static flag (in addition to also removing the mylib library linking)).
I then tried compiling helper_code.c separately and then linking it to main_code.c since it's just helper_code.c that needs mylib:
helper.o:
g++ helper_code.c -c -static -L/usr/local/mylib/lib -lmylib -lmylib2
cuda-code.o:
nvcc cuda_code.cu -c
main-code: helper.o cuda-code.o
g++ main_code.c -o main_code helper_code.o cuda_code.o -L/usr/local/cuda-10.0/lib64 -lcudart -lpthread
But this also does not work. I get an undefined reference error that's referring to a function defined in mylib, meaning the linking to mylib isn't working. I can resolve that error by including the mylib library and using the -static flag but that then breaks the CUDA linking.
I can separately get the CUDA linking (to cuda_code.cu) to work or mylib linking to work but not both at the same time.
So is there a workaround to link mylib (which needs -static) while at the same time also linking my CUDA code (which does not allow -static)?
Following the answer linked in talonmies's comment, the following did the trick:
g++ main_code.c -o main_code helper_code.o cuda_code.o -L/usr/local/mylib/lib -L/usr/local/cuda-10.0/lib64 -Wl,-Bstatic -lmylib -lmylib2 -Wl,-Bdynamic -lcudart

main.c:(.text+0x170): undefined reference to `sqrt' (used -lm)

ok, so i'm trying to compile my code using makefile, i've got only 2 .c file and 1 .h file, i used "sqrt()" function from math.h (only in main), here is my makefile:
a.out: GBST.o main.o
gcc GBST.o main.o
GBST.o: GBST.c GBST.h
gcc -c GBST.c
main.o: main.c
gcc -c main.c -lm
still, I get main.c:(.text+0x170): undefined reference to `sqrt' error, what can it be? (btw, i wrote -lm in GBST line before and it did not help, so i have deleted it)
You need to use -lm in the link line, not in the compile line.
a.out: GBST.o main.o
gcc GBST.o main.o -lm
# ^^^^ Need it here
GBST.o: GBST.c GBST.h
gcc -c GBST.c
main.o: main.c
gcc -c main.c
# ^^^^ Don't need it here

gcc flags equivalent to LD_PRELOAD?

I currently compile a program called do_foo like so:
gcc -Wall -Wextra -g3 -pthread do_foo.c -o do_foo
and I run it like this:
LD_LIBRARY_PATH=.. LD_PRELOAD=libfoo.so ./do_foo
libfoo.so is strange because:
Has a bunch of functions marked with __attribute__((constructor)) and
Intercepts libc functions like malloc, send, etc
Instead of using LD_PRELOAD to link libfoo.so, I'd like to do it at compile time. I would expect to be able to do it like this:
gcc -Wall -Wextra -g3 -L.. -lfoo -pthread do_foo.c -o do_foo_ld
but this doesn't work: none of the ctor functions run and none of the libc functions get intercepted. When I run ldd do_foo_ld, I don't see libfoo.so in the list of libraries linked to it.
What gcc flags are equivalent to LD_PRELOAD? I assume t here is some simple translation between the two, but I haven't been able to find it.
EDIT: I've made some progress with the following:
gcc -Wall -Wextra -g3 -nodefaultlibs -pthread -L.. -lfoo -lc -lgcc do_foo.c -o do_foo_ld
My rationale is that I need to prevent loading libc at first with -nodefaultlibs, then link libfoo.so, then manually pull whatever gets taken out by nodefaultlibs in afterwards. With this, I don't get undefined reference errors about symbols from libc, but I do get the following:
/tmp/ccSsQHmx.o: In function `fun_1':
/my/proj/do_foo.c:217: undefined reference to `pthread_create'
/tmp/ccSsQHmx.o: In function `fun_2':
/my/proj/do_foo.c:269: undefined reference to `pthread_create'
/tmp/ccSsQHmx.o: In function `fun_3':
/my/proj/do_foo.c:281: undefined reference to `pthread_join'
No combination of -pthread -lpthread at various points in the gcc invocation seems to fix it, and I'm not sure why. I thought that nodefaultlibs might mean "prevent any of the default libraries from being linked" rather than just "don't link them yet," so I tried making a new symlink:
ln -s /lib/x86_64-linux-gnu/libpthread.so.0 ../libnotpthread.so
and adding the following:
gcc -Wall -Wextra -g3 -nodefaultlibs -pthread -L.. -lfoo -lnotpthread -lc -lgcc do_foo.c -o do_foo_ld
but no dice.
What am I missing here?
You should put linked libraries after source or object files:
gcc -Wall -Wextra -g3 do_foo.c -L.. -lfoo -pthread -o do_foo_ld
If this fails to work, try the big hammer:
gcc -Wall -Wextra -g3 do_foo.c -Wl,--no-as-needed -L.. -lfoo -Wl,--as-needed -pthread -o do_foo_ld
Modern distroes enable -Wl,--as-needed flag by default which forces -lfoo to be ignored if none of preceding source or object files uses it (in your case there are no files so it's considered to be unused).

Undefined reference to `initscr' Ncurses

I'm trying to compile my project and I use the lib ncurse. And I've got some errors when compiler links files.
Here is my flags line in Makefile:
-W -Wall -Werror -Wextra -lncurses
I've included ncurses.h
Some layouts :
prompt$> dpkg -S curses.h
libslang2-dev:amd64: /usr/include/slcurses.h
libncurses5-dev: /usr/include/ncurses.h
libncurses5-dev: /usr/include/curses.h
prompt$> dpkg -L libncurses5-dev | grep .so
/usr/lib/x86_64-linux-gnu/libncurses.so
/usr/lib/x86_64-linux-gnu/libcurses.so
/usr/lib/x86_64-linux-gnu/libmenu.so
/usr/lib/x86_64-linux-gnu/libform.so
/usr/lib/x86_64-linux-gnu/libpanel.s
And here are my erros :
gcc -W -Wall -Werror -Wextra -I./Includes/. -lncurses -o Sources/NCurses/ncurses_init.o -c Sources/NCurses/ncurses_init.c
./Sources/NCurses/ncurses_init.o: In function `ncruses_destroy':
ncurses_init.c:(.text+0x5): undefined reference to `endwin'
./Sources/NCurses/ncurses_init.o: In function `ncurses_write_line':
ncurses_init.c:(.text+0xc5): undefined reference to `mvwprintw'
./Sources/NCurses/ncurses_init.o: In function `ncurses_init':
ncurses_init.c:(.text+0xee): undefined reference to `initscr'
collect2: error: ld returned 1 exit status
Thanks a lot
You need to change your makefile so that the -lncurses directive comes after your object code on the gcc command line, i.e. it needs to generate the command:
gcc -W -Wall -Werror -Wextra -I./Includes/. -o Sources/NCurses/ncurses_init.o -c Sources/NCurses/ncurses_init.c -lncurses
This is because object files and libraries are linked in order in a single pass.
In C++ , I fixed it just by linking the ncurses library .
Here is the command :
g++ main.cpp -lncurses
I got flags to correct order by using LDLIBS variable:
ifndef PKG_CONFIG
PKG_CONFIG=pkg-config
endif
CFLAGS+=-std=c99 -pedantic -Wall
LDLIBS=$(shell $(PKG_CONFIG) --libs ncurses)
man gcc | grep -A10 "\-l library"
-l library
Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX
compliance and is not recommended.)
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files
in the order they are specified. Thus, foo.o -lz bar.o searches
library z after file foo.o but
before bar.o. If bar.o refers to functions in z, those functions may not be loaded.

Member at n is not an ELF object

I am trying to build a library (Tesseract OCR) for Android. It seems to compile just fine, and I get a bunch of static libraries, but it fails during the linking phase.
The command is:
libtool: link: /opt/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/arm-linux-androideabi-g++ -fPIC -DPIC -shared -nostdlib /opt/android-ndk-r8c/platforms/android-8/arch-arm/usr/lib/crtbegin_so.o -Wl,--whole-archive ./.libs/libtesseract_api.a ../ccmain/.libs/libtesseract_main.a ../cube/.libs/libtesseract_cube.a ../neural_networks/runtime/.libs/libtesseract_neural.a ../textord/.libs/libtesseract_textord.a ../wordrec/.libs/libtesseract_wordrec.a ../classify/.libs/libtesseract_classify.a ../dict/.libs/libtesseract_dict.a ../ccstruct/.libs/libtesseract_ccstruct.a ../image/.libs/libtesseract_image.a ../cutil/.libs/libtesseract_cutil.a ../viewer/.libs/libtesseract_viewer.a ../ccutil/.libs/libtesseract_ccutil.a -Wl,--no-whole-archive -Wl,-rpath -Wl,/Users/xxx/dev/libs/leptonica/current/android-arm/release/lib -Wl,-rpath -Wl,/Users/xxx/dev/libs/leptonica/current/android-arm/release/lib -L./ -L../ -L../api -L../ccutil -L../viewer -L../cutil -L../image -L../ccstruct -L../dict -L../classify -L../wordrec -L../neural_networks/runtime -L../textord -L../cube -L../ccmain -L/opt/android-ndk-r8c/platforms/android-8/arch-arm/usr/lib -L/Users/xxx/dev/libs/leptonica/current/android-arm/release/lib /Users/xxx/dev/libs/leptonica/current/android-arm/release/lib/liblept.so -lz -L/opt/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/armv7-a -L/opt/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6 -L/opt/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc -L/opt/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/lib -lstdc++ -lm -lc -ldl -lgcc /opt/android-ndk-r8c/platforms/android-8/arch-arm/usr/lib/crtend_so.o -Os -march=armv7-a --sysroot /opt/android-ndk-r8c/platforms/android-8/arch-arm -mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -Wl,-rpath-link=/opt/android-ndk-r8c/platforms/android-8/arch-arm/usr/lib -Wl,-soname -Wl,libtesseract.so.3 -o .libs/libtesseract.so.3.0.1
And the output looks like:
/opt/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: ./.libs/libtesseract_api.a: member at 8 is not an ELF object
/opt/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: ./.libs/libtesseract_api.a: member at 96 is not an ELF object
/opt/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: ./.libs/libtesseract_api.a: member at 104400 is not an ELF object`
...
As far as I can tell, libtesseract_api.a and related files are valid. Any idea what's happening here? This isn't an error I've seen before.
Check if you have the right archive type by nm
.../arm-linux-androideabi-nm .libs/libtesseract_api.a
You should use the right format.
After adding the following to PATH, it link success :
$ANDROID_NDK/toolchain/bin

Resources