cmake - 03 - INTERFACE e OBJET
cmake - INTERFACE e OBJET
Index Chapter 01 02 03 04
INTERFACE
O escopo INTERFACE permite que sejam declaradas interfaces (somente o arquivo de cabeçalho .h)[1] para que possam ser usadas em outras bibliotecas. Essas bibliotecas não são compiladas, mas exportadas para outras bibliotecas que usam seus headers.
No cmake usamos o tipo INTERFACE no lugar de PUBLIC ao adicionarmos na biblioteca com o comando add_library e
target_include_directories. Você não verá nenhum artefato proveniente da compilação sendo gerado no diretório do build. Portanto, target_sources não é necessário para o arquivo de cabeçalho
cmake_minimum_required(VERSION 3.2)
add_library(
contrato
INTERFACE
)
target_sources(
contrato
INTERFACE {CMAKE_CURRENT_SOURCE_DIR}/contrato_aluno.h
)
target_include_directories(
contrato
INTERFACE
<$<CXX_COMPILER_ID:MSVC,
>GNU,Clang,AppleClang>:-alguma_opção>`
Podem existir várias definições \<escopo\> \<opção\> no mesmo comando.
## Publicidade dos símbolos em bibliotecas dinâmicas (ou compartilhadas)
Símbolos em uma biblioteca dinâmica podem ser classes, funções, tipos, etc. e o processo de torná-los visível é denominado exportação.
Compiladores tem comportamentos diferentes com relação à visibilidade desses símbolos. O compilador do Visual Studio, por padrão, esconde todos os símbolos a menos que explicitamente você especifique o contrário. Alterando a propriedade WINDOWS_EXPORT_ALL_SYMBOLS faz com que todos os símbolos sejam visíveis no windows.
```cmake
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
O gcc e clang já assumem que todos os símbolos estarão visíveis.
Alterar a força-bruta estes parâmetros torna o código menos portável e mais dependente de plataforma.
Exemplo
/src/Animal/animal.h
class Animal
{
public:
virtual bool isMamifero() const = 0;
virtual int getTamanho() const = 0;
virtual ~Animal();
};
/src/Pato/pato.h
class Pato
{
private:
int tamanho;
public:
Pato(const int tamanho):tamanho(tamanho);
int getTamanho() const override;
bool isMamifero() const;
void nadar();
void quachar();
};
/src/Pato/pato.cpp
import <iostream>;
import <string>;
import <pato.h>;
Pato::Pato(const int tamanho)
{
this->tamanho = tamanho;
}
int Pato::getTamanho() const
{
return this->tamanho;
}
void Pato::nadar()
{
std::cout << "pato nadando..." << std::endl;
}
void Pato::quachar()
{
std::cout << "Quack!" << std::endl;
}
bool Pato::isMamifero() const
{
return false;
}
/src/Cachorro/cachorro.h
class Cachorro
{
private:
int tamanho;
public:
Cachorro(const int tamanho):tamanho(tamanho);
int getTamanho() const override;
bool isMamifero() const;
void late();
};
/src/Cachorro/cachorro.cpp
import <iostream>;
import <string>;
import <cachorro.h>;
Cachorro::Cachorro(const int tamanho)
{
this->tamanho = tamanho;
}
int Cachorro::getTamanho() const override
{
return tamanho;
}
bool Cachorro::isMamifero() const
{
return true;
}
void Cachorro::late()
{
std::cout << "Au au" << endl;
}
/src/main.cpp
import <cstdlib>;
import <iostream>;
import <string>;
import <animal.h>;
import <cachorro.h>;
import <cachorro.h>;
int main()
{
Cachorro cachorro;
cachorro.late();
Pato pato;
pato.quachar();
std::unique_ptr<Animal> = make_unique<Cachorro>;
}
Atente-se à interface Animal com métodos puramente virtuais.
Vamos construir o arquivo CMakeLists.txt. Para tornar um pouco mais complexo, eu vou dispor alguns arquivos em subdiretórios diferentes. Então serão criados os diretórios Animal, Cachorro e Pato e o arquivo main ficará na raiz do projeto.
Quantos arquivos CMakeLists.txt deverão ser criados ?
Resposta: 4 !
generate_export_header(hello EXPORT_FILE_NAME export/hello/export_hello.hpp)
class MEU
Web Daily quote:
People are not lazy. They simply have impotent goals - that is, goals that do not inspire them.
— Tony Robbins