当前位置:首页 » 编程软件 » vscode怎样预编译

vscode怎样预编译

发布时间: 2025-08-25 00:48:29

㈠ 5分钟掌握cmake(19): 使用 SYSTEM 关键字忽略三方库头文件的编译警告

1年前,@大缺弦 在 CMake 官方仓库中为 add_subdirectory() 增加了 SYSTEM 关键字 (FetchContent_Declare 也加了, 不过我还没用过这个函数), 并在 CMake 3.25 版本中正式发布。 本文提供一个简单的例子, 展示个人对 add_subdirectory(xxx SYSTEM) 的理解。

2. 复现工程代码

2.1 目录结构

有如下的目录结构:在自己的工程example 下, 引入了第三方的工程 hello: 可以是完全基于源代码的三方工程, 也可以是头文件 + 库文件的形式, 异或是 header-only 的三方库。 即:

hello 子目录是别人工程的源码:

或如下的目录结构: hello 子目录是头文件 + 预编译好的库 + CMakeLists.txt:

或者 header-only 形式:

无论是哪种形式,hello/hello.h 这一头文件, 都会被自己的源代码 test_hello.cpp 包含, 从而参与到 example 工程的构建中。 而 example 工程可能使用了和 hello 不同的 "treat warning as errors" 设定, 会导致 hello.h 在 hello 工程中不会编译报错, 但在 example 工程中就会报错了。

我们的预期是:hello.h 在参与到 example/test_hello.cpp 的预处理过程时, 不要使用 example/CMakeLists.txt 里的严格的编译报错设定, 放宽它的编译报错等级; 同时保持 test_hello.cpp 自身的 cpp 代码, 仍然是被严格处理的。

2.2 头文件 hello.h 内容

2.3 test_hello.cpp 内容

2.4 根目录 CMakeLists.txt 内容

2.5 完整工程

github.com/zchrissirhcz...

3. Linux下的运行结果和分析

3.1 运行结果: 使用 SYSTEM 后, 头文件 hello/hello.h 不再触发编译报错

3.2 检查 compile_commands.json 里的具体编译命令, -I 被 -isystem 替代

3.3 -I 和 -isystem 的区别是什么? man gcc 可以知道, 被 -isystem 指定的目录, 会被当作标准系统目录对待:

而人们提到的

-isystem

会忽略自行在 makefile/CMakeLists.txt 中指定的 warning, 可以在 gcc 在线文档中找到:

3.4include_directories() 和 target_include_directories() 也可以用 SYSTEM 在 How to suppress GCC warnings from library headers? 问答中, 有人提到可以在 include_directories() 中指定 SYSTEM 关键字来抑制编译警告:

查看文档得到验证:

实际上,

target_include_directories()

也可以用

SYSTEM

关键字, 也是生成

-isystem

的编译命令:

查看 compile_commands.json 验证:

4. 使用 -isystem 的进一步探讨

4.1 -Wsystem-headers 开启 system headers 的 warning man gcc 可以知道, 提供的 -Wsystem-headers 编译选项, 是把 system headers 里的警告开启, 也就是说当你用 -isystem 指定了一个三方库路径后, 如果想开启它里面的 warning, 可以用 -I 替代 -isystem 来开启 warning, 也可以用 -Wsystem-headers 来开启 warning:

4.2 使用 -fsystem-headers 的提议 (尚未实现)

在 Bug 93506 - Create hybrid of -I and -isystem that is like -I but deactivates warnings 中有人提到, 人们使用 -isystem /some/path 替代 -I /some/path, 有点滥用系统头文件路径的问题, 考虑让 gcc 增加 -fsystem-headers 参数, 进而使用:

来让/some/path 被搜索时忽略警告。 不过这个 feature 尚未实现。

5. MSVC 下的结果

MSVC 使用/I, 和 GCC 的 -I 对应; MSVC 使用 /externel:W0, 和 GCC 里的 -isystem 对应。

作为实验, 先前-Werror=shadow 的写法, 在 MSVC 下要更换为:

6. 总结

CMake 中, 有如下几个命令, 都可以使用SYSTEM 关键字, 使得被添加的头文件搜索目录中, 头文件里的 warning 完全被编译器忽略:

上述这些 cmake 命令, 是映射-I dir 为 -isystem dir, 根据 GCC 文档, -isystem 指定的 dir 被当作标准系统头文件目录:

由于编译器本身忽略了-isystem 指定目录中的警告, 那么开发者在 CMakeLists.txt 里指定的 treat warnings as errors 的设定, 由于没捕获到这些目录里的 waring, 因而不会触发编译报错。 这是一种避免陷入修改第三方库头文件源码的方法, 它仅对于头文件有效, 对于 add_subdirectories() 引入的源代码文件 (.c/.cpp) 不起作用。

在 GCC 和 MSVC 下,SYSTEM 关键字都起作用。

7. References

本文使用 Zhihu On VSCode 创作并发布

热点内容
asp班级源码 发布:2025-08-25 04:28:06 浏览:502
python连接redis集群 发布:2025-08-25 03:52:28 浏览:859
易语言邮箱在云服务器上 发布:2025-08-25 03:18:56 浏览:531
一刀辅助脚本 发布:2025-08-25 03:13:53 浏览:28
彩虹源码对接 发布:2025-08-25 02:12:19 浏览:902
sql字段包含某字段 发布:2025-08-25 02:04:09 浏览:377
百度网盘在线解压 发布:2025-08-25 01:48:24 浏览:731
java反射数组 发布:2025-08-25 01:33:03 浏览:566
如何连接sqlserver 发布:2025-08-25 01:21:28 浏览:393
JAVA拳皇 发布:2025-08-25 01:16:34 浏览:716