Поиск…


Вступление

Простота основных переменных CMake противоречит сложности полного синтаксиса переменных. На этой странице представлены различные случаи с примерами и указаны недостатки, которых следует избегать.

Синтаксис

  • set (значение переменной_имя [описание типа CACHE [FORCE]])

замечания

Имена переменных зависят от регистра. Их значения имеют тип string. Значение переменной ссылается через:

${variable_name}

и оценивается внутри цитируемого аргумента

"${variable_name}/directory"

Кэшированная (глобальная) переменная

set(my_global_string "a string value"
    CACHE STRING "a description about the string variable")
set(my_global_bool TRUE
    CACHE BOOL "a description on the boolean cache entry")

Если кэшированная переменная уже определена в кеше, когда CMake обрабатывает соответствующую строку (например, когда перезагружается CMake), она не изменяется. Чтобы перезаписать по умолчанию, добавьте FORCE в качестве последнего аргумента:

set(my_global_overwritten_string "foo"
    CACHE STRING "this is overwritten each time CMake is run" FORCE)

Локальная переменная

set(my_variable "the value is a string")

По умолчанию локальная переменная определяется только в текущем каталоге и любых подкаталогах, добавленных через команду add_subdirectory .

Чтобы расширить область действия переменной, существует две возможности:

  1. CACHE , что сделает его доступным по всему миру

  2. используйте PARENT_SCOPE , который сделает его доступным в родительской области. Родительская область - это либо файл CMakeLists.txt в родительском каталоге, либо вызывающая функция текущей функции.

    Технически родительский каталог будет файлом CMakeLists.txt который включает текущий файл с помощью команды add_subdirectory .

Строки и списки

Важно знать, как CMake различает списки и простые строки. Когда вы пишете:

set(VAR "ab c")

вы создаете строку со значением "ab c" . Но когда вы пишете эту строку без кавычек:

set(VAR abc)

Вместо этого вы создаете список из трех элементов: "a" , "b" и "c" .

Переменные не списка также являются списками (одного элемента).

Списки могут управляться командой list() , которая позволяет объединять списки, искать их, получать доступ к произвольным элементам и т. Д. ( Документация по списку () ).

Немного запутанный, список также является строкой . Линия

set(VAR abc)

эквивалентно

set(VAR "a;b;c")

Поэтому, чтобы объединить списки, вы также можете использовать команду set() :

set(NEW_LIST "${OLD_LIST1};${OLD_LIST2})"

Переменные и глобальный кеш переменных

В основном вы будете использовать «обычные переменные» :

set(VAR TRUE)
set(VAR "main.cpp")
set(VAR1 ${VAR2})

Но CMake также знает глобальные «кэшированные переменные» (сохраняется в CMakeCache.txt ). И если в текущей области существуют обычные и кешированные переменные с тем же именем, обычные переменные скрывают кэшированные:

cmake_minimum_required(VERSION 2.4)
project(VariablesTest)

set(VAR "CACHED-init" CACHE STRING "A test")
message("VAR = ${VAR}")

set(VAR "NORMAL")
message("VAR = ${VAR}")

set(VAR "CACHED" CACHE STRING "A test" FORCE)
message("VAR = ${VAR}")

Выход первого запуска

VAR = CACHED-init
VAR = NORMAL
VAR = CACHED

Выход второго запуска

VAR = CACHED
VAR = NORMAL
VAR = CACHED

Примечание. Параметр FORCE также отменяет / удаляет нормальную переменную из текущей области.

Использовать случаи для кэшированных переменных

Обычно используются два случая использования (пожалуйста, не используйте их для глобальных переменных):

  1. Значение вашего кода должно быть модифицировано у пользователя вашего проекта, например, с помощью cmakegui , ccmake или с помощью cmake -D ... :

    CMakeLists.txt / MyToolchain.cmake

    set(LIB_A_PATH "/some/default/path" CACHE PATH "Path to lib A")
    

    Командная строка

    $ cmake -D LIB_A_PATH:PATH="/some/other/path" ..
    

    Это предопределяет это значение в кеше, и указанная выше строка не будет изменять его.

    CMake GUI

    введите описание изображения здесь

    В графическом интерфейсе пользователь сначала запускает процесс настройки, затем может модифицировать любое кешированное значение и заканчивается запуском создания среды сборки.

  1. Кроме того, CMake выполняет кэширование результатов поиска / тестирования / компилятора (поэтому ему не нужно делать это снова при повторном запуске шагов конфигурации / генерации)

    find_path(LIB_A_PATH libA.a PATHS "/some/default/path")
    

    Здесь LIB_A_PATH создается как кэшированная переменная.

Добавление профилей для CMake для использования gprof

Предполагается, что ряд событий будет работать следующим образом:

  1. Компилировать код с опцией -pg
  2. Код ссылки с опцией -pg
  3. Запустить программу
  4. Программа генерирует файл gmon.out
  5. Запустить программу gprof

Чтобы добавить флаги профилирования, вы должны добавить в свой CMakeLists.txt:

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg")

Это должно добавить флаги для компиляции и ссылки и использовать после выполнения программы:

gprof ./my_exe

Если вы получите сообщение об ошибке:

gmon.out: No such file or directory

Это означает, что компиляция не добавила информацию профилирования должным образом.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow