Erstellt von GH-MD-TOC
SOBJECTICER ist einer der wenigen plattformübergreifenden und OpenSource-Schauspieler-Frameworks für C ++. Sobjectizer unterstützt jedoch nicht nur das Schauspielermodell, sondern auch das Subscribe-Modell und die CSP-ähnlichen Kanäle. Das Ziel des Sobjektizers ist eine signifikante Vereinfachung der Entwicklung von gleichzeitigen und multithreadischen Anwendungen in C ++.
Sobjectizer ermöglicht die Erstellung einer gleichzeitigen App als Satz von Agenten-Objekten, die durch asynchrone Nachrichten miteinander interagieren. Es kümmert sich um das Versand von Nachrichten und bietet einen funktionierenden Kontext für die Nachrichtenverarbeitung. Und ermöglicht diese Dinge, indem Sie verschiedene konfrontierte Dispatcher liefern.
Reife . Sobjectizer basiert auf Ideen, die 1995-2000 vorgestellt wurden. Seit 2002 wird Sobjektizer selbst entwickelt. Sobjectizer-5 wird seit 2010 kontinuierlich entwickelt.
Stabilität . Von Anfang an wurde der Sobjektizer für geschäftskritische Anwendungen verwendet, und einige von ihnen werden immer noch in der Produktion verwendet. Das Brechen von Veränderungen des Sobjektizers ist selten und wir nähern uns sehr sorgfältig.
Plattformübergreifend . Sobjectizer läuft unter Windows, Linux, FreeBSD, MacOS und Android.
Benutzerfreundlich . Sobjectizer bietet leicht zu verstehen und einfach zu verwendende APIs mit vielen Beispielen in der Verteilung des Sobjektizers und zahlreiche Informationen im Wiki des Projekts.
Frei . Sobjectizer wird unter BSD-3-Klausel-Lizenz verteilt, sodass er kostenlos zur Entwicklung einer proprietären kommerziellen Software verwendet werden kann.
Sobjectizer wird häufig mit Werkzeugen wie Intel -Threading -Bausteinen, Taskflow, HPX und ähnlichem zu ihnen verglichen. Ein solcher Vergleich ist einfach nutzlos.
Alle diese Tools sollen zum Lösen von Aufgaben aus dem parallelen Rechenbereich verwendet werden: Sie ermöglichen die Reduzierung der Rechenzeit durch die Verwendung mehrerer CPU -Kerne. Sie können beispielsweise Ihre Videodatei innerhalb einer Stunde auf einem CPU -Kern von einem Format zum anderen neu einschränken, wobei Sie auf vier Kernen nur 15 Minuten dauern. Das ist das Hauptziel des parallelen Computers.
Sobjektizer ist für einen etwas anderen Bereich bestimmt: das gleichzeitige Computing. Das Hauptziel des Sobjektizers ist die Vereinfachung, viele verschiedene Aufgaben gleichzeitig zu erledigen. Manchmal muss nicht nur ein CPU -Kern dafür verwendet werden. Wenn es jedoch mehrere CPU -Kerne gibt, erleichtert Sobjectizer diese Aufgaben und die Interaktion zwischen ihnen viel einfacher.
Der knifflige Teil ist die Tatsache, dass parallel- und gleichzeitige Computing die gleichen Parallelitätsmechanismen und Primitiven (wie Fäden, Mutexes, Atomik usw.) unter der Motorhaube verwenden. Aus hochrangiger Sicht wird jedoch parallel und gleichzeitig für sehr unterschiedliche Aufgaben verwendet.
Als Beispiele für Anwendungen, die auf Sobjectizer implementiert wurden oder konnten, können wir Multithread-Proxy-Server, automatisches Steuerungssystem, MQ-Broker, Datenbankserver usw. auflisten.
Dies ist ein klassisches Beispiel "Hallo, Welt", das mit den Agenten von Sobjectizer ausgedrückt wird:
# 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 ;
}Schauen wir uns ein interessanteres Beispiel mit zwei Agenten und Nachrichtenaustausch zwischen ihnen an. Es ist ein weiteres berühmtes Beispiel für Schauspieler-Frameworks, "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 ;
}Alle Agenten im obigen Code arbeiten an demselben Arbeits -Thread. Wie binden Sie sie an verschiedene Arbeitsfäden?
Es ist sehr einfach. Verwenden Sie einfach einen geeigneten Dispatcher:
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 unterstützt Pub/Sub-Modell über Multi-Produzent/Multi-Consumer-Nachrichtenboxen. Eine an dieses Nachrichtenfeld gesendete Nachricht wird von allen Abonnenten dieses Nachrichtentyps empfangen:
# 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 ;
}Alle Agenten im Sobjektizer sind Finite-State-Maschinen. Fast alle Funktionen hierarchischer Finite-State-Maschinen (HSM) werden unterstützt: Kinderzustände und Handler Erbe, On_enter/On_exit-Handler, staatliche Auszeiten, tief- und flache Zustandsgeschichte mit Ausnahme orthogonaler Zustände.
Lassen Sie uns sehen, wie ein Agent, der das folgende StatechArt implementiert, aussehen kann:

