Table of Contents
Giới thiệu
Trong chương trình C, một chương trình thường được chia sẻ qua nhiều tập tin nguồn và tập tin đầu nguồn khác nhau để cải tiến tổ chức, khả năng phục hồi và tốc độ tính năng hiệu chỉnh. Tuy nhiên, tính năng này đưa ra một thách thức: khi tập tin phụ đề thay đổi, mỗi tập tin nguồn chứa nó phải được giải quyết bằng tay. Làm cho tập tin này là lỗi này là lỗi chính tả và thời gian tính toán. Làm cho tập tin [FL: 0] được điều khiển [FL: 0] tạo [FL: 1] thành [FL:] khả năng tự động tạo [FL: 1], công cụ giải quyết vấn đề này bằng cách mã và tự động cấu trúc phụ thuộc. Làm cho tập tin này là một quá trình cải tiến nghiêm trọng, phát triển các tập tin màu đen, như thế nào để tạo tập tin cấu trúc tự động và tạo tập tin cấu trúc tự động.
Tạo ra các tập tin nào?
Một tập tin Makefile là một tập tin văn bản đơn giản định nghĩa một tập hợp các quy tắc để xây dựng một dự án. Tiện ích đọc những quy tắc này, kiểm tra giờ, nhãn giờ, và thực hiện chỉ những lệnh cần thiết để đưa dự án lên ngày. Ý tưởng chính là đơn giản: mỗi quy tắc có [FL:2] [FLT:] [FLT:] [FLT] (tập tin để tạo ra], [FL4] có thể làm cho tập tin thay đổi [FT], [FT], Bản sao], mà chỉ có thể làm cho tập tin có khả năng ghi chú [FT].
Các tập tin tạo tập tin đã thuộc về Unix từ những năm 1970, và GNU Make là tiêu chuẩn thực tế trên Linux và MacOS. Quyền cú pháp là ngắn gọn nhưng có thể tinh tế; quyền phụ thuộc là kỹ năng chính yếu mà người phát triển C cần.
Hiểu các quan hệ phụ thuộc
Trong một dự án C, phụ thuộc không chỉ có các tập tin . Mỗi tập tin nguồn chứa một hay nhiều tập tin đầu (v., [FLT: 1). Nếu tập tin đầu bị sửa đổi, tất cả ) cần phải được sao chép lại. Tương tự, tập tin đối tượng phụ thuộc vào tập tin [FLT:] tương ứng với tập tin [FLT:], và tập tin thực hiện cuối cùng phụ thuộc vào mọi đối tượng.
Mở rộng và phù hợp với phụ thuộc
Trong các tập tin đầu tiên, lập trình viên liệt kê tất cả các điều kiện tiên quyết bằng tay. Cách tiếp cận đó là mong manh: quên đi đầu đề có nghĩa là xây dựng cũ, trong khi liệt kê quá nhiều kích hoạt cần thiết. Tệ hơn, khi dự án tăng, danh sách hướng dẫn trở nên không bền vững. Giải pháp hiện đại là có bộ biên dịch tự động tạo ra các phụ thuộc, chuyển chúng thành điều kiện tối ưu tiên ( máy) tiềm ẩn, kiểm tra điều khiển máy.
Một tập tin Makefile được khéo léo quản lý xem quan hệ phụ thuộc là mối quan tâm cấp bậc đầu tiên. Mục tiêu không bao giờ là xây dựng lại bất cứ điều gì không cần thiết, và luôn luôn xây dựng lại mọi thứ. Đây là bản chất của [FLT: 0] [FLT: 1] và ) sự phát triển ).
Sự cấu tạo cơ bản của một tập tin tạo hình
Một tập tin Makefile điển hình chứa định nghĩa biến, quy tắc và mục tiêu giả. Dưới đây là một ví dụ tối thiểu nhưng chức năng cho một dự án có và :]:
CC = gcc
CFLAGS = -Wall -Wextra -O2
main: main.o utils.o
$(CC) $(CFLAGS) -o main main.o utils.o
main.o: main.c
$(CC) $(CFLAGS) -c main.c
utils.o: utils.c
$(CC) $(CFLAGS) -c utils.c
clean:
rm -f main main.o utils.o
Tập tin Makefile này có bốn mục tiêu: (có thể thực hiện), hai tập tin đối tượng, và một mục tiêu giả . Đường kẻ phụ thuộc sau khi nói [FLT: 0]] làm [FLT: 1] mà tập tin cần kiểm tra trước khi quyết định tái thiết đích.
Mục tiêu Xyne
Những mục tiêu như hoặc không đại diện cho tập tin. Để ngăn chặn [FLT: 0] làm [FLT:] để làm [FLT: 1] cho chúng bị nhầm lẫn với tên tập tin, chúng nên được tuyên bố là phony :]::]:::
.PHONY: clean all
Nếu không có điều này, nếu một tập tin tên tồn tại, sẽ làm xem nó lên đến ngày tháng và bỏ qua công thức.
Quản lý các quan hệ phụ thuộc một cách hiệu quả
Tập tin làm sạch thủ công ở trên có một lỗi nghiêm trọng: phụ thuộc vào là đúng, còn về đầu đề thì sao? Nếu , (mà bao gồm cả] thì phải được tái lập, nhưng quy tắc chỉ phụ thuộc vào . Việc sửa đổi là để cho người biên dịch tạo ra danh sách thật.
Thế hệ phụ thuộc tự động với GCC
GCC (và Clang) có thể tạo thông tin phụ thuộc bằng họ cờ . Tổ hợp thực tế nhất cho hầu hết các dự án là :]:
- ) – viết một tập tin phụ thuộc ( trong khi tính toán, liệt kê chỉ người dùng xác định tiêu đề (không phải tiêu đề hệ thống).
- – xác định tên của tập tin phụ thuộc.
- ) – thêm mục tiêu giả cho mỗi đầu trang, ngăn chặn lỗi khi một đầu đề bị gỡ bỏ.
Đây là cách kết hợp quan hệ phụ thuộc tự động vào một tập tin tạo:
CC = gcc
CFLAGS = -Wall -Wextra -O2 -MMD -MP
SRCDIR = src
OBJDIR = obj
SRCS = $(wildcard $(SRCDIR)/*.c)
OBJS = $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SRCS))
DEPS = $(OBJS:.o=.d)
all: myprogram
myprogram: $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
$(OBJDIR)/%.o: $(SRCDIR)/%.c
@mkdir -p $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@
-include $(DEPS)
.PHONY: all clean
clean:
rm -rf $(OBJDIR) myprogram
Giải thích:
- thu thập tất cả các tập tin trong thư mục nguồn.
- biến chúng thành đường dẫn đối tượng.
- liệt kê các tập tin phụ thuộc (v. d., .
- Quy tắc mẫu biên dịch mỗi tập tin và, vì , tạo ra một tập tin là một hiệu ứng phụ.
- Dòng đọc các tập tin tạo , biến chúng thành những điều kiện tiên quyết thật. Đường gạch () đè nén lỗi khi tập tin chưa tồn tại (v. d. vào lần xây dựng đầu tiên.
Bây giờ, nếu bị sửa đổi, lần cầu hôn kế tiếp sẽ tự động vì tập tin bao gồm như một điều kiện tiên quyết.
Kỹ thuật cao cấp
Việc giải quyết các mối quan hệ phụ thuộc được an toàn
Khi một đầu trang bị xoá, tập tin có thể vẫn còn tham chiếu nó, gây ra [FLT: 0] làm [FLT: 1] lỗi [FLT:]. Cờ chỉ đơn giản chạy lệnh giả (không làm gì cả) và tiếp tục.
Bao gồm các tập tin quan hệ phụ thuộc sau khi nguồn thay đổi
Một tinh tế: nếu tập tin gốc được thêm hay gỡ bỏ một , tập tin tương ứng cần được tái tạo. Vì tập tin là điều kiện tiên quyết của tập tin đối tượng, sẽ tạo ) để làm [FLT: 1], mà được thay đổi thời gian và tính toán, mà tái tạo tập tin . Việc này tự động làm việc lại khi đã hoàn tất.
Chỉ dùng lệnh của người được chọn
Đôi khi bạn cần một thư mục để tồn tại trước khi xây cất, nhưng bạn không muốn dấu giờ để khởi động lại.
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR):
mkdir -p $@
Việc này bảo đảm thư mục được tạo trước khi có sự tính toán nào, nhưng việc thay đổi thư mục (v. d., tập tin mới bên trong) sẽ không kích hoạt khả năng phục hồi lại.
Những thực hành tốt nhất để quản lý các phụ thuộc
- , hãy dùng thế hệ phụ thuộc tự động từ ngày đầu.
- Giữ riêng các tập tin phụ thuộc khỏi tập tin nguồn ). Đặt chúng vào hoặc thư mục. Điều này làm cho việc làm sạch dễ dàng hơn và tránh làm lộn xộn cây nguồn.
- Chỉ thị là tốt, nhưng đặt nó sau khi quy tắc ) làm [FLT:] [FLT: 1] chỉ thị , nhưng đặt nó sau khi quy tắc ) bảo đảm ) [FLT:] [FLT:] trước tiên] làm [FLT:] biết làm thế nào để xây dựng tập tin [FLT] trước khi đọc tập tin .
- sử dụng mục tiêu giả để giữ nhà. , , , và là phổ biến. Luôn luôn tuyên bố chúng với .
- Biến số thay đổi cho việc biên dịch cờ, thư mục nguồn và danh sách tập tin. Điều này làm cho các tập tin có khả năng tái sử dụng qua các dự án và tùy chỉnh dễ dàng hơn.
- Đặt tên tập tin Makefile của bạn với một thay đổi đầu trang cố ý. sửa đổi đầu trang, chạy , và chỉ kiểm tra lại tập tin ảnh hưởng. Nếu việc xây dựng lại đầy đủ xảy ra, việc theo dõi quan hệ phụ thuộc bị lỗi.
- Giữ tập tin Makefile đơn giản nhưng không đơn giản hơn cần thiết. Quá trình điều chỉnh với các chức năng tiên tiến như có thể gây ra đau đớn. Bắt đầu với mẫu được hiển thị trong bài này; nó cân bằng nhiều tập tin.
Tài nguyên bên ngoài
Để hiểu rõ hơn, hãy tham khảo những tài liệu có thẩm quyền sau:
- Sổ tay làm ra ) – Hướng dẫn chắc chắn để làm cú pháp, chức năng và tính năng tiên tiến.
- Tùy chọn trước khi xử lý ) – Tài liệu cho , , , và cờ liên quan.
- Tạo ra sự gia sư của Chase Lambert ) – Một cơ sở thực tiễn, tốt bao gồm nhiều trường hợp thực tế sử dụng.
Kết luận
Quản lý các phụ thuộc C với Makefiles không phải là một xa hoa, nhưng là một điều cần thiết cho bất kỳ dự án nào phát triển nhanh và đúng. Bằng cách kết hợp các quy tắc mẫu tự động, thế hệ phụ thuộc với , và cẩn thận cấu hình tập tin tạo , bạn có thể tạo một hệ thống xây dựng vừa nhanh vừa đúng. Các kỹ thuật ở đây loại bỏ khả năng theo dõi bằng tay, xây dựng thời gian, và ngăn chặn lỗi gây ra bởi tập tin bị lỗi. Một khi bạn nội bộ hoá các mẫu này, bạn sẽ không bao giờ viết lại một danh sách phụ thuộc bằng tay. Trong việc học quản lý quan hệ thống phụ thuộc đúng đắn, bạn có thể trả tiền mỗi [F] và chỉ thay đổi tập tin.