CMake target_include_directories significado do escopo

101

Qual é o significado da palavra-chave PUBLIC, PRIVATEe INTERFACErelacionado com CMake de target_include_directories?

Poorna
fonte
Intimamente relacionado: stackoverflow.com/q/26037954/3425536
emlai

Respostas:

120

Essas palavras-chave são usadas para dizer quando a lista de diretórios de inclusão que você está passando para o destino é necessária. Por quando , isso significa que, se os incluir diretórios são necessários:

  • Para compilar o próprio destino.
  • Para compilar outros destinos que dependem desse destino (como usar seus cabeçalhos públicos).
  • Em ambas as situações acima.

Quando CMake está compilando um alvo, ele usa os alvos INCLUDE_DIRECTORIES, COMPILE_DEFINITIONSe COMPILE_OPTIONSpropriedades. Quando você usa a PRIVATEpalavra - chave em target_include_directories()e similares, diz ao CMake para preencher essas propriedades de destino.

Quando o CMake detecta uma dependência entre um alvo A e outro alvo B (como quando você usa o target_link_libraries(A B)comando), ele propaga transitivamente os B requisitos de uso para o Aalvo. Esses requisitos de uso de destino são os diretórios de inclusão, definições de compilação, etc. que qualquer destino que dependa Bdeve atender. Eles são especificados pela INTERFACE_*versão das propriedades listadas acima (como INTERFACE_INCLUDE_DIRECTORIES) e são preenchidos usando a INTERFACEpalavra - chave ao chamar otarget_*() comandos.

A PUBLICpalavra-chave significa aproximadamente PRIVATE + INTERFACE.

Portanto, suponha que você esteja criando uma biblioteca Aque usa alguns cabeçalhos Boost. Você faria:

  • target_include_directories(A PRIVATE ${Boost_INCLUDE_DIRS})se você usar apenas esses cabeçalhos Boost dentro de seus arquivos de origem ( .cpp) ou arquivos de cabeçalho privados ( .h).
  • target_include_directories(A INTERFACE ${Boost_INCLUDE_DIRS})se você não usar esses cabeçalhos Boost dentro de seus arquivos de origem (portanto, não precisa deles para compilar A). Na verdade, não consigo pensar em um exemplo do mundo real para isso.
  • target_include_directories(A PUBLIC ${Boost_INCLUDE_DIRS})se você usar esses cabeçalhos Boost em seus arquivos de cabeçalho públicos, que estão incluídos AMBOS em alguns dos Aarquivos de origem de e também podem ser incluídos em qualquer outro cliente de sua Abiblioteca.

A documentação do CMake 3.0 tem mais detalhes sobre esta especificação de construção e propriedades de requisitos de uso .

TManhente
fonte
18
Em relação a um exemplo do mundo real de INTERFACE. target_include_directories(libname INTERFACE include PRIVATE include/libname). Isso significa que em sua biblioteca você pode incluir arquivos diretamente, mas como um usuário da biblioteca, você deve inserir libname/primeiro.
KaareZ
2
Essas respostas fazem sentido para mim para criar bibliotecas. Mas que tal chamar target_include_directories para um destino que é um executável?
Norman Pellet
1
@NormanPellet: Você pode chamar target_include_directories()um destino executável se precisar definir diretórios de inclusão onde os arquivos de cabeçalho usados ​​por esses executáveis ​​podem ser encontrados (por exemplo: Boost :: Program_options, se você usá-lo para analisar argumentos em sua main()função) . Você provavelmente usaria a PRIVATEpalavra - chave neste caso, pois esses arquivos são necessários para compilar o próprio executável. Não sei se existe alguma utilidade para INTERFACEou PUBLICem um executável, no entanto.
TManhente
13

As palavras-chave INTERFACE, PUBLIC e PRIVATE são necessárias para especificar o escopo dos seguintes argumentos. Os itens PRIVATE e PUBLIC irão preencher a propriedade INCLUDE_DIRECTORIES de <target>. Os itens PUBLIC e INTERFACE preencherão a propriedade INTERFACE_INCLUDE_DIRECTORIES de <destino>. Os seguintes argumentos especificam diretórios de inclusão.

Da documentação: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html

Para reformular a documentação com minhas próprias palavras:

  • você deseja adicionar um diretório à lista de diretório de inclusão de um alvo
  • com PRIVATE o diretório é adicionado aos diretórios de inclusão do alvo
  • com INTERFACE, o destino não é modificado, mas INTERFACE_INCLUDE_DIRECTORIES é estendido pelo diretório. A variável é uma lista de diretórios de inclusão públicos para uma biblioteca.
  • com PUBLIC ambas as ações de PRIVATE e INTERFACE são executadas.
usr1234567
fonte
4
Eu examinei a documentação do CMAKE, mas ainda não entendi o que eles realmente significam e em que contexto (criar arquivos ou como eles foram compilados).
Poorna
@Sirish: Tentei reformular a documentação, espero que ajude.
usr1234567 de