CMake 指示编译器不支持标志,但它支持
CMake indicates compiler does not support flag but it does
我正在使用 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 错误?
本次测试使用的工具及其版本:
- macOS 10.13.4
- CMake 3.11.2
- 经过测试的编译器(都显示相同的问题):
- Apple LLVM 版本 9.1.0 (clang-902.0.39.1)
- gcc-8(自制 GCC 8.1.0)8.1.0
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 中的一个错误。
我正在使用 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 错误?
本次测试使用的工具及其版本:
- macOS 10.13.4
- CMake 3.11.2
- 经过测试的编译器(都显示相同的问题):
- Apple LLVM 版本 9.1.0 (clang-902.0.39.1)
- gcc-8(自制 GCC 8.1.0)8.1.0
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 中的一个错误。