Zkusili jste export
direktivu Make samotné (za předpokladu, že používáte GNU Make)?
export PATH := bin:$(PATH)
test all:
x
Ve vašem příkladu je také chyba:
test all:
PATH=bin:${PATH}
@echo $(PATH)
x
Za prvé, hodnota je echo
ed je rozšířením PATH
proměnná prováděná Make, nikoli shellem. Pokud vypíše očekávanou hodnotu, pak, myslím, jste nastavili PATH
proměnná někde dříve ve vašem Makefile nebo v shellu, který vyvolal Make. Abyste takovému chování zabránili, měli byste uniknout dolarům:
test all:
PATH=bin:$$PATH
@echo $$PATH
x
Za druhé, v žádném případě to nebude fungovat, protože Make provádí každý řádek receptu v samostatném shellu. To lze změnit napsáním receptu na jeden řádek:
test all:
export PATH=bin:$$PATH; echo $$PATH; x
Podle návrhu make
parser provádí řádky v samostatném shellu, proto mění proměnnou (např. PATH
) v jednom řádku, změna nemusí být aplikována na další řádky (viz tento příspěvek).
Jedním ze způsobů, jak tento problém vyřešit, je převést více příkazů na jeden řádek (oddělený ;
), nebo použijte speciální cíl One Shell (.ONESHELL
, od GNU Make 3.82).
Případně můžete poskytnout PATH
proměnná v době, kdy je spuštěn shell. Například:
PATH := $(PATH):$(PWD)/bin:/my/other/path
SHELL := env PATH=$(PATH) /bin/bash
Co obvykle dělám, je výslovně zadat cestu ke spustitelnému souboru:
EXE=./bin/
...
test all:
$(EXE)x
Tuto techniku také používám ke spouštění nenativních binárních souborů pod emulátorem, jako je QEMU, pokud provádím křížovou kompilaci:
EXE = qemu-mips ./bin/
Pokud make používá shell sh, mělo by to fungovat:
test all:
PATH=bin:$PATH x
Změny cesty se zdají být trvalé, pokud nejprve nastavíte proměnnou SHELL v makefile:
SHELL := /bin/bash
PATH := bin:$(PATH)
test all:
x
Nevím, jestli je to žádoucí chování nebo ne.