Dependências de interface de bibliotecas de link_de_alvo CMake

108

Eu sou novo no CMake e um pouco confuso com as palavras-chave PUBLIC, PRIVATE e INTERFACE relacionadas a target_link_libraries(). A documentação menciona que eles podem ser usados ​​para especificar as dependências do link e a interface do link em um comando.

O que realmente significam as dependências e a interface do link?

Sirish
fonte
1
Pergunta semelhante: stackoverflow.com/questions/26243169/…
TManhente

Respostas:

211

Se você estiver criando uma biblioteca compartilhada e seus arquivos cpp de origem # incluem os cabeçalhos de outra biblioteca (digamos, QtNetwork por exemplo), mas seus arquivos de cabeçalho não incluem cabeçalhos QtNetwork, então QtNetwork é uma PRIVATEdependência.

Se seus arquivos de origem e seus cabeçalhos incluem os cabeçalhos de outra biblioteca, então é uma PUBLICdependência.

Se seus arquivos de cabeçalho, mas não seus arquivos de origem, incluem os cabeçalhos de outra biblioteca, então é uma INTERFACEdependência.

Outras propriedades de construção PUBLICe INTERFACEdependências são propagadas para as bibliotecas de consumo. http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html#transitive-usage-requirements

steveire
fonte
43
Esta é a explicação mais clara para essa pergunta que já ouvi. Gostaria que a documentação do cmake fosse tão clara! :-)
Ela782
1
Obrigado pela explicação eu entendo o significado agora, mas por que especificar PUBLICou PRIVATEimporta? O que isso muda?
user3667089
9
O uso PRIVATEnão adiciona suas dependências a projetos vinculados à sua biblioteca. É mais limpo e também evita possíveis conflitos entre suas dependências e as do usuário.
user2658323
7
@steveire Por motivos de clareza, pode valer a pena declarar explicitamente que "incluir" significa inclusão transitiva, não apenas inclusão direta. Por exemplo, se os arquivos de cabeçalho de outra biblioteca são incluídos apenas diretamente por seus arquivos de cabeçalho, mas todos os seus arquivos de cabeçalho são incluídos por seus arquivos de origem, então seus arquivos de origem incluem transitivamente os arquivos de cabeçalho da outra biblioteca, e assim você tem uma PUBLICdependência, não uma INTERFACEdependência.
Ose
A documentação do cmake deve ser tão concisa quanto esta resposta!
Bryan Jyh Herng Chong
4

A resposta aceita de @steveire é ótima. Eu só queria adicionar uma tabela para ver rapidamente a diferença:

.-----------.------------------.----------------.
|           | Linked by target | Link interface |
:-----------+------------------+----------------:
| PUBLIC    |        X         |        X       |
:-----------+------------------+----------------:
| PRIVATE   |        X         |                |
:-----------+------------------+----------------:
| INTERFACE |                  |        X       |
'-----------'------------------'----------------'
  • Vinculado por destino : bibliotecas incluídas nas fontes de destino (não é uma dependência para projetos vinculando a biblioteca).
  • Interface do link : bibliotecas incluídas nos cabeçalhos públicos de destino (dependências para projetos que vinculam a biblioteca).
ikaro
fonte
0

Algumas respostas diziam apenas quando usar PRIVATE / PUBLIC / INTERFACE, mas os efeitos são ignorados. Consulte: CMake-Public-Private-Interface

PUBLIC
Todos os objetos que seguem PUBLIC serão usados ​​para vincular ao destino atual e fornecer a interface para os outros destinos que possuem dependências do destino atual.

PRIVATE
Todos os objetos que seguem PRIVATE serão usados ​​apenas para vincular ao alvo atual.

INTERFACE
Todos os objetos que seguem INTERFACE serão usados ​​apenas para fornecer a interface para os outros destinos que possuem dependências no destino atual.

WangJian
fonte