Подтвердить что ты не робот

Кросс-компиляция CMake: флаги C из файла toolchain игнорируются

Я использую cmake для кросс-компиляции. В моем файле toolchain есть строка

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?

EDIT: добавлено 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")
4b9b3361

Ответ 1

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

SET(CMAKE_C_FLAGS "-std=gnu99")

по

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

Ответ 2

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

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

Итак, вы должны - если установить их в файле Toolchain - сначала поместите их в кеш. Свойство CMake script (выполняется после файла 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 анализируется дважды во время процесса Configuration/Generation - вы даже можете добавить вызов UNSET перед установкой CMAKE_C_FLAGS в файл инструментальной цепочки:

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

Другое часто найденное решение - использовать что-то вроде:

add_definitions(" -std=gnu99")

для ввода флагов компиляции (но это не значит, что конфигурация не поддерживается, поскольку определения переменных). См. Также CMake clang и С++ 0x

С CMake 2.8.12 были введены новые команды, поэтому вы могли бы (не тестировали, просто чтобы показать возможности):

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

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