BazelでJavaのプロジェクトをビルドする
概要
- Bazelを実際に使って見るためにインストールとサンプルプロジェクトのビルドを試してみる。
Bazel?
BazelはGoogleで使われているビルドツールBlazeのOSS版。巨大なソースコードのビルド、テストおよびリリースの要件を満たすように設計されたビルドツールで、迅速かつ確実に巨大なソースコードをビルドすることが可能ならしい。現在α版。
Bazelの特徴
- Fast
- キャッシュと並列処理でビルドを高速化
- Reproducible
- ビルドサーバ、開発機問わずbitwise-identicalなバイナリをビルド
- Flexible
- 他言語サポート、同じコードベースでサーバ、クライアント両方のビルドに対応
なぜBazelを試してみるのか
- AndroidでのGradleの次のビルドシステム(と勝手に思っている)
- Gradleチームの見解
- ロードマップを見ると2015/6月にiOS、Androidのビルドをサポートする
- 未確定だがAndroid Studio互換がロードマップに記載されている
- Goのサポートも未確定だが予定されている
- Androidのビルドが高速化される可能性
- AndroidのビルドがBazelを使うことで高速になるかもしれない
- もし高速化されれば開発効率が大幅にアップ
- Jakeが言及していた。
I can finally talk about Bazel! Check it out at http://t.co/dd6LMJxS8Z
— Jake Wharton (@JakeWharton) March 24, 2015
Bazel実行環境の用意
- http://bazel.io/docs/install.htmlを参考に進める
- Macで実行可能だが、ローカルを汚したくないのでDockerでUbuntu環境を構築する
Ubuntu環境の構築
MacでDockerを利用するための環境を構築
boot2dockerのインストール
- homebrewでもインストールできるようだが公式サイトのやり方でインストールする
- osx-installerを開く
Boot2Docker-1.6.0.pkgを実行しインストール
- Boot2Docker VMの作成
$ boot2docker init
- boot2docker VMの起動
$ boot2docker start
- Dockerクライアント用の環境変数が表示される
$ boot2docker start Waiting for VM and Docker daemon to start... ...........................oooooooooooooooo Started. Writing /Users/horie1024/.boot2docker/certs/boot2docker-vm/ca.pem Writing /Users/horie1024/.boot2docker/certs/boot2docker-vm/cert.pem Writing /Users/horie1024/.boot2docker/certs/boot2docker-vm/key.pem To connect the Docker client to the Docker daemon, please set: export DOCKER_HOST=tcp://192.168.59.103:2376 export DOCKER_CERT_PATH=/Users/horie1024/.boot2docker/certs/boot2docker-vm export DOCKER_TLS_VERIFY=1
- shellの設定ファイルに以下を記述。手動で
export
しても問題は無い。
eval "$(boot2docker shellinit)"
hello-world
コンテナを起動
$ docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from hello-world ・ ・ ・ Hello from Docker. This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (Assuming it was not already locally available.) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash For more examples and ideas, visit: http://docs.docker.com/userguide/
$ boot2docker ssh ## . ## ## ## == ## ## ## ## ## === /"""""""""""""""""\___/ === ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~ \______ o __/ \ \ __/ \____\_______/ _ _ ____ _ _ | |__ ___ ___ | |_|___ \ __| | ___ ___| | _____ _ __ | '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__| | |_) | (_) | (_) | |_ / __/ (_| | (_) | (__| < __/ | |_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_| Boot2Docker version 1.6.0, build master : a270c71 - Thu Apr 16 19:50:36 UTC 2015 Docker version 1.6.0, build 4749651
Ubuntuコンテナを起動してみる
- dockerコマンドで起動
$ docker run -it ubuntu bash
- 起動できた
$ docker run -it ubuntu bash Unable to find image 'ubuntu:latest' locally Pulling repository ubuntu b7cf8f0d9e82: Download complete 706766fe1019: Download complete a62a42e77c9c: Download complete 2c014f14d3d9: Download complete Status: Downloaded newer image for ubuntu:latest root@3kdi85o3d:/#
- Ubuntuのバージョンを確認
root@3kdi85o3d:/# cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=14.04 DISTRIB_CODENAME=trusty DISTRIB_DESCRIPTION="Ubuntu 14.04.2 LTS"
Bazelのインストール
バイナリインストールのサポートはまだ無い(後日サポートするらしい)。http://bazel.io/docs/install.htmlを参考に進める
- aptリポジトリの追加
$ sudo add-apt-repository ppa:webupd8team/java sudo: add-apt-repository: command not found
add-apt-repositoryが無いと言われ失敗。
- software-properties-commonをインストールすると解決
$ sudo apt-get install software-properties-common
- apt-getをアップデート
$ sudo apt-get update
- Java8のインストール
$ sudo apt-get install oracle-java8-installer
- JAVA_HOMEの設定
$ export JAVA_HOME=/usr/lib/jvm/java-8-oracle
- 必要なパッケージのインストール
$ sudo apt-get install libarchive-dev pkg-config zip g++ zlib1g-dev
- Bazelをダウンロード
$ git clone https://github.com/google/bazel/
- Bazelのインストール
$ cd bazel $ ./compile.sh
- PATHを通す
$ export PATH="$PATH:$HOME/bazel/output"
- インストールできた
$ bazel Extracting Bazel installation... Apr 25, 2015 7:15:15 AM com.google.devtools.build.lib.runtime.BlazeRuntime batchMain INFO: Running Blaze in batch mode with startup args [--batch, --install_base=/root/.cache/bazel/_bazel_root/install/e3f3e466c8e7784303e1f835508f8561, --output_base=/root/.cache/bazel/_bazel_root/d41d8cd98f00b204e9800998ecf8427e, --workspace_directory=, --nofatal_event_bus_exceptions, --option_sources=] [bazel development version] Usage: bazel <command> <options> ... Available commands: analyze-profile Analyzes build profile data. build Builds the specified targets. canonicalize-flags Canonicalizes a list of bazel options. clean Removes output files and optionally stops the server. doc_ext Prints help for commands, or the index. help Prints help for commands, or the index. info Displays runtime info about the bazel server. query Executes a dependency graph query. run Runs the specified target. shutdown Stops the bazel server. test Builds and runs the specified test targets. version Prints version information for bazel. Getting more help: bazel help <command> Prints help and options for <command>. bazel help startup_options Options for the JVM hosting bazel. bazel help target-syntax Explains the syntax for specifying targets. bazel help info-keys Displays a list of keys used by the info command.
- versionをみてみる
$ bazel version Apr 25, 2015 7:20:22 AM com.google.devtools.build.lib.runtime.BlazeRuntime batchMain INFO: Running Blaze in batch mode with startup args [--batch, --install_base=/root/.cache/bazel/_bazel_root/install/e3f3e466c8e7784303e1f835508f8561, --output_base=/root/.cache/bazel/_bazel_root/d41d8cd98f00b204e9800998ecf8427e, --workspace_directory=, --nofatal_event_bus_exceptions, --option_sources=] ERROR: Version information not available.
ERRORでた・・
サンプルプロジェクトのビルド
インストールが正常に行われたか確認うるためにサンプルプロジェクトをビルドする。
- プロジェクトディレクトリの作成
$ mkdir my-project
- WORKSPACEファイルを作成
$ cd my-project $ touch WORKSPACE
- bazelインストール時にcloneしてきたディレクトリからexampleをコピー
$ cp -r $HOME/bazel/examples .
- ビルドの実行
初回実行時にbazel-binやbazel-outといったリンクが作られる。
$ bazel build examples/java-native/src/main/java/com/example/myproject:hello-world INFO: Found 1 target... Target //examples/java-native/src/main/java/com/example/myproject:hello-world up-to-date: bazel-bin/examples/java-native/src/main/java/com/example/myproject/hello-world.jar bazel-bin/examples/java-native/src/main/java/com/example/myproject/hello-world INFO: Elapsed time: 3.269s, Critical Path: 1.21s
- ビルド成果物の実行
ビルドによって作成されたバイナリはbazel-bin/以下に配置される。
$ bazel-bin/examples/java-native/src/main/java/com/example/myproject/hello-world Hello world
実行できた。Androidのビルドに対応したらまた試したい。
Docker Hubに登録
登録した。
https://registry.hub.docker.com/u/horie1024/bazel/registry.hub.docker.com
参考
OpenBRをインストールしてみる
概要
ちょっと興味があったのでOpenBRをビルドして動かしてみる。
OpenBR
OpenBRはOSSの生体識別ライブラリで、顔写真から年齢や性別を判別したりできる。最近だとMicrosoftのProjectOxfordで公開されたデモが話題になっていた。
OpenBRのインストール
installationをみてみると現状ソースコードからビルドするしかないようだった。Macにインストールはしたくないので適当なUbuntu環境を用意してビルドする。
DockerでUbuntu環境を用意
boo2dockerを起動
boo2dockerのVMが起動していないなら起動
$ boot2docker up
コンテナを起動
$ docker run --name openbr -i -t ubuntu /bin/bash
Ubuntuのバージョンを確認
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=14.04 DISTRIB_CODENAME=trusty DISTRIB_DESCRIPTION="Ubuntu 14.04.2 LTS"
OpenBRをビルド
installationに沿って作業を進める。
GCCのインストール
$ sudo apt-get update $ sudo apt-get install build-essential
CMakeのインストール
$ sudo apt-get install cmake cmake-curses-gui
OpenCVのインストール
ビデオのデコードに問題出たらここ参考にしてねとあるが、取り敢えず手順通りに進める。手順ではOpenCVのバージョンが2.4.5になってるが2.4.11で試す。
OpenCVはここからダウンロードしてきてコンテナにボリュームをマウントするなりして渡す。
$ sudo apt-get install unzip $ unzip opencv-2.4.11.zip $ cd opencv-2.4.11 $ mkdir build $ cd build $ cmake -DCMAKE_BUILD_TYPE=Release .. $ make -j4 $ sudo make install $ cd ../.. $ rm -rf opencv-2.4.11
/usr/local/lib
以下にインストールされた。
Qtのインストール
$ sudo apt-get install qt5-default libqt5svg5-dev qtcreator
OpenBRのビルド
$ git clone https://github.com/biometrics/openbr.git $ cd openbr $ git checkout 0.5 $ git submodule init $ git submodule update $ mkdir build $ cd build $ cmake -DCMAKE_BUILD_TYPE=Release ..
ここでなぜかOpenCVがインストールされて無いと言われたので、再度OpenCVをインストール後再度cmakeを実行。
$ cmake -DCMAKE_BUILD_TYPE=Release .. $ make -j4 $ sudo make install
バージョンを確認
$ br -version 0.5.0
インストールできた。
動かしてみる
OpenBRのトップページにあるAge Estimationを実行してみる。実行例だと写真を2枚使用しているが一枚でも問題ないようだった。(metadata.csvの中身を見る限る)
$ br -algorithm AgeEstimation -enroll me.jpg metadata.csv
metadata.csvに結果が出力されるので見てみる。
File,Affine_0_X,Affine_0_Y,Affine_1_X,Affine_1_Y,Age,Confidence,DFFS,FTE,First_Eye_X,First_Eye_Y,FrameNumber,FrontalFace_X,FrontalFace_Y,FrontalFace_Width,FrontalFace_Height,PossibleFTE,Second_Eye_X,Second_Eye_Y me.jpg,88,74,116,73,35.2215,1,737.614,false,88,74,0,66,47,74,74,false,116,73
35.2215歳か・・
Docker imageを作成
OpenBRをインストールできたのでimageを作成しておく。
$ docker commit -m 'OpenBRをインストール' <コンテナID> horie1024/openbr_0.5
作成されているか確認。
$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE horie1024/openbr_0.5 latest 12abc56def About a minute ago 5.000 GB
作成できた。
Docker Hubにimageを登録する
Docker Hubに登録
https://hub.docker.com/account/signup/から登録する。
コマンドラインからログイン
$ docker login
以下のようなエラーが出てdocker loginに失敗する場合、boot2docker restart
すればok。
FATA[0034] Error response from daemon: Server Error: Post https://index.docker.io/v1/users/: dial tcp: lookup index.docker.io on 192.168.13.1:50: read udp 192.168.13.1:50: i/o timeout
Docker Hubに作成したimageを登録
先ほど作成したimageをpush。
$ docker push horie1024/openbr_0.5
登録できた。
使用する場合は、docker pull
後にdocker run
すればok。
追記
Node.jsのバインディングがあった。https://www.npmjs.com/package/openbr
参考
ReactNativeを試してみる
概要
ReactNativeを試してみた。現在iOSのみサポート。Androidサポートはcoming soonらしい。
準備
Getting Startedを参考に進める。
Node.jsのインストール
watchmanとflowのインストール
$ brew install watchman
$ brew install flow
watchmanとflowはサンプルを動かすだけならインストールしなくても問題ないと思う。
ReactNativeクライアントのインストール
$ npm install -g react-native-cli
サンプルプロジェクトの作成
$ react-native init AwesomeProject
xcodeでプロジェクトを読み込む
サンプルを編集してみる
- index.ios.jsをエディタで開く
- Welcome to React Native!の後ろにHello World!を追記してみる。
var AwesomeProject = React.createClass({ render: function() { return ( <View style={styles.container}> <Text style={styles.welcome}> Welcome to React Native! Hello World! </Text> <Text style={styles.instructions}> To get started, edit index.ios.js{'\n'} Press Cmd+R to reload </Text> </View> ); } });
- 保存してcmd+R
変更が反映される。
デバッグ
感想
思ってた以上に簡単にサンプルを動かせた。デバッガの使い方がよく分かってないので、もう少し触ってみようと思う。
build.gradleからの環境変数の参照
build.gradleからの環境変数の参照
CIサーバなどで以下のように環境変数を定義する。
export ORG_GRADLE_PROJECT_TEST="hoge"
ORG_GRADLE_PROJECT_propertyと定義すると、propertyという変数名でbuild.gradleから参照できる。
apply plugin: 'com.android.application' // 環境変数ORG_GRADLE_PROJECT_TESTの内容をTESTで参照できる。 println(TEST) android { compileSdkVersion 22 buildToolsVersion "22" defaultConfig { } buildTypes { debug { } release { } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) }
実行すると参照できていることがわかる。
$ ./gradlew aR ・ ・ ・ 'hoge' ・ ・ ・
参考
GradleでJavaDocを出力する
ターミナルからコマンドでJavaDocを出力できるようにしてみる。
build.gradleの修正
JavaDocを出力したい対象(moduleとか)のbuild.gradleに以下を追加。
android.libraryVariants.all { variant -> if (variant.name == "debug") { return } task("generateJavadoc", type: Javadoc) { title = "My JavaDoc" description "Generates JavaDoc." source = variant.javaCompile.source ext.androidJar = "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar" classpath = files(variant.javaCompile.classpath.files) + files(ext.androidJar) options.links("http://docs.oracle.com/javase/7/docs/api/"); options.links("http://d.android.com/reference/"); exclude '**/BuildConfig.java' exclude '**/R.java' } }
確認
tasksで確認。「Other tasks」にgenerateJavadocが追加されてる。
./gradlew tasks Other tasks ----------- generateJavadoc - Generates JavaDoc.
出力
コマンドを実行して出力する。
./gradlew generateJavadoc
文字化けを直す
charsetをutf-8にしてやる。optionsのcharSetを使えば良い。
android.libraryVariants.all { variant -> if (variant.name == "debug") { return } task("generateJavadoc", type: Javadoc) { title = "My JavaDoc" description "Generates Javadoc" source = variant.javaCompile.source ext.androidJar = "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar" classpath = files(variant.javaCompile.classpath.files) + files(ext.androidJar) options.links("http://docs.oracle.com/javase/7/docs/api/"); options.links("http://d.android.com/reference/"); options.charSet("utf-8") exclude '**/BuildConfig.java' exclude '**/R.java' } }
出力先
デフォルトでは、build/docs/javadoc以下に出力される。destinationDirを指定すれば任意の出力先を指定できる。
自動化
コマンドで完結するので自動化できる。masterにマージされるとJavaDocを出力して、GitHubPagesとかに上げるまで自動化すると良さそう。
追記
publicのクラス、メソッドのみJavaDocに出力したいので、showFromPublicを追加してみた。
android.libraryVariants.all { variant -> if (variant.name == "debug") { return } task("generateJavadoc", type: Javadoc) { title = "My JavaDoc" description "Generates Javadoc" source = variant.javaCompile.source ext.androidJar = "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar" classpath = files(variant.javaCompile.classpath.files) + files(ext.androidJar) options.links("http://docs.oracle.com/javase/7/docs/api/"); options.links("http://d.android.com/reference/"); options.charSet("utf-8") options.showFromPublic() exclude '**/BuildConfig.java' exclude '**/R.java' } }
これでpublicのクラス、メソッドのみ出力できた。
参考
- http://snowdream.github.io/blog/android/2013/11/01/how-to-generate-javadocs-with-android-gradle-plugin/
- http://stackoverflow.com/questions/25912190/how-to-set-an-encoding-for-the-javadoc
- http://gradle.monochromeroad.com/docs/userguide/java_plugin.html
- http://www.gradle.org/docs/current/javadoc/org/gradle/external/javadoc/MinimalJavadocOptions.html#showFromPublic()
Golangでネットワークプログラミングの勉強
Whispering Gophers を読みながらネットワークプログラミングの勉強をしてる。 part2は標準入力で受けた文字をjsonに変換してlocalhost内でtcpを使って送るというもの。 JavaScriptとか書いてて個人的に未知の領域だったのだけど、こんな簡単に書けるんですね。
c, _ := net.Dial("tcp", "localhost:8000") enc := json.NewEncoder(c) enc.Encode("Hello World")
通信を受ける側はdump.go - whispering-gophers - Whispering Gophers - Google Project Hosting を使えとサンプルコードにコメントがあったのでこれを使えばおk。
Macにtreeコマンドを入れる
Macにtreeコマンドが入ってないのでHomebrewで入れた。
$ brew install tree