Принудительно заставить команды выполнять команды в одной среде
У меня есть make-файл для компиляции кроссплатформенного приложения. Для Windows я решил использовать MSVC. Для настройки цепочки инструментов компилятора (переменные среды для легкого доступа к компилятору для конкретной целевой архитектуры) MSVC предоставляет пакетный файл с именем vcvarsall
, Если я вызываю его вручную, он работает нормально, и make-файл может выполняться тоже. Я попытался немного автоматизировать его, вызвав его из make-файла, но, похоже, make запускает его в другой среде, поэтому он не может найти компилятор.
Есть ли способ заставить make не выполнять некоторые команды в другой среде?
1 ответ
Make, как и все процессы, запускается в среде, с которой он запущен. Каждая строка выполняемого им рецепта выполняется в отдельном подпроцессе, в частности, в отдельном вызове оболочки. Подпроцесс не может ничего сделать для изменения среды своего родительского процесса или дочернего подпроцесса: он может только передать измененную среду своим собственным подпроцессам.
targetA: prequisitesA...
command1 # New shell; inherits environment of `make`
command2 # Another new shell; inherits environment of `make`
...
targetB: prequisitesB...
command1 && command2 # New shell; inherits environment of `make`
command3 # Another new shell; inherits environment of `make`
...
targetC: prequisitesC...
command1 && \
command2 # New shell; inherits environment of `make`
command3; \
command4 # Another new shell; inherits environment of `make`
...
Чтобы использовать в команде в make-recipe любые параметры среды, которые применяются при запуске vcvarsall
тогда либо make
должен быть запущен после vcvarsall
в той же среде или унаследованной, которая сохраняет эти настройки, или же это должно быть верно для каждой команды рецепта, которая зависит от этих настроек.
Вы можете указать Make запускать все команды каждого рецепта в одной оболочке для каждого рецепта, написав псевдо-цель .ONESHELL:
в make-файле. Но вряд ли это будет решением для вас.
Вероятно, подходящая автоматизация для вашего случая - написать скрипт-обертку, который вызывает vcvarsall
до make
,
В зависимости от структуры вашего make-файла и вашего допуска к рекурсивному make, вы можете представить себе рекурсивное решение в духе:
ARCH ?= amd64
.PHONY: all
all:
vcvarsall $(ARCH) && $(MAKE) prog
где:-
ARCH
(архитектура) по умолчаниюamd64
если не определено наmake
командная строка или в вызывающей средеall
ваша цель по умолчанию фальшивая цельprog
ваша настоящая цель.