tag:crieit.net,2005:https://crieit.net/tags/Cerflet/feed 「Cerflet」の記事 - Crieit Crieitでタグ「Cerflet」に投稿された最近の記事 2019-06-06T08:03:20+09:00 https://crieit.net/tags/Cerflet/feed tag:crieit.net,2005:PublicArticle/15024 2019-05-25T13:19:11+09:00 2019-06-06T08:03:20+09:00 https://crieit.net/posts/POCO-static-link POCO を static に link する <h1 id="結論"><a href="#%E7%B5%90%E8%AB%96">結論</a></h1> <pre><code class="bash:">-Wl,--start-group -Wl,-Bstatic -lPocoFoundation -lPocoUtil -lPocoXML -lPocoJSON -lPocoNet -Wl,--end-group -Wl,-Bdynamic -lpthread </code></pre> <p>今世のリンカオプションには <code>--start-group, --end-group</code> なんて便利なものがあるんですね</p> <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p><a href="https://crieit.net/posts/C-Cerflet">Cerflet</a> ベースの WebApplication を deploy しようとして、POCO に依存してしまうのもアレだなと思い、だったら static に link してしまおうと思ったのが事の発端です</p> <h2 id="POCO の static library を make"><a href="#POCO+%E3%81%AE+static+library+%E3%82%92+make">POCO の static library を make</a></h2> <p>POCO の configure の <a target="_blank" rel="nofollow noopener" href="https://github.com/pocoproject/poco/blob/develop/configure#L117">--static</a> オプションを使って make します</p> <pre><code class="bash:">./configure --static make </code></pre> <p>はじめは shared library 作る時と同じで <code>make -j4</code> ってやってたんですけどリンクエラーがでるので、多分、static に link してるから順番とかが影響してるんだろうなと深く考えずに <code>make</code> にしたらでなくなりました<br /> こんな些細なところからすでにlink する時の嫌な事が始まってます ^^;;;</p> <h2 id="しっかりハマる"><a href="#%E3%81%97%E3%81%A3%E3%81%8B%E3%82%8A%E3%83%8F%E3%83%9E%E3%82%8B">しっかりハマる</a></h2> <p>マジメな C++ プログラマだった頃の辛い思い出が蘇ってきます...</p> <h3 id="pthread がない"><a href="#pthread+%E3%81%8C%E3%81%AA%E3%81%84">pthread がない</a></h3> <p>dynamic に link した時と同じ感覚で素朴に lPocoFoundation をリンクしようとしたのですが</p> <pre><code class="bash:">g++ -o hellocerflet_s HelloCerflet.cpp ../lib/httpcerflet.cpp -I../lib/ -L/usr/local/lib -lPocoFoundation -static Thread.cpp:(.text+0x1ec): undefined reference to `pthread_setspecific' Thread.cpp:(.text+0x228): undefined reference to `pthread_sigmask' Thread.cpp:(.text+0x30c): undefined reference to `pthread_mutex_lock' Thread.cpp:(.text+0x328): undefined reference to `pthread_cond_broadcast' Thread.cpp:(.text+0x338): undefined reference to `pthread_mutex_unlock' ... </code></pre> <p>-lpthread つけてやらないといけないんですね</p> <h3 id="Poco 自身の依存関係"><a href="#Poco+%E8%87%AA%E8%BA%AB%E3%81%AE%E4%BE%9D%E5%AD%98%E9%96%A2%E4%BF%82">Poco 自身の依存関係</a></h3> <p>で、-lpthread つけてあげたんですが</p> <pre><code class="bash:">g++ -o hellocerflet_s HelloCerflet.cpp ../lib/httpcerflet.cpp -I../lib/ -L/usr/local/lib -lPocoFoundation -static -lpthread httpcerflet.cpp:(.text+0x54): undefined reference to `Poco::Util::Application::loadConfiguration(int)' httpcerflet.cpp:(.text+0x64): undefined reference to `Poco::Util::Application::initialize(Poco::Util::Application&)' /tmp/ccZExLN3.o: In function `HttpCerflet::uninitialize()': httpcerflet.cpp:(.text+0x8c): undefined reference to `Poco::Util::Application::uninitialize()' ... </code></pre> <p>あ、static link だから lPocoFoundation が依存する Poco のライブラリも先にリンクしておいてあげないと...</p> <h3 id="link の順番"><a href="#link+%E3%81%AE%E9%A0%86%E7%95%AA">link の順番</a></h3> <p>で、undefined だって言われる Poco のライブラリをどんどん前に追加しているのに、まだ undefined が...</p> <pre><code class="bash:">g++ -o hellocerflet_s HelloCerflet.cpp ../lib/httpcerflet.cpp -I../lib/ -L/usr/local/lib -lPocoXML -lPocoJSON -lPocoUtil -lPocoNet -lPocoFoundation -static -lpthread ... JSONConfiguration.cpp:(.text+0x6a0): undefined reference to `Poco::JSON::Query::~Query()' ... XMLConfiguration.cpp:(.text+0x1cc): undefined reference to `Poco::XML::Document::documentElement() const' </code></pre> <p>ちゃんと -lPocoXML も -lPocoJSON も link してるのになんで undefined なんて言われるんだろ?<br /> このあたりでもう考えるのが嫌になって POCO static link とかでググるとそのものズバリなのが<br /> <a target="_blank" rel="nofollow noopener" href="https://kotaeta.com/55682155">定義されていないシンボルへのPoco C++ 静的リンクの問題</a></p> <p>そうだ、<strong>リンクの順番!使われる前にリンクしておかないといけない</strong>んでした</p> <h3 id="glibc の静的リンク"><a href="#glibc+%E3%81%AE%E9%9D%99%E7%9A%84%E3%83%AA%E3%83%B3%E3%82%AF">glibc の静的リンク</a></h3> <p>POCO内部の依存関係に合わせて正しい順番でリンクすると</p> <pre><code>g++ -o hellocerflet_s HelloCerflet.cpp ../lib/httpcerflet.cpp -I../lib/ -L/usr/local/lib -lPocoUtil -lPocoXML -lPocoJSON -lPocoNet -lPocoFoundation -static -lpthread /usr/local/lib/libPocoFoundation.a(Path.o): In function `Poco::PathImpl::homeImpl[abi:cxx11]()': Path.cpp:(.text+0x220): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking </code></pre> <p>glibc まで static にリンクしようとしてました ^^;;;</p> <h3 id="第一次正解"><a href="#%E7%AC%AC%E4%B8%80%E6%AC%A1%E6%AD%A3%E8%A7%A3">第一次正解</a></h3> <p>なので、pthread だけは dynamic に link するようにして</p> <pre><code class="bash">g++ -o hellocerflet_s HelloCerflet.cpp ../lib/httpcerflet.cpp -I../lib/ -L/usr/local/lib -Wl,-Bstatic -lPocoUtil -Wl,-Bstatic -lPocoXML -Wl,-Bstatic -lPocoJSON -Wl,-Bstatic -lPocoNet -Wl,-Bstatic -lPocoFoundation -Wl,-Bdynamic -lpthread </code></pre> <p>やっとできました</p> <h1 id="ちょっと考察"><a href="#%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E8%80%83%E5%AF%9F">ちょっと考察</a></h1> <p>しかし今どきリンクの順番みたいな機械的に解決できることに人間が頭を使わないといけないのってちょっと残念ですよね、人って機械的な作業が苦手なクリエイティブなクリーチャーなのに</p> <p>でも、さすがになにか進歩してるんじゃないかとおもって static link order とかでググりまくってると <a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc">Why does the order in which libraries are linked sometimes cause errors in GCC?</a><br /> やっぱり人類は賢かった!<strong>--start-group, --end-group</strong> なんてリンカのオプションをつくってくれた人がいて、この中だと順番気にしなくてもリンカがよしなにやってくれるんですね!</p> <p>で、本稿の結論にいたります</p> <h2 id="再度、結論"><a href="#%E5%86%8D%E5%BA%A6%E3%80%81%E7%B5%90%E8%AB%96">再度、結論</a></h2> <pre><code class="bash:">-Wl,--start-group -Wl,-Bstatic -lPocoFoundation -lPocoUtil -lPocoXML -lPocoJSON -lPocoNet -Wl,--end-group -Wl,-Bdynamic -lpthread </code></pre> <h1 id="感想"><a href="#%E6%84%9F%E6%83%B3">感想</a></h1> <p>まるで紅茶に浸した一匙のマドレーヌを口に含んだ時みたいに鮮明に記憶が戻ってきました<br /> 私は gcc のこういう所があんまり好きじゃなかったんでした</p> Dr. Takeyuki Ueda tag:crieit.net,2005:PublicArticle/14937 2019-04-20T12:08:57+09:00 2019-07-02T19:43:14+09:00 https://crieit.net/posts/C-Cerflet C++ ベースのウェブアプリケーションサーバ Cerflet のご紹介 <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/MayaPosch/Cerflet">Cerflet</a> は <a target="_blank" rel="nofollow noopener" href="https://github.com/MayaPosch">Maya Posch</a> さん作の C++ ベースのシンプルな Web Application server です<br /> Raspberry Pi でもサクサクに動いています</p> <p>python の tornado みたいにリクエストハンドラを書くだけで簡単に使える上に、<strong>オール C++</strong> かつ<strong>オンメモリ</strong>なので超高速が期待できます</p> <p>ちなみに Cerf はジビエ好きな方はピンと来るかと存じますが多分、フランス語の <strong>鹿(セール)</strong> なんじゃないかなと想像してます、Maya さんの他のプロダクトも動物の名前のが多いし、彼女の会社の名前からして <a target="_blank" rel="nofollow noopener" href="http://www.nyanko.ws">Nyanko</a> だし</p> <h1 id="実装"><a href="#%E5%AE%9F%E8%A3%85">実装</a></h1> <p>本体の<a target="_blank" rel="nofollow noopener" href="https://github.com/MayaPosch/Cerflet/blob/master/lib/httpcerflet.cpp">実装</a>は物凄くシンプルでコメント込で 80行ぐらいしかないです、すごい<br /> 私だったら C++ の80行ってコマンドライン処理するだけでもゆうに超えちゃったりします</p> <p>サーバの処理も実行時オプションの処理も <a target="_blank" rel="nofollow noopener" href="https://pocoproject.org/">POCO</a> の機能が有効に使われてて、POCO の凄さと、POCOを使えば Web Application でさえこんなにシンプルにつくれるという Maya さんのソフトウェア・アーキテクチャのセンスの良さに敬服いたしますとともに、Poco.Net のプラグマティックなチュートリアルとして大変ありがたく読ませていただきました次第でございます</p> <h1 id="How to try it"><a href="#How+to+try+it">How to try it</a></h1> <ol> <li>POCO を<a target="_blank" rel="nofollow noopener" href="https://pocoproject.org/download.html">インストール</a></li> <li>git clone https://github.com/MayaPosch/Cerflet.git</li> <li>cd Cerflet/sample</li> <li>make</li> <li>./hellocerflet</li> </ol> <p>「libPocoNet.so.60 がないよ」とかエラーになるようでしたら <a href="https://crieit.net/posts/POCO-error-while-loading-shared-libraries-libPocoNet-so-60-cannot-open-shared-object-file-No-such-file-or-directory">ldconfigして</a>みてください</p> <p>で、hellocerflet を起動したサーバの port 8080 番をブラウザで開くと</p> <p><a href="https://crieit.now.sh/upload_images/7cc81f710697ae3e872d25b283d8f9535cba83edb5f74.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7cc81f710697ae3e872d25b283d8f9535cba83edb5f74.png?mw=700" alt="スクリーンショット 2019-04-20 11.27.15.png" /></a></p> <p><strong>ビックリするほど簡単</strong>です</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/MayaPosch/Cerflet/blob/master/sample/HelloCerflet.cpp#L22">こちら</a> の HTTPRequestHandler の中身を変えて、たとえば ContentType を "text/html" じゃなくて <strong>"application/json"</strong> にして、<a target="_blank" rel="nofollow noopener" href="https://github.com/MayaPosch/Cerflet/blob/master/sample/HelloCerflet.cpp#L32">ostr</a> に <strong>json 文字列</strong>を返したら超高速かつコンパクトな API サーバーとしてすぐにでも大活躍しそうです</p> <h1 id="作者の御紹介"><a href="#%E4%BD%9C%E8%80%85%E3%81%AE%E5%BE%A1%E7%B4%B9%E4%BB%8B">作者の御紹介</a></h1> <p>作者の <a target="_blank" rel="nofollow noopener" href="https://github.com/MayaPosch">Maya Posch</a> さんですが、<a target="_blank" rel="nofollow noopener" href="http://www.mayaposch.com/autobiography.php">御本人のブログ</a>によると生まれつきに抱えるいくつかの問題、特に<strong>両性具有</strong>に起因する問題(当時のニュース番組が<a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=M4N-0CgUCX8">これ</a> とか <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=DKW2c0H2iGw">これ</a> とか残ってます)で祖国オランダを離れざるを得ず、安住の地を求めて世界を旅しながら自分の会社 <a target="_blank" rel="nofollow noopener" href="http://www.nyanko.ws/">Nyanko</a> を運営しつつプログラミングと電子工作に関する<a target="_blank" rel="nofollow noopener" href="http://www.mayaposch.com/index.php">数々のプロダクトと著作</a>を世に出していらっしゃいます<br /> まるで物語みたいに数奇な人生を歩みながら outcomes を出されていることに正直圧倒されてしまいました、すごい人がいるもんなんだなぁ<br /> 翻って自分を鑑みるにいったい何をやってるんだと情けなく忸怩たる思いに至る次第です</p> <p>近著 <a target="_blank" rel="nofollow noopener" href="https://learning.oreilly.com/library/view/hands-on-embedded-programming/9781788629300/">Hands-On Embedded Programming with C++17</a> を魅力的なタイトルに惹かれて読んだのが彼女を知るきっかけだったんですが、この本も POCO の紹介をふくめて Raspberry Pi みたいなSBC でプロダクトをつくる上でのオリジナルな話題にあふれていてとても面白い本でした</p> <h1 id="感想"><a href="#%E6%84%9F%E6%83%B3">感想</a></h1> <p>数日前に<a href="https://crieit.net/posts/Nuitka-python-code">某所</a>で「C++でウェブアプリ書く気にはならないし」なんて言っちゃったの、謹んで取り消させてください</p> <p>読書は時として人の世界観をダイナミックに変えてしまうものなのです ^^;;;;;;;</p> Dr. Takeyuki Ueda