-I和-isystem编译时的行为不同

时间:2018-09-18 01:24:22

标签: c++ cmake avr

我有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 ?谢谢!!

1 个答案:

答案 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中找到了完整的示例。