Qual è l'equivalente di CMake di 'configure --prefix = DIR && make all install'?


386

Lo faccio cmake . && make all install. Funziona, ma si installa su /usr/local.

Devo installare un prefisso diverso (ad esempio, a /usr).

Qual è la riga di comando cmakee makeda installare /usrinvece di /usr/local?


1
Questa è un'ottima domanda per cambiare al volo la directory di installazione, ma perché è un'esigenza così apparentemente comune? Dal mio punto di vista, la risposta dovrebbe essere NON utilizzare un'opzione della riga di comando, invece modifica la base in CMakeLists.txtmodo da poterla impostare e dimenticarla. Non sto dicendo che non esiste un caso d'uso comune per cambiare la directory di installazione al volo - chiaramente c'è un giudizio sul numero di voti - Sono appena nuovo su CMake e curioso quando si presenta questo problema.
CivFan,

8
@CivFan è per soddisfare gli utenti che vogliono costruire e installare il progetto in una posizione particolare, ma non sono le stesse persone degli sviluppatori / manutentori del progetto.
David Röthlisberger,

4
@CivFan Quindi come manutentore, non è raro per me testare il mio make installpercorso temporaneo per assicurarsi che tutto ciò che deve essere installato, sia stato installato nella posizione giusta senza incasinare la mia macchina di sviluppo. Solo un esempio. Un altro caso è la compilazione incrociata per un'altra architettura.
Daniel

5
@CivFan: ho bisogno di questo perché voglio creare un pacchetto RPM. Se avessi bisogno di cambiare il CMakeLists.txt, allora ho bisogno di patchare la fonte originale. Il solo fatto di avere un'opzione da riga di comando mi permette di ottenere i percorsi nel specfile Fedora .
Martin Ueding,

1
@CivFan (e altri che leggono questo) Cordiali saluti, è generalmente considerata una cattiva idea modificare il CMakeLists.txtfile se si sta solo costruendo e installando software: sovrascrivere / impostare variabili dalla riga di comando o dal file di cache iniziale, ecc. È il "consumatore" preferito modo di impostare le opzioni.
Ryan Pavlik,

Risposte:


444

È possibile passare qualsiasi variabile CMake sulla riga di comando o modificare le variabili memorizzate nella cache utilizzando ccmake / cmake-gui. Sulla riga di comando,

cmake -DCMAKE_INSTALL_PREFIX: PATH = / usr. && effettua l'installazione completa

Configurerebbe il progetto, costruiva tutte le destinazioni e si installava nel prefisso / usr. Il tipo (PATH) non è strettamente necessario, ma farebbe in modo che cmake-gui basato su Qt presentasse la finestra di dialogo di scelta della directory.

Alcune aggiunte minori come commenti chiariscono che fornire una semplice equivalenza non è sufficiente per alcuni. La migliore pratica sarebbe quella di utilizzare una directory di build esterna, cioè non la fonte direttamente. Anche per usare una sintassi CMake più generica astrarre il generatore.

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

Puoi vedere che diventa un po 'più lungo e non è più direttamente equivalente, ma è più vicino alle migliori pratiche in una forma abbastanza concisa ... --config è usato solo da generatori multi-configurazione (cioè MSVC), ignorato dagli altri.


21
Chiedendosi cosa: PATH è? È utile per cmake-gui, che aiuta a scegliere il widget per quella variabile. Vedi doc in linux.die.net/man/1/cmake-gui (sezione set)
albfan,

2
Forniscono suggerimenti sulla GUI di CMake come indicato, tutto in CMake è effettivamente una stringa, ma l'impostazione di PATH, FILEPATH, STRING, BOOL ecc aiuta la GUI a presentare un widget più appropriato.
Marcus D. Hanwell,

13
Puoi anche usare: "cmake --build --target install". invece di fare.
RobertJMaynard,

2
Qual è il punto per after / usr? /usr .
bodacydo,

5
@bodacydo posizione della cartella con CMakeLists.txt che stiamo generando.
Kamiccolo,


29

Si noti che sia in CMake che in Autotools non è sempre necessario impostare il percorso di installazione al momento della configurazione. È possibile utilizzare DESTDIR al momento dell'installazione (vedere anche qui ) invece come in:

make DESTDIR=<installhere> install

Vedi anche questa domanda che spiega la sottile differenza tra DESTDIR e PREFIX.

Ciò è previsto per installazioni in fasi e per consentire l'archiviazione di programmi in una posizione diversa da quella in cui vengono eseguiti, ad esempio /etc/alternativestramite collegamenti simbolici.

Tuttavia, se il pacchetto è trasferibile e non richiede percorsi codificati (prefisso) impostati tramite la fase di configurazione, è possibile saltarlo. Quindi invece di:

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

corri:

cmake . && make DESTDIR=/usr all install

Si noti che, come sottolinea user7498341, questo non è appropriato per i casi in cui si dovrebbe davvero utilizzare PREFIX.


9
Mi piace mostrare l'uso di DESTDIR. Ma in realtà questo è sbagliato. È necessario fare riferimento ai documenti di cmake cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html ... make DESTDIR=/home/john installche installerà il software in questione utilizzando il prefisso di installazione, ad esempio "/ usr / local" con il valore DESTDIR che alla fine dà "/ home / john / usr / local".
Joakim,

