Belajar mengkompilasi sesuatu dari sumber (di Unix / Linux / OSX)

47

Sementara saya menginstal perangkat lunak dari paket (MacPorts / apt-get) di mana mungkin, saya sering menemukan diri saya perlu mengkompilasi paket dari sumber. ./configure && make && sudo make installbiasanya cukup, tetapi kadang-kadang tidak berhasil - dan ketika tidak, saya sering macet. Ini hampir selalu berkaitan dengan dependensi perpustakaan lain dalam beberapa cara.

Saya ingin belajar yang berikut:

  • Bagaimana saya mencari tahu argumen apa yang harus dilewati ./configure?
  • Bagaimana pustaka bersama bekerja di bawah OS X / Linux - di mana mereka tinggal di sistem file, bagaimana ./configure && makemenemukannya, apa yang sebenarnya terjadi ketika mereka ditautkan
  • Apa perbedaan aktual antara pustaka bersama dan yang terhubung secara statis? Mengapa saya tidak bisa hanya menautkan semuanya secara statis (RAM dan ruang disk murah hari ini) dan karenanya menghindari konflik versi perpustakaan yang aneh?
  • Bagaimana saya bisa tahu perpustakaan apa yang telah saya instal, dan versi apa?
  • Bagaimana saya bisa menginstal lebih dari satu versi perpustakaan tanpa merusak sistem normal saya?
  • Jika saya sedang memasang barang-barang dari sumber pada sistem yang jika tidak dikelola dengan menggunakan paket, apa cara terbersih melakukannya?
  • Dengan asumsi saya berhasil mengkompilasi sesuatu secara fiddly dari sumber, bagaimana saya bisa mengemasnya sehingga orang lain tidak harus melompat melalui lingkaran yang sama? Khususnya pada OS X ....
  • Apa alat baris perintah yang perlu saya kuasai untuk menjadi ahli dalam hal ini? Hal-hal seperti otool, pkg-config dll.

Saya bersedia menginvestasikan sedikit waktu dan upaya di sini - Saya tidak ingin jawaban langsung untuk pertanyaan di atas, saya lebih suka mendapatkan rekomendasi tentang buku / tutorial / FAQ yang dapat saya baca yang akan memberi saya pengetahuan saya perlu memahami apa yang sebenarnya terjadi dan karenanya mencari tahu masalah saya sendiri.

Simon Willison
sumber

Jawaban:

40

Saya minta maaf karena langsung menjawab semuanya, tetapi saya tidak tahu tutorial, FAQ, dll yang bermanfaat. Pada dasarnya yang berikut adalah 8 tahun membuat aplikasi desktop (yang saya bantu distribusikan), frustrasi dan googling:

1. Bagaimana cara mencari tahu argumen apa yang harus dilewatkan ./configure?

Berlatih dengan sungguh-sungguh. Autotool cukup mudah karena konsisten. Tetapi ada banyak hal di luar sana menggunakan cmake, atau skrip pembuatan kustom. Secara umum, Anda tidak harus melewatkan apa pun untuk dikonfigurasikan, itu harus mencari tahu apakah sistem Anda dapat membangun foo-tool atau tidak.

Konfigurasi dan alat GNU semuanya mencari di dalam,, / usr dan / usr / local untuk dependensi. Jika Anda memasang apa pun di tempat lain (yang membuat hal-hal menyakitkan jika ketergantungan diinstal oleh MacPorts atau Fink), Anda harus melewati sebuah flag untuk mengonfigurasi atau memodifikasi lingkungan shell untuk membantu alat GNU menemukan dependensi ini.

2. Bagaimana pustaka bersama bekerja di OS X / Linux - di mana mereka tinggal di sistem file, bagaimana ./configure && make menemukannya, apa yang sebenarnya terjadi ketika mereka ditautkan

Di Linux, mereka perlu diinstal ke jalur yang dapat ditemukan oleh tautan dinamis, ini ditentukan oleh LD_LIBRARY_PATHvariabel lingkungan dan konten /etc/ld.conf. Pada Mac, hampir selalu sama untuk sebagian besar perangkat lunak open source (kecuali jika itu adalah Proyek Xcode). Kecuali variabel env DYLD_LIBRARY_PATHsebagai gantinya.

Ada jalur default yang dicari linker untuk perpustakaan. Ini adalah / lib: / usr / lib: / usr / local / lib

Anda dapat melengkapi ini dengan menggunakan variabel CPATH, atau CFLAGS atau sejumlah variabel lingkungan lainnya benar-benar (mudah rumit). Saya menyarankan CFLAGS seperti:

export CFLAGS = "$ CFLAGS -L / new / path"

Parameter -L ditambahkan ke jalur tautan.

Barang-barang modern menggunakan alat pkg-config. Barang-barang modern yang Anda instal juga menginstal file .pc yang menggambarkan perpustakaan dan di mana perpustakaan itu berada dan bagaimana menautkannya. Ini bisa membuat hidup lebih mudah. Tapi itu tidak datang dengan OS X 10.5 sehingga Anda harus menginstalnya juga. Juga banyak deps dasar tidak mendukungnya.

Tindakan menautkan hanya "menyelesaikan fungsi ini saat runtime", sebenarnya ini adalah tabel string besar.

