Mengapa makefile memiliki target "instal"?

18

Berasal dari dunia C dan C ++, sebagian besar sistem build memiliki installtarget, terutama Makefiles (di mana direkomendasikan oleh GNU misalnya) atau CMake . Target ini menyalin file runtime (executable, libraries, ...) di sistem operasi (misalnya, di C:\Program Files\Windows).

Ini terasa benar-benar berantakan, karena bagi saya itu bukan tanggung jawab sistem build untuk menginstal program (yang sebenarnya adalah tanggung jawab manajer sistem operasi / paket). Ini juga berarti membangun sistem atau membangun skrip harus mengetahui organisasi program yang diinstal, dengan variabel lingkungan, variabel registri, symlink, izin, dll.

Paling-paling, sistem build harus memiliki releasetarget yang akan menghasilkan program yang dapat diinstal (misalnya .debatau .msi), dan kemudian dengan hormat meminta sistem operasi untuk menginstal program itu. Itu juga akan memungkinkan pengguna untuk menghapus instalasi tanpa harus mengetik make uninstall.

Jadi, pertanyaan saya: mengapa membangun sistem biasanya merekomendasikan memiliki installtarget?

Synxis
sumber
7
Pendapat Anda bahwa "melakukan instal" tidak termasuk dalam tanggung jawab sistem build, tetapi tanggung jawab yang jauh lebih terlibat dan platform untuk membuat paket yang dapat diinstal tidak.
PMF
2
Pokoknya: kadang-kadang Anda ingin menginstal aplikasi yang tidak ditangani oleh OS / manajer paket (karena memiliki dependensi yang akan menyebabkan konflik yang tidak mungkin diselesaikan dengan menggunakan manajer paket dll). make installbiasanya menginstal di bawah /usr/local(atau bahkan /opt) yang direktori tidak ditangani oleh "sistem manajemen inti OS / paket". Tidak tahu apakah Windows memiliki konvensi serupa.
Bakuriu
11
"Rasanya benar-benar berantakan." Nah, apa yang Anda harapkan dari dunia C / C ++? ;-)
Mason Wheeler
1
Catatan yang make installtidak masuk akal ketika kita berbicara tentang kompilasi silang
Hagen von Eitzen
1
@HagenvonEitzen tidak dengan DESTDIR.
Nax 'vi-vim-nvim'

Jawaban:

23

Banyak skrip build atau Makefile memiliki target instalasi karena mereka dibuat sebelum manajer paket ada, dan karena bahkan saat ini banyak sistem tidak memiliki manajer paket. Plus, ada sistem di mana make installsebenarnya adalah cara yang lebih disukai untuk mengelola paket.

Jörg W Mittag
sumber
Saya ingin tahu tentang sistem di mana make installlebih disukai. Selain itu, saya maksud manajer program ketika saya mengatakan bahwa makefiles harus membuat paket yang dapat diinstal. Saya pikir hampir semua OS datang dengan cara mengelola program yang diinstal? Misalnya, Windows tidak memiliki manajer paket (selain dari toko) tetapi masih memiliki cara untuk mengelola program yang diinstal (melalui .msipaket sebagai contoh)
Synxis
2
@Synxis BSD, Linux, Unix semuanya menggunakan makefile. Entah lebih suka menggunakannya untuk instalasi, saya tidak tahu, tetapi Anda sering menggunakan kemampuan itu make install.
Rob
1
Setidaknya di debian lebih disukai menggunakan checkinstalllebih dari make installdua alasan: "Anda dapat dengan mudah menghapus paket dengan satu langkah." dan "Anda dapat menginstal paket yang dihasilkan pada beberapa mesin." - Saat checkinstall membangun .deb dan memasangnya, ia menggunakan pengelola paket ...
Aaron Hall
1
@ Sinxis - Ada beberapa distribusi linux (sering disebut distro sumber) di mana manajer paket menginstal program dengan mengunduh file tar, mendekompresnya kemudian menjalankanmake install
slebetman
1
@ AaronHall Perbaiki saya jika saya salah, tapi saya mendapat kesan bahwa checkinstalldoa benar-benar akan menggunakan make install dan memantau tindakannya untuk pembuatan paket.
cmaster - mengembalikan monica
5

