Nesta página, você vai aprender a criar sua própria biblioteca C/C++ em sandbox com a API em sandbox (SAPI). Use-o como um guia junto com os exemplos e a documentação de código nos arquivos de cabeçalho.
Dependências do build
As seguintes dependências precisam ser instaladas no sistema:
- Kernel do Linux com suporte para namespaces UTS, IPC, de usuário, PID e de rede
- Cabeçalhos da API do espaço do usuário do Linux
- Para compilar seu código: GCC 6 (preferencialmente versão 7 ou mais recente) ou Clang 7 (ou mais recente)
- Para gerar automaticamente arquivos de cabeçalho: vinculações do Python do Clang
- Python 3.5 ou posterior
- Bazel versão 2.2.0 ou CMake versão 3.12 ou mais recente.
Como usar o Bazel
O Bazel é o sistema de build recomendado e o mais fácil de integrar.
Nossa documentação usa o compilador Clang. Se você precisar de um conjunto de ferramentas específico (por exemplo, compilador, vinculador etc.), consulte a documentação do Bazel para saber como mudar o conjunto de ferramentas do compilador padrão.
Debian 10 (Buster)
Para instalar dependências de build:
echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \ sudo tee /etc/apt/sources.list.d/bazel.list
wget -qO - https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install -qy build-essential linux-libc-dev bazel python3 \ python3-pip libclang-dev
pip3 install clang
Gentoo
Opções de kernel necessárias:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
Para instalar dependências de build:
emerge dev-util/bazel dev-python/typing dev-python/clang-python
Como usar o CMake
O CMake é um sistema de metabuild de código aberto muito usado que gera arquivos de projeto para ferramentas de build como Ninja ou Make.
Debian 10 (Buster)
Para instalar dependências de build:
sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \ python3 python3-pip libclang-dev libcap-dev
pip3 install absl-py clang
Gentoo
Opções de kernel necessárias:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
Para instalar dependências de build:
emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-python
Processo de desenvolvimento
Para isolar uma biblioteca C/C++, é preciso preparar dois itens para o projeto:
- A biblioteca em sandbox
- O código do host, que vai usar a funcionalidade exposta pela biblioteca em sandbox. A SAPI vai gerar automaticamente o objeto SAPI e o stub RPC durante o processo de build.
Talvez você já conheça a zlib dos exemplos do Sandbox2. Aqui, um programa inteiro (zpipe.c) foi colocado em sandbox. Nas etapas a seguir, você vai aprender a usar a SAPI para colocar a biblioteca zlib em sandbox e usar a biblioteca em sandbox.
1. Decidir quais funções são necessárias
Se você analisar o código do host zlib (main_zlib.cc), vai perceber que a funcionalidade da ferramenta é ler dados de stdin e usar a função deflate()
do zlib para compactar os dados até que um marcador EOF
seja lido.
No total, o programa usa três funções da zlib:
deflateInit_()
: para inicializar a compactaçãodeflate()
: para realizar a operação de compactação no bloco de dadosdeflateEnd()
: para encerrar a compactação e liberar estruturas de dados alocadas dinamicamente
Em um exemplo real, você revisaria a biblioteca C/C++ e decidiria quais funções são necessárias. Uma estratégia possível é começar com o código do host e usar a biblioteca sem sandbox. Em seguida, em uma segunda etapa, você pode gerar a biblioteca em sandbox e adaptar o código do host para usar as chamadas de função em sandbox.
2. Escrever a regra de build sapi_library
Depois de identificar as três funções zlib necessárias da biblioteca zlib em sandbox, defina a regra de build no arquivo BUILD. A documentação da regra de build sapi_library
pode ser encontrada na página Regras de build.
O snippet de código abaixo mostra a definição de sapi_library
para o exemplo da SAPI zlib. Usando o atributo lib
, o Bazel é instruído a procurar a biblioteca zlib no arquivo WORKSPACE.
sapi_library(
name = "zlib-sapi",
srcs = [],
hdrs = [],
functions = [
"deflateInit_",
"deflate",
"deflateEnd",
],
lib = "@net_zlib//:zlib",
lib_name = "Zlib",
namespace = "sapi::zlib",
)
Como resultado, a biblioteca zlib em sandbox é gerada. A saída é o objeto SAPI, que pode ser incluído no código do host e usado para se comunicar com a biblioteca em sandbox por chamadas de RPC. A política de sandbox usada neste exemplo é a padrão.
3. Escrever ou mudar o código do host
Agora é hora de incorporar a biblioteca SAPI gerada ao código do host.
Criar a sandbox
Use sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create());
para criar um objeto de
sandbox.
Use sapi::zlib::ZlibApi api(&sandbox);
para instanciar o objeto SAPI e, assim,
disponibilizar as funções em sandbox para uso.
Usar tipos de SAPI
Os tipos SAPI são tipos especiais na forma de classes C++ que a SAPI fornece porque, às vezes, os tipos C regulares não funcionam.
O primeiro uso de um tipo de SAPI pode ser observado na declaração de strm
, em que
uma estrutura SAPI é usada: sapi::v::Struct<sapi::zlib::z_stream> strm;
O tipo de modelo (sapi::zlib::z_stream
) é um bom exemplo de código
gerado automaticamente pela regra de build.
Confira mais detalhes na página "Variáveis".
Fazer chamadas de API
Para fazer chamadas para defalteInit_
, deflate
ou deflateEnd
, use o objeto
SAPI. Se você decidir usar a abordagem "change", verifique se os parâmetros da função correspondem aos valores esperados.
Um exemplo de cada uma das chamadas no zlib example:
api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION, version.PtrBefore(), sizeof(sapi::zlib::z_stream));
api.deflate(strm.PtrBoth(), flush);
api.deflateEnd(strm.PtrBoth()).IgnoreError();
Como usar transações da SAPI
A SAPI isola o código do host da biblioteca em sandbox e dá ao autor da chamada a capacidade de reiniciar ou interromper solicitações problemáticas de processamento de dados. A transação SAPI vai um passo além e repete automaticamente os processos com falha.
Confira mais detalhes na página de transações da SAPI.
Exemplos
Em Exemplos, você encontra algumas bibliotecas já preparadas pela equipe da SAPI.