######## dir_guard=@mkdir -p $(@D) ######## define add_distro # Avoid nested distro section ifdef DISTRO_NAME $$(error Nested distro section is not allowed! Currently in "$$(DISTRO_NAME)") endif undefine DISTRO_NAME undefine PACKAGE_MANAGER $$(eval $$(call stack_include,$1/distro.mk)) ifndef DISTRO_NAME $$(error DISTRO_NAME not provided) endif ifndef PACKAGE_MANAGER $$(error PACKAGE_MANAGER not provided) endif undefine DISTRO_NAME undefine PACKAGE_MANAGER endef ######## define add_distro_release ifndef DISTRO_NAME $$(error Not within distro section) endif ifdef RELEASE_NAME $$(error Nested distro release section is not allowed! Currently in "$$(DISTRO_NAME) $$(RELEASE_NAME)") endif undefine RELEASE_NAME $$(eval $$(call stack_include,$1/release.mk)) ifndef RELEASE_NAME $$(error RELEASE_NAME not provided) endif $$(DISTRO_NAME)_$$(RELEASE_NAME)_RECEIPES := undefine RELEASE_NAME endef ######## define add_receipe ifndef RELEASE_NAME $$(error Not within distro release section) endif # Cleanup and register new receipe undefine RECEIPE_NAME undefine COMPRESSION undefine EXTENDS $$(eval $$(call stack_include,$1/receipe.mk)) # Check name ifndef RECEIPE_NAME $$(error RECEIPE_NAME not defined) endif # Check compression method ifeq ($$(COMPRESSION),zstd) COMPRESSION_SUFFIX := tar.zst COMPRESSION_CMD := tar --use-compress-program=zstd -cf "$$$$$$$${OUTPUT_ARCHIVE}" -C "$$$$$$$${ROOTFS_DIR}" . else $$(error Unsupported compression mode) endif # Define global references $$(DISTRO_NAME)_$$(RELEASE_NAME)_RECEIPES := $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_RECEIPES) $$(RECEIPE_NAME) $$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_DIR := $1 $$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_ARTIFACT := $(DIST_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/$$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(RECEIPE_NAME)-rootfs.$$(COMPRESSION_SUFFIX) ROOTFS_TARGETS += $$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(RECEIPE_NAME)-rootfs # Populate workdir # Ensure prereq exists define check_receipe_exist ifndef $$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(1)_DIR $$$$(error $$(RECEIPE_NAME) requires $$(1), but it is missing) endif endef $$(foreach dep,$$(EXTENDS),$$(eval $$(call check_receipe_exist,$$(dep)))) undefine check_receipe_exist # Does not contains itself, may be referenced by other receipes $$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_DEPS := $$(foreach depname,$$(EXTENDS),$$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(depname)_DEPS) $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(depname)_DIR)) # Itself is listed for constructing current receipe $$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_DEPS_FULL := $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_DEPS) $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_DIR) $$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_DEPS_FULL := $$(foreach dep,$$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_DEPS_FULL),$$(dep)/) define GENERATE_SYNC_TARGET $(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/receipes/$$(RECEIPE_NAME): $$$$(foreach dep,$$$$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_DEPS_FULL),$$$$(shell find -L $$$$(dep) -type f,d | tr '\n' ' ')) $$$$(dir_guard) $(ECHOCTL)rm -rf "$$$$@" @# Not preserving modification time, aka -t $(ECHOCTL)rsync -rLpgoD --exclude receipe.mk $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_DEPS_FULL) $$$$@ endef # Introduce one level of indirection to evaluate receipes ahead of time $$(eval $$(GENERATE_SYNC_TARGET)) # Define entry target .PHONY: $$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(RECEIPE_NAME)-rootfs $$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(RECEIPE_NAME)-rootfs: $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_ARTIFACT) define GENERATE_TAR_TARGET $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_ARTIFACT): $(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/receipes/$$(RECEIPE_NAME) $$$$(dir_guard) $(ECHOCTL)$(CONTAINER_CMD) run --rm \ -v $(ROOT_DIR)/tools:/image-builder/tools:ro \ -v $$$$<:/image-builder/receipe:ro \ -v $$$$(dir $$$$@):/image-builder/output \ $(CONTAINER_IMAGE_TAG) \ /bin/sh -c ' \ mkdir /tmp/rootfs && \ cd /image-builder/tools && \ LOG_LEVEL=$(LOG_LEVEL) ./build_rootfs.sh -i /image-builder/receipe -o /tmp/rootfs -p $$(PACKAGE_MANAGER) && \ export OUTPUT_ARCHIVE=/image-builder/output/$$$$(notdir $$$$@) && \ export ROOTFS_DIR=/tmp/rootfs && \ $$(COMPRESSION_CMD)' endef $$(eval $$(GENERATE_TAR_TARGET)) # Reset registers again undefine GENERATE_TAR_TARGET undefine EXTENDS undefine COMPRESSION_CMD undefine COMPRESSION_SUFFIX undefine COMPRESSION undefine RECEIPE_NAME endef ######## define add_device ifndef RELEASE_NAME $$(error Not within distro release section) endif ifdef DEVICE_NAME $$(error Nested device section is not allowed! Currently in "$$(DISTRO_NAME) $$(RELEASE_NAME) $$(DEVICE_NAME)") endif undefine DEVICE_NAME $$(eval $$(call stack_include,$1/device.mk)) ifndef DEVICE_NAME $$(error DEVICE_NAME not provided) endif undefine DEVICE_NAME endef ######## define add_device_profile ifndef DEVICE_NAME $$(error Not within device section) endif ifdef PROFILE_NAME $$(error Nested profile section is not allowed! Currently in "$$(DISTRO_NAME) $$(RELEASE_NAME) $$(DEVICE_NAME)" $$(PROFILE_NAME)) endif undefine PROFILE_NAME $$(eval $$(call stack_include,$1/profile.mk)) ifndef PROFILE_NAME $$(error PROFILE_NAME not provided) endif BSP_PROFILE_DIR := $1 define GENERATE_RECEIPE_PROFILE_MATRIX BSP_TARGETS += $$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(1)-$$(DEVICE_NAME)-$$(PROFILE_NAME) $$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(1)-$$(DEVICE_NAME)_PROFILES += $$(PROFILE_NAME) .PHONY: $$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(1)-$$(DEVICE_NAME)-$$(PROFILE_NAME) $$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(1)-$$(DEVICE_NAME)-$$(PROFILE_NAME): $(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/bsp/$$(DEVICE_NAME)/$$(PROFILE_NAME)/$$(1) $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(1)_ARTIFACT) @mkdir -p $(DIST_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/$$(DEVICE_NAME) $(ECHOCTL)$(CONTAINER_CMD) run --privileged --rm \ -v $(ROOT_DIR)/tools:/image-builder/tools:ro \ -v $$$$<:/image-builder/receipe:ro \ -v $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(1)_ARTIFACT):/image-builder/$$(notdir $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(1)_ARTIFACT)):ro \ -v $(DIST_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/$$(DEVICE_NAME):/image-builder/output \ $(CONTAINER_IMAGE_TAG) \ /bin/sh -c 'cd /image-builder/tools && \ LOG_LEVEL=$(LOG_LEVEL) ./build_bsp.sh -i /image-builder/receipe -s /image-builder/$$(notdir $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(1)_ARTIFACT)) -o /image-builder/output/$$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(1)-$$(DEVICE_NAME)-$$(PROFILE_NAME) -p $$(PACKAGE_MANAGER)' ifneq ($$$$(wildcard $$(BSP_PROFILE_DIR)/extensions/$$(1)/.),) # corresponding extension exists BSP_PROFILE_EXTENSION_DIR := $$(BSP_PROFILE_DIR)/extensions/$$(1) endif .PHONY: $(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/bsp/$$(DEVICE_NAME)/$$(PROFILE_NAME)/$$(1) $(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/bsp/$$(DEVICE_NAME)/$$(PROFILE_NAME)/$$(1): $$$$(BSP_PROFILE_DIR) $$$$(BSP_PROFILE_EXTENSION_DIR) $$$$(dir_guard) $(ECHOCTL)rm -rf "$$$$@" @# Not preserving modification time, aka -t $(ECHOCTL)rsync -rLpgoD --exclude profile.mk --exclude extensions $$$$(foreach dep,$$$$+,$$$$(dep)/) $$$$@ undefine BSP_PROFILE_EXTENSION_DIR endef $$(foreach receipe,$$($$(DISTRO_NAME)_$$(RELEASE_NAME)_RECEIPES),$$(eval $$(call GENERATE_RECEIPE_PROFILE_MATRIX,$$(receipe)))) undefine PROFILE_NAME undefine BSP_PROFILE_DIR undefine GENERATE_RECEIPE_PROFILE_MATRIX endef