Co to jest odpowiednik CMake dla „configure --prefix = DIR && make all install”?


386

Robię cmake . && make all install. To działa, ale instaluje się w /usr/local.

Muszę zainstalować z innym prefiksem (na przykład do /usr).

Do czego należy użyć wiersza polecenia cmakei zamiast ?make/usr/usr/local


1
To świetne pytanie na temat zmiany katalogu instalacyjnego w locie, ale dlaczego taka pozornie powszechna potrzeba? Z mojej perspektywy odpowiedź powinna brzmieć: NIE używaj opcji wiersza poleceń, zamiast tego edytuj bazę CMakeLists.txt, abyś mógł ją ustawić i zapomnieć. Nie twierdzę, że nie ma częstego przypadku zmiany katalogu instalacyjnego w locie - najwyraźniej liczba osądów jest oceniana - jestem dość nowy w CMake i jestem ciekawy, kiedy pojawia się ten problem.
CivFan

8
@CivFan jest przeznaczony dla użytkowników, którzy chcą zbudować i zainstalować projekt w określonej lokalizacji, ale nie są to te same osoby, co twórcy / opiekunowie projektu.
David Röthlisberger

4
@CivFan Tak więc, jako opiekun, nierzadko testuję moją make installścieżkę tymczasową, aby upewnić się, że wszystko, co musi zostać zainstalowane, zostało zainstalowane we właściwej lokalizacji bez zepsucia mojej maszyny programistycznej. Tylko jeden przykład. Innym przypadkiem jest kompilacja krzyżowa dla innej architektury.
Daniel

5
@CivFan: Potrzebuję tego, ponieważ chcę zbudować pakiet RPM. Jeśli musiałbym zmienić CMakeLists.txt, to muszę załatać oryginalne źródło. Samo posiadanie opcji wiersza poleceń pozwala mi uzyskać ścieżki bezpośrednio w specpliku Fedory .
Martin Ueding

1
@CivFan (i inni czytający to) FYI, ogólnie uważa się za zły pomysł, aby edytować CMakeLists.txtplik, jeśli tylko budujesz i instalujesz oprogramowanie - nadpisywanie / ustawianie zmiennych z wiersza poleceń lub początkowego pliku pamięci podręcznej itp. Jest preferowanym „konsumentem” sposób ustawiania opcji.
Ryan Pavlik

Odpowiedzi:


444

Możesz przekazać dowolną zmienną CMake w wierszu poleceń lub edytować zmienne buforowane przy użyciu ccmake / cmake-gui. W wierszu poleceń

cmake -DCMAKE_INSTALL_PREFIX: ŚCIEŻKA = / usr. && zainstaluj wszystkie

Skonfiguruje projekt, zbuduje wszystkie cele i zainstaluje na prefiksie / usr. Typ (PATH) nie jest absolutnie konieczny, ale spowodowałby, że cmake-gui oparte na Qt wyświetli okno dialogowe wyboru katalogu.

Niektóre drobne uzupełnienia w komentarzach wyjaśniają, że zapewnienie prostej równoważności nie jest wystarczające dla niektórych. Najlepszą praktyką byłoby użycie zewnętrznego katalogu kompilacji, tzn. Nie źródła bezpośrednio. Aby również użyć bardziej ogólnej składni CMake, wyodrębniającej generator.

mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX: PATH = / usr .. && cmake --build. - instalacja docelowa - wydanie Concon

Widać, że robi się to nieco dłużej i nie jest już bezpośrednio równoważne, ale jest bliższe najlepszym praktykom w dość zwięzłej formie ... --config jest używany tylko przez generatory wielu konfiguracji (tj. MSVC), zignorowane przez innych.


21
Zastanawiasz się, czym jest: ŚCIEŻKA? Jest to przydatne dla cmake-gui, pomaga wybrać widżet dla tej zmiennej. Patrz dokument w linux.die.net/man/1/cmake-gui (set set)
albfan

