2019年1月26日土曜日

TOPPERS cfg の 64 bit ビルドに挑戦した記録(その4 最適化なしのスタティックリンクバイナリを作った)

前回、セグフォのデバッグで絶望してあきらめたわけですが、 最適化なしなら正常動作するので、それでスタティックリンクバイナリを作りたい。

環境

  • 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.configOPTION-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-clibcurl を要求しているのか...。

元の 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 ビルド再挑戦

  1. apt でインストールした libxerces-c-dev を削除
  2. Makefile.config 修正
  3. 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 使ってソース取り込んだうえで、それ含めたビルドスクリプト作るというのもよさそうだ。

3 件のコメント:

  1. ご対応感謝します。
    Linux 64bit版cfgの公開期待しています!
    #我が家のPCが64bit版ubuntuなもので、自宅での開発が頓挫していますもので・・

    返信削除
    返信
    1. バイナリを以下の場所に置きましたので、必要であれば使ってみてください。

      https://github.com/mikoto2000/cfg-1/releases/tag/1.9.7.1

      削除
    2. 早速のご対応ありがとうございました!
      無事、我が家のPCでもcfg使えるようになりました。感謝です。

      削除