よく通っているコーヒースタンド
遅くなってすみません。。。すっかり忘れておりました。
この記事は「コーヒー Advent Calendar 2015」5日目の記事です。
俺氏について
ブラックコーヒーデビューは小学4年生位の頃。
元々は牛乳入れないとダメだったのですが、コーヒー牛乳を飲み過ぎて、腹を壊しまくった結果、牛乳入れずに飲んだら苦いものの、腹を壊さない事に感動し、飲み続けていたら「あれ?うまい!?」とはまっていった次第であります。
最近は健康診断で貧血気味と診断されコーヒー飲み過ぎてることを怒られました。
いわゆる渋谷で働く〜系のエンジニアで、渋谷に近いところに住んでいます。 渋谷周辺って結構コーヒー激戦区だったりするんですよ!
早速、おすすめをリストアップしていきますっ!
THE COFFEE SHOP
渋谷駅からは歩いて10分くらい。本日のコーヒーは300円くらいでフレンチプレスで淹れてもらえます。初めてここで飲んだ時は感動しました。 コーヒーにこだわるきっかけとなったお店です。
おいてる豆はすべてスペシャルティコーヒーなので、どれも個性がはっきりしているので、好みの豆に出会ったらリピート間違いなしです!
店員さんも気さくに色々教えてくれるので待ってる間も無駄になりません!
About Life Coffee Brewers
オフィスの目の前にあるが故に週3,4くらいで通っているスタンド。ここもスペシャルティコーヒーのみ。 ペーパードリップを感じさせないドリップ技術。淹れ方や温度を聞いたりして、やってるんですがどうも真似できないです。ミルの問題なのか・・・?
それはともあれ、外国のガイドブックにでものっているのか?というくらい外国人の観光客が多いイメージがあります。
オーナーさんは焙煎技術を競う大会で日本で3位になっていて、外国の知り合いからたまーに豆が送られて来るらしく、運が良ければ定番以外の豆が飲めることも。
年に1回ゲイシャ豆もでます
NOZY COFFEE
ここのコーヒーはどれを飲んでも甘い!家で淹れても甘い! 夏はここでアイスコーヒーをかって世田谷公園のベンチで「あついー」ってやるのが結構好きだったりします。冬は店内でゆっくりと。
また、カフェにコーヒー豆をおろしてたりするので、そこでは美味しいコーヒーを飲むことができます。
tabelog.com 会社の近辺だとここです。ここはテイクアウトでコーヒーの注文だけも可能なのでたまに行きます。
全体的に渋谷近辺かつ山の手線の外側になりましたが、この3つにいつも行っています。美味しいコーヒーさいこーーー!
C++初心者ならビルドはBazelでラクしちゃいましょう
この記事は 初心者C++er Advent Calendar 2015, Qiita C++ Advent Calendar 2015 15 日目の記事です.
注意
- UbuntuもしくはMac OSXの環境が作れない方はそっと閉じてください。(VagrantでUbuntuはすぐ準備できる)
- スマホアプリ畑の人間が書くので、それに向けた内容も多くなっています。
- PCからの閲覧をおすすめします。スマホで読むと、コードのレイアウトが崩れるようなので。
ビルドツールについて
みなさんはビルドオートメーションツールには何を使っていますか?
玄人界隈ではcmakeが定番です。
私が携わっているプロジェクトではgypと呼ばれるツールを使っています。
元々Chromiumで開発されていたGoogleのオープンソースの一つで、node.jsにも使われているビルドツールです。
特殊なフォーマットに従ってファイルやマクロを定義することで、設定ファイルに応じたmakeファイルやXcodeなどプロジェクトを吐き出してくれる中間的なツールで、今は開発が進んでいないようです。
さて、前振りが長くなりましたが、このgypに取って代わる次世代ビルドツールとして開発されているのがBazelです。
BazelはCookpadの技術ブログでも取り上げてられているように、C++だけではなくスマホアプリや複数言語のビルドにも対応しているので、延長線上にポテンシャルがあるという観点も含めてBazelをピックアップしました。
また、話題の機械学習フレームワークTensorFlowもBazelでビルドされてます。
少しの設定ファイルを書けば機能単位でライブラリ化や依存関係を定義できるので、初心者はBazelでラクしましょう!!!
サンプル
↑を元に、解説していきます。
Hello World
インストール方法は環境によって違うのと、簡単なので割愛します。
HelloWorldプロジェクトのファイル構成
HelloWorld ├── Makefile ├── WORKSPACE └── src ├── BUILD └── main.cpp
注目すべきはWORKSPACEとBUILDです。
WORKSPACE
The location of the workspace directory is not significant, but it must contain a file called WORKSPACE in the top-level directory. The WORKSPACE file may be an empty file, or it may contain references to external dependencies required to build the outputs.
Getting Started with Bazelより引用
「WORKSPACEという名前のファイルがプロジェクトのトップとなるディレクトリに必要で、他のプロジェクトへの依存性を定義するもの。依存性がなければ空ファイルとしておいておけばOK」とのこと
今回は、外部のソースに依存しないのでWORKSPACEは空ファイルです。
TensorFlowのWORKSPACEでは、外部に依存する設定が定義されていますね!
zipをダウンロードしてhashチェックしたり、gitのリポジトリをhash指定で持ってきてくれたりしてくれるので使い勝手が良さそうです!
BUILD
Bazel figures out what to build by looking for files named BUILD in your workspace
Getting Started with Bazelより引用
「BazelはBUILDと呼ばれるファイルからビルドすべきファイルを割り出す」とのこと。
つまり、WORKSPACEが外部のソースに対する依存関係の設定、BUILDが具体的なビルドの設定であり、両方ともビルドに欠かせない設定ファイルということになります。
それでは早速設定を見ていきましょう。
main.cpp
#include <iostream> int main() { std::cout << "Hello World" << std::endl; return 0; }
まずは、ソースから。シンプルなHello Worldなので解説は不要ですね。
src/BUILD
cc_binary( name = "main", srcs = ["main.cpp"], )
main.cpp
をmain
というターゲット名で実行ファイルを作成するという設定になります。nameのみがrequiredなパラメータです。
Makefile
all: run BAZEL=$(shell which bazel) .PHONY: run run : build $(BAZEL) run //src:main .PHONY: build build : $(BAZEL) build //src:main .PHONY: clean clean : $(BAZEL) clean
BazelはURIスキームライクにパッケージを定義しており、それらをdependencyとして扱うことができます。 そして、サブコマンドの後にパッケージを指定することでビルドターゲットとしてビルドを開始することができます。
Makefile内に定義してある//src:main
はsrcディレクトリ以下にあるBUILDファイルに定義されているmainというターゲット名を示していることになります。
実行してみる
make run
を実行すればsrc/BUILD
に定義されているmain
がビルドターゲットとなり、main.cpp
がコンパイルされ、main
ターゲットが実行されます。
失敗させてみる
セミコロンを抜いてみました
実行後のディレクトリ
HelloWorld ├── Makefile ├── WORKSPACE ├── bazel-HelloWorld ├── bazel-bin ├── bazel-genfiles ├── bazel-out ├── bazel-testlogs └── src ├── BUILD └── main.cpp
このように、bazel
というプレフィックスでビルド関連のディレクトリ郡が生成されます。自動生成されたディレクトリやファイルは、bazel clean
で一挙に削除することができます。
HelloWorldプロジェクトではMakefileにエイリアスを定義したのでmake clean
で同様のことが可能です。
static libraryの依存関係を定義し、mainから呼び出してみる
HelloWorld出力部分をstatic library化し、//src:main
から依存関係を解決して、コールしてみます。
HelloWorldStaticLibのプロジェクト構成
. ├── Makefile ├── WORKSPACE └── src ├── greeting │ ├── BUILD │ ├── hello.cpp │ └── hello.hpp ├── BUILD └── main.cpp
Makefile
とWORKSPACE
は全く一緒です。
また、hello.hpp,hello.cpp,main.cppはHello World
の出力を関数化しただけなので記載を割愛します。
src/greeting/BUILD
cc_library( name = "greeting", srcs = glob(["*.cpp"]), hdrs = glob(["*.hpp"]), visibility = ["//visibility:public"], linkstatic = 1, )
あらたな設定が出てきましたが、雰囲気でおわかりかと思います。
まず、cc_library
という単位に変わりました。
さらに、srcsがファイルの列挙ではなくglob
関数を使っています。
お察しの通りワイルドカードでコンパイルターゲットとなるファイルを指定しています。hdrsも同様です。
visibility
はそのビルド単位の可視性となります。適切に設定することでビルド単位間の結合性を疎にできるので、必要なcc_libaryだけをpublicにすることが好ましいです。
publicにしたことで、src:main
からsrc/greeting:greeting
が可視化されています。
linkstatic
はフラグです。
src/BUILD
cc_binary( name = "main", srcs = glob(["*.cpp"]), deps = ["//src/greeting"], )
deps
という設定が入りました。greetingライブラリに依存してるんですね〜。
実行してみる
実行結果は変わらないので割愛して、変わったところをば
~/p/h/HelloWorldStaticLib ❯❯❯ ls bazel-out/local_darwin-fastbuild/bin/src/greeting/ _objs libgreeting.a
libgreeting.aができていますね!
と、こんな感じでstatic libraryやshared libraryをつくれて依存関係もよしなにしてくれるので、コーディングに時間を割きたい初心者C++erにはおすすめなのではないでしょうか。
gitignore
*.swp *~ .DS_Store bazel-*
特に問題なければ、bazel-*
のようにワイルドカードでexcludeしちゃって問題無いでしょう。
Bazelはドキュメントもしっかりあるので、「最適化オプション使いたい!」だとか、「マクロを定義したい!」だとかあれば、参考にしてみてください。Bazelで良き、C++のビルドライフを〜!