2
Zapewniają wskazówki do GUI CMake, jak powiedziano, wszystko w CMake jest w rzeczywistości łańcuchem, ale ustawienie PATH, FILEPATH, STRING, BOOL itp. Pomaga GUI w przedstawieniu bardziej odpowiedniego widżetu.
Marcus D. Hanwell

13
Możesz także użyć: „cmake --build --target install”. zamiast zrobić.
RobertJMaynard,

2
Do czego służy kropka po / usr? /usr .
bodacydo

5
@bodacydo lokalizacja folderu z CMakeLists.txt, z którego generujemy.
Kamiccolo,


29

Zauważ, że zarówno w CMake, jak i Autotools nie zawsze musisz ustawiać ścieżkę instalacji w czasie konfiguracji. Możesz użyć DESTDIR w czasie instalacji (patrz również tutaj ) zamiast w:

make DESTDIR=<installhere> install

Zobacz także to pytanie które wyjaśnia subtelną różnicę między DESTDIR a PREFIX.

Jest to przeznaczone dla instalacji etapowych i pozwala na przechowywanie programów w innym miejscu niż te, w których są uruchamiane, np. /etc/alternativesPoprzez dowiązania symboliczne.

Jeśli jednak twój pakiet jest relokowalny i nie wymaga żadnych ścieżek zakodowanych na stałe (prefiksów) ustawionych na etapie konfiguracji, możesz go pominąć. Więc zamiast:

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

uciekłbyś:

cmake . && make DESTDIR=/usr all install

Zauważ, że jak wskazuje użytkownik 7498341, nie jest to odpowiednie w przypadkach, w których naprawdę powinieneś używać PREFIKSU.


9
Lubię pokazywać użycie DESTDIR. Ale tak naprawdę to jest źle. Powinieneś odwołać się do cmake docs cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html ... make DESTDIR=/home/john installktóry zainstaluje dane oprogramowanie przy użyciu prefiksu instalacyjnego, np. „/ Usr / local” poprzedzony wartością DESTDIR co w końcu daje „/ home / john / usr / local”.
Joakim

1
Nie uważam, że to sprzeczne. Jeśli twoja paczka jest relokowalna, nie potrzebujesz CMAKE_INSTALL_PREFIX, a raczej możesz wybrać jedną z metod. Jeśli tak nie jest, ponieważ CMAKE_INSTALL_PREFIX zostanie upieczony gdzieś w czasie kompilacji.
Bruce Adams,

jeśli wiesz, że twój generator to Makefile ... Wolę cmake --build build --target install -- DESTDIR=/usrpamiętać: to powinno również działać z generatorem Ninja (wydaje się, że zawiera reguły $ENV{DESTDIR})
Mizux

@Joakim tak bardzo, jak chciałbym użyć CMAKE_INSTALL_PREFIX, tym samym osadzając ścieżkę instalacji w skompilowanych plikach. Tak się składa, że ​​po prostu budowałem pakiet .rpm, więc to by się nie udało. DESTDIR działał jak urok przy wprowadzaniu rzeczy do wersji rootroot.
Pan Redstoner

18

Sposób, w jaki buduję projekty CMake na różnych platformach, jest następujący:

