Working with Targets

Overview

Teaching: 10 min
Exercises: 15 min
Questions

    Como funcionam os objectivos?

Objectivos

  • Sabe como configurar metas

  • a Correcta ligação e propriedades de INTERFACE

  • Fazer INTERFACE metas

Agora você sabe como compilar um único arquivo usando três linhas de CMake. Mas o que acontece se você tem mais do que um arquivo com dependências? Você precisa ser capaz de contar ao CMake sobre a estrutura do seu projeto, e ele irá ajudá-lo a construí-lo. Para isso, precisarão de alvos.

Você já viu um alvo:

add_executable(myexample simple.cpp)

Isto cria um “executável” destino com o nome de myexample. Os nomes de destino devem ser únicos (e há uma maneira de definir o nome do executável para algo que não o nome de destino, se você realmente quiser).os alvos são muito parecidos com “objectos” noutras línguas.; eles têm propriedades (variáveis-membro)da informação. The SOURCES property, for example, will havesimple.cpp in it.

Outro tipo de alvo é uma biblioteca de:

add_library(mylibrary simplelib.cpp)

Você pode adicionar as palavras-chave STATICSHARED ou MODULE se você sabe que tipo de biblioteca que você wantto fazer; o padrão é uma espécie de um “auto” biblioteca que é seleccionável pelo utilizador com BUILD_SHARED_LIBS.

Você também pode fazer bibliotecas não-construídas. Mais tarde, quando virmos o que podemos fazer com os alvos.

a Vinculação

Depois de ter diversos objectivos, você pode descrever o relacionamento entre eles comtarget_link_libraries e palavra-chave; um PUBLICPRIVATE e INTERFACE. Não esqueça esta palavra-chave ao fazer uma biblioteca! O CMake entra num modo de compatibilidade antigo para este alvo que geralmente quebra as coisas.

Pergunta

Você tem uma biblioteca, my_lib, feita a partir de my_lib.hpp e my_lib.cpp. Ele requer pelo menos c++14to compilar. Se você então adicionar my_exe, e ele precisa my_lib, deve essa força my_exe para compilar com C++14 ou melhor?

resposta

isto depende do cabeçalho. Se o cabeçalho contém C++14, Este é um requisito público-tanto a biblioteca quanto os usuários precisam dele. No entanto, se o cabeçalho é válido em todas as versões do C++, andonly as implementações dentro de my_lib.cpp require C++14, em seguida, este é um PRIVATE requisito

  • os usuários não precisa ser forçado em C++14 modo.

talvez precise que os utilizadores tenham C++14, mas a sua biblioteca pode compilar com qualquer versão de C++.Trata-se de um requisito INTERFACE.

Exemplo de Público e Privado de herança

a Figura 1: Exemplo de público, privado e INTERFACE. myprogram irá construir as três bibliotecas através de mylibrary; a biblioteca privada não irá afetá-la.

Existem duas coleções de propriedades em cada alvo que podem ser preenchidas com valores; as propriedades”privadas” controlam o que acontece quando você constrói esse alvo, e os alvos “interface” propertiestell ligados a este o que fazer ao construir. ThePUBLIC keyword fills both propertyfields at the same time.exemplo 1: Incluir diretórios

Quando você executa , thenthe INCLUDE_DIRECTORIES propriedade TargetA tem mydir acrescentado. If you use the keywordINTERFACE instead, then INTERFACE_INCLUDE_DIRECTORIES is appended to, instead. Se você usarPUBLIC, então ambas as propriedades são anexadas ao mesmo tempo.

Exemplo 2: norma c++

existe uma propriedade padrão C++ – CXX_STANDARD. Você pode definir essa propriedade, e como manyproperties no CMake, ele fica com o valor padrão de uma CMAKE_CXX_STANDARD variável se ele está definido,mas não há nenhuma versão de INTERFACE – você não pode forçar um CXX_STANDARD através de um alvo. O que faria se tivesse um alvo de interface C++11 e um alvo de interface C++14 e ligado a ambos?