1
Non credo sia contraddittorio. Se il pacchetto è trasferibile, non è necessario CMAKE_INSTALL_PREFIX, oppure è possibile scegliere uno dei due metodi. In caso contrario, perché CMAKE_INSTALL_PREFIX verrà cotto da qualche parte al momento della creazione.
Bruce Adams,

se sai che il tuo generatore è Makefile ... Preferisco cmake --build build --target install -- DESTDIR=/usrnotare: questo dovrebbe funzionare anche con il generatore Ninja (le regole sembrano contenere $ENV{DESTDIR})
Mizux

@Joakim quanto vorrei usare CMAKE_INSTALL_PREFIX, facendo così incorporato il percorso di installazione nei file compilati. In effetti, stavo semplicemente costruendo un pacchetto .rpm, quindi non sarebbe successo. DESTDIR ha funzionato come un incantesimo per mettere le cose in buildroot.
Mr Redstoner,

18

Il modo in cui costruisco i progetti CMake multipiattaforma è il seguente:

/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
  • Le prime due righe creano la directory di build out-of-source
  • La terza riga genera il sistema di generazione specificando dove inserire il risultato dell'installazione (che inserisco sempre ./project-root/build/stage- il percorso è sempre considerato relativo alla directory corrente se non è assoluto)
  • La quarta riga crea il progetto configurato .con il buildsystem configurato nella riga precedente. Eseguirà la installdestinazione che costruisce anche tutte le destinazioni dipendenti necessarie se devono essere costruite e quindi copia i file nel CMAKE_INSTALL_PREFIX(che in questo caso è ./project-root/build/stage. Per le build multi-configurazione, come in Visual Studio, puoi anche specificare la configurazione con la --config <config>bandiera opzionale .
  • La parte buona quando si utilizza il cmake --buildcomando è che funziona per tutti i generatori (es. Makefile e Visual Studio) senza bisogno di comandi diversi.

Successivamente utilizzo i file installati per creare pacchetti o includerli in altri progetti ...


Grazie per la spiegazione dettagliata! IMO questo è l'unico modo, altrimenti l'intero punto di cmake (indipendenza dalla piattaforma) viene scartato ...
helmesjo,

1
hai dimenticato di includere il percorso alle fonti (../) nella riga 3? A proposito, questa dovrebbe essere la risposta accettata.
Slava,

1
LIne 3 dovrebbe esserecmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
codeenamezero

1
Come nota aggiuntiva, pragmaticamente, le persone usano make -j $(nproc), per specificare il numero di thread di build, fare cmake --build . --target=install --config=Release -- -j 8per il generatore Makefile o cmake --build . --target=install --config=Release -- /m:8per il generatore di Visual Studio con 8 thread. In realtà, puoi passare qualsiasi parametro della riga di comando dopo--
Cloud

1
@MrRedstoner -jnon è un flag per cmake, tutti i flag che seguono --passano al sistema di build sottostante ...
Cloud

4

Per quanto riguarda la risposta di Bruce Adams:

La tua risposta crea pericolosa confusione. DESTDIR è destinato alle installazioni dall'albero della radice. Permette di vedere cosa verrebbe installato nell'albero della radice se non si specifica DESTDIR. PREFIX è la directory di base su cui si basa l'installazione reale.

Ad esempio, PREFIX = / usr / local indica che la destinazione finale di un pacchetto è / usr / local. Usando DESTDIR = $ HOME installerai i file come se $ HOME fosse il root (/). Se, diciamo DESTDIR, fosse / tmp / destdir, si potrebbe vedere che cosa influirebbe su "make install". In questo spirito, DESTDIR non dovrebbe mai influenzare gli oggetti costruiti.

Un segmento di makefile per spiegarlo:

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

I programmi devono presumere che PREFIX sia la directory di base della directory finale (cioè di produzione). La possibilità di collegare simbolicamente un programma installato in DESTDIR = / qualcosa significa solo che il programma non accede ai file basati su PREFIX in quanto semplicemente non funzionerebbe. cat (1) è un programma che (nella sua forma più semplice) può essere eseguito da qualsiasi luogo. Ecco un esempio che non lo farà:

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

Se si provasse a eseguire prog da altrove rispetto a $ PREFIX / bin / prog, prog.db non verrebbe mai trovato in quanto non si trova nella posizione prevista.

Infine, / etc / alternative non funziona davvero in questo modo. Esistono collegamenti simbolici ai programmi installati nella struttura ad albero delle radici (ad es. Vi -> / usr / bin / nvi, vi -> / usr / bin / vim, ecc.).


1
Questa risposta potrebbe essere meglio posizionata come risposta a stackoverflow.com/questions/11307465/destdir-and-prefix-of-make
Bruce Adams

2

È considerata una cattiva pratica invocare il generatore effettivo (ad es. Via make) se si utilizza CMake . Si consiglia vivamente di farlo in questo modo:

  1. Configura fase:

    cmake -Hfoo -B_builds/foo/debug -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEBUG_POSTFIX=d -DCMAKE_INSTALL_PREFIX=/usr
    
  2. Fasi di costruzione e installazione

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

Seguendo questo approccio, il generatore può essere facilmente commutato (ad esempio -GNinjaper Ninja ) senza dover ricordare alcun comando specifico del generatore.


1
La risposta avrebbe potuto essere migliore se fosse stata fornita una spiegazione a tutti gli argomenti utilizzati e al perché vengano utilizzati. In particolare, qual è il punto --configdell'argomento?
Dmitry Kabanov il

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.