2

I am developing a C application that uses the expat XML library. I have built expat from source and installed it under path /opt/libexpat-2.4.8. I build my program with something like (simplified wrt. the original):

gcc -I/optlibexpat-2.4.8/include -L/opt/libexpat-2.4.8/lib -lexpat -o myorogram myprogram.c

Everything worked fine for almost a year, until I upgraded my GNU/Linux distribution last week. My distribution has now the following compiler version:

gcc (Debian 10.2.1-6) 10.2.1 20210110

When I try to compile the source using the new toolchain, I get lots of linker errors such as:

/usr/bin/ld: /tmp/[...].o: in function [...] undefined reference to `XML_ParserCreate'

On the other hand, if I look at /opt/libexpat-2.4.8/lib/libexpat.a:

$ nm /opt/libexpat-2.4.8/lib/libexpat.a | grep XML_ParserCreate

I get

00000000000037a0 T XML_ParserCreate
0000000000003790 T XML_ParserCreate_MM
00000000000037b0 T XML_ParserCreateNS

So: the symbol is in the library but ld cannot find it.

I copied the source code and the compiled expat library without any change to another computer that has an older toolchain (gcc 8.3.0), and everything works fine there.

I have also tested on a third computer that has the newer toolchain (same GNU/Linux distribution, same version) and I get the same errors there.

So I suppose that maybe some compile options have changed in gcc-10, but I have no clue as to where to look for them. I am using basic options like -I, -L and -l.

Do you have any hints?

Giorgio
  • 5,023
  • 6
  • 41
  • 71
  • Depending on what you upgrading from, you may have upgraded to a compiler that's 64 bit default from one that was 32 bit default, and your libexpat possibly contains 32 bit code. – Cubic Sep 01 '22 at 16:22
  • @Cubic: Thanks for the hint. I have deleted the external library and re-compiled it with the new toolchain, but I am still getting the same error. – Giorgio Sep 01 '22 at 16:26
  • Try moving the `-L` and `-l` options to the end of the command (after any .c and .o files). – Ian Abbott Sep 01 '22 at 16:34
  • @Giorgio I'm just noticing you have your lib before your source files - for some reason gcc throws away symbols that aren't already needed before, so you need to move these to the end – Cubic Sep 01 '22 at 16:36
  • 1
    @Cubic: I tried this and put all the options after the end of the line, and it works! But why wasn't this necessary with gcc version 8? – Giorgio Sep 01 '22 at 16:39
  • It has been my experience that sometimes compilers will figure things out even when something isn't configured exactly correctly. I've seen similar issues where something would build with gcc but not clang, and after further investigation, it was that it was never properly configured but gcc managed to make it work anyways. – Christian Gibbons Sep 01 '22 at 18:32
  • The important change is to move the option to link the library (`-lexpat`) _after_ the source modules. The `-L` and `-I` options don't need to be moved. Libraries are searched only for unresolved references and given too early there are none. Unfortunately I don't have the time now to look for the relevant duplicate here on SO. – the busybee Sep 01 '22 at 19:32

0 Answers0