Dlaczego przyrostowe kompilacje „make” nie używają algorytmów mieszających?

10

Jestem początkującym makei zastanawiam się, kiedy użyć make clean.

Jeden kolega powiedział mi, że przyrostowe kompilacje makeoparte są na znacznikach czasowych plików. Tak więc, jeśli pobierzesz starą wersję pliku w VCS, będzie on miał „stary” znacznik czasu i będzie oznaczony jako „nie ma potrzeby ponownej kompilacji tego pliku”. Wtedy ten plik nie zostałby włączony do następnej kompilacji.
Według tego samego kolegi byłby to powód do korzystania make clean.

Tak czy make cleaninaczej, z grubsza uzyskałem odpowiedź na pytanie „kiedy używać ” z innych pytań StackExchange, ale moje inne pytanie brzmi:

Dlaczego kompilacje przyrostowe przy użyciu makepolegają na sygnaturach czasowych plików, a nie na przykład na SHA-1? Na przykład Git pokazuje, że możemy z powodzeniem ustalić, czy plik został zmodyfikowany za pomocą SHA-1.
Czy dotyczy to problemów z prędkością?

filaton
źródło
5
makepowstał w latach 70-tych. SHA-1 powstał w latach 90-tych. Git powstał w latach 00-tych. Ostatnią rzeczą, jakiej pragniesz, jest to, że niektóre niejasne wersje działające przez 30 lat nagle zawiodą, ponieważ ktoś zdecydował się na nowoczesność dzięki wypróbowanemu i przetestowanemu systemowi.
Zwyczajny
1
Hashowanie plików przez cały czas jest wolne. Myślę, że git używa również metadanych systemu plików do optymalizacji swoich kontroli pod kątem zmienionych plików.
CodesInChaos
4
Oryginalne rozwiązanie oparte na datach plików jest bardzo proste, nie wymaga żadnych dodatkowych plików do przechowywania kodów skrótu i ​​działało wyjątkowo dobrze przez kilka dziesięcioleci. Dlaczego ktoś miałby zastąpić dobrze działające rozwiązanie bardziej skomplikowanym? Co więcej, AFAIK większość systemów VCS przypisuje wyrejestrowane pliki „datą wyjazdu”, więc zmienione pliki poprawnie spowodują rekompilację bez „wyczyszczenia”.
Doc Brown
@Ordous: Zabawne, ale czy ma to znaczenie tutaj? Oprogramowanie nie rdzewieje; daje się, ponieważ ktoś zmienił coś w otoczeniu. Chyba że nie, w takim przypadku powinno to nadal działać.
Robert Harvey
1
@RobertHarvey Oczywiście, że tak! Oczywiście, jeśli nie zaktualizujesz swojego makeoprogramowania, oprogramowanie się nie zepsuje, ale makeraczej starasz się zachować kompatybilność wsteczną w nowych wersjach. Zmiana zachowania rdzenia bez uzasadnionego powodu jest wręcz przeciwna. A daty pokazują, dlaczego pierwotnie nie został stworzony do użycia SHA-1 lub dlaczego nie było łatwo go zmodernizować, gdy stał się dostępny ( makemiał wtedy już dekady).
Zwyczajny

Odpowiedzi:

7

Oczywistym (i prawdopodobnie powierzchownym) problemem byłoby to, że system kompilacji musiałby rejestrować skróty plików, które zostały użyte dla ostatniej kompilacji. Chociaż ten problem można z pewnością rozwiązać, wymagałby on bocznego przechowywania, gdy informacje o znaczniku czasu są już obecne w systemie plików.

A tak na poważnie, skrót nie przekazałby tej samej semantyki. Jeśli wiesz, że plik T został zbudowany z zależności D z haszowaniem H 1, a następnie dowiesz się, że D teraz haszuje do H 2 , czy powinieneś przebudować T ? Prawdopodobnie tak, ale możliwe, że H 2 faktycznie odnosi się do starszej wersji pliku. Znaczniki czasu definiują porządek, podczas gdy skróty są porównywalne tylko dla równości.

Obsługa znaczników czasu polega na tym, że można po prostu zaktualizować znacznik czasu (na przykład za pomocą narzędzia wiersza polecenia POSIX touch), aby oszukać, makeże zależność uległa zmianie lub - co ciekawsze - cel jest nowszy niż jest w rzeczywistości. Podczas gdy gra się tym, jest świetną okazją do zastrzelenia się w stopę, jest jednak przydatna od czasu do czasu. W systemie opartym na haszowaniu potrzebna byłaby pomoc samego systemu kompilacji, aby zaktualizować wewnętrzną bazę danych skrótów używanych dla ostatniej kompilacji bez budowania czegokolwiek.