3. Apa perbedaan aktual antara pustaka bersama dan yang terhubung secara statis? Mengapa saya tidak bisa hanya menautkan semuanya secara statis (RAM dan ruang disk murah hari ini) dan karenanya menghindari konflik versi perpustakaan yang aneh?

Ketika Anda menautkan ke file perpustakaan statis kode menjadi bagian dari aplikasi Anda. Akan seperti jika ada satu file .c raksasa untuk perpustakaan itu dan Anda mengompilasinya ke dalam aplikasi Anda.

Pustaka dinamis memiliki kode yang sama, tetapi ketika aplikasi dijalankan, kode tersebut dimuat ke dalam aplikasi saat runtime (penjelasan yang disederhanakan).

Anda dapat menautkan secara statis ke semuanya, sayangnya, hampir tidak ada sistem pembangunan yang membuatnya mudah. Anda harus mengedit file sistem build secara manual (mis. Makefile.am, atau CMakeLists.txt). Namun ini mungkin layak dipelajari jika Anda secara teratur menginstal hal-hal yang memerlukan versi pustaka yang berbeda dan Anda merasa sulit untuk menginstal dependensi secara paralel.

Caranya adalah dengan mengubah garis tautan dari -lfoo ke -l / path / ke / static / foo.a

Anda mungkin dapat menemukan dan mengganti. Setelah itu periksa alat tidak terhubung ke .so atau dylib menggunakan ldd foo atau otool -L foo

Masalah lain adalah tidak semua perpustakaan mengkompilasi ke perpustakaan statis. Banyak yang melakukannya. Tetapi MacPorts atau Debian mungkin telah memutuskan untuk tidak mengirimkannya.

4. Bagaimana saya bisa tahu perpustakaan apa yang telah saya instal, dan versi apa?

Jika Anda memiliki file pkg-config untuk pustaka itu mudah:

pkg-config --list-all

Kalau tidak, Anda seringkali tidak dapat dengan mudah. Dylib mungkin memiliki soname (mis. Foo.0.1.dylib, soname adalah 0,1) yang sama dengan versi perpustakaan. Namun ini tidak diperlukan. Soname adalah fitur komputabilitas biner, Anda harus menabrak bagian utama soname jika Anda mengubah format fungsi di perpustakaan. Jadi Anda bisa mendapatkan mis. versi 14.0.5 soname untuk pustaka 2.0. Meskipun ini tidak umum.

Saya frustrasi dengan hal semacam ini dan telah mengembangkan solusi untuk ini di Mac, dan saya akan membicarakannya selanjutnya.

5. Bagaimana saya bisa menginstal lebih dari satu versi perpustakaan tanpa merusak sistem normal saya?

Solusi saya untuk ini ada di sini: http://github.com/mxcl/homebrew/

Saya suka menginstal dari sumber, dan menginginkan alat yang membuatnya mudah, tetapi dengan beberapa manajemen paket. Jadi dengan Homebrew saya membangun, misalnya. wget diri saya dari sumber, tetapi pastikan untuk menginstal ke awalan khusus:

/usr/local/Cellar/wget/1.1.4

Saya kemudian menggunakan alat homebrew untuk menghubungkan semua itu ke / usr / local, jadi saya masih memiliki / usr / local / bin / wget dan /usr/local/lib/libwget.dylib

Nanti jika saya membutuhkan versi wget yang berbeda, saya dapat menginstalnya secara paralel dan hanya mengubah versi yang ditautkan ke pohon / usr / local.

6. Jika saya menginstal barang dari sumber pada sistem yang jika tidak dikelola menggunakan paket, apa cara paling bersih untuk melakukannya?

Saya percaya cara Homebrew paling bersih, jadi gunakan atau lakukan yang setara. Instal ke / usr / local / pkgs / name / versi dan symlink atau hard link sisanya masuk

Gunakan / usr / lokal. Setiap alat build yang ada mencari dependensi dan header di sana. Hidupmu akan jauh lebih mudah.

7. Dengan asumsi saya berhasil menyusun sesuatu secara fiddly dari sumber, bagaimana saya dapat mengemasnya sehingga orang lain tidak perlu melompat melalui lingkaran yang sama? Khususnya pada OS X ....

Jika tidak memiliki dependensi, Anda dapat menggunakan direktori build dan memberikannya kepada orang lain yang kemudian dapat melakukan "make install". Namun Anda hanya dapat melakukan ini dengan andal untuk versi OS X yang sama persis. Di Linux mungkin akan bekerja untuk Linux yang serupa (mis. Ubuntu) dengan versi Kernel dan libc versi minor yang sama.

Alasan mengapa tidak mudah untuk mendistribusikan binari di Unix adalah karena kompatibilitas binari. Orang-orang GNU, dan semua orang sering mengubah antarmuka biner mereka.

Pada dasarnya jangan mendistribusikan binari. Berbagai hal mungkin akan pecah dengan cara yang sangat aneh.

Di Mac, opsi terbaik adalah membuat paket macports. Semua orang menggunakan macports. Di Linux ada begitu banyak sistem dan kombinasi build yang berbeda, saya kira tidak ada saran yang lebih baik daripada menulis entri blog tentang bagaimana Anda berhasil membangun x tool dalam konfigurasi yang aneh.

