Как изменить переменные среды, переданные пользовательскому целевому объекту CMake?

#cmake

Вопрос:

Возможно, я упускаю что-то очевидное, но я, похоже, не могу понять, как явно задать переменные среды, которые могут быть видны запущенным процессам add_custom_target() .

Я попробовал следующее:

 set(ENV{PATH} "C:/Some/Path;$ENV{PATH}")
add_custom_target(newtarget somecommand)
 

К сожалению, %PATH% переменная окружения, по-видимому, не изменилась somecommand . (Я создал суть, которая воспроизводит проблему здесь.)

Что я делаю не так?

Комментарии:

1. Я бы предположил, что, поскольку вы создаете новый процесс (из ваших комментариев), то новому процессу будет предоставлена собственная среда, а не наследование среды основного процесса. Если вы создадите дочерний процесс основного процесса, то среда должна быть унаследована — но я ничего об этом не знаю cmake , поэтому я могу быть далеко отсюда. Однако вы должны использовать backslash в качестве разделителей каталогов, а не / как / префикс коммутатора. Иногда / работает хорошо, но это ненадежно.

Ответ №1:

Переносимый способ настройки переменных среды для пользовательской цели-использовать команду CMake в режиме командной строки env :

 env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]...
 

Выполните команду в измененной среде.

Напр.:

 add_custom_target(newtarget ${CMAKE_COMMAND} -E env NAME=VALUE somecommand)
 

Также смотрите раздел Режим инструмента командной строки.

Ответ №2:

Вы задаете переменную среды на этапе настройки, но команда, указанная для add_custom_target , выполняется на этапе сборки. См. Также Часто задаваемые вопросы CMake: Как я могу получить или установить переменные среды?

[…]
переменные среды SET в CMakeLists.txt вступают в силу только для самого cmake (время настройки), поэтому вы не можете использовать этот метод для установки переменной среды, которая может потребоваться пользовательской команде (время сборки). За исключением поддержки переменных среды различными командами CMake (например add_custom_command() , в настоящее время еще не поддерживается), приемлемым обходным путем может быть вызов сценариев оболочки, которые заключают в себе команды, которые должны быть выполнены.

В настоящее add_custom_target время (и другие команды, которые определяют действия для шага сборки, например add_custom_command ) не поддерживают простые переменные среды настройки. Как указано в этом багрепорте, для значения переменной set без пробелов в Linux вы можете добавить команду с предложениями «VAR=VAL». Для общих случаев вы можете подготовить сценарий-оболочку, который настраивает среду и запускает фактическую команду:

На окнах:

обертка.летучая мышь:

 @ECHO OFF
set PATH=C:\Some\Path;%PATH%
%*
 

CMakeLists.txt:

 add_custom_target(...
    COMMAND cmd /c ${CMAKE_CURRENT_SOURCE_DIR}/wrapper.bat <real_command> args...
)
 

В Linux:

wrapper.sh:

 export "PATH=/Some/Path:$PATH"
eval "$*"
 

CMakeLists.txt:

 add_custom_target(...
    COMMAND /bin/sh ${CMAKE_CURRENT_SOURCE_DIR}/wrapper.sh <real_command> args...
)
 

Если значение переменной зависит от конфигурации, вы можете настроить сценарий-оболочку с configure_file помощью .

Обновить:

Как отметил @sakra, env инструментальный режим cmake исполняемого файла можно использовать в качестве сценария-оболочки:

 add_custom_target(...
    COMMAND ${CMAKE_COMMAND} -E env "PATH=C:/Some/Path;$ENV{PATH}" <real_command> args...
)
 

Этот способ доступен начиная с CMake 3.2.

Комментарии:

1. что написать вместо 3 точек ? Что такое «реальная команда»? Что за «аргументы»? Плохой ответ

2. Первый аргумент для add_custom_target() — это имя цели. <real_command> является заменой исходного COMMAND параметра и args... является аргументами исходной команды.

3. Без полного примера я совершенно не понимаю, как работает эта команда, извините

4. Если вы не понимаете, что add_custom_target происходит, вы можете заглянуть в документацию или задать новый вопрос о переполнении стека. Текущий пост с вопросом содержит призыв add_custom_target(newtarget somecommand) , поэтому оба ответа (один от сакры и мой) подразумевают, что значение этого призыва известно читателям.

5. Документация Cmake без примера — я все еще не понимаю, потратив много времени! Так что это мне не поможет.

Ответ №3:

Поздний ответ на этот вопрос, но, возможно, это кому-то поможет. Мы используем оператор amp;amp; для этого в наших файлах cmake в Windows.

 set(MY_COMMAND set "PATH=C:\some\path;%PATH%"amp;amp;
        somecommand)

add_custom_target(TARGET newtarget COMMAND ${MY_COMMAND})
 

Обратите внимание, что у вас не может быть места перед amp;amp; (по причинам, которые я не совсем понимаю). Кроме того, пространства-это настоящая боль, с которой здесь приходится иметь дело, поэтому я не знаю, правильно ли я поступаю, если c:somepath имеет пробелы. Это работает, если в вашем исходном пути есть пробелы.