Agregar directorio a RUTA a través de Makefile

9

Tengo algunos problemas para exportar la RUTA que he modificado dentro del Makefile a la Terminal actual. Estoy tratando de agregar a la RUTA, la carpeta bin dentro de donde sea que esté el directorio Makefile.

Aquí está la tira relevante del archivo MAKE:

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

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

El eco lo imprime correctamente, pero si rehago el eco en el terminal, la RUTA sigue siendo la misma.

tshepang
fuente

Respuestas:

16

Simplemente no puedes hacer esto. No hay forma de que el proceso de creación pueda cambiar el entorno de su padre (o su directorio actual, en el que podría estar pensando a continuación).

De hecho, está sucediendo incluso menos de lo que piensas.

  • No todas las makeimplementaciones reflejan la asignación a la PATHvariable make en el entorno; GNU make (que se encuentra en Linux y otros sistemas) sí, pero BSD make no.
  • Cada línea de comando debajo de un objetivo se ejecuta en una subshell separada. (Excepto en algunas implementaciones anteriores de BSD make). Por lo tanto, la export PATHlínea se ejecuta en un shell que termina inmediatamente después. No es que esta línea esté haciendo algo en primer lugar; si PATHse define en ese punto, es porque ya está en el entorno del shell.

Make es para construir cosas automáticamente. Si desea establecer variables para su entorno interactivo, esta no es la herramienta que debería mirar. En su lugar, escriba un fragmento de shell y búsquelo en el shell actual:

. ./define-my-variables.sh

En su archivo MAKE, obtenga el script en cada subshell . Puede usar una barra invertida para hacer un comando largo; recuerda eso

  • La secuencia de barra invertida-nueva línea se elimina por marca, por lo que el shell no verá una nueva línea allí.
  • No obstante, recuerde prefijar cada línea con una pestaña.
  • El comportamiento de error de Make es abortar si falla un comando. El shell no lo hará de forma predeterminada, y el fallo de cualquier comando, pero el último pasará desapercibido de forma predeterminada, por lo que debe ejecutar set -e.
install:
    set -e; \
    . ./define-my-variables.sh; \
    mkdir -p bin; \
    …

¹ Nota obligatoria: de ninguna manera sensata. Incluso invocar de forma remota a chdirtravés ptracede un depurador no funcionará como lo hace con la mayoría de los shells porque no les gusta que cambien su directorio actual bajo sus pies.

Gilles 'SO- deja de ser malvado'
fuente
Er, creo que "Simplemente no puedes hacer esto" es incorrecto. Consulte @Yeo answer: unix.stackexchange.com/a/291973/176350
XML
La respuesta de @XML Yeo hace algo diferente, que no es lo que pide la pregunta.
Gilles 'SO- deja de ser malvado'
7

No puedes No es posible que un subproceso (como make) altere el entorno de su proceso padre.

Podrías hacer algo como

$ eval `make pathupdate`

Donde se pathupdateve el objetivo:

pathupdate:
    @echo PATH=\"$(PATH)\"
cjm
fuente
6

Su respuesta se puede encontrar aquí: https://stackoverflow.com/a/8942216/367461

Básicamente, debes hacer esto:

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

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

Probé esto en Fedora 23 con GNU Make 4.0, y funciona bien para mí.

Dan Jones
fuente
1
Esta es la respuesta correcta para GNU Make. Para BSD Make, puede usar .SHELL: name=sh path=/path/to/wrapper-scripty luego crear un script de contenedor comoexport FOO=bar; exec bash "$@"
rjh
2

Estoy a punto de hacer esta misma pregunta porque no pude lograr que el otro ejemplo de respuesta funcione.

Sin embargo, logré lograr la solución de trabajo para mí usando el evalcomando. No estoy muy seguro de por qué esto no se publicó anteriormente.

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

Nota: los PATHcambios son temporales dentro de la propia marca. Después de salir de la marca, la RUTA se restablece al valor anterior.

Yeo
fuente
Esto no se publicó antes porque no es lo que la pregunta pregunta: la pregunta pregunta cómo obtener el CAMINO modificado después de salir de make. Además, esto podría hacerse de una manera mucho más simple: poner export PATH=…en la do_something:línea, no es necesario eval.
Gilles 'SO- deja de ser malvado'
1

Puede hacer que Make se llame recursivamente con un entorno modificado, como tal:

dummy: build_all

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

build_all:
    your make rules 

Si desea usar un fragmento de shell:

dummy: build_all

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

build_all:
   your make rules
Sam B.
fuente