3

I am working on a complex C ecosystem where different packages/libraries are developed by different people.

I would like to create a new project named foobar. This project uses two libraries, the library foo and the library bar.

Unfortunately, bar does not require the same version that foo requires. Both use say so there is a conflict.

If all the packages are on Git with submodules, the foobar project cannot be built when cloned recursively because two say functions exist in different translation units. So the submodule strategy doesn't work.

My question is: how is it possible to manage one project that uses two different version of the same static library (*.a)?

Structure

 foobar | .----'----. <---- (require) v v foo bar (v1.0) | | (v2.0) '-> say <-' 

The project foobar require the library foo and the library bar, both of these libraries uses the say package: foo requires version 1 and bar requires version 2.

Packages

say

// say.h void say(char *); 

foo

// foo.c #include "say.h" void foo(void) { say("I am foo"); } 

bar

// bar.c #include "say.h" void bar(void) { say("I am bar"); } 

foobar

// main.c #include <stdlib.h> #include "foo" #include "bar" int main() { foo(); bar(); return EXIT_SUCCESS; } 
7
  • 1
    For anyone to provide a meaningful answer, you'll probably need to provide a lot more detail about how the different libraries are all compiled, how they're all linked into libraries, and how they're linked into executables. Commented Feb 20, 2018 at 10:27
  • @AndrewHenle, for now, the libraries are yet not libraries. They are just source-code. I am thinking about static libraries because I target embedded bare-metal systems. Commented Feb 20, 2018 at 12:12
  • 1
    If they are in source code, just change the name of one of the functions. Commented Feb 20, 2018 at 12:14
  • What tool chain? GCC, with the ld linker? Commented Feb 20, 2018 at 12:33
  • 1
    Keil has a --partial switch. Some 2009 documentation for IAR does not show such a switch, but it suggests that other tools can produce files conforming to the Embedded Application Binary for Interface for ARM (AEABI), so you could investigate whether GCC’s linker could be used. Commented Feb 20, 2018 at 14:22

1 Answer 1

6

Linkers typically have a mode in which they perform a partial link, which resolves references that can currently be resolved and produces an object module ready for further linking instead of a finished executable file.

For example, the GCC linker ld has a -r switch that allows this. Using this switch, and possibly others, you could link foo.o with one library to make foo.partial.o and separately link bar.o with another library to make bar.partial.o. Then you could link foo.partial.o and bar.partial.o with each other, the main program, and any other libraries and object modules needed.

This can work for static libraries, where the code for each library is included in the resulting executable or object file, and the references to its symbols are fully resolved. For shared dynamic libraries, there may be problems, since dynamic libraries require references to be resolved at run time, and the linker and executable file format might or might not support the ability to distinguish symbols of the same name in different versions of one library.

Sign up to request clarification or add additional context in comments.

3 Comments

That's very interesting. I didn't know about the -r switch. This is perhaps a good answer to my question.
The answer skips one step? Using objcopy to localize symbols.
@hunter_tech: I have performed the link operations described in this answer without using objcopy and see no reason it would generally be needed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.