Chociaż z pewnością można argumentować za używaniem skrótów zamiast znaczników czasu, moim celem jest to, że nie są one lepszym rozwiązaniem dla osiągnięcia tego samego celu, ale innym rozwiązaniem dla osiągnięcia innego celu. Który z tych celów jest bardziej pożądany, może zostać poddany debacie.

5gon12eder
źródło
1
Chociaż semantyka różni się między skrótami i znacznikami czasu, w tym przypadku zwykle nie ma znaczenia, ponieważ najprawdopodobniej potrzebujesz kompilacji na podstawie bieżących plików, bez względu na ich wiek.
axl
Większość tego, co mówisz, jest poprawna. Jednak dobrze zaimplementowany system kompilacji, który używa skrótów, takich jak Google Blaze / Bazel (wewnętrzna wersja Blaze, bazowa wersja open source to Bazel), pokonuje spodnie systemu oznaczonego czasem, takiego jak Make. To powiedziawszy, musisz włożyć wiele wysiłku w powtarzalne kompilacje, aby zawsze bezpiecznie używać starych artefaktów kompilacji zamiast odbudowywać.
btilly,
Mapowanie tutaj nie jest wiele do jednego, to jeden do jednego. Jeśli Dteraz do skrótów H2, a nie masz jakiś wyjściowy T2zbudowany z D@H2, trzeba produkować i przechowywać go. Następnie, niezależnie od tego, w jakiej kolejności Dprzełączane są między stanami H1i H2, będziesz mógł używać danych wyjściowych z pamięci podręcznej.
Asad Saeeduddin
1

Hashowanie całego projektu jest bardzo wolne. Musisz przeczytać każdy bajt każdego pliku. Git nie haszuje każdego pliku przy każdym uruchomieniu git status. Kasy VCS również nie ustawiają czasu modyfikacji pliku na pierwotny czas autorstwa. Jeśli to zrobisz, zostanie przywrócona kopia zapasowa. Cały powód, dla którego systemy plików mają znaczniki czasu, dotyczy takich przypadków użycia.

Deweloper zwykle działa, make cleangdy zmienia się zależność, która nie jest bezpośrednio śledzona przez plik Makefile. Jak na ironię, zwykle obejmuje to sam Makefile. Zwykle zawiera również wersje kompilatora. W zależności od tego, jak dobrze napisany jest Twój plik Makefile, może on zawierać wersje bibliotek zewnętrznych.

Są to rzeczy, które mają tendencję do aktualizowania się, gdy wykonujesz aktualizację kontroli wersji, więc większość programistów po prostu przyzwyczaja się do uruchamiania make cleanw tym samym czasie, więc wiesz, że zaczynasz od czystej listy. Możesz uciec bez robienia tego dużo czasu, ale naprawdę trudno jest przewidzieć czasy, których nie możesz.

Karl Bielefeldt
źródło
Możesz używać systemów plików, takich jak ZFS, w których koszt mieszania jest amortyzowany w czasie modyfikacji plików, zamiast płacić od razu podczas kompilacji.
Asad Saeeduddin
1

Kilka uwag na temat skrótów a znaczników czasu w systemach kompilacji:

  1. Podczas pobierania pliku znacznik czasu należy zaktualizować do bieżącej godziny, co powoduje przebudowę. To, co opisuje twój kolega, zwykle nie jest trybem awarii systemów znaczników czasu.
  2. Znaczniki czasu są nieznacznie szybsze niż skróty. System znacznika czasu musi tylko sprawdzić znacznik czasu, podczas gdy system skrótu musi sprawdzić znacznik czasu, a następnie potencjalnie skrót.
  3. Marka została zaprojektowana tak, aby była lekka i niezależna. Aby pokonać (2), systemy oparte na haszowaniu zwykle uruchamiają proces sprawdzania skrótów w tle (np. Watchman z Facebooka ). Jest to sprzeczne z celami projektowymi (i historią) marki Make.
  4. Skróty zapobiegają niepotrzebnym przebudowaniom po zmianie znacznika czasu, ale nie zawartości. Często równoważy to koszt obliczania skrótu.
  5. Skróty umożliwiają współdzielenie pamięci podręcznych artefaktów między projektami i siecią. Ponownie, to więcej niż rekompensuje koszt haszowania obliczeniowego.
  6. Nowoczesne systemy kompilacji oparte na hashach obejmują Bazel (Google) i Buck (Facebook).
  7. Większość programistów powinna rozważyć użycie systemu opartego na haszowaniu, ponieważ nie mają takich samych wymagań, jak te, w których zaprojektowano program Make.
sdgfsdh
źródło