我们目前正在开发一个无法使用 C++ 异常的嵌入式系统,因此在编译器/链接器设置中禁用了它们的支持。在此项目中,我们遇到一个构造的 IAR 链接器错误,如下面的简化示例所示:
代码:
struct Bla
{
Bla():blup{3u}{}
uint8_t blup;
};
template<typename T, size_t N>
struct Warp
{
T bla[N];
};
int32_t main()
{
Warp<Bla,2> bla{};
return 0;
}
留言:
IAR ELF Linker V9.30.1.335/W64 for ARM
Copyright 2007-2022 IAR Systems AB.
Error[Li009]: runtime model conflict: Module iar_Raise.o(dlpprt6M_tl_nc.a)
specifies that '__CPP_Exceptions' must be 'Used', but module main.o
has the value 'Disabled'
如果没有定义自定义构造函数,或者显式默认它,或者它只有一个空主体,则不会立即显示该错误。为什么我们会看到这个错误以及如何消除它?我们无法弄清楚这段代码哪里需要异常处理。
编辑:
我们已经进一步追踪了错误的根源。正如 @Clifford 在评论中提到的,解决方案似乎与 iar_Raise.o 链接到 main.o 的原因有关。我们检查了构建标志中的一些更改,并通过从链接库中删除
dlpprt6M_tl_nc.a
并同时删除标志 --no_library_search
来消除错误。因此,通过此更改,链接器可以自由选择库存档来获取它所需的对象(在我们项目的上下文中,这不是我们想要的)。事实证明,该库所需的唯一对象是 cxxabi.o 而不是 iar_Raise.o,如映射文件中所示:
dlpprt6M_tl_nc.a: [40]
cxxabi.o 38
为了确保我们指定的文件不会以某种方式不兼容,我们手动指定了链接器选择的相同存档文件。即使这样,链接也会失败并出现相同的错误。
使错误消失的另一种方法是在编译器的调用中不使用
--no_exceptions
标志,而仅在链接器中使用。然而,这对我来说没有任何意义,而且还增加了二进制文件的大小。
我们还有许多其他自定义编译器和链接器设置。为了使我们项目的构建过程可重现,以下是导致上述错误的构建调用:
Compiling ../../../application/source/Startup/startup_stm32g071xx.s ...
'C:\Program Files\IAR Systems\Embedded Workbench 9.1\arm'/bin/iasmarm ../../../application/source/Startup/startup_stm32g071xx.s -o ../../../target/build/obj/Startup/startup_stm32g071xx.o -r --cpu Cortex-M0+ -E42 --fpu=none -g -M'<>'
Compiling ../../../application/source/main.cpp ...
'C:\Program Files\IAR Systems\Embedded Workbench 9.1\arm'/bin/iccarm --debug -DDEBUG_BUILD --align_sp_on_irq --char_is_unsigned --cpu=Cortex-M0+ -DSTM32G071xx -DUSE_FULL_LL_DRIVER --dlib_config 'C:\Program Files\IAR Systems\Embedded Workbench 9.1\arm'/inc/c/DLib_Config_Normal.h -e --error_limit 42 --fpu=none --no_system_include --nonportable_path_warnings -Oh --only_stdout --require_prototypes --c++ --no_exceptions --no_rtti --no_static_destruction --pending_instantiations 256 -I"../../../application/source" -I'C:\Program Files\IAR Systems\Embedded Workbench 9.1\arm'/inc -I'C:\Program Files\IAR Systems\Embedded Workbench 9.1\arm'/inc/c -I'C:\Program Files\IAR Systems\Embedded Workbench 9.1\arm'/inc/c/aarch32 -I'C:\Program Files\IAR Systems\Embedded Workbench 9.1\arm'/inc/cpp -c ../../../application/source/main.cpp -o ../../../target/build/obj/main.o --dependencies=m ../../../target/build/dep/main.d
Linking ...
'C:\Program Files\IAR Systems\Embedded Workbench 9.1\arm'/bin/ilinkarm --no_library_search --config CNT_stm32g071xB.icf --cpu=Cortex-M0+ --entry __iar_program_start --entry_list_in_address_order --error_limit 42 --extra_init __iar_cstart_call_ctors --fpu=none --log call_graph,libraries,sections,unused_fragments --no_exceptions --no_free_heap --only_stdout --remarks --semihosting --vfe ../../../target/build/obj/main.o ../../../target/build/obj/Startup/startup_stm32g071xx.o -o ../../../target/output/demo.elf --map ../../../target/output/demo.map --call_graph ../../../target/output/demo.cgx --export_builtin_config ../../../target/output/demo.icf --log_file ../../../target/output/demo.llog 'C:\Program Files\IAR Systems\Embedded Workbench 9.1\arm'/lib/rt6M_tl.a 'C:\Program Files\IAR Systems\Embedded Workbench 9.1\arm'/lib/dlpprt6M_tl_nc.a 'C:\Program Files\IAR Systems\Embedded Workbench 9.1\arm'/lib/dl6M_tln.a
我们仍在努力实现的是使用特定档案来构建我们的项目。非常感谢任何有关我们如何实现这一目标的提示。
目前,我们已收到 IAR 代表我们问题的答复。他们建议使用 --log 库链接器选项以及启用的自动库选择来确定在库搜索中执行的重定向步骤。
之后,可以查看链接器日志文件的以下部分:
### Library selection:
### Library configuration:
这显示了自动完成的“全局重定向”。这些重定向可能与异常相关。如果没有这些重定向,就会生成 Li009。然后可以在手动选择中使用自动选择的库,以确保库选择的再现。