【发布时间】:2018-09-18 01:24:21
【问题描述】:
我有 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)
我想这就是 CMake 使用 -isystem 选项而不是使用 -I 自动生成 Make 文件的原因。因为在我的 CMake 配置中,我使用 find_package() 命令链接库,所以 CMake 将其解释为供应商提供的系统?!
这个项目与 clang(也使用 -isystem)配合得很好。我的问题是 avr-g++。
在使用 avr-g++ 的 -isystem 之前有人遇到过问题吗?是否可以强制 CMake 使用 -I?谢谢!!
【问题讨论】:
-
我不太确定你的问题是什么。
-I和-isystem做不同的事情。所以……他们做的事情是不同的。有关的。但不一样。大多数第 3 方库都应该使用-I,除了少数伪装成其他类型的库(我在看着你,Boost)。 -
也许你曾经在
extern "C"块中包含了标题,然后你又在这样的块之外包含了它。没有minimal reproducible example,很难判断你做错了什么。确保不要在extern "C"块中包含标题,并将#pragma once放在标题顶部以确保它只包含一次。 -
感谢您的回答。我更新了我的问题以便更好地解释我的问题。