前回、セグフォのデバッグで絶望してあきらめたわけですが、 最適化なしなら正常動作するので、それでスタティックリンクバイナリを作りたい。
環境
- OS: Windows 10 Pro
- 使用する docker image: ubuntu:bionic
コンテナ起動
ダウンロードした cfg のディレクトリと、動作確認用に athrillのディレクトリをマウントして ubuntu:bionic
コンテナを起動。
デバッグの可能性を考えてデバッグ用オプションもつけておく。
docker run -it --rm --cap-add=SYS_PTRACE --security-opt="seccomp=unconfined" -v "$(pwd)\cfg:/cfg" -v "$(pwd)\athrill:/athrill" ubuntu:bionic
必要なパッケージのダウンロード
いつものやつ。
apt-get update
apt-get -y upgrade
apt-get install -y g++ make libboost-dev libboost-regex-dev libboost-system-dev libboost-filesystem-dev libboost-program-options-dev libxerces-c-dev
ビルド
スタティックビルドをしたいので、Makefile.config
の OPTION
に -static
を設定。
cd /cfg
./configure --with-libraries=/usr/lib/x86_64-linux-gnu --with-xml
sed -i -e 's/OPTIONS=/OPTIONS=-static/' Makefile.config
make
おや失敗だ。ビルドログ抜粋は以下。
...(略)
(.text._ZN12_GLOBAL__N_14pool4freeEPv.constprop.2+0x1d): undefined reference to `pthread_mutex_lock'
collect2: error: ld returned 1 exit status
...(略)
Makefile:45: recipe for target 'cfg' failed
make[1]: *** [cfg] Error 1
make[1]: Leaving directory '/cfg/cfg'
Makefile:35: recipe for target 'cfg' failed
make: *** [cfg] Error 2
pthred
のリファレンスが無い? -static
付けただけでこういうことになるものなんですかね? とりあえず、 cfg
のリンクをしているところに -lpthread
を追加してリビルド。
sed -i -e "45,45 s/$/ -lpthread/" cfg/Makefile
make
ビルドログ。
...(略)
/usr/lib/x86_64-linux-gnu/libxerces-c.a(CurlNetAccessor.o): In function `xercesc_3_2::CurlNetAccessor::~CurlNetAccessor()':
(.text+0xca): undefined reference to `curl_global_cleanup'
...(略)
collect2: error: ld returned 1 exit status
Makefile:45: recipe for target 'cfg' failed
make[1]: *** [cfg] Error 1
make[1]: Leaving directory '/cfg/cfg'
Makefile:35: recipe for target 'cfg' failed
make: *** [cfg] Error 2
curl
?なんでそんなものが必要なんだと思ったら、 xerces-c
が libcurl
を要求しているのか...。
元の cfg
で要求していないということは、 xerces-c
のビルドオプションで curl
有無を変更できるのではないかと思って調べたら、その通りだったっぽい。
ということで xerces-c のソースをダウンロードして、 curl がいらないビルドオプションでビルドする。
Xerces の入手とビルド
Build Instructions を見ながら、「ネットワーク無効」「共有ライブラリ無効」の configure オプションを設定
apt-get install -y wget
mkdir /xerces
cd /xerces
wget http://ftp.meisei-u.ac.jp/mirror/apache/dist//xerces/c/3/sources/xerces-c-3.2.2.tar.bz2
tar xfv xerces-c-3.2.2.tar.bz2
mkdir build
cd build
../xerces-c-3.2.2/configure --prefix=/opt/local/xerces-c --disable-network --disable-shared
make
make install
cfg ビルド再挑戦
- apt でインストールした libxerces-c-dev を削除
- Makefile.config 修正
- make やりなおし
cd /cfg
apt-get remove -y libxerces-c-dev
sed -i -e 's/XERCES_DIR=\/usr\/include/XERCES_DIR=\/opt\/local\/xerces-c\/include/g' Makefile.config
sed -i -e 's/LIBXERCES_DIR=\/usr\/lib\/x86_64-linux-gnu/LIBXERCES_DIR=\/opt\/local\/xerces-c\/lib/g' Makefile.config
make
はい、エラー。ビルドログはこれ。
...(略)
/usr/lib/x86_64-linux-gnu/libicuuc.a(putil.ao): In function `uprv_dl_open_60':
(.text+0x1ce2): undefined reference to `dlopen'
...(略)
-ldl
も必要? 追加して再チャレンジ。
sed -i -e "45,45 s/$/ -ldl/" cfg/Makefile
make
ビルドログ抜粋。
/usr/lib/x86_64-linux-gnu/libicuuc.a(putil.ao): In function `uprv_dl_open_60':
(.text+0x1ce2): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
ワーニングがでつつもビルド自体は成功。
「そもそも dlopen
自体が動的リンクするための関数なので、このバイナリを作った glibc
が無いと上手く共有ライブラリを読み込めないですよ」という感じ?
とりあえず、この環境と、 debian/buster-slim
あたりで試してみる。
# スタティックリンク確認
file /cfg/cfg/cfg
# 共有ライブラリを参照していないことを確認
ldd /cfg/cfg/cfg
# バイナリをコピーして pass2 を動かしてみる
cp /cfg/cfg/cfg /athrill/sample/os/atk2-sc1_1.4.2/cfg/cfg/cfg
cd /athrill/sample/os/atk2-sc1_1.4.2/OBJ/
../cfg/cfg/cfg --pass 2 --kernel atk2 -I. -I../include -I../arch -I.. -I../target/v850esfk3_gcc -I..//arch/v850esfk3_gcc -I..//arch/gcc -T ../target/v850esfk3_gcc/target.tf --api-table ../kernel/kernel.csv --cfg1-def-table ../kernel/kernel_def.csv --ini-file ../kernel/kernel.ini --cfg1-def-table ..//arch/v850esfk3_gcc/prc_def.csv sample1.arxml ..//arch/v850esfk3_gcc/uart.arxml ../target/v850esfk3_gcc/target_hw_counter.arxml
この環境では OK.
ログは省略するが、 debian:buster-slim
でもワンバイナリで問題なく動いた。
本日はここまで。
この記事を書いている間に、 cfg のソースが GitHub に公開されていることに気づいたので、ソース修正 PR 出してみようか。
xerces-c のミラーもあるし、 submodule 使ってソース取り込んだうえで、それ含めたビルドスクリプト作るというのもよさそうだ。
ご対応感謝します。
返信削除Linux 64bit版cfgの公開期待しています!
#我が家のPCが64bit版ubuntuなもので、自宅での開発が頓挫していますもので・・
バイナリを以下の場所に置きましたので、必要であれば使ってみてください。
削除https://github.com/mikoto2000/cfg-1/releases/tag/1.9.7.1
早速のご対応ありがとうございました!
削除無事、我が家のPCでもcfg使えるようになりました。感謝です。