-Wl,--start-group -Wl,-Bstatic -lPocoFoundation -lPocoUtil -lPocoXML -lPocoJSON -lPocoNet -Wl,--end-group -Wl,-Bdynamic -lpthread
今世のリンカオプションには --start-group, --end-group
なんて便利なものがあるんですね
Cerflet ベースの WebApplication を deploy しようとして、POCO に依存してしまうのもアレだなと思い、だったら static に link してしまおうと思ったのが事の発端です
POCO の configure の --static オプションを使って make します
./configure --static
make
はじめは shared library 作る時と同じで make -j4
ってやってたんですけどリンクエラーがでるので、多分、static に link してるから順番とかが影響してるんだろうなと深く考えずに make
にしたらでなくなりました
こんな些細なところからすでにlink する時の嫌な事が始まってます ^^;;;
マジメな C++ プログラマだった頃の辛い思い出が蘇ってきます...
dynamic に link した時と同じ感覚で素朴に lPocoFoundation をリンクしようとしたのですが
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'
...
-lpthread つけてやらないといけないんですね
で、-lpthread つけてあげたんですが
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()'
...
あ、static link だから lPocoFoundation が依存する Poco のライブラリも先にリンクしておいてあげないと...
で、undefined だって言われる Poco のライブラリをどんどん前に追加しているのに、まだ undefined が...
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'
ちゃんと -lPocoXML も -lPocoJSON も link してるのになんで undefined なんて言われるんだろ?
このあたりでもう考えるのが嫌になって POCO static link とかでググるとそのものズバリなのが
定義されていないシンボルへのPoco C++ 静的リンクの問題
そうだ、リンクの順番!使われる前にリンクしておかないといけないんでした
POCO内部の依存関係に合わせて正しい順番でリンクすると
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
glibc まで static にリンクしようとしてました ^^;;;
なので、pthread だけは dynamic に link するようにして
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
やっとできました
しかし今どきリンクの順番みたいな機械的に解決できることに人間が頭を使わないといけないのってちょっと残念ですよね、人って機械的な作業が苦手なクリエイティブなクリーチャーなのに
でも、さすがになにか進歩してるんじゃないかとおもって static link order とかでググりまくってると Why does the order in which libraries are linked sometimes cause errors in GCC?
やっぱり人類は賢かった!--start-group, --end-group なんてリンカのオプションをつくってくれた人がいて、この中だと順番気にしなくてもリンカがよしなにやってくれるんですね!
で、本稿の結論にいたります
-Wl,--start-group -Wl,-Bstatic -lPocoFoundation -lPocoUtil -lPocoXML -lPocoJSON -lPocoNet -Wl,--end-group -Wl,-Bdynamic -lpthread
まるで紅茶に浸した一匙のマドレーヌを口に含んだ時みたいに鮮明に記憶が戻ってきました
私は gcc のこういう所があんまり好きじゃなかったんでした
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント