Créé par GH-MD-TOC
Sobjectizer est l'un des rares «frameworks d'acteurs» et opensource pour C ++. Mais Sobjectizer prend en charge non seulement le modèle d'acteur, mais aussi le modèle de publication-abonnement et les canaux de type CSP. L'objectif de Sobjectizer est une simplification significative du développement d'applications simultanées et multithread en C ++.
Sobjectizer permet la création d'une application simultanée en tant qu'ensemble d'objets d'agent qui interagissent entre eux via des messages asynchrones. Il gère la répartition des messages et fournit un contexte de travail pour le traitement des messages. Et permet de régler ces choses en fournissant divers répartiteurs prêts à l'emploi.
Maturité . Sobjectizer est basé sur des idées qui ont été proposées en 1995-2000. Et Sobjectizer lui-même est en cours de développement depuis 2002. Sobjectizer-5 est constamment évolué depuis 2010.
Stabilité . Dès le début, le sanglot a été utilisé pour les applications critiques, et certains d'entre eux sont toujours utilisés en production. Les changements de rupture dans Sobjectizer sont rares et nous nous approchons très attentivement.
Multiplateforme . Sobjectizer s'exécute sur Windows, Linux, FreeBSD, MacOS et Android.
Facile à utiliser . Sobjectizer fournit une API facile à comprendre et facile à utiliser avec de nombreux exemples dans la distribution de Sobjectizer et de nombreuses informations dans le wiki du projet.
Gratuit . Sobjectizer est distribué sous licence de clause BSD-3, il peut donc être utilisé gratuitement dans le développement de logiciels commerciaux propriétaires.
Sobjectizer est souvent comparé à des outils tels que les blocs de construction Intel Fileing, Taskflow, HPX et similaires à eux. Une telle comparaison est tout simplement inutile.
Tous ces outils sont destinés à être utilisés pour résoudre les tâches de la zone informatique parallèle: ils permettent de réduire le temps de calcul en utilisant plusieurs noyaux de CPU. Par exemple, vous pouvez réencoder votre fichier vidéo d'un format à un autre dans un délai d'une heure sur un noyau de processeur, en ne prenant que 15 minutes sur quatre cœurs. C'est l'objectif principal de l'informatique parallèle.
Sobjectizer est destiné à une zone légèrement différente: l'informatique simultanée. L'objectif principal de Sobjectizer est la simplification de faire de nombreuses tâches différentes à la fois. Parfois, il n'est pas nécessaire d'utiliser plus d'un simple noyau de processeur pour cela. Mais s'il existe plusieurs noyaux de processeur, alors Sobjectizer facilite la manipulation de ces tâches et l'interaction entre eux.
La partie délicate est le fait que l'informatique parallèle et simultanée utilise les mêmes mécanismes et primitives de concurrence (comme les fils, les mutex, les atomiques, etc.) sous le capot. Mais du point de vue de haut niveau de haut niveau, l'informatique parallèle et simultané est utilisé pour des tâches très différentes.
En tant qu'exemples d'applications qui ont été ou peuvent être implémentées en haut de Sobjectizer, nous pouvons répertorier le serveur proxy multithread, le système de contrôle automatique, le courtier MQ, le serveur de base de données, etc.
Ceci est un exemple classique "Hello, World" exprimé en utilisant les agents de Sobjectizer:
# include < so_5/all.hpp >
class hello_actor final : public so_5:: agent_t {
public:
using so_5:: agent_t :: agent_t ;
void so_evt_start () override {
std::cout << " Hello, World! " << std::endl;
// Finish work of example.
so_deregister_agent_coop_normally ();
}
};
int main () {
// Launch SObjectizer.
so_5::launch ([](so_5:: environment_t & env) {
// Add a hello_actor instance in a new cooperation.
env. register_agent_as_coop ( env. make_agent <hello_actor>() );
});
return 0 ;
}Regardons un exemple plus intéressant avec deux agents et l'échange de messages entre eux. C'est un autre exemple célèbre pour les cadres d'acteurs, "ping-pong":
# include < so_5/all.hpp >
struct ping {
int counter_;
};
struct pong {
int counter_;
};
class pinger final : public so_5:: agent_t {
so_5:: mbox_t ponger_;
void on_pong ( mhood_t <pong> cmd) {
if (cmd-> counter_ > 0 )
so_5::send<ping>(ponger_, cmd-> counter_ - 1 );
else
so_deregister_agent_coop_normally ();
}
public:
pinger ( context_t ctx) : so_5:: agent_t { std::move (ctx)} {}
void set_ponger ( const so_5:: mbox_t mbox) { ponger_ = mbox; }
void so_define_agent () override {
so_subscribe_self (). event ( &pinger::on_pong );
}
void so_evt_start () override {
so_5::send<ping>(ponger_, 1000 );
}
};
class ponger final : public so_5:: agent_t {
const so_5:: mbox_t pinger_;
int pings_received_{};
public:
ponger ( context_t ctx, so_5:: mbox_t pinger)
: so_5:: agent_t { std::move (ctx)}
, pinger_{ std::move (pinger)}
{}
void so_define_agent () override {
so_subscribe_self (). event (
[ this ]( mhood_t <ping> cmd) {
++pings_received_;
so_5::send<pong>(pinger_, cmd-> counter_ );
});
}
void so_evt_finish () override {
std::cout << " pings received: " << pings_received_ << std::endl;
}
};
int main () {
so_5::launch ([](so_5:: environment_t & env) {
env. introduce_coop ([](so_5:: coop_t & coop) {
auto pinger_actor = coop. make_agent <pinger>();
auto ponger_actor = coop. make_agent <ponger>(
pinger_actor-> so_direct_mbox ());
pinger_actor-> set_ponger (ponger_actor-> so_direct_mbox ());
});
});
return 0 ;
}Tous les agents du code ci-dessus fonctionnent sur le même thread de travail. Comment les lier à différents fils de travail?
C'est très simple. Utilisez simplement un répartiteur approprié:
int main () {
so_5::launch ([](so_5:: environment_t & env) {
env. introduce_coop (
so_5::disp::active_obj::make_dispatcher (env). binder (),
[](so_5:: coop_t & coop) {
auto pinger_actor = coop. make_agent <pinger>();
auto ponger_actor = coop. make_agent <ponger>(
pinger_actor-> so_direct_mbox ());
pinger_actor-> set_ponger (ponger_actor-> so_direct_mbox ());
});
});
return 0 ;
}Sobjectizer prend en charge le modèle Pub / Sub via des boîtes de messages multi-producteur / multi-consommation. Un message envoyé à cette boîte de message sera reçu par tous les abonnés de ce type de message:
# include < so_5/all.hpp >
using namespace std ::literals ;
struct acquired_value {
std::chrono::steady_clock::time_point acquired_at_;
int value_;
};
class producer final : public so_5:: agent_t {
const so_5:: mbox_t board_;
so_5:: timer_id_t timer_;
int counter_{};
struct acquisition_time final : public so_5:: signal_t {};
void on_timer ( mhood_t <acquisition_time>) {
// Publish the next value for all consumers.
so_5::send<acquired_value>(
board_, std::chrono::steady_clock::now (), ++counter_);
}
public:
producer ( context_t ctx, so_5:: mbox_t board)
: so_5:: agent_t { std::move (ctx)}
, board_{ std::move (board)}
{}
void so_define_agent () override {
so_subscribe_self (). event (&producer::on_timer);
}
void so_evt_start () override {
// Agent will periodically recive acquisition_time signal
// without initial delay and with period of 750ms.
timer_ = so_5::send_periodic<acquisition_time>(* this , 0ms, 750ms);
}
};
class consumer final : public so_5:: agent_t {
const so_5:: mbox_t board_;
const std::string name_;
void on_value ( mhood_t <acquired_value> cmd) {
std::cout << name_ << " : " << cmd-> value_ << std::endl;
}
public:
consumer ( context_t ctx, so_5:: mbox_t board, std::string name)
: so_5:: agent_t { std::move (ctx)}
, board_{ std::move (board)}
, name_{ std::move (name)}
{}
void so_define_agent () override {
so_subscribe (board_). event (&consumer::on_value);
}
};
int main () {
so_5::launch ([](so_5:: environment_t & env) {
auto board = env. create_mbox ();
env. introduce_coop ([board](so_5:: coop_t & coop) {
coop. make_agent <producer>(board);
coop. make_agent <consumer>(board, " first " s);
coop. make_agent <consumer>(board, " second " s);
});
std::this_thread::sleep_for ( std::chrono::seconds ( 4 ));
env. stop ();
});
return 0 ;
}Tous les agents de Sobjectizer sont des machines à États finis. Presque toutes les fonctionnalités des machines hiérarchiques à l'état final (HSM) sont soutenues: les états des enfants et les gestionnaires de l'héritage, ON_ENTER / ON_EXIT HANDERS, STAT TIMEURS, HISTOIRE DE L'ÉTAT-ET SUCONDEMENT ET SUPEL, à l'exception des états orthogonaux.
Voyons à quoi peut ressembler un agent qui implémente le statechart suivant:

