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_
变量在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 ++代码 。