0
  • code::blocks version 17.12
  • Ubuntu MATE 19.10 1.22.2
  • gcc - 4:9.2.1-3.1ubuntu1
  • libavahi-client3 - 0.7-4ubuntu5 (although probably not relevant)

I have C++ app which uses avahi to communicate across the network. This compiles fine and links with:

g++  -o bin/Debug/Zeroconf obj/Debug/AVAHi.o {...} -lavahi-common -lavahi-core -lavahi-common -lavahi-client  

So far, so good. I want to put the AvaHi functionality into a static library to make it easier for other developers. Ideally, I would like to include the Avahi library (among others) in my static library to make linking easier but it looks like the libraries it contains have to be linked by the executable - okay, fair enough.

Building the library works fine and goes off without a hitch and generates libHomeLib.a. Running nm on this shows the calls to AvaHi similar to:

         U avahi_address_snprint
         U avahi_alternative_service_name

so, not munged into C++ format.

Now, creating a simple C++ executable and adding the library to the linker options along with the Avahi libraries compiles fine and links with:

g++  -o bin/Debug/HomeConsole obj/Debug/main.o  -lglib-2.0 -lavahi-common -lavahi-client  /home/mike/Projects/HomeLib/bin/Debug/libHomeLib.a

(no -l for the library I added?). main () simply referenced a static object declared in the factory:

CHomeFactory *pFactory = CHomeFactory::get_factory ();

However, the link fails with:

/home/mike/Projects/HomeLib/AVAHi.cpp:27: undefined reference to `avahi_client_new'
/usr/bin/ld: /home/mike/Projects/HomeLib/AVAHi.cpp:29: undefined reference to `avahi_service_browser_new'
...

and so on, naming all of the functions directly or indirectly called in the library which is odd since I could call any function from the current code without difficulty - I did by by adding a call in main:

avahi_client_new (NULL, (AvahiClientFlags)0, NULL, NULL, NULL);

This time, the compiler only complained:

/usr/bin/ld: /home/mike/Projects/HomeLib/bin/Debug/libHomeLib.a(AVAHi.o): undefined reference to symbol 'avahi_string_list_get_service_cookie'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libavahi-common.so: error adding symbols: DSO missing from command line

So I added a call to "avahi_string_list_get_service_cookie(NULL);" to main and got a clean link.

At the risk of being specific in my details but vague in my question, does anyone know what the hell is going on? Why does the link fail to connect the library calls unless they are referenced in the main executable?

It looks almost as if the first stage of the linker sees that the library isn't called in the code and so doesn't bother to include it which leads the final fixup stage to be unable to find the functions.

Mike
  • 2,721
  • 1
  • 15
  • 20
  • "although probably not relevant" -- you will find that out yourself when you extract the required [mcve]. Same goes for code::blocks. – Ulrich Eckhardt May 17 '20 at 15:07
  • Well, I have one library, one included library and a 3 line application. Short of writing my own stub library (thereby introducing more unknowns), that's about as minimal as it gets. Which library probably is not relevant - we'll find that out when we get an answer! – Mike May 17 '20 at 15:10
  • Try adding `-static` – Brandon May 17 '20 at 15:15
  • No. Specified -static in the executable, the library and both. Same result. – Mike May 17 '20 at 15:26
  • 1
    Does this answer your question? [Why does the order in which libraries are linked sometimes cause errors in GCC?](https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc) – dewaffled May 17 '20 at 16:07
  • You should specify `libHomeLib.a` in command line before the libraries it depends on. – dewaffled May 17 '20 at 16:08
  • 1
    Your linkage inputs `libHomeLib.a` *after* the libraries that it depends on, thus introducing new `avahi_*` references into the linkage which no subsequent libraries can resolve. The linker does not search backwards to resolve symbols. Adding the redundant `avahi_*` references to `main.o` - which is linked *first* - has the same effect on the linkage as doing the right thing: input `libHomeLib.a` *before* the libraries it depends on. – Mike Kinghan May 17 '20 at 16:29
  • Thanks, Mike. Do you want to put your comment as an answer so that I can mark it as the right one? Code::Blocks orders link options as extra commands general, extra commands build, extra libraries. By moving the extra library to the link options, it appeared in the right place in the link command. Also, I wasn't aware of the importance of linking order so thanks for that one, too. – Mike May 17 '20 at 16:49
  • Not sure about closing it. If I knew the link order was the problem then I wouldn't have had to ask the question but thanks to all anyway. I can get back on with to project now. – Mike May 17 '20 at 16:58
  • It's a clear dupe I'm afraid. The explanation and solution of the problem is definitely given by the answer(s) to another question (in this case a "canonical" dupe-target for the problem). If I answered it rather than closing it I would deservedly get a kicking. No reflection on you! – Mike Kinghan May 17 '20 at 19:51
  • Thanks, anyway, Mike. I'd like to leave it here because I'd have loved to have found it rather than being baffled for a day! I really appreciate your help. – Mike May 17 '20 at 21:15

0 Answers0