Создан GH-MD-TOC
Sobjectizer-одна из нескольких кроссплатформенных и открытых «фреймворков актера» для C ++. Но Sobjectizer поддерживает не только модель актера, но и модель Publish-Subscribe и CSP-подобные каналы. Целью Sobjectizer является значительное упрощение разработки параллельных и многопоточных приложений в C ++.
Sobjectizer позволяет создавать одновременное приложение в качестве набора объектов агентов, которые взаимодействуют друг с другом через асинхронные сообщения. Он обрабатывает отправку сообщений и обеспечивает рабочий контекст для обработки сообщений. И позволяет настроить эти вещи, поставляя различных готовых диспетчеров.
Зрелость . Sobjectizer основан на идеях, которые были выдвинуты в 1995-2000 гг. И сам Sobjectizer разрабатывается с 2002 года. Sobjectizer-5 постоянно развивается с 2010 года.
Стабильность . С самого начала Sobjectizer использовался для критически важных приложений, и некоторые из них все еще используются в производстве. Разрушение изменений в Sobjectizer редко, и мы очень тщательно подходим к ним.
Кроссплатформенный . Sobjectizer работает на Windows, Linux, FreeBSD, MacOS и Android.
Простой в использовании . Sobjectizer предоставляет простые для понимания и простые в использовании API с множеством примеров в распределении Sobjectizer и большой информации в вики проекта.
Бесплатно . Sobjectizer распределяется по лицензии BSD-3-Clause, поэтому его можно бесплатно использовать для разработки проприетарного коммерческого программного обеспечения.
Sobjectizer часто сравнивается с такими инструментами, как строительные блоки Intel резьбы, задача, HPX и аналогичные им. Такое сравнение просто бесполезно.
Все эти инструменты предназначены для решения задач из области параллельных вычислений: они позволяют сократить время вычисления, используя несколько сердечников процессора. Например, вы можете переназначить свой видеофайл из одного формата в другой в течение одного часа на одном ядре процессора, на нем займет всего 15 минут на четыре ядра. Это главная цель параллельных вычислений.
Sobjectizer предназначен для немного другой области: одновременные вычисления. Основной целью Sobjectizer является упрощение выполнения множества различных задач одновременно. Иногда для этого нет необходимости использовать не только одно ядро процессора. Но если есть несколько сердечников процессора, то Sobjectizer делает обработку этих задач и взаимодействие между ними намного проще.
Сложной частью является тот факт, что параллельные и одновременные вычисления используют те же механизмы параллелизма и примитивы (такие как потоки, мутекс, атомика и т. Д.) Под капюшоном. Но с высокого уровня точки зрения параллельные и одновременные вычисления используются для очень разных задач.
В качестве примеров приложений, которые были или могли быть реализованы поверх Sobjectizer, мы можем перечислить многопоточный прокси-сервер, автоматическую систему управления, MQ-брокер, сервер базы данных и так далее.
Это классический пример «Привет, мир», выраженный с использованием агентов 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 ;
}Давайте посмотрим на более интересный пример с двумя агентами и обменом сообщениями между ними. Это еще один известный пример для фреймворков актера, "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 ;
}Все агенты в приведенном выше коде работают над одним и тем же рабочим потоком. Как связать их с различными рабочими потоками?
Это очень просто. Просто используйте соответствующий диспетчер:
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 поддерживает Pub/Sub Model через многопродуктивные/многопонаси. Сообщение, отправленное в это окно сообщения, будет получено всеми подписчиками этого типа сообщения:
# 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 ;
}Все агенты в Sobjectizer-это машины с конечным состоянием. Практически все функциональность иерархических машин с конечными состояниями (HSM) поддерживаются: унылые состояния и хендлеры, наследство, обработчики ON_ENTER/ON_EXIT, тайм-ауты штатов, история глубокого и мелкого состояния, кроме ортогональных состояний.
Посмотрим, как может выглядеть агент, который реализует следующий StateChart:

