Bỏ qua điều hướng, tới nội dung chính
Học C
Bài 37.124 phút đọc

Cú pháp cơ bản và cái bẫy TAB

Sau bài này bạn sẽ làm được

  • Viết một quy tắc mục tiêu, phụ thuộc, công thức
  • Giải thích vì sao Make chỉ dựng lại cái cần dựng
  • Tránh lỗi TAB số một của người mới
  • Dùng .PHONY cho mục tiêu không phải file

Make trả lời một câu hỏi đơn giản: khi bạn sửa một tệp, cần dịch lại những gì, và không dịch lại những gì. Với một chương trình chục tệp, câu trả lời đúng tiết kiệm hàng phút mỗi lần dựng.

#Vấn đề Make giải

# Khong co Make: go tay moi lan, dich LAI TAT CA
gcc -std=c17 -Iinclude src/main.c src/toan.c src/db.c ... -o app

/* Hai van de:
   1. Ban go lai dong dai nay moi lan, va de go sai.
   2. Sua MOT dong trong main.c van dich lai CA db.c va toan.c,
      du chung khong doi. Voi 100 file, do la phut cho vo ich.

   Make giai ca hai:
     - Ban viet cong thuc MOT lan trong Makefile.
     - Make so THOI GIAN SUA cua file nguon voi file dich, va
       chi dich lai cai nao co nguon MOI HON dich. */
Make
Một công cụ dựng dựa trên thời gian sửa tệp. Bạn khai báo mục tiêu nào phụ thuộc tệp nào, và công thức để tạo mục tiêu. Make so thời gian sửa và chỉ chạy công thức cho mục tiêu có phụ thuộc mới hơn nó.

#Cú pháp một quy tắc

Một quy tắc Make
muc_tieu: phu_thuoc1 phu_thuoc2
<TAB>cong_thuc

# Vi du cu the:
app.exe: main.o toan.o
	gcc main.o toan.o -o app.exe

main.o: main.c toan.h
	gcc -c main.c -o main.o

toan.o: toan.c toan.h
	gcc -c toan.c -o toan.o

#Chỉ dựng cái cần

terminal
# Lan dau: dich moi thu
make
gcc -std=c17 -Wall -Wextra -Iinclude -MMD -MP -c src/main.c -o build/main.o
gcc -std=c17 -Wall -Wextra -Iinclude -MMD -MP -c src/toan.c -o build/toan.o
gcc build/main.o build/toan.o -o build/app.exe
==> Da build: build/app.exe
# Lan hai, khong doi gi: Make khong lam gi
make
mingw32-make: Nothing to be done for 'all'.
terminal
# Sua RIENG toan.c
touch src/toan.c && make
gcc -std=c17 -Wall -Wextra -Iinclude -MMD -MP -c src/toan.c -o build/toan.o
gcc build/main.o build/toan.o -o build/app.exe
==> Da build: build/app.exe

#Cái bẫy TAB

#.PHONY

Mục tiêu giả (phony)
Một mục tiêu không tương ứng với tệp thật, ví dụ clean hay run. Khai báo nó là .PHONY để Make luôn chạy công thức, không so thời gian với một tệp cùng tên.
Vì sao cần .PHONY
clean:
	rm -f build/*.o build/app.exe

# Van de: neu tinh co co mot FILE ten "clean" trong thu muc,
# thi Make thay "clean da ton tai va khong co phu thuoc moi hon"
# -> "make clean" bao "Nothing to be done" va KHONG xoa gi.

# Chua: khai bao clean la phony
.PHONY: clean run all
clean:
	rm -f build/*.o build/app.exe

# Bay gio Make hieu "clean" khong phai file, luon chay cong thuc.
terminal
# Khong co .PHONY, va co file ten 'clean' trong thu muc:
touch clean && make clean
mingw32-make: 'clean' is up to date.
# Voi .PHONY: clean, luon chay
make clean
rm -f build/*.o build/app.exe
Thiếu .PHONY
all: app.exe clean: rm -f build/* run: app.exe ./app.exe test: app.exe ./run_tests.sh # Neu co file all, clean, run, hay test trong thu muc, # cac muc tieu do ngung hoat dong mot cach kho hieu.
Khai báo phony đầy đủ
.PHONY: all clean run test all: app.exe clean: rm -f build/* run: app.exe ./app.exe test: app.exe ./run_tests.sh # Moi muc tieu khong-phai-file deu duoc liet ke .PHONY. # Quy tac: neu cong thuc khong TAO ra mot file cung ten muc tieu, # thi muc tieu do la phony.

Tự làm thử

  1. Viết một Makefile ba quy tắc cho một chương trình hai tệp và dựng được.
  2. Sửa một tệp và quan sát Make chỉ dịch lại tệp đó.
  3. Thay TAB bằng dấu cách và đọc thông báo lỗi Make đưa ra.
  4. Tạo một tệp tên clean và chứng minh mục tiêu clean ngừng hoạt động khi thiếu .PHONY.
  5. Thêm @ vào một lệnh echo và so đầu ra có và không có nó.
  6. Thêm mục tiêu run phụ thuộc chương trình và chạy nó.

Trình chấm điểm tự động sẽ được bổ sung ở giai đoạn sau. Hiện tại bạn tự chạy thử trên máy.

Tóm tắt

  • Make dựng lại chỉ những mục tiêu có phụ thuộc mới hơn chúng, dựa trên thời gian sửa tệp.
  • Một quy tắc gồm mục tiêu, phụ thuộc, và công thức; mục tiêu đầu tiên là mặc định.
  • Một thay đổi lan lên theo đồ thị phụ thuộc, dựng lại đúng những gì cần.
  • Công thức phải bắt đầu bằng TAB, không phải dấu cách; đó là lỗi số một của người mới.
  • Mục tiêu không tạo tệp phải là .PHONY; @ ẩn lệnh, - bỏ qua lỗi.