สร้างโดย GH-MD-TOC
Sobjectizer เป็นหนึ่งในสองสามแพลตฟอร์มและ OpenSource "กรอบนักแสดง" สำหรับ C ++ แต่ Sobjectizer ไม่เพียง แต่รองรับโมเดลนักแสดงเท่านั้น แต่ยังต้องเผยแพร่โมเดลโมเดลและช่องทาง CSP เป้าหมายของ sobjectizer คือการทำให้ง่ายขึ้นอย่างมีนัยสำคัญของการพัฒนาแอปพลิเคชันที่เกิดขึ้นพร้อมกันและแบบมัลติเธรดใน C ++
Sobjectizer ช่วยให้สามารถสร้างแอพที่เกิดขึ้นพร้อมกันเป็นชุดของ Agent-Bjects ที่มีปฏิสัมพันธ์ซึ่งกันและกันผ่านข้อความแบบอะซิงโครนัส มันจัดการการส่งข้อความและจัดทำบริบทการทำงานสำหรับการประมวลผลข้อความ และอนุญาตให้ปรับแต่งสิ่งเหล่านั้นโดยการจัดหาผู้ส่งพร้อมที่จะใช้งานต่างๆ
วุฒิภาวะ Sobjectizer ขึ้นอยู่กับแนวคิดที่ได้รับการหยิบยกในปี 1995-2000 และ Sobjectizer นั้นได้รับการพัฒนามาตั้งแต่ปี 2545 Sobjectizer-5 ได้รับการพัฒนาอย่างต่อเนื่องตั้งแต่ปี 2010
ความมั่นคง จากจุดเริ่มต้นของ sobjectizer ถูกใช้สำหรับแอปพลิเคชันที่สำคัญทางธุรกิจและบางส่วนยังคงถูกใช้ในการผลิต การเปลี่ยนแปลงการเปลี่ยนแปลงใน sobjectizer นั้นหายากและเราเข้าใกล้พวกเขาอย่างระมัดระวัง
ข้ามแพลตฟอร์ม Sobjectizer ทำงานบน Windows, Linux, FreeBSD, MacOS และ Android
ใช้งานง่าย Sobjectizer ให้ API ที่เข้าใจง่ายและใช้งานง่ายพร้อมตัวอย่างมากมายในการกระจายของ Sobjectizer และข้อมูลมากมายในวิกิของโครงการ
ฟรี . Sobjectizer จัดจำหน่ายภายใต้ใบอนุญาต BSD-3-clause ดังนั้นจึงสามารถใช้ในการพัฒนาซอฟต์แวร์เชิงพาณิชย์ที่เป็นกรรมสิทธิ์ได้ฟรี
Sobjectizer มักจะถูกนำมาเปรียบเทียบกับเครื่องมือเช่น Intel Threading Building Block, Testflow, HPX และคล้ายกับพวกเขา การเปรียบเทียบดังกล่าวไม่มีประโยชน์
เครื่องมือทั้งหมดเหล่านั้นมีวัตถุประสงค์เพื่อใช้ในการแก้ปัญหาจากพื้นที่คอมพิวเตอร์แบบขนาน: พวกเขาอนุญาตให้ลดเวลาในการคำนวณโดยใช้คอร์ CPU หลายตัว ตัวอย่างเช่นคุณสามารถ reencode ไฟล์วิดีโอของคุณจากรูปแบบหนึ่งไปยังอีกรูปแบบหนึ่งภายในหนึ่งชั่วโมงในหนึ่ง CPU Core โดยใช้เวลาเพียง 15 นาทีในสี่คอร์ นั่นคือเป้าหมายหลักของการคำนวณแบบขนาน
Sobjectizer มีไว้สำหรับพื้นที่ที่แตกต่างกันเล็กน้อย: การคำนวณพร้อมกัน เป้าหมายหลักของ sobjectizer คือการทำให้เข้าใจง่ายขึ้นในการทำงานที่แตกต่างกันมากมายในครั้งเดียว บางครั้งไม่จำเป็นต้องใช้มากกว่าหนึ่ง CPU Core สำหรับสิ่งนั้น แต่ถ้ามีคอร์ CPU หลายตัว Sobjectizer ทำให้การจัดการงานเหล่านั้นและการมีปฏิสัมพันธ์ระหว่างพวกเขาง่ายขึ้นมาก
ส่วนที่ยุ่งยากคือความจริงที่ว่าการคำนวณแบบขนานและพร้อมกันใช้กลไกการทำงานร่วมกันและดั้งเดิม (เช่นเธรด, mutexes, atomics และอื่น ๆ ) ภายใต้ประทุน แต่จากมุมมองระดับสูงของมุมมองแบบขนานและการคำนวณพร้อมกันใช้สำหรับงานที่แตกต่างกันมาก
เป็นตัวอย่างของแอปพลิเคชันที่สามารถนำไปใช้กับ Sobjectizer ได้เราสามารถแสดงรายการพร็อกซีมัลติเธรด, ระบบควบคุมอัตโนมัติ, MQ-Broker, ฐานข้อมูลเซิร์ฟเวอร์และอื่น ๆ
นี่เป็นตัวอย่างคลาสสิก "Hello, World" ที่แสดงออกโดยใช้ตัวแทนของ 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 ;
}ตัวแทนทั้งหมดในรหัสด้านบนทำงานกับเธรดงานเดียวกัน จะผูกมัดพวกเขากับเธรดการทำงานที่แตกต่างกันได้อย่างไร?
มันง่ายมาก เพียงแค่ใช้ 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 รองรับ 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 handlers, การหมดเวลาของรัฐ, ประวัติศาสตร์ของรัฐลึกและตื้นยกเว้นรัฐ orthogonal
มาดูกันว่าเอเจนต์ที่ใช้ 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 ฟังก์ชั่นนี้อนุญาตให้รอข้อความขาเข้าจากห่วงโซ่ข้อความหลายรายการ นอกจากนี้ยังช่วยให้รอความพร้อมของห่วงโซ่ข้อความเพื่อรับข้อความขาออกใหม่ ดังนั้นเลือก () อนุญาตให้ทำการโทรที่ไม่ปิดกั้น () การโทรด้วยการจัดการข้อความขาเข้าในขณะที่ห่วงโซ่ข้อความเป้าหมายเต็ม
มีตัวอย่างการคำนวณ 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 ที่มีสิ่งที่มีประโยชน์มากมายเช่น dispatchers ตาม ASIO ของ ASIO, ประเภทของ mboxes เพิ่มเติม, ตัวจับเวลาที่เพิกถอนได้การร้องขอแบบซิงโครนัสและอื่น ๆ
ตัวอย่างเช่นมีการโต้ตอบแบบซิงโครนัสอย่างไร (โดยใช้ 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 ไม่มีข้อ จำกัด นี้ นั่นคือเหตุผลที่ dispatchers และโครงสร้างพื้นฐานด้านสิ่งแวดล้อมของ 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 และผู้จัดการการพึ่งพา Conan ดูส่วนที่เหมาะสมด้านล่าง
5.8-branch of sobjectizer ต้องใช้ C ++ 17
หากคุณต้องการการสนับสนุนสำหรับ C ++ 14 หรือ C ++ 11 ลองดู Sobjectizer รุ่นเก่าบน SourceForge หรือติดต่อ Stiffstream เพื่อหารือเกี่ยวกับการพอร์ตของ Sobjectizer-5.8 กับมาตรฐาน C ++ ที่เก่ากว่า
บันทึก. นี่เป็นวิธีมาตรฐานสำหรับการสร้าง sobjectizer วิธีนี้ใช้ในกระบวนการพัฒนา sobjectizer
ในการสร้าง sobjectizer จำเป็นต้องใช้ภาษาทับทิมและเครื่องมือ mxx_ru ติดตั้งทับทิมแล้วติดตั้ง mxx_ru ผ่านคำสั่ง Rubygems:
gem install Mxx_ruหากคุณติดตั้ง MXX_RU อยู่แล้วโปรดอัปเดตเป็นอย่างน้อยเวอร์ชัน 1.6.14.6:
gem update Mxx_ruSobjectizer สามารถรับได้จากที่เก็บ Git บน GitHub:
git clone https://github.com/stiffstream/sobjectizerเพื่อสร้าง sobjectizer:
cd sobjectizer/dev
ruby build.rbห้องสมุดคงที่และแบ่งปันสำหรับ sobjectizer จะถูกสร้างขึ้น ไลบรารีจะถูกวางลงในไดเรกทอรีย่อย/รีลีส
หากคุณต้องการสร้างห้องสมุดที่ใช้ร่วมกัน:
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 และลำดับคำสั่ง build ที่แท้จริงภายใต้ FreeBSD อาจเป็นดังนี้:
cd sobjectizer/dev
export LD_LIBRARY_PATH=target/release
ruby build_all.rbในการสร้างเอกสารประกอบ HTML-Format สำหรับ sobjectizer เครื่องมือ doxygen เป็นสิ่งจำเป็น หากติดตั้งแล้ว:
cd sobjectizer/doxygen
doxygenHTML-files ที่สร้างขึ้นจะอยู่ใน sobjectizer/dev/doc/html
บันทึก. หากคุณไม่ได้ระบุ MXX_RU_CPP_TOOLSET ด้วยตัวคุณเอง 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เมื่อ 'ติดตั้ง' เสร็จสิ้น './target' จะมีสองโฟลเดอร์ย่อย './bin' พร้อมตัวอย่างและ './lib' กับ libso.5.xxso ที่ใช้ร่วมกัน
ปัจจุบันระบบ CMake Build รองรับตัวเลือกนี้:
SOBJECTIZER_BUILD_STATIC เปิดใช้งานการสร้าง sobjectizer เป็นไลบรารีคงที่ [ค่าเริ่มต้น: เปิด]SOBJECTIZER_BUILD_SHARED เปิดใช้งานการสร้าง sobjectizer เป็นไลบรารีที่ใช้ร่วมกัน [ค่าเริ่มต้น: เปิด]BUILD_ALL เปิดใช้งานการสร้างตัวอย่างและการทดสอบ [ค่าเริ่มต้น: ปิด]BUILD_EXAMPLES เปิดใช้งานตัวอย่างการสร้าง [ค่าเริ่มต้น: ปิด]BUILD_TESTS เปิดใช้งานการทดสอบการสร้าง [ค่าเริ่มต้น: ปิด] โปรดทราบว่าหากเปิด 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 ผ่านคำสั่ง find_package ของ CMake
การสร้างสำหรับ 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 ตัวอย่างเช่นสำหรับ build 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 ข้อ สำหรับข้อมูลใบอนุญาตโปรดดูไฟล์ใบอนุญาต