ฉันสามารถส่งตัวแปรไปยัง GNU Makefile เป็นอาร์กิวเมนต์บรรทัดคำสั่งได้หรือไม่ กล่าวอีกนัยหนึ่งฉันต้องการผ่านการขัดแย้งบางอย่างซึ่งในที่สุดจะกลายเป็นตัวแปรใน Makefile
ฉันสามารถส่งตัวแปรไปยัง GNU Makefile เป็นอาร์กิวเมนต์บรรทัดคำสั่งได้หรือไม่ กล่าวอีกนัยหนึ่งฉันต้องการผ่านการขัดแย้งบางอย่างซึ่งในที่สุดจะกลายเป็นตัวแปรใน Makefile
คำตอบ:
คุณมีหลายตัวเลือกในการตั้งค่าตัวแปรจากนอก makefile ของคุณ:
From environment - แต่ละตัวแปรสภาพแวดล้อมจะถูกแปลงเป็นตัวแปร makefile ด้วยชื่อและค่าเดียวกัน
คุณอาจต้องการตั้งค่า-e
ตัวเลือก (aka --environments-override
) และตัวแปรสภาพแวดล้อมของคุณจะแทนที่การมอบหมายที่ทำไว้ใน makefile (ยกเว้นว่าการมอบหมายเหล่านี้ใช้override
คำสั่งอย่างไรก็ตามไม่แนะนำให้ใช้และจะดีกว่าและยืดหยุ่นกว่าในการใช้การ?=
มอบหมาย ผู้ประกอบการที่ได้รับมอบหมายมันจะมีผลเฉพาะถ้าตัวแปรยังไม่ได้กำหนด):
FOO?=default_value_if_not_set_in_environment
โปรดทราบว่าตัวแปรบางอย่างไม่ได้รับมาจากสภาพแวดล้อม:
MAKE
ได้มาจากชื่อของสคริปต์SHELL
ถูกตั้งค่าภายใน makefile หรือค่าเริ่มต้นเป็น/bin/sh
(เหตุผล: คำสั่งถูกระบุไว้ใน makefile และพวกเขากำลังเฉพาะเชลล์)จากบรรทัดคำสั่ง - make
สามารถรับการกำหนดตัวแปรเป็นส่วนหนึ่งของบรรทัดคำสั่งของเขาผสมกับเป้าหมาย:
make target FOO=bar
แต่การมอบหมายทั้งหมดให้กับFOO
ตัวแปรภายใน makefile จะถูกละเว้นเว้นแต่คุณจะใช้override
คำสั่งในการมอบหมาย (เอฟเฟกต์เหมือนกับ-e
ตัวเลือกสำหรับตัวแปรสภาพแวดล้อม)
การส่งออกจาก Make หลัก - ถ้าคุณเรียกใช้ Make จาก Makefile โดยปกติคุณไม่ควรเขียนการกำหนดตัวแปรอย่างชัดเจนดังนี้:
# Don't do this!
target:
$(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
แต่ทางออกที่ดีกว่าคือการส่งออกตัวแปรเหล่านี้ การส่งออกตัวแปรทำให้เป็นสภาพแวดล้อมของการเรียกใช้เชลล์ทุกครั้งและการโทรจากคำสั่งเหล่านี้จะเลือกตัวแปรสภาพแวดล้อมเหล่านี้ตามที่ระบุไว้ข้างต้น
# Do like this
CFLAGS=-g
export CFLAGS
target:
$(MAKE) -C target
คุณสามารถส่งออกตัวแปรทั้งหมดโดยใช้export
โดยไม่มีอาร์กิวเมนต์
export PROJECT_MAKE_ARGS = CC=$(CC) CFLAGS=$(CFLAGS)
make -C folder $(PROJECT_MAKE_FLAGS)
หากมีวิธีที่จะบอกให้ makefile ของห้องสมุดเพิกเฉยต่อสภาพแวดล้อมนั่นจะเป็นอุดมคติ (ตรงข้ามกับ -e)
make target FOO=bar
make FOO=bar target
?
วิธีที่ง่ายที่สุดคือ:
make foo=bar target
จากนั้นใน Makefile $(foo)
ของคุณคุณสามารถอ้างถึง โปรดทราบว่าสิ่งนี้จะไม่เผยแพร่ไปยังการย่อยโดยอัตโนมัติ
หากคุณกำลังใช้งานย่อยทำดูบทความนี้: การสื่อสารตัวแปรเพื่อทำย่อย
included
ใน makefile หลักหรือไม่
จากคู่มือ :
ตัวแปรใน make อาจมาจากสภาพแวดล้อมที่ make ถูกเรียกใช้ ตัวแปรสภาพแวดล้อมทุกตัวที่ทำให้เห็นเมื่อเริ่มต้นจะถูกแปลงเป็นตัวแปรทำให้มีชื่อและค่าเหมือนกัน อย่างไรก็ตามการกำหนดอย่างชัดเจนใน makefile หรือด้วยอาร์กิวเมนต์คำสั่งแทนที่สภาพแวดล้อม
ดังนั้นคุณสามารถทำได้ (จาก bash):
FOOBAR=1 make
ส่งผลให้ตัวแปรFOOBAR
ใน Makefile ของคุณ
มีตัวเลือกอื่นที่ไม่ได้อ้างถึงที่นี่ซึ่งรวมอยู่ใน GNU Make book โดย Stallman และ McGrath (ดูhttp://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html ) มันมีตัวอย่าง:
archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
+touch archive.a
+ranlib -t archive.a
else
ranlib archive.a
endif
MAKEFLAGS
มันเกี่ยวข้องกับการตรวจสอบถ้าพารามิเตอร์ให้ปรากฏใน ตัวอย่างเช่น .. สมมติว่าคุณกำลังศึกษาเกี่ยวกับเธรดใน c ++ 11 และคุณแบ่งการศึกษาของคุณออกเป็นหลายไฟล์ ( class01
, ... , classNM
) และคุณต้องการ: คอมไพล์แล้วทั้งหมดและเรียกใช้ทีละรายการหรือคอมไพล์ที่ เวลาและรันหากระบุแฟล็ก ( -r
ตัวอย่างเช่น) ดังนั้นคุณสามารถคิดสิ่งต่อไปนี้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
คุณมี:
make -r class02
;make
หรือmake all
;make -r
(สมมติว่าพวกเขาทั้งหมดมีเนื้อหายืนยันบางประเภทและคุณต้องการทดสอบทั้งหมด)มันดูเหมือน
คำสั่ง args เขียนทับตัวแปรสภาวะแวดล้อม
Makefile
send:
echo $(MESSAGE1) $(MESSAGE2)
เรียกใช้ตัวอย่าง
$ MESSAGE1=YES MESSAGE2=NG make send MESSAGE2=OK
echo YES OK
YES OK
หากคุณสร้างไฟล์ชื่อ Makefile และเพิ่มตัวแปรเช่น $ (unittest) คุณจะสามารถใช้ตัวแปรนี้ใน Makefile ได้แม้จะมีสัญลักษณ์แทน
ตัวอย่าง:
make unittest=*
ฉันใช้ BOOST_TEST และให้การแทนที่สัญลักษณ์กับพารามิเตอร์ --run_test = $ (ไม่ตอบ) แล้วฉันจะสามารถใช้นิพจน์ทั่วไปเพื่อกรองการทดสอบที่ฉันต้องการให้ Makefile ทำงาน
export ROOT_DIR=<path/value>
จากนั้นใช้ตัวแปร$(ROOT_DIR)
ใน Makefile
make A='"as df"'