1# -*- mode: makefile;-*- 2# 3# Copyright (C) 1999-2016 Apple Inc. All rights reserved. 4# 5# MakeInc.dir allows makefiles throughout the XNU codebase to leverage recursive 6# build behavior with minimal effort while promoting code reuse. 7# 8# For instance, a makefile need only define the special variable SETUP_SUBDIRS 9# to be a list of subdirectories in order for the build system to automatically 10# (1) go into those subdirectories building the target `build_setup`, (2) wait 11# for those targets to be built, and then (3) build the target `do_build_setup` 12# in the current directory. 13# 14# There are a number of other such special variables including (but not limited 15# to): INSTINC_SUBDIRS, EXPINC_SUBDIRS, COMP_SUBDIRS, and CONFIG_SUBDIRS. For 16# some of these special variables, there are are also architecture-specific 17# variants if a makefile needs to specify architecture-dependent builds. 18# 19 20# 21# This function/template provides generic recursive build functionality that 22# allows you to specify a list of subdirectories, a target to build in those 23# subdirectories, and a target to build in the current directory afterwards. 24# 25# Parameters: 26# 27# $(1): The target to build in each subdirectory. 28# $(2): A list of subdirectories. 29# $(3): The target to build in the current directory _after_ the subdirectory 30# targets have already been built. 31# $(4): This parameter controls the value of the TARGET make variable that's 32# passed down to the sub-makes for each subdirectory. If it's anything 33# but the empty string (but please just use 1 for consistency), then 34# the TARGET variable is BUILD/obj/<CURRENT_BUILD_CONFIG>/<COMPONENT>. 35# Otherwise, the TARGET variable is <TARGET>/<subdirectory>. 36# 37define RECURSIVE_BUILD_RULES_template 38$(1)_recurse_target_list := $(addprefix $(1)_recurse_into_,$(2)) 39 40.PHONY: $$($(1)_recurse_target_list) 41 42$$($(1)_recurse_target_list): 43 $(_v)$(MKDIR) $(CURDIR)/$$(patsubst $(1)_recurse_into_%,%,$$@) 44 $(_v)$(MAKE) \ 45 -C $(CURDIR)/$$(patsubst $(1)_recurse_into_%,%,$$@) \ 46 -f $(SOURCE)$$(patsubst $(1)_recurse_into_%,%,$$@)/Makefile \ 47 CURRENT_KERNEL_CONFIG=$(CURRENT_KERNEL_CONFIG) \ 48 CURRENT_ARCH_CONFIG=$(CURRENT_ARCH_CONFIG) \ 49 CURRENT_MACHINE_CONFIG=$(CURRENT_MACHINE_CONFIG) \ 50 CURRENT_BUILD_CONFIG=$(CURRENT_BUILD_CONFIG) \ 51 SOURCE=$(SOURCE)$$(patsubst $(1)_recurse_into_%,%,$$@)/ \ 52 RELATIVE_SOURCE_PATH=$(RELATIVE_SOURCE_PATH)/$$(patsubst $(1)_recurse_into_%,%,$$@) \ 53 TARGET=$(if $(4),$(OBJPATH)/$(COMPONENT),$(TARGET)$$(patsubst $(1)_recurse_into_%,%,$$@)/) \ 54 OBJPATH=$(OBJPATH) \ 55 $(1) 56 57.PHONY: $(1) 58 59$(1): $$($(1)_recurse_target_list) 60 $(_v)$(MAKE) \ 61 -f $(firstword $(MAKEFILE_LIST)) \ 62 CURRENT_KERNEL_CONFIG=$(CURRENT_KERNEL_CONFIG) \ 63 CURRENT_ARCH_CONFIG=$(CURRENT_ARCH_CONFIG) \ 64 CURRENT_MACHINE_CONFIG=$(CURRENT_MACHINE_CONFIG) \ 65 CURRENT_BUILD_CONFIG=$(CURRENT_BUILD_CONFIG) \ 66 SOURCE=$(SOURCE) \ 67 RELATIVE_SOURCE_PATH=$(RELATIVE_SOURCE_PATH) \ 68 TARGET=$(TARGET) \ 69 OBJPATH=$(OBJPATH) \ 70 $(3) 71endef 72 73# 74# Setup pass for all architectures for all Configuration/Architecture options 75# 76$(eval $(call RECURSIVE_BUILD_RULES_template,build_setup,$(SETUP_SUBDIRS),do_build_setup,)) 77 78# 79# Install machine independent kernel header files 80# 81$(eval $(call RECURSIVE_BUILD_RULES_template,build_installhdrs_mi,$(INSTINC_SUBDIRS),do_installhdrs_mi,)) 82 83# 84# Install machine dependent kernel header files 85# 86$(eval $(call RECURSIVE_BUILD_RULES_template,build_installhdrs_md,$(INSTINC_SUBDIRS_$(CURRENT_ARCH_CONFIG)),do_installhdrs_md,)) 87 88# 89# Install machine independent kernel header files 90# 91$(eval $(call RECURSIVE_BUILD_RULES_template,build_exporthdrs_mi,$(EXPINC_SUBDIRS),do_exporthdrs_mi,)) 92 93# 94# Install machine dependent kernel header files 95# 96$(eval $(call RECURSIVE_BUILD_RULES_template,build_exporthdrs_md,$(EXPINC_SUBDIRS_$(CURRENT_ARCH_CONFIG)),do_exporthdrs_md,)) 97 98# 99# Build all architectures for all Configuration/Architecture options 100# 101$(eval $(call RECURSIVE_BUILD_RULES_template,build_all,$(COMP_SUBDIRS) $(COMP_SUBDIRS_$(CURRENT_ARCH_CONFIG)),do_build_all,1)) 102 103# 104# Post-process build results 105# 106$(eval $(call RECURSIVE_BUILD_RULES_template,config_all,$(CONFIG_SUBDIRS),do_config_all,1)) 107 108# 109# Install for all architectures for all Configuration/Architecture options 110# 111$(eval $(call RECURSIVE_BUILD_RULES_template,build_install_primary,$(INST_SUBDIRS),do_build_install_primary,1)) 112$(eval $(call RECURSIVE_BUILD_RULES_template,build_install_non_primary,$(INST_SUBDIRS),do_build_install_non_primary,1)) 113$(eval $(call RECURSIVE_BUILD_RULES_template,config_install_primary,$(CONFIG_SUBDIRS),do_config_install_primary,1)) 114$(eval $(call RECURSIVE_BUILD_RULES_template,config_install_variant,$(CONFIG_SUBDIRS),do_config_install_variant,1)) 115$(eval $(call RECURSIVE_BUILD_RULES_template,config_install,$(CONFIG_SUBDIRS),do_config_install,1)) 116 117# 118# Install machine independent text files 119# 120$(eval $(call RECURSIVE_BUILD_RULES_template,textfiles_install_mi,$(INSTTEXTFILES_SUBDIRS),do_textfiles_install_mi,)) 121 122# 123# Install machine dependent text files 124# 125$(eval $(call RECURSIVE_BUILD_RULES_template,textfiles_install_md,$(INSTTEXTFILES_SUBDIRS_$(CURRENT_ARCH_CONFIG)),do_textfiles_install_md,)) 126 127# vim: set ft=make: 128