失败的命令是这样的
arm-none-eabi-gcc ...-mcpu=cortex-m4 .. template/obj/main.o \ -lstm32f4_hal ... -lstm32f4_bsp
和你的 libstm32f4_hal.a 档案有功能 HAL_SPI_GetState 定义,并使用此函数 libstm32f4_bsp.a 存档。
libstm32f4_hal.a
HAL_SPI_GetState
libstm32f4_bsp.a
因此,您的链接命令中的归档顺序错误。你应该知道链接器( ld ,通常由gcc调用来执行实际的链接步骤)适用于输入档案( .a 文件)从左到右,检查手册页 ld(1) 在 http://linux.die.net/man/1/ld
ld
.a
ld(1)
通常,只按命令行中指定的顺序搜索存档一次。
您可以尝试更改hal和bsp档案的顺序( -lstm32f4_bsp ... -lstm32f4_hal ),但如果它也失败了,那么你就有了循环依赖。您可以在链接命令中多次提及库( -lstm32f4_bsp ... -lstm32f4_hal -lstm32f4_bsp ),或只是指示链接器迭代档案子列表 -( 和 -) 要么 --start-group 和 --end-group 链接器选项 ,正如人和人所描述的那样 https://stackoverflow.com/a/5651895/196561 。应该在具有循环依赖关系的库周围放置选项: --start-group -lstm32f4_bsp ... -lstm32f4_hal --end-group
-lstm32f4_bsp ... -lstm32f4_hal
-lstm32f4_bsp ... -lstm32f4_hal -lstm32f4_bsp
-(
-)
--start-group
--end-group
--start-group -lstm32f4_bsp ... -lstm32f4_hal --end-group
完整的选项描述 ld的手册页
-( archives -) --start-group archives --end-group 存档应该是存档文件列表。它们可以是显式文件名,也可以是 -l 选项。 将重复搜索指定的归档,直到未创建新的未定义引用。通常,只按命令行中指定的顺序搜索存档一次。如果需要该存档中的符号来解析稍后在命令行中显示的存档中的对象引用的未定义符号,则链接器将无法解析该引用。通过对存档进行分组,可以反复搜索所有存档,直到解决所有可能的引用。 使用此选项会产生显着的性能成本。最好只在两个或多个档案之间存在不可避免的循环引用时才使用它。
-( archives -) --start-group archives --end-group
-( archives -)
--start-group archives --end-group
存档应该是存档文件列表。它们可以是显式文件名,也可以是 -l 选项。
-l
将重复搜索指定的归档,直到未创建新的未定义引用。通常,只按命令行中指定的顺序搜索存档一次。如果需要该存档中的符号来解析稍后在命令行中显示的存档中的对象引用的未定义符号,则链接器将无法解析该引用。通过对存档进行分组,可以反复搜索所有存档,直到解决所有可能的引用。
使用此选项会产生显着的性能成本。最好只在两个或多个档案之间存在不可避免的循环引用时才使用它。
使用gcc调用链接器时,请使用 -Wl, 如果你的gcc不能识别它们,则将选项传递给链接器的前缀: -Wl,--start-group -lstm32f4_bsp ... -lstm32f4_hal -Wl,--end-group
-Wl,
-Wl,--start-group -lstm32f4_bsp ... -lstm32f4_hal -Wl,--end-group
当您使用shell / make时,您可能需要引用 ( 和 ) 在简短的选项变体中,例如使用单引号: '-Wl,-(' -lstm32f4_bsp ... -lstm32f4_hal '-Wl,-)'
(
)
'-Wl,-(' -lstm32f4_bsp ... -lstm32f4_hal '-Wl,-)'