Это отличный вопрос для изменения директории установки на лету, но почему это такая очевидная необходимость? С моей точки зрения, ответ не должен использовать параметр командной строки, вместо этого отредактируйте базу, CMakeLists.txtчтобы вы могли установить ее и забыть. Я не говорю, что не существует единого варианта использования для изменения каталога установки на лету - очевидно, что судя по количеству голосов - я просто новичок в CMake и мне любопытно, когда возникнет эта проблема.
CivFan
8
@CivFan предназначен для пользователей, которые хотят собрать и установить проект в определенном месте, но не являются теми же людьми, что и разработчики / сопровождающие проекта.
Дэвид Ротлисбергер
4
@CivFan Так что, как сопровождающий, я нередко проверяю мой make installвременный путь, чтобы убедиться, что все, что нужно установить, было установлено в нужное место, не портя мою машину для разработки. Всего один пример. Другой случай - кросс-компиляция для другой архитектуры.
Даниэль
5
@CivFan: мне это нужно, потому что я хочу создать пакет RPM. Если мне нужно будет изменить CMakeLists.txt, то мне нужно исправить исходный код. Просто наличие параметра командной строки позволяет мне получить пути прямо в specфайле Fedora .
Мартин Уединг
1
@CivFan (и другие читающие это) К вашему сведению, обычно считается плохой идеей редактировать CMakeLists.txtфайл, если вы просто собираете и устанавливаете программное обеспечение - предпочтительным «потребителем» является переопределение / установка переменных из командной строки или исходного файла кэша и т. Д. способ настройки параметров.
Райан Павлик
Ответы:
444
Вы можете передать любую переменную CMake в командной строке или отредактировать кэшированные переменные, используя ccmake / cmake-gui. В командной строке
cmake -DCMAKE_INSTALL_PREFIX: PATH = / usr. && сделать все установить
Настроит проект, создаст все цели и установит префикс / usr. Тип (PATH) не является строго обязательным, но может привести к тому, что cmake-gui на основе Qt представит диалоговое окно выбора каталога.
Некоторые незначительные дополнения в виде комментариев проясняют, что для некоторых недостаточно предоставить простую эквивалентность. Лучше всего использовать внешний каталог сборки, т.е. не исходный код напрямую. Также использовать более общий синтаксис CMake, абстрагирующий генератор.
Вы можете видеть, что он становится немного длиннее и больше не является прямым эквивалентом, но ближе к передовому опыту в довольно сжатой форме ... --config используется только генераторами с несколькими конфигурациями (т.е. MSVC), игнорируется другими.
Хотите знать, что: PATH? Это полезно для cmake-gui, помогая выбрать виджет для этой переменной. Смотрите документ в linux.die.net/man/1/cmake-gui (раздел set)
albfan
2
Они предоставляют подсказки для графического интерфейса CMake, как указано, все в CMake фактически является строкой, но установка PATH, FILEPATH, STRING, BOOL и т. Д. Помогает графическому интерфейсу представить более подходящий виджет.
Маркус Д. Ханвелл
13
Вы также можете использовать: "cmake --build --target install." вместо того, чтобы делать.
РобертДжейнард
2
Какова точка для после / usr? /usr .
бодасидо
5
@bodacydo расположение папки с CMakeLists.txt, из которого мы генерируем.
Kamiccolo
48
Часть ": PATH" в принятом ответе может быть опущена. Этот синтаксис может быть более запоминающимся:
cmake -DCMAKE_INSTALL_PREFIX=/usr . && make all install
Обратите внимание, что как в CMake, так и в Autotools вам не всегда нужно устанавливать путь установки во время настройки. Вы можете использовать DESTDIR во время установки (см. Также здесь ) вместо этого, как в:
make DESTDIR=<installhere> install
Смотрите также этот вопрос, который объясняет тонкую разницу между DESTDIR и PREFIX.
Это предназначено для поэтапной установки и позволяет хранить программы в другом месте, где они запускаются, например, /etc/alternativesпо символическим ссылкам.
Однако, если ваш пакет перемещаемый и ему не нужны какие-либо жестко заданные (префиксные) пути, заданные на этапе настройки, вы можете пропустить его. Так что вместо:
cmake -DCMAKE_INSTALL_PREFIX=/usr . && make all install
вы бы запустить:
cmake . && make DESTDIR=/usr all install
Обратите внимание, что, как указывает пользователь 7498341, это не подходит для случаев, когда вам действительно следует использовать PREFIX.
Мне нравится показывать использование DESTDIR. Но на самом деле это неправильно. Вы должны обратиться к cmake docs cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html ..., make DESTDIR=/home/john installкоторый установит соответствующее программное обеспечение с использованием префикса установки, например, «/ usr / local» с добавлением значения DESTDIR. что в итоге дает «/ home / john / usr / local».
Иоаким
1
Я не думаю, что это противоречиво. Если ваш пакет перемещаемый, вам не нужен CMAKE_INSTALL_PREFIX, или, скорее, вы можете выбрать любой метод. Если это не так, потому что CMAKE_INSTALL_PREFIX будет запечен где-то во время сборки.
Брюс Адамс
если вы знаете, что ваш генератор - Makefile ... Я предпочитаю cmake --build build --target install -- DESTDIR=/usrзаметить: это также должно работать с генератором Ninja (правила, кажется, содержат $ENV{DESTDIR})
Mizux
@Joakim столько, сколько я хотел бы использовать CMAKE_INSTALL_PREFIX, делая это встроенным путем установки в скомпилированные файлы. Так получилось, что я просто собирал пакет .rpm, так что это не сработало. DESTDIR работал как заклинание для получения вещей в buildroot.
Мистер Редстонер,
18
Я строю кроссплатформенные проекты CMake следующим образом:
Первые две строки создают каталог сборки вне источника
Третья строка генерирует систему сборки, указывающую, куда поместить результат установки (в который я всегда помещаю ./project-root/build/stage- путь всегда считается относительно текущего каталога, если он не абсолютен)
Четвертая строка .собирает проект, настроенный в системе сборки, настроенной в строке ранее. Он выполнит installцель, которая также создает все необходимые зависимые цели, если они должны быть собраны, и затем скопирует файлы в CMAKE_INSTALL_PREFIX(что в данном случае является ./project-root/build/stage. Для сборок с несколькими конфигурациями, как в Visual Studio, вы также можете указать конфигурацию с помощью необязательный --config <config>флаг.
Хорошая сторона при использовании cmake --buildкоманды заключается в том, что она работает для всех генераторов (т.е. make-файлов и Visual Studio) без необходимости использования других команд.
После этого я использую установленные файлы для создания пакетов или включения их в другие проекты ...
Спасибо за пошаговое объяснение! ИМО это единственный способ, иначе весь смысл cmake (независимости от платформы) отбрасывается ...
helmesjo
1
Вы забыли включить путь к источникам (../) в строке 3? Кстати, это должен быть принятый ответ.
Слава
1
Линия 3 должна бытьcmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
codenamezero
1
В качестве дополнительного примечания, прагматично, люди используют make -j $(nproc), чтобы указать количество потоков сборки, сделать cmake --build . --target=install --config=Release -- -j 8для генератора Makefile или cmake --build . --target=install --config=Release -- /m:8для генератора Visual Studio с 8 потоками. На самом деле, вы можете передавать любые параметры командной строки после--
Cloud
1
@MrRedstoner -j- это не флаг для cmake, все флаги приходят после того, --как он передается в базовую систему сборки ...
Облако
4
Относительно ответа Брюса Адамса:
Ваш ответ создает опасную путаницу. DESTDIR предназначен для установки вне корневого дерева. Это позволяет увидеть, что будет установлено в корневом дереве, если не указать DESTDIR. PREFIX - это базовый каталог, на котором основана настоящая установка.
Например, PREFIX = / usr / local указывает, что конечным пунктом назначения пакета является / usr / local. Использование DESTDIR = $ HOME установит файлы, как если бы $ HOME был корневым каталогом (/). Если, скажем, DESTDIR, был / tmp / destdir, можно было бы увидеть, как повлияет «make install». В этом духе DESTDIR никогда не должен влиять на построенные объекты.
Сегмент makefile, чтобы объяснить это:
install:
cp program $DESTDIR$PREFIX/bin/program
Программы должны предполагать, что PREFIX является базовым каталогом конечного (т.е. рабочего) каталога. Возможность символической ссылки на программу, установленную в DESTDIR = / что-то, только означает, что программа не имеет доступа к файлам, основанным на PREFIX, поскольку она просто не будет работать. cat (1) - это программа, которая (в простейшем виде) может запускаться откуда угодно. Вот пример, который не будет:
Если вы попытаетесь запустить prog из другого места, кроме $ PREFIX / bin / prog, prog.db никогда не будет найден, поскольку он не находится в ожидаемом месте.
Наконец, / etc / alternatives действительно не работает таким образом. Существуют символические ссылки на программы, установленные в корневом дереве (например, vi -> / usr / bin / nvi, vi -> / usr / bin / vim и т. Д.).
Следуя этому подходу, генератор может быть легко переключен (например, -GNinjaдля ниндзя ) без необходимости запоминать какие-либо специфичные для генератора команды.
Ответ мог бы быть лучше, если бы было дано объяснение всем использованным аргументам и почему они используются. В частности, в чем смысл --configаргумента?
Дмитрий Кабанов
2
Начиная с CMake 3.15, правильным способом достижения этого будет использование:
CMakeLists.txt
чтобы вы могли установить ее и забыть. Я не говорю, что не существует единого варианта использования для изменения каталога установки на лету - очевидно, что судя по количеству голосов - я просто новичок в CMake и мне любопытно, когда возникнет эта проблема.make install
временный путь, чтобы убедиться, что все, что нужно установить, было установлено в нужное место, не портя мою машину для разработки. Всего один пример. Другой случай - кросс-компиляция для другой архитектуры.CMakeLists.txt
, то мне нужно исправить исходный код. Просто наличие параметра командной строки позволяет мне получить пути прямо вspec
файле Fedora .CMakeLists.txt
файл, если вы просто собираете и устанавливаете программное обеспечение - предпочтительным «потребителем» является переопределение / установка переменных из командной строки или исходного файла кэша и т. Д. способ настройки параметров.Ответы:
Вы можете передать любую переменную CMake в командной строке или отредактировать кэшированные переменные, используя ccmake / cmake-gui. В командной строке
Настроит проект, создаст все цели и установит префикс / usr. Тип (PATH) не является строго обязательным, но может привести к тому, что cmake-gui на основе Qt представит диалоговое окно выбора каталога.
Некоторые незначительные дополнения в виде комментариев проясняют, что для некоторых недостаточно предоставить простую эквивалентность. Лучше всего использовать внешний каталог сборки, т.е. не исходный код напрямую. Также использовать более общий синтаксис CMake, абстрагирующий генератор.
Вы можете видеть, что он становится немного длиннее и больше не является прямым эквивалентом, но ближе к передовому опыту в довольно сжатой форме ... --config используется только генераторами с несколькими конфигурациями (т.е. MSVC), игнорируется другими.
источник
/usr .
Часть ": PATH" в принятом ответе может быть опущена. Этот синтаксис может быть более запоминающимся:
... как используется в ответах здесь .
источник
:PATH
это не ошибка .Обратите внимание, что как в CMake, так и в Autotools вам не всегда нужно устанавливать путь установки во время настройки. Вы можете использовать DESTDIR во время установки (см. Также здесь ) вместо этого, как в:
Смотрите также этот вопрос, который объясняет тонкую разницу между DESTDIR и PREFIX.
Это предназначено для поэтапной установки и позволяет хранить программы в другом месте, где они запускаются, например,
/etc/alternatives
по символическим ссылкам.Однако, если ваш пакет перемещаемый и ему не нужны какие-либо жестко заданные (префиксные) пути, заданные на этапе настройки, вы можете пропустить его. Так что вместо:
вы бы запустить:
Обратите внимание, что, как указывает пользователь 7498341, это не подходит для случаев, когда вам действительно следует использовать PREFIX.
источник
DESTDIR
. Но на самом деле это неправильно. Вы должны обратиться к cmake docs cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html ...,make DESTDIR=/home/john install
который установит соответствующее программное обеспечение с использованием префикса установки, например, «/ usr / local» с добавлением значения DESTDIR. что в итоге дает «/ home / john / usr / local».cmake --build build --target install -- DESTDIR=/usr
заметить: это также должно работать с генератором Ninja (правила, кажется, содержат$ENV{DESTDIR}
)Я строю кроссплатформенные проекты CMake следующим образом:
./project-root/build/stage
- путь всегда считается относительно текущего каталога, если он не абсолютен).
собирает проект, настроенный в системе сборки, настроенной в строке ранее. Он выполнитinstall
цель, которая также создает все необходимые зависимые цели, если они должны быть собраны, и затем скопирует файлы вCMAKE_INSTALL_PREFIX
(что в данном случае является./project-root/build/stage
. Для сборок с несколькими конфигурациями, как в Visual Studio, вы также можете указать конфигурацию с помощью необязательный--config <config>
флаг.cmake --build
команды заключается в том, что она работает для всех генераторов (т.е. make-файлов и Visual Studio) без необходимости использования других команд.После этого я использую установленные файлы для создания пакетов или включения их в другие проекты ...
источник
cmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
make -j $(nproc)
, чтобы указать количество потоков сборки, сделатьcmake --build . --target=install --config=Release -- -j 8
для генератора Makefile илиcmake --build . --target=install --config=Release -- /m:8
для генератора Visual Studio с 8 потоками. На самом деле, вы можете передавать любые параметры командной строки после--
-j
- это не флаг для cmake, все флаги приходят после того,--
как он передается в базовую систему сборки ...Относительно ответа Брюса Адамса:
Ваш ответ создает опасную путаницу. DESTDIR предназначен для установки вне корневого дерева. Это позволяет увидеть, что будет установлено в корневом дереве, если не указать DESTDIR. PREFIX - это базовый каталог, на котором основана настоящая установка.
Например, PREFIX = / usr / local указывает, что конечным пунктом назначения пакета является / usr / local. Использование DESTDIR = $ HOME установит файлы, как если бы $ HOME был корневым каталогом (/). Если, скажем, DESTDIR, был / tmp / destdir, можно было бы увидеть, как повлияет «make install». В этом духе DESTDIR никогда не должен влиять на построенные объекты.
Сегмент makefile, чтобы объяснить это:
Программы должны предполагать, что PREFIX является базовым каталогом конечного (т.е. рабочего) каталога. Возможность символической ссылки на программу, установленную в DESTDIR = / что-то, только означает, что программа не имеет доступа к файлам, основанным на PREFIX, поскольку она просто не будет работать. cat (1) - это программа, которая (в простейшем виде) может запускаться откуда угодно. Вот пример, который не будет:
Если вы попытаетесь запустить prog из другого места, кроме $ PREFIX / bin / prog, prog.db никогда не будет найден, поскольку он не находится в ожидаемом месте.
Наконец, / etc / alternatives действительно не работает таким образом. Существуют символические ссылки на программы, установленные в корневом дереве (например, vi -> / usr / bin / nvi, vi -> / usr / bin / vim и т. Д.).
источник
При
make
использовании CMake считается плохой практикой вызывать реальный генератор (например, через ) . Настоятельно рекомендуется сделать это так:Настроить фазу:
Этапы сборки и установки
Следуя этому подходу, генератор может быть легко переключен (например,
-GNinja
для ниндзя ) без необходимости запоминать какие-либо специфичные для генератора команды.источник
--config
аргумента?Начиная с CMake 3.15, правильным способом достижения этого будет использование:
Официальная документация
источник