A makefilemungkin tidak memiliki installtarget, dan yang lebih penting, Anda dapat memiliki program yang bahkan seharusnya tidak dapat diinstal (misalnya karena mereka harus dijalankan dari direktori build mereka, atau karena mereka dapat menjalankan instal di mana saja). The installtarget hanya konvensi untuk biasa makefile-s.

Namun, banyak program memerlukan sumber daya eksternal untuk dijalankan (misalnya: font, database, file konfigurasi, dll). Dan executable mereka sering membuat beberapa hipotesis tentang sumber daya ini. Sebagai contoh, bashshell Anda biasanya akan membaca beberapa file inisialisasi dari /etc/bash.bashrcdll ... Sumber daya ini umumnya di sistem file (lihat hier (7) untuk konvensi tentang hirarki file) dan jalur file default dibangun di executable Anda.

Cobalah untuk menggunakan string (1) pada sebagian besar executable sistem Anda. Anda akan menemukan jalur file mana yang diketahui.

BTW, untuk banyak program GNU menggunakan autoconf, Anda bisa menjalankan make install DESTDIR=/tmp/destdir/tanpa menjadi root. Kemudian /tmp/destdir/diisi dengan file-file yang nantinya harus dikemas.

FWIW, saya cenderung percaya bahwa program bismon saya (GPLv3 + berlisensi) (dijelaskan dalam laporan bismon-chariot-doc.pdf saya ) tidak dapat "diinstal"; Saya tidak yakin bisa membuktikannya, dan saya tidak bisa membayangkan bagaimana saya bisa membuat program itu dapat diinstal.

Basile Starynkevitch
sumber
2
DESTDIR atau awalan lainnya terlalu sering dilupakan. Segera setelah sumber daya eksternal seperti perpustakaan dinamis terlibat, tidak mungkin untuk membangun perangkat lunak tanpa mengetahui di mana ia akan diinstal . Juga bagus untuk menginstal ke lokasi non-standar, misalnya /optatau ke $HOME. Satu-satunya cara untuk menghindari awalan yang berbeda adalah dengan menggunakan wadah, tapi itu tentu saja solusi khusus Linux.
amon
2
Saya telah melihat lebih dari satu paket yang jika Anda mencoba DESTDIR = / tmp / destdir tidak akan berfungsi kemudian ketika diinstal ke tempat normal karena DESTDIR digunakan dalam pembuatan jalur.
Joshua
@amon: Saya tidak yakin saya akan mencirikan kontainer sebagai khusus Linux. Linux mungkin merupakan platform target umum untuk kontainerisasi, tetapi beberapa bentuk teknologi wadah ada di sebagian besar sistem operasi modern.
Kevin
1
@Joshua Seharusnya tidak, DESTDIR seharusnya hanya relevan selama langkah instalasi. Anda harus dapat melakukan: ./configure --prefix="/opt/foo" && make && DESTDIR=/tmp/foo make install dan dapat memindahkan paket ke /opt/footanpa masalah.
Nax 'vi-vim-nvim'
3

Ada beberapa alasan yang muncul di benak saya.

  • Banyak paket perangkat lunak yang membuat - misalnya sistem pembangunan Debian , dan rpm IIRC juga - sudah diharapkan dari skrip bangunan untuk "menginstal" program ke beberapa subdirektori khusus. Jadi itu didorong oleh kompatibilitas ke belakang di kedua arah.
  • Seorang pengguna mungkin ingin menginstal perangkat lunak ke ruang lokal, seperti di $HOMEdirektori. Tidak semua manajer paket mendukungnya.
  • Mungkin masih ada lingkungan yang tidak memiliki paket.
max630
sumber
Saya menulis ulang sedikit pertanyaan, maksud saya manajer program ketika saya mengatakan bahwa makefile harus membuat paket yang dapat diinstal.
Synxis
1

Salah satu alasan yang tidak disebutkan adalah ada banyak waktu ketika Anda tidak menggunakan versi perangkat lunak saat ini atau menggunakan versi perangkat lunak yang dimodifikasi. Mencoba membuat paket khusus tidak hanya berfungsi, tetapi dapat bertentangan dengan paket yang dibuat dan didistribusikan saat ini. Dalam kode sumber terbuka ini sering terjadi terutama jika perubahan melanggar diperkenalkan di versi masa depan yang Anda gunakan.

