У меня есть проект с тысячами файлов C, множеством библиотек и десятками программ для связи, и для ускорения компиляции я объединяю файлы C в единицы перевода, которые включают несколько файлов C.Иногда это называется единичной единицей компиляции, единичной единицей трансляции или сборкой единиц.
У меня есть несколько таких единиц трансляции, скомпилированных в разные библиотеки, и эти библиотеки были ранее созданы путем компиляции каждого файла C по отдельности.
Например:
old library.lib:
file1.o
file2.o
file3.o
file4.o
file5.o
file6.o
new library.lib:
translation_unit_1.o
translation_unit_2.o
translation_unit_1.c:
#include "file1.c"
#include "file2.c"
#include "file3.c"
translation_unit_2.c:
#include "file4.c"
#include "file5.c"
#include "file6.c"
Таким образом, они компилируются в: translation_unit_1.o и translation_unit_2.o.И библиотека - это новый library.lib, показанный выше.
Теперь скажите, что у меня есть программа, которую я хочу связать с library.lib, которая ссылается на функцию в file2.c.Но имеет другую версию file1.c, которая компилирует, которая дублирует символы в file1.c в библиотеке, так что для связывания нужен только file2.c из library.lib.Или, возможно, мне нужно связать код из file1.c, но я не могу связать file2.c, потому что у него есть зависимость, на которую я не хочу полагаться (пример ниже).
program:
main.o
file1.o
library.lib
Есть ли способ с любым известным вам компоновщиком получить компоновщик только для извлечения кода из file2.c из объектного кода translation_unit_1.o и использования его для связи main.o с целью создания программы?
Альтернативой может быть разделение translation_unit_1.o на file1.o, file2.o, file3.o, если это возможно, а затем передать его компоновщику.
Спасибо залюбая помощь.
edit 1
Это для единой кодовой базы, которая скомпилирована как для платформы ARM с открытым исходным кодом, использующей ELF, скомпилированную с ARM ADS 1.2, так и дляплатформа Windows, которая использует набор инструментов Visual Studio.Однако, мысли о том, как подойти к проблеме на других платформах и инструментальных цепочках, приветствуются.
Вот конкретный пример на MacOS с использованием clang.
Пример кода ниже приведен здесь: https://github.com/awmorgan/single_translation_unit_lib_link
библиотека:
file1.c этот файл необходим для связи
file2.c этот файл не используется для связи и имеет неразрешенную зависимость, которая может быть в другой библиотеке или объекте
main.c:
int main( void ) {
extern int file1_a( void );
int x = file1_a();
}
file1.c:
int file1_a(void) {
return 1;
}
file2.c:
int file2_a( void ) {
extern int file3_a( void );
return file3_a(); // file3_a() is located somewhere else
}
single_translation_unit.c:
#include "file1.c"
#include "file2.c"
это работает для создания program1.out:
++ clang -c file1.c -o file1.o
++ clang -c file2.c -o file2.o
++ libtool -static file1.o file2.o -o library1.lib
++ clang -c main.c -o main1.o
++ clang main1.o library1.lib -o program1.out
это не приводит к program2.out:
++ clang -c single_translation_unit.c -o single_translation_unit.o
++ libtool -static single_translation_unit.o -o library2.lib
++ clang -c main.c -o main2.o
++ clang main2.o library2.lib -o program2.out
Undefined symbols for architecture x86_64:
"_file3_a", referenced from:
_file2_a in library2.lib(single_translation_unit.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
изменение порядка ссылок также не работает:
++ clang library2.lib main2.o -o program2.out
Undefined symbols for architecture x86_64:
"_file3_a", referenced from:
_file2_a in library2.lib(single_translation_unit.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)