我有一个包含数千个 C 文件、许多库和数十个要链接的程序的项目,为了加快编译速度,我将 C 文件组合成包含多个 C 文件的翻译单元。这有时称为单个编译单元、单个翻译单元或统一构建。
我将多个这样的翻译单元编译成不同的库,这些库之前是通过单独编译每个 C 文件创建的。
例如:
旧库.lib:
file1.o
file2.o
file3.o
file4.o
file5.o
file6.o
新库.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 中的符号,因此它只需要 library.lib 中的 file2.c 进行链接。或者我可能需要从 file1.c 链接代码但无法链接 file2.c,因为它具有我不想依赖的依赖项(如下示例)。
程序:
main.o
file1.o
library.lib
是否有任何您知道的链接器可以让链接器仅将代码从 file2.c 中拉出 translation_unit_1.o 目标代码并使用它来链接 main.o 以制作程序?
另一种方法是将 translation_unit_1.o 拆分为 file1.o、file2.o、file3.o(如果可能),然后将其提供给链接器。
感谢您的帮助。
编辑1
这适用于为使用 ARM ADS 1.2 工具链编译的 ELF 的裸机 ARM 平台和使用 Visual Studio 工具链的 Windows 平台编译的单一代码库。但是,欢迎考虑如何在其他平台和工具链上解决该问题。
这是在 MacOS 上使用 clang 的具体示例。
下面的示例代码在这里:https://github.com/awmorgan/single_translation_unit_lib_link
图书馆:
file1.c 链接需要这个文件
file2.c 此文件不用于链接并且具有 Unresolved 依赖关系,它可能在另一个库或对象中
主.c:
int main( void ) {
extern int file1_a( void );
int x = file1_a();
}
文件1.c:
int file1_a(void) {
return 1;
}
文件2.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)
最佳答案
Is there a way with clang, gcc, microsoft or any linker
clang
、gcc
或 microsoft
都不是链接器(前两个是编译器,第三个是公司)。
答案还取决于平台(您未指定)。
如果您在 Linux 或其他 ELF 平台上构建,您可以使用 -ffunction-sections -fdata-sections
编译代码,链接器将自动做你想做的。
Is there a way to have a linker pull part of an object file from a library for linking?
一般来说,链接器对部分进行操作,并且不能将部分分开(要么得到全部,要么一无所有)。
没有 -ffunction-sections
,单个翻译单元中的所有函数最终都在单个 .text
部分(这是一个近似值——模板实例化和输出inline
函数的离线函数定义通常在它们自己的一个部分中结束)。因此,链接器无法选择 .text
的部分而非全部部分。
关于c - 有没有办法让链接器从库中拉出目标文件的一部分进行链接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54607237/