cloverrose's blog

Python, Machine learning, Emacs, CI/CD, Webアプリなど

Make tips: Cloud Spanner EmulatorとGCP Spannerの2つの接続先をもつMakefileの作り方

最近仕事でGCPのCloud Spannerを使い始めて勉強中です。今回はSpannerを使うときにMakeでこんなことできるんだ!って知ったことを共有します。

恥ずかしながら今までMakeを体系的に勉強していませんでした。 しかし社内のシステムはだいたいがMakeで運用コマンド作ることが多く、今回のシステムも例にもれずMakefileを書くことになったので、ちゃんと勉強しよう!と思い参考書を読んだらもっと早く読んでおけばよかったーということだらけでした。

しかもなんとオライリーGNU Makeの本無料PDF読める。

www.oreilly.co.jp

以下のブログがPDFを連結して扱いやすくして再配布してくれています。 Kindleに入れたら目次も機能したのでかなり助かりました。

https://www.yokoweb.net/2016/08/28/gnu-make-3rd-pdf-github/

1章から5章までが基礎編で今回はそこだけ読んでんですが、これだけでもMakefileに向き合うときの苦手意識がなくなったのでおすすめです。


まずはじめに、自分がMakefileの構成要素をなんと呼ぶのかわからず検索するときに苦労したのでそこから。(この情報は1章でわかります)

f:id:cloverrose:20200718105254p:plain
Makefile構成要素の名前

  • 作りたい・実行したいもののことをターゲット, target
  • targetが依存しているもののことを必須項目, prereq, prerequisite
  • 実行するもののことをコマンド,command
  • これらの塊をルール, rule と呼ぶ

次に今回自分がMakeをちゃんと勉強するまでわからず苦戦していた、GCPのCloud SpannerとLocalのSpanner Emulatorと接続先の切り替え方について紹介します。

Cloud SpannerのEmulatorはGCP本家が出しているこちらを使っています。Docker imageも提供されているのですぐに使い始めることができます。

github.com

GCPのCloud Spannerの中での接続先の切り替えは各種ツールのproject,instance,databaseのパラメータを変えることで可能ですが、 一方でGCPのCloud SpannerとLocal環境のEmulatorの接続先の切り替えは、こちらのドキュメントにあるようにexport SPANNER_EMULATOR_HOST=localhost:9010のように環境変数を設定すると、SpannerのクライアントライブラリはGCPにあるSpannerではなく、Localで動いているEmulatorに接続するようになります。

cloud.google.com

Cloud SpannerのMigrationツールとしてwrenchを使います。このツールもSPANNER_EMULATOR_HOST環境変数によってLocal環境を使うようになります。

github.com

そこで今回問題になったのが、1つのMakefileでLocalのEmulatorに対して使いたいコマンドとGCPのSpannerに対して使いたいコマンドがあるときに、Globalに環境変数をセットするとすべてがLocalに接続してしまうことです。

ここでGNU Make 第3版の3.5章「ターゲットとパターンに固有の変数」がまさに解決策でした。

f:id:cloverrose:20200718111526p:plain
ターゲット固有の変数の設定

このようにtarget:の横に変数の設定を記述するとそのルールと、このルールを実行するために必要なprerepのルールのスコープでだけ有効な変数を設定できます。

なのでdev/migrateGCPemulator/migrateはLocalのEmulatorに接続するように使い分けることができます。

注意点としてcommandsを設定する前はtarget: 変数設定ではなくてtarget:target:必須項目のどちらかである必要があります。(エラーがでます)