Jika Anda membuat deskripsi paket (untuk macports atau homebrew) maka siapa pun dapat menginstal paket itu, dan itu memecahkan masalah ketergantungan juga. Namun ini seringkali tidak mudah, dan juga tidak mudah untuk mendapatkan resep macports Anda termasuk dalam pohon macports utama. Juga macports tidak mendukung jenis instalasi yang eksotis, mereka menawarkan satu pilihan untuk semua paket.

Salah satu tujuan masa depan saya dengan Homebrew adalah memungkinkan untuk mengklik tautan di situs web (mis. Homebrew: // blah dan itu akan mengunduh skrip Ruby itu, menginstal deps untuk paket itu dan kemudian membangun aplikasinya. Tapi ya, belum selesai, tapi tidak terlalu rumit mengingat desain yang saya pilih.

8. Apa saja alat baris perintah yang harus saya kuasai untuk menjadi ahli dalam hal ini? Hal-hal seperti otool, pkg-config dll.

otool benar-benar hanya bermanfaat sesudahnya. Ini memberi tahu Anda apa yang dibangun tautan biner. Ketika Anda mencari tahu dependensi alat yang harus Anda bangun, itu tidak berguna. Hal yang sama berlaku untuk pkg-config karena Anda telah menginstal dependensi sebelum dapat menggunakannya.

Rantai alat saya adalah, baca file README dan INSTALL, dan lakukan configure --help. Tonton output build untuk memeriksa apakah ia waras. Parsing setiap kesalahan build. Mungkin di masa depan, tanyakan pada serverfault :)

Max Howell
sumber
2
Menarik, Homebrew sepertinya mirip dengan Portage (manajer paket dari Gentoo Linux). Kedengarannya seperti pekerjaan yang bagus.
David Z
12

Ini adalah topik yang sangat besar, jadi mari kita mulai dengan perpustakaan bersama di Linux (ELF di Linux dan Mach-O di OS X), Ulrich Drepper memiliki pengantar yang baik untuk menulis DSO (objek bersama dinamis) yang mencakup beberapa sejarah perpustakaan bersama di Linux yang tersedia di sini termasuk mengapa mereka penting

Ulrich juga menjelaskan mengapa tautan statis dianggap berbahaya. Salah satu poin kunci di sini adalah pembaruan keamanan. Kelebihan buffer di perpustakaan umum (mis. Zlib) yang terhubung secara statis secara luas dapat menyebabkan overhead yang sangat besar untuk distribusi - ini terjadi dengan zlib 1.1.3 ( Red Hat advisory )

PERI

Linker ld.so halaman manual

man ld.so 

menjelaskan jalur dasar dan file yang terlibat dalam tautan dinamis runtime. Pada sistem Linux modern Anda akan melihat jalur tambahan ditambahkan melalui /etc/ld.so.conf.d/ ditambahkan biasanya melalui glob termasuk dalam /etc/ld.so.conf.

Jika Anda ingin melihat apa yang tersedia secara dinamis melalui konfigurasi ld.so Anda, Anda dapat menjalankannya

ldconfig -v -N -X

Membaca DSO howto harus memberi Anda tingkat dasar pengetahuan yang baik untuk kemudian memahami bagaimana prinsip-prinsip itu berlaku untuk Mach-O pada OS X.

Jantan

Pada OS X format biner adalah Mach-O. Dokumentasi sistem lokal untuk tautannya adalah

man dyld

The dokumentasi Format Mach tersedia dari Apple

UNIX membangun alat

Umum configure, make, make installproses umumnya disediakan oleh GNU autotools yang memiliki buku secara online yang mencakup beberapa sejarah configure / membangun split dan GNU toolchain. Autoconf menggunakan tes untuk menentukan ketersediaan fitur pada sistem build target, ia menggunakan bahasa makro M4 untuk mendorong ini. Automake pada dasarnya adalah metode templating untuk Makefile, template yang umumnya disebut Makefile.am yang menghasilkan Makefile.in yang output autoconf (skrip configure) dikonversi menjadi Makefile.

Program halo GNU bertindak sebagai contoh yang baik untuk memahami rantai alat GNU - dan manual menyertakan dokumentasi autotools.


sumber
10

Simon! Saya tahu apa yang kau rasakan; Saya berjuang dengan bagian ini belajar Linux, juga. Berdasarkan pengalaman saya sendiri, saya menulis tutorial tentang beberapa item yang Anda alamat (kebanyakan sebagai referensi untuk diri saya sendiri!): Http://easyaspy.blogspot.com/2008/12/buildinginstalling-application-from.html . Saya pikir Anda akan menghargai catatan saya tentang bagaimana membangun / menginstal aplikasi Python sederhana. :)

Semoga ini bisa membantu! Dan senang menyusunnya.

Tim Jones


Membangun / Memasang aplikasi dari sumber di Ubuntu Linux

Sementara repositori Ubuntu penuh dengan aplikasi hebat, pada satu waktu atau lain Anda terikat untuk menemukan alat "must-have" yang tidak ada dalam repositori (atau tidak memiliki paket Debian) atau Anda memerlukan versi yang lebih baru daripada di repositori. Apa yang kamu kerjakan? Nah, Anda harus membangun aplikasi dari sumber! Jangan khawatir, ini benar-benar tidak serumit kedengarannya. Berikut adalah beberapa tips, berdasarkan pengalaman saya untuk menjadi amatir peringkat! (Sementara saya menggunakan Ubuntu untuk contoh ini, konsep umum harus berlaku untuk sebagian besar distribusi Unix / Linux, seperti Fedora, dan bahkan platform Cygwin pada Windows.)

