Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mixing C and C++ libraries

Tags:

c++

c

gnu

I've got a strange problem building an executable coded in C++ that uses a C++ library which itself relies on a C library. I compiled the C modules making up the C library using gcc and all other source modules using g++. Both, the C and C++ library are static libs.

When I include a header file from the C library in C++ source code, I alwas wrap it in extern "C":

extern "C"
{
  #include <c-library-header.h> 
}

The strange thing now is that get "undefined reference" errors when linking, but these change depending on the order I list the libraries:

  • If I list the C library first, all the symbols in that library referenced by C++ modules show as "undefined".
  • If I list the C++ library first, all the symbols in that library referenced by C++ modules show as "undefined".

I would have thought to order in which static libs appear on the g++ command-line would be totally irrelevant. Anybody any clues?

like image 293
pete Avatar asked Jan 10 '23 21:01

pete


2 Answers

The order is important.

If libxxx depends on libyyy, then libxxx should be specified first, i.e. -lxxx -lyyy

In the unfortunate case, when both depend on each other, then one library may be mentioned twice

-lxxx -lyyy -lxxx

See:

  • http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html
  • g++ linking order dependency when linking c code to c++ code
  • Why does the order in which libraries are linked sometimes cause errors in GCC?
like image 126
Arun Avatar answered Jan 19 '23 08:01

Arun


Instead of listing the libraries multiple times (this may be cumbersome if there are many interdependent libraries) one can rely on GNU ld to do the right thing and search the library list back and forth until all the symbols are resolved. This is achieved using start_group/end_group command line switches:

g++ <...flags...> -Wl,--start-group -lxxx -lyyy -Wl,--end-group <...other flags...>

or by directly supplying the archives if they happen to be named in "non-conforming" way:

g++ <...flags...> -Wl,--start-group xxx.a yyy.a -Wl,--end-group <...other flags...>

The price to pay for such a neat feature is reduced linking speed, which, in many case, is not critical.

like image 40
oakad Avatar answered Jan 19 '23 08:01

oakad