Это очень простой пример, который демонстрирует агент для StateChart, показанного выше:
# 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 позволяет писать одновременные приложения даже без агентов внутри. Можно использовать только простые нити и CSP-подобные каналы.
Это простая внедрение примера пинг-понга (обратите внимание, что main () не является исключительной защитой):
# 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 предоставляет функцию select (), которая аналогична оператору Select Golang. Эта функция позволяет ждать входящих сообщений из нескольких цепочек сообщений. Это также позволяет ждать готовности цепочек сообщений для принятия нового исходящего сообщения. Таким образом, Select () позволяет выполнять неблокирующие вызовы send () с обработкой входящих сообщений, в то время как целевая цепочка сообщений заполнена.
Существует пример вычисления Fibonacci, в котором используется Select () в качестве механизма обратного давления (поток производителя номеров будет ждать, если поток для чтения номеров еще не прочитал предыдущий номер). Обратите внимание также, что функция main () в этом примере безопасна для исключений.
# 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 );
}Более подробную информацию о Sobjectizer можно найти в соответствующем разделе вики проекта.
Существует отдельный сопутствующий проект SO5EXTRA, который содержит множество различных полезных вещей, таких как диспетчеры ASIO, дополнительные типы Mbobes, отзывенный таймер, синхронные запросы и многое другое.
Например, существует то, как выглядит синхронное взаимодействие (с помощью 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 предназначен для того, чтобы быть относительно небольшим проектом без внешних зависимостей. SO5Extra не имеет этого ограничения. Вот почему диспетчеры и инфраструктуры окружающей среды ASIO реализованы в SO5EXTRA, а не в Sobjectizer.
Другим значительным свойством Sobjectizer является стабильность. Мы стараемся держать Sobjectizer максимально стабильным, но есть необходимость попробовать некоторые новые функции, даже если мы еще не знаем, насколько они будут успешными и потребовавшими. SO5Extra - это хорошее место для экспериментов с новыми функциями, некоторые из них могут быть перемещены в Sobjectizer со временем.
Так что, если вы не найдете полезной функции в Sobjectizer, давайте попробуем посмотреть на SO5Extra. Может быть, это уже есть.
Sobjectizer-это структура отправки сообщений. Это не поддерживает распределенные приложения только вне коробки. Но в этом случае могут использоваться внешние инструменты и библиотеки. Посмотрите на наш эксперимент Mosquitto_transport: https://github.com/stiffstream/mosquitto_transport
Sobjectizer можно проверить из GitHub. Архивы с исходным кодом Sobjectizer можно загрузить из GitHub или из Sourceforge.
Есть два способа создания Sobjectizer. Первый, используя инструмент mxx_ru. Второй, используя Cmake.
ПРИМЕЧАНИЕ. Поскольку V.5.5.15.2 существует поддержка платформы Android. Строительство для Android возможно только от Cmake. См. Соответствующий раздел ниже.
Sobjectizer также может быть установлен и использован с помощью VCPKG и управляющих зависимостями VCPKG и CONAN . См. Подходящие разделы ниже.
5,8-й ветвь Sobjectizer требует C ++ 17.
Если вам нужна поддержка C ++ 14 или C ++ 11, попробуйте посмотреть на более старые версии Sobjectizer на Sourceforge. Или свяжитесь с StiftStream, чтобы обсудить портирование Sobjectizer-5.8 в более старые стандарты C ++.
ПРИМЕЧАНИЕ. Это стандартный способ для строительства Sobjectizer. Этот способ используется в процессе разработки Sobjectizer.
Для создания Sobjectizer необходимо использовать Ruby Language и инструмент MXX_RU. Установите Ruby, а затем установите mxx_ru с помощью команды Rubygems:
gem install Mxx_ruЕсли у вас уже установлен MXX_RU, обновите, по крайней мере, версию 1.6.14.6:
gem update Mxx_ruSobjectizer можно получить из GIT Repository на GitHub:
git clone https://github.com/stiffstream/sobjectizerЧтобы построить Sobjectizer:
cd sobjectizer/dev
ruby build.rbБудет построена статическая и общая библиотека для Sobjectizer. Библиотеки будут помещены в подкаталог для Target/Release.
Если вы хотите построить просто общую библиотеку:
cd sobjectizer/dev
ruby so_5/prj.rbИли если вы хотите построить только статическую библиотеку:
cd sobjectizer/dev
ruby so_5/prj_s.rbДля создания Sobjectizer со всеми тестами и образцами:
cd sobjectizer/dev
ruby build_all.rbОбратите внимание, что при FreeBSD может потребоваться определить переменную среды LD_LIBRARY_PATH. И фактическая последовательность команды сборки под FreeBSD может быть следующей:
cd sobjectizer/dev
export LD_LIBRARY_PATH=target/release
ruby build_all.rbДля создания документации HTML-формата для Sobjectizer необходим инструмент Doxygen. Если он установлен, тогда:
cd sobjectizer/doxygen
doxygenСгенерированные HTML-Files будут расположены в Sobjectizer/Dev/Doc/HTML.
ПРИМЕЧАНИЕ. Если вы не указаете MXX_RU_CPP_TOOLSET SY SWOR, то MXX_RU постарается автоматически обнаружить ваш набор инструментов C ++. Если вы хотите использовать компилятор C ++, который не является по умолчанию в вашей системе, пожалуйста, определите переменную среды MXX_RU_CPP_TOOLSET. Это может выглядеть как:
export MXX_RU_CPP_TOOLSET= " clang_linux compiler_name=clang++-6 linker_name=clang++-6 "Более подробная информация о настройке MXX_RU для ваших потребностей вы можете найти в соответствующей документации.
Для создания Sobjectizer через CMAKE необходимо иметь CMAKE и некоторые знания о том, как его использовать. Следующее действие - это просто демонстрация. Более подробную информацию о системе сборки Cmake для Sobjectizer см. Dev/Cmake/CmakeQuickhowto.txt.
Чтобы получить и построить Sobjectizer под Linux/FreeBSD в командной строке.
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 installЭти команды создадут все необходимые Makefile, а затем создаст Sobjectizer. Если необходимо создавать примеры и тесты, используйте
cmake -DBUILD_ALL=ON -DCMAKE_INSTALL_PREFIX=target ../devКогда «сделать установку».
Система сборки Cmake в настоящее время поддерживает эти варианты:
SOBJECTIZER_BUILD_STATIC . Включить здание Sobjectizer в качестве статической библиотеки [по умолчанию: ON]SOBJECTIZER_BUILD_SHARED . Включить здание Sobjectizer в качестве общей библиотеки [по умолчанию: ON]BUILD_ALL . Включить примеры и тесты строительства [по умолчанию: OFF]BUILD_EXAMPLES . Включить примеры строительства [по умолчанию: OFF]BUILD_TESTS . Включить строительные тесты [по умолчанию: OFF] Обратите внимание, что если BUILD_ALL или BUILD_EXAMPLES или BUILD_TESTS включены, то SOBJECTIZER_BUILD_STATIC и SOBJECTIZER_BUILD_SHARED должны быть включены. Это означает, что если SOBJECTIZER_BUILD_STATIC или SOBJECTIZER_BUILD_SHARED выключен, то BUILD_ALL / BUILD_EXAMPLES / BUILD_TESTS все должно быть отключено.
Для создания Sobjectizer в Windows от MS Visual Studio 2013 из командной строки:
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 Если необходимо также создавать примеры, используйте BUILD_ALL в Cmake Invocation:
cmake -DCMAKE_INSTALL_PREFIX=target -DCMAKE_BUILD_TYPE=Release -DBUILD_ALL=ON -G " Visual Studio 15 2017 " ../dev Поскольку v.5.5.24 Sobjectizer предоставляет файлы sobjectizer-config.cmake. Эти файлы автоматически устанавливаются в подпапку <target>/lib/cmake/sobjectizer . Он позволяет использовать Sobjectizer с помощью команды Cmake Find_Package.
Строительство для Android возможно через довольно свежий Android NDK или Crystax NDK.
Вам нужны установки Android SDK и Android NDK. А также подходящая версия Cmake. Вам также нужно правильно установить переменные среды ANDROID_HOME , ANDROID_NDK . Затем вы можете выпустить следующие команды:
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 installВам нужен Crystax NDK V.10.4.0 или выше, уже установленные в вашей системе. Cmake используется для строительства Sobjectizer:
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 installЧтобы использовать Sobjectizer через VCPKG, необходимо выполнить следующие шаги.
Установите пакет sobjectizer :
vcpkg install sobjectizerДобавьте следующие строки в свой файл cmakelists.txt:
find_package (sobjectizer CONFIG REQUIRED)
target_link_libraries (your_target sobjectizer::SharedLib) # or sobjectizer::StaticLibПРИМЕЧАНИЕ. Поскольку февраль 2021 года новые версии Sobjectizer доступны только через Conan-центр.
Чтобы использовать Sobjectizer через Conan, необходимо добавить Sobjectizer в conanfile.txt вашего проекта:
[requires]
sobjectizer/5.8.0
Также может быть необходимо указать shared вариант для Sobjectizer. Например, для строительства Sobjectizer в качестве статической библиотеки:
[options]
sobjectizer:shared=False
Установите зависимости для вашего проекта:
conan install SOME_PATH --build=missing
...
include ( ${CMAKE_BINARY_DIR} /conanbuildinfo.cmake)
conan_basic_setup()
...
target_link_libraries (your_target ${CONAN_LIBS} )Sobjectizer распределяется по лицензии BSD с 3 пунктами. Для получения информации, пожалуйста, см. Файл лицензии.