Adicionando diretório ao PATH através do Makefile


9

Estou com problemas para exportar o PATH que modifiquei dentro do Makefile para o terminal atual. Estou tentando adicionar ao PATH, a pasta bin dentro de onde quer que esteja o diretório Makefile.

Aqui está a faixa relevante do makefile:

PATH := $(shell pwd)/bin:$(PATH)

install:
    mkdir -p ./bin 
    export PATH
    echo $(PATH)

O eco é impresso corretamente, mas se eu refazer o eco no terminal, o PATH permanece o mesmo.

Respostas:


16

Você simplesmente não pode fazer isso. Não há como: o processo de criação pode alterar o ambiente de seus pais (ou o diretório atual, no qual você pode estar pensando a seguir).

De fato, ainda menos está acontecendo do que você pensa.

  • Nem todas as makeimplementações refletem a atribuição à PATHvariável make no ambiente; O GNU make (encontrado no Linux e em outros sistemas) funciona, mas o BSD make não.
  • Cada linha de comando sob um destino é executada em um subshell separado. (Exceto em alguns BSD mais antigos, faça implementações.) Portanto, a export PATHlinha está sendo executada em um shell que termina imediatamente depois. Não que essa linha esteja fazendo algo em primeiro lugar - se PATHfor definida nesse ponto, é porque já está no ambiente do shell.

Make é para construir coisas automaticamente. Se você deseja definir variáveis ​​para o seu ambiente interativo, esta não é a ferramenta que você deveria procurar. Em vez disso, escreva um trecho de shell e origine -o no shell atual:

. ./define-my-variables.sh

No seu makefile, forneça o script em cada subshell . Você pode usar uma barra invertida para fazer um comando longo; lembre-se disso

  • A sequência de barra invertida e nova linha é removida pelo make, para que o shell não veja uma nova linha lá.
  • Lembre-se de prefixar cada linha com uma guia.
  • O comportamento do erro de Make é abortar se um comando falhar. O shell não fará isso por padrão, e a falha de qualquer comando, mas o último passará despercebido por padrão, portanto, você precisa executar set -e.
install:
    set -e; \
    . ./define-my-variables.sh; \
    mkdir -p bin; \
    …

¹ Nota obrigatória: não há maneira sã. Mesmo invocando remotamente chdirvia ptracede um depurador não funcionará como na maioria dos shells, porque eles não gostam de ter seu diretório atual alterado.


Er, acho que "você simplesmente não pode fazer isso" está incorreto. Consulte a resposta @Yeo: unix.stackexchange.com/a/291973/176350
XML

A resposta da @XML Yeo faz algo diferente, que não é o que a pergunta pede.
Gilles 'SO- stop being evil'

7

Você não pode. Não é possível que um subprocesso (como make) altere o ambiente do processo pai.

Você poderia fazer algo como

$ eval `make pathupdate`

Onde o pathupdatedestino se parece:

pathupdate:
    @echo PATH=\"$(PATH)\"

6

Sua resposta pode ser encontrada aqui: https://stackoverflow.com/a/8942216/367461

Basicamente, você deve fazer isso:

export PATH := $(shell pwd)/bin:$(PATH)

test:
    mkdir -p ./bin
    @echo $(PATH)

Eu testei isso no Fedora 23 com o GNU Make 4.0, e funciona bem para mim.


1
Esta é a resposta correta para o GNU Make. Para BSD faz, você pode usar .SHELL: name=sh path=/path/to/wrapper-scripte, em seguida, fazer um script wrapper comoexport FOO=bar; exec bash "$@"
rjh

2

Estou prestes a fazer a mesma pergunta porque não consegui que o outro exemplo de resposta funcionasse.

No entanto, consegui obter a solução de trabalho para mim usando o evalcomando Não sei ao certo por que isso não foi publicado anteriormente.

do_something: 
    $(eval export PATH=$(shell pwd)/bin:$(PATH))
    @echo $(PATH)

Nota: as PATHalterações são temporárias na própria marca. Após sair da marca, o PATH é redefinido para o valor anterior.


Isso não foi publicado anteriormente porque não é o que a pergunta: a pergunta é como obter o PATH alterado após a saída do make. Além disso, isso pode ser feito de uma maneira muito mais simples: coloque export PATH=…em jogo do_something:, você não precisa eval.
Gilles 'SO- stop be evil'

1

Você pode fazer com que o Make se chame recursivamente com um ambiente modificado, como:

dummy: build_all

all: 
    PATH=/new/directory:$(PATH) $(MAKE) build_all

build_all:
    your make rules 

Se você deseja usar um snippet de shell:

dummy: build_all

all:
    . ./define-my-variables.sh ; $(MAKE) build_all

build_all:
   your make rules
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.