/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
  • Pierwsze dwa wiersze tworzą katalog kompilacji spoza źródła
  • Trzeci wiersz generuje system kompilacji określający, gdzie umieścić wynik instalacji (w którym zawsze umieszczam ./project-root/build/stage - ścieżka jest zawsze uważana za względną do bieżącego katalogu, jeśli nie jest bezwzględna)
  • Czwarta linia buduje projekt skonfigurowany w .systemie kompilacji skonfigurowanym wcześniej w linii. Wykona installcel, który również zbuduje wszystkie niezbędne cele zależne, jeśli trzeba je zbudować, a następnie skopiuje pliki do CMAKE_INSTALL_PREFIX(co w tym przypadku jest ./project-root/build/stage. W przypadku kompilacji z wieloma konfiguracjami, takich jak Visual Studio, można również określić konfigurację za pomocą opcjonalna --config <config>flaga.
  • Zaletą korzystania z cmake --buildpolecenia jest to, że działa on dla wszystkich generatorów (tj. Makefiles i Visual Studio) bez potrzeby używania różnych poleceń.

Następnie używam zainstalowanych plików do tworzenia pakietów lub włączania ich do innych projektów ...


Dzięki za wyjaśnienie krok po kroku! IMO to jedyny sposób, w przeciwnym razie cały punkt cmake (niezależność platformy) zostanie odrzucony ...
helmesjo

1
zapomniałeś podać ścieżkę do źródeł (../) w linii 3? BTW to powinna być zaakceptowana odpowiedź.
Slava

1
Linia 3 powinna byćcmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
kryptonim

1
Jako dodatkową uwagę pragmatycznie ludzie używają make -j $(nproc), aby określić liczbę wątków kompilacji, cmake --build . --target=install --config=Release -- -j 8dla generatora Makefile lub cmake --build . --target=install --config=Release -- /m:8dla generatora Visual Studio z 8 wątkami. Właściwie możesz przekazać dowolne parametry wiersza poleceń później--
Cloud

1
@ MrRedstoner -jnie jest flagą dla cmake, wszystkie kolejne flagi --przechodzą do bazowego systemu kompilacji ...
Chmura

4

Jeśli chodzi o odpowiedź Bruce'a Adamsa:

Twoja odpowiedź powoduje niebezpieczne zamieszanie. DESTDIR jest przeznaczony do instalacji z drzewa głównego. Pozwala zobaczyć, co byłoby zainstalowane w drzewie głównym, gdyby nie określono DESTDIR. PREFIKS to katalog podstawowy, na którym oparta jest prawdziwa instalacja.

Na przykład PREFIKS = / usr / local wskazuje, że ostatecznym miejscem docelowym pakietu jest / usr / local. Użycie DESTDIR = $ HOME spowoduje zainstalowanie plików tak, jakby $ HOME był rootem (/). Gdyby, powiedzmy DESTDIR, był / tmp / destdir, można by zobaczyć, co wpłynie na „make install”. W tym duchu DESTDIR nigdy nie powinien wpływać na budowane obiekty.

Segment makefile, aby to wyjaśnić:

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

Programy muszą zakładać, że PREFIX jest katalogiem podstawowym katalogu końcowego (tj. Produkcyjnego). Możliwość symlinkowania programu zainstalowanego w DESTDIR = / coś oznacza tylko, że program nie ma dostępu do plików opartych na PREFIX, ponieważ po prostu nie działałby. cat (1) to program, który (w najprostszej formie) może działać z dowolnego miejsca. Oto przykład, który nie:

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

Jeśli spróbujesz uruchomić prog z innego miejsca niż $ PREFIX / bin / prog, prog.db nigdy nie zostanie znaleziony, ponieważ nie znajduje się w oczekiwanej lokalizacji.

Wreszcie, / etc / alternatives naprawdę nie działa w ten sposób. Istnieją dowiązania symboliczne do programów zainstalowanych w drzewie głównym (np. Vi -> / usr / bin / nvi, vi -> / usr / bin / vim itp.).


1
Ta odpowiedź może być lepiej umieszczona jako odpowiedź na stackoverflow.com/questions/11307465/destdir-and-prefix-of-make
Bruce Adams

2

Uważa się za złą praktykę wywoływanie faktycznego generatora (np. Via make), jeśli używa się CMake . Zdecydowanie zaleca się zrobienie tego w następujący sposób:

  1. Skonfiguruj fazę:

    cmake -Hfoo -B_builds/foo/debug -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEBUG_POSTFIX=d -DCMAKE_INSTALL_PREFIX=/usr
    
  2. Kompiluj i instaluj fazy

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

Postępując zgodnie z tym podejściem, generator można łatwo przełączać (np. -GNinjaDla Ninja ) bez konieczności zapamiętywania poleceń specyficznych dla generatora.


1
Odpowiedź mogłaby być lepsza, gdyby podano wyjaśnienie wszystkich użytych argumentów i ich uzasadnienia. W szczególności, jaki jest sens --configargumentu?
Dmitrij Kabanow,

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.