Proses dasar membangun (mengkompilasi) sebagian besar aplikasi dari sumber mengikuti urutan ini: configure -> compile -> install. Perintah Unix / Linux untuk melakukan hal-hal ini adalah: config-> make-> make install. Dalam beberapa kasus, Anda bahkan akan menemukan halaman web yang menunjukkan bahwa semua ini dapat digabungkan menjadi satu perintah:

$ config && make && make install

Tentu saja, perintah ini mengasumsikan bahwa tidak ada masalah dalam langkah-langkah ini. Di sinilah kesenangan datang!

Mulai

Jika Anda belum pernah mengkompilasi aplikasi dari sumber pada sistem Anda sebelumnya, Anda mungkin perlu mengaturnya dengan beberapa alat pengembangan umum, seperti gccsuite kompiler, beberapa file header umum (anggap ini sebagai kode yang telah ditulis oleh orang lain yang digunakan oleh program yang Anda instal), dan alat make. Untungnya, di Ubuntu, ada metapackage yang disebut build-essentialyang akan menginstal ini. Untuk menginstalnya (atau pastikan Anda sudah memilikinya!), Jalankan perintah ini di terminal:

$ sudo apt-get install build-essential

Sekarang setelah Anda memiliki pengaturan dasar, unduh file sumber aplikasi dan simpan ke direktori yang telah Anda baca / tulis izinnya, seperti direktori "home" Anda. Biasanya, ini akan berada dalam file arsip dengan ekstensi file baik .tar.gzatau .tar.bz2. Secara .tarsederhana ini berarti "arsip tape", yang merupakan pengelompokan file yang mempertahankan struktur direktori relatif mereka. The .gzsingkatan gzip (GNU zip), yang merupakan format kompresi Unix / Linux populer. Demikian pula, .bz2singkatan dari bzip2, yang merupakan format kompresi yang lebih baru yang memberikan kompresi lebih tinggi (ukuran file terkompresi lebih kecil) daripada gzip.

Setelah Anda mengunduh file sumber, buka jendela terminal (Terminal Sistem dari menu Ubuntu) dan ubah ke direktori tempat Anda menyimpan file Anda. (Saya akan gunakan ~/downloaddalam contoh ini. Di sini, '~' adalah jalan pintas ke direktori "home" Anda.) Gunakan perintah tar untuk mengekstrak file dari file arsip yang diunduh:

Jika file Anda adalah arsip gzip (mis. Diakhiri dengan .tar.gz), gunakan perintah:

            $ tar -zxvf filename.tar.gz

Jika file Anda adalah arsip bzip2 (mis. Diakhiri dengan .tar.bz2), gunakan perintah:

            $ tar -jxvf filename.tar.gz

Kiat: Jika Anda tidak ingin harus mengingat semua sakelar baris perintah untuk mengekstraksi arsip, saya sarankan untuk mendapatkan satu (atau keduanya) dari utilitas ini: dtrx (favorit saya!) Atau deco (lebih populer). Dengan salah satu dari utilitas ini, Anda cukup memasukkan nama utilitas (dtrx atau deco) dan nama file, ia mengerjakan sisanya. Kedua "tahu" ini bagaimana menangani sebagian besar format arsip yang cenderung Anda temui dan mereka memiliki penanganan kesalahan yang besar.

Saat membangun dari sumber, ada dua jenis kesalahan umum yang cenderung Anda temui:

  1. Kesalahan konfigurasi terjadi ketika Anda menjalankan skrip konfigurasi (biasanya bernama config atau configure) untuk membuat makefile yang khusus untuk pengaturan Anda.
  2. Kesalahan kompiler terjadi ketika Anda menjalankan perintah make (setelah makefile dibuat) dan kompiler tidak dapat menemukan beberapa kode yang diperlukan.

Kami akan melihat masing-masing dan membahas bagaimana menyelesaikannya.

Konfigurasi dan Kesalahan Konfigurasi

Setelah Anda mengekstrak file arsip kode sumber, di terminal, Anda harus mengubah ke direktori yang berisi file yang diekstraksi. Biasanya, nama direktori ini akan sama dengan nama file (tanpa ekstensi .tar.gzatau .tar.bz2). Namun, kadang-kadang nama direktori hanyalah nama aplikasi, tanpa informasi versi apa pun.

Di direktori sumber, cari READMEfile dan / atau INSTALLfile (atau sesuatu dengan nama yang mirip). File-file ini biasanya berisi informasi berguna tentang cara membangun / mengkompilasi aplikasi dan menginstalnya, termasuk informasi tentang dependensi. "Ketergantungan" hanyalah nama yang bagus untuk komponen atau pustaka lain yang diperlukan untuk berhasil dikompilasi.

Setelah Anda membaca file READMEdan / atau INSTALLfile (dan, semoga melihat dokumentasi online yang relevan untuk aplikasi), cari file executable (memiliki izin "x" pada file) bernama configatau configure. Terkadang file mungkin memiliki ekstensi, seperti .sh(misalnya, config.sh). Ini biasanya skrip shell yang menjalankan beberapa utilitas lain untuk mengonfirmasi bahwa Anda memiliki lingkungan "waras" untuk dikompilasi. Dengan kata lain, itu akan memeriksa untuk memastikan bahwa Anda telah menginstal semua yang Anda butuhkan.

Tip: Jika ini adalah aplikasi berbasis Python, alih-alih file konfigurasi, Anda harus mencari file yang bernama setup.py. Aplikasi python biasanya sangat sederhana untuk diinstal. Untuk menginstal aplikasi ini, sebagai root (mis., Letakkan sudo di depan perintah berikut di bawah Ubuntu), jalankan perintah ini:

    $ python setup.py install

Hanya itu yang harus Anda lakukan. Anda dapat melewati sisa tutorial ini dan melanjutkan langsung untuk menggunakan dan menikmati aplikasi Anda.

Jalankan skrip konfigurasi di terminal. Biasanya, Anda dapat (dan seharusnya!) Menjalankan skrip konfigurasi dengan akun pengguna reguler Anda.

$ ./config

Script akan menampilkan beberapa pesan untuk memberi Anda gambaran tentang apa yang dilakukannya. Seringkali, skrip akan memberi Anda indikasi apakah berhasil atau gagal dan, jika gagal, beberapa informasi tentang penyebab kegagalan. Jika Anda tidak mendapatkan pesan kesalahan, maka Anda biasanya dapat menganggap bahwa semuanya berjalan dengan baik.

Jika Anda tidak menemukan skrip apa pun yang terlihat seperti skrip konfigurasi, maka itu biasanya berarti bahwa aplikasinya sangat sederhana dan merupakan platform independen. Ini berarti bahwa Anda dapat langsung beralih ke langkah build / compile di bawah ini, karena yang disediakan Makefileharus bekerja pada sistem apa pun.

Sebuah contoh

Dalam tutorial ini, saya akan menggunakan RSS reader berbasis teks yang disebut Newsbeuter sebagai contoh untuk jenis kesalahan yang mungkin Anda temui ketika membangun aplikasi Anda. Untuk Newsbeuter, nama skrip konfigurasi adalah config.sh. Di sistem saya, ketika saya menjalankan config.sh, kesalahan berikut terjadi:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ ./config.sh
Checking for package sqlite3... not found

You need package sqlite3 in order to compile this program.
Please make sure it is installed.

Setelah melakukan beberapa penelitian, saya menemukan bahwa, pada kenyataannya, sqlite3aplikasi telah diinstal. Namun, karena saya mencoba membangun dari sumber, ini adalah tip yang config.shsebenarnya dicari adalah pustaka pengembangan (header) sqlite3. Di Ubuntu, sebagian besar paket memiliki paket rekanan pengembangan terkait yang diakhiri -dev. (Platform lain, seperti Fedora, sering menggunakan sufiks paket -develuntuk paket pengembangan.)

Untuk menemukan paket yang sesuai untuk paket sqlite3pengembangan, kita dapat menggunakan apt-cacheutilitas di Ubuntu (dan, juga, yumutilitas di Fedora):

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-cache search sqlite

Perintah ini mengembalikan daftar hasil yang cukup besar, jadi kita harus melakukan sedikit pekerjaan detektif untuk menentukan paket mana yang sesuai. Dalam hal ini, paket yang sesuai ternyata libsqlite3-dev. Perhatikan bahwa kadang-kadang paket yang kita cari akan memiliki libawalan, bukan hanya nama paket plus yang sama -dev. Ini karena kadang-kadang kita hanya mencari pustaka bersama yang dapat digunakan oleh banyak aplikasi berbeda. Untuk menginstal libsqlite3-dev, jalankan perintah apt-get install di terminal:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-get install libsqlite3-dev

Sekarang, kita harus menjalankan config.shlagi untuk memastikan bahwa kita telah menyelesaikan masalah ketergantungan ini dan bahwa kita tidak memiliki masalah ketergantungan lagi. (Walaupun saya tidak akan menunjukkannya di sini, dalam kasus Newsbeuter, saya juga harus menginstal libcurl4-openssl-devpaket.) Juga, jika Anda menginstal paket pengembangan (seperti libsqlite3-dev) dan paket aplikasi yang terkait (mis., sqlite3) Tidak sudah diinstal, sebagian besar sistem akan secara otomatis menginstal paket aplikasi terkait pada saat yang sama.

Ketika konfigurasi berjalan dengan sukses, hasilnya akan membuat satu atau lebih file make. File-file ini biasanya dinamai Makefile(ingat bahwa kasus nama file penting di Unix / Linux!). Jika paket build menyertakan sub-direktori, seperti src, dll., Masing-masing sub-direktori ini akan berisi Makefile, juga.

Kesalahan Bangunan dan Kompilasi

Sekarang, kami siap untuk benar-benar mengkompilasi aplikasi. Ini sering disebut bangunan dan namanya dipinjam dari proses membangun sesuatu di dunia nyata. Berbagai "potongan" aplikasi, yang biasanya merupakan beberapa file kode sumber, digabungkan bersama untuk membentuk keseluruhan aplikasi. Utilitas make mengelola proses pembuatan dan memanggil aplikasi lain, seperti kompiler dan tautan, untuk benar-benar melakukan pekerjaannya. Dalam kebanyakan kasus, Anda cukup menjalankan make (dengan akun pengguna reguler Anda) dari direktori tempat Anda menjalankan konfigurasi. (Dalam beberapa kasus, seperti mengkompilasi aplikasi yang ditulis dengan pustaka Qt, Anda perlu menjalankan aplikasi "pembungkus" lain seperti qmake sebagai gantinya. Sekali lagi, selalu periksa READMEdan / atau INSTALLdokumen untuk detailnya.)

