我有libTimer.alib2.alib3.a和应用程序代码。
lib2.a通过将libTimer.a(从timer.o创建)与其他对象文件a.ob.o链接而创建。
甚至lib3.a也可以通过链接libTimer.a和其他对象文件(如c.od.o)来创建。
现在应用程序main.o与库lib2.alib3.a链接。
我知道使用此方法不会增加应用程序的大小(不会发生多个包含)。我刚刚测试了一下,发现当通过链接库或添加单个源文件来构建应用程序时,应用程序大小没有变化。
但是用这种方式嵌套库有什么指导原则吗?
下面是命令摘要:
libTimer.a库定时器
编译命令:

avr-gcc.exe -Os -Wextra -Wall -mmcu=atmega328p -std=gnu99 \
    -fshort-enums -ffunction-sections -fdata-sections -DF_CPU=16000000UL \
    -g -Os -Wmain -Wextra -Wall -c CL_Timer.c -o Debug\CL_Timer.o

链接命令:
avr-g++.exe -o Debug\Timer.elf Debug\Timer.o -mmcu=atmega328p \
    -Wl,-Map=Debug\timer.map -Wl,--gc-sections

生成后命令:
avr-ar rcs libTimer.a Debug\timer.o
ranlib libTimer.a

伦敦银行同业拆借利率2.a
链接命令:
avr-g++.exe -o Debug\library2.elf Debug\a.o Debug\b.o -mmcu=atmega328p \
    -Wl,-Map=Debug\library2.map -Wl,--gc-sections .\libTimer.a

后期生成:
avr-ar rcs lib2.a Debug\a.o Debug\b.o
ranlib lib2.a

伦敦银行同业拆借利率3.a
链接命令:
avr-g++.exe -o Debug\library3.elf Debug\c.o Debug\c.o -mmcu=atmega328p \
    -Wl,-Map=Debug\library3.map -Wl,--gc-sections .\libTimer.a

生成后命令:
avr-ar rcs lib3.a Debug\c.o Debug\d.o
ranlib lib3.a

主应用程序链接:
avr-g++.exe -o Debug\main.elf Debug\main.o -mmcu=atmega328p \
    -Wl,-Map=Debug\main.map -Wl,--gc-sections .\liba.a .\liba.b

最佳答案

除了主应用程序之外,显示为“链接命令”的内容是不必要的。我很惊讶它没有抛出错误,因为库代码不应该包含main()
创建静态库的命令是ar命令(在您的例子中是交叉编译器avr-ar命令)。他们唯一要做的就是将库的所有对象文件放在一个归档文件中(*.a)。
使用共享库,您将拥有一些依赖关系信息,因此共享库可以链接到另一个共享库。使用静态库,不存在这样的事情,它们只是对象文件的档案,在您的主应用程序的最后链接步骤中,您必须确保链接所有所需的库。因此,正如您所描述的,libalibb都依赖于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.alibb.a——您在问题中对名为lib2.alib3.a的库也有一些混淆。
需要注意的重要事项:在链接命令中,始终在库和对象文件的依赖项之前列出它们。链接器通过维护未解析的符号来工作,并且只能从稍后在命令行中提供的库和对象文件解析它们。

关于c - 在C中多次包含静态库,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45262102/

10-15 01:37