Cross compiling with linker scripts containing absolute paths - linker

I am trying to do a cross compile making use of gcc's -sysroot option. However, when attempting to link against a linker script (libpthread.so or libc.so in particular), I get
$CTC_PATH/bin/ld: skipping incompatible /lib/libc.so.6 when searching for /lib/libc.so.6
$CTC_PATH/bin/ld: cannot find /lib/libc.so.6
Basically the loader scripts contain absolute paths, and now it is trying to link against my host system's libraries located at those paths. I have worked around the problem by removing the absolute paths.
Does anyone know of another fix to this problem that doesn't involve editing the linker scripts.
Thanks.

I don't know how to convince GCC to do so, but the linker's prefix can be overriden by the --rlink-path /path/to/prefix option.
I assume there is some gcc param to pass params to ld.

Related

ld and lld use only paths I input

I am trying to cross compile for my raspberry pi, unfortunately the pi has an older version of libstdc++ than my build machine and when I try to run my executable it says "./<exe_name>: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by ./<exe_name>). I've gotten it working by using "-static", but really I'd like to be able to tell both ld (the gcc linker) and lld (the clang linker) "Only look in these paths for any libraries" it keeps finding the system one and linking against it. I've rsynced the raspberry pi's /usr/lib and /lib directores over to the host machine and I'd like to say "use /path_to_raspberry_pi_rsync/lib and /path_to_raspberry_pi_rsync/usr/lib" only.
Bonus points for getting ld and lld to tell me what path it's using when it tries to link.
I'd like to be able to tell both ld (the gcc linker) and lld (the clang linker) "Only look in these paths for any libraries"
Both will do that if you supply proper -L/path/to/target/libraries with sufficient contents.
it keeps finding the system one and linking against it. I've rsynced the raspberry pi's /usr/lib and /lib directores over to the host machine and I'd like to say "use /path_to_raspberry_pi_rsync/lib and /path_to_raspberry_pi_rsync/usr/lib" only.
Your problem most likely stems from the fact that what you rsynced are runtime libraries, not actual development libraries. So if e.g. /path_to_raspberry_pi_rsync/usr/lib contains libstdc++.so.6, but doesn't contain libstdc++.so symlink, then the linker will keep looking for libstdc++.so., until it finds one in the system directory.
In addition, once you succeed limiting your link to just the "rsync"d libraries, it is likely that your link will fail with unresolved libstdc++ symbols. That is because you need a matching set of headers and libraries.
Your best bet is to obtain a proper toolchain targeting your runtime environment.
Bonus points for getting ld and lld to tell me what path it's using when it tries to link.
With ld, you can add -Wl,-t flag and it will tell you about each and every library and object file it opens. lld may support this flag as well.

Link error using old libraries

