Make tips: Cloud Spanner EmulatorとGCP Spannerの2つの接続先をもつMakefileの作り方
最近仕事でGCPのCloud Spannerを使い始めて勉強中です。今回はSpannerを使うときにMakeでこんなことできるんだ!って知ったことを共有します。
恥ずかしながら今までMakeを体系的に勉強していませんでした。 しかし社内のシステムはだいたいがMakeで運用コマンド作ることが多く、今回のシステムも例にもれずMakefileを書くことになったので、ちゃんと勉強しよう!と思い参考書を読んだらもっと早く読んでおけばよかったーということだらけでした。
しかもなんとオライリーのGNU Makeの本無料PDF読める。
以下のブログがPDFを連結して扱いやすくして再配布してくれています。 Kindleに入れたら目次も機能したのでかなり助かりました。
https://www.yokoweb.net/2016/08/28/gnu-make-3rd-pdf-github/
1章から5章までが基礎編で今回はそこだけ読んでんですが、これだけでもMakefileに向き合うときの苦手意識がなくなったのでおすすめです。
まずはじめに、自分がMakefileの構成要素をなんと呼ぶのかわからず検索するときに苦労したのでそこから。(この情報は1章でわかります)
- 作りたい・実行したいもののことを
ターゲット, target
target
が依存しているもののことを必須項目, prereq, prerequisite
- 実行するもののことを
コマンド,command
- これらの塊を
ルール, rule
と呼ぶ
次に今回自分がMakeをちゃんと勉強するまでわからず苦戦していた、GCPのCloud SpannerとLocalのSpanner Emulatorと接続先の切り替え方について紹介します。
Cloud SpannerのEmulatorはGCP本家が出しているこちらを使っています。Docker imageも提供されているのですぐに使い始めることができます。
GCPのCloud Spannerの中での接続先の切り替えは各種ツールのproject,instance,databaseのパラメータを変えることで可能ですが、
一方でGCPのCloud SpannerとLocal環境のEmulatorの接続先の切り替えは、こちらのドキュメントにあるようにexport SPANNER_EMULATOR_HOST=localhost:9010
のように環境変数を設定すると、SpannerのクライアントライブラリはGCPにあるSpannerではなく、Localで動いているEmulatorに接続するようになります。
Cloud SpannerのMigrationツールとしてwrenchを使います。このツールもSPANNER_EMULATOR_HOST
環境変数によってLocal環境を使うようになります。
そこで今回問題になったのが、1つのMakefileでLocalのEmulatorに対して使いたいコマンドとGCPのSpannerに対して使いたいコマンドがあるときに、Globalに環境変数をセットするとすべてがLocalに接続してしまうことです。
ここでGNU Make 第3版の3.5章「ターゲットとパターンに固有の変数」がまさに解決策でした。
このようにtarget:
の横に変数の設定を記述するとそのルールと、このルールを実行するために必要なprerepのルールのスコープでだけ有効な変数を設定できます。
なのでdev/migrate
はGCPにemulator/migrate
はLocalのEmulatorに接続するように使い分けることができます。
注意点としてcommands
を設定する前はtarget: 変数設定
ではなくてtarget:
かtarget:必須項目
のどちらかである必要があります。(エラーがでます)