Bazelでは一般的にどのような構成のプロジェクトディレクトリを作ればいいのかいろいろ調査していたのだが、日本語でうまいこと説明してくれている文章が見つからない。
クックパッドのブログは、実際の運用とビルドのトライアルの面でかなり役に立つものだった。
なるほど、プロジェクトの構成として、ソースコードのディレクトリはちょっと階層の深いところにあり、ビルドファイルを出力できそうな、ちょっと一階層深まったような構造になっている。
以下はクックパッドのブログから引用。
├── BUILD ├── HelloBazel │ ├── app │ │ ├── build.gradle │ │ ├── libs │ │ ├── proguard-rules.pro │ │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── jp │ │ │ └── tomorrowkey │ │ │ └── android │ │ │ └── hellobazel │ │ │ └── MainActivity.java ...
今の段階では僕のISSのプロジェクトは、
src instruction.cpp hoge.cpp huga.cpp genfile.rb ... vendor google_flags ... softfloat src *.cpp build ... build_riscv bulid_mips ...
のような構成になっており、上記のクックパッドのプロジェクトに比べるとやや階層は浅い。ただし、ビルドようにbuild_xxxのような階層を「ソースと同じ深さの場所」に用意しており、こちらでビルドすることになる。
各build_xxxのディレクトリにはCMakeLists.txtが置かれており、やはり一度ディレクトリを上に登っていき、
add_library (core_riscv ../src/riscv_env.cpp ../src/env.cpp ../src/trace.cpp ../src/inst_print.cpp ../src/inst_mnemonic.cpp ../src/inst_riscv_init.cpp ../src/inst_decoder.cpp
の形で、親ディレクトリを参照する形で配置されている。ただしBazelはラベルとして親ディレクトリの参照を許してはいないので、この形では実現できない。ではどうするか。 もう少し深めのディレクトリにするのが良いかもしれない。ただし、すぐに変更するのは無理なので、現状の構成のまま、BUILDファイルを配置してみる。以下のようになる。
BUILD WORKSPACE src instruction.cpp hoge.cpp huga.cpp genfile.rb ... BUILD WORKSPACE vendor google_flags ... softfloat src *.cpp BUILD WORKSPACE ...
Google Flagsがまだ対応できていないのが残念だ。というかGoogle FlagsはCMakeを使ってあるので、移行がちょっと難しい。
まず、srcディレクトリ配下のBUILDで、ISSの本体をビルドしていく。これも2段階のビルドになっており、CPUのコア部をライブラリとして作ってから、その外側を作っていく。以下のような構成だ。
- src/BUILD
cc_library ( name = "swimmer_core", visibility = ["//visibility:public"], defines = ["ARCH_RISCV"], srcs = ["swimmer_main.cpp", "bfd_env.cpp", "img_env.cpp", "lua_env.cpp", ], ) cc_library ( name = "core_riscv", visibility = ["//visibility:public"], srcs = ["riscv_env.cpp", "env.cpp", "trace.cpp", "inst_print.cpp", "inst_mnemonic.cpp", "inst_riscv_init.cpp", ...
visibility = ["//visibility:public"],
によって、さらに親ディレクトリのBUILDファイルからこのラベルが参照できるようになる。最終的にはsoftfloatのライブラリと接合しなくてはならないので、上位のBUILDからはこのライブラリは見えておく必要がある。
さらにsoftfloatの部分は、vendorディレクトリに配置されているが、こちらも基本BUILDファイルを置いて同様にビルドする。
- vendor/softfloat/SoftFloat-3a/BUILD
cc_library ( name = "softfloat", linkstatic = 1, srcs = ["source/extF80_add.c", "source/extF80_div.c", "source/extF80_eq.c", "source/extF80_eq_signaling.c", "source/extF80_isSignalingNaN.c", "source/extF80_le.c", "source/extF80_le_quiet.c", "source/extF80_lt.c", "source/extF80_lt_quiet.c",
最後に最上位のBUILDファイルで結合するのだが、これは下位のディレクトリ(いわゆるパッケージ)を参照して結び付けていく。
- BUILD
cc_binary ( name = "swimmer_riscv", defines = ["ARCH_RISCV"], srcs = ["//src:swimmer_core", "//src:core_riscv", ], linkopts = ["-llua5.2", "-lbfd",
といいつつまだこれは完成していなくて、GoogleFlagsの対応と、softfloatがちゃんと接続できるかを見る必要がある。そこはまだ未トライだ。