In questa pagina scoprirai come creare la tua libreria C/C++ in sandbox con Sandboxed API (SAPI). Utilizzala come guida insieme agli esempi e alla documentazione del codice nei file di intestazione.
Dipendenze build
Le seguenti dipendenze devono essere installate sul sistema:
- Kernel Linux con supporto per gli spazi dei nomi UTS, IPC, utente, PID e di rete
- Intestazioni API dello spazio utente Linux
- Per compilare il codice: GCC 6 (versione 7 o successive consigliata) o Clang 7 (o versioni successive)
- Per la generazione automatica dei file di intestazione: Clang Python Bindings
- Python 3.5 o versioni successive
- Bazel versione 2.2.0 o CMake versione 3.12 o successive.
Utilizzo di Bazel
Bazel è il sistema di compilazione consigliato ed è il più facile da integrare.
La nostra documentazione utilizza il compilatore Clang. Se hai bisogno di una toolchain specifica (ad es. compilatore, linker e così via), consulta la documentazione di Bazel per informazioni su come modificare la toolchain del compilatore predefinita.
Debian 10 (Buster)
Per installare le dipendenze di build:
echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \ sudo tee /etc/apt/sources.list.d/bazel.listwget -qO - https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -sudo apt-get updatesudo apt-get install -qy build-essential linux-libc-dev bazel python3 \ python3-pip libclang-devpip3 install clang
Gentoo
Opzioni del kernel richieste:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
Per installare le dipendenze di build:
emerge dev-util/bazel dev-python/typing dev-python/clang-pythonUtilizzo di CMake
CMake è un sistema di meta-compilazione open source molto diffuso che genera file di progetto per strumenti di compilazione come Ninja o Make.
Debian 10 (Buster)
Per installare le dipendenze di build:
sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \ python3 python3-pip libclang-dev libcap-devpip3 install absl-py clang
Gentoo
Opzioni del kernel richieste:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
Per installare le dipendenze di build:
emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-pythonProcesso di sviluppo
Per inserire una libreria C/C++ in sandbox, devi preparare due elementi per il tuo progetto:
- La libreria in sandbox
- Il codice host che utilizzerà le funzionalità esposte dalla libreria in sandbox. SAPI genererà automaticamente l'oggetto SAPI e lo stub RPC durante il processo di compilazione.
Potresti conoscere zlib dagli esempi di Sandbox2 , dove è stato inserito in sandbox un intero programma (zpipe.c) . Nei passaggi che seguono, imparerai a utilizzare SAPI per inserire in sandbox la libreria zlib e utilizzare la libreria in sandbox.
1. Decidi quali funzioni sono necessarie
Se esamini il codice host zlib
(main_zlib.cc),
puoi notare che la funzionalità dello strumento è leggere i dati da stdin e utilizzare
la funzione deflate() di zlib per comprimere i dati finché non viene letto un indicatore EOF.
In totale, il programma utilizza tre funzioni di zlib:
deflateInit_(): per inizializzare la compressionedeflate(): per eseguire l'operazione di compressione sul blocco di datideflateEnd(): per terminare la compressione e liberare le strutture di dati allocate dinamicamente
In un esempio reale, esamineresti la libreria C/C++ e decideresti quali funzioni sono necessarie. Una strategia possibile è iniziare con il codice host e utilizzare la libreria senza sandbox. Poi, in un secondo passaggio, potresti generare la libreria in sandbox e adattare il codice host per utilizzare le chiamate di funzione in sandbox.
2. Scrivi la regola di build sapi_library
Dopo aver identificato le tre funzioni zlib necessarie dalla
libreria zlib in sandbox, puoi definire la regola di build nel
file BUILD. La documentazione per la regola di build sapi_library è disponibile nella pagina
Regole di build.
Lo snippet di codice riportato di seguito mostra la definizione di sapi_library per l'esempio SAPI zlib. Utilizzando l'attributo lib, Bazel riceve l'istruzione di cercare la libreria zlib nel file
WORKSPACE.
sapi_library(
name = "zlib-sapi",
srcs = [],
hdrs = [],
functions = [
"deflateInit_",
"deflate",
"deflateEnd",
],
lib = "@net_zlib//:zlib",
lib_name = "Zlib",
namespace = "sapi::zlib",
)
Il risultato è la generazione della libreria zlib in sandbox. L'output è l'oggetto SAPI che può essere incluso nel codice host e utilizzato per comunicare con la libreria in sandbox tramite chiamate RPC. Il criterio di sandbox utilizzato in questo esempio è il criterio predefinito.
3. Scrivi o modifica il codice host
Ora è il momento di incorporare la libreria SAPI generata nel codice host.
Crea la sandbox
Utilizza sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create()); per creare un oggetto sandbox.
Utilizza sapi::zlib::ZlibApi api(&sandbox); per creare un'istanza dell'oggetto SAPI e rendere quindi
disponibili le funzioni in sandbox.
Utilizza i tipi SAPI
I tipi SAPI sono tipi speciali sotto forma di classi C++ che SAPI fornisce perché a volte i tipi C normali non funzionano.
Il primo utilizzo di un tipo SAPI può essere osservato nella dichiarazione di strm, dove
viene utilizzata una struttura SAPI: sapi::v::Struct<sapi::zlib::z_stream> strm;
Il tipo di modello (sapi::zlib::z_stream) è un buon esempio di codice generato automaticamente dalla regola di build.
Per maggiori dettagli, consulta la pagina Variabili.
Esegui chiamate API
Per effettuare chiamate a defalteInit_, deflate o deflateEnd, utilizza l'oggetto SAPI. Se decidi di utilizzare l'approccio "modifica", devi assicurarti che i parametri della funzione corrispondano ai valori previsti.
Un esempio di ciascuna delle chiamate nell'esempio zlib:
api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION, version.PtrBefore(), sizeof(sapi::zlib::z_stream));
api.deflate(strm.PtrBoth(), flush);
api.deflateEnd(strm.PtrBoth()).IgnoreError();
Utilizzo delle transazioni SAPI
SAPI isola il codice host dalla libreria in sandbox e consente al chiamante di riavviare o interrompere le richieste di elaborazione dei dati problematiche. La transazione SAPI va oltre e ripete automaticamente i processi non riusciti.
Per maggiori dettagli, consulta la pagina Transazioni SAPI Page.
Esempi
In Esempi puoi trovare alcune librerie già preparate dal team SAPI.