我有一个使用 main.c 和 CMakeLists.txt 设置的基本程序。它们包含以下内容:
/* CMakeLists.txt */
cmake_minumum_required(VERSION 3.1)
project(cmake-test)
add_executable(${PROJECT_NAME} main.c)
set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD 90)
set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD_REQUIRED ON)
/* main.c */
#include <stdio.h>
// Erroneous comment for C90
int main(){
for(int i = 0; i < 10; i++)
printf("%d\n", i);
return 0;
}
当我运行 cmake 然后 make 时,我收到
int i
内联声明的错误,但 C99 样式注释没有错误。当我修复此错误以在上一行声明 i
时,不再有错误或警告,并且构建顺利完成。除非指定了 C99 或更高版本,否则不应允许这些 //
注释,并且如果未捕获此代码将在 C89 或 C90 编译器上失败。事实上,当使用 -ansi
、-std=c89
或 -std=c90
选项手动运行 GCC 时,它确实会失败。
我知道可以直接在 CMakeLists.txt 中设置 GCC 选项,但这当然会破坏与非 GNU 系统的交叉兼容性,因此在某种程度上违背了使用 CMake 的目的。
如果这个问题没有单一的交叉兼容解决方案,那么如何检查 CMake 可能产生输出的所有相关编译器并适当地设置它们的选项?
编辑:答案已关闭,给出的答案不清楚,并给出了一些与行话混合的无用建议。只需将以下行添加到我的 CMake 即可解决我的问题:
set_property(TARGET ${PROJECT_NAME} PROPERTY C_EXTENSIONS OFF)
如果其他人在使用 CMake 时尝试强制 ANSI C/C89/C90 时遇到同样的问题。
除非 C99,否则不应允许这些 // 注释
允许编译器扩展。没有指定 C99“不允许”
//
注释,而是没有定义它们在源文件中时会发生什么。
如果你想让 CMake 编译时不带扩展,请使用 https://cmake.org/cmake/help/latest/prop_tgt/C_EXTENSIONS.html .
是否可以在 CMake 中强制使用 C90 并让编译器以交叉兼容的方式捕获 C99 样式注释的错误?
编写您自己的交叉兼容 linter 来执行此操作,例如使用 CMake 语言,因为您无论如何都在使用 CMake。
如何检查 CMake 可能生成输出的所有相关编译器并适当设置其选项?
一个没有。采取反应性行动。只需处理您认为相关的当前相关编译器即可。当有人要为不同的编译器进行编译时,您或他将为该编译器移植您的 CMakeLists.txt。有些选项已由 CMake 处理,也有一些情况未由 CMake 一般处理。
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
add_compile_option(-pedantic)
else()
message(WARNING "Untested compiler. Contact me for more info")
endif()