Dlaczego pliki makefile powinny mieć cel „instaluj”?

18

Pochodzące ze świata C i C ++ większość systemów kompilacji ma installcel, w szczególności Makefile (tam, gdzie jest to zalecane na przykład przez GNU ) lub CMake . Ten cel kopiuje pliki środowiska wykonawczego (pliki wykonywalne, biblioteki, ...) w systemie operacyjnym (na przykład w C:\Program Files\systemie Windows).

Jest to naprawdę hackerskie, ponieważ dla mnie nie jest obowiązkiem kompilacji systemu instalowanie programów (co w rzeczywistości jest odpowiedzialnością systemu operacyjnego / menedżera pakietów). Oznacza to również, że system kompilacji lub skrypt kompilacji musi znać organizację zainstalowanych programów, ze zmiennymi środowiskowymi, zmiennymi rejestru, dowiązaniami symbolicznymi, uprawnieniami itp.

W najlepszym wypadku systemy kompilacji powinny mieć releasecel, który wyśle ​​program instalacyjny (na przykład .deblub .msi), a następnie uprzejmie poprosi system operacyjny o zainstalowanie tego programu. Umożliwiłoby to również użytkownikowi odinstalowanie bez konieczności pisania make uninstall.

Więc moje pytanie: dlaczego system kompilacji zwykle zaleca posiadanie installcelu?

Synxis
źródło
7
Twój argument, że „make install” nie wchodzi w zakres systemu kompilacji, ale o wiele bardziej zaangażowany i specyficzny dla platformy obowiązek tworzenia pakietu instalacyjnego.
pmf
2
W każdym razie: czasami chcesz zainstalować aplikację, która nie jest obsługiwana przez system operacyjny / menedżera pakietów (ponieważ ma zależności, które powodowałyby konflikty niemożliwe do rozwiązania za pomocą menedżera pakietów itp.). make installzwykle instaluje się w /usr/local(a nawet /opt) katalogach nieobsługiwanych przez „podstawowy system zarządzania pakietami / systemami operacyjnymi”. Nie mam pojęcia, czy system Windows ma podobną konwencję.
Bakuriu
11
„To jest naprawdę hacking”. Czego oczekiwałeś po świecie C / C ++? ;-)
Mason Wheeler
1
Zauważ, make installże nie ma to sensu, gdy mówimy o kompilacji krzyżowej
Hagen von Eitzen
1
@HagenvonEitzen robi to DESTDIR.
Nax 'vi-vim-nvim'

Odpowiedzi:

23

Wiele skryptów kompilacji lub plików Makefiles ma cel instalacji, ponieważ zostały one utworzone przed istnieniem menedżerów pakietów i ponieważ nawet dziś wiele systemów nie ma menedżerów pakietów. Ponadto istnieją systemy, w których make installfaktycznie jest preferowanym sposobem zarządzania pakietami.

Jörg W Mittag
źródło
Jestem ciekawy systemów, w których make installjest preferowany. Poza tym miałem na myśli menedżera programów, kiedy powiedziałem, że makefile powinny tworzyć instalowalne pakiety. Myślę, że prawie wszystkie systemy operacyjne posiadają sposób zarządzania zainstalowanymi programami? Na przykład system Windows nie ma menedżera pakietów (poza sklepem), ale nadal ma sposób zarządzania zainstalowanymi programami (za pomocą .msipakietów na przykład)
Synxis,
2
@Synxis BSD, Linux, Unix używają plików makefile. Nie wiem, czy wolisz używać ich do instalacji, ale często masz taką umiejętność make install.
Rob
1
Przynajmniej w Debianie zaleca się używanie checkinstallz make installdwóch powodów: „Możesz łatwo usunąć pakiet jednym krokiem”. i „Możesz zainstalować wynikowy pakiet na wielu komputerach”. - ponieważ checkinstall buduje .deb i instaluje go, używa menedżera pakietów ...
Aaron Hall
1
@ Synxis - Istnieje kilka dystrybucji linuksa (często nazywanych dystrybucjami źródłowymi), w których menedżer pakietów instaluje programy, pobierając plik tar, rozpakuj go, a następnie uruchommake install
slebetman
1
@AaronHall Popraw mnie, jeśli się mylę, ale mam wrażenie, że checkinstallwywołanie faktycznie używa make install i monitoruje jego działania w celu budowania pakietów.
cmaster
5

