I have an old static library that includes some functions produced by a C auto-coder (Mathworks/Simulink). I have just made a new static library (that does totally different things from the old library) that uses a newer version of the auto-coder. I need to make an executable that links both these libraries. Unfortunately many of the helper functions generated by the auto-coder have the same name in the old and new libraries but their functionality has changed. These functions are not part of the API. Obviously when I try to link I get complaints that the same symbols appear in both libraries. The old library is untouchable, but I can mess with the new one.
The libraries are built with
gcc -c *.c
ar -crs libwhatever.a *.o
and linked with
gcc main.o -L. -lold -lnew
My current solution is to look at all the symbol clashes given by gcc and rename the symbols in the new library using
objcopy --redefine-sym sym=sym_new libnew.a
This seems to work. My program links and behaves as expected. But I'm wondering if it is the right/best thing to do.
Ideally I'd like to make a libnew.a that only exposes the API functions and nothing else. That way I guarantee no symbol clashes when I try to link. Is this possible I cannot figure out how.
Please note that I have little previous experience in these matters. Also, if it's relevant/not obvious, I'm using Linux.
Edit
Below is a rather contrived minimal working example.
old/printOld.c:
#include "printOld.h"
#include <stdio.h>
void printOld()
{
printStr();
}
void printStr()
{
printf("Old\n");
}
old/printOld.h:
void printStr();
old/buildOld:
gcc -c printOld.c
ar -crs libold.a printOld.o
new/printNew.c:
#include "printNew.h"
#include <stdio.h>
void printNew()
{
printStr();
}
void printStr()
{
printf("New\n");
}
new/printNew.h:
void printStr();
new/buildNew:
gcc -c printNew.c
ar -crs libnew.a printNew.o
#objcopy --redefine-sym printStr=printStrNew libnew.a
main/main.c:
void printOld();
void printNew();
int main()
{
printOld();
printNew();
return 0;
}
main/buildMain:
gcc main.c -L../old -L../new -lold -lnew
The linker error when I leave objcopy commented out is:
/usr/bin/ld: ../new/libnew.a(printNew.o): in function `printStr':
printNew.c:(.text+0x11): multiple definition of `printStr'; ../old/libold.a(printOld.o):printOld.c:(.text+0x11): first defined here
collect2: error: ld returned 1 exit status
The above example has the same kind of structure as the auto-generated code. I know that I can fix my problem by declaring the functions in the header files as static, but I'd rather not have to mess with the auto-generated code. It is very large and very unpleasant.
Use --keep-global-symbol=symbolname option with objcopy:
objcopy --keep-global-symbol=printOld libold.a
or
objcopy --keep-global-symbols=api libold.a
where api is a file with a list of API functions