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

Выражение генератора CMake не оценивается

Я не могу понять, что я делаю неправильно. Я всегда получаю строку "$<TARGET_FILE:tgt1>" вместо пути к библиотеке.

Я создал фиктивный проект.

Вот мой корень CMakeLists.txt

cmake_minimum_required (VERSION 3.0) # also tried 2.8 with the same result
set(PROJECT_NAME CMP0026)

add_subdirectory(src)

set(TGT_PATH $<TARGET_FILE:tgt1>)
message(STATUS "${TGT_PATH}")

Вот мой src/CMakeLists.txt

add_library(tgt1 a.c)

Файл a.c создан и пуст

Я пробовал следующие генераторы: Visual Studio 2013 Win64, Ninja и MingW Makefile. Я использовал набор инструментов Android для последних двух, скачанный с здесь

Я ожидаю, что последняя команда message(STATUS выведет полный путь к библиотеке. Тем не менее, все варианты печатают строку $<TARGET_FILE:tgt1>.

4b9b3361

Ответ 1

Выражения генератора не оцениваются во время настройки (когда CMake анализирует CMakeLists, выполняя команды типа add_target() или message() и т.д.). В это время выражение генератора представляет собой буквальную строку - символ $, за которым следует <, затем T, затем...

Оценка выражений генератора происходит при генерации времени (поэтому их называют "генераторными выражениями" ). Время генерации происходит после анализа и обработки кода CMake, а CMake начинает действовать на данные в нем для создания файлов системных файлов. Только тогда у него есть вся информация, необходимая для оценки выражений генератора.

Таким образом, вы можете реально использовать выражения генератора для вещей, которые происходят во время генерации или позже (например, время сборки). Надуманным примером может быть следующее:

add_custom_target(
  GenexDemo
  COMMAND ${CMAKE_COMMAND} -E echo "$<TARGET_FILE:tgt1>"
  VERBATIM
)

В момент настройки CMake записывает литеральную строку $<TARGET_FILE:tgt1> в качестве аргумента COMMAND. Затем при генерации времени (когда местоположение tgt1 известно для каждой конфигурации и гарантировано не изменится больше), оно заменит его на выражение генератора.