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 Brequisitos 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.
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.
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.
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.
Respostas:
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:
Quando CMake está compilando um alvo, ele usa os alvos
INCLUDE_DIRECTORIES
,COMPILE_DEFINITIONS
eCOMPILE_OPTIONS
propriedades. Quando você usa aPRIVATE
palavra - chave emtarget_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 osB
requisitos de uso para oA
alvo. Esses requisitos de uso de destino são os diretórios de inclusão, definições de compilação, etc. que qualquer destino que dependaB
deve atender. Eles são especificados pelaINTERFACE_*
versão das propriedades listadas acima (comoINTERFACE_INCLUDE_DIRECTORIES
) e são preenchidos usando aINTERFACE
palavra - chave ao chamar otarget_*()
comandos.A
PUBLIC
palavra-chave significa aproximadamentePRIVATE + INTERFACE
.Portanto, suponha que você esteja criando uma biblioteca
A
que 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 compilarA
). 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 dosA
arquivos de origem de e também podem ser incluídos em qualquer outro cliente de suaA
biblioteca.A documentação do CMake 3.0 tem mais detalhes sobre esta especificação de construção e propriedades de requisitos de uso .
fonte
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 inserirlibname/
primeiro.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 suamain()
função) . Você provavelmente usaria aPRIVATE
palavra - chave neste caso, pois esses arquivos são necessários para compilar o próprio executável. Não sei se existe alguma utilidade paraINTERFACE
ouPUBLIC
em um executável, no entanto.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:
fonte