Dies ist ein sehr einfaches Beispiel, das einen Agenten für den oben gezeigten StateChart demonstriert:
# 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 ;
}Mit Sobjectizer können gleichzeitige Anwendungen auch ohne Agenten im Inneren geschrieben werden. Es können nur einfache Fäden und CSP-ähnliche Kanäle verwendet werden.
Dies ist eine einfache Thread-Implementierung von Ping-Pong-Beispiel (bitte beachten Sie, dass main () keine Ausnahmesicherheit ist):
# 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 bietet eine Select () -Funktion, die der SELECT -Anweisung von Golang ähnelt. Diese Funktion ermöglicht das Warten auf eingehende Nachrichten von mehreren Nachrichtenketten. Es ermöglicht auch, auf die Bereitschaft von Nachrichtenketten zu warten, um eine neue ausgehende Nachricht zu akzeptieren. Select () ermöglicht es, nicht blockierende send () -Anrufe mit dem Umgang mit eingehenden Nachrichten durchzuführen, während die Zielmeldungskette voll ist.
Es gibt ein Fibonacci-Berechnungsbeispiel, das Select () als Rückdruckmechanismus verwendet (Zahlenerzeuger-Thread wartet, wenn der Nummernleser-Thread die vorherige Nummer noch nicht liest). Beachten Sie auch, dass Main () -Funktion in diesem Beispiel ausnahmssicher ist.
# 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 );
}Weitere Informationen zum Sobjektizer finden Sie im entsprechenden Abschnitt des Projekts des Projekts.
Es gibt ein separates Begleitprojekt SO5EXTRA, das viele verschiedene nützliche Dinge wie die basierten Dispatcher von ASIO, zusätzliche Arten von Mboxen, widerruflichen Timer, synchrone Anfragen und vieles mehr enthält.
Zum Beispiel gibt es, wie die synchrone Interaktion aussieht (indem sie so_5::extra::sync ):
# 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 selbst soll ein relativ kleines Projekt ohne externe Abhängigkeiten sein. SO5EXTRA hat diese Einschränkung nicht. Aus diesem Grund werden die basierten Dispatcher und Umweltinfrastrukturen von ASIO in SO5EXTRA implementiert, nicht im SOBJECTION.
Eine weitere signifikante Eigenschaft des Sobjektizers ist die Stabilität. Wir versuchen, den Sobjektizer so stabil wie möglich zu halten, aber es besteht die Notwendigkeit, einige neue Funktionen auszuprobieren, auch wenn wir noch nicht wissen, wie erfolgreich und verlangt sie sein werden. SO5EXTRA ist ein guter Ort, um mit neuen Funktionen zu experimentieren. Einige von ihnen könnten mit der Zeit in den Sobjektisator verschoben werden.
Wenn Sie also keine hilfreiche Funktion im Sobjektizer finden, versuchen wir, SO5Extra zu betrachten. Vielleicht ist es schon da.
Sobjectizer ist ein In-Process-Nachrichten-Versand-Framework. Es unterstützt keine verteilten Anwendungen, nur aus dem Kasten. In diesem Fall können jedoch externe Werkzeuge und Bibliotheken verwendet werden. Bitte werfen Sie einen Blick auf unser Mosquitto_Transport -Experiment: https://github.com/stiffstream/mosquitto_transport
SOBJECTICER kann aus GitHub ausgecheckt werden. Archive mit Sobjectizer Quellcode können von GitHub oder SourceForge heruntergeladen werden.
Es gibt zwei Möglichkeiten zum Aufbau von Sobjektizern. Das erste mit mxx_ru -Tool. Die zweite mit CMake.
NOTIZ. Da V.5.5.15.2 eine Unterstützung der Android -Plattform unterstützt. Das Gebäude für Android ist nur durch CMake möglich. Siehe den entsprechenden Abschnitt unten.
Sobjectizer kann auch über VCPKG- und Conan -Abhängigkeitsmanager installiert und verwendet werden. Siehe die entsprechenden Abschnitte unten.
Die 5,8-Branch des Sobjektizers benötigt C ++ 17.
Wenn Sie Unterstützung für C ++ 14 oder C ++ 11 benötigen, versuchen Sie, auf ältere Versionen von Sobjectizer auf SourceForge zu suchen. Oder Kontakt mit Steifstream, um die Portierung von Sobjectizer-5.8 nach älteren C ++-Standards zu erörtern.
NOTIZ. Dies ist eine Standardmethode zum Aufbau von Sobjektizer. Dieser Weg wird im Sobjektizerentwicklungsprozess verwendet.
Zum Aufbau von SOBJECTICS ist es erforderlich, Ruby Language und MXX_RU Tool zu verwenden. Installieren Sie Ruby und installieren Sie dann mxx_ru über den Befehl Rubygemems:
gem install Mxx_ruWenn Sie bereits mxx_ru installiert haben, aktualisieren Sie bitte mindestens Version 1.6.14.6:
gem update Mxx_ruSobjectizer kann vom Git -Repository auf GitHub erhalten werden:
git clone https://github.com/stiffstream/sobjectizerSOBJECTIONS aufbauen:
cd sobjectizer/dev
ruby build.rbEs wird eine statische und gemeinsame Bibliothek für SOBJECTICS erstellt. Bibliotheken werden in das Ziel-/Release -Unterverzeichnis eingesetzt.
Wenn Sie nur gemeinsame Bibliothek erstellen möchten:
cd sobjectizer/dev
ruby so_5/prj.rbOder wenn Sie nur eine statische Bibliothek erstellen möchten:
cd sobjectizer/dev
ruby so_5/prj_s.rbSoBjektizer mit allen Tests und Proben aufbauen:
cd sobjectizer/dev
ruby build_all.rbBitte beachten Sie, dass es unter FreeBSD erforderlich sein könnte, LD_LIBRARY_PATH -Umgebungsvariable zu definieren. Und die tatsächliche Build -Befehlssequenz unter FreeBSD könnte wie folgt sein:
cd sobjectizer/dev
export LD_LIBRARY_PATH=target/release
ruby build_all.rbSo erstellen Sie die HTML-Format-Dokumentation für SOBJECTICER, das Doxygen-Tool ist erforderlich. Wenn es installiert ist, dann:
cd sobjectizer/doxygen
doxygenGenerierte HTML-Files finden Sie in Sobjectizer/Dev/Doc/HTML.
NOTIZ. Wenn Sie MXX_RU_CPP_TOOLSET für Sie nicht angeben, versucht MXX_RU, Ihr C ++ TOOLSET automatisch zu erkennen. Wenn Sie den C ++ - Compiler verwenden möchten, der nicht in Ihrem System standardmäßig standardmäßig ist, definieren Sie bitte die Umgebungsvariable mxx_ru_cpp_toolset manuell. Es könnte aussehen wie:
export MXX_RU_CPP_TOOLSET= " clang_linux compiler_name=clang++-6 linker_name=clang++-6 "Weitere Informationen zum Tuning mxx_ru für Ihre Anforderungen finden Sie in der entsprechenden Dokumentation.
Um einen Sobjektizer über CMAKE zu erstellen, ist es erforderlich, CMAKE und einige Kenntnisse darüber zu haben, wie man ihn benutzt. Die folgende Aktion ist nur eine Demonstration. Weitere Informationen zum CMake -Build -System für SOBJECTICER finden Sie unter dev/cmake/cmakequickhowto.txt
Sobjectizer unter Linux/FreeBSD im Befehlszeilenlauf zu erhalten und zu erstellen:
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 installDiese Befehle erzeugen alle notwendigen Makefile und erstellen dann den Sobjektizer. Wenn auch Beispiele und Tests erstellt werden müssen, verwenden Sie auch
cmake -DBUILD_ALL=ON -DCMAKE_INSTALL_PREFIX=target ../devWenn 'Installation' fertig './target' 'enthält zwei Unterordner' ./bin 'mit Proben und' ./lib 'mit Shared libso.5.xxso
Das CMake Build -System unterstützt derzeit diese Optionen:
SOBJECTIZER_BUILD_STATIC . Aktivieren Sie den Sobjektizer als statische Bibliothek auf [Standard: auf]SOBJECTIZER_BUILD_SHARED . Aktivieren Sie den SOBJECTISKER als gemeinsame Bibliothek auf [Standard: eins]BUILD_ALL . Aktivieren Sie Beispiele und Tests für das Erstellen von Bauen [Standard: Aus]BUILD_EXAMPLES . Aktivieren Sie das Erstellen von Beispielen [Standard: Aus]BUILD_TESTS . Aktivieren Sie das Erstellen von Tests [Standard: Aus] Bitte beachten Sie, dass, wenn BUILD_ALL oder BUILD_EXAMPLES oder BUILD_TESTS eingeschaltet ist, sowohl SOBJECTIZER_BUILD_STATIC UND SOBJECTIZER_BUILD_SHARED eingeschaltet werden müssen. Dies bedeutet, dass, wenn SOBJECTIZER_BUILD_STATIC oder SOBJECTIZER_BUILD_SHARED ausgeschaltet wird, BUILD_ALL / BUILD_EXAMPLES / BUILD_TESTS alle ausgeschaltet werden müssen.
So erstellen Sie Sobjectizer unter Windows von MS Visual Studio 2013 aus der Befehlszeile:
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 Wenn auch Beispiele erstellt werden müssen, verwenden Sie BUILD_ALL im CMAKE -Aufruf:
cmake -DCMAKE_INSTALL_PREFIX=target -DCMAKE_BUILD_TYPE=Release -DBUILD_ALL=ON -G " Visual Studio 15 2017 " ../dev Da V.5.5.24 SOBJECTICER SOBJECTICER-CONFIG.CMAKE-Dateien bereitstellt. Diese Dateien werden automatisch in <target>/lib/cmake/sobjectizer -Unterordner installiert. Es ermöglicht die Verwendung von SOBJECTICER über den Befehl find_package über den CMAKE.
Das Gebäude für Android ist über einen eher frischen Android -NDK oder Crystax NDK möglich.
Sie benötigen Android SDK und Android NDK in Ihrem System installiert. Sowie eine geeignete Version von CMake. Sie benötigen auch ordnungsgemäße Umgebungsvariablen ANDROID_HOME , ANDROID_NDK . Dann können Sie die folgenden Befehle ausstellen:
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 installSie benötigen Crystax NDK V.10.4.0 oder höher bereits in Ihrem System installiert. CMAKE wird zum Erstellen von SOBJECTISIKER verwendet:
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 installUm SOBJECTICER über VCPKG zu verwenden, müssen die folgenden Schritte durchgeführt werden.
Installieren Sie sobjectizer -Paket:
vcpkg install sobjectizerFügen Sie die folgenden Zeilen in Ihre cmakelists.txt -Datei hinzu:
find_package (sobjectizer CONFIG REQUIRED)
target_link_libraries (your_target sobjectizer::SharedLib) # or sobjectizer::StaticLibNOTIZ. Seit Februar 2021 sind neue Versionen von Sobjectizer nur über Conan-Center erhältlich.
Um SOBJECTICER über Conan zu verwenden, muss conanfile.txt Ihres Projekts SOBJECTICER hinzufügen:
[requires]
sobjectizer/5.8.0
Es kann auch erforderlich sein, dass die shared Option für SOBJECIZER angeben wird. Zum Beispiel zum Erstellen von Sobjektizer als statische Bibliothek:
[options]
sobjectizer:shared=False
Installieren Sie Abhängigkeiten für Ihr Projekt:
conan install SOME_PATH --build=missing
...
include ( ${CMAKE_BINARY_DIR} /conanbuildinfo.cmake)
conan_basic_setup()
...
target_link_libraries (your_target ${CONAN_LIBS} )Sobjectizer ist unter 3-Klausel-BSD-Lizenz verteilt. Lizenzinformationen finden Sie unter Lizenzdatei.