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


  1. https://en.wikipedia.org/wiki/Header-only ↩︎