Làm thế nào để tiếp tục biên dịch?


11

Tôi biết rằng tôi có thể làm gián đoạn một makequá trình bất cứ lúc nào mà không cần phải biên dịch lại toàn bộ cây nguồn. Như tôi biết, makechỉ biên dịch một mục tiêu nếu nó chưa được biên dịch hoặc mã nguồn được sửa đổi sau lần biên dịch cuối cùng.
Nhưng nếu tôi làm gián đoạn make, chắc chắn sẽ có một hoặc nhiều (tùy theo mức độ đồng thời) các nhị phân sẵn sàng một nửa. Nó làm gì với chúng trong lần tiếp theo tôi chạy make? Hoặc nó hoàn thành mục tiêu hiện tại khi tôi nhấn Ctrl+ Cđể tránh các nhị phân được biên dịch một phần?


2
Hầu như bạn chỉ cần lo lắng nếu máy tính tắt đột ngột. Một vài lần Ubuntu của tôi đã xoay sở để gặp bế tắc hạt nhân (hoặc bất kể đó là gì) và để lại các nhị phân sẵn sàng một nửa, cuối cùng đã lãng phí hơn hai giờ.
Alvin Wong

Câu trả lời:


12

Nói một cách đơn giản, bạn có thể nghĩ rằng makecó một số bước (có thể lớn), trong đó mỗi bước lấy một số tệp làm đầu vào và tạo một tệp làm đầu ra.

Một bước có thể là "biên dịch file.cthành file.o" hoặc "sử dụng ldđể liên kết main.ofile.ovào program". Nếu bạn ngắt makevới CtrlC, sau đó bước hiện đang thực hiện sẽ được chấm dứt mà sẽ (hoặc phải) loại bỏ các tập tin đầu ra nó đã làm việc trên. Thường không có bất kỳ "nhị phân nửa sẵn sàng" nào bị bỏ lại.

Khi bạn khởi động lại make, nó sẽ xem các dấu thời gian của tất cả các tệp đầu vào và đầu ra và chạy lại các bước trong đó:

  • một tệp đầu vào có dấu thời gian mới hơn tệp đầu ra
  • tập tin đầu ra không tồn tại

Điều này thường có nghĩa là nếu một bước mất nhiều thời gian để chạy (điều này hiếm thấy trên các máy tính hiện đại, nhưng ldbước cho các chương trình lớn có thể dễ dàng mất nhiều phút khi makeđược thiết kế), sau đó dừng và khởi động lại makesẽ bắt đầu lại từ đầu.

Thực tế trung bình của bạn Makefilephức tạp hơn đáng kể so với mô tả ở trên, nhưng các nguyên tắc cơ bản là như nhau.


8

Ctrl+ Ckhiến a SIGINTđược gửi đến tiến trình đang chạy. Tín hiệu này có thể được bắt bởi quá trình. Trong mã nguồn, bạn có thể tìm thấy bẫy cho tín hiệu này trong commands.c:

  /* If we got a signal that means the user
     wanted to kill make, remove pending targets.  */

  if (sig == SIGTERM || sig == SIGINT

  ... remove childrens ...

  /* Delete any non-precious intermediate files that were made.  */

  remove_intermediates (1);

remove_intermediates()là chức năng dọn dẹp của make, xem định nghĩa của nó ở đây:

/* Remove all nonprecious intermediate files.
   If SIG is nonzero, this was caused by a fatal signal,
   meaning that a different message will be printed, and
   the message will go to stderr rather than stdout.  */

Và sau này trong chức năng bạn thấy, chúng sẽ bị xóa một cách hiệu quả:

status = unlink (f->name);

Kết luận: Nói chung đừng sợ làm gián đoạn việc biên dịch với make. Nếu nó không phải là tín hiệu không thể so sánh được ( SIGKILL, SIGSEGV, SIGSTOP) thì nó sẽ dọn sạch các tệp trung gian.


1
SIGSEGVcó thể bắt được trên nhiều Unices.
Chris Xuống

1

Khi một cái gì đó dừng lại make(có thể là ctrl-C, tắt máy hoặc thậm chí là một lệnh không thành công), công việc đã hoàn thành. Khi được trình bày lại, hãy makelàm như mọi khi: nó chỉ ra những gì vẫn cần phải làm (vì một tệp đã thay đổi hoặc makekhông bao giờ phải xử lý nó không quan trọng) và tiếp tục công việc.

Mô tả ở trên giả định rõ ràng các Makefiles có liên quan mô tả các phụ thuộc và các lệnh để thực thi chính xác, vì vậy tất cả những gì cần phải được thực hiện lại.

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.