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
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
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
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).
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.
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