Кросс-компиляция 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")

person ejoerns    schedule 10.07.2012    source источник
comment
Спасибо! У меня была именно эта проблема.   -  person DouglasHeriot    schedule 01.07.2016


Ответы (2)


Я нашел временное решение, заменив строку

SET(CMAKE_C_FLAGS "-std=gnu99")

by

SET(CMAKE_C_FLAGS "-std=gnu99" CACHE STRING "" FORCE)
person ejoerns    schedule 18.07.2012
comment
Работает, спасибо (строчку добавил сразу после инструкции по проекту) - person Thomas K; 09.09.2014
comment
Это спасло мне вечер. - person Albin Stigo; 22.12.2018

Я просто хотел добавить некоторую справочную информацию (обсуждается, например, здесь, как настроить cmake_c / xx_flags на цепочку инструментов?).

Короче говоря, переменные CMAKE_<LANG>_FLAGS кэшируются в сценариях CMake<Lang>Information.cmake (это означает, что вы можете изменить их в приложении CMake с графическим интерфейсом после этапа настройки).

Поэтому вам нужно - если вы устанавливаете их в файле 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 не будут распознаваться (кеш не будет перезаписан, см. Выше).

С учетом всего этого ваше временное решение - правильный выбор. Чтобы быть действительно уверенным - поскольку файл Toolchain анализируется дважды во время процесса настройки / генерации, вы даже можете добавить вызов UNSET перед установкой CMAKE_C_FLAGS в файле toolchain:

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("$<$<CONFIG:RELASE>:-std=gnu99>")
add_compile_options("$<$<CONFIG:DEBUG>:-std=gnu99 -g3>")

См. Каков современный метод настройки общие флаги компиляции в CMake? и выражение генератора CMake, различать код C / C ++, чтобы узнать об этом подробнее.

person Florian    schedule 13.05.2015