Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking Libraries with Duplicate Class Names using GCC

Tags:

c++

gcc

Is there a way for GCC to produce a warning while linking libraries that contain classes with the same name? For example

Port.h

class Port {
public:
  std::string me();
};

Port.cpp

#include "Port.h"
std::string Port::me() { return "Port"; }

FakePort.h

class Port {
public:
  std::string me();
};

FakePort.cpp

#include "FakePort.h"
std::string Port::me() { return "FakePort"; }

main.cpp

#include "Port.h"

int main() {
  Port port;
  std::cout << "Hello world from " << port.me() << std::endl;
  return 0;
}

Building

# g++ -c -o Port.o Port.cpp
# ar rc Port.a Port.o
# g++ -c -o FakePort.o FakePort.cpp
# ar rc FakePort.a FakePort.o
# g++ -c -o main.o main.cpp
# g++ main.o Port.a FakePort.a
# ./a.out
  Hello world from Port

Change library order

# g++ main.o FakePort.a Port.a
# ./a.out
  Hello world from FakePort

According to this page:

If a symbol is defined in two different libraries gcc will use the first one it finds and ignore the second one unless the second one is included in an object file which gets included for some other reason.

So the above behavior make sense. Unfortunately I am inheriting a sizable code base that doesn't make use of namespaces (and adding them isn't feasible right now) and uses some generic class names throughout multiple libraries. I would like to automatically detect duplicate names at link time to make sure that the wrong copy of a class isn't accidentally being instantiating. Something like:

# g++ -Wl,--warnLibraryDupSymbols main.o FakePort.a Port.a
  Warning: Duplicate symbol: Port

but I can't find anything in the GCC linker options to do that. Is it possible to get GCC to automatically detect and report such cases?

like image 923
joesdiner Avatar asked May 04 '10 14:05

joesdiner


1 Answers

The following might be worth a try (I honestly don't know if it'll do what you want):

--whole-archive

For each archive mentioned on the command line after the --whole-archive option, include every object file in the archive in the link, rather than searching the archive for the required object files. This is normally used to turn an archive file into a shared library, forcing every object to be included in the resulting shared library. This option may be used more than once.

I haven't tried it, but it sounds as if it'll pull in all the items in a library as if they were object files. You'll need to specify the option for each library.

As Neil said, this won't give you class-level conflicts, but if there are class members with the same signature, this might make the linker tell you.

like image 106
Michael Burr Avatar answered Oct 07 '22 21:10

Michael Burr