11

Ok, this is the situation: I'm trying to use some older software: works fine on Ubuntu Lucid, fails on Natty.

So, I straced around a bit, and it turns out that this software calls ld, and ld eventually fails with:

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

... yes, the old crti.o file missing error :) However, I'd like to ask the question in more general terms...

The thing is, this is 'standalone' (older) ld here, and when I run .../ld -verbose | less, I get:

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

Now, the thing is that:

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

... so no surprise why crt1.o cannot be found, I guess. It seems, all I have to do, is tell ld to look for crt1.o in /usr/lib/i386-linux-gnu, but how do I do that?

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.

... meaning, '-L' would influence where we look for "libc.a" (in man example) - but not for the object files.

I would actually prefer an environment variable for this, but I tried both LD_PRELOAD_PATH and LD_LIBRARY_PATH to no avail (I guess, those are related to "shared objects", and these .o files aren't one of those).

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

As a note, I guess I could just symlink /usr/lib/i386-linux-gnu/crt1.o in /usr/lib/, but I'd rather use an environment variable, if it exists... If not, are there any other possible solutions to this?

Thank in advance for any answers,
Cheers!

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

Community
  • 1
  • 1
sdaau
  • 36,975
  • 46
  • 198
  • 278
  • natty is a development release; smells like a bug anywayz so maybe asking the ubuntu dev team is the right path to follow – user237419 Mar 30 '11 at 16:13
  • Hi @adirau - thanks for that; but still, I'd like to know in general if there exists an option to control directories where `ld` looks for `.o` object files... Cheers! – sdaau Mar 30 '11 at 16:16
  • i suppose this software is using gcc to compile something? – user237419 Mar 30 '11 at 16:33
  • @adirau - yes it does (it packages its own gcc and ldd to do this compilation) EDIT: ups, I think it is actually g++ ... – sdaau Mar 30 '11 at 16:36

4 Answers4

9

OK, after some messing about, I think I managed to solve my original problem (though note, as far as the original question goes, it's still 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 distinction which I should remember:

  • LD_LIBRARY_PATH is used to 'help' an executable find library files, when it is run (i.e. loading, LD_)
  • LIBRARY_PATH helps gcc, g++ and company find libraries referenced via '-l' argument (for instance, -ldl, i.e. libdl, which was also a problem in my case; see man g++ for more on LIBRARY_PATH)

So since myprogram was calling g++, ld and such, and those were crashing unable to find the libraries during compilation - adding the LIBRARY_PATH argument seems to have fixed the g++/ld behavior, and so I don't get problems (even with crt1.o!) anymore with myprogram.. Hopefully that will last :)

Thanks all for the help,
Cheers!

sdaau
  • 36,975
  • 46
  • 198
  • 278
7

ld doesn't use a search path for .o files at all - you must pass it the full path (as in the example you quote from the manual). So no, there is no way to change the search path it uses to find .o files.

In general, ld shouldn't be called directly - for instance you'd normally call gcc instead to do your linking. I'd say it's the program calling ld which is at fault here.

richvdh
  • 1,163
  • 11
  • 19
  • Thanks for that, @richvdh - I suspected that would be the case, it's nice having it confirmed. I was hoping maybe I could cheat it with something like appending to `$PATH` (but that would work for executables, which `.o` files aren't, so `$PATH` doesn't help).. I guess I could always try to symlink the `.o` files in the calling dir ... – sdaau Mar 30 '11 at 16:41
3

You can use also --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 linker (beginning with version 2.16) has the necessary support for this option.

Vladyslav Savchenko
  • 1,282
  • 13
  • 10
2

if that's and x86_64 machine (I think it is) then you should make sure you have libc6-dev installed (i think the other crt1.o is libc6-dev-i386's file IF natty is renaming the 32bit libs folders (on previous releases its /usr/lib32) ....

if you're compiling for 32bit and you get that error... that must be a bug in gcc/g++; try giving it the path with the -B option

user237419
  • 8,829
  • 4
  • 31
  • 38