2010-01-24 40 views
48

Tôi đang sử dụng Makefile của GNU để xây dựng một dự án C với một vài mục tiêu (all, clean và một vài mục tiêu cụ thể của dự án). Trong quá trình gỡ lỗi, tôi muốn nối thêm một số cờ vào một bản dựng duy nhất mà không cần chỉnh sửa vĩnh viễn Makefile (ví dụ: thêm các biểu tượng gỡ lỗi hoặc đặt cờ tiền xử lý).Nối với GNU tạo biến thông qua dòng lệnh

Trong quá khứ, tôi đã làm điều đó như sau (sử dụng những biểu tượng gỡ lỗi chẳng hạn):

make target CFLAGS+=-g 

Thật không may, đây không phải phụ thêm vào biến CFLAGS, nhưng thay vào đó, thanh toán bù trừ nó và ngăn không cho nó biên dịch . Có cách nào làm sạch điều này mà không xác định một số loại biến giả được nối vào cuối CFLAGSLDFLAGS?

Trả lời

65

Khám phá override directive. Bạn có thể sẽ cần phải sửa đổi makefile một lần, nhưng nó sẽ làm những gì bạn muốn.

Ví dụ makefile:

override CFLAGS += -Wall 

app: main.c 
    gcc $(CFLAGS) -o app main.c 

Ví dụ lệnh dòng:

$ make 
gcc -Wall -o app main.c 
$ make CFLAGS=-g 
gcc -g -Wall -o app main.c 
+0

Cảm ơn bạn đã liên kết tham chiếu. Điều này trông giống như một trong những giải pháp tốt hơn cho vấn đề. –

20

Đối với hồ sơ, @Carl Norum của câu trả lời prepends biến, từ góc độ dòng lệnh.

Tôi cần một cách để thực sự gắn và đã đưa ra:

override CFLAGS := -Wall $(CFLAGS) 
6

Chỉ cần một lưu ý, như tôi đã nhầm lẫn - để điều này được tập tin testmake:

$(eval $(info A: CFLAGS here is $(CFLAGS))) 

override CFLAGS += -B 

$(eval $(info B: CFLAGS here is $(CFLAGS))) 

CFLAGS += -C 

$(eval $(info C: CFLAGS here is $(CFLAGS))) 

override CFLAGS += -D 

$(eval $(info D: CFLAGS here is $(CFLAGS))) 

CFLAGS += -E 

$(eval $(info E: CFLAGS here is $(CFLAGS))) 

Sau đó:

$ make -f testmake 
A: CFLAGS here is 
B: CFLAGS here is -B 
C: CFLAGS here is -B 
D: CFLAGS here is -B -D 
E: CFLAGS here is -B -D 
make: *** No targets. Stop. 
$ make -f testmake CFLAGS+=-g 
A: CFLAGS here is -g 
B: CFLAGS here is -g -B 
C: CFLAGS here is -g -B 
D: CFLAGS here is -g -B -D 
E: CFLAGS here is -g -B -D 
make: *** No targets. Stop. 

Với chỉ thị override bị xóa khỏi tệp testmake:

$ make -f testmake 
A: CFLAGS here is 
B: CFLAGS here is -B 
C: CFLAGS here is -B -C 
D: CFLAGS here is -B -C -D 
E: CFLAGS here is -B -C -D -E 
make: *** No targets. Stop. 
$ make -f testmake CFLAGS+=-g 
A: CFLAGS here is -g 
B: CFLAGS here is -g 
C: CFLAGS here is -g 
D: CFLAGS here is -g 
E: CFLAGS here is -g 
make: *** No targets. Stop. 

Vì vậy,

  • nếu một biến được sử dụng override một lần, nó chỉ có thể được nối với một tuyên bố với override (các bài tập bình thường sẽ bị bỏ qua);
  • khi hoàn toàn không có override; cố gắng nối thêm (như trong +=) từ dòng lệnh sẽ ghi đè mọi biến thể của biến đó.
9

Có hai cách để vượt qua các biến để thực hiện:

  • Sử dụng đối số dòng lệnh:

    make VAR=value 
    
  • Sử dụng môi trường:

    export VAR=var; make 
    

    hoặc (tốt hơn bởi vì nó thay đổi môi trường chỉ cho comman hiện tại d)

    VAR=var make 
    

Họ là hơi khác nhau. Cái đầu tiên mạnh hơn. Nó có nghĩa là bạn biết những gì bạn muốn. Thứ hai có thể được coi là một gợi ý. Sự khác biệt giữa chúng là về các toán tử =+= (không có override). Các toán tử này được bỏ qua khi một biến được định nghĩa trên dòng lệnh, nhưng không bị bỏ qua khi biến được định nghĩa trong môi trường. Vì vậy, tôi đề nghị bạn để có một Makefile với:

CC ?= gcc 
    CFLAGS += -Wall 
    INTERNAL_VARS = value 

và gọi nó với:

CFLAGS=-g make 

Chú ý, nếu bạn muốn rút -Wall, bạn có thể sử dụng:

make CFLAGS= 

Vui lòng không sử dụng từ khóa override, nếu không bạn sẽ không có bất kỳ cách nào để thay đổi biến bị ảnh hưởng với override.

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