Я пытаюсь создать настраиваемую команду, которая запускается с некоторыми переменными среды, такими как LDFLAGS, значение которых необходимо указать, если оно содержит пробелы:
LDFLAGS="-Lmydir -Lmyotherdir"
Я не могу найти способ включить этот аргумент в настраиваемую команду CMake из-за правил экранирования CMake. Вот что я пробовал до сих пор:
COMMAND LDFLAGS="-Ldir -Ldir2" echo blah VERBATIM)
Дает "LDFLAGS=\"-Ldir -Ldir2\"" echo blah
COMMAND LDFLAGS=\"-Ldir -Ldir2\" echo blah VERBATIM)
Дает LDFLAGS=\"-Ldir -Ldir2\" echo blah
Кажется, я либо цитирую всю строку, либо экранированные кавычки не разрешаются при использовании как части команды.
Я был бы признателен либо за использование буквальных двойных кавычек, либо за лучший способ установки переменных среды для команды. Обратите внимание, что я все еще использую CMake 2.8, поэтому у меня нет новой команды "env", доступной в версии 3.2.
Обратите внимание, что это не дубликат Когда помещать переменные в кавычки? поскольку ни один из этих методов цитирования не работает в данном конкретном случае.
4 ответа
Очевидный выбор - часто рекомендуемый при выходе за границы COMMAND
, особенно со старыми версиями CMake - это использовать внешний скрипт.
Я просто хотел добавить несколько простых COMMAND
вариантов, которые действительно работают и не нуждаются в оболочке, но, я должен признать, все еще частично зависят от платформы.
Один из примеров - поместить в переменную только указанную в кавычках часть:
set(vars_as_string "-Ldir -Ldir2") add_custom_target( QuotedEnvVar COMMAND env LD_FLAGS=${vars_as_string} | grep LD_FLAGS )
Что на самом деле избегает пробела, а не кавычек.
Другой пример - добавить его с экранированными кавычками в качестве правила запуска:
add_custom_target( LauncherEnvVar COMMAND env | grep LD_FLAGS ) set_target_properties( LauncherEnvVar PROPERTIES RULE_LAUNCH_CUSTOM "env LD_FLAGS=\"-Ldir -Ldir2\"" )
Изменить : добавлены примеры для нескольких аргументов в кавычках без необходимости экранирования кавычек.
Другой пример - «скрыть некоторую сложность» в функции и - если вы хотите добавить это ко всем своим пользовательским вызовам команд - использовать каталог global /
RULE_LAUNCH_CUSTOM
:function(set_env) get_property(_env GLOBAL PROPERTY RULE_LAUNCH_CUSTOM) if (NOT _env) set_property(GLOBAL PROPERTY RULE_LAUNCH_CUSTOM "env") endif() foreach(_arg IN LISTS ARGN) set_property(GLOBAL APPEND_STRING PROPERTY RULE_LAUNCH_CUSTOM " ${_arg}") endforeach() endfunction(set_env) set_env(LDFLAGS="-Ldir1 -Ldir2" CFLAGS="-Idira -Idirb") add_custom_target( MultipleEnvVar COMMAND env | grep -E 'LDFLAGS|CFLAGS' )
Альтернатива (для CMake> = 3.0)
Я думаю, то, что мы действительно ищем здесь (помимо
cmake -E env ...
), называется Аргумент скобки и разрешает любой символ без необходимости добавления обратной косой черты:set_property( GLOBAL PROPERTY RULE_LAUNCH_CUSTOM [=[env LDFLAGS="-Ldir1 -Ldir2" CFLAGS="-Idira -Idirb"]=] ) add_custom_target( MultipleEnvVarNew COMMAND env | grep -E 'LDFLAGS|CFLAGS' )
Ссылки
- 0005145: установить переменные среды для ADD_CUSTOM_COMMAND / ADD_CUSTOM_TARGET
- Как изменить переменные среды, передаваемые в настраиваемую цель CMake?
- [CMake] Как установить переменную среды для пользовательской команды
- cmake: когда заключать в кавычки переменные?
Некоторые ребята предлагают использовать $ {CMAKE_COMMAND} и передавать ваш исполняемый файл в качестве аргумента, например:
COMMAND ${CMAKE_COMMAND} -E env "$(WindowsSdkDir)/bin/x64/makecert.exe" ...
Это сработало для меня.
Вам понадобится три обратной косой черты. Мне это понадобилось недавно, чтобы получить определение препроцессора из PkgConfig и применить его к моим флагам C ++:
pkg_get_variable(SHADERDIR movit shaderdir)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSHADERDIR=\\\"${SHADERDIR}\\\"")
Хорошо, я удалил свой исходный ответ, так как вариант, предложенный @Florian, лучше. Для нескольких аргументов в кавычках требуется одна дополнительная настройка. Рассмотрим список переменных среды как таковых:
set(my_env_vars LDFLAGS="-Ldir1 -Ldir2" CFLAGS="-Idira -Idirb")
Чтобы получить желаемое расширение, преобразуйте его в строку, а затем замените ;
пробелом.
set(my_env_string "${my_env_vars}") #produces LDFLAGS="...";CFLAGS="..."
string(REPLACE ";" " " my_env_string "${my_env_string}")
Затем вы можете перейти к блестящему ответу @Florian и добавить настраиваемое правило запуска. Если вам нужны точки с запятой в вашей строке, вам нужно сначала преобразовать их во что-то другое.
Затем вы можете перейти к блестящему ответу @Florian и добавить настраиваемое правило запуска. Если вам нужны точки с запятой в вашей строке, вам нужно сначала преобразовать их во что-то другое.…
set_target_properties(mytarget PROPERTIES RULE_LAUNCH_CUSTOM "${my_env_string}")
Конечно, это зависит от вашей оболочки.
Если подумать, мой исходный ответ приведен ниже, так как у меня также есть случай, когда у меня нет доступа к целевому имени.
set(my_env LDFLAGS=\"-Ldir -Ldir2" CFLAGS=\"-Idira -Idirb\")
add_custom_command(COMMAND sh -c "${my_env} grep LDFLAGS" VERBATIM)
Этот метод по-прежнему требует замены точек с запятой при преобразовании списка в строку.
Похожие вопросы
Связанные вопросы
Новые вопросы
cmake
CMake - это кроссплатформенный генератор систем с открытым исходным кодом. Он генерирует файлы для систем сборки, такие как собственные make-файлы, ninja-build и файлы проектов для нескольких интегрированных сред разработки.