在C

时间:2017-07-23 06:14:02

标签: c static-libraries

我有libTimer.alib2.alib3.a和应用程序代码。 lib2.a通过将libTimer.a(从timer.o创建)与其他对象文件a.ob.o相关联而创建的lib3.a。 即使libTimer.a也是通过关联c.o和其他对象文件(例如d.omain.o)创建的。

现在,应用lib2.a与图书馆lib3.aa.o相关联。 我知道应用程序的大小不会增加(这种方法不会发生多次包含)。我刚刚测试过,通过链接库或添加单个源文件b.oc.od.otimer.o和{{1}来构建应用程序时,应用程序大小没有变化}}

但是这样嵌套库有什么指导原则吗?

以下是命令摘要:

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

Lib2.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

lib3.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

1 个答案:

答案 0 :(得分:2)

除主应用程序外,您所显示的“链接命令”是不必要的。我真的很惊讶它不会抛出错误,因为你的库代码不应该包含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库之间存在一些混淆。

需要注意的重要事项:在链接命令中,始终在依赖项之前列出库和目标文件。链接器通过维护未解析的符号来工作,并且只能从稍后在命令行中的库和目标文件中恢复它们。