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.
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.
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,
48
Część „: PATH” w zaakceptowanej odpowiedzi można pominąć. Ta składnia może być bardziej niezapomniana:
cmake -DCMAKE_INSTALL_PREFIX=/usr . && make all install
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.
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:
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:
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.).
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:
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.
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,
2
Począwszy od CMake 3.15, poprawnym sposobem osiągnięcia tego byłoby użycie:
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.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.CMakeLists.txt
, to muszę załatać oryginalne źródło. Samo posiadanie opcji wiersza poleceń pozwala mi uzyskać ścieżki bezpośrednio wspec
pliku Fedory .CMakeLists.txt
plik, 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.Odpowiedzi:
Możesz przekazać dowolną zmienną CMake w wierszu poleceń lub edytować zmienne buforowane przy użyciu ccmake / cmake-gui. W wierszu poleceń
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.
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.
źródło
/usr .
Część „: PATH” w zaakceptowanej odpowiedzi można pominąć. Ta składnia może być bardziej niezapomniana:
... jak wykorzystano w odpowiedziach tutaj .
źródło
:PATH
to nie pomyłka .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:
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/alternatives
Poprzez 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:
uciekłbyś:
Zauważ, że jak wskazuje użytkownik 7498341, nie jest to odpowiednie w przypadkach, w których naprawdę powinieneś używać PREFIKSU.
źródło
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 install
któ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”.cmake --build build --target install -- DESTDIR=/usr
pamiętać: to powinno również działać z generatorem Ninja (wydaje się, że zawiera reguły$ENV{DESTDIR}
)Sposób, w jaki buduję projekty CMake na różnych platformach, jest następujący:
./project-root/build/stage
- ścieżka jest zawsze uważana za względną do bieżącego katalogu, jeśli nie jest bezwzględna).
systemie kompilacji skonfigurowanym wcześniej w linii. Wykonainstall
cel, który również zbuduje wszystkie niezbędne cele zależne, jeśli trzeba je zbudować, a następnie skopiuje pliki doCMAKE_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.cmake --build
polecenia 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 ...
źródło
cmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
make -j $(nproc)
, aby określić liczbę wątków kompilacji,cmake --build . --target=install --config=Release -- -j 8
dla generatora Makefile lubcmake --build . --target=install --config=Release -- /m:8
dla generatora Visual Studio z 8 wątkami. Właściwie możesz przekazać dowolne parametry wiersza poleceń później--
-j
nie jest flagą dla cmake, wszystkie kolejne flagi--
przechodzą do bazowego systemu kompilacji ...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ć:
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:
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.).
źródło
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:Skonfiguruj fazę:
Kompiluj i instaluj fazy
Postępując zgodnie z tym podejściem, generator można łatwo przełączać (np.
-GNinja
Dla Ninja ) bez konieczności zapamiętywania poleceń specyficznych dla generatora.źródło
--config
argumentu?Począwszy od CMake 3.15, poprawnym sposobem osiągnięcia tego byłoby użycie:
Oficjalna dokumentacja
źródło