Câu trả lời:
Bạn có một số tùy chọn để thiết lập các biến từ bên ngoài tệp thực hiện của mình:
Từ môi trường - mỗi biến môi trường được chuyển thành biến makefile có cùng tên và giá trị.
Bạn cũng có thể muốn thiết lập -e
tùy chọn (aka --environments-override
) trên, và các biến môi trường của bạn sẽ ghi đè lên tập làm thành makefile (trừ những bài tập mình sử dụng override
chỉ thị . Tuy nhiên, nó không được khuyến khích, và nó tốt hơn nhiều và linh hoạt để sử dụng ?=
chuyển nhượng (biến có điều kiện toán tử gán, nó chỉ có hiệu lực nếu biến chưa được xác định):
FOO?=default_value_if_not_set_in_environment
Lưu ý rằng các biến nhất định không được kế thừa từ môi trường:
MAKE
được lấy từ tên của kịch bảnSHELL
được đặt trong tệp tạo tệp hoặc mặc định là /bin/sh
(lý do: các lệnh được chỉ định trong tệp tạo tệp và chúng là đặc trưng cho vỏ).Từ dòng lệnh - make
có thể thực hiện các nhiệm vụ thay đổi như một phần của dòng lệnh của mình, trộn lẫn với các mục tiêu:
make target FOO=bar
Nhưng sau đó tất cả các bài tập để FOO
biến trong makefile sẽ bị bỏ qua trừ khi bạn sử dụng các override
chỉ thị trong chuyển nhượng. (Hiệu ứng này giống như với -e
tùy chọn cho các biến môi trường).
Xuất từ cha mẹ Make - nếu bạn gọi Make từ Makefile, bạn thường không nên viết rõ ràng các bài tập biến như thế này:
# Don't do this!
target:
$(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
Thay vào đó, giải pháp tốt hơn có thể là xuất các biến này. Việc xuất một biến làm cho nó vào môi trường của mọi lệnh gọi shell và Thực hiện các cuộc gọi từ các lệnh này chọn các biến môi trường này như được chỉ định ở trên.
# Do like this
CFLAGS=-g
export CFLAGS
target:
$(MAKE) -C target
Bạn cũng có thể xuất tất cả các biến bằng cách sử dụng export
mà không cần đối số.
export PROJECT_MAKE_ARGS = CC=$(CC) CFLAGS=$(CFLAGS)
và chuyển nó theo make -C folder $(PROJECT_MAKE_FLAGS)
. Nếu có một cách để nói với thư viện của bạn bỏ qua môi trường, thì đó là lý tưởng (ngược lại với -e).
make target FOO=bar
make FOO=bar target
?
Cách đơn giản nhất là:
make foo=bar target
Sau đó, trong makefile của bạn, bạn có thể tham khảo $(foo)
. Lưu ý rằng điều này sẽ không lan truyền đến các phụ bản tự động.
Nếu bạn đang sử dụng các sản phẩm phụ, hãy xem bài viết này: Truyền đạt các biến đến một sản phẩm phụ
included
trong makefile chính?
Từ hướng dẫn :
Các biến trong make có thể đến từ môi trường mà make được chạy. Mỗi biến môi trường tạo ra khi nhìn thấy nó khởi động được chuyển thành biến tạo có cùng tên và giá trị. Tuy nhiên, một gán rõ ràng trong tệp thực hiện hoặc với một đối số lệnh, sẽ ghi đè môi trường.
Vì vậy, bạn có thể làm (từ bash):
FOOBAR=1 make
dẫn đến một biến FOOBAR
trong Makefile của bạn.
Có một tùy chọn khác không được trích dẫn ở đây, được bao gồm trong cuốn sách GNU Make của Stallman và McGrath (xem http://www.oolie.fu-berlin.de/oolnet/use/info/make/make_7.html ). Nó cung cấp ví dụ:
archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
+touch archive.a
+ranlib -t archive.a
else
ranlib archive.a
endif
Nó liên quan đến việc xác minh nếu một tham số nhất định xuất hiện trong MAKEFLAGS
. Ví dụ: giả sử bạn đang nghiên cứu về các chủ đề trong c ++ 11 và bạn đã chia nghiên cứu của mình qua nhiều tệp ( class01
, ..., classNM
) và bạn muốn: biên dịch tất cả và chạy riêng lẻ hoặc biên dịch từng tệp tại một thời gian và chạy nó nếu một cờ được chỉ định ( -r
ví dụ). Vì vậy, bạn có thể đưa ra những điều sau đây Makefile
:
CXX=clang++-3.5
CXXFLAGS = -Wall -Werror -std=c++11
LDLIBS = -lpthread
SOURCES = class01 class02 class03
%: %.cxx
$(CXX) $(CXXFLAGS) -o $@.out $^ $(LDLIBS)
ifneq (,$(findstring r, $(MAKEFLAGS)))
./$@.out
endif
all: $(SOURCES)
.PHONY: clean
clean:
find . -name "*.out" -delete
Có điều đó, bạn:
make -r class02
;make
hoặc make all
;make -r
(giả sử rằng tất cả chúng đều chứa một số loại xác nhận nhất định và bạn chỉ muốn kiểm tra tất cả)dường như
lệnh args ghi đè biến môi trường
Makefile
send:
echo $(MESSAGE1) $(MESSAGE2)
Chạy ví dụ
$ MESSAGE1=YES MESSAGE2=NG make send MESSAGE2=OK
echo YES OK
YES OK
Nếu bạn tạo một tệp có tên Makefile và thêm một biến như $ này (không đáng tin nhất) thì bạn sẽ có thể sử dụng biến này bên trong Makefile ngay cả với các ký tự đại diện
thí dụ :
make unittest=*
Tôi sử dụng BOOST_TEST và bằng cách đưa ký tự đại diện cho tham số --run_test = $ (unittest), sau đó tôi sẽ có thể sử dụng biểu thức chính quy để lọc thử nghiệm mà tôi muốn Makefile của mình chạy
export ROOT_DIR=<path/value>
Sau đó sử dụng biến, $(ROOT_DIR)
trong Makefile.
make A='"as df"'