Tôi đang thử nghiệm bằng cách sử dụng Shake để xây dựng mã Java và có một chút khó khăn do tính chất bất thường của trình biên dịch javac. Nói chung cho mỗi mô-đun của một dự án lớn, trình biên dịch được gọi với tất cả của các tệp nguồn cho mô-đun đó làm đầu vào và tạo tất cả các tệp đầu ra trong một lần truyền. Sau đó, chúng tôi thường lấy các tệp .class do trình biên dịch tạo và lắp ráp chúng thành một JAR (về cơ bản chỉ là một ZIP).Trình biên dịch nhiều đầu vào, nhiều đầu ra với Shake
Ví dụ, một dự án module Java điển hình được bố trí như sau:
- một thư mục
src
có chứa nhiều file java, một số trong số họ lồng nhau nhiều cấp độ sâu trong một cái cây. - một thư mục
bin
chứa đầu ra từ trình biên dịch. Thông thường, đầu ra này theo cùng cấu trúc thư mục và tên tệp, với.class
được thay thế cho mỗi tệp .java, nhưng ánh xạ là không phải là nhất thiết là một: một tệp .java có thể tạo không cho nhiều tệp .class! do đó
Các quy tắc tôi muốn xác định trong Shake như sau:
1) Nếu bất kỳ tập tin dưới src
mới hơn bất kỳ tập tin dưới bin
sau đó xóa tất cả nội dung của bin
và tái tạo với:
javac -d bin <recursive list of .java files under src>
Tôi biết quy tắc này có vẻ quá mức nhưng không yêu cầu trình biên dịch e không thể biết mức độ thay đổi trong đầu ra do thậm chí là một thay đổi nhỏ trong một tệp đầu vào đơn lẻ.
2) nếu bất kỳ tập tin dưới bin
mới hơn module.jar
sau đó tái module.jar
với:
jar cf module.jar -C bin .
Rất cám ơn!
PS Câu trả lời trong tĩnh mạch "chỉ cần sử dụng Ant/Maven/Gradle /" sẽ không được đánh giá cao! Tôi biết những công cụ này cung cấp Java compilation out-of-the-box, nhưng chúng khó hơn nhiều để soạn và tổng hợp. Đây là lý do tại sao tôi muốn thử nghiệm với một công cụ dựa trên Haskell/Shake.
Tuyệt vời, cảm ơn Neil! Điều này về cơ bản hoạt động nhưng một vài thay đổi nhỏ là bắt buộc. Ví dụ chúng ta cần 'cần' đường dẫn đầy đủ của các tệp .java và .class bao gồm tiền tố src/bin. Ngoài ra chúng ta cần tạo thư mục 'bin' một cách rõ ràng trước khi gọi javac. Tôi có nên chỉnh sửa câu trả lời của bạn không? –
Có, vui lòng! Tôi nghi ngờ nếu bạn thay đổi getDirectoryFiles thành "" ["src // *. Java"] sẽ dễ dàng hơn so với src trước sau đó, mặc dù cả hai sẽ hoạt động giống hệt nhau (và chỉ hiệu quả). Để tạo thư mục, bạn sẽ cần liftIO $ createDirectory - thường không cần thiết vì shake tạo ra tất cả các thư mục cho các kết quả đầu ra mà nó biết, nhưng ở đây nó không biết về bin. –
Tôi đang làm một cái gì đó tương tự, nhưng tôi dường như nhận được vào "thread bị chặn vô thời hạn trong một hoạt động MVar" khi tôi 'cần' FilePaths được tạo động. – user239558