Eksperymentuję z wykorzystaniem Shake do budowania kodu Java i jestem nieco zablokowany z powodu niezwykłej natury kompilatora javac. Ogólnie dla każdego modułu dużego projektu kompilator jest wywoływany z all plików źródłowych dla tego modułu jako danych wejściowych i tworzy wszystkie pliki wyjściowe w jednym przebiegu. Następnie zwykle bierzemy pliki .class produkowane przez kompilator i łączymy je w plik JAR (w zasadzie po prostu ZIP).Kompilatory z wieloma wejściami i wieloma wyjściami z Shake
Na przykład, typowy projekt Java moduł umieszczony jest w następujący sposób:
src
katalogu, który zawiera wiele plików .java, niektóre z nich zagnieżdżone wiele poziomów głęboko w drzewie.- a
bin
katalog zawierający dane wyjściowe kompilatora. Zwykle dane wyjściowe mają tę samą strukturę katalogów i nazwy plików, a każdy plik .java zastępuje.class
, ale mapowanie to: , a nie niekoniecznie jeden do jednego: pojedynczy plik .java może wygenerować zero do wielu plików .class!
Zasady chciałbym zdefiniować w wstrząsnąć są zatem następujące:
1) Jeżeli każdy plik pod src
jest nowszy niż każdy plik pod bin
następnie usunąć całą zawartość z bin
i odtworzyć z:
javac -d bin <recursive list of .java files under src>
wiem zasada ta wydaje się zbędne, ale bez wywoływania kompilator wagowo e nie może znać zakresu zmian danych wyjściowych wynikających nawet z niewielkiej zmiany w jednym pliku wejściowym.
2) jeżeli każdy plik pod bin
jest nowszy niż module.jar
następnie odtworzyć module.jar
z:
jar cf module.jar -C bin .
Many thanks!
PS Odpowiedzi w żyle "po prostu użyj Ant/Maven/Gradle /" nie zostaną docenione! Wiem, że te narzędzia oferują kompilację Java, ale są znacznie trudniejsze w komponowaniu i agregowaniu. Właśnie dlatego chcę eksperymentować z narzędziem opartym na Haskell/Shake.
Świetnie, dzięki Neil! Zasadniczo działa, ale wymagane są kilka drobnych zmian. Na przykład potrzebujemy "potrzebować" pełnej ścieżki plików .java i .class, w tym prefiksu src/bin. Musimy również jawnie utworzyć katalog 'bin' przed wywołaniem javac. Czy powinienem edytować odpowiedź? –
Tak, proszę! Podejrzewam, że jeśli zmienisz getDirectoryFiles na "" ["src // *. Java"], będzie to łatwiejsze niż wcześniejsze src, chociaż oba powinny zachowywać się identycznie (i równie skutecznie). Do stworzenia katalogu potrzebny będzie liftIO $ createDirectory - zwykle nie jest to konieczne, ponieważ shake tworzy wszystkie katalogi dla wyjść, o których wie, ale tutaj nie wie o bin. –
Robię coś podobnego, ale wydaje mi się, że wchodzę w "wątek blokowany w nieskończoność w operacji MVar", kiedy potrzebuję 'dynamicznie generowanych ścieżek FilePath. – user239558