A propósito, existe uma maneira de lidar com isto – você pode especificar as características mínimas de compilação que você precisa para compilar um alvo; cxx_std_11 e semelhantes meta-funcionalidades são perfeitos para isso – o seu targetwill compilar com, pelo menos, o mais alto nível especificado, a menos que CXX_STANDARD é definido (e que sa agradável, claro erro de se definir CXX_STANDARD muito baixo). target_compile_features pode preencherCOMPILE_FEATURES e INTERFACE_COMPILE_FEATURES, assim como diretórios no exemplo 1.

Experimente

obtenha este repositório e vá para o exemplo. Tente escrever um CMakeLists que irá construir corretamente.

git clone https://github.com/hsf-training/hsf-training-cmake-webpage.gitcd hsf-training-cmake-webpage/code/01-simple

Os arquivos aqui são:

  • simple_lib.cpp: Deve ser compilado com MYLIB_PRIVATE e MYLIB_PUBLIC definido.
  • simple_ example.cpp: Deve ser compilado com MYLIB_PUBLIC definido, mas não MYLIB_PRIVATE

Use para definir as definições simple_lib.

Coisas que você pode definir metas

  • target_link_libraries: Outros destinos; também pode passar nomes de biblioteca diretamente
  • target_include_directories: Include directories
  • target_compile_features: The compiler features you need activated, like cxx_std_11
  • target_compile_definitions: Definitions
  • target_compile_options: More general compile flags
  • target_link_directories: Don’t use, give full paths instead (CMake 3.13+)
  • target_link_options: General link flags (CMake 3.13+)
  • target_sources: Add source files

See more commands here.

outros tipos de alvos

pode ser realmente atingido por alvos e já está a planear como pode descrever os seus programas em termos de alvos. Isso é óptimo! No entanto, você vai rapidamente encontrar mais duas situações onde a linguagem alvo é útil, mas você precisa de alguma flexibilidade extra sobre o que nós cobrimos.

primeiro, você pode ter uma biblioteca que conceitualmente deve ser um alvo, mas na verdade não tem nenhum componente de construção – uma biblioteca “header-only”. Estas são chamadas bibliotecas de interface em CMake e você iria escrever:

add_library(some_header_only_lib INTERFACE)

Notice you didn’t need to add any source files. Agora você pode definir INTERFACE propriedades apenas sobre este(uma vez que não existe nenhum componente construído).

a segunda situação é se você tem uma biblioteca pré-construída que você deseja usar. Isto é chamado de biblioteca animportada em CMake, e usa a palavra-chave IMPORTED. Bibliotecas importadas também podem serINTERFACE bibliotecas, elas podem ser construídas e modificadas usando a mesma sintaxe que outras bibliotecas(começando em CMake 3.11), e eles podem ter :: em seu nome. (ALIAS bibliotecas, que simplyrename alguma outra biblioteca, também estão autorizados a ter ::). A maior parte do tempo você vai receber importantes bibliotecas de outros lugares, e não vai fazer o seu próprio.

INTERFACE impressa

e sobre INTERFACE IMPORTED?A diferença resume-se a duas coisas:

  1. IMPORTED alvos não são exportáveis. Se você salvar seus alvos, você não pode salvar os importados-eles precisam ser recriados (ou encontrados novamente).
  2. IMPORTED as pastas de inclusão do cabeçalho serão sempre marcadas como SYSTEM.

portanto, umIMPORTED alvo deve representar algo que não faz directamente parte do seu pacote.

Mais de leitura

  • com Base na Moderna CMake básico
  • veja Também o CMake docs

Pontos-Chave

  • Bibliotecas e executáveis são os alvos.os alvos têm muitas propriedades úteis.os objectivos podem ser associados a outros objectivos.

  • pode controlar as partes de um alvo que são herdadas ao ligar.

  • Você pode fazer alvos de INTERFACE em vez de fazer variáveis.

Deixe uma resposta

O seu endereço de email não será publicado.