|
| 1 | +############################################################################### |
| 2 | +# set some flags to control Make's behavior |
| 3 | +############################################################################### |
| 4 | + |
| 5 | +# disable all builtin suffix pattern rules |
| 6 | +.SUFFIXES: |
| 7 | + |
| 8 | +# these rules should all run in parallel just fine |
| 9 | +MAKEFLAGS := "-j " |
| 10 | + |
| 11 | +# run all the rule commands in Bash with "-o pipefail" so failing commands with |
| 12 | +# piped output still exit with the right status |
| 13 | +SHELL = /bin/bash -o pipefail |
| 14 | + |
| 15 | +# define all our top level targets |
| 16 | +TARGETS := build build-release test fmt lint clean update-deps |
| 17 | +.PHONY: $(TARGETS) |
| 18 | + |
| 19 | +# the default will be to build for the current host platform/arch (for easy development) |
| 20 | +.DEFAULT_GOAL := build |
| 21 | + |
| 22 | + |
| 23 | +############################################################################### |
| 24 | +# define some versioning logic (see "Versioning" in the README for details) |
| 25 | +############################################################################### |
| 26 | + |
| 27 | +# full Git commit hash of the revision we're building |
| 28 | +SUBSTRATE_COMMIT := $(shell git rev-parse HEAD) |
| 29 | + |
| 30 | +# append -dirty to the commit hash if the working directory has been modified |
| 31 | +SUBSTRATE_COMMIT := $(SUBSTRATE_COMMIT)$(shell git status | grep -q 'added to commit' && echo -dirty) |
| 32 | + |
| 33 | +# current version as tagged in ./VERSION |
| 34 | +SUBSTRATE_VERSION := $(shell cat VERSION) |
| 35 | + |
| 36 | +# if the current branch/tag == VERSION, we must be doing a final release build, |
| 37 | +# otherwise we're doing a "snapshot" build. |
| 38 | +ifneq ($(SUBSTRATE_VERSION),$(shell git describe --tags)) |
| 39 | +SUBSTRATE_VERSION := $(SUBSTRATE_VERSION)-snapshot |
| 40 | +endif |
| 41 | + |
| 42 | + |
| 43 | +############################################################################### |
| 44 | +# set up some cross-compilation variables |
| 45 | +############################################################################### |
| 46 | + |
| 47 | +# detect the host OS/arch (where this make is running) |
| 48 | +export HOST_TARGET ?= $(shell uname -s | tr A-Z a-z)-$(subst x86_64,amd64,$(shell uname -m)) |
| 49 | + |
| 50 | +# target platform/architectures for when we want to build a full release |
| 51 | +export RELEASE_TARGETS ?= linux-amd64 darwin-amd64 |
| 52 | + |
| 53 | +# define some helpers to extract just the platform or architecture from our target, |
| 54 | +# assuming the target is the pattern stem (%) value |
| 55 | +export PLATFORM = $(word 1, $(subst -, ,$*)) |
| 56 | +export ARCH = $(word 2, $(subst -, ,$*)) |
| 57 | + |
| 58 | + |
| 59 | +############################################################################### |
| 60 | +# define some additional top level variables |
| 61 | +############################################################################### |
| 62 | + |
| 63 | +# what version of Terraform we're bundling |
| 64 | +export TERRAFORM_VERSION := 0.8.3 |
| 65 | + |
| 66 | +# this is a directory we'll cache downloaded files in by default, we |
| 67 | +# can override this to point at $HOME/... in Jenkins to keep cached files |
| 68 | +# between builds |
| 69 | +export CACHE_DIR ?= $(CURDIR)/cache |
| 70 | + |
| 71 | +# this is the directory we'll use to store all intermediate build products |
| 72 | +export BUILD_DIR := $(CURDIR)/build |
| 73 | + |
| 74 | +# this is the directory we'll use for the final output binaries |
| 75 | +export BIN_DIR := $(CURDIR)/bin |
| 76 | + |
| 77 | +# we're going to do all builds inside an isolated GOPATH under BUILD_DIR |
| 78 | +export GOPATH := $(BUILD_DIR)/gopath |
| 79 | + |
| 80 | +# define a separate GOPATH only for tools that we need during the build |
| 81 | +export TOOLS_GOPATH := $(CACHE_DIR)/tools-$(HOST_TARGET) |
| 82 | + |
| 83 | + |
| 84 | +############################################################################### |
| 85 | +# define top level targets (ones you might type on the command line) |
| 86 | +############################################################################### |
| 87 | + |
| 88 | +# build (default target) compiles substrate for the current host platform |
| 89 | +# and copy to ./bin/substrate for convenience |
| 90 | +build: bin/substrate |
| 91 | +bin/substrate: $(BIN_DIR)/substrate-$(HOST_TARGET)-$(SUBSTRATE_VERSION) |
| 92 | + @cp -v $< $@ && touch $@ |
| 93 | + |
| 94 | +# build-release compiles substrate for all supported target platforms |
| 95 | +build-release: $(patsubst %,$(BIN_DIR)/substrate-%-$(SUBSTRATE_VERSION),$(RELEASE_TARGETS)) |
| 96 | + |
| 97 | +# clean should essentially revert back to a clean checkout |
| 98 | +# it should always run before any other top level targs |
| 99 | +clean: |
| 100 | + rm -rf $(BIN_DIR) $(BUILD_DIR) |
| 101 | + |
| 102 | +# fmt and lint are broken out into their own Makefile |
| 103 | +fmt lint: $(BUILD_DIR)/$(HOST_TARGET)/terraform |
| 104 | + @$(MAKE) -C util $@ TERRAFORM=$< SOURCE_DIR=$(CURDIR) GOPATH=$(TOOLS_GOPATH) | sed -e 's/^/[$@] /' |
| 105 | + |
| 106 | +# test only runs linters and checks that things compile for now |
| 107 | +test: lint build-release |
| 108 | + @echo WARNING: Substrate only has lint checks for now, not any real tests! |
| 109 | + |
| 110 | + |
| 111 | +############################################################################### |
| 112 | +# define rules to set up the Go build environment (isolated GOPATH) |
| 113 | +############################################################################### |
| 114 | + |
| 115 | +# directory of the substrate directory within GOPATH |
| 116 | +SUBSTRATE_PKG_DIR := $(GOPATH)/src/github.com/SimpleFinance/substrate |
| 117 | + |
| 118 | +# copied_go_sources returns a list of all the the .go source files, translated |
| 119 | +# into their destination path under the GOPATH |
| 120 | +copied_go_sources = $(patsubst %, $(SUBSTRATE_PKG_DIR)/%, $(shell find $1 -type f -name '*.go')) |
| 121 | +# copy our source files into the right place within the GOPATH package directory on demand |
| 122 | +$(SUBSTRATE_PKG_DIR)/%: % |
| 123 | + @mkdir -p $(@D) |
| 124 | + @cp $< $@ |
| 125 | +.PRECIOUS: $(SUBSTRATE_PKG_DIR)/% |
| 126 | + |
| 127 | +# GO_DEPS is a marker file so we can set up the Go environment when we need it |
| 128 | +# it needs to be updated whenever our Glide-specified dependencies change |
| 129 | +GO_DEPS := $(SUBSTRATE_PKG_DIR)/vendor/installed |
| 130 | +$(GO_DEPS): glide.yaml glide.lock |
| 131 | + @(go version | grep -q "go version") || (echo "You don't seem to have a valid Go toolchain, maybe GOROOT isn't set?"; exit 1) |
| 132 | + @mkdir -p $(@D) |
| 133 | + @cp glide.yaml glide.lock $(SUBSTRATE_PKG_DIR) |
| 134 | + cd $(SUBSTRATE_PKG_DIR) && glide --no-color install 2>&1 | sed -e 's/^/[glide] /' |
| 135 | + @touch $@ |
| 136 | + |
| 137 | +# update-deps updates the glide.lock file with the latest updates to glide.yaml |
| 138 | +# and any new package versions (subject to version constraints in glide.yaml) |
| 139 | +update-deps: $(GO_DEPS) |
| 140 | + cd $(SUBSTRATE_PKG_DIR) && glide --no-color update |
| 141 | + cp $(SUBSTRATE_PKG_DIR)/glide.lock glide.lock |
| 142 | + |
| 143 | + |
| 144 | +############################################################################### |
| 145 | +# install tools we need to do the build itself |
| 146 | +############################################################################### |
| 147 | + |
| 148 | +# go-bindata is a tool for bundling binary assets into a .go source file |
| 149 | +GOBINDATA := $(TOOLS_GOPATH)/bin/go-bindata |
| 150 | +$(GOBINDATA): |
| 151 | + GOPATH=$(TOOLS_GOPATH) go get -u github.com/jteeuwen/go-bindata/... |
| 152 | + @touch $@ |
| 153 | + |
| 154 | + |
| 155 | +############################################################################### |
| 156 | +# define rules to build our custom Terraform provider plugins |
| 157 | +############################################################################### |
| 158 | + |
| 159 | +# our custom terraform providers |
| 160 | +CUSTOM_PROVIDERS := \ |
| 161 | + terraform-provider-bakery \ |
| 162 | + terraform-provider-tarball |
| 163 | + |
| 164 | +# messy macro-laden loop which defines the build rules for all the custom providers |
| 165 | +CUSTOM_TERRAFORM_BINARIES:= |
| 166 | +define build_provider |
| 167 | +CUSTOM_TERRAFORM_BINARIES += $(BUILD_DIR)/%/$(1) |
| 168 | +$$(BUILD_DIR)/%/$(1): $$(GO_DEPS) $$(call copied_go_sources, providers/$(1)) |
| 169 | + GOOS=$$(PLATFORM) GOARCH=$$(ARCH) go build -o $$@ github.com/SimpleFinance/substrate/providers/$(1) |
| 170 | + @touch $$@ |
| 171 | +endef |
| 172 | +$(foreach p, $(CUSTOM_PROVIDERS),$(eval $(call build_provider,$(p)))) |
| 173 | +.PRECIOUS: $(CUSTOM_TERRAFORM_BINARIES) |
| 174 | + |
| 175 | + |
| 176 | +############################################################################### |
| 177 | +# define rules to download and extract the builtin Terraform providers we need |
| 178 | +############################################################################### |
| 179 | + |
| 180 | +#the builtin terraform binaries on which we depend |
| 181 | +BUILTIN_PROVIDERS := terraform |
| 182 | + |
| 183 | +# download the Terraform release zip for a particular platform/arch |
| 184 | +CACHED_TERRAFORM_ZIP := $(CACHE_DIR)/terraform-$(TERRAFORM_VERSION)-%.zip |
| 185 | +.PRECIOUS: $(CACHED_TERRAFORM_ZIP) # don't delete the cached zip between builds |
| 186 | +$(CACHED_TERRAFORM_ZIP): |
| 187 | + @mkdir -p $(@D) |
| 188 | + curl -s -o $@ https://releases.hashicorp.com/terraform/$(TERRAFORM_VERSION)/terraform_$(TERRAFORM_VERSION)_$(PLATFORM)_$(ARCH).zip |
| 189 | + @touch $@ |
| 190 | + |
| 191 | +TERRAFORM_ZIP := $(BUILD_DIR)/%/terraform-$(TERRAFORM_VERSION).zip |
| 192 | +.PRECIOUS: $(TERRAFORM_ZIP) |
| 193 | +$(TERRAFORM_ZIP): $(CACHED_TERRAFORM_ZIP) |
| 194 | + @mkdir -p $(@D) |
| 195 | + @cp $< $@ |
| 196 | + |
| 197 | +# extract the builtin terraform binaries we want into $BUILD_DIR/$TARGET/ |
| 198 | +BUILTIN_TERRAFORM_BINARIES := $(BUILD_DIR)/%/terraform |
| 199 | + |
| 200 | +$(BUILD_DIR)/%/terraform: $(TERRAFORM_ZIP) |
| 201 | + @mkdir -p $(@D) |
| 202 | + unzip -p $< $(notdir $@) > $@ |
| 203 | + @chmod +x $@ && touch $@ |
| 204 | +.PRECIOUS: $(BUILTIN_TERRAFORM_BINARIES) |
| 205 | + |
| 206 | +############################################################################### |
| 207 | +# define rules to bundle the (platform/arch specifc) binaries into a .go file |
| 208 | +############################################################################### |
| 209 | + |
| 210 | +# define a rule to bundle all our custom and builtin binaries into a .go source file |
| 211 | +CLI_BUNDLE_BINARIES := $(SUBSTRATE_PKG_DIR)/cmd/substrate/assets/binaries/data-%.go |
| 212 | +$(CLI_BUNDLE_BINARIES): $(CUSTOM_TERRAFORM_BINARIES) $(BUILTIN_TERRAFORM_BINARIES) | $(GOBINDATA) |
| 213 | + $(GOBINDATA) \ |
| 214 | + -pkg binaries \ |
| 215 | + -nomemcopy \ |
| 216 | + -nocompress \ |
| 217 | + -tags "$(PLATFORM),$(ARCH)" \ |
| 218 | + -prefix $(BUILD_DIR)/$(PLATFORM)-$(ARCH)/ \ |
| 219 | + -o $@ \ |
| 220 | + $^ |
| 221 | + @touch $@ |
| 222 | +.PRECIOUS: $(CLI_BUNDLE_BINARIES) |
| 223 | + |
| 224 | + |
| 225 | +############################################################################### |
| 226 | +# define rules to bundle the zone configuration (./zone) into a .go file |
| 227 | +############################################################################### |
| 228 | + |
| 229 | +# generate a bundle of the ./zone directory containing all our configuration files |
| 230 | +CLI_BUNDLE_ZONE_CONFIG := $(SUBSTRATE_PKG_DIR)/cmd/substrate/assets/zoneconfig/data.go |
| 231 | +$(CLI_BUNDLE_ZONE_CONFIG): $(shell find ./zone -not -iname "*~" -type f) | $(GOBINDATA) |
| 232 | + $(GOBINDATA) \ |
| 233 | + -pkg zoneconfig \ |
| 234 | + -nomemcopy \ |
| 235 | + -nocompress \ |
| 236 | + -o $@ \ |
| 237 | + $^ |
| 238 | + @touch $@ |
| 239 | +.PRECIOUS: $(CLI_BUNDLE_ZONE_CONFIG) |
| 240 | + |
| 241 | + |
| 242 | +############################################################################### |
| 243 | +# define the rule for building the final CLI binary from everything above |
| 244 | +############################################################################### |
| 245 | + |
| 246 | +# build the final `substrate` CLI binary for a particular target |
| 247 | +$(BIN_DIR)/substrate-%-$(SUBSTRATE_VERSION): $(CLI_BUNDLE_BINARIES) $(CLI_BUNDLE_ZONE_CONFIG) $(call copied_go_sources, cmd) |
| 248 | + @mkdir -p $(@D) |
| 249 | + GOOS=$(PLATFORM) GOARCH=$(ARCH) go build \ |
| 250 | + -o $@ \ |
| 251 | + -tags "$(PLATFORM),$(ARCH)" \ |
| 252 | + -ldflags "-X main.version=$(SUBSTRATE_VERSION) -X main.commit=$(SUBSTRATE_COMMIT)" \ |
| 253 | + github.com/SimpleFinance/substrate/cmd/substrate |
| 254 | + @touch $@ |
0 commit comments