I am trying to use third-party libraries (.a) , for which I dont have the source code, that worked in an older app. I imported the older app into Xcode 7 and built and ran it successfully. The libraries were dependent on system libraries which had extension .dylib The program still worked.
I then tried to build a new app using the same libraries. However, I had to replace the system libraries with their .tbd equivalents. When I issued the build command, I got link errors such as shown below where the library name is libavutil.a
ld: library not found for -lavutil
clang: error: linker command failed with exit code 1 (use -v to see invocation
I read in stack overflow posts about the need to add to the 'other linker flags' in the build settings.
My questions are:
Do I need to add flags (to Debug and Release) such as lavutil for libavutil.a or flags for the system libraries -lc++ for libc++?
Am I on the right track? Or is there some other solution to the
linker errors.
Reading through some SO posts on similar linker errors encountered by others, it was suggested that instead of adding a -lavutil like statement to the other linker flags, I could drag and drop the libraries into the window that opens up for multiple values. This worked well. Drag and drop maintains the right relative directory structure and removes the ambiguity that the linker may encounter to find the libraries. The linker errors were eliminated and I could execute the program.
In summary, I switched to Xcode 7, changed target to 9.2, dragged my third-party libraries, and built and ran.

Linker cannot find existing Static Library File

I have a Eclipse project using C programming language. I have been stuck with a problem related to linker error since two days now. I have checked various forums to find a solution. Tried a lot of the suggestions but could not resolve it. So as a last resort, i am asking question here. My main program MotorRun.c has code which calls functions in the static library FtMscLib_Static_LIBCMT_Release.Lib which is in Libs folder in the path C:\FT-Project\Common\Libs. I am using MinGW gcc compiler.
When i run the makefile, it generates an error:
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.9.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lC:\FT-Project\Common\Libs\FtMscLib_Static_LIBCMT_Release.Lib
collect2.exe: error: ld returned 1 exit status
The code run by the makefile is
gcc "-LC:\\FT-Project\\Common\\Libs" -shared -o libRoboCopMinGW.exe "src\\MotorRun.o" "-lC:\\FT-Project\\Common\\Libs\\FtMscLib_Static_LIBCMT_Release.Lib"
By looking at the execution code, we can see that the paths and library name has been set correctly, but the linker just cannot find it so that it can link the library with my MotorRun.o object file. Hope someone can help me in finding a solution.
The program MotorRun.c is a very simple one, so i am not posting it here. But if necessary i can update it later. Thanks in advance!
The correct linker syntax is typically something like:
-Lpath_to_library_directory -lname
where the library filename (for a Windows static library) would be name.lib. So your above linker line needs to lose the .lib part. You may also need to prefix the -l argument with another argument -static, to instruct the linker to search for the static library FtMscLib_Static_LIBCMT_Release.Lib otherwise it might try to find the DLL instead.
By the way, there are heaps of posts on StackOverflow regarding the issue of static and dynamic linking with MinGW, so feel free to search for these also. The MinGW web pages also have numerous tips on the same topic.

Do I really need to specify library location for linking with automake?

I am working on a multi-platform C program. The makefile has become pretty complicated because of all the different compilers, library locations, etc. on each machine. I figured Autoconf/Automake would be a good solution, though my previous experience using those tools was minimal.
My Makefile.am has the line LIBS=-lX11, but linking fails with the error "/usr/bin/ld: cannot find -lX11". I can work around this by adding "-L/usr/X11R6/lib/" to the definition of LIBS, but should I really need to do that? When I run ./configure, it says:
checking for X... libraries /usr/X11R6/lib, headers /usr/X11R6/include
So it seems like Automake should know where to find it. Is there a way I can reference its location in Makefile.am without having to hardcode it, since the X11 libs will be in a different place on each machine?
Your Makefile.am should not set LIBS. If you need to link with a library, configure.ac should include a check for the library and the configure script will set LIBS accordingly. Also, Makefile.am should not specify paths to libraries. Each system should be configured so that the precompiler can find the headers and the linker can find the libraries. If the system is not set up so that the linker can find a library, the correct solution is for the user to specify the location in LDFLAGS rather than hard coding something in Makefile.am. (eg, rather than adding -L/p/a/t/h to a Makefile, you should add LDFLAGS=-L/p/a/t/h to the invocation of configure.)

Linking to libraries in gcc

I have a collection of dynamic libraries that I want to link to in /usr/local/lib, how can I do this using gcc without setting my LD_LIBRARY_PATH (i have heard it is bad to do this fora number of reasons).
I have spent an hour looking at this on the internet, and fiddling with command line arguments, the only way I got it to work was using the -static -I/usr/local/lib/ flag, but this converts dynamic libraries to static libraries, and the compiler throws up some warnings.
Thanks for your help
Add /usr/local/lib to the loader configuration in /etc/ld.so.conf and run ldconfig.
You can set the system wide search directories for ldd (the dynamic linker) in /etc/ld.so.conf. In many distributions (well, mine) there is a /etc/ld.so.conf.d/ directory, from which the /etc/ld.so.conf includes all *.conf files. You can add the directory directly in ld.so.conf or add a .conf file in the directory.
Of course, you'll need root access to do this.
Oh, yeah: as Ignacio says, run ldconfig after changing these config files.

Resources