I have a few static libraries I want to link with ld. My libraries are in the directories /Users/rlt/p4/lib/ and /Users/rlt/p4/usr2/lib. I want to pass in the relative paths of these directories w.r.t /Users/rlt/p4 and use the -syslibroot to point to this directory. The documentation for ld says that this option will prepend a pre-fix to all search paths. However, the following command gives me directory not found errors for both paths I specify:
ld -syslibroot /Users/rlt/p4 -L/lib -L/usr2/lib -lA -lB -lC
This gives me could not find /lib and /usr2/lib. I tried using -Lusr2/lib and -Llib with same results. What am I missing?
-syslibroot does not prepend its argument string to arbitrary paths. It will only add it to the paths which are consistent with the sdk directory structure.
Related
I am using boost.build.
In one of the steps "g++" -o "testbed/bin/gcc-5.3.0/debug/link-static/get_tag34_tag34_processed" -Wl,--start-group "testbed/bin/gcc-5.3.0/debug/link-static/get_tag34_tag34_processed.o" "/usr/local/lib64/librabbitmq.a" "/usr/lib64/libmysqlcppconn-static.a" "/apps/boost/root/bin.v2/libs/date_time/build/gcc-5.3.0/debug/link-static/libboost_date_time.a" -Wl,-Bstatic -lz -lbz2 -Wl,-Bdynamic -Wl,--end-group -g -lSimpleAmqpClient -lcrypto -ldl -lmysqlcppconn -lpthread -lrdkafka -lrdkafka++ -lssl
I am trying to link to a kafka library.
In the system directory there is the .so and .a /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/librdkafka++.so and /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/librdkafka++.a. However it is preferring the .so.
How do I fix that?
Use full path for .a file. So instead of
-lrdkafka
use
"/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/librdkafka++.a"
(notice lack of '-l')
Alternatively, delete .so. :)
This is not boost.build behavior, this is how gcc and ld work:
-l namespec
--library=namespec
Add the archive or object file specified by namespec to the list of files to link. This option may be used any number of times. If namespec is of the form :filename, ld will search the library path for a file called filename, otherwise it will search the library path for a file called libnamespec.a.
On systems which support shared libraries, ld may also search for files other than libnamespec.a. Specifically, on ELF and SunOS systems, ld will search a directory for a library called libnamespec.so before searching for one called libnamespec.a. (By convention, a ".so" extension indicates a shared library.) Note that this behavior does not apply to :filename, which always specifies a file called filename.
The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again.
See the -( option for a way to force the linker to search archives multiple times.
You may list the same archive multiple times on the command line.
This type of archive searching is standard for Unix linkers. However, if you are using ld on AIX , note that it is different from the behaviour of the AIX linker.
I'm trying to figure out how to set some environment variable which would make g++ to link to correct versions of the libraries.
I have some old boost libraries in /usr/lib64 (linking against these will fail) and new libraries in /v/users/regel/lib. So the linker should link against the new libraries.
Command:
$ g++ test.cpp -lboost_system -L/v/users/regel/lib
links the program correctly. However, I wish to set this as the number 1 search directory for the linker so that I don't have to specify '-L' every time I link.
The following environment variables do not seem to do the trick:
$ LIBRARY_PATH=/v/users/regel/lib g++ test.cpp -lboost_system
/tmp/regel/cc4SmBtI.o: In function `main':
test.cpp:(.text+0x5): undefined reference to `boost::system::system_category()'
collect2: error: ld returned 1 exit status
and
$ LD_LIBRARY_PATH=/v/users/regel/lib:$LD_LIBRARY_PATH g++ test.cpp -lboost_system
/tmp/regel/ccUreBZy.o: In function `main':
test.cpp:(.text+0x5): undefined reference to `boost::system::system_category()'
collect2: error: ld returned 1 exit status
Despite reading numerous articles and posts on similar subjects, I have not found a solution yet.
As the GCC manual says, LIBRARY_PATH is the correct environment variable to add directories to the library search path.
If you add -v to the g++ command you should see the LIBRARY_PATH that it uses, and you should see it includes the directory you have specified, and that it gets added to the collect2 command as -L, but you will see it gets added after the standard directories such as -L/usr/lib etc.
I don't know any way to make the directories in LIBRARY_PATH come first, I think you have to use -L for that.
Try specifying the library path in a .conf file in /etc/ld.so.conf.d/
The linker looks at paths specified in files in /etc/ld.so.conf.d/ while linking.
Make sure you run 'ldconfig' once you create the file, that will force it to update its cache.
I will start by saying that I am new to gcc and makefiles. I have a .so file on the desktop (~/Desktop) called lib.so. I want to link my program (called myProgram) to it. What I wrote in my makefile is:
g++ myProgram.o -L ~/Desktop -l lib -o myProgram
When I run make I get an error:
/usr/bin/ld: cannot find -llib
I also tried -l lib.so and got the same error.
What is the correct way to link?
Two solutions:
Rename the file to libsomething.so, then use -l something. The linker automatically wraps the name with lib prefix and .so suffix (or .a suffix for static libraries).
Use the option -l :lib.so. When you prefix the name with :, the linker uses the name as given.
These are explained in the ld man page.
I have written a makefile like this:
HEADER = -I./cygdrive/c/cpros/kajj/source4
LIBB = -L./cygdrive/c/cpros/kajj/source1 -L./cygdrive/c/cpros/kajj/source2
LIBRA = -larith -ldekk
target : game.o
gcc $(HEADER) $(LIBB) $< -o $# $(LIBRA)
game.o : game.c
gcc -c game.c
I have created my own static library and included the header file path and library path. When I execute my makefile it gives an error saying that
/usr/lib/gcc cannot find -larith -ldekk.
It is pointing to the lib/ directory but it is not over there: -ldekk and -larith are in source1 and source2 files respectively.
How to solve this error?
Instead of -L./cygdrive/c, use -L/cygdrive/c. The dot makes the library path relative from the current directory, i.e. it will look for a cygdrive subfolder of the current folder instead of drive C.
My revised Makefile libraries line is:
LIBS=-L/usr/lib/arm-linux-gnueabihf -lrtlsdr -lpthread -lm
This solved the issue in a Raspberry Pi 4 running the latest Raspbain as of Dec 30, 2019
Happy New Year Everybody,
I am struggling with a rather stupid gcc include problem. I tried to change my working relative include paths (using -I) to absolute paths, so that I could move the source files and it would still compile.
Relative path (working):
-I../../../NVIDIA_GPU_Computing_SDK/OpenCL/common/inc -lOpenCL
Absolute path (not working):
-I~/NVIDIA_GPU_Computing_SDK/OpenCL/common/inc -lOpenCL
So how do you inlcude header files with absolute paths from the home directory?
Thanks
[update]
I tried the $HOME idea with -I$HOME/NVIDIA_GPU_Computing_SDK/OpenCL/common/inc
but the output of the make file says:
gccIOME/NVIDIA_GPU_Computing_SDK/OpenCL/common/inc-lOpenCL -O3 -fno-strict-aliasing -fopenmp -std=c99 -lm -D_GNU_SOURCE -Wall -pedantic foo.c
foo.c:14: fatal error: CL/cl.h: No such file or directory
compilation terminated.
Does it make a difference that I use a make file for these parameters?
Specify the full path or $HOME instead of using ~ for the home directory
Try using $HOME instead of ~.