Aggiunta di directory a PATH tramite Makefile


9

Ho dei problemi nell'esportazione del PERCORSO che ho modificato all'interno del Makefile nell'attuale Terminale. Sto cercando di aggiungere al PATH, la cartella bin all'interno della directory Makefile.

Ecco la striscia pertinente del makefile:

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

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

L'eco lo stampa correttamente ma se rifaccio l'eco nel terminale, il PERCORSO rimane lo stesso.

Risposte:


16

Semplicemente non puoi farlo. Non c'è modo¹ che il processo di creazione possa cambiare l'ambiente del suo genitore (o la sua directory corrente, a cui potresti pensare in seguito).

In effetti, anche meno sta accadendo di quanto pensi.

  • Non tutte le makeimplementazioni riflettono l'assegnazione alla PATHvariabile make nell'ambiente; GNU make (presente su Linux e altri sistemi) lo fa, ma BSD make no.
  • Ogni riga di comando sotto una destinazione viene eseguita in una subshell separata. (Tranne che in alcuni BSD precedenti eseguono implementazioni.) Quindi la export PATHlinea è in esecuzione su una shell che termina immediatamente dopo. Non che questa linea possa fare qualcosa in primo luogo - se PATHè definita a quel punto, è perché è già nell'ambiente della shell.

Make è per costruire cose automaticamente. Se vuoi impostare variabili per il tuo ambiente interattivo, questo non è lo strumento che dovresti guardare. Invece, scrivi uno snippet di shell e procuralo nella shell corrente:

. ./define-my-variables.sh

Nel tuo makefile, crea lo script in ogni subshell . È possibile utilizzare una barra rovesciata per eseguire un comando lungo; ricordati che

  • La sequenza backslash-newline è eliminata da make, quindi la shell non vedrà una nuova riga lì.
  • Ricorda comunque di aggiungere un prefisso a ciascuna riga di una scheda.
  • Il comportamento dell'errore di Make è quello di interrompere se un comando fallisce. La shell non lo farà per impostazione predefinita e il fallimento di qualsiasi comando, ma l'ultimo passerà inosservato per impostazione predefinita, quindi è necessario eseguire set -e.
install:
    set -e; \
    . ./define-my-variables.sh; \
    mkdir -p bin; \
    …

¹ Nota obbligatoria: nessun modo sano. Anche invocare in remoto chdirtramite ptraceun debugger non funzionerà come nella maggior parte delle shell perché a loro non piace cambiare la loro directory corrente sotto i loro piedi.


Ehm, penso che "semplicemente non puoi farlo" non è corretto. Vedi la risposta di @Yeo: unix.stackexchange.com/a/291973/176350
XML

@XML La risposta di Yeo fa qualcosa di diverso che non è quello che la domanda pone.
Gilles 'SO- smetti di essere malvagio' il

7

Non puoi. Per un sottoprocesso (come make) non è possibile modificare l'ambiente del suo processo padre.

Potresti fare qualcosa del genere

$ eval `make pathupdate`

Dove pathupdateappare il bersaglio:

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

6

La risposta è disponibile qui: https://stackoverflow.com/a/8942216/367461

Fondamentalmente, dovresti fare questo:

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

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

Ho provato questo su Fedora 23 con GNU Make 4.0, e funziona bene per me.


1
Questa è la risposta corretta per GNU Make. Per BSD Make, è possibile utilizzare .SHELL: name=sh path=/path/to/wrapper-scripte quindi creare uno script wrapper comeexport FOO=bar; exec bash "$@"
rjh

2

Sto per porre questa stessa domanda perché non sono riuscito a far funzionare l'altro esempio di risposta.

Tuttavia, sono riuscito a ottenere la soluzione di lavoro per me usando il evalcomando. Non sono troppo sicuro del perché questo non sia stato pubblicato prima.

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

Nota: le PATHmodifiche sono temporanee all'interno della marca stessa. Dopo l'uscita dalla marca, il PERCORSO viene ripristinato al valore precedente.


Questo non è stato pubblicato prima perché non è quello che la domanda pone: la domanda chiede come ottenere il PATH modificato dopo l'uscita da make. Inoltre, questo potrebbe essere fatto in un modo molto più semplice: putexport PATH=… in gioco do_something:, non è necessario eval.
Gilles 'SO- smetti di essere cattivo' il

1

Puoi far chiamare ricorsivamente se stesso con un ambiente modificato, come tale:

dummy: build_all

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

build_all:
    your make rules 

Se vuoi usare uno snippet di shell:

dummy: build_all

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

build_all:
   your make rules
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.