A makefilemoże nie mieć installcelu, a co ważniejsze, możesz mieć programy, które nawet nie powinny być instalowalne (np. Ponieważ powinny działać z katalogu kompilacji lub ponieważ mogą być zainstalowane w dowolnym miejscu). installCel jest tylko konwencja dla zwykłych makefile-s.

Jednak wiele programów wymaga uruchamiania zasobów zewnętrznych (na przykład: czcionek, baz danych, plików konfiguracyjnych itp.). Ich pliki wykonywalne często stawiają hipotezę na temat tych zasobów. Na przykład, bashpowłoka będzie na ogół przeczytać jakiś plik inicjalizacji od /etc/bash.bashrcetc .... Zasoby te są na ogół w systemie plików (patrz hier (7) do konwencji o hierarchii plików), a domyślna ścieżka pliku jest wbudowany w plik wykonywalny.

Spróbuj użyć ciągów (1) w większości plików wykonywalnych systemu. Dowiesz się, jakie ścieżki do plików są mu znane.

BTW, dla wielu używających programów GNU autoconfmożna uruchomić make install DESTDIR=/tmp/destdir/bez rootowania. Następnie /tmp/destdir/jest wypełniany plikami, które powinny być później spakowane.

FWIW, uważam, że mojego programu bismon (licencjonowanego na GPLv3 +) (opisanego w moim raporcie bismon-chariot-doc.pdf ) nie można „zainstalować”; Nie jestem pewien, czy będę w stanie to udowodnić, i nie wyobrażam sobie, jak sprawić, by ten program był instalowalny.

Basile Starynkevitch
źródło
2
DESTDIR lub inne prefiksy są zbyt często zapominane. Po zaangażowaniu zasobów zewnętrznych, takich jak biblioteki dynamiczne, nie jest możliwe zbudowanie oprogramowania bez wiedzy, gdzie zostanie ono zainstalowane . Idealny również do instalacji w niestandardowych lokalizacjach, np. /optLub w $HOME. Jedynym sposobem uniknięcia różnych prefiksów jest użycie kontenerów, ale jest to oczywiście rozwiązanie specyficzne dla systemu Linux.
amon
2
Widziałem więcej niż jeden pakiet, który jeśli spróbowałeś DESTDIR = / tmp / destdir nie działałby później, gdy był zainstalowany w normalnym miejscu, ponieważ DESTDIR był używany do generowania ścieżki.
Joshua
@amon: Nie jestem pewien, czy scharakteryzuję kontenery jako specyficzne dla Linuksa. Linux może być powszechną platformą docelową dla konteneryzacji, ale pewna forma technologii kontenerowej istnieje w większości nowoczesnych systemów operacyjnych.
Kevin,
1
@Joshua To nie powinno, DESTDIR powinno być istotne tylko na etapie instalacji. Powinieneś być w stanie: ./configure --prefix="/opt/foo" && make && DESTDIR=/tmp/foo make install i móc przenieść pakiet /opt/foobez żadnych problemów.
Nax 'vi-vim-nvim'
3

Przychodzi mi na myśl kilka powodów.

  • Wiele programów do tworzenia pakietów - na przykład system kompilacji Debiana , a także rpm IIRC - już oczekuje od skryptu budowania, aby „zainstalował” program do jakiegoś specjalnego podkatalogu. Jest więc napędzany kompatybilnością wsteczną w obu kierunkach.
  • Użytkownik może chcieć zainstalować oprogramowanie w lokalnej przestrzeni, np. W $HOMEkatalogu. Nie wszyscy menedżerowie pakietów obsługują to.
  • Nadal mogą istnieć środowiska, które nie mają pakietów.
max630
źródło
Trochę przeredagowałem pytanie, miałem na myśli menedżera programów, kiedy powiedziałem, że makefile powinny tworzyć instalowalne pakiety.
Synxis
1

Jednym z powodów, o których nie wspomniano, jest to, że wiele razy nie używasz bieżącej wersji oprogramowania lub używasz zmodyfikowanej wersji oprogramowania. Próba stworzenia niestandardowego pakietu to nie tylko więcej pracy, ale może powodować konflikt z aktualnie tworzonymi i dystrybuowanymi pakietami. W otwartym kodzie źródłowym dzieje się to często, zwłaszcza jeśli w przyszłych wersjach, których używasz, wprowadzane są przełomowe zmiany.

