Menambahkan direktori ke PATH melalui Makefile

9

Saya mengalami masalah dalam mengekspor PATH yang telah saya modifikasi di dalam Makefile ke Terminal saat ini. Saya mencoba menambahkan ke PATH, folder bin di dalam dimanapun direktori Makefile berada.

Inilah strip relevan dari makefile:

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

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

Gema mencetaknya dengan benar tetapi jika saya mengulang gema di terminal, PATH tetap sama.

tepang
sumber

Jawaban:

16

Anda tidak bisa melakukan ini. Tidak mungkin¹ proses make dapat mengubah lingkungan induknya (atau direktori saat ini, yang mungkin Anda pikirkan selanjutnya).

Faktanya, bahkan lebih sedikit yang membahagiakan daripada yang Anda pikirkan.

  • Tidak semua makeimplementasi mencerminkan penugasan ke PATHvariabel make di lingkungan; GNU make (ditemukan di Linux dan sistem lain) tidak, tetapi BSD make tidak.
  • Setiap baris perintah di bawah target berjalan dalam subkulit terpisah. (Kecuali dalam beberapa implementasi BSD yang lebih tua.) Jadi export PATHbaris tersebut berjalan pada shell yang berakhir segera setelah itu. Bukan berarti baris ini akan melakukan apa pun di tempat pertama - jika PATHdidefinisikan pada titik itu, itu karena sudah ada di lingkungan shell.

Buat adalah untuk membangun sesuatu secara otomatis. Jika Anda ingin mengatur variabel untuk lingkungan interaktif Anda, ini bukan alat yang harus Anda lihat. Alih-alih, tulis snippet shell, dan sumber di shell saat ini:

. ./define-my-variables.sh

Di makefile Anda, sumber skrip di setiap subkulit . Anda bisa menggunakan backslash untuk membuat perintah panjang; ingat bahwa

  • Urutan backslash-newline dilucuti oleh make, sehingga shell tidak akan melihat baris baru di sana.
  • Ingatlah untuk mengawali setiap baris dengan sebuah tab.
  • Perilaku kesalahan Make adalah untuk membatalkan jika suatu perintah gagal. Shell tidak akan melakukan itu secara default, dan kegagalan perintah apa pun tetapi yang terakhir tidak diketahui secara default, jadi Anda harus menjalankannya set -e.
install:
    set -e; \
    . ./define-my-variables.sh; \
    mkdir -p bin; \
    …

¹ Wajib catatan: tidak ada cara waras. Bahkan jauh memohon chdirmelalui ptracedari debugger tidak akan bekerja seperti kebanyakan kerang karena mereka tidak ingin memiliki direktori mereka saat ini berubah di bawah kaki mereka.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Eh, saya pikir "Anda tidak bisa melakukan ini" tidak benar. Lihat @Yeo answer: unix.stackexchange.com/a/291973/176350
XML
@XML Jawaban Yeo melakukan sesuatu yang berbeda yang bukan pertanyaannya.
Gilles 'SANGAT berhenti menjadi jahat'
7

Kamu tidak bisa Subproses (seperti make) tidak mungkin mengubah lingkungan proses induknya.

Anda bisa melakukan sesuatu seperti

$ eval `make pathupdate`

Di mana pathupdatetargetnya terlihat seperti:

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

Jawaban Anda dapat ditemukan di sini: https://stackoverflow.com/a/8942216/367461

Pada dasarnya, Anda harus melakukan ini:

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

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

Saya menguji ini pada Fedora 23 dengan GNU Make 4.0, dan itu berfungsi dengan baik untuk saya.

Dan Jones
sumber
1
Ini adalah jawaban yang benar untuk GNU Make. Untuk BSD Make, Anda dapat menggunakan .SHELL: name=sh path=/path/to/wrapper-scriptdan kemudian membuat skrip pembungkus sepertiexport FOO=bar; exec bash "$@"
rjh
2

Saya akan mengajukan pertanyaan yang sama karena saya tidak bisa mendapatkan contoh jawaban yang lain untuk bekerja.

Namun, saya berhasil mencapai solusi kerja untuk saya dengan menggunakan evalperintah. Saya tidak terlalu yakin mengapa ini tidak diposting sebelumnya.

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

Catatan: PATHperubahan bersifat sementara di dalam proses itu sendiri. Setelah keluar dari make, PATH diatur ulang ke nilai sebelumnya.

Yeo
sumber
Ini tidak diposting sebelumnya karena bukan itu pertanyaannya: pertanyaan bertanya bagaimana cara mendapatkan PATH yang diubah setelah keluar dari make. Juga, ini bisa dilakukan dengan cara yang lebih sederhana: letakkan export PATH=…di do_something:telepon, Anda tidak perlu eval.
Gilles 'SANGAT berhenti menjadi jahat'
1

Anda dapat menyebabkan Make untuk menyebut dirinya secara rekursif dengan lingkungan yang dimodifikasi, seperti:

dummy: build_all

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

build_all:
    your make rules 

Jika Anda ingin menggunakan potongan shell:

dummy: build_all

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

build_all:
   your make rules
Sam B.
sumber