Skip to content

Commit

Permalink
build: further mature make build process
Browse files Browse the repository at this point in the history
  • Loading branch information
dekobon committed Dec 21, 2022
1 parent dfef41b commit 853449b
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 109 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,4 @@ priority = "optional"
assets = [
{ source = "target/release/bunyan", dest = "/usr/bin/bunyan", mode = "755" },
{ source = "target/man/bunyan.1.gz", dest = "/usr/share/man/man1/bunyan.1.gz", mode = "644" },
{ source = "<path_relative_to_project_root>/*/apps/XXX.png", dest = "/usr/share/icons/hicolor/", mode = "644" },
]
13 changes: 12 additions & 1 deletion Containerfile.debian
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,22 @@ FROM rust:slim-buster
RUN set -eux \
export DEBIAN_FRONTEND=noninteractive; \
apt-get -qq update; \
apt-get -qq upgrade --yes; \
apt-get -qq install --yes --no-install-recommends --no-install-suggests \
ca-certificates \
gzip \
grep \
gawk \
sed \
make; \
make \
rpm \
dpkg-dev \
musl-dev \
musl-tools \
gcc-aarch64-linux-gnu \
libc6-dev-arm64-cross \
gcc-x86-64-linux-gnu \
libc6-dev-amd64-cross; \
rustup target install x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu x86_64-unknown-linux-musl; \
cargo install --quiet cargo-deb cargo-generate-rpm; \
rm -rf /var/lib/apt/lists/* /var/tmp/* /tmp/*;
11 changes: 0 additions & 11 deletions Containerfile.rocky

This file was deleted.

19 changes: 0 additions & 19 deletions Formula/bunyan_view.rb

This file was deleted.

136 changes: 59 additions & 77 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,34 @@ ifneq ($(shell test $(MAKE_MAJOR_VER) -gt 3; echo $$?),0)
$(error Make version $(MAKE_VERSION) is not supported, please install GNU Make 4.x)
endif

COMMITSAR_DOCKER := docker run --tty --rm --workdir /src -v "$(CURDIR):/src" aevea/commitsar
COMMITSAR ?= $(shell command -v commitsar 2> /dev/null)

GREP ?= $(shell command -v ggrep 2> /dev/null || command -v grep 2> /dev/null)
SED ?= $(shell command -v gsed 2> /dev/null || command -v sed 2> /dev/null)
AWK ?= $(shell command -v gawk 2> /dev/null || command -v awk 2> /dev/null)
DEB_ARCH := $(shell uname -m | $(SED) -e 's/x86_64/amd64/g' -e 's/i686/i386/g')
RUSTUP ?= $(shell command -v rustup 2> /dev/null)
RPM_ARCH := $(shell uname -m)
VERSION ?= $(shell $(GREP) -Po '^version\s+=\s+"\K.*?(?=")' $(CURDIR)/Cargo.toml)
CARGO := cargo
DOCKER := docker
DEFAULT_TARGET ?= $(shell $(RUSTUP) toolchain list | $(GREP) '(default)' | cut -d' ' -f1 | cut -d- -f2-)
SHELL := /bin/bash
OUTPUT_BINARY ?= bunyan
CARGO ?= cargo
DOCKER ?= docker
CHECKSUM ?= sha256sum
COMMITSAR_DOCKER := $(DOCKER) run --tty --rm --workdir /src -v "$(CURDIR):/src" aevea/commitsar
COMMITSAR ?= $(shell command -v commitsar 2> /dev/null)

# Define platform targets based off of the current host OS
# If we are running MacOS, then we can build for MacOS platform targets that have been installed in rustup
# If we are running Linux, then we can build for Linux platform targets that have been installed in rustup
UNAME = $(shell uname | tr '[:upper:]' '[:lower:]')
ifeq ($(UNAME),darwin)
TARGETS := $(sort $(shell $(RUSTUP) target list | $(GREP) '(installed)' | $(GREP) 'apple' | cut -d' ' -f1))
else ifeq ($(UNAME),linux)
TARGETS := $(sort $(shell $(RUSTUP) target list | $(GREP) '(installed)' | $(GREP) 'linux' | cut -d' ' -f1))
else
TARGETS := $(DEFAULT_TARGET)
endif

BUILD_FLAGS += --bin bunyan
RELEASE_BUILD_FLAGS ?= --quiet --release --bin $(OUTPUT_BINARY)

Q = $(if $(filter 1,$V),,@)
M = $(shell printf "\033[34;1m▶\033[0m")
Expand All @@ -40,88 +55,55 @@ commitsar: ## Run git commit linter
$Q $(info $(M) running commitsar...)
$(COMMITSAR)

.PHONY: all
all: target/debug/bunyan
.PHONY: list-targets
list-targets: ## List all available platform targets
$Q echo $(TARGETS) | $(SED) -e 's/ /\n/g'

target/%/bunyan:
$Q if [ ! -f "$(CURDIR)/$(@)" ]; then \
echo "$(M) building $(@) with flags [$(BUILD_FLAGS)]"; \
$(CARGO) build $(BUILD_FLAGS); \
.PHONY: all
all: $(TARGETS) ## Build all available platform targets [see: list-targets]

.PHONY: $(TARGETS)
.ONESHELL: $(TARGETS)
$(TARGETS): ## Build for a specific target
$Q if [ ! -f "$(CURDIR)/target/$(@)/release/$(OUTPUT_BINARY)" ]; then
echo "$(M) building $(OUTPUT_BINARY) with flags [$(RELEASE_BUILD_FLAGS) --target $(@)]"
$(CARGO) build $(RELEASE_BUILD_FLAGS) --target $@
fi

target:
$Q mkdir -p $@

.PHONY: debug
debug: target/debug/bunyan ## Create debug build for current platform
debug: target/debug/$(OUTPUT_BINARY) ## Build current platform target in debug mode

target/debug/$(OUTPUT_BINARY):
$Q echo "$(M) building $(OUTPUT_BINARY) in debug mode for the current platform"
$Q $(CARGO) build --bin $(OUTPUT_BINARY)

.PHONY: release
release: BUILD_FLAGS += --release
release: target/release/bunyan ## Create release build for current platform
release: target/release/$(OUTPUT_BINARY) ## Build current platform target in release mode

target/release/$(OUTPUT_BINARY):
$Q echo "$(M) building $(OUTPUT_BINARY) in release mode for the current platform"
$Q $(CARGO) build $(RELEASE_BUILD_FLAGS)

.PHONY: test
test: ## Run tests
$Q cargo test --features dumb_terminal
$Q $(CARGO) test --features dumb_terminal

.ONESHELL: target/man/bunyan.1.gz
target/man/bunyan.1.gz:
$(info $(M) processing manpage)
$Q mkdir -p target/man
$Q cp man/bunyan.1 target/man/bunyan.1
$Q $(SED) -i 's/%%VERSION%%/$(VERSION)/' target/man/bunyan.1
$Q gzip target/man/bunyan.1
$Q $(info $(M) building distributable manpage)
mkdir -p target/man
cp man/bunyan.1 target/man/bunyan.1
$(SED) -i 's/%%VERSION%%/$(VERSION)/' target/man/bunyan.1
gzip target/man/bunyan.1

target/gz:
$Q mkdir -p target/gz

.PHONY: manpage
manpage: target/man/bunyan.1.gz ## Builds man page

.PHONY: install-packaging-deb
install-packaging-deb:
$Q cargo install --quiet cargo-deb

.PHONY: install-packaging-rpm
install-packaging-rpm:
$Q cargo install --quiet cargo-generate-rpm

.PHONY: install-packaging-tools
install-packaging-tools: ## Installs tools needed for building distributable packages
$Q cargo install --quiet cargo-deb cargo-generate-rpm

target/debian/bunyan_view_%.deb: target/man/bunyan.1.gz
$Q if [ ! -f "$(CURDIR)/$(@)" ]; then \
echo "$(M) building debian package: $(@)"; \
cargo deb; \
fi

.PHONY: debian-package
debian-package: install-packaging-deb release manpage target/debian/bunyan_view_$(VERSION)_$(DEB_ARCH).deb ## Creates a debian package for the current platform

target/generate-rpm/bunyan_view_%.rpm: target/man/bunyan.1.gz
$Q if [ ! -f "$(CURDIR)/$(@)" ]; then \
echo "$(M) building rpm package: $(@)"; \
cargo generate-rpm; \
fi

.PHONY: rpm-package
rpm-package: install-packaging-rpm clean release manpage target/generate-rpm/bunyan_view_$(VERSION)_$(RPM_ARCH).rpm ## Creates a rpm package for the current platform

.PHONY: container-debian-build-image
container-debian-build-image: ## Builds a container image for building on Debian Linux
$Q if [ "$$($(DOCKER) images --quiet --filter=reference=bunyan_view_debian_builder)" = "" ]; then \
echo "$(M) building debian linux docker build image: $(@)"; \
$(DOCKER) build -t bunyan_view_debian_builder -f Containerfile.debian .; \
fi

.PHONY: container-debian-package
container-debian-package: container-debian-build-image ## Builds a rpm package using a the Debian Linux container image
$Q $(DOCKER) run --rm --tty --interactive --volume "$(CURDIR):/project" --workdir /project bunyan_view_debian_builder make debian-package

.PHONY: container-rocky-build-image
container-rocky-build-image: ## Builds a container image for building on Rocky Linux
$Q if [ "$$($(DOCKER) images --quiet --filter=reference=bunyan_view_rocky_builder)" = "" ]; then \
echo "$(M) building rocky linux docker build image: $(@)"; \
$(DOCKER) build -t bunyan_view_rocky_builder -f Containerfile.rocky .; \
fi

.PHONY: container-rpm-package
container-rpm-package: container-rocky-build-image ## Builds a rpm package using a the Rocky Linux container image
$Q $(DOCKER) run --rm --tty --interactive --volume "$(CURDIR):/project" --workdir /project bunyan_view_rocky_builder make rpm-package

.PHONY: container-test
container-test: container-debian-build-image ## Run tests inside container
$Q $(DOCKER) run --rm --tty --interactive --volume "$(CURDIR):/project" --workdir /project bunyan_view_rocky_builder make test
include $(CURDIR)/build/package.mk
include $(CURDIR)/build/container.mk
1 change: 1 addition & 0 deletions HomebrewFormula
34 changes: 34 additions & 0 deletions build/container.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.PHONY: container-debian-build-image
container-debian-build-image: ## Builds a container image for building on Debian Linux
$Q if [ "$$($(DOCKER) images --quiet --filter=reference=bunyan_view_debian_builder)" = "" ]; then \
echo "$(M) building debian linux docker build image: $(@)"; \
$(DOCKER) build -t bunyan_view_debian_builder -f Containerfile.debian .; \
fi

.PHONY: container-deb-packages
container-deb-packages: container-debian-build-image ## Builds deb packages using a container image
$Q $(DOCKER) run --rm --tty --interactive --volume "$(CURDIR):/project" --workdir /project bunyan_view_debian_builder make deb-packages
# Reset permissions on the target directory to the current user
if command -v id > /dev/null; then \
$(DOCKER) run --rm --tty --interactive --volume "$(CURDIR):/project" --workdir /project bunyan_view_debian_builder chown --recursive "$(shell id -u):$(shell id -g)" /project/target
fi

.PHONY: container-rpm-packages
container-rpm-packages: container-debian-build-image ## Builds a rpm packages using a container image
$Q $(DOCKER) run --rm --tty --interactive --volume "$(CURDIR):/project" --workdir /project bunyan_view_debian_builder make rpm-packages
# Reset permissions on the target directory to the current user
if command -v id > /dev/null; then \
$(DOCKER) run --rm --tty --interactive --volume "$(CURDIR):/project" --workdir /project bunyan_view_debian_builder chown --recursive "$(shell id -u):$(shell id -g)" /project/target
fi

.PHONY: container-all-packages
container-all-packages: container-debian-build-image ## Builds all packages using a container image
$Q $(DOCKER) run --rm --tty --interactive --volume "$(CURDIR):/project" --workdir /project bunyan_view_debian_builder make all-packages
# Reset permissions on the target directory to the current user
if command -v id > /dev/null; then \
$(DOCKER) run --rm --tty --interactive --volume "$(CURDIR):/project" --workdir /project bunyan_view_debian_builder chown --recursive "$(shell id -u):$(shell id -g)" /project/target
fi

.PHONY: container-test
container-test: container-debian-build-image ## Run tests inside container
$Q $(DOCKER) run --rm --tty --interactive --volume "$(CURDIR):/project" --workdir /project bunyan_view_rocky_builder make test
117 changes: 117 additions & 0 deletions build/package.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
.PHONY: install-packaging-deb
install-packaging-deb:
$Q if ! command -v cargo-deb > /dev/null; then \
$(CARGO) install --quiet cargo-deb; \
fi

.PHONY: install-packaging-rpm
install-packaging-rpm:
$Q if ! command -v cargo-generate-rpm > /dev/null; then \
$(CARGO) install --quiet cargo-generate-rpm; \
fi

.PHONY: install-packaging-tools
install-packaging-tools: ## Installs tools needed for building distributable packages
$Q $(CARGO) install --quiet cargo-deb cargo-generate-rpm

target/dist:
$Q mkdir -p $@

.PHONY: all-packages
all-packages: deb-packages rpm-packages gz-packages ## Builds all packages for all targets

target/dist/SHA256SUMS:
$Q cd target/dist && $(CHECKSUM) * > SHA256SUMS

.PHONY: checksums
checksums: target/dist/SHA256SUMS ## Generates checksums for all packages

######################################################################################################################
### Debian Packages
######################################################################################################################

to_debian_arch = $(shell echo $(1) | $(SED) -e 's/x86_64/amd64/' -e 's/aarch64/arm64/' -e 's/armv7/armhf/')
DEBIAN_PACKAGE_TARGETS := $(foreach t, $(TARGETS), target/$(t)/debian/bunyan-view_$(VERSION)_$(call to_debian_arch, $(firstword $(subst -, , $(t)))).deb)

.ONESHELL: $(DEBIAN_PACKAGE_TARGETS)
$(DEBIAN_PACKAGE_TARGETS): $(TARGETS) target/man/bunyan.1.gz target/dist
$Q TARGET="$(word 2, $(subst /, , $(dir $@)))"
# Skip building debs for musl targets
if echo "$(@)" | grep -q 'musl'; then \
exit 0
fi
if [ ! -f "$(CURDIR)/$(@)" ]; then
echo "$(M) building debian package for target [$${TARGET}]: $(@)"
$(CARGO) deb --no-build --target "$${TARGET}" --output "$(CURDIR)/$(@)"
ln -f -t "$(CURDIR)/target/dist/" "$(CURDIR)/$(@)"
fi

.PHONY: deb-packages
deb-packages: install-packaging-deb $(TARGETS) manpage $(DEBIAN_PACKAGE_TARGETS) ## Creates a debian package for the current platform

######################################################################################################################
### RPM Packages
######################################################################################################################

RPM_PACKAGE_TARGETS := $(foreach t, $(TARGETS), target/$(t)/generate-rpm/bunyan-view_$(VERSION)_$(firstword $(subst -, , $(t))).rpm)

.ONESHELL: $(RPM_PACKAGE_TARGETS)
$(RPM_PACKAGE_TARGETS): $(TARGETS) target/man/bunyan.1.gz target/dist
$Q TARGET="$(word 2, $(subst /, , $(dir $@)))"
ARCH="$(firstword $(subst -, , $(word 2, $(subst /, , $(dir $@)))))"
# Skip building rpms for musl targets
if echo "$(@)" | grep -q 'musl'; then \
exit 0
fi
if [ ! -f "$(CURDIR)/$(@)" ]; then
if [ -d "$(CURDIR)/target/release" ]; then \
echo "$(M) removing existing release directory: $(CURDIR)/target/release"
rm -rf "$(CURDIR)/target/release"
fi
echo "$(M) copying target architecture [$${ARCH}] build to target/release directory"
cp -r "$(CURDIR)/target/$${TARGET}/release" "$(CURDIR)/target/release"
echo "$(M) building rpm package: $(@)"
$(CARGO) generate-rpm --arch "$${ARCH}" --target "$${TARGET}" --output "$(CURDIR)/$(@)"
rm -rf "$(CURDIR)/target/release"
ln -f -t "$(CURDIR)/target/dist/" "$(CURDIR)/$(@)"
fi

.PHONY: rpm-packages
rpm-packages: install-packaging-rpm $(TARGETS) manpage $(RPM_PACKAGE_TARGETS) ## Creates a rpm package for the current platform

######################################################################################################################
### Homebrew Packages
######################################################################################################################

.PHONY: homebrew-packages
.ONESHELL: homebrew-packages
homebrew-packages: target/dist/SHA256SUMS
$Q VERSION="$(VERSION)" \
AARCH64_UNKNOWN_LINUX_GNU_SHA256="$$($(GREP) bunyan-view_v$(VERSION)_aarch64-unknown-linux-gnu.tar.gz $(CURDIR)/target/dist/SHA256SUMS | cut -d ' ' -f 1)" \
X86_64_UNKNOWN_LINUX_GNU_SHA256="$$($(GREP) bunyan-view_v$(VERSION)_x86_64-unknown-linux-gnu.tar.gz $(CURDIR)/target/dist/SHA256SUMS | cut -d ' ' -f 1)" \
X86_64_APPLE_DARWIN_SHA256="$$($(GREP) bunyan-view_v$(VERSION)_x86_64-apple-darwin.tar.gz $(CURDIR)/target/dist/SHA256SUMS | cut -d ' ' -f 1)" \
AARCH64_APPLE_DARWIN_SHA256="$$($(GREP) bunyan-view_v$(VERSION)_aarch64-apple-darwin.tar.gz $(CURDIR)/target/dist/SHA256SUMS | cut -d ' ' -f 1)" \
envsubst < pkg/brew/bunyan-bin.rb.template > $(CURDIR)/pkg/brew/bunyan-bin.rb


######################################################################################################################
### Tarball Packages
######################################################################################################################

GZ_PACKAGE_TARGETS = $(foreach t, $(TARGETS), target/gz/$(t)/bunyan-view_$(VERSION)_$(firstword $(subst -, , $(t))).tar.gz)

.ONESHELL: $(GZ_PACKAGE_TARGETS)
$(GZ_PACKAGE_TARGETS): $(TARGETS) target/man/bunyan.1.gz target/dist
$Q mkdir -p "$(CURDIR)/target/gz"
TARGET="$(word 3, $(subst /, , $(dir $@)))"
PACKAGE="$(CURDIR)/target/gz/bunyan-view_v$(VERSION)_$${TARGET}.tar.gz"
if [ ! -f "$${PACKAGE}}" ]; then
tar -cz -f $${PACKAGE} \
-C $(CURDIR)/target/man bunyan.1.gz \
-C $(CURDIR)/target/$${TARGET}/release bunyan \
-C $(CURDIR) LICENSE.txt
ln -f -t "$(CURDIR)/target/dist/" "$${PACKAGE}"
fi

.PHONE: gz-packages
gz-packages: $(GZ_PACKAGE_TARGETS) ## Creates a gzipped tarball all target platforms
Loading

0 comments on commit 853449b

Please sign in to comment.