Załóżmy, że korzystasz z projektu open source FOO, który jest obecnie w wersji 2.0.1 i używasz wersji 1.3.0. Nie chcesz używać niczego powyżej, ponieważ wersja 2.0.0 jest niezgodna z tym, co obecnie robisz, ale istnieje jedna poprawka błędu w wersji 2.0.1, której desperacko potrzebujesz. Dzięki tej make installopcji możesz zainstalować zmodyfikowane oprogramowanie 1.3.0 bez martwienia się o utworzenie pakietu i zainstalowanie go w systemie.

Dom
źródło
1

Dystrybucje Linuksa zasadniczo oddzielają obsługę programu od obsługi pakietu. System kompilacji, który integruje generowanie pakietów, zmusiłby opiekunów programów do przeprowadzania również konserwacji pakietów.

To zwykle zły pomysł. Dystrybucje mają wiele infrastruktury do weryfikacji wewnętrznej spójności, zapewniają pliki binarne dla wielu platform docelowych, wykonują małe zmiany w celu lepszej integracji z resztą systemu i zapewniają spójne środowisko dla użytkowników zgłaszających błędy.

Aby wygenerować pakiety bezpośrednio z systemu kompilacji, musisz zintegrować lub ominąć całą tę infrastrukturę. Jego integracja byłaby bardzo pracochłonna dla wątpliwych korzyści, a jej ominięcie dałoby gorsze wrażenia dla użytkownika.

Jest to jeden z najbardziej typowych problemów w systemach wielopartyjnych. Jeśli masz wiele złożonych systemów, musi istnieć jasna hierarchia, który system jest odpowiedzialny za koordynację wszystkich innych.

W przypadku zarządzania instalacją oprogramowania menedżerem pakietów jest ten komponent, który uruchomi system kompilacji pakietu, a następnie przejdzie przez wygodny interfejs („pliki w katalogu po kroku instalacji”), wygeneruje pakiet i przygotuje w celu przesłania do repozytorium.

Menedżer pakietów stoi tutaj pośrodku między systemem kompilacji a repozytorium i jest w najlepszej pozycji, aby dobrze zintegrować się z obydwoma.

Być może zauważyłeś, że jest tylko kilka pakietów JavaScript dostępnych za pośrednictwem npmrównież dostępnych poprzez apt- to głównie dlatego, że ludzie JavaScript zdecydowali, że npmi powiązane z nim repozytorium będzie na szczycie ich łańcucha pokarmowego, co sprawiło, że prawie niemożliwe było wysyłaj te pakiety jako pakiety Debiana.

Z moim kapeluszem dewelopera Debiana: jeśli wypuszczasz oprogramowanie typu open source, zostaw opakowanie opiekunom dystrybucji. Oszczędza to zarówno Tobie, jak i nam dużo pracy.

Simon Richter
źródło
Nie powiedziałeś nic o tym, dlaczego istnieje cel instalacyjny, i wydaje mi się, że większość tego, co napisałeś, miałaby zastosowanie również do niego ...
curiousdannii
1
@curiousdannii, musi istnieć jakiś interfejs między systemem kompilacji a menedżerem pakietów, i to jest najprostszy, więc wygrał.
Simon Richter,
1

Cóż, twórcy aplikacji wiedzą, gdzie powinien iść każdy plik. Mogą zostawić to w dokumentacji i poprosić opiekunów pakietu o przeczytanie tego i zbudowanie skryptu dla każdego pakietu. Być może opiekunowie pakietów źle interpretują dokumentację i będą musieli debugować skrypt, dopóki nie zadziała. To jest nieefektywne. Twórcy aplikacji lepiej jest napisać skrypt, aby poprawnie zainstalować napisaną przez siebie aplikację.

Mógłby napisać skrypt instalacyjny o dowolnej nazwie lub może włączyć go do procedury innego skryptu. Jednak mając standardowe polecenie instalacji make install(konwencja, która poprzedza menedżerów pakietów), tworzenie pakietów jest naprawdę łatwe. Jeśli spojrzysz na szablon PKGBUILD do tworzenia pakietów Archlinux , możesz zobaczyć, że funkcja, która faktycznie pakuje, po prostu wykonuje make DESTDIR="$pkgdir/" install. Prawdopodobnie działa to dla większości pakietów i prawdopodobnie więcej z niewielką modyfikacją. Dzięki temu, że make(i narzędzia automatyczne) są standardowe, pakowanie jest naprawdę bardzo łatwe.

JoL
źródło