CMake交叉编译:忽略工具链文件中的C标志

我使用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") 

我通过更换线找到了一个临时解决方案

 SET(CMAKE_C_FLAGS "-std=gnu99") 

通过

 SET(CMAKE_C_FLAGS "-std=gnu99" CACHE STRING "" FORCE) 

我只是想添加一些背景信息(例如在这里讨论如何为每个工具链设置cmake_c / xx_flags? )。

简而言之, CMAKE__FLAGS变量在CMakeInformation.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注入其他标志。 问题在于,工具链文件中的后续更改将无法识别(缓存不会被覆盖,请参见上文)。

考虑到所有这些因素,您的临时解决方案是正确的选择。 要确定 – 因为在配置/生成过程中解析了两次Toolchain文件 – 您甚至可以在工具链文件中设置CMAKE_C_FLAGS之前添加UNSET调用:

 UNSET(CMAKE_C_FLAGS CACHE) SET(CMAKE_C_FLAGS "-std=gnu99" CACHE STRING "" FORCE) 

另一个经常找到的解决方案是使用类似:

 add_definitions(" -std=gnu99") 

注入编译标志(但这不是构建配置,因为变量定义是)。 另请参阅CMake clang和c ++ 0x

使用CMake 2.8.12,引入了新的命令,所以你可以做(​​没有测试,只是为了显示可能性):

 add_compile_options("$<$:-std=gnu99>") add_compile_options("$<$:-std=gnu99 -g3>") 

请参阅在CMake中设置常规编译标志的现代方法是什么? 和CMake生成器表达式,在此更多地区分C / C ++代码 。