Thêm thư mục vào PATH thông qua Makefile


9

Tôi gặp một số khó khăn trong việc xuất PATH mà tôi đã sửa đổi bên trong Makefile thành Terminal hiện tại. Tôi đang cố gắng thêm vào PATH, thư mục bin bên trong bất cứ nơi nào có thư mục Makefile.

Đây là dải liên quan của tệp thực hiện:

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

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

Tiếng vang in chính xác nhưng nếu tôi làm lại tiếng vang trong thiết bị đầu cuối, thì PATH vẫn như cũ.

Câu trả lời:


15

Bạn chỉ đơn giản là không thể làm điều này. Không có cách nào - quá trình tạo có thể thay đổi môi trường của cha mẹ (hoặc thư mục hiện tại của nó, mà bạn có thể nghĩ đến tiếp theo).

Trong thực tế, thậm chí ít hơn là hạnh phúc hơn bạn nghĩ.

  • Không phải tất cả các maketriển khai đều phản ánh sự gán cho PATHbiến tạo trong môi trường; GNU make (tìm thấy trên Linux và các hệ thống khác), nhưng BSD thì không.
  • Mỗi dòng lệnh dưới một mục tiêu chạy trong một khung con riêng biệt. (Ngoại trừ trong một số BSD cũ thực hiện triển khai.) Vì vậy, export PATHdòng đang chạy trên một vỏ kết thúc ngay sau đó. Không phải là dòng này sẽ làm bất cứ điều gì ở nơi đầu tiên - nếu PATHđược xác định tại thời điểm đó, đó là vì nó đã ở trong môi trường của vỏ.

Làm là để xây dựng mọi thứ tự động. Nếu bạn muốn đặt các biến cho môi trường tương tác của mình, đây không phải là công cụ bạn nên xem xét. Thay vào đó, hãy viết một đoạn mã shell và tìm nguồn trong shell hiện tại:

. ./define-my-variables.sh

Trong tệp tạo tệp của bạn, hãy tìm tập lệnh trong mọi khung con . Bạn có thể sử dụng dấu gạch chéo ngược để tạo một lệnh dài; nhớ lấy

  • Chuỗi backslash-newline bị tước bằng make, vì vậy shell sẽ không thấy một dòng mới ở đó.
  • Tuy nhiên, hãy nhớ tiền tố mỗi dòng bằng một tab.
  • Thực hiện hành vi lỗi là hủy bỏ nếu một lệnh thất bại. Shell sẽ không làm điều đó theo mặc định và sự thất bại của bất kỳ lệnh nào nhưng lệnh cuối cùng sẽ không được chú ý theo mặc định, vì vậy bạn cần phải chạy set -e.
install:
    set -e; \
    . ./define-my-variables.sh; \
    mkdir -p bin; \
    …

¹ lưu ý bắt buộc: không có cách nào lành mạnh. Thậm chí từ xa gọi chdirqua ptracetừ một trình gỡ lỗi sẽ không làm việc như là với hầu hết vỏ vì họ không muốn có thư mục hiện tại của họ đã thay đổi dưới chân họ.


Er, tôi nghĩ rằng "Đơn giản là bạn không thể làm điều này" là không chính xác. Xem câu trả lời @Yeo: unix.stackexchange.com/a/291973/176350
XML

Câu trả lời của @XML Yeo làm một cái gì đó khác biệt mà không phải là câu hỏi yêu cầu.
Gilles 'SO- ngừng trở nên xấu xa'

7

Bạn không thể. Không thể cho một quy trình con (như make) thay đổi môi trường của quy trình mẹ của nó.

Bạn có thể làm một cái gì đó như

$ eval `make pathupdate`

Trường hợp pathupdatemục tiêu trông như thế nào:

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

6

Câu trả lời của bạn có thể được tìm thấy ở đây: https://stackoverflow.com/a/8942216/367461

Về cơ bản, bạn nên làm điều này:

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

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

Tôi đã thử nghiệm điều này trên Fedora 23 với GNU Make 4.0 và nó hoạt động tốt với tôi.


1
Đây là câu trả lời đúng cho GNU Make. Đối với BSD Make, bạn có thể sử dụng .SHELL: name=sh path=/path/to/wrapper-scriptvà sau đó tạo tập lệnh bao bọc nhưexport FOO=bar; exec bash "$@"
rjh

2

Tôi sắp hỏi câu hỏi tương tự vì tôi không thể lấy ví dụ trả lời khác để làm việc.

Tuy nhiên, tôi quản lý để đạt được giải pháp làm việc cho tôi bằng cách sử dụng evallệnh. Tôi không chắc tại sao điều này không được đăng trước đó.

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

Lưu ý: những PATHthay đổi là tạm thời trong chính nó. Sau khi thoát khỏi make, PATH được đặt lại về giá trị trước đó.


Điều này không được đăng trước đó bởi vì đó không phải là những gì câu hỏi yêu cầu: câu hỏi hỏi làm thế nào để có được PATH thay đổi sau khi thoát khỏi make. Ngoài ra, điều này có thể được thực hiện theo cách đơn giản hơn nhiều: đặt export PATH=…trên do_something:đường dây, bạn không cần eval.
Gilles 'SO- ngừng trở nên xấu xa'

1

Bạn có thể khiến Make gọi đệ quy chính nó với một môi trường được sửa đổi, như sau:

dummy: build_all

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

build_all:
    your make rules 

Nếu bạn muốn sử dụng đoạn mã shell:

dummy: build_all

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

build_all:
   your make rules
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.