読者です 読者をやめる 読者になる 読者になる

FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://sites.google.com/site/fpgadevelopindex/

Bazelで自作ISSビルドの調査(階層ディレクトリとライブラリのライブラリのビルド)

Bazel

f:id:msyksphinz:20160529232134p:plain

Bazelでは一般的にどのような構成のプロジェクトディレクトリを作ればいいのかいろいろ調査していたのだが、日本語でうまいこと説明してくれている文章が見つからない。

クックパッドのブログは、実際の運用とビルドのトライアルの面でかなり役に立つものだった。

techlife.cookpad.com

なるほど、プロジェクトの構成として、ソースコードディレクトリはちょっと階層の深いところにあり、ビルドファイルを出力できそうな、ちょっと一階層深まったような構造になっている。

以下はクックパッドのブログから引用。

├── 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ファイルを配置してみる。以下のようになる。

github.com

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がちゃんと接続できるかを見る必要がある。そこはまだ未トライだ。