O que é o CMake equivalente a 'configure --prefix = DIR && make all install'?

386

Eu faço cmake . && make all install. Isso funciona, mas instala para /usr/local.

Preciso instalar em um prefixo diferente (por exemplo, para /usr).

Qual é a linha de comando cmakee makepara instalar em /usrvez de /usr/local?

Andrei
fonte
11
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.

Marcus D. Hanwell
fonte
21
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

... conforme usado nas respostas aqui .

user2023370
fonte
7
:PATHnão é um erro .
Kirbyfan64sos
29

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.

Bruce Adams
fonte
9
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:

/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
  • 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 ...

toeb
fonte
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:

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 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.).

user7498341
fonte
11
Esta resposta poderia ser melhor colocado como uma resposta a stackoverflow.com/questions/11307465/destdir-and-prefix-of-make
Bruce Adams
2

É uma prática recomendada chamar o gerador real (por exemplo, via make) se estiver usando o CMake . É altamente recomendável fazer assim:

  1. Fase de configuração:

    cmake -Hfoo -B_builds/foo/debug -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEBUG_POSTFIX=d -DCMAKE_INSTALL_PREFIX=/usr
    
  2. Fases de construção e instalação

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

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.

Florian Wolters
fonte
11
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:

cmake --install <dir> --prefix "/usr"

Documentação oficial

ExaltedBagel
fonte