Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve conflicting linker dependencies?

If I have two libraries, A.lib and B.lib, both of which export foo and bar, how do I tell the linker to use the symbol foo from A.lib and the symbol bar from B.lib?

like image 289
user541686 Avatar asked Jan 23 '12 01:01

user541686


3 Answers

You cannot. For your example you can have definitions from foo.lib or bar.lib but not both (especially if you cannot recompile the libraries and set symbol visibility so that only the symbols you want are exported). The order you link them against your application will depend on which library's definitions are used (you'll have to use the scientific method, I think the first one linked wins). Niklas Hansson's answer is a great way to do this dynamically but it seems you don't want to modify the original application, either, to dynamically pick/choose what symbols to take out of the libraries.

If you really wanted to you could mangle the symbol tables with a hex editor so that the symbols you don't want exported have different names (hacky, but it would work). I know on Linux there is a tool called objcopy that would let you do this (not sure about Windows).

like image 136
sholsapp Avatar answered Nov 03 '22 16:11

sholsapp


You can use LIB.EXE /EXTRACT ... to extract only the object files you want to use, and link those files into your own application.

Or you may use LIB to create one new library containing the elements you need:

  • First, use /REMOVE on A.LIB to remove bar.obj:
    LIB.EXE /OUT:ANOBAR.LIB /REMOVE:bar.obj A.LIB
  • Then combine A.LIB and B.LIB, and make sure to use ANOBAR.LIB as the last on the command line to ensure its foo.obj is used instead of B.LIB's:
    LIB.EXE /OUT:COMBINED.LIB B.LIB ANOBAR.LIB

Details are found here: Managing a library, especially the paragraph:

You can use LIB [...] To replace a library member with a new object, specify the library containing the member object to be replaced and the file name for the new object (or the library that contains it). When an object that has the same name exists in more than one input file, LIB puts the last object specified in the LIB command into the output library. When you replace a library member, be sure to specify the new object or library after the library that contains the old object.

I didn't test the command lines given, but I've used similar ones extensively in the past.

like image 36
Johan Bezem Avatar answered Nov 03 '22 16:11

Johan Bezem


If you are using dynamic libraries, you could use dynamic loading and pick foo from A and bar from B when loading.

like image 1
Niklas Hansson Avatar answered Nov 03 '22 15:11

Niklas Hansson