Przez większość mojej kariery programistycznej korzystałem z polecenia „build / compile / run” w dowolnym środowisku IDE, z którym pracuję, aby stworzyć program, który można uruchomić. To jeden przycisk, całkiem proste. Kiedy uczę się więcej o różnych językach i frameworkach, coraz częściej mówię o „skryptach budujących” (ANT, Maven, Gradle itp.), Aby uruchomić projekt. Rozumiem, że są to instrukcje dla kompilatora / linkera / magicznego programu do tworzenia programów, które określają szczegóły konfiguracji - minucje.
Pamiętam, jak zapisywałem makefile w szkole, ale nie widziałem wtedy żadnej specjalnej korzyści (korzystaliśmy z nich tylko podczas pisania w terminalu uniksowym, gdzie IDE z jego przydatnym przyciskiem „kompilacji” nie było obecne). Poza tym widziałem tutaj inne pytania, które omawiają, w jaki sposób skrypty kompilacji mogą zrobić coś więcej niż tylko tworzenie programu - mogą uruchamiać testy jednostkowe, a także zabezpieczać zasoby, niezależnie od komputera hosta .
Nie mogę pozbyć się wrażenia, że skrypty budowania są ważne, aby zrozumieć je jako programista, ale chciałbym mieć sensowne wyjaśnienie; dlaczego powinienem używać / pisać skrypty kompilacji?
Obowiązki Build Script i Build Server omawiają rolę, jaką odgrywa w szerszym zakresie. Szukam konkretnych zalet oferowanych przez skrypt kompilacji w porównaniu z komendą IDE „build / run” lub podobnie prostymi metodami.
źródło
important to understand as a developer
, choć na pewno nie zawsze. Nawet w środowiskach, w których skrypty budowania są wymaganiami praktycznymi, wielu „programistów” nie będzie się nimi przejmować. Ale skrypty są wtedy ważne dla „konstruktorów”, a nie dla programistów. W ostatnich miejscach, w których pracowałem, większość programistów miała praktycznie zerowe połączenie do tworzenia skryptów.Odpowiedzi:
Automatyzacja.
Kiedy się rozwijasz, tylko w najprostszych projektach domyślny przycisk „buduj” zrobi wszystko, czego potrzebujesz; może być konieczne utworzenie WS z interfejsów API, wygenerowanie dokumentów, połączenie z zasobami zewnętrznymi, wdrożenie zmian na serwerze itp. Niektóre środowiska IDE pozwalają dostosować proces kompilacji poprzez dodanie dodatkowych kroków lub konstruktorów, ale to tylko oznacza, że jesteś generowanie skryptu kompilacji poprzez towary IDE.
Ale rozwój systemu to nie tylko pisanie kodu. W grę wchodzi wiele kroków. Niezależny skrypt IDE można wykonać automatycznie, co oznacza, że:
Po zatwierdzeniu zmiany w kontroli wersji serwer może uruchomić automatycznie nową kompilację. Zapewni to, że nie zapomnisz popełnić niczego, co jest potrzebne do kompilacji.
Podobnie po zakończeniu kompilacji można automatycznie uruchomić testy, aby sprawdzić, czy coś się zepsuło.
Teraz reszta organizacji (QA, sysadmins) ma wbudowany produkt, który
a) jest doskonale odtwarzalny tylko z wersji kontrolnej.
b) jest wspólny dla nich wszystkich.
Nawet kiedy pracowałem jako jednoosobowy zespół, używałem do tego celu skryptów; kiedy opracowałem poprawkę, zobowiązałem się do SVN, wyeksportowałem SVN z powrotem do innego katalogu i użyłem skryptu kompilacji do wygenerowania rozwiązania, które następnie przejdzie do systemów Preprodukcji, a później do Produkcji. Jeśli kilka tygodni później (gdy moja lokalna baza kodów już się zmieniła) ktoś narzekał na błąd, wiedziałbym dokładnie, którą wersję SVN muszę sprawdzić, aby poprawnie debugować system.
źródło
Podobnie jak kod, skrypt kompilacji jest wykonywany przez komputer. Komputery są wyjątkowo dobre w przestrzeganiu zestawu instrukcji. W rzeczywistości (poza kodem samodmodyfikującym) komputery wykonają tę samą sekwencję instrukcji dokładnie w ten sam sposób, przy tych samych danych wejściowych. Zapewnia to poziom spójności, który dobrze pasuje tylko komputer.
Dla kontrastu, wypełnione wodą worki z mięsem są po prostu wręcz godne pogardy, jeśli chodzi o następujące kroki. Ten nieznośny analityczny mózg ma tendencję do kwestionowania wszystkiego, na co się natknie. „Och ... nie muszę tego” lub „Czy naprawdę muszę użyć tej flagi? Eh… Po prostu ją zignoruję”. Ponadto mamy skłonność do samozadowolenia. Po zrobieniu czegoś kilka razy zaczynamy wierzyć, że znamy instrukcje i nie musimy patrzeć na instrukcję.
Z „The Pragmatic Programmer”:
Ponadto jesteśmy NIEPOPRAWNIE powolni w wykonywaniu instrukcji (w porównaniu do komputera). W dużym projekcie, z setkami plików i konfiguracji, ręczne wykonanie wszystkich kroków w procesie kompilacji zająłoby lata.
Dam ci przykład z prawdziwego świata. Pracowałem nad oprogramowaniem wbudowanym, w którym większość kodu była udostępniana na kilku różnych platformach sprzętowych. Każda platforma miała inny sprzęt, ale większość oprogramowania była taka sama. Ale były małe elementy, które były specyficzne dla każdego sprzętu. Najlepiej byłoby, gdyby wspólne elementy zostały umieszczone w bibliotece i połączone z każdą wersją. Jednak wspólnych elementów nie można skompilować we wspólnej bibliotece. Musiał zostać skompilowany z każdą inną konfiguracją.
Najpierw ręcznie skompilowałem każdą konfigurację. Przełączanie się między konfiguracjami zajęło tylko kilka sekund i nie było to wielkim problemem. Pod koniec projektu odkryto krytyczną wadę we wspólnej części kodu, w której urządzenie zasadniczo przejmuje magistralę komunikacyjną. To było ZŁE! Naprawdę źle. Znalazłem błąd w kodzie, naprawiłem go i ponownie skompilowałem każdą wersję. Z wyjątkiem jednego. Podczas procesu kompilacji byłem rozproszony i zapomniałem o jednym. Pliki binarne zostały zwolnione, maszyna została zbudowana, a dzień później dostaję telefon z informacją, że maszyna przestała odpowiadać. Sprawdziłem to i odkryłem, że urządzenie zablokowało autobus. „Ale naprawiłem ten błąd!”.
Mogłem to naprawić, ale nigdy nie znalazło się na tej jednej planszy. Dlaczego? Ponieważ nie miałem zautomatyzowanego procesu kompilacji, w którym każda wersja była budowana jednym kliknięciem.
źródło
Jeśli wszystko, co kiedykolwiek chcesz zrobić, to
<compiler> **/*.<extension>
skrypty budowania nie mają większego sensu (choć można argumentować, że jeśli widziszMakefile
projekt, wiesz, że możesz go zbudowaćmake
). Chodzi o to, że nietrywialne projekty zwykle wymagają czegoś więcej - przynajmniej musisz zazwyczaj dodać biblioteki i (w miarę dojrzewania projektu) skonfigurować parametry kompilacji.IDE są zwykle co najmniej konfigurowalne - ale teraz proces kompilacji opiera się na opcjach specyficznych dla IDE. Jeśli korzystasz z Eclipse , Alice woli NetBeans , a Bob chce korzystać z IntelliJ IDEA , nie możesz udostępnić konfiguracji, a gdy jedno z was przesunie zmianę do kontroli źródła, muszą albo ręcznie edytować konfigurację utworzoną przez IDE pliki innych programistów lub powiadom innych programistów, aby sami to zrobili (co oznacza, że będą zatwierdzenia, w których konfiguracja IDE jest nieprawidłowa dla niektórych IDE ...).
Musisz także dowiedzieć się, jak dokonać tej zmiany w każdym z IDE używanych przez zespół, a jeśli jedno z nich nie obsługuje tego konkretnego ustawienia ...
Teraz ten problem jest zależny od kultury - Twoi programiści mogą uznać, że nie ma wyboru IDE. Ale programiści, którzy mają doświadczenie z IDE, są zwykle zarówno szczęśliwsi, jak i bardziej wydajni podczas korzystania z niego, a użytkownicy edytorów tekstu mają skłonność do religijnego zapału o swoich ulubionych narzędziach, więc jest to jedno z miejsc, w których chcesz dać programistom swobodę - i buduj systemy pozwalają to zrobić. Niektóre osoby mogą mieć preferencje systemu kompilacji, ale nie są tak fanatyczne jak preferencje IDE / edytora ...
Nawet jeśli wszyscy programiści używają tego samego IDE - powodzenia przekonanie serwera kompilacji do korzystania z niego ...
Teraz dotyczy to prostych dostosowań procesu kompilacji, dla których IDE zwykle zapewniają przyjemny interfejs GUI. Jeśli chcesz bardziej skomplikowanych rzeczy - takich jak wstępne przetwarzanie / automatyczne generowanie plików źródłowych przed kompilacją - zwykle będziesz musiał napisać skrypt przed kompilacją w jakimś podstawowym obszarze tekstowym w konfiguracji IDE. W których systemach kompilacji nadal musisz kodować tę część, ale możesz to zrobić w edytorze, w którym piszesz kod, a co ważniejsze: sama struktura systemu kompilacji zazwyczaj zapewnia pewne wsparcie w organizacji tych skryptów.
Wreszcie - systemy kompilacji nadają się nie tylko do budowania projektu - możesz je zaprogramować do wykonywania innych zadań, które każdy zespół może potrzebować do wykonania. Na przykład w Ruby on Rails istnieją zadania systemowe kompilacji do uruchamiania migracji baz danych, czyszczenia plików tymczasowych itp. Umieszczenie tych zadań w systemie kompilacji gwarantuje, że wszyscy w zespole mogą je konsekwentnie wykonywać.
źródło
Wiele IDE po prostu pakuje polecenia użyte do zbudowania czegoś, a następnie generuje skrypt i wywołuje go!
Na przykład w programie Visual Studio można wyświetlić parametry wiersza polecenia dla kompilacji C ++ w polu „wiersza polecenia”. Jeśli przyjrzysz się uważnie wynikowi kompilacji, zobaczysz plik tymczasowy zawierający skrypt kompilacji użyty do uruchomienia kompilacji.
W dzisiejszych czasach to wszystko MSBuild , ale nadal jest obsługiwane bezpośrednio przez IDE.
Dlatego używasz wiersza poleceń, ponieważ idziesz prosto do źródła i pomijasz pośrednika, pośrednika, który mógł zostać zaktualizowany lub wymagać sterty zależności, których po prostu nie chcesz lub potrzebujesz na bezgłowym serwerze, który działa jako serwer ciągłej integracji (CI).
Ponadto Twoje skrypty wykonują więcej niż zwykłe kroki programistyczne, do których zostały zaprojektowane. Na przykład po kompilacji możesz chcieć spakować i skopiować pliki binarne do specjalnej lokalizacji, utworzyć pakiet instalatora lub uruchomić na nich narzędzie do dokumentacji. Serwer CI wykonuje wiele różnych zadań, które są bezcelowe na komputerze dewelopera, więc chociaż można utworzyć projekt IDE, który wykonałby wszystkie te kroki, należałoby zachować dwa z nich - projekt dla programistów i drugi dla kompilacji. Niektóre zadania kompilacji (na przykład analiza statyczna) mogą zająć dużo czasu, czego nie chciałbyś w przypadku projektów deweloperskich.
Krótko mówiąc, jest to po prostu łatwiejsze - stwórz skrypt, który zrobi wszystko, co chcesz, i szybko i łatwo uruchom go z wiersza poleceń lub konfiguracji serwera kompilacji.
źródło
jest o wiele łatwiejsze do zapamiętania i pisania niż
Projekty mogą mieć bardzo złożone polecenia kompilacji. Skrypt kompilacji ma również możliwość ponownej kompilacji rzeczy, które uległy zmianie. Jeśli chcesz zrobić czystą kompilację,
jest łatwiejszy i bardziej niezawodny po prawidłowym skonfigurowaniu, niż próba zapamiętania każdego miejsca, w którym mógł zostać utworzony plik pośredni.
Oczywiście, jeśli używasz IDE, łatwe jest również kliknięcie przycisku kompilacji lub czyszczenia. Znacznie trudniej jest jednak zautomatyzować przenoszenie kursora do określonego miejsca na ekranie, szczególnie gdy miejsce to może się przesunąć, jeśli okno się porusza, niż zautomatyzować proste polecenie tekstowe.
źródło
Jak inaczej byś to zrobił? Jedynym innym sposobem jest określenie jednego długiego polecenia wiersza poleceń.
Innym powodem jest to, że makefile pozwalają na kompilację przyrostową, co znacznie przyspiesza czas kompilacji.
Pliki makefile mogą również tworzyć proces kompilacji na wiele platform. CMake generuje różne skrypty budowania w oparciu o platformę.
Edytować:
Dzięki IDE jesteś przywiązany do określonego sposobu robienia rzeczy. Wiele osób używa vima lub emacsa, mimo że nie mają wielu funkcji podobnych do IDE. Robią to, ponieważ chcą mocy zapewnianej przez te edytory. Skrypty kompilacji są niezbędne dla tych, którzy nie używają IDE.
Nawet dla tych, którzy używają IDE, możesz naprawdę chcieć wiedzieć, co się dzieje, więc skrypt kompilacji oferuje szczegółowe informacje o implementacji, których nie ma GUI.
Same środowiska IDE często także wewnętrznie budują skrypty; przycisk Uruchom to po prostu inny sposób uruchomienia polecenia make.
źródło
Powyższe odpowiedzi obejmują wiele dobrych podstaw, ale jeden przykład z prawdziwego świata, który chciałbym dodać (którego nie mogę dodać jako komentarz z powodu braku karmy), pochodzi z programowania na Androida.
Jestem profesjonalnym Android / iOS / Windows Phone programista i używam API usług Google (głównie Google Maps) na wiele .
W systemie Android usługi te wymagają dodania magazynu kluczy lub pliku identyfikatora programisty, który informuje Google, że jestem tym, za kogo się podaje, w konsoli programisty. Jeśli moja aplikacja jest skompilowana z innym magazynem kluczy, sekcja Mapy Google nie będzie działać.
Zamiast dodawać i zarządzać kilkoma magazynami kluczy do konsoli programisty, z których tylko jeden można faktycznie zaktualizować, dołączam ten magazyn kluczy do naszego bezpiecznego repozytorium i używam Gradle, aby powiedzieć Android Studio, jakiego magazynu kluczy użyć podczas tworzenia „debugowanie” lub „wydanie”. Teraz muszę tylko dodać dwa magazyny kluczy do mojej konsoli programisty Google, jeden do „debugowania” i jeden do „wydania”, a wszyscy członkowie mojego zespołu mogą sklonować repozytorium i rozpocząć tworzenie bez konieczności wchodzenia do dewelopera konsolę i dodaj skrót SHA do ich konkretnego magazynu kluczy lub, co gorsza, zmuszając mnie do zarządzania nimi. Ma to tę dodatkową zaletę, że każdy członek zespołu otrzymuje kopię magazynu kluczy podpisywania, co oznacza, że jeśli jestem poza biurem i zaplanowana jest aktualizacja, członek zespołu musi jedynie postępować zgodnie z bardzo krótką listą instrukcji, aby przekazać aktualizacja.
Automatyzacja kompilacji w ten sposób utrzymuje spójność kompilacji i redukuje zadłużenie techniczne, skracając czas konfiguracji, gdy otrzymujemy nowego programistę, nową maszynę lub kiedy musimy ponownie zobrazować maszynę.
źródło
Buduj zalety skryptu:
zmiany wyglądają jak kod (na przykład w poleceniu git diff), a nie jak różne zaznaczone opcje w oknie dialogowym
tworzenie większej wydajności niż prosta kompilacja
W niektórych moich wcześniejszych projektach korzystałem ze skryptów kompilacji, aby:
źródło
Często możesz wywołać przycisk „buduj” w sposób zautomatyzowany (Visual Studio akceptuje na przykład argumenty wiersza poleceń). Ludzie piszą skrypty budowania, gdy tylko potrzebują czegoś, czego przycisk kompilacji nie może dostarczyć.
Na przykład większość IDE pozwala budować tylko jedną platformę na raz. Lub tylko jeden język na raz. Jest jeszcze to, co robisz z wbudowanymi wyjściami: czy Twoje IDE może zwinąć je wszystkie w pakiet instalacyjny?
źródło