1

I'm compiled a GTK+ program using clang, rather than gcc. So far so good, except I can't have ld link correctly.

Original makefile called gcc to do the linking, like this:

gcc -g -O2 -export-dynamic -o my_application somefile.o another.o -pthread -lgnomeui-2 -lSM -lICE -lbonoboui-2 -lgnomevfs-2 -lgnomecanvas-2 -lgnome-2 -lpopt -lbonobo-2 -lbonobo-activation -lORBit-2 -lart_lgpl_2 -lgconf-2 -lglade-2.0 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lglib-2.0 -lxml2 -pthread -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lxml2 -lgthread-2.0 -lrt -lglib-2.0

If I simply substitute gcc with clang in the above command, I get this warning from the latter:

clang: warning: argument unused during compilation: '-e xport-dynamic'

Problem is: clang doesn't recognize "-export-dynamic" as a linker option, so it doesn't pass it off to ld. This causes the references to external functions to be scrapped: when final binary is executed, neither the menu options nor the buttons react.

If I do final linking step with gcc the binary works perfectly (even though it was really compiled with clang and gcc only does the linking). Since I'm trying to completely replace gcc with clang in my machine, this is not acceptable.

So I tried this:

ld /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o -g -O2 -export-dynamic my_application somefile.o another.o -o -lgnomeui-2 -lSM -lICE -lbonoboui-2 -lgnomevfs-2 -lgnomecanvas-2 -lgnome-2 -lpopt -lbonobo-2 -lbonobo-activation -lORBit-2 -lart_lgpl_2 -lgconf-2 -lglade-2.0 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lglib-2.0 -lxml2 -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lxml2 -lgthread-2.0 -lrt -lglib-2.0

By adding first 3 objects I avoid the "can't find _start" message. But then I get the aforementioned two complaints:

/usr/lib/crt1.o: In function _start: (.text+0x12): undefined reference to __libc_csu_fini /usr/lib/crt1.o: In function _start: (.text+0x19): undefined reference to __libc_csu_init

I tried adding crtbegin.o and crtend.o at the list, even before crt1.o , to no avail. What is the linker's correct invocation?

(Post Edit): If nothing else works, is there a way to catch what exact parameters gcc is passing to ld when gcc is used for the linking?

Joe Pineda
  • 5,521
  • 3
  • 31
  • 40

2 Answers2

2

gcc automatically adds language support libraries and objects to your supplied list for link. You have to add them yourself if you want to invoke ld directly. Taking an example from man ld, it could be

ld -o <output> /lib/crt0.o hello.o -lc

Try adding -lc, the symbol you need should be in it (at least on my system, it is).

jpalecek
  • 47,058
  • 7
  • 102
  • 144
  • Thanks! Just adding this "-lc" flag without adding the "crt*.o" objects causes ld to still complains about being unable to find entry symbol "_start" missing.With both those object files and "-lc" then ld gives out no error, but the executable is unrunnable: when I try to run it, bash complains: "-bash: ./gnomebaker: No existe el fichero o el directorio" (File or folder does not exist in Spanish - sorry, forgot to modify my locale :P ) – Joe Pineda Apr 24 '12 at 12:30
  • That means file `gnomebaker` is missing. Haven't you got your `-o` option wrong? Hasn't other file with suspicious name appeared? – jpalecek Apr 24 '12 at 12:35
  • Nope, the options are correct and the file does exist. After searching a bit, found what's the problem here: http://stackoverflow.com/questions/2716702/no-such-file-or-directory-error-when-executing-a-binary I, too, can't run the file and ldd fails with it, also. Turns out the "gnomebaker" binary is looking for /lib/ld64.so.1 which doesn't exist in my system - need to understand and fix this. – Joe Pineda Apr 24 '12 at 13:06
  • @JoePineda: Hm. It seems you have created a binary for libc5 (not libc6 which is current). – jpalecek Apr 24 '12 at 15:07
  • Thank you very much! Still don't know why the binary got badly linked, on the bright side it's solved now (albeit in a different way) and I learned to use ldd and readelf. An interesting discursion, altogether :-) – Joe Pineda Apr 25 '12 at 03:36
  • In the end, found out I could create that ld64.so.1 as a link to ld-linux-x86-64.so.2 (as did the asker of http://superuser.com/questions/248512/why-do-i-get-command-not-found-when-the-binary-file-exists ) and this caused the binary created by ld -lc (etc) to work, too. I prefer the other answer, though, as it's cleaner than creating links in the /lib folder. – Joe Pineda Apr 25 '12 at 03:48
1

You can use -Wl,-export-dynamic to pass -export-dynamic to ld without clang knowing about it.

Per Johansson
  • 6,697
  • 27
  • 34