我正在使用CMake配置C项目的可移植编译,我想检查所使用的编译器是否支持我愿意使用的各种编译标志。
假设我有一个使用非初始化变量的简单C文件noinit.c
:
#include <stdio.h>
int main(void)
{
int i; // Uninitialized
printf("%d\n", i+2);
return 0;
}
我想编译器引发错误,所以我使用了标志-Wall -Werror
。这是我的CMakeLists.txt
文件:
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
project(cmake_compiler_flag_test C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
include(CheckCCompilerFlag)
list(APPEND COMPILER_FLAGS_TO_USE "-Wall" "-Werror")
foreach (FLAG IN LISTS COMPILER_FLAGS_TO_USE)
# Check if the compiler supports the flag. The result of this test
# is printed to STDOUT when calling `cmake`.
check_c_compiler_flag(${FLAG} COMPILER_SUPPORTS_${FLAG})
# Regardless of the test, force the usage of the flag anyway.
string(APPEND CMAKE_C_FLAGS " ${FLAG}")
endforeach()
add_executable(noinit noinit.c)
当我打电话给CMake时,它说我的编译器不支持-Werror
。
> mkdir build
> cd build
> cmake ..
-- The C compiler identification is AppleClang 9.1.0.9020039
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Performing Test COMPILER_SUPPORTS_-Wall
-- Performing Test COMPILER_SUPPORTS_-Wall - Success
-- Performing Test COMPILER_SUPPORTS_-Werror
-- Performing Test COMPILER_SUPPORTS_-Werror - Failed # <-- NOTICE THE FAIL HERE!
-- Configuring done
-- Generating done
-- Build files have been written to: /some/path/to/cmake_compiler_flag_test/build
但是当我调用编译器(支持标志)时,它实际上按预期工作并引发有关未初始化变量的错误:
> make
[ 50%] Building C object CMakeFiles/noinit.dir/noinit.c.o
/some/path/to/cmake_compiler_flag_test/noinit.c:5:20: error: variable 'i' is
uninitialized when used here [-Werror,-Wuninitialized]
printf("%d\n", i+2);
^
/some/path/to/cmake_compiler_flag_test/noinit.c:4:10: note: initialize the
variable 'i' to silence this warning
int i; // Uninitialized
^
= 0
1 error generated.
make[2]: *** [CMakeFiles/noinit.dir/noinit.c.o] Error 1
make[1]: *** [CMakeFiles/noinit.dir/all] Error 2
make: *** [all] Error 2
我在CMake配置中做错了什么或者这是一个CMake错误?
用于此测试的工具及其版本:
答案 0 :(得分:1)
CMakeFiles/CMakeError.log
有点暗示:
In file included from <built-in>:341:
<command line>:1:27: error: ISO C99 requires whitespace after
the macro name [-Werror,-Wc99-extensions]
#define COMPILER_SUPPORTS_-Werror 1
1 error generated.
您的变量名称创建(COMPILER_SUPPORTS_${FLAG}
)似乎失败,因为名称中有连字符-
。您需要在添加之前从${FLAG}
中删除该连字符,或者找到其他方法。
根据您自己的建议,您可以添加
行string(REPLACE "-" "" FLAG_NO_HYPHEN ${FLAG})
在编译器标志测试之前,然后使用
check_c_compiler_flag(${FLAG} COMPILER_SUPPORTS_${FLAG_NO_HYPHEN})
代替。
对我来说真正奇怪的是-Wall
似乎成功了,这可能会让你失望(如果两者都失败了,CMakeLists.txt
中有一些问题就更明显了。)
反转顶部附近的list(...)
中的两个标志字符串的顺序实际上会导致两个测试都失败。
CMakeFiles/CMakeOutput.log
显示
In file included from <built-in>:341:
<command line>:1:27: warning: ISO C99 requires whitespace after the
macro name [-Wc99-extensions]
#define COMPILER_SUPPORTS_-Wall 1
1 warning generated.
在这里,它只是一个警告,但顺序相反,两个测试都会出错。
也许有人知道为什么会这样,并且可以评论它。或者它只是CMake中的一个错误。