Created
March 11, 2025 15:08
-
-
Save barries/72aa6a96873bf65d4e8a8a8c1c9f295c to your computer and use it in GitHub Desktop.
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
| ################################################################################ | |
| # Make configuration | |
| # | |
| # Most variables are non-recursive ("simple expanded" to be technical) for | |
| # speed. `override` is necessary to rewrite variables that could be in the | |
| # environment or on the command line. This speed improvement is not relevant on | |
| # small projects, but non-recursive variables are easier for non make gurus to | |
| # work with. | |
| # --no-builtin-rules: prevent make from scanning filesystem for many possible | |
| # dependencies. | |
| # | |
| # --output-sync=recurse: Don't intermingle concurrent recipes' output. | |
| # | |
| # --jobs=...: Allow 5 more than number of CPUs (should occupy all CPUs because | |
| # some will block on I/O now and then. | |
| # | |
| # These get passed to $(MAKE) invocations, along with file descriptors to talk | |
| # to the jobserver. This can confuse some projects' (eg buildroot's) Makefiles; | |
| # if so use `$(MAKE) MAKEFLAGS= ...` to prevent that confusion. | |
| MAKEFLAGS := --no-builtin-rules --output-sync=recurse --jobs=$(shell echo $$((`nproc` + 5))) | |
| # Don't search implicit rules | |
| .SUFFIXES: | |
| # Entire recipe is a single bash script | |
| .ONESHELL: | |
| SHELL := bash | |
| # Put bash into strict mode | |
| .SHELLFLAGS := -E -e -u -o pipefail -c | |
| # Don't delete intermediate files | |
| .SECONDARY: | |
| # Delete output files on error. | |
| # | |
| # This doesn't help if `make` is killed by, say, kill -9 or a system crash, | |
| # so rules should use the "output to a temp file, rename the temp file" | |
| # pattern anyway. This is just provided as a helpful default in case a rule | |
| # doesn't do that. | |
| .DELETE_ON_ERROR: | |
| ################################################################################ | |
| # Configuration | |
| VERSION := TBD | |
| ################################################################################ | |
| # Usage and Help text | |
| define COMMANDS | |
| make # Make everything | |
| make os # Make output/my_os-$(VERSION).img | |
| make ui # Make output/my_ui-$(VERSION) | |
| make clean # Delete tmp/* and output/* | |
| make sboms # Create SBOM files | |
| make help # Print other commands | |
| make VERBOSE=0 ... # Don't print targets before they're made | |
| make VERBOSE=1 ... # Print shell commands as they are executed | |
| endef | |
| define HELP | |
| Usage: | |
| make [variables] targets... | |
| Common Commands: | |
| $(COMMANDS) | |
| Other Commands: | |
| make buildroot # Create tmp/buildroot/ | |
| make clean_buildroot # Delete tmp/buildroot/ | |
| endef | |
| ################################################################################ | |
| # Functions and Special Variables | |
| ifeq ($(VERBOSE),0) | |
| # Squelch "Making $@" messages | |
| TRACE_COMMAND := @ | |
| else | |
| TRACE_COMMAND = @echo "Making $@" | |
| ifneq ($(VERBOSE),) | |
| override .SHELLFLAGS := $(.SHELLFLAGS) -x | |
| endif | |
| endif | |
| # ..._TARGET variables | |
| # | |
| # These ..._TARGET variables allow shell scripts to refer to the target | |
| # regardless of what directory they're in, handle spaces in $PWD, and are | |
| # somewhat more self-documenting than "$@". | |
| # | |
| # They're recursive so that the $@s aren't expanded until the recipe is run. | |
| # | |
| ABS_TARGET = $(abspath $@) | |
| TMP_TARGET = $(ABS_TARGET).tmp | |
| MV_TMP_TO_TARGET = mv "$(TMP_TARGET)" "$(ABS_TARGET)" | |
| TOUCH_TARGET = touch "$(ABS_TARGET)" | |
| ################################################################################ | |
| # Top Level Rules | |
| # | |
| # Don't depend on the .PHONY targets in non-.PHONY rules to prevent unnecessary | |
| # recipe runs. | |
| .PHONY: all | |
| all: os | |
| .PHONY: clean | |
| clean: clean_buildroot | |
| $(TRACE_COMMAND) | |
| rm -rf tmp/* */tmp/* | |
| DIR="$$PWD" | |
| CARGO_DIRS=($(dir $(wildcard */Cargo.toml))) | |
| for CARGO_DIR in "$${CARGO_DIRS[@]}"; do | |
| cd $$CARGO_DIR | |
| cargo clean | |
| cd $$DIR | |
| done | |
| .PHONY: clean_buildroot | |
| clean_buildroot: | |
| $(TRACE_COMMAND) | |
| rm -rf tmp/buildroot tmp/sentinels/buildroot* | |
| .PHONY: buildroot | |
| buildroot: tmp/buildroot/buildroot_configured.sentinel | |
| tmp/buildroot/buildroot_configured.sentinel: tmp/buildroot/buildroot_untarred.sentinel | |
| $(TRACE_COMMAND) | |
| cd tmp/buildroot | |
| # Remove paths with spaces to avoid a make limitation | |
| PATH=`echo "$$PATH" | sed -e 's/\(:\|\)[^:]* [^:]*\(:\|$$\)/\1\2/g' | sed -e 's/::\+/:/g'` | |
| $(MAKE) BR2_EXTERNAL=../../os my_console_1_0_defconfig | |
| $(TOUCH_TARGET) | |
| .PHONY: tmp/buildroot | |
| tmp/buildroot: tmp/buildroot/buildroot_untarred.sentinel | |
| tmp/buildroot/buildroot_untarred.sentinel: | tmp/buildroot_untar/ | |
| $(TRACE_COMMAND) | |
| cd tmp/buildroot_untar | |
| tar xf ../../os/buildroot*.*z | |
| rm -rf ../buildroot | |
| mv * ../buildroot | |
| cd .. | |
| rmdir buildroot_untar | |
| $(TOUCH_TARGET) | |
| .PHONY: cargo_vendor | |
| cargo_vendor: tmp/buildroot/.cargo/config.toml | |
| tmp/buildroot/.cargo/config.toml: tmp/buildroot/buildroot_configured.sentinel | |
| $(TRACE_COMMAND) | |
| # Vendor deps because buildroot builds with --offline and can't fetch them. Put the Cargo.toml | |
| # snippet where buildroot's host cargo can find it. | |
| # mkdir here instead of with an order-only dependency because the order-only approach | |
| # causes the directory to be made before tmp/buildroot/buildroot_configured.sentinel runs, and that | |
| # recipe deletes it. | |
| [[ ! -d "$(dir $@)" ]] && mkdir "$(dir $@)" | |
| cd ui | |
| cargo vendor --quiet --locked --versioned-dirs "../tmp/cargo_vendor" | sed "s:/tmp/:/:" > "../$@.tmp" | |
| cd .. | |
| mv "$@.tmp" "$@" | |
| .PHONY: help | |
| help: | |
| @$(info $(HELP)) | |
| # | |
| .PHONY: os | |
| os: ../output/my_os-$(VERSION).img ../output/my_os-$(VERSION).cyclonedx.json | |
| .PHONY: print_commands | |
| print_commands: | |
| @$(info $(COMMANDS)) | |
| # | |
| .PHONY: sboms | |
| sboms: ../output/my_os-$(VERSION).cyclonedx.json | |
| # TODO: implement UI SBOM generaiton | |
| .PHONY: ui | |
| ui: ../output/my_ui-$(VERSION) # TODO (when cargo SBOM support released): SBOM via cargo | |
| ################################################################################ | |
| # Internal Rules | |
| OS_PREREQUISITES := $(shell find os -type f -not \( -path "os/docs/*" -o -path os/README.md \)) | |
| tmp/buildroot/output/images/disk.img: $(OS_PREREQUISITES) tmp/buildroot/.cargo/config.toml | |
| $(TRACE_COMMAND) | |
| cd tmp/buildroot | |
| # Remove paths with spaces to avoid a make limitation | |
| PATH=`echo "$$PATH" | sed -e 's/\(:\|\)[^:]* [^:]*\(:\|$$\)/\1\2/g' | sed -e 's/::\+/:/g'` | |
| env | |
| $(MAKE) MAKEFLAGS= > ../make_log.txt 2>&1 || ( | |
| EXIT_CODE=$$? | |
| tail -n 100 ../make_log.txt | |
| exit $$EXIT_CODE | |
| ) | |
| ../output/my_os-$(VERSION).img: tmp/buildroot/output/images/disk.img | |
| $(TRACE_COMMAND) | |
| cp $^ output | |
| ../output/my_os-$(VERSION).cyclonedx.json: tmp/buildroot/buildroot_configured.sentinel | |
| $(TRACE_COMMAND) | |
| cd tmp/buildroot | |
| # Remove paths with spaces to avoid a make limitation | |
| PATH=`echo "$$PATH" | sed -e 's/\(:\|\)[^:]* [^:]*\(:\|$$\)/\1\2/g' | sed -e 's/::\+/:/g'` | |
| $(MAKE) MAKEFLAGS= --silent show-info | utils/generate-cyclonedx | jaq '.' > "$(TMP_TARGET)" | |
| $(MV_TMP_TO_TARGET) | |
| ../output/my_ui-$(VERSION): ui/target/debug/my-ui | ../output/ | |
| $(TRACE_COMMAND) | |
| cp $^ "$(TMP_TARGET)" | |
| $(MV_TMP_TO_TARGET) | |
| UI_PREREQUISITES := $(shell find ui/assets ui/Cargo.*; find ui -type f -name "*.toml" -o -name "*.rs") | |
| ui/target/debug/my-ui: $(UI_PREREQUISITES) | |
| $(TRACE_COMMAND) | |
| cd ui | |
| cargo build | |
| ################################################################################ | |
| # Pattern Rules | |
| %/: | |
| $(TRACE_COMMAND) | |
| mkdir -p $@ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment