Apa yang setara dengan CMake dari 'configure --prefix = DIR && make all install'?

386

Saya lakukan cmake . && make all install. Ini berfungsi, tetapi instal ke /usr/local.

Saya perlu menginstal ke awalan yang berbeda (misalnya, ke /usr).

Apa cmakedan makebaris perintah untuk menginstal /usrbukan /usr/local?

Andrei
sumber
1
Ini adalah pertanyaan yang bagus untuk mengubah direktori instalasi dengan cepat, tetapi mengapa ini merupakan kebutuhan yang tampaknya umum? Dari sudut pandang saya, jawabannya harus JANGAN menggunakan opsi baris perintah, alih-alih mengedit basis CMakeLists.txtsehingga Anda dapat mengaturnya dan melupakannya. Saya tidak mengatakan tidak ada kasus penggunaan umum untuk mengubah direktori instal on the fly - jelas ada yang menilai dari jumlah suara - Saya hanya cukup baru untuk CMake dan ingin tahu ketika masalah ini muncul.
CivFan
8
@CivFan ini untuk melayani pengguna yang ingin membangun & menginstal proyek ke lokasi tertentu, tetapi bukan orang yang sama dengan pengembang / pengelola proyek.
David Röthlisberger
4
@CivFan Jadi sebagai pengelola, tidak jarang bagi saya untuk menguji saya make installke jalur sementara untuk memastikan semua yang perlu diinstal, dipasang ke lokasi yang tepat tanpa mengacaukan mesin pengembangan saya. Hanya satu contoh. Kasus lain adalah kompilasi silang untuk arsitektur lain.
Daniel
5
@CivFan: Saya perlu ini karena saya ingin membangun paket RPM. Jika saya perlu mengubah CMakeLists.txt, maka saya perlu menambal sumber aslinya. Hanya dengan memiliki opsi baris perintah memungkinkan saya untuk mendapatkan jalur yang benar di specfile Fedora .
Martin Ueding
1
@CivFan (dan lainnya yang membaca ini) FYI, umumnya dianggap ide yang buruk untuk mengedit CMakeLists.txtfile jika Anda hanya membangun dan menginstal perangkat lunak - mengesampingkan / mengatur variabel dari baris perintah atau file cache awal, dll. Adalah "konsumen" yang lebih disukai cara pengaturan opsi.
Ryan Pavlik

Jawaban:

444

Anda bisa meneruskan variabel CMake apa pun di baris perintah, atau mengedit variabel yang di-cache menggunakan ccmake / cmake-gui. Di baris perintah,

cmake -DCMAKE_INSTALL_PREFIX: PATH = / usr. && buat semua instal

Akan mengkonfigurasi proyek, membangun semua target dan menginstal ke awalan / usr. Tipe (PATH) tidak sepenuhnya diperlukan, tetapi akan menyebabkan cmake-gui berbasis Qt untuk menyajikan dialog pemilih direktori.

Beberapa tambahan kecil sebagai komentar memperjelas bahwa memberikan kesetaraan sederhana tidak cukup untuk beberapa orang. Praktik terbaik adalah dengan menggunakan direktori build eksternal, yaitu bukan sumber secara langsung. Juga untuk menggunakan sintaks CMake yang lebih umum, abstraksi generator.

mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX: PATH = / usr .. && cmake --build. --target instal --config Release

Anda dapat melihatnya sedikit lebih lama, dan tidak secara langsung setara lagi, tetapi lebih dekat dengan praktik terbaik dalam bentuk yang cukup ringkas ... --config hanya digunakan oleh generator multi-konfigurasi (yaitu MSVC), diabaikan oleh orang lain.

Marcus D. Hanwell
sumber
21
Ingin tahu apa: PATH itu? Ini berguna untuk cmake-gui, membantu memilih widget untuk variabel itu. Lihat doc di linux.die.net/man/1/cmake-gui (set section)
albfan
2
Mereka memberikan petunjuk kepada GUI CMake seperti yang dinyatakan, semua yang ada di CMake secara efektif adalah string, tetapi pengaturan PATH, FILEPATH, STRING, BOOL dll membantu GUI untuk menyajikan widget yang lebih tepat.
Marcus D. Hanwell
13
Anda juga dapat menggunakan: "cmake --build --target install." bukannya membuat.
RobertJMaynard
2
Apa titik untuk after / usr? /usr .
bodacydo
5
@bodacydo lokasi folder dengan CMakeLists.txt tempat kami membuat.
Kamiccolo
48

Bagian ": PATH" dalam jawaban yang diterima dapat dihilangkan. Sintaks ini mungkin lebih mudah diingat:

cmake -DCMAKE_INSTALL_PREFIX=/usr . && make all install

... seperti yang digunakan dalam jawaban di sini .

pengguna2023370
sumber
7
:PATHbukan kesalahan .
kirbyfan64sos
29

Perhatikan bahwa dalam CMake dan Autotools Anda tidak selalu harus menetapkan jalur instalasi pada waktu konfigurasi. Anda dapat menggunakan DESTDIR pada waktu instalasi (lihat juga di sini ) sebagai gantinya di:

make DESTDIR=<installhere> install

Lihat juga pertanyaan ini yang menjelaskan perbedaan halus antara DESTDIR dan PREFIX.

Ini dimaksudkan untuk menginstal bertahap dan untuk memungkinkan menyimpan program di lokasi yang berbeda dari tempat mereka dijalankan misalnya /etc/alternativesmelalui tautan simbolik.

Namun, jika paket Anda dapat dipindahkan dan tidak membutuhkan jalur kode (awalan) keras yang ditetapkan melalui tahap configure, Anda mungkin dapat melewatinya. Jadi alih-alih:

cmake -DCMAKE_INSTALL_PREFIX=/usr . && make all install

Anda akan lari:

cmake . && make DESTDIR=/usr all install

Perhatikan bahwa, seperti yang ditunjukkan pengguna7498341, ini tidak sesuai untuk kasus di mana Anda benar-benar harus menggunakan PREFIX.

Bruce Adams
sumber
9
Saya suka menunjukkan penggunaan DESTDIR. Tapi sebenarnya ini salah. Anda harus merujuk ke cmake docs cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html ... make DESTDIR=/home/john installyang akan menginstal perangkat lunak terkait menggunakan awalan instalasi, mis. "/ Usr / local" yang diawali dengan nilai DESTDIR yang akhirnya memberi "/ home / john / usr / local".
Joakim
1
Saya tidak berpikir itu bertentangan. Jika paket Anda dapat dipindahkan, Anda tidak perlu CMAKE_INSTALL_PREFIX, atau Anda dapat memilih salah satu metode. Jika tidak, Anda akan melakukannya karena CMAKE_INSTALL_PREFIX akan dipanggang di suatu tempat pada saat membangun.
Bruce Adams
jika Anda tahu bahwa generator Anda adalah Makefile ... Saya lebih suka cmake --build build --target install -- DESTDIR=/usrcatatan: ini juga harus bekerja dengan generator Ninja (aturan tampaknya mengandung $ENV{DESTDIR})
Mizux
@ Joakim sebanyak saya ingin menggunakan CMAKE_INSTALL_PREFIX, dengan melakukan hal itu tertanam path instal di file yang dikompilasi. Seperti yang terjadi, saya hanya membangun paket .rpm, sehingga tidak akan berhasil. DESTDIR bekerja seperti pesona untuk membuat segalanya menjadi buildroot.
Tuan Redstoner
18

Cara saya membangun lintas platform proyek CMake adalah sebagai berikut:

/project-root> mkdir build
/project-root> cd build
/project-root/build> cmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
/project-root/build> cmake --build . --target=install --config=Release
  • Dua baris pertama membuat direktori build out-of-source
  • Baris ketiga menghasilkan sistem build yang menentukan di mana harus meletakkan hasil instalasi (yang selalu saya tempatkan ./project-root/build/stage- path selalu dianggap relatif terhadap direktori saat ini jika tidak mutlak)
  • Baris keempat membangun proyek yang dikonfigurasikan .dengan sistem build yang dikonfigurasikan di baris sebelumnya. Ini akan mengeksekusi installtarget yang juga membangun semua target tergantung yang diperlukan jika mereka perlu dibangun dan kemudian menyalin file ke dalam CMAKE_INSTALL_PREFIX(yang dalam hal ini adalah ./project-root/build/stage. Untuk membangun multi-konfigurasi, seperti di Visual Studio, Anda juga dapat menentukan konfigurasi dengan --config <config>bendera opsional .
  • Bagian yang baik ketika menggunakan cmake --buildperintah adalah ia bekerja untuk semua generator (yaitu makefiles dan Visual Studio) tanpa memerlukan perintah yang berbeda.

Setelah itu saya menggunakan file yang diinstal untuk membuat paket atau memasukkannya ke dalam proyek lain ...

toeb
sumber
Terima kasih untuk penjelasan langkah demi langkah! IMO ini adalah satu-satunya cara, jika tidak seluruh titik cmake (platform kemerdekaan) dibuang ...
helmesjo
1
apakah Anda lupa menyertakan jalur ke sumber (../) di baris 3? BTW ini harus menjadi jawaban yang diterima.
Slava
1
LIne 3 seharusnyacmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
codenamezero
1
Sebagai catatan tambahan, secara pragmatis, orang menggunakan make -j $(nproc), untuk menentukan jumlah thread build, lakukan cmake --build . --target=install --config=Release -- -j 8untuk generator Makefile atau cmake --build . --target=install --config=Release -- /m:8untuk generator Visual Studio dengan 8 thread. Sebenarnya, Anda dapat melewati parameter commandline apa pun setelah--
Cloud
1
@MrRedstoner -jbukan bendera untuk cmake, semua bendera datang setelah --melewati sistem pembangunan yang mendasarinya ...
Cloud
4

Mengenai jawaban Bruce Adams:

Jawaban Anda menciptakan kebingungan yang berbahaya. DESTDIR dimaksudkan untuk menginstal dari root tree. Ini memungkinkan seseorang untuk melihat apa yang akan dipasang di root tree jika seseorang tidak menentukan DESTDIR. PREFIX adalah direktori dasar yang menjadi dasar instalasi sebenarnya.

Sebagai contoh, PREFIX = / usr / local menunjukkan bahwa tujuan akhir suatu paket adalah / usr / local. Menggunakan DESTDIR = $ HOME akan menginstal file seolah-olah $ HOME adalah root (/). Jika, katakanlah DESTDIR, adalah / tmp / destdir, orang dapat melihat apa yang akan mempengaruhi 'make install'. Dengan semangat itu, DESTDIR seharusnya tidak pernah memengaruhi objek yang dibangun.

Segmen makefile untuk menjelaskannya:

install:
    cp program $DESTDIR$PREFIX/bin/program

Program harus berasumsi bahwa PREFIX adalah direktori dasar dari direktori final (produksi). Kemungkinan menghubungkan program yang terinstal di DESTDIR = / sesuatu hanya berarti bahwa program tersebut tidak mengakses file berdasarkan PREFIX karena itu tidak akan berfungsi. cat (1) adalah program yang (dalam bentuk paling sederhana) dapat dijalankan dari mana saja. Berikut adalah contoh yang tidak akan:

prog.pseudo.in:
    open("@prefix@/share/prog.db")
    ...

prog:
    sed -e "s/@prefix@/$PREFIX/" prog.pseudo.in > prog.pseudo
    compile prog.pseudo

install:
    cp prog $DESTDIR$PREFIX/bin/prog
    cp prog.db $DESTDIR$PREFIX/share/prog.db

Jika Anda mencoba menjalankan prog dari tempat lain selain $ PREFIX / bin / prog, prog.db tidak akan pernah ditemukan karena tidak ada di lokasi yang diharapkan.

Akhirnya, / etc / alternative benar-benar tidak berfungsi seperti ini. Ada symlink ke program yang diinstal di root tree (mis. Vi -> / usr / bin / nvi, vi -> / usr / bin / vim, dll.).

pengguna7498341
sumber
1
Jawaban ini mungkin lebih baik ditempatkan sebagai jawaban untuk stackoverflow.com/questions/11307465/destdir-and-prefix-of-make
Bruce Adams
2

Ini dianggap praktik yang buruk untuk memanggil generator yang sebenarnya (misalnya via make) jika menggunakan CMake . Sangat disarankan untuk melakukannya seperti ini:

  1. Tahap konfigurasi:

    cmake -Hfoo -B_builds/foo/debug -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEBUG_POSTFIX=d -DCMAKE_INSTALL_PREFIX=/usr
    
  2. Bangun dan Instal fase

    cmake --build _builds/foo/debug --config Debug --target install
    

Saat mengikuti pendekatan ini, generator dapat dengan mudah dialihkan (misalnya -GNinjauntuk Ninja ) tanpa harus mengingat perintah khusus generator.

Florian Wolters
sumber
1
Jawabannya bisa lebih baik jika penjelasan diberikan untuk semua argumen yang digunakan dan mengapa mereka digunakan. Khususnya, apa gunanya --configargumen?
Dmitry Kabanov
2

Dimulai dengan CMake 3.15, cara yang benar untuk mencapai ini akan menggunakan:

cmake --install <dir> --prefix "/usr"

Dokumentasi Resmi

ExaltedBagel
sumber