Команда CMake set_property с выражениями генератора, использующими несколько значений

Я использую CMake v3.13.4 с генератором Visual Studio 2017 Win64, и мне нужно изменить параметры командной строки для библиотеки Visual Studio (для библиотеки объектов CMake).

Для этого CMake предлагает целевое свойство STATIC_LIBRARY_OPTIONS, которое можно установить с помощью команды set_property и set_target_properties.

В документации указано, что STATIC_LIBRARY_OPTIONS поддерживает выражения генератора:

Contents of STATIC_LIBRARY_OPTIONS may use “generator expressions” with the syntax $<...>. See the cmake-generator-expressions(7) manual for available expressions. See the cmake-buildsystem(7) manual for more on defining buildsystem properties.

Но: Что бы я ни пытался, значения не экранируются должным образом, например.

set_property(TARGET object_library PROPERTY STATIC_LIBRARY_OPTIONS $<$<CONFIG:Release>:/WX /NOLOGO /LTCG /ERRORREPORT:NONE>)

приводит к следующему в Visual Studio:

All Options: `/OUT:"..." /LTCG /MACHINE:X64 /NOLOGO 
Additional Options: %(AdditionalOptions) /machine:x64 ""$"<1:/WX" "/ERRORREPORT:NONE>"

Я пробовал следующее, все они, похоже, терпят неудачу.

set_property(TARGET object_library PROPERTY
  STATIC_LIBRARY_OPTIONS $<$<CONFIG:Release>:/WX /NOLOGO /LTCG /ERRORREPORT:NONE>
  #STATIC_LIBRARY_OPTIONS "$<$<CONFIG:Release>:/WX /NOLOGO /LTCG /ERRORREPORT:NONE>"
  #STATIC_LIBRARY_OPTIONS $<$<CONFIG:Release>:"/WX /NOLOGO /LTCG /ERRORREPORT:NONE">
  #STATIC_LIBRARY_OPTIONS $<$<CONFIG:Release>:/WX /NOLOGO /LTCG /ERRORREPORT:NONE>
  #STATIC_LIBRARY_OPTIONS $<$<CONFIG:Release>:/WX;/NOLOGO;/LTCG;/ERRORREPORT:NONE>
  #STATIC_LIBRARY_OPTIONS $<$<CONFIG:Release>:"/WX;/NOLOGO;/LTCG;/ERRORREPORT:NONE">
  #STATIC_LIBRARY_OPTIONS "$<$<CONFIG:Release>:/WX;/NOLOGO;/LTCG;/ERRORREPORT:NONE>"
  )

Итак, мой вопрос: как я могу передать несколько значений с помощью выражений генератора в STATIC_LIBRARY_OPTIONS с помощью команды set_property или set_target_properties?

«Как я могу передать несколько значений, используя выражения генератора?» - Оберните каждое значение в собственное выражение генератора: $<$<CONFIG:Release>:/WX> $<$<CONFIG:Release>:/NOLOGO> ....

Tsyvarev 20.03.2019 16:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
2 285
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Благодаря @Tsyvarev я смог решить эту проблему. Решение состоит в том, чтобы преобразовать обернуть каждое значение в собственное выражение генератора:

set_property(TARGET object_library PROPERTY
    STATIC_LIBRARY_OPTIONS
      $<$<CXX_COMPILER_ID:MSVC>:/WX>
      $<$<CXX_COMPILER_ID:MSVC>:/NOLOGO>
      $<$<CXX_COMPILER_ID:MSVC>:/ERRORREPORT:NONE>
      $<$<CXX_COMPILER_ID:MSVC>:$<$<CONFIG:Release>:/LTCG>>
  )

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

Этот ответ предназначен для будущих читателей с более новым cmake: Как подробно описано в этот ответ от @firmament, в зависимости от версии cmake также может быть возможно поместить все значения в список через

set(my_option_list /WX /NOLOGO /LTCG /ERRORREPORT:NONE)

и передайте этот список в выражение генератора:

"<$<CONFIG:Release>:${my_option_list}>"

Это работает на cmake 3.18.4 с выражениями генератора clang и gcc.

Я протестировал этот подход. Ваше генераторное выражение в конфигурации Release внутренне производит "/WX;/NOLOGO;/LTCG;/ERRORREPORT:NONE". Для некоторых команд это эквивалентно списку этих опций: /WX /NOLOGO /LTCG /ERRORREPORT:NONE, так что все работает. Среди них команда add_compile_options от ваш вопрос. Но для некоторых других команд это не работает. Например. add_custom_target(my_target COMMAND echo "<$<CONFIG:Release>:${my_option_list}>" печатает точки с запятой между вариантами. (Вместо того, чтобы печатать их через пробел).

Tsyvarev 09.12.2020 20:02

Спасибо, что дал мне знать! Я думаю, это делает недействительным мой ответ на этот вопрос. Каков наилучший план действий? Должен ли я удалить его? Видимо, это неправильный ответ на этот вопрос.

Eike 10.12.2020 21:22

«По-видимому, это неправильный ответ на этот вопрос». - Почему вы так думаете? Вы отвечаете отвечает на текущий вопрос, он отвечает на ваш вопрос. На самом деле, это решает проблему add_custom_target, но с дополнительным ключевым словом COMMAND_EXPAND_LISTS: stackoverflow.com/a/65231456/3440745. Я только что объяснил некоторые... особенности вашего подхода. Кстати, я проголосовал за ваш ответ, а не против.

Tsyvarev 10.12.2020 21:35

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

Eike 12.12.2020 11:08

Также, может быть, текущее поведение следует зарегистрировать как ошибку? Меня, например, очень сбивает с толку то, как по-разному работают выражения генератора для разных команд. Но я не уверен в своих способностях и их отсутствии с помощью cmake, чтобы на самом деле подать его.

Eike 12.12.2020 11:16

«почему выражения генератора работают так по-разному для разных команд». - Нет, генератор выражений самих себя работает точно так же. И ваше генераторное выражение всегда выдает "/WX;/NOLOGO;/LTCG;/ERRORREPORT:NONE". Но такой строка, разделенная точкой с запятой обрабатывается разными командами по-разному. Кажется, что многие команды (которые поддерживают выражения генератора) обрабатывают эту строку как список, и это желаемое поведение. Команда add_custom_target относится к этому по-разному... но есть способ официальный для изменения этого поведения. Я не вижу в этом проблемы.

Tsyvarev 12.12.2020 14:02

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

Eike 12.12.2020 15:15

Предполагая, что у вас есть список вариантов:

set(option_list /WX /NOLOGO /LTCG /ERRORREPORT:NONE)

вы можете создать для них список генераторных выражений одной командой:

list(TRANSFORM option_list
  REPLACE ".+" "$<$<CXX_COMPILER_ID:MSVC>:\\0>"
  OUTPUT_VARIABLE option_list_msvc
)

Полученный список можно использовать напрямую:

set_property(TARGET object_library PROPERTY STATIC_LIBRARY_OPTIONS ${option_list_msvc})

Поток команд список(ПРЕОБРАЗОВАНИЕ) доступен, начиная с CMake 3.12.

Другие вопросы по теме