Seperti halnya skrip konfigurasi di atas, ketika Anda menjalankan make (atau utilitas serupa) di terminal, ia akan menampilkan beberapa pesan tentang apa yang sedang dieksekusi dan setiap peringatan dan kesalahan. Anda biasanya dapat mengabaikan peringatan, karena ini terutama untuk pengembang aplikasi dan memberi tahu mereka bahwa ada beberapa praktik standar yang dilanggar. Biasanya, peringatan ini tidak memengaruhi fungsi aplikasi. Di sisi lain, kesalahan penyusun harus ditangani. Dengan Newsbeuter, ketika saya berlari membuat, segalanya berjalan baik untuk sementara waktu, tapi kemudian saya mendapat kesalahan:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ make
...
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/configparser.o -c src/configparser.cpp
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/colormanager.o -c src/colormanager.cpp
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:5:18: error: stfl.h: No such file or directory
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:33: error: ISO C++ forbids declaration of \u2018stfl_form\u2019 with no type
./include/stflpp.h:33: error: expected \u2018;\u2019 before \u2018*\u2019 token
./include/stflpp.h:34: error: ISO C++ forbids declaration of \u2018stfl_ipool\u2019 with no type
./include/stflpp.h:34: error: expected \u2018;\u2019 before \u2018*\u2019 token
make: *** [src/colormanager.o] Error 1

Proses make akan berhenti segera setelah kesalahan pertama ditemukan. Menangani kesalahan kompiler terkadang bisa menjadi bisnis yang rumit. Anda harus melihat kesalahan untuk beberapa petunjuk tentang masalah tersebut. Biasanya, masalahnya adalah bahwa beberapa file header, yang biasanya memiliki ekstensi .hatau .hpp, tidak ada. Dalam kasus kesalahan di atas, jelas (atau seharusnya!) Masalahnya adalah bahwa stfl.hfile header tidak dapat ditemukan. Seperti yang ditunjukkan contoh ini, Anda ingin melihat baris pertama dari pesan kesalahan dan mencari cara untuk menemukan penyebab masalah yang mendasarinya.

Setelah melihat dokumentasi Newsbeuter (yang seharusnya saya lakukan sebelum saya mulai, tapi kemudian bagian tutorial ini tidak akan sangat berarti!), Saya menemukan bahwa itu membutuhkan perpustakaan pihak ke-3 yang disebut STFL. Jadi apa yang kita lakukan dalam kasus ini? Yah, pada dasarnya kami mengulangi proses yang sama persis untuk pustaka yang diperlukan: dapatkan pustaka dan jalankan proses configure-build-install untuk itu dan, kemudian, lanjutkan membangun aplikasi yang diinginkan. Sebagai contoh, dalam kasus STFL, saya harus menginstal libncursesw5-devpaket agar dapat dibangun dengan benar. (Biasanya, tidak perlu mengulang langkah konfigurasi pada aplikasi asli kami setelah menginstal aplikasi lain yang diperlukan, tetapi tidak ada salahnya juga.)

Setelah berhasil menginstal STFL toolkit, proses make untuk Newsbeuter berjalan dengan sukses. Proses make biasanya mengambil di mana ia pergi (pada titik kesalahan). Dengan demikian, semua file yang telah berhasil dikompilasi tidak akan dikompilasi ulang. Jika Anda ingin mengkompilasi ulang semuanya, Anda dapat menjalankan make clean all untuk menghapus objek yang dikompilasi dan kemudian jalankan make lagi.

Menginstal

Setelah proses build selesai dengan sukses, Anda siap untuk menginstal aplikasi. Dalam kebanyakan kasus, untuk menginstal aplikasi ke area umum sistem file (misalnya, /usr/binatau /usr/share/bin, dll.), Anda harus menjalankan instalasi sebagai root. Instalasi sebenarnya adalah langkah paling sederhana dalam keseluruhan proses. Untuk menginstal, dalam terminal run:

$ make install

Periksa output dari proses ini untuk setiap kesalahan. Jika semuanya berhasil, Anda harus dapat menjalankan nama perintah di terminal dan itu akan diluncurkan. (Tambahkan & ke akhir baris perintah, jika itu adalah aplikasi GUI, atau Anda tidak akan dapat menggunakan sesi terminal sampai aplikasi selesai berjalan.)

Saat Anda membangun aplikasi dari sumber, biasanya tidak akan menambahkan ikon atau pintasan ke menu GUI di Ubuntu. Anda harus menambahkan ini secara manual.

Dan itu pada dasarnya adalah proses, meskipun berpotensi berulang, untuk membangun dan menginstal aplikasi dari sumber di Ubuntu. Setelah Anda melakukan ini hanya beberapa kali, itu akan menjadi kebiasaan Anda!

Tim Jones
sumber
Tim, saya ingin membaca tutorial Anda, tetapi tautan yang Anda posting tidak berfungsi.
gareth_bowles
6

Nah, ./configure --help akan memberi Anda banyak informasi, untuk autotools yang dihasilkan GNU mengkonfigurasi file. Sebagian besar turun ke --with / - tanpa mengaktifkan fitur (ini mungkin mengambil parameter tambahan, seperti "dibagikan" untuk mengatakan di mana menemukan perpustakaan).

