我有3个CMake项目:myapp-avr(对于AVR是可执行的),myapp-unix(对于Unix是可执行的)和my_lib(由可执行文件导入的c ++静态库)。当我编译MyLib项目时,我一点都没有问题。我还可以成功编译myapp-avr和myapp-unix项目。但是,链接我的app-avr时出现错误,例如“未定义的引用”。
我将示例上传到GitHub:https://github.com/cajomferro/basic-cmake。我的CMake结构基于Pablo Ariasal示例项目:https://github.com/pabloariasal/modern-cmake-sample。
我现在知道问题与-isystem选项有关。相同的确切命令怎么能与-I选项一起使用而不与-isystem选项一起使用(这是用于导入/供应商库的命令)?
不起作用:(由CMake自动生成)
/ usr / local / CrossPack-AVR / bin / avr-g ++ -DARDUINO = 10805 -DF_CPU = 16000000L- isystem mylib / include -Os -g -w -fpermissive -fno -exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto -mmcu = atmega328p -std = gnu ++ 11 -o src / main.cpp.obj -c src / main.cpp
作品:
/ usr / local / CrossPack-AVR / bin / avr-g ++ -DARDUINO = 10805 -DF_CPU = 16000000L- I mylib / include -Os -g -w -fpermissive -fno -exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto -mmcu = atmega328p -std = gnu ++ 11 -o src / main.cpp.obj -c src / main.cpp
根据avr-g ++手册,-isystem表示:在-I指定的所有目录之后但在标准系统目录之前,搜索头文件的目录。将其标记为系统目录,以便对其进行与标准系统目录相同的特殊处理
此外,在阅读有关-I选项时,avr-g ++表示:您不应使用此选项来添加包含供应商提供的系统头文件的目录(为此使用-isystem) < / p>
我想这就是CMake使用 -isystem 选项而不是使用 -I 自动生成Make文件的原因。因为在我的CMake配置中,我使用find_package()命令链接库,所以CMake会将其解释为供应商提供的系统?!
该项目与clang(也使用-isystem)一起正常工作。我的问题是avr-g ++。
在使用avr-g ++的 -isystem 之前,有人遇到过问题吗?是否可以强制CMake使用 -I ?谢谢!!
答案 0 :(得分:0)
问题解决了!根据{{3}},显然-isystem在GNU编译器上具有不同的行为:
在非常老的系统上,一些预定义的系统头目录 得到更多特殊待遇。 GNU C ++在标头中考虑代码 在这些目录中被一个外部的“ C”块包围。
这些人有类似的问题:https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html。
因此,为了避免造成混乱,只需通知CMake使用-I即可。需要简单的一行:NO_SYSTEM_FROM_IMPORTED ON(https://github.com/conan-io/conan/issues/269)。
一个例子是:
set_target_properties(my_target
PROPERTIES
NO_SYSTEM_FROM_IMPORTED ON
)
在myapp-avr可执行文件https://cmake.org/cmake/help/latest/prop_tgt/NO_SYSTEM_FROM_IMPORTED.html的CMakeLists.txt中找到了完整的示例。