Ceci est un exemple très simple qui démontre un agent pour le Statechart indiqué ci-dessus:
# include < so_5/all.hpp >
using namespace std ::literals ;
class blinking_led final : public so_5:: agent_t {
state_t off{ this }, blinking{ this },
blink_on{ initial_substate_of{ blinking } },
blink_off{ substate_of{ blinking } };
public :
struct turn_on_off : public so_5 :: signal_t {};
blinking_led ( context_t ctx) : so_5:: agent_t { std::move (ctx)} {
this >>= off;
off. just_switch_to <turn_on_off>(blinking);
blinking. just_switch_to <turn_on_off>(off);
blink_on
. on_enter ([]{ std::cout << " ON " << std::endl; })
. on_exit ([]{ std::cout << " off " << std::endl; })
. time_limit (1250ms, blink_off);
blink_off
. time_limit (750ms, blink_on);
}
};
int main ()
{
so_5::launch ([](so_5:: environment_t & env) {
so_5:: mbox_t m;
env. introduce_coop ([&](so_5:: coop_t & coop) {
auto led = coop. make_agent < blinking_led >();
m = led-> so_direct_mbox ();
});
const auto pause = []( auto duration) {
std::this_thread::sleep_for (duration);
};
std::cout << " Turn blinking on for 10s " << std::endl;
so_5::send<blinking_led::turn_on_off>(m);
pause (10s);
std::cout << " Turn blinking off for 5s " << std::endl;
so_5::send<blinking_led::turn_on_off>(m);
pause (5s);
std::cout << " Turn blinking on for 5s " << std::endl;
so_5::send<blinking_led::turn_on_off>(m);
pause (5s);
std::cout << " Stopping... " << std::endl;
env. stop ();
} );
return 0 ;
}Sobjectizer permet d'écrire des applications simultanées même sans agents à l'intérieur. Seuls les fils simples et les canaux de type CSP peuvent être utilisés.
Ceci est une implémentation à fil clair de l'exemple de ping-pong (veuillez noter que Main () n'est pas une exception envers):
# include < so_5/all.hpp >
struct ping {
int counter_;
};
struct pong {
int counter_;
};
void pinger_proc (so_5:: mchain_t self_ch, so_5:: mchain_t ping_ch) {
so_5::send<ping>(ping_ch, 1000 );
// Read all message until channel will be closed.
so_5::receive ( so_5::from (self_ch). handle_all (),
[&](so_5:: mhood_t <pong> cmd) {
if (cmd-> counter_ > 0 )
so_5::send<ping>(ping_ch, cmd-> counter_ - 1 );
else {
// Channels have to be closed to break `receive` calls.
so_5::close_drop_content (so_5::exceptions_enabled, self_ch);
so_5::close_drop_content (so_5::exceptions_enabled, ping_ch);
}
});
}
void ponger_proc (so_5:: mchain_t self_ch, so_5:: mchain_t pong_ch) {
int pings_received{};
// Read all message until channel will be closed.
so_5::receive ( so_5::from (self_ch). handle_all (),
[&](so_5:: mhood_t <ping> cmd) {
++pings_received;
so_5::send<pong>(pong_ch, cmd-> counter_ );
});
std::cout << " pings received: " << pings_received << std::endl;
}
int main () {
so_5:: wrapped_env_t sobj;
auto pinger_ch = so_5::create_mchain (sobj);
auto ponger_ch = so_5::create_mchain (sobj);
std::thread pinger{pinger_proc, pinger_ch, ponger_ch};
std::thread ponger{ponger_proc, ponger_ch, pinger_ch};
ponger. join ();
pinger. join ();
return 0 ;
}SobjectIzer fournit une fonction sélectionnée () similaire à l'instruction SELECT de Golang. Cette fonction permet d'attendre les messages entrants de plusieurs chaînes de messages. Il permet également d'attendre la préparation des chaînes de messages pour accepter un nouveau message sortant. SELECT () permet donc de faire des appels Send () Send () avec la gestion des messages entrants tandis que la chaîne de messages cible est pleine.
Il existe un exemple de calcul Fibonacci qui utilise SELECT () comme mécanisme de pression arrière (le thread de producteur de numéro attendra si le thread de lecteur de numéro ne lit pas encore le numéro précédent). Notez également que la fonction Main () dans cet exemple est une sécurité d'exception.
# include < so_5/all.hpp >
# include < chrono >
using namespace std ;
using namespace std ::chrono_literals ;
using namespace so_5 ;
struct quit {};
void fibonacci ( mchain_t values_ch, mchain_t quit_ch )
{
int x = 0 , y = 1 ;
mchain_select_result_t r;
do
{
r = select (
from_all (). handle_n ( 1 ),
// Sends a new message of type 'int' with value 'x' inside
// when values_ch is ready for a new outgoing message.
send_case ( values_ch, message_holder_t < int >:: make (x),
[&x, &y] { // This block of code will be called after the send().
auto old_x = x;
x = y; y = old_x + y;
} ),
// Receive a 'quit' message from quit_ch if it is here.
receive_case ( quit_ch, [](quit){} ) );
}
// Continue the loop while we send something and receive nothing.
while ( r. was_sent () && !r. was_handled () );
}
int main ()
{
wrapped_env_t sobj;
thread fibonacci_thr;
auto thr_joiner = auto_join ( fibonacci_thr );
// The chain for Fibonacci number will have limited capacity.
auto values_ch = create_mchain ( sobj, 1s, 1 ,
mchain_props:: memory_usage_t ::preallocated,
mchain_props:: overflow_reaction_t ::abort_app );
auto quit_ch = create_mchain ( sobj );
auto ch_closer = auto_close_drop_content ( values_ch, quit_ch );
fibonacci_thr = thread{ fibonacci, values_ch, quit_ch };
// Read the first 10 numbers from values_ch.
receive ( from ( values_ch ). handle_n ( 10 ),
// And show every number to the standard output.
[]( int v ) { cout << v << endl; } );
send< quit >( quit_ch );
}Plus d'informations sur Sobjectizer peuvent être trouvées dans la section correspondante du wiki du projet.
Il existe un projet compagnon distinct SO5Extra qui contient beaucoup de choses utiles diverses comme les répartiteurs basés sur ASIO, des types supplémentaires de Mbbox, une minuterie révocable, des demandes synchrones, etc.
Par exemple, il y a à quoi ressemble l'interaction synchrone (en utilisant so_5::extra::sync Stuff):
# include < so_5_extra/sync/pub.hpp >
# include < so_5/all.hpp >
// Short alias for convenience.
namespace sync_ns = so_5::extra::sync;
using namespace std ::chrono_literals ;
// The type of service provider.
class service_provider_t final : public so_5:: agent_t
{
public :
using so_5:: agent_t :: agent_t ;
void so_define_agent () override
{
so_subscribe_self (). event (
[]( sync_ns:: request_mhood_t < int , std::string> cmd ) {
// Transform the incoming value, convert the result
// to string and send the resulting string back.
cmd-> make_reply ( std::to_string (cmd-> request () * 2 ) );
} );
}
};
// The type of service consumer.
class consumer_t final : public so_5:: agent_t
{
// Message box of the service provider.
const so_5:: mbox_t m_service;
public :
consumer_t ( context_t ctx, so_5:: mbox_t service )
: so_5:: agent_t { std::move (ctx) }
, m_service{ std::move (service) }
{}
void so_evt_start () override
{
// Issue a request and wait for the result no more than 500ms.
auto result = sync_ns::request_reply< int , std::string>(
// The destination for the request.
m_service,
// Max waiting time.
500ms,
// Request's value.
4 );
std::cout << " The result: " << result << std::endl;
so_deregister_agent_coop_normally ();
}
};
int main ()
{
so_5::launch ( [](so_5:: environment_t & env) {
env. introduce_coop (
// Every agent should work on its own thread.
so_5::disp::active_obj::make_dispatcher ( env ). binder (),
[](so_5:: coop_t & coop) {
auto service_mbox = coop. make_agent < service_provider_t >()
-> so_direct_mbox ();
coop. make_agent < consumer_t >( service_mbox );
} );
} );
}Sobjectizer lui-même est destiné à être un projet relativement petit sans dépendances externes. SO5Extra n'a pas cette contrainte. C'est pourquoi les répartiteurs et les infrastructures environnementaux basés sur ASIO sont mis en œuvre dans SO5Extra, pas dans le sanglot.
Une autre propriété importante de Sobjectizer est la stabilité. Nous essayons de garder Sobjectizer aussi stable que possible, mais il est nécessaire d'essayer de nouvelles fonctionnalités, même si nous ne savons pas encore à quel point ils seront réussis et exigés. SO5Extra est un bon endroit pour expérimenter de nouvelles fonctionnalités, certaines pourraient être déplacées vers le Sobjectizer avec le temps.
Donc, si vous ne trouvez pas de fonctionnalité utile dans le Sobjectizer, essayons de regarder SO5Extra. Peut-être qu'il est déjà là.
Sobjectizer est un cadre de distribution de messages en cours. Il ne prend pas en charge les applications distribuées juste hors de la boîte. Mais les outils et les bibliothèques externes peuvent être utilisés dans ce cas. Veuillez jeter un œil à notre expérience Mosquitto_Transport: https://github.com/stiffstream/mosquitto_transport
Sobjectizer peut être vérifié à partir de GitHub. Les archives avec le code source de Sobjectizer peuvent être téléchargées à partir de GitHub ou de Sourceforge.
Il existe deux façons de construire un sanglot. Le premier en utilisant l'outil MXX_RU. Le second en utilisant cmake.
NOTE. Depuis V.5.5.15.2, il y a une prise en charge de la plate-forme Android. La construction pour Android est possible uniquement par CMake. Voir la section correspondante ci-dessous.
Sobjectizer peut également être installé et utilisé via les gestionnaires de dépendance VCPKG et Conan . Voir les sections appropriées ci-dessous.
La branche de 5,8 de Sobjectizer nécessite C ++ 17.
Si vous avez besoin d'une prise en charge de C ++ 14 ou C ++ 11, essayez de regarder les anciennes versions de Sobjectizer sur sourceforge. Ou contactez Stiffstream pour discuter du portage de Sobjectizer-5.8 aux normes C ++ plus anciennes.
NOTE. Il s'agit d'un moyen standard de construire Sobjectizer. Cette manière est utilisée dans le processus de développement de Sobjectizer.
Pour construire Sobjectizer, il est nécessaire d'utiliser Ruby Language et MXX_RU Tool. Installez Ruby puis installez MXX_RU via la commande RubyGems:
gem install Mxx_ruSi vous avez déjà installé MXX_RU, veuillez mettre à jour au moins la version 1.6.14.6:
gem update Mxx_ruSobjectizer peut être obtenu à partir du référentiel GIT sur GitHub:
git clone https://github.com/stiffstream/sobjectizerPour construire Sobjectizer:
cd sobjectizer/dev
ruby build.rbLa bibliothèque statique et partagée pour Sobjectizer sera construite. Les bibliothèques seront placées dans le sous-répertoire cible / version.
Si vous voulez créer une bibliothèque partagée:
cd sobjectizer/dev
ruby so_5/prj.rbOu si vous voulez créer une bibliothèque statique:
cd sobjectizer/dev
ruby so_5/prj_s.rbPour construire Sobjectizer avec tous les tests et échantillons:
cd sobjectizer/dev
ruby build_all.rbVeuillez noter que sous FreeBSD, il pourrait être nécessaire de définir la variable d'environnement LD_LIBRARY_PATH. Et la séquence de commande de construction réelle sous FreeBSD pourrait être la suivante:
cd sobjectizer/dev
export LD_LIBRARY_PATH=target/release
ruby build_all.rbPour construire une documentation HTML-format pour SOBjectizer, l'outil Doxygen est nécessaire. S'il est installé, alors:
cd sobjectizer/doxygen
doxygenLes fichiers HTML générés seront situés dans Sobjectizer / Dev / Doc / HTML.
NOTE. Si vous ne spécifiez pas MXX_RU_CPP_TOOLSET par vous-même, MXX_RU essaiera automatiquement de détecter votre ensemble d'outils C ++. Si vous souhaitez utiliser le compilateur C ++ qui n'est pas par défaut dans votre système, veuillez définir manuellement la variable d'environnement MXX_RU_CPP_TOOLSET. Cela pourrait ressembler:
export MXX_RU_CPP_TOOLSET= " clang_linux compiler_name=clang++-6 linker_name=clang++-6 "Plus d'informations sur le réglage MXX_RU pour vos besoins que vous pouvez trouver dans la documentation correspondante.
Pour construire Sobjectizer via CMake, il est nécessaire d'avoir CMake et une certaine connaissance de la façon de l'utiliser. L'action suivante n'est qu'une démonstration. Pour des informations plus détaillées sur le système de construction CMake pour Sobjectizer, voir Dev / Cmake / CMakequickHowto.txt
Pour obtenir et construire Sobjectizer sous Linux / FreeBSD dans la ligne de commande RUN:
git clone https://github.com/stiffstream/sobjectizer
cd sobjectizer
mkdir cmake_build
cd cmake_build
cmake -DCMAKE_INSTALL_PREFIX=target -DCMAKE_BUILD_TYPE=Release ../dev
cmake --build . --config Release
cmake --build . --config Release --target installCes commandes créeront tous les fichiers de make en make nécessaire, puis construisent Sobjectizer. S'il faut également créer des exemples et des tests, utilisez
cmake -DBUILD_ALL=ON -DCMAKE_INSTALL_PREFIX=target ../devLorsque «faire installer« fini »./target» contiendra deux sous-dossiers »./bin 'avec des échantillons et« ./lib »avec libso partagé.5.xxso
CMake Build System prend actuellement en charge ces options:
SOBJECTIZER_BUILD_STATIC . Activer la construction de sobjectizer en tant que bibliothèque statique [par défaut: ON]SOBJECTIZER_BUILD_SHARED . Activer la construction de sobjectizer en tant que bibliothèque partagée [par défaut: ON]BUILD_ALL . Activer les exemples de construction et les tests [par défaut: OFF]BUILD_EXAMPLES . Activer les exemples de construction [par défaut: OFF]BUILD_TESTS . Activer les tests de construction [par défaut: OFF] Veuillez noter que si BUILD_ALL ou BUILD_EXAMPLES ou BUILD_TESTS est activé, les deux SOBJECTIZER_BUILD_STATIC et SOBJECTIZER_BUILD_SHARED doivent être activés. Cela signifie que si SOBJECTIZER_BUILD_STATIC ou SOBJECTIZER_BUILD_SHARED est désactivé, alors BUILD_ALL / BUILD_EXAMPLES / BUILD_TESTS doit être désactivé.
Pour construire Sobjectizer sous Windows par MS Visual Studio 2013 à partir de la ligne de commande:
git clone https://github.com/stiffstream/sobjectizer
cd sobjectizer
mkdir cmake_build
cd cmake_build
cmake -DCMAKE_INSTALL_PREFIX=target -DCMAKE_BUILD_TYPE=Release -G " Visual Studio 15 2017 " ../dev
cmake --build . --config Release
cmake --build . --config Release --target install S'il faut également construire des exemples, utilisez BUILD_ALL dans Cmake Invocation:
cmake -DCMAKE_INSTALL_PREFIX=target -DCMAKE_BUILD_TYPE=Release -DBUILD_ALL=ON -G " Visual Studio 15 2017 " ../dev Étant donné que V.5.5.24 Sobjectizer fournit des fichiers Sobjectizer-Config.cmake. Ces fichiers sont automatiquement installés dans le sous-dossier <target>/lib/cmake/sobjectizer . Il permet d'utiliser Sobjectizer via la commande find_package de CMake.
Le bâtiment pour Android est possible via un Android NDK ou Crystax NDK assez frais.
Vous avez besoin d'Android SDK et Android NDK installés dans votre système. Ainsi qu'une version appropriée de CMake. Vous avez également besoin de définir correctement les variables d'environnement ANDROID_HOME , ANDROID_NDK . Ensuite, vous pouvez émettre les commandes suivantes:
git clone https://github.com/stiffstream/sobjectizer
cd sobjectizer
mkdir cmake_build
cd cmake_build
cmake -DBUILD_ALL -DCMAKE_INSTALL_PREFIX=target -DCMAKE_BUILD_TYPE=Release
-DCMAKE_TOOLCHAIN_FILE= ${ANDROID_NDK} /build/cmake/android.toolchain.cmake
-G Ninja
-DANDROID_ABI=arm64-v8a
-DANDROID_NDK= ${ANDROID_NDK}
-DANDROID_NATIVE_API_LEVEL=23
-DANDROID_TOOLCHAIN=clang
../dev
cmake --build . --config=Release
cmake --build . --config=Release --target installVous avez besoin de Crystax NDK V.10.4.0 ou plus déjà installée dans votre système. CMake est utilisé pour la construction de sanglots:
git clone https://github.com/stiffstream/sobjectizer
cd sobjectizer
mkdir cmake_build
cd cmake_build
export NDK=/path/to/the/crystax-ndk
cmake -DBUILD_ALL -DCMAKE_INSTALL_PREFIX=result -DCMAKE_TOOLCHAIN_FILE= $NDK /cmake/toolchain.cmake -DANDROID_ABI=arm64-v8a ../dev
make
make test
make installPour utiliser Sobjectizer via VCPKG, il est nécessaire de faire les étapes suivantes.
Installer le package sobjectizer :
vcpkg install sobjectizerAjoutez les lignes suivantes dans votre fichier cMakelists.txt:
find_package (sobjectizer CONFIG REQUIRED)
target_link_libraries (your_target sobjectizer::SharedLib) # or sobjectizer::StaticLibNOTE. Depuis février 2021, les nouvelles versions de Sobjectizer sont disponibles via Conan-Center uniquement.
Pour utiliser Sobjectizer via Conan, il est nécessaire d'ajouter Sobjectizer à conanfile.txt de votre projet:
[requires]
sobjectizer/5.8.0
Il peut également être nécessaire de spécifier l'option shared pour Sobjectizer. Par exemple, pour construire Sobjectizer en tant que bibliothèque statique:
[options]
sobjectizer:shared=False
Installez les dépendances de votre projet:
conan install SOME_PATH --build=missing
...
include ( ${CMAKE_BINARY_DIR} /conanbuildinfo.cmake)
conan_basic_setup()
...
target_link_libraries (your_target ${CONAN_LIBS} )Sobjectizer est distribué dans le cadre d'une licence BSD de 3 clause. Pour les informations de licence, veuillez consulter le fichier de licence.