Yang penting lainnya adalah --prefix (yang default ke / usr / local / sebagian besar waktu) untuk mengatakan di mana harus menginstal (jika Anda membangun paket, Anda biasanya menginginkan ini sebagai --prefix = / usr atau mungkin --prefix = / opt / YourPackage).

Di Linux, / lib, / usr / lib dan / usr / local / lib umumnya mencari gcc saya, dan termasuk dalam konfigurasi default ldconfig. Kecuali Anda memiliki alasan yang bagus, ini adalah di mana Anda ingin perpustakaan Anda. /etc/ld.so.conf dapat mendaftar entri tambahan.

konfigurasikan dan temukan dengan hanya mencoba menjalankan "gcc -l" dan melihat apakah ada kesalahan. Anda dapat menambahkan "-L" ke parameter CFLAGS Anda untuk menambahkan jalur tambahan untuk pencarian.

Anda dapat menginstal beberapa versi, dan peranti lunak yang ditautkan dengan versi yang lebih lama akan tetap ditautkan dengannya (jalankan ldd untuk mencari tahu pengikatannya di Linux), tetapi kompilasi baru umumnya menargetkan versi terbaru dari pustaka dinamis pada sistem Anda.

Sebagian besar perangkat lunak mengasumsikan lib dinamis, terutama jika menggunakan libtool, jadi Anda mungkin menemukan aplikasi non-sepele tidak membangun dengan benar secara statis.

ls-l adalah taruhan terbaik Anda untuk menemukan perpustakaan diinstal.

Dan di situlah saya kehabisan informasi; cara bermain baik dengan paket: tidak tahu. Jika memungkinkan, saya mencoba dan membungkus barang-barang menjadi satu paket untuk menghindari masalah.

Aaron Brady
sumber
4

"Bagaimana cara mencari tahu argumen apa yang harus dilewati ./configure?"

biasanya: ./configure --help akan memberi tahu Anda apa yang Anda inginkan di sana.

"Bagaimana saya bisa tahu perpustakaan apa yang telah saya instal, dan versi apa?"

Itu tergantung pada sistem. Salah satu caranya adalah dengan hanya melakukan find /|grep libname|lesskarena umumnya file perpustakaan memiliki versi dalam nama file.

"Bagaimana saya bisa menginstal lebih dari satu versi perpustakaan tanpa merusak sistem normal saya?"

Sekali lagi, tergantung pada sistem dan perpustakaan. sudo make altinstallakan membuat nama versi untuk Anda. File perpustakaan biasanya versi sendiri. Perlu diingat; karena versi sering membuat symlink ke nama "dinormalisasi" ini dapat merusak hal-hal.

"Jika saya menginstal barang dari sumber pada sistem yang jika tidak dikelola menggunakan paket, apa cara paling bersih untuk melakukannya?"

Menggunakan parameter --prefix di ./configure dan meletakkannya di suatu tempat /optmerupakan praktik yang baik untuk diikuti.

Penafian: Saya bukan ahli, tapi saya sudah menggunakan linux selama lebih dari 5 tahun dari baris cmd (slackware, CentOS, redhat, ubuntu, misc others, dan OS X).

Phillip B Oldham
sumber
4

Untuk menjawab sedikit pertanyaan Anda, saya menemukan cara yang baik beberapa hari yang lalu untuk melihat perpustakaan apa yang telah Anda instal dan versinya (Ini ada di Linux Debian jadi harus juga bekerja dengan versi lain).

dpkg --list

Anda harus mendapatkan daftar yang sangat panjang dengan beberapa keluaran seperti ini

ii  libssl0.9.8    0.9.8c-4etch5  SSL shared libraries
ii  libssp0        4.1.1-21       GCC stack smashing protection library
ii  libstdc++5     3.3.6-15       The GNU Standard C++ Library v3
ii  libstdc++5-3.3 3.3.6-15       The GNU Standard C++ Library v3 (development
ii  libstdc++6     4.1.1-21       The GNU Standard C++ Library v3
Mark Davidson
sumber
4

Simon,

1.) ./configure --help menyediakan banyak informasi. Saya sarankan memeriksanya. Biasanya memiliki opsi untuk mengkompilasi pustaka yang terhubung secara dinamis / dinamis bila perlu.

2.) Libaries hidup di jalur tautan dinamis. Ini biasanya diatur di /etc/ld.so.conf. Linker mencari pustaka yang sesuai seperti variabel lingkungan PATH yang cocok dengan yang pertama ditemukan.

3.) Itu biasanya mengarah ke masalah karena Anda harus mengkompilasi ulang semuanya ketika versi pustaka berubah. Jika Anda melakukan pencarian, Anda mungkin akan menemukan banyak sekali alasan mengapa menghubungkan secara statis adalah ide yang buruk. Saya belum melakukannya dalam waktu yang lama sehingga saya tidak bisa menjelaskannya di sini.

4.) Ini agak sulit. Anda perlu memeriksa jalur perpustakaan Anda untuk memastikannya. Perpustakaan umumnya memiliki tautan simbolis ke versi yang diinstal.

mis. libssh2.so.1 -> libssh2.so.1.0.0

