Làm cách nào để chuyển định nghĩa macro từ các đối số dòng lệnh “make” (-D) sang mã nguồn C?


107

Tôi thường chuyển các định nghĩa macro từ "dòng lệnh make" sang "makefile" bằng cách sử dụng tùy chọn: -Dname = value. Định nghĩa có thể truy cập được bên trong makefile.

Tôi cũng chuyển các định nghĩa macro từ "makefile" sang "mã nguồn" bằng cách sử dụng tùy chọn trình biên dịch tương tự: -Dname = value (được hỗ trợ trong nhiều trình biên dịch). Định nghĩa này có thể truy cập được trong mã nguồn.

Điều tôi cần bây giờ là cho phép người dùng makefile của tôi có thể chuyển các định nghĩa macro tùy ý từ "dòng lệnh make.exe" sang "mã nguồn" ngay lập tức mà không cần phải thay đổi bất kỳ điều gì trong makefile.

vì vậy người dùng có thể gõ: make -f mymakefile.mk -SOMEOPTION var = 5

sau đó trực tiếp mã main.c có thể thấy var:

int main()
{
  int i = var;
}

15
Tại sao lại ủng hộ? Có vẻ như một câu hỏi hoàn toàn chính đáng đối với tôi.
Thomas

Câu trả lời:


99

Gọi makelệnh theo cách này:

make CFLAGS=-Dvar=42

Và hãy chắc chắn sử dụng $(CFLAGS)lệnh biên dịch của bạn trong Makefile. Như @ jørgensen đã đề cập, việc gán biến sau makelệnh sẽ ghi đè CFLAGSgiá trị đã được xác định trên Makefile.

Ngoài ra, bạn có thể đặt -Dvar=42trong một biến khác CFLAGSvà sau đó sử dụng lại biến này CFLAGSđể tránh ghi đè hoàn toàn CFLAGS.


8
Bạn không thể sử dụng "CFLAGS = $ (CFLAGS) -Wall"; đây sẽ là một định nghĩa đệ quy và make không cho phép điều này. Bạn có thể sử dụng "CFLAGS: = $ (CFLAGS) -Wall" hoặc "CFLAGS + = -Wall", nhưng những thứ đó cũng sẽ không hoạt động vì một phép gán trên dòng lệnh có mức độ ưu tiên cao hơn. Bạn có thể sử dụng "ghi đè CFLAGS + = -Wall", nhưng nói chung, chúng tôi khuyên bạn chỉ nên chọn các biến khác nhau trong nội bộ. Tiêu chuẩn mã hóa GNU yêu cầu CFLAGS, v.v. được để lại cho người dùng và các tệp thực hiện chọn một biến khác, như "local_CFLAGS = $ (CFLAGS) -Wall".
MadScientist,

2
Chỉ cần thêm vào ghi chú @MadScientist, Tiêu chuẩn mã hóa GNU cũng nêu rõ tiêu chuẩn đó $(CFLAGS)sẽ đến sau cùng, vì vậy bất kỳ tùy chọn nào do người dùng chỉ định sẽ ghi đè bất kỳ thứ gì Makefile đặt bên trong. Điều đó có nghĩa là sử dụng vd local_CFLAGS = -Wall $(CFLAGS). Ngược lại, nếu có điều gì đó bạn thực sự muốn ưu tiên, hãy đặt nó sau $(CFLAGS), như trong nhận xét của @MadScientist.
Sam

1
Làm thế nào để đặt nhiều macro bằng cách này?
Woody Huang

2
@WoodyHuang chẳng hạnCFLAGS="-Dvar1=42 -Dvar2=314"
ouah

1
CPPFLAGScó thể đại diện cho một sự phù hợp tốt hơn CFLAGShay CXXFLAGS: stackoverflow.com/a/53527858/2278206
psq

11

Chỉ cần sử dụng một biến cụ thể cho điều đó.

$ cat Makefile 
all:
    echo foo | gcc $(USER_DEFINES) -E -xc - 

$ make USER_DEFINES="-Dfoo=one"
echo foo | gcc -Dfoo=one -E -xc - 
...
one

$ make USER_DEFINES="-Dfoo=bar"
echo foo | gcc -Dfoo=bar -E -xc - 
...
bar

$ make 
echo foo | gcc  -E -xc - 
...
foo

10

Gọi theo cách này

make CFLAGS=-Dvar=42

bởi vì bạn muốn ghi đè CFLAGS của Makefile chứ không chỉ môi trường (có mức độ ưu tiên thấp hơn đối với các biến Makefile).


6

Vì danh tiếng thấp, tôi không thể bình luận câu trả lời được chấp nhận.

Tôi muốn đề cập đến biến được xác định trước CPPFLAGS. Nó có thể thể hiện sự phù hợp tốt hơn CFLAGShoặc CXXFLAGS, vì nó được hướng dẫn sử dụng GNU Make mô tả như sau:

Các cờ bổ sung để cung cấp cho bộ tiền xử lý C và các chương trình sử dụng nó (bộ biên dịch C và Fortran).

Ví dụ về các quy tắc ngầm định sẵn sử dụng CPPFLAGS

  • n.ođược tạo tự động từ n.cvới công thức có dạng:
    • $(CC) $(CPPFLAGS) $(CFLAGS) -c
  • n.ođược tạo tự động từ n.cc, n.cpphoặc n.Cvới công thức có dạng:
    • $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c

Người ta sẽ sử dụng lệnh make CPPFLAGS=-Dvar=123để xác định macro mong muốn.

Thêm thông tin


1
$ cat x.mak
tất cả:
    echo $ (TÙY CHỌN)
$ make -f x.mak 'TÙY CHỌN = -DPASSTOC = 42'
echo -DPASSTOC = 42
-DPASSTOC = 42

-4

Tìm tệp C và triển khai Makefile bên dưới để đáp ứng yêu cầu của bạn

foo.c

 main ()
    {
        int a = MAKE_DEFINE;
        printf ("MAKE_DEFINE value:%d\n", a);
    }

Makefile

all:
    gcc -DMAKE_DEFINE=11 foo.c

câu hỏi đặt ra là chuyển các định nghĩa tùy ý từ dòng lệnh make trực tiếp sang mã nguồn C "mà không cần thay đổi makefile". Vì vậy, tôi muốn thay đổi makefile của mình một lần, để cho phép tạo ra những định nghĩa tùy ý đó.
MohamedEzz

Không hiệu quả. Đó là làm cho -DMAKE_DEFINE = 11 cho biết tùy chọn không hợp lệ.
Ramakrishnan Kannan
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.