我使用cmake进行交叉编译。在我的工具链文件中有一行
SET(CMAKE_C_FLAGS "-std=gnu99")
此变量未再次在CMakeLists.txt中设置。
当我运行cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake ..
时,将忽略此标志。
更详细:flags.cmake
行显示空C_FLAGS =
行。
但是在CMakeOutput.log
我可以找到一行Build flags: -std=gnu99
。
我发现第二次运行cmake ..
(指定或不指定工具链文件)可以解决此问题。
但是为什么我第一次运行cmake时没设置?
编辑:添加了MNWE
的CMakeLists.txt:
cmake_minimum_required(VERSION 2.6)
project(myproject)
SET(files src/main.c)
add_executable(myexec ${files})
avr.cmake:
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_C_COMPILER avr-gcc)
SET(CMAKE_C_FLAGS "-std=gnu99")
答案 0 :(得分:18)
我通过替换
找到了临时解决方案SET(CMAKE_C_FLAGS "-std=gnu99")
通过
SET(CMAKE_C_FLAGS "-std=gnu99" CACHE STRING "" FORCE)
答案 1 :(得分:11)
我只是想添加一些背景信息(例如这里讨论how to setup cmake_c/xx_flags per toolchain?)。
简而言之,CMAKE_<LANG>_FLAGS
变量在CMake<Lang>Information.cmake
脚本中被设计缓存(这意味着您可以在配置步骤后在CMake的GUI应用程序中更改它们)。
所以你必须 - 如果在Toolchain文件中设置它们 - 首先将它们放入缓存中。 CMake自己的脚本(在Toolchain文件之后执行)没有FORCE
,所以它不会再次覆盖它。
查看CMakeCInformation.cmake(来自share \ cmake-2.8 \ Modules):
set(CMAKE_C_FLAGS_INIT "$ENV{CFLAGS} ${CMAKE_C_FLAGS_INIT}")
# avoid just having a space as the initial value for the cache
if(CMAKE_C_FLAGS_INIT STREQUAL " ")
set(CMAKE_C_FLAGS_INIT)
endif()
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS_INIT}" CACHE STRING
"Flags used by the compiler during all build types.")
如您所见,正式的方法是使用CMAKE_C_FLAGS_INIT
注入额外的标志。问题在于,工具链文件中的后续更改将无法识别(缓存不会被覆盖,请参见上文)。
考虑到所有这些因素,您的临时解决方案是正确的选择。要确定 - 因为工具链文件在配置/生成过程中被解析了两次 - 您甚至可以在工具链文件中设置UNSET
之前添加CMAKE_C_FLAGS
调用:
UNSET(CMAKE_C_FLAGS CACHE)
SET(CMAKE_C_FLAGS "-std=gnu99" CACHE STRING "" FORCE)
另一个经常找到的解决方案是使用类似的东西:
add_definitions(" -std=gnu99")
注入编译标志(但这不是构建配置,因为变量定义是)。另请参阅CMake clang and c++0x
使用CMake 2.8.12引入了新命令,所以你可以做(没有测试,只是为了展示可能性):
add_compile_options("$<$<CONFIG:RELASE>:-std=gnu99>")
add_compile_options("$<$<CONFIG:DEBUG>:-std=gnu99 -g3>")
有关详情,请参阅What is the modern method for setting general compile flags in CMake?和CMake generator expression, differentiate C / C++ code。