I've been searching a portable way to force CMake to enable the compiler's C99 features in order to avoid the following gcc
error for instance:
error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int s = 1; s <= in_para->StepNumber; s++){
^
I also wouldn't like to check for which compiler and append something like:
set(CMAKE_C_FLAGS "-std=c99") # that would be bad
So I found this post: Enabling C99 in CMake and the associated feature request: 0012300: CMake has no cross-platform way to ask for C99 . In this Mantis bug I learned about target_compiler_features
and after that I found these SOF answers on it: How to activate C++11 in CMake? and How to detect C++11 support of a compiler with CMake .
So my questions are: this target_compiler_features
will provide a way to require a C feature as well as a C++ one? What is the most portable way to achive this by now - I'm currently using CMake 2.8.12.2. The target_compiler_features
isn't in CMake's most recent release version (3.0.0). Do you know when it is being released?
After creating a target such as a library or executable, put a line like this in your CMakeLists.txt file:
set_property(TARGET tgt PROPERTY C_STANDARD 99)
where tgt
is the name of your target.
I think this was added in CMake 3.1, and the documentation is here:
http://www.cmake.org/cmake/help/v3.1/prop_tgt/C_STANDARD.html
If you need to support versions of CMake older than 3.1, you can use this macro:
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)
After putting that macro in your top-level file so it is visible everywhere, you can just write use_c99()
at the top of any CMakeLists file that defines a target with C99 code in it.
If you are using CMake and clang to target MacOS there is a bug that can cause the CMAKE_C_STANDARD
feature to simply not work (not add any compiler flags). Make sure that you do one of the following things:
Set policy CMP0025 to NEW with the following code at the top of your CMakeLists.txt file before the project
command:
# Fix behavior of CMAKE_C_STANDARD when targeting macOS. if (POLICY CMP0025) cmake_policy(SET CMP0025 NEW) endif ()
As this question keeps getting attention I'm summarizing here what I think are the best options today.
The following command sets C99 as a minimum requirement for target
:
target_compile_features(target PUBLIC c_std_99)
I consider this the preferred way, as it is per target and exposes a way to control the visibility through the PUBLIC
, INTERFACE
and PRIVATE
keywords - see the reference . Although the target_compile_features
command was introduced on the 3.1 version, c_std_99
requires at least CMake 3.8 .
Similar to the above, another way to set C99 as the standard for target
is the following:
set_property(TARGET target PROPERTY C_STANDARD 99)
This is available since CMake 3.1. A possible drawback is that it doesn't enforce the standard (see the reference ). For this reason setting the C_STANDARD_REQUIRED
property may be useful:
set_property(TARGET target PROPERTY C_STANDARD_REQUIRED ON)
The above two properties are defaulted to the values of CMAKE_C_STANDARD
and CMAKE_C_STANDARD_REQUIRED
respectively.
So a possible way to make C99 default for all targets is:
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED TRUE)
As a side note, expanding on the target_compile_features
approach, there may be no need to require some specific language standard if all you care about is some specific feature. For instance by setting:
target_compile_features(target PUBLIC c_variadic_macros)
CMake will take care to pick the proper flags that enforce the availability of variadic macros. However currently there are only a few such features available for the C language - see CMAKE_C_KNOWN_FEATURES for the complete list - and loop initial declarations is not among them.
在 libevent 中,在 CMakeLists.txt 中添加以下内容
set (CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")
Edit CMakeLists
add on line > 2
set (CMAKE_C_STANDARD 99)
then
cmake 3 ..
The C_STANDARD property will allow use to apply the C standard to a specific target, rather than globally. The following will apply C99 to mytarget
.
set_property(TARGET mytarget PROPERTY C_STANDARD 99)
将以下内容添加到 CMakeLists.txt 文件并再次运行 cmake
set(CMAKE_C_FLAGS "std=c99")
From CMake 3.0.2, it is possible to use add_compile_options ( https://cmake.org/cmake/help/latest/command/add_compile_options.html#command:add_compile_options ), it is one of the most portable way I found to set C standart.
Take care to use this command before to declare target (with add_library or add_executable).
Below is a CMake script example setting C standart to C99:
add_compile_options(-std=c99)
add_executable(my_exe ${SOURCES})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.