C语言中静态库的多重包含
我有C语言中静态库的多重包含,c,static-libraries,C,Static Libraries,我有libTimer.a,lib2.a,lib3.a和应用程序代码。 lib2.a通过链接libTimer.a(从timer.o创建)与其他对象文件a.o和b.o创建。 甚至lib3.a也是通过链接libTimer.a和其他对象文件(如c.o和d.o创建的 现在,应用程序main.o与库lib2.a和lib3.a链接。 我知道应用程序的大小不会通过这种方法增加(不会发生多次包含)。我刚刚测试并发现,当通过链接库或添加单个源文件a.o、b.o、c.o、d.o和timer.o构建应用程序时,应用程序
libTimer.a
,lib2.a
,lib3.a
和应用程序代码。
lib2.a
通过链接libTimer.a
(从timer.o
创建)与其他对象文件a.o
和b.o
创建。
甚至lib3.a
也是通过链接libTimer.a
和其他对象文件(如c.o
和d.o
创建的
现在,应用程序main.o
与库lib2.a
和lib3.a
链接。
我知道应用程序的大小不会通过这种方法增加(不会发生多次包含)。我刚刚测试并发现,当通过链接库或添加单个源文件a.o
、b.o
、c.o
、d.o
和timer.o
构建应用程序时,应用程序大小没有变化
但是,以这种方式嵌套库有什么指导原则吗
以下是命令摘要:
libTimer.a
编译命令:
avr-gcc.exe-Os-Wextra-Wall-mmcu=atmega328p-std=gnu99\
-fshort枚举-函数部分-fdata部分-DF_CPU=16000000UL\
-g-Os-Wmain-Wextra-Wall-c CL_Timer.c-o调试\CL_Timer.o
链接命令:
avr-g++.exe-o Debug\Timer.elf Debug\Timer.o-mmcu=atmega328p\
-Wl,-Map=Debug\timer.Map-Wl,--gc节
生成后命令:
avr ar rcs libTimer.a Debug\timer.o
ranlib libTimer.a
Lib2.a
链接命令:
avr-g++.exe-o Debug\library2.elf Debug\a.o Debug\b.o-mmcu=atmega328p\
-Wl,-Map=Debug\library2.Map-Wl,--gc节。\libTimer.a
建造后:
avr ar rcs lib2.a调试\a.o调试\b.o
ranlib lib2.a
lib3.a
链接命令:
avr-g++.exe-o Debug\library3.elf Debug\c.o Debug\c.o-mmcu=atmega328p\
-Wl,-Map=Debug\library3.Map-Wl,--gc节。\libTimer.a
生成后命令:
avr ar rcs lib3.a调试\c.o调试\d.o
ranlib lib3.a
主应用程序链接:
avr-g++.exe-o Debug\main.elf Debug\main.o-mmcu=atmega328p\
-Wl,-Map=Debug\main.Map-Wl,--gc节。\liba.a。\liba.b
除了主应用程序之外,不需要显示为“链接命令”的内容。实际上,我很惊讶它没有抛出错误,因为库代码不应该包含main()
创建静态库的命令是ar
命令(在您的例子中是交叉编译器avr-ar
命令)。他们所做的唯一一件事就是将库的所有对象文件放在存档文件(*.a
)中
使用共享库,您将拥有一些依赖信息,因此共享库可以链接到另一个共享库。对于静态库,不存在这样的东西,它们只是对象文件的存档,在主应用程序的最后链接步骤中,必须确保链接所有必需的库。因此,如您所述,liba
和libb
都取决于libTimer
,最后的链接步骤是错误的,应该如下所示:
avr-g++.exe -o Debug\main.elf Debug\main.o -mmcu=atmega328p \
-Wl,-Map=Debug\main.map -Wl,--gc-sections .\liba.a .\libb.a .\libTimer.a
这假设它们实际上被命名为liba.a
和libb.a
——您在问题中对名为lib2.a
和lib3.a
的库有些混淆
需要注意的重要事项:在链接命令中,始终在依赖项之前列出库和对象文件。链接器通过维护未解析的符号来工作,并且只能从稍后在命令行中出现的库和对象文件中解析它们。如何使用
lib2.a
containlibTimer.a
?你确定它被控制住了吗?使用ar
创建静态库时,只需将其所有.o
文件添加到一个存档文件中。通常,您不关心依赖项,而是将它们留给使用库的可执行文件的最后链接步骤(例如,在链接lib2.a
时,还必须在它之后链接libTimer.a
)。静态库不“包含”任何其他库,静态库只不过是对象文件的存档。为了清晰起见,请将原文改写。可能是我的话“包含”错了。它仅与库链接。重新措辞没有帮助<代码>.a库不是通过链接创建的。也许你需要的是展示你是如何创建这些命令的,我想你的意思是“取决于”。如果两个库都依赖于第三个库,只要它们不需要不同的版本就可以了。