Katakanlah Anda menggunakan proyek sumber terbuka FOO yang saat ini ada di versi 2.0.1 dan Anda menggunakan versi 1.3.0. Anda tidak ingin menggunakan apa pun di atas itu karena versi 2.0.0 tidak kompatibel dengan apa yang Anda lakukan saat ini, tetapi ada satu perbaikan bug di 2.0.1 yang sangat Anda butuhkan. Dengan make installopsi ini, Anda dapat menginstal perangkat lunak 1.3.0 yang dimodifikasi tanpa harus khawatir membuat paket dan menginstalnya di sistem Anda.

Dom
sumber
1

Distribusi Linux umumnya memisahkan pemeliharaan program dari pemeliharaan paket. Sistem build yang mengintegrasikan pembuatan paket akan memaksa pengelola program untuk juga melakukan pemeliharaan paket.

Ini biasanya ide yang buruk. Distribusi memiliki banyak infrastruktur untuk memverifikasi konsistensi internal, menyediakan binari untuk beberapa platform target, melakukan perubahan kecil untuk lebih terintegrasi dengan seluruh sistem dan memberikan pengalaman yang konsisten bagi pengguna yang melaporkan bug.

Untuk menghasilkan paket langsung dari sistem build, Anda harus mengintegrasikan atau mem-bypass semua infrastruktur ini. Mengintegrasikannya akan banyak pekerjaan untuk keuntungan yang dipertanyakan, dan memintasinya akan memberikan pengalaman pengguna yang lebih buruk.

Ini adalah salah satu masalah "puncak rantai makanan" yang khas dalam sistem multi-partai. Jika Anda memiliki banyak sistem yang kompleks, perlu ada hierarki yang jelas tentang sistem mana yang bertanggung jawab untuk mengoordinasikan semua yang lain.

Dalam hal manajemen instalasi perangkat lunak, manajer paket adalah komponen ini, dan itu akan menjalankan sistem build paket, kemudian mengambil output melalui antarmuka yang nyaman ("file dalam direktori setelah langkah instalasi"), menghasilkan paket dan mempersiapkan itu untuk diunggah ke repositori.

Manajer paket berdiri di tengah-tengah antara sistem build dan repositori di sini, dan berada dalam posisi terbaik untuk berintegrasi dengan baik dengan keduanya.

Anda mungkin telah memperhatikan bahwa hanya ada beberapa paket JavaScript yang tersedia melalui npmjuga tersedia melalui apt- ini terutama karena orang-orang JavaScript memutuskan bahwa npmdan repositori terkait akan menjadi bagian atas rantai makanan mereka, yang membuatnya hampir mustahil untuk kirimkan paket-paket ini sebagai paket Debian.

Dengan tutup Pengembang Debian saya: jika Anda merilis perangkat lunak open source, silakan serahkan kemasannya ke pengelola distribusi. Ini menghemat banyak pekerjaan Anda dan kami.

Simon Richter
sumber
Anda tidak mengatakan apa-apa tentang mengapa ada target instal, dan bagi saya sepertinya sebagian besar dari apa yang Anda tulis juga berlaku untuk itu ...
curiousdannii
1
@curiousdannii, perlu ada beberapa antarmuka antara sistem build dan manajer paket, dan ini yang paling sederhana, jadi ia menang.
Simon Richter
1

Nah, pengembang aplikasi adalah orang-orang yang tahu ke mana masing-masing file harus pergi. Mereka dapat meninggalkannya dalam dokumentasi, dan meminta pengelola paket membacanya dan membuat skrip untuk setiap paket. Mungkin pengelola paket akan salah menafsirkan dokumentasi dan harus men-debug skrip hingga berfungsi. Ini tidak efisien. Lebih baik bagi pengembang aplikasi untuk menulis skrip untuk menginstal aplikasi yang ditulisnya dengan benar.

Dia bisa menulis skrip instalasi dengan nama yang arbitrer atau mungkin menjadikannya bagian dari prosedur beberapa skrip lain. Namun, memiliki perintah instalasi standar, make install(sebuah konvensi yang mendahului manajer paket), menjadi sangat mudah untuk membuat paket. Jika Anda melihat template PKGBUILD untuk membuat paket Archlinux , Anda dapat melihat bahwa fungsi yang sebenarnya dilakukan paket adalah a make DESTDIR="$pkgdir/" install. Ini mungkin bekerja untuk sebagian besar paket dan mungkin lebih banyak dengan sedikit modifikasi. Berkat make(dan autotool) menjadi standar, pengemasan benar-benar mudah.

JoL
sumber