2009-10-09 36 views
7

Vì vậy, để biên dịch tệp thực thi của tôi, tôi cần phải thiết lập đúng vị trí thư viện. Vấn đề là, thiết lập xuất phát từ một loạt các kịch bản làm biến env xuất và những thứ cần được thiết lập có thể thay đổi (ngoài tầm kiểm soát của tôi) vì vậy tôi cần sử dụng các tập lệnh đó thay vì sao chép chức năng của chúng. Để biên dịch trong dòng lệnh thông thường, tôi cần phải làm điều gì đó như:Làm thế nào để xử lý thiết lập môi trường trong makefile?

setup library1 
setup library2 
source some_other_setup_script.bash 
g++ blah.c 
# setup is a executable on my system that run some scripts 

Làm cách nào để viết một makefile hoàn thành? Theo như tôi đã thử, biến env xuất không mang theo (ví dụ: "VAR xuất khẩu = ghi nhớ; echo $ VAR" sẽ không hoạt động)

Trả lời

5

Nếu xuất biến không hoạt động theo cách trên dòng lệnh của bạn, điều đó gợi ý rằng chọn chọn vỏ khác với trình bạn đang sử dụng, với cú pháp khác nhau để xử lý biến (export VAR=remember; echo $VAR hoạt động tốt cho tôi). Hãy sử dụng theo mặc định /bin/sh nhưng bạn có thể ghi đè điều này bằng biến SHELL, thực hiện nhập không nhập từ môi trường. Tôi khuyên bạn nên đặt SHELL (trong Makefile) thành bất kỳ thứ gì bạn đang sử dụng trong môi trường của mình và thử lại thử nghiệm export VAR=remember.

+0

Tôi cũng nhận ra rằng tôi nên sử dụng $$ VAR để làm cho sẽ không nghĩ rằng tôi đang trích dẫn một macro ... – polyglot

+3

Nó không thực sự có nghĩa là. GNU chỉ đơn giản là chạy một shell mới cho mỗi dòng trong comand. (Tôi nghi ngờ ông kết hợp hai lệnh với; ngắn gọn) http://www.gnu.org/software/make/manual/make.html#Execution "Khi đến lúc thực hiện các lệnh để cập nhật một mục tiêu, chúng được thực hiện bằng cách gọi một subshell mới cho mỗi dòng lệnh. " –

3

Cuối cùng, bạn sẽ cần xác định biến và thực thi trình biên dịch trong trình bao danh sách hoặc thậm chí một tập lệnh, thay vì trong các lệnh riêng biệt make. Tuy nhiên, có một vài cải tiến mà bạn có thể thêm vào. Bạn có thể nói make về kịch bản:

maintarget: script.sh blah.c 
    source script.sh; g++ blah.c 

script.sh: 
    setup include script here 

Một điều là nên chỉ thực hiện tất cả những thứ trong cùng một vỏ

maintarget: blah.c 
    run this; run that; run the other thing; g++ blah.c 

Tôi tin rằng tất cả make phiên bản sẽ chạy một danh sách ; trong cùng một vỏ , nhưng bạn luôn có thể buộc một subshell với (list) hoặc bằng cách gọi cụ thể một kịch bản shell như là một trình bao bọc lệnh trình biên dịch.

Đừng quên có các mục tiêu phù hợp tùy thuộc vào chính tập lệnh của bạn. BTW, một số phiên bản make (pmake aka bsd make) có thể thực hiện lệnh khi xác định biến số thực hiện và tất cả các phiên bản make sau đó xuất các biến đó. Nhưng tôi không nghĩ rằng gmake có thể làm điều đó.

1

Bạn có thể viết một tập lệnh shell khác để thực hiện tất cả các lệnh đó, sau đó in ra các phép gán biến có thể sử dụng. Chạy tập lệnh, đưa đầu ra của nó vào một tệp, sau đó bao gồm tệp đó từ Makefile của bạn. Ví dụ:

Makefile:

all: 
    echo $(FOO) 

test.mk: test.sh 
    ./$< > [email protected] 

include test.mk 

test.sh

echo "FOO=1" 

Chạy "làm" trong thư mục chứa Makefile này sản xuất:

make: Entering directory `/home/luser/build/mktest' 
Makefile:7: test.mk: No such file or directory 
./test.sh > test.mk 
make: Leaving directory `/home/luser/build/mktest' 
make: Entering directory `/home/luser/build/mktest' 
echo 1 
1 
make: Leaving directory `/home/luser/build/mktest' 

làm tạo test.mk bằng cách chạy tập lệnh shell, sau đó bao gồm nó. test.mk chứa đầu ra của test.sh và được phân tích cú pháp dưới dạng Makefile. Xem http://www.gnu.org/software/make/manual/make.html#Include để biết thêm chi tiết.
Chúng tôi sử dụng một biến thể của điều này trong ứng dụng khách của Mozilla.mk để cho bạn xác định tùy chọn trong một "mozconfig" file: http://mxr.mozilla.org/mozilla-central/source/client.mk#138

11

Bạn cũng có thể thêm các biến môi trường đúng với máy móc thiết bị của GNU thực hiện, như vậy:

export TEST:="Something Good!" 
test: 
    echo $$TEST 

này (tôi nghĩ) có khác nhau ngữ nghĩa từ:

TEST2:="Something not quite so useful?" 
test2: 
    echo ${TEST2} 

Làm thế nào để thay thế trước khi chuyển đến vỏ. Lưu ý rằng lệnh xuất không hoạt động bên trong một khối đích, chỉ cần unindented như một lệnh được thực hiện ngay lập tức.

0

Restatement: Làm thế nào để có được một biến shell vào một tập tin thực hiện?

Cái gì như:

MYVAR := $(shell echo $(MYVAR)) <any_makefile_additions_here> 

Vì vậy, điều này xác định myVar bên trong một makefile khi một myVar biến môi trường được đặt tên cũng được thiết lập.

0

Có thể bạn muốn ghi đè tùy chọn đã được xác định trong tệp makefile, make hỗ trợ (Tôi tham khảo GNU Hãy 3.82, nhưng phiên bản khác có thể quá) tùy chọn -e. Ví dụ:

Makefile:

CC=gcc 
... 

Run thực hiện:

CC=gcc-4.7 
make -e 

sẽ sử dụng gcc-4.7 thay vì gcc.

Các vấn đề liên quan