Created
September 25, 2015 20:30
-
-
Save akutz/d5d4e9a85663e69806bf to your computer and use it in GitHub Desktop.
A makefile example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
STAT_FILE_SIZE = stat --format '%s' $$FILE 2> /dev/null || stat -f '%z' $$FILE 2> /dev/null | |
CALC_FILE_SIZE := BYTES=$$($(STAT_FILE_SIZE)); SIZE=$$(($$BYTES / 1024 / 1024)); printf "$${SIZE}MB" | |
PRINT_FILE_SIZE := $(STAT_FILE_SIZE) $(CALC_FILE_SIZE) | |
MAX_PAD := 80 | |
STATUS_DELIM := .................................................................................................... | |
START_STATUS = export FILE=$(1); export PAD_LEN=$$(($(MAX_PAD) - $${\#FILE})); printf "$$FILE" | |
PRINT_STATUS = export EC=$$?; cd $(_); if [ "$$EC" -eq "0" ]; then printf "%*.*s%s\n" 0 $$PAD_LEN "$(STATUS_DELIM)" "SUCCESS!"; else exit $$EC; fi | |
PARSE_RESULT = export EC=$$?; cd $(_); if [ "$$EC" -ne "0" ]; then exit $$EC; fi | |
GET_GOOS = $(shell echo $(1) | tr A-Z a-z) | |
GET_GOARCH = $(shell if [ "$(1)" = "x86_64" ]; then echo amd64; else echo 386; fi) | |
BINDIR := .bin | |
RPMDIR := .rpm | |
TSTDIR := .tst | |
NOT_PATH := -not -path './.*' -not -path './vendor/*' | |
PKG_PARS := { while read F; do F=$${F\#.}; F=$${F%/*}; if [ "$$F" != "" ]; then echo $$F; fi; done } | sort | uniq | |
IF_MAIN = { while read F; do grep '^package main' $$F > /dev/null; if [ "$$?" $(1) "0" ]; then echo $$F; fi; done; } | |
IF_MAIN_TRUE := $(call IF_MAIN,-eq) | |
IF_MAIN_FALSE := $(call IF_MAIN,-ne) | |
FIND_SRCS := find . -type f -name "*.go" | |
SRCS := $(shell $(FIND_SRCS) $(NOT_PATH) -not -path '*/*test.go' | tr '\n' ' ') | |
PKGS := $(shell $(FIND_SRCS) $(NOT_PATH) | $(IF_MAIN_FALSE) | $(PKG_PARS)) | |
MAIN_PKG := .$(shell $(FIND_SRCS) $(NOT_PATH) | $(IF_MAIN_TRUE) | $(PKG_PARS)) | |
MAIN_NAME := $(notdir $(MAIN_PKG)) | |
FIND_TSTS := find . -type f -name "*test.go" | |
TEST_PKGS := $(shell $(FIND_TSTS) $(NOT_PATH) | $(IF_MAIN_FALSE) | $(PKG_PARS)) | |
TEST_SRCS := $(shell $(FIND_TSTS) $(NOT_PATH) | tr '\n' ' ') | |
TESTS := $(shell for P in $(TEST_PKGS); do echo $(BUILD)/$$P$$(basename $$P).test; done) | |
ALL_SRCS := $(SRCS) $(TEST_SRCS) | |
VENDOR := vendor | |
$(VENDOR): glide.yaml | |
@$(call START_STATUS,"glide up") | |
$(GLIDE) -q up 2> /dev/null | |
$(PRINT_STATUS) | |
define OBJS_TARGET | |
OBJS_SRC_PKG_$1 := .$$(basename $$(subst $2,,$1)) | |
ifeq ($$(OBJS_SRC_PKG_$1),.) | |
OBJS_SRC_PKG_$1 := ./ | |
endif | |
ifeq ($$(origin OFFLINE), undefined) | |
OBJS_SRC_PKG_GOGET_$1 = $$(GO) get -d ./$$(dir $$(1)) | |
else | |
OBJS_SRC_PKG_GOGET_$1 = echo "" > /dev/null | |
endif | |
$1: $$(wildcard $$(OBJS_SRC_PKG_$1)/*.go) | $$(VENDOR) | |
@$$(call START_STATUS,$3-$4/$$(BASEPKG)$$(subst $2,,$1)) | |
$$(GO) fmt $$? | |
$$(GO) fix $$? | |
$$(call OBJS_SRC_PKG_GOGET_$1,$$<) | |
env GOOS=$3 GOARCH=$4 $$(GO) \ | |
build \ | |
-buildmode=archive \ | |
-o $1 \ | |
$$(GOFLAGS) $$(LDFLAGS) \ | |
$$(OBJS_SRC_PKG_$1) | |
$$(PRINT_STATUS) | |
endef | |
define BUILD_PLATFORM_TARGET | |
BLD_$1 := $$(BINDIR)/$1 | |
BIN_FILE_$1 := $$(MAIN_NAME) | |
BIN_$1 := $$(BLD_$1)/$$(BIN_FILE_$1) | |
TGZ_FILE_$1 := $$(BIN_FILE_$1)-$1.$$(V_SEMVER).tar.gz | |
TGZ_FILE_LATEST_$1 := $$(BIN_FILE_$1)-$1.tar.gz | |
TGZ_$1 := $$(BLD_$1)/$$(TGZ_FILE_$1) | |
TGZ_LATEST_$1 := $$(BLD_$1)/$$(TGZ_FILE_LATEST_$1) | |
RPM_FILE_$1 := $$(BIN_FILE_$1)-$$(V_RPM_SEMVER)-1.$$(V_ARCH).rpm | |
RPM_FILE_LATEST_$1 := $$(BIN_FILE_$1)-latest-$$(V_ARCH).rpm | |
RPM_$1 := $$(BLD_$1)/$$(RPM_FILE_$1) | |
RPM_LATEST_$1 := $$(BLD_$1)/$$(RPM_FILE_LATEST_$1) | |
DEB_FILE_$1 := $$(BIN_FILE_$1)_$$(V_RPM_SEMVER)-1_amd64.deb | |
DEB_FILE_LATEST_$1 := $$(BIN_FILE_$1)-latest-$$(V_ARCH).deb | |
DEB_$1 := $$(BLD_$1)/$$(DEB_FILE_$1) | |
DEB_LATEST_$1 := $$(BLD_$1)/$$(DEB_FILE_LATEST_$1) | |
V_OS_ARCH_$1 := $1 | |
V_OS_$1 := $$(firstword $$(subst -, ,$$(V_OS_ARCH_$1))) | |
V_ARCH_$1 := $$(lastword $$(subst -, ,$$(V_OS_ARCH_$1))) | |
GOOS_$1 := linux | |
#$$(call GET_GOOS,$$(V_OS_$1)) | |
GOARCH_$1 := amd64 | |
#$$(call GET_GOARCH,$$(V_ARCH_$1)) | |
PKG_DIR_$1 := .obj/$$(V_OS_ARCH_$1) | |
OBJS_PREFIX_$1 := $$(GOPATH)/pkg/$$(GOOS_$1)_$$(GOARCH_$1)/$$(BASEPKG) | |
OBJS_$1 := $$(OBJS_PREFIX_$1).a $$(addsuffix .a,$$(addprefix $$(OBJS_PREFIX_$1),$$(PKGS))) | |
$$(foreach o,$$(OBJS_$1),$$(eval $$(call OBJS_TARGET,$$(o),$$(OBJS_PREFIX_$1),$$(GOOS_$1),$$(GOARCH_$1)))) | |
objs: $$(OBJS_$1) | |
build-$$(V_OS_ARCH_$1): $$(BIN_$1) | |
build-$$(GOOS_$1)-$$(GOARCH_$1): $$(BIN_$1) | |
$$(BIN_$1): $$(OBJS_$1) $$(wildcard $$(MAIN_PKG)/*.go) | $$(VENDOR) | |
@$$(call START_STATUS,$$(BIN_$1)) | |
env GOOS=$$(GOOS_$1) GOARCH=$$(GOARCH_$1) $$(GO) | |
build \ | |
-buildmode=exe \ | |
-o $$(BIN_$1) \ | |
$$(GOFLAGS) $$(LDFLAGS) \ | |
$$(MAIN_PKG) | |
$$(PRINT_STATUS) | |
tgz-$$(V_OS_ARCH_$1): $$(TGZ_$1) | |
tgz-$$(GOOS_$1)-$$(GOARCH_$1): $$(TGZ_$1) | |
$$(TGZ_$1): $$(BIN_$1) | |
@$$(call START_STATUS,$$(TGZ_$1)) | |
tar -C $$(BLD_$1) -czf $$(TGZ_$1) $$(BIN_FILE_$1) | |
$$(PRINT_STATUS) | |
tgz-latest-$$(V_OS_ARCH_$1): $$(TGZ_LATEST_$1) | |
tgz-latest-$$(GOOS_$1)-$$(GOARCH_$1): $$(TGZ_LATEST_$1) | |
$$(TGZ_LATEST_$1): $$(TGZ_$1) | |
@$$(call START_STATUS,$$(TGZ_LATEST_$1)) | |
cd $$(BLD_$1) | |
cp -f $$(TGZ_FILE_$1) $$(TGZ_FILE_LATEST_$1) | |
$$(PRINT_STATUS) | |
rpm-$$(V_OS_ARCH_$1): $$(RPM_$1) | |
rpm-$$(GOOS_$1)-$$(GOARCH_$1): $$(RPM_$1) | |
$$(RPM_$1): $$(BIN_$1) $$(MAIN_NAME).spec | |
ifeq ($$(V_OS),Linux) | |
@$$(call START_STATUS,$$(RPM_$1)) | |
rm -fr $$(RPMDIR) | |
mkdir -p \ | |
$$(RPMDIR)/BUILD \ | |
$$(RPMDIR)/RPMS \ | |
$$(RPMDIR)/SRPMS \ | |
$$(RPMDIR)/SOURCES \ | |
$$(RPMDIR)/tmp | |
ln -s ../../$$(BLD_$1) $$(RPMDIR)/RPMS/$$(V_ARCH_$1) | |
ln -s .. $$(RPMDIR)/SPECS | |
cd $$(RPMDIR) | |
setarch $$(V_ARCH_$1) rpmbuild -ba --quiet \ | |
-D "rpmbuild $$(_)/$$(RPMDIR)" \ | |
-D "v_semver $$(V_RPM_SEMVER)" \ | |
-D "v_arch $$(V_ARCH_$1)" \ | |
-D "binfile $$(_)/$$(BIN_$1)" \ | |
../$$(MAIN_NAME).spec | |
$$(PRINT_STATUS) | |
endif | |
rpm-latest-$$(V_OS_ARCH_$1): $$(RPM_LATEST_$1) | |
rpm-latest-$$(GOOS_$1)-$$(GOARCH_$1): $$(RPM_LATEST_$1) | |
$$(RPM_LATEST_$1): $$(RPM_$1) | |
ifeq ($$(V_OS),Linux) | |
@$$(call START_STATUS,$$(RPM_LATEST_$1)) | |
cd $$(BLD_$1) | |
cp -f $$(RPM_FILE_$1) $$(RPM_FILE_LATEST_$1) | |
$$(PRINT_STATUS) | |
endif | |
deb-$$(V_OS_ARCH_$1): $$(DEB_$1) | |
deb-$$(GOOS_$1)-$$(GOARCH_$1): $$(DEB_$1) | |
$$(DEB_$1): $$(RPM_$1) | |
ifeq ($$(V_OS),Linux) | |
@$$(call START_STATUS,$$(DEB_$1)) | |
cd $$(BLD_$1) | |
fakeroot alien -k -c --bump=0 $$(RPM_FILE_$1) > /dev/null | |
$$(PRINT_STATUS) | |
endif | |
deb-latest-$$(V_OS_ARCH_$1): $$(DEB_LATEST_$1) | |
deb-latest-$$(GOOS_$1)-$$(GOARCH_$1): $$(DEBLATEST_$1) | |
$$(DEB_LATEST_$1): $$(DEB_$1) | |
ifeq ($$(V_OS),Linux) | |
@$$(call START_STATUS,$$(DEB_LATEST_$1)) | |
cd $$(BLD_$1) | |
cp -f $$(DEB_FILE_$1) $$(DEB_FILE_LATEST_$1) | |
$$(PRINT_STATUS) | |
endif | |
endef | |
$(foreach b,$(BUILD_PLATFORMS),$(eval $(call BUILD_PLATFORM_TARGET,$(b)))) | |
build: build-$(V_OS_ARCH) | |
tgz: tgz-$(V_OS_ARCH) | |
rpm: rpm-$(V_OS_ARCH) | |
deb: deb-$(V_OS_ARCH) | |
tgz-latest: tgz-latest-$(V_OS_ARCH) | |
rpm-latest: rpm-latest-$(V_OS_ARCH) | |
deb-latest: deb-latest-$(V_OS_ARCH) | |
define TEST_TARGET | |
$1: $$(SRCS) $$(wildcard $$(dir $1)*test.go) | |
@printf "building $1..." | |
go test -c ./$$(@D) -o $$@ | |
$$(PRINT_STATUS) | |
endef | |
$(foreach t,$(TESTS),$(eval $(call TEST_TARGET,$(t)))) | |
test: $(TESTS) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment