Linux: control, where does `ld` look for .o object files?

Well, this is the situation: I'm trying to use some old software: it works fine on Ubuntu Lucid, does not work on Natty.

So, I strace d around the bit, and it turns out that this software calls ld , and ld ultimately fails with:

 .../ld: crt1.o: No such file: No such file or directory 

... yes, the old crti.o file is missing an error :) However, I would like to ask a question in more general terms ...

The fact is that this is a "standalone" (older) ld here, and when I run .../ld -verbose | less .../ld -verbose | less , I get:

 ... SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); ... 

Now the fact is that:

  • In Lucid, crt1.o is in /usr/lib/crt1.o
  • In Natty, crt1.o is located in /usr/lib/i386-linux-gnu/crt1.o

... so it is not surprising why crt1.o cannot be found, I think. It seems that all I need to do is tell ld to look for crt1.o in /usr/lib/i386-linux-gnu , but how to do it?

I thought I could use the -L option, but man ld says:

 to link a file "hello.o": ld -o <output> /lib/crt0.o hello.o -lc This tells ld to produce a file called output as the result of linking the file "/lib/crt0.o" with "hello.o" and the library "libc.a", which will come from the standard search directories. ... -L searchdir --library-path=searchdir Add path searchdir to the list of paths that ld will search for archive libraries and ld control scripts. 

... The value of " -L " will affect where we look for " libc.a " (in the human example), but not for object files.

I would prefer an environment variable for this, but I tried both LD_PRELOAD_PATH and LD_LIBRARY_PATH no avail (I think they are associated with "shared objects" and these .o files are not one of those).

Does anyone know if there is an environment variable (preferably - or if not, a command line option for ld ) that will control where ld searches for .o object files?

As a side note, I think I could just symbolize /usr/lib/i386-linux-gnu/crt1.o in /usr/lib/ , but I would prefer to use an environment variable if it exists ... If not, are there any other possible solutions?

Thanks in advance for any answers,
Hooray!

EDIT: possibly relevant: Daniel Kegel - --with-sysroot newbie: "ld: cannot open crt1.o"

+4
source share
4 answers

ld does not use the search path for .o files at all - you must pass it the full path (as in the example given in the manual). No, there is no way to change the search path that it uses to find .o files.

In general, ld should not be called directly - for example, you usually call gcc to complete your binding. I would say that this is the program that calls ld , which is to blame here.

+4
source

OK, after some involvement, I think I managed to solve my original problem (although note that as far as the original question goes, it still remains the same answer as the accepted answer):

 LIBRARY_PATH=/lib/i386-linux-gnu:/usr/lib/i386-linux-gnu:$LIBRARY_PATH myprogram --args.. 

Here is the difference I must remember:

  • LD_LIBRARY_PATH used to "help" the search library executables when they are started (i.e., load, LD_ )
  • LIBRARY_PATH helps gcc , g++ and companies find libraries referenced by the -l 'argument (e.g. -ldl , i.e. libdl ), which was also a problem in my case, see t29> for more on LIBRARY_PATH )

Since myprogram called g++ , ld and such, and they failed to find the libraries at compile time - adding the LIBRARY_PATH argument apparently eliminated the g++ / ld behavior and therefore I get no problems (even with crt1.o !) more with myprogram .. Hope this lasts :)

Thank you all for your help,
Hooray!

+7
source

if it is an x86_64 machine (I think it is) then you need to make sure libc6-dev is installed (I think the other crt1.o is the libc6-dev-i386 file. IF natty renames 32-bit libs folders (on previous releases of his / usr / lib 32) ....

if you compile the 32-bit version and get this error ... it should be an error in gcc / g ++; try giving it a path with the -B option

+1
source

You can also use --sysroot:

  --sysroot=dir Use dir as the logical root directory for headers and libraries. For example, if the compiler normally searches for headers in /usr/include and libraries in /usr/lib, it instead searches dir/usr/include and dir/usr/lib. If you use both this option and the -isysroot option, then the --sysroot option applies to libraries, but the -isysroot option applies to header files. The GNU linker (beginning with version 2.16) has the necessary support for this option. If your linker does not support this option, the header file aspect of --sysroot still works, but the library aspect does not. 

!!! => The GNU host (starting with version 2.16) has the necessary support for this option.

0
source

Source: https://habr.com/ru/post/1345905/


All Articles