Umumnya orang mengelola perpustakaan dan program yang mereka instal dengan menggulirkan paket debian mereka sendiri atau menggunakan teknik lain. Saya mengelola perangkat lunak yang diinstal menggunakan stow ( http://www.gnu.org/software/stow/ ) yang sangat sederhana dan menginstal perpustakaan menggunakan tautan simbolik. Saya merasa lebih mudah karena saya tidak perlu membangun / menginstal / menguji paket deb / rpm.

5.) Beberapa versi perpustakaan dapat diinstal secara normal di direktori perpustakaan. Perpustakaan yang ditautkan ke executable akan tetap terhubung dengan versi yang ditautkan. menjalankan ldd pada file executable akan memberi tahu Anda perpustakaan mana yang bisa dieksekusi.

6.) Seperti yang saya sebutkan sebelumnya, menggulung paket debian Anda sendiri atau menggunakan stow mungkin merupakan solusi terbersih.

7.) Saya tidak bisa berbicara untuk Mac OSX tetapi untuk Linux sistem pengemasan distribusi adalah cara terbaik.

8.) Mungkin banyak frustrasi akan diselesaikan dengan menggunakan ldd dan mencari tahu versi apa yang dihubungkan sesuatu atau pustaka apa yang tertaut pada suatu executable tidak dapat ditemukan. pkg-config akan banyak membantu Anda tetapi hanya untuk perangkat lunak yang menggunakannya. Ini bukan bagian dari sistem autotools bawaan meskipun sudah populer akhir-akhir ini.

Ian Lewis
sumber
4

Perpustakaan statis bukan ide yang baik - jika Anda perlu memutakhirkan perpustakaan (untuk memperbaiki masalah keamanan, misalnya), Anda harus mengkompilasi ulang semuanya dengan ketergantungan pada perpustakaan itu.

Saya tidak suka ide "make install" yang berpotensi mengacaukan sistem saya, tetapi seperti yang dikatakan orang lain, biasanya jauh lebih sedikit rasa sakit untuk menginstal sesuatu di / usr / local daripada menggunakan --prefix untuk menginstal di tempat lain. Jadi, saya sudah membagikan / usr / lokal ke pengguna reguler saya (non-privilege). Dengan begitu "make install" dijamin cukup banyak untuk tidak mengacaukan file sistem penting. (Ini jelas tidak akan bekerja pada sistem multi-pengguna. Ini bagus untuk server virtual.)

ithinkihaveacat
sumber
4

Meskipun tidak secara eksplisit ada dalam daftar pertanyaan Anda, Anda menyebutkan dalam kata pengantar Anda:

./configure && make && sudo make install biasanya cukup, tetapi kadang-kadang tidak berhasil - dan ketika tidak, saya sering macet.

Ketika saya macet di Debian atau Ubuntu saya akan menggunakan auto-apt yang secara otomatis akan menginstal paket yang berisi file-file yang mengkonfigurasi tidak dapat menemukan.

Lihat:

Alat lain yang mungkin berguna bagi Anda adalah CheckInstall, itu menambah aplikasi yang diinstal bersama make installke dalam daftar paket yang diinstal: https://help.ubuntu.com/community/CheckInstall

Swoogan
sumber
3

Untuk OS X:

  • Bagaimana cara mencari tahu argumen apa yang harus dilewati ./configure?

./configure --help

  • Apa perbedaan aktual antara pustaka bersama dan yang terhubung secara statis? Mengapa saya tidak bisa hanya menautkan semuanya secara statis (RAM dan ruang disk murah hari ini) dan karenanya menghindari konflik versi perpustakaan yang aneh?

Menggunakan pustaka bersama memungkinkan Anda untuk meningkatkan pustaka tanpa mengkompilasi ulang semua yang memanfaatkannya.

  • Bagaimana pustaka bersama bekerja di bawah OS X / Linux - di mana mereka tinggal di sistem file, bagaimana ./configure && make menemukannya, apa yang sebenarnya terjadi ketika mereka ditautkan

Pustaka sistem tinggal di / usr / lib.

Perpustakaan yang Anda kompilasi sendiri tinggal di / usr / local / lib (/ usr / local menjadi flag --prefix default untuk ./configure).

Variabel lingkungan DYLD_FALLBACK_LIBRARY_PATH dan LD_LIBRARY_PATH memungkinkan Anda menentukan folder mana yang akan dicari, jadi / usr / local / lib harus ada di awal daftar.

  • Bagaimana saya bisa menginstal lebih dari satu versi perpustakaan tanpa merusak sistem normal saya?

Instal semuanya ke / usr / local - dengan variabel lingkungan di atas, versi di / usr / local / lib diutamakan daripada versi di / usr / lib di lingkungan Anda.

  • Jika saya menginstal hal-hal dari sumber pada sistem yang dikelola menggunakan paket, apa cara paling bersih untuk melakukannya?

Instal ke / usr / lokal. Di Ubuntu, saya mencoba dan menggunakan checkinstall terlebih dahulu, untuk membuat paket deb.

  • Dengan asumsi saya berhasil mengkompilasi sesuatu secara fiddly dari sumber, bagaimana saya bisa mengemasnya sehingga orang lain tidak harus melompat melalui lingkaran yang sama? Khususnya pada OS X ....

Dokumentasikan langkah kompilasi dalam posting blog, kataku.

Alf Eaton
sumber