2010-07-20 24 views
5

Giả sử có một chương trình C, lưu trữ phiên bản của nó trong toàn cầu char* trong main.c. Có thể hệ thống builds (gnu make) bằng cách nào đó trích xuất giá trị của biến này vào thời gian xây dựng, sao cho tệp thi hành được xây dựng có thể có tên phiên bản chính xác như nó xuất hiện trong chương trình không?Có thể gán các biến makefile với các giá trị được đọc từ các tệp nguồn không?

Những gì tôi muốn đạt được là đưa nguồn:

char g_version[] = "Superprogram 1.32 build 1142"; 

các buildsystem sẽ tạo ra một file thực thi có tên Superprogram 1.32 build 1142.exe

Trả lời

5

Các shell function cho phép bạn gọi các ứng dụng bên ngoài như sed có thể được được sử dụng để phân tích nguồn cho các chi tiết được yêu cầu.

+0

Mặc dù chuỗi phiên bản của ông có vẻ nghi ngờ hand-crafted, tôi cũng sẽ khuyên nên kiểm tra 'công cụ what'. Điều đó cộng với 'vỏ 'có thể là những gì anh ta đang tìm kiếm. – Dummy00001

+0

Cảm ơn bạn đã trả lời, điều này có thể thực sự hoạt động, miễn là tôi tăng tốc độ khả năng của mình trên sed (và các utils khác, được đề cập dưới đây bởi mouviciel) ... – Manjabes

1

Bạn có thể sử dụng bất kỳ tổ hợp công cụ văn bản unix nào (grep, sed, awk, perl, tail, ...) trong Makefile của bạn để trích xuất thông tin đó từ tệp nguồn.

5

Xác định biến phiên bản của bạn từ một Macro:

char g_version[] = VERSION; 

sau đó hãy chắc makefile của bạn đặt một lập luận -D trên dòng lệnh khi biên dịch

gcc hack.c -DVERSION=\"Superprogram\ 1.99\" 

Và dĩ nhiên bạn nên sử dụng trong ví dụ của bạn sed/grep/awk vv để tạo chuỗi phiên bản của bạn.

+0

Tôi biết tùy chọn -D, nhưng điều đó không thể áp dụng được trong trường hợp này. Chuỗi phiên bản phải ở vị trí cũ. – Manjabes

0

Thông thường các phiên bản được định nghĩa là một thành phần của nhiều #define giá trị (như trong arv library ví dụ).

Vì vậy, chúng ta hãy đi cho một ví dụ đơn giản và làm việc:

// myversion.h 
#define __MY_MAJOR__ 1 
#define __MY_MINOR__ 8 

Sau đó, trong Makefile của bạn:

# Makefile 
source_file := myversion.h 
MAJOR_Identifier := __MY_MAJOR__ 
MINOR_Identifier := __MY_MINOR__ 

MAJOR := `cat $(source_file) | tr -s ' ' | grep "\#define $(MAJOR_Identifier)" | cut -d" " -f 3` 
MINOR := `cat $(source_file) | tr -s ' ' | grep '\#define $(MINOR_Identifier)' | cut -d" " -f 3` 

all: 
    @echo "From the Makefile we extract: MAJOR=$(MAJOR) MINOR=$(MINOR)" 

Giải thích

Ở đây tôi đã sử dụng một số công cụ để nó là nhiều mạnh mẽ:

  • tr -s ' ': để loại bỏ thêm không gian giữa các yếu tố,
  • grep: để chọn dòng độc đáo phù hợp với mục đích của chúng tôi,
  • cut -d" " -f 3: để trích xuất các yếu tố thứ ba của dòng chọn là giá trị mục tiêu!

Lưu ý rằng giá trị xác định có thể là bất kỳ thứ gì (không chỉ số).

Cẩn thận sử dụng := (không =) xem: https://stackoverflow.com/a/10081105/4716013

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