我一直在寻找一种可移植的方法来强制CMake启用编译器的C99功能,以避免出现以下gcc
错误:
error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int s = 1; s <= in_para->StepNumber; s++){
^
我也不想检查哪个编译器并附加类似的内容:
set(CMAKE_C_FLAGS "-std=c99") # that would be bad
所以我发现了这篇帖子:Enabling C99 in CMake以及相关的功能请求:0012300: CMake has no cross-platform way to ask for C99。在这个Mantis bug中,我了解了target_compiler_features
,之后我发现了这些SOF答案:How to activate C++11 in CMake?和How to detect C++11 support of a compiler with CMake。
所以我的问题是:这个target_compiler_features
将提供一种需要C功能和C ++功能的方法吗?现在最简单的方法是什么 - 我现在正在使用CMake 2.8.12.2。 target_compiler_features
不在CMake的最新发行版本(3.0.0)中。你知道什么时候被释放吗?
答案 0 :(得分:24)
创建目标(如库或可执行文件)后,在CMakeLists.txt文件中添加如下所示的行:
set_property(TARGET tgt PROPERTY C_STANDARD 99)
其中tgt
是目标的名称。
我认为这是在CMake 3.1中添加的,文档在这里:
http://www.cmake.org/cmake/help/v3.1/prop_tgt/C_STANDARD.html
如果您需要支持早于3.1的CMake版本,您可以使用此宏:
macro(use_c99)
if (CMAKE_VERSION VERSION_LESS "3.1")
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
set (CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")
endif ()
else ()
set (CMAKE_C_STANDARD 99)
endif ()
endmacro(use_c99)
将宏放在顶级文件中以便它随处可见后,您只需在任何CMakeLists文件的顶部写入use_c99()
,该文件定义了包含C99代码的目标。
如果您使用CMake和clang来定位MacOS,则bug会导致CMAKE_C_STANDARD
功能无法正常工作(不添加任何编译器标志)。确保您执行以下操作之一:
在project
命令之前,在CMakeLists.txt文件的顶部将策略CMP0025设置为NEW,并使用以下代码:
# Fix behavior of CMAKE_C_STANDARD when targeting macOS.
if (POLICY CMP0025)
cmake_policy(SET CMP0025 NEW)
endif ()
答案 1 :(得分:0)
编辑CMakeLists
在线添加> 2
set (CMAKE_C_STANDARD 99)
然后
cmake 3 ..
答案 2 :(得分:0)
随着这个问题越来越引起人们的关注,我在这里总结一下我认为是当今最好的选择。
以下命令将C99设置为target
的最低要求:
target_compile_features(target PUBLIC c_std_99)
我认为这是首选方法,因为它是针对每个目标的,它公开了一种通过PUBLIC
,INTERFACE
和PRIVATE
关键字控制可见性的方法-请参见the reference 。尽管target_compile_features
命令是在3.1版本上引入的,但是c_std_99
至少需要CMake 3.8。
与上述类似,将C99设置为target
的标准的另一种方法是:
set_property(TARGET target PROPERTY C_STANDARD 99)
从CMake 3.1开始可用。可能的缺点是它不执行标准(请参见the reference)。因此,设置C_STANDARD_REQUIRED
属性可能会有用:
set_property(TARGET target PROPERTY C_STANDARD_REQUIRED ON)
以上两个属性分别默认为CMAKE_C_STANDARD
和CMAKE_C_STANDARD_REQUIRED
的值。
因此使所有目标都默认使用C99的一种可能方法是:
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED TRUE)
请注意,在target_compile_features
方法上进行扩展,如果您只关心某些特定功能,则可能不需要某些特定语言标准。例如,通过设置:
target_compile_features(target PUBLIC c_variadic_macros)
CMake将注意选择适当的标志来强制可变参数宏的可用性。但是,目前只有少数此类功能可用于C语言-有关完整列表,请参见CMAKE_C_KNOWN_FEATURES-并且循环初始声明不在其中。
答案 3 :(得分:-1)
将以下内容添加到CMakeLists.txt文件并再次运行cmake
set(CMAKE_C_FLAGS "std=c99")
答案 4 :(得分:-1)
从CMake 3.0.2起,可以使用add_compile_options(https://cmake.org/cmake/help/latest/command/add_compile_options.html#command:add_compile_options),这是我发现设置C标准的最便捷的方法之一。
在声明目标(使用add_library或add_executable)之前,请务必使用此命令。
下面是一个CMake脚本示例,将C standart设置为C99:
add_compile_options(-std=c99)
add_executable(my_exe ${SOURCES})
答案 5 :(得分:-2)
在libevent中,在CMakeLists.txt中添加以下内容
set (CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")