Essa é uma ótima pergunta para alterar o diretório de instalação rapidamente, mas por que essa é uma necessidade aparentemente comum? Na minha perspectiva, a resposta deve ser NÃO use uma opção de linha de comando; em vez disso, edite a base CMakeLists.txtpara que você possa configurá-la e esquecê-la. Não estou dizendo que não há um caso de uso comum para alterar o diretório de instalação em tempo real - claramente, a julgar pelo número de votos - sou apenas bastante novo no CMake e curioso quando esse problema surgir.
CivFan
8
O @CivFan serve para usuários que desejam criar e instalar o projeto em um local específico, mas não são as mesmas pessoas que os desenvolvedores / mantenedores do projeto.
David Röthlisberger
4
@CivFan Então, como mantenedor, não é incomum que eu teste meu make installcaminho temporário para garantir que tudo o que precisa ser instalado seja instalado no local certo sem atrapalhar minha máquina de desenvolvimento. Apenas um exemplo. Outro caso é a compilação cruzada para outra arquitetura.
187 Daniel Daniel
5
@CivFan: Eu preciso disso porque quero criar um pacote RPM. Se eu precisar alterar o CMakeLists.txt, preciso corrigir a fonte original. Ter apenas uma opção de linha de comando me permite encontrar os caminhos corretos no specarquivo do Fedora .
Martin Ueding
11
@CivFan (e outros que estão lendo isso) Para sua informação, geralmente é uma má idéia editar o CMakeLists.txtarquivo se você estiver apenas criando e instalando software - substituir / definir variáveis na linha de comando ou no arquivo de cache inicial etc. é o "consumidor" preferido maneira de definir opções.
21419 Ryan Pavlik
Respostas:
444
Você pode passar qualquer variável CMake na linha de comando ou editar variáveis em cache usando ccmake / cmake-gui. Na linha de comando,
cmake -DCMAKE_INSTALL_PREFIX: PATH = / usr. && make all install
Configure o projeto, construa todos os destinos e instale no prefixo / usr. O tipo (PATH) não é estritamente necessário, mas faria com que o cmake-gui baseado em Qt apresentasse a caixa de diálogo do seletor de diretório.
Algumas pequenas inclusões como comentários deixam claro que fornecer uma equivalência simples não é suficiente para alguns. A melhor prática seria usar um diretório de construção externo, ou seja, não a fonte diretamente. Também para usar a sintaxe mais genérica do CMake, abstraindo o gerador.
mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX: PATH = / usr .. && cmake --build. --target install --config Versão
Você pode ver que fica um pouco mais longo e não é mais equivalente diretamente, mas está mais próximo das melhores práticas de forma bastante concisa ... O --config é usado apenas por geradores de várias configurações (por exemplo, MSVC), ignorados por outros.
Querendo saber o que: PATH é? É útil para o cmake-gui, ajudando a escolher o widget para essa variável. Veja doc em linux.die.net/man/1/cmake-gui (seção de conjunto)
albfan 26/10/12
2
Eles fornecem dicas para a GUI do CMake, conforme declarado, tudo no CMake é efetivamente uma string, mas a configuração de PATH, FILEPATH, STRING, BOOL etc ajuda a GUI a apresentar um widget mais apropriado.
Marcus D. Hanwell
13
Você também pode usar: "cmake --build --target install." em vez de fazer.
RobertJMaynard
2
Qual é o ponto para depois de / usr? /usr .
bodacydo
5
@bodacydo localização da pasta com CMakeLists.txt da qual estamos gerando.
22814 Kamiccolo
48
A parte ": PATH" na resposta aceita pode ser omitida. Essa sintaxe pode ser mais memorável:
cmake -DCMAKE_INSTALL_PREFIX=/usr . && make all install
Observe que no CMake e no Autotools nem sempre é necessário definir o caminho da instalação no momento da configuração. Você pode usar o DESTDIR no momento da instalação (veja também aqui ) como em:
make DESTDIR=<installhere> install
Veja também esta pergunta que explica a diferença sutil entre DESTDIR e PREFIX.
Isso é destinado a instalações em etapas e permite o armazenamento de programas em um local diferente do local em que são executados, por exemplo, por /etc/alternativesmeio de links simbólicos.
No entanto, se o seu pacote for realocável e não precisar de nenhum caminho codificado (prefixo) definido através do estágio de configuração, você poderá ignorá-lo. Então, em vez de:
cmake -DCMAKE_INSTALL_PREFIX=/usr . && make all install
você correria:
cmake . && make DESTDIR=/usr all install
Observe que, como aponta user7498341, isso não é apropriado para os casos em que você realmente deveria estar usando PREFIX.
Eu gosto de mostrar o uso de DESTDIR. Mas, na verdade, isso está errado. Você deve consultar o cmake docs cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html ... make DESTDIR=/home/john installque instalará o software em questão usando o prefixo de instalação, por exemplo, “/ usr / local” precedido com o valor DESTDIR que finalmente fornece "/ home / john / usr / local".
Joakim
11
Eu não acho isso contraditório. Se o seu pacote for realocável, você não precisará de CMAKE_INSTALL_PREFIX ou poderá escolher um dos métodos. Se não for o seu caso, porque o CMAKE_INSTALL_PREFIX será instalado em algum lugar no momento da compilação.
Bruce Adams
se você souber que o seu gerador é Makefile ... eu prefiro cmake --build build --target install -- DESTDIR=/usrobservação: isso também deve funcionar com o gerador Ninja (as regras parecem conter $ENV{DESTDIR})
Mizux
@ Joakim, tanto quanto eu gostaria de usar CMAKE_INSTALL_PREFIX, fazendo assim o caminho de instalação incorporado nos arquivos compilados. Por acaso, eu estava apenas criando um pacote .rpm, para que não funcionasse. DESTDIR funcionou como um encanto para colocar as coisas na raiz da construção.
Mr Redstoner
18
A maneira como construo projetos entre plataformas do CMake é a seguinte:
As duas primeiras linhas criam o diretório de construção fora da fonte
A terceira linha gera o sistema de construção especificando onde colocar o resultado da instalação (no qual eu sempre coloco ./project-root/build/stage- o caminho é sempre considerado em relação ao diretório atual, se não for absoluto)
A quarta linha cria o projeto configurado .com o sistema de construção configurado na linha anterior. Ele executará o installdestino, que também cria todos os destinos dependentes necessários, se eles precisarem ser construídos, e copia os arquivos no diretório CMAKE_INSTALL_PREFIX(que nesse caso é ./project-root/build/stage.) Para construções com várias configurações, como no Visual Studio, você também pode especificar a configuração com a --config <config>bandeira opcional .
A parte boa ao usar o cmake --buildcomando é que ele funciona para todos os geradores (por exemplo, makefiles e Visual Studio) sem a necessidade de comandos diferentes.
Depois, uso os arquivos instalados para criar pacotes ou incluí-los em outros projetos ...
Obrigado pela explicação passo a passo! IMO este é o único caminho, caso contrário, todo o ponto de cmake (independência de plataforma) é descartado ...
helmesjo
11
você esqueceu de incluir o caminho para as fontes (../) na linha 3? BTW, esta deve ser a resposta aceita.
Slava
11
Linha 3 deve sercmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
codenamezero
11
Como uma observação adicional, pragmaticamente, as pessoas usam make -j $(nproc), para especificar o número de threads de compilação, faça cmake --build . --target=install --config=Release -- -j 8para o gerador Makefile ou cmake --build . --target=install --config=Release -- /m:8para o gerador do Visual Studio com 8 threads. Na verdade, você pode passar qualquer parâmetro da linha de comando após o--
Cloud
11
@MrRedstoner -jnão é um sinalizador para cmake, todos os sinalizadores que vêm depois --passam para o sistema de compilação subjacente ...
Cloud
4
Em relação à resposta de Bruce Adams:
Sua resposta cria confusão perigosa. DESTDIR destina-se a instalações fora da árvore raiz. Ele permite ver o que seria instalado na árvore raiz se não especificasse DESTDIR. PREFIX é o diretório base no qual a instalação real se baseia.
Por exemplo, PREFIX = / usr / local indica que o destino final de um pacote é / usr / local. Usar DESTDIR = $ HOME instalará os arquivos como se $ HOME fosse a raiz (/). Se, digamos DESTDIR, fosse / tmp / destdir, seria possível ver o que 'make install' afetaria. Nesse espírito, DESTDIR nunca deve afetar os objetos construídos.
Um segmento de makefile para explicá-lo:
install:
cp program $DESTDIR$PREFIX/bin/program
Os programas devem assumir que PREFIX é o diretório base do diretório final (ou seja, produção). A possibilidade de vincular um programa instalado no DESTDIR = / algo significa apenas que o programa não acessa arquivos com base no PREFIX, pois simplesmente não funcionaria. O cat (1) é um programa que (em sua forma mais simples) pode ser executado de qualquer lugar. Aqui está um exemplo que não:
Se você tentou executar o prog de outro lugar que não o $ PREFIX / bin / prog, o prog.db nunca seria encontrado, pois não está no local esperado.
Finalmente, o / etc / alternative realmente não funciona dessa maneira. Existem links simbólicos para programas instalados na árvore raiz (por exemplo, vi -> / usr / bin / nvi, vi -> / usr / bin / vim, etc.).
Ao seguir esta abordagem, o gerador pode ser facilmente trocado (por exemplo, -GNinjapara Ninja ) sem ter que lembrar de nenhum comando específico do gerador.
A resposta poderia ter sido melhor se fossem fornecidas explicações para todos os argumentos usados e por que eles são usados. Em particular, qual é o objetivo do --configargumento?
Dmitry Kabanov
2
Começando com o CMake 3.15, a maneira correta de conseguir isso seria usando:
CMakeLists.txt
para que você possa configurá-la e esquecê-la. Não estou dizendo que não há um caso de uso comum para alterar o diretório de instalação em tempo real - claramente, a julgar pelo número de votos - sou apenas bastante novo no CMake e curioso quando esse problema surgir.make install
caminho temporário para garantir que tudo o que precisa ser instalado seja instalado no local certo sem atrapalhar minha máquina de desenvolvimento. Apenas um exemplo. Outro caso é a compilação cruzada para outra arquitetura.CMakeLists.txt
, preciso corrigir a fonte original. Ter apenas uma opção de linha de comando me permite encontrar os caminhos corretos nospec
arquivo do Fedora .CMakeLists.txt
arquivo se você estiver apenas criando e instalando software - substituir / definir variáveis na linha de comando ou no arquivo de cache inicial etc. é o "consumidor" preferido maneira de definir opções.Respostas:
Você pode passar qualquer variável CMake na linha de comando ou editar variáveis em cache usando ccmake / cmake-gui. Na linha de comando,
Configure o projeto, construa todos os destinos e instale no prefixo / usr. O tipo (PATH) não é estritamente necessário, mas faria com que o cmake-gui baseado em Qt apresentasse a caixa de diálogo do seletor de diretório.
Algumas pequenas inclusões como comentários deixam claro que fornecer uma equivalência simples não é suficiente para alguns. A melhor prática seria usar um diretório de construção externo, ou seja, não a fonte diretamente. Também para usar a sintaxe mais genérica do CMake, abstraindo o gerador.
Você pode ver que fica um pouco mais longo e não é mais equivalente diretamente, mas está mais próximo das melhores práticas de forma bastante concisa ... O --config é usado apenas por geradores de várias configurações (por exemplo, MSVC), ignorados por outros.
fonte
/usr .
A parte ": PATH" na resposta aceita pode ser omitida. Essa sintaxe pode ser mais memorável:
... conforme usado nas respostas aqui .
fonte
:PATH
não é um erro .Observe que no CMake e no Autotools nem sempre é necessário definir o caminho da instalação no momento da configuração. Você pode usar o DESTDIR no momento da instalação (veja também aqui ) como em:
Veja também esta pergunta que explica a diferença sutil entre DESTDIR e PREFIX.
Isso é destinado a instalações em etapas e permite o armazenamento de programas em um local diferente do local em que são executados, por exemplo, por
/etc/alternatives
meio de links simbólicos.No entanto, se o seu pacote for realocável e não precisar de nenhum caminho codificado (prefixo) definido através do estágio de configuração, você poderá ignorá-lo. Então, em vez de:
você correria:
Observe que, como aponta user7498341, isso não é apropriado para os casos em que você realmente deveria estar usando PREFIX.
fonte
DESTDIR
. Mas, na verdade, isso está errado. Você deve consultar o cmake docs cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html ...make DESTDIR=/home/john install
que instalará o software em questão usando o prefixo de instalação, por exemplo, “/ usr / local” precedido com o valor DESTDIR que finalmente fornece "/ home / john / usr / local".cmake --build build --target install -- DESTDIR=/usr
observação: isso também deve funcionar com o gerador Ninja (as regras parecem conter$ENV{DESTDIR}
)A maneira como construo projetos entre plataformas do CMake é a seguinte:
./project-root/build/stage
- o caminho é sempre considerado em relação ao diretório atual, se não for absoluto).
com o sistema de construção configurado na linha anterior. Ele executará oinstall
destino, que também cria todos os destinos dependentes necessários, se eles precisarem ser construídos, e copia os arquivos no diretórioCMAKE_INSTALL_PREFIX
(que nesse caso é./project-root/build/stage
.) Para construções com várias configurações, como no Visual Studio, você também pode especificar a configuração com a--config <config>
bandeira opcional .cmake --build
comando é que ele funciona para todos os geradores (por exemplo, makefiles e Visual Studio) sem a necessidade de comandos diferentes.Depois, uso os arquivos instalados para criar pacotes ou incluí-los em outros projetos ...
fonte
cmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
make -j $(nproc)
, para especificar o número de threads de compilação, façacmake --build . --target=install --config=Release -- -j 8
para o gerador Makefile oucmake --build . --target=install --config=Release -- /m:8
para o gerador do Visual Studio com 8 threads. Na verdade, você pode passar qualquer parâmetro da linha de comando após o--
-j
não é um sinalizador para cmake, todos os sinalizadores que vêm depois--
passam para o sistema de compilação subjacente ...Em relação à resposta de Bruce Adams:
Sua resposta cria confusão perigosa. DESTDIR destina-se a instalações fora da árvore raiz. Ele permite ver o que seria instalado na árvore raiz se não especificasse DESTDIR. PREFIX é o diretório base no qual a instalação real se baseia.
Por exemplo, PREFIX = / usr / local indica que o destino final de um pacote é / usr / local. Usar DESTDIR = $ HOME instalará os arquivos como se $ HOME fosse a raiz (/). Se, digamos DESTDIR, fosse / tmp / destdir, seria possível ver o que 'make install' afetaria. Nesse espírito, DESTDIR nunca deve afetar os objetos construídos.
Um segmento de makefile para explicá-lo:
Os programas devem assumir que PREFIX é o diretório base do diretório final (ou seja, produção). A possibilidade de vincular um programa instalado no DESTDIR = / algo significa apenas que o programa não acessa arquivos com base no PREFIX, pois simplesmente não funcionaria. O cat (1) é um programa que (em sua forma mais simples) pode ser executado de qualquer lugar. Aqui está um exemplo que não:
Se você tentou executar o prog de outro lugar que não o $ PREFIX / bin / prog, o prog.db nunca seria encontrado, pois não está no local esperado.
Finalmente, o / etc / alternative realmente não funciona dessa maneira. Existem links simbólicos para programas instalados na árvore raiz (por exemplo, vi -> / usr / bin / nvi, vi -> / usr / bin / vim, etc.).
fonte
É uma prática recomendada chamar o gerador real (por exemplo, via
make
) se estiver usando o CMake . É altamente recomendável fazer assim:Fase de configuração:
Fases de construção e instalação
Ao seguir esta abordagem, o gerador pode ser facilmente trocado (por exemplo,
-GNinja
para Ninja ) sem ter que lembrar de nenhum comando específico do gerador.fonte
--config
argumento?Começando com o CMake 3.15, a maneira correta de conseguir isso seria usando:
Documentação oficial
fonte