github.com/rkt/rkt@v1.30.1-0.20200224141603-171c416fac02/stage1/stage1.mk (about)

     1  # Prepare some variables, this might look strange so here goes: let's
     2  # assume we are going to build two flavors - coreos and kvm. The
     3  # following code is going to initialize some variables to some initial
     4  # values. The name of the variable depends on the flavor:
     5  # STAGE1_COPY_SO_DEPS_coreos, STAGE1_USR_STAMPS_coreos,
     6  # STAGE1_APP_STAMPS_coreos and so on for the coreos flavor. For the
     7  # kvm flavor the names would be STAGE1_COPY_SO_DEPS_kvm,
     8  # STAGE1_USR_STAMPS_kvm, STAGE1_APP_STAMPS_kvm and so on.
     9  #
    10  # STAGE1_COPY_SO_DEPS_$(flavor) tells whether a given flavor wants to
    11  # get missing libraries from build host before building an ACI.
    12  #
    13  # STAGE1_USR_STAMPS_$(flavor) is a list of stamps that say whether the
    14  # initial /usr contents of ACI are prepared.
    15  #
    16  # STAGE1_SECONDARY_STAMPS_$(flavor) is a list of stamps that say
    17  # whether the additional stuff was copied to the ACI rootfs (init,
    18  # enter, units, net config and so on). Usually the dependencies of
    19  # these stamps depend in turn on the stamps from
    20  # STAGE1_USR_STAMPS_$(flavor) - which means that the additional stuff
    21  # is copied to the ACI rootfs only after the initial /usr contents are
    22  # already there.
    23  #
    24  # STAGE1_ACIDIR_$(flavor) tells where is the ACI directory for a given
    25  # flavor. Note that this is the toplevel directory (where manifest is
    26  # stored). Most of the time you will want the
    27  # STAGE1_ACIROOTFSDIR_$(flavor) variable.
    28  #
    29  # STAGE1_ACIROOTFSDIR_$(flavor) tells where is the ACI rootfs
    30  # directory for a given flavor.
    31  #
    32  # STAGE1_ACI_IMAGE_$(flavor) tells where in the build directory the
    33  # final ACI is going to be built.
    34  #
    35  # STAGE1_INSTALL_FILES_$(flavor) - a list of files that can be
    36  # installed only after all the stamps in STAGE1_USR_STAMPS_$(flavor)
    37  # are created.
    38  #
    39  # STAGE1_INSTALL_SYMLINKS_$(flavor) - a list of symlinks that can be
    40  # installed only after all the stamps in STAGE1_USR_STAMPS_$(flavor)
    41  # are created.
    42  #
    43  # STAGE1_INSTALL_DIRS_$(flavor) - a list of directories that can be
    44  # installed only after all the stamps in STAGE1_USR_STAMPS_$(flavor)
    45  # are created.
    46  #
    47  # STAGE1_CREATE_DIRS_$(flavor) - a list of files that can be installed
    48  # only after all the stamps in STAGE1_USR_STAMPS_$(flavor) are
    49  # created. (This is less restrictive than INSTALL_DIRS counterpart,
    50  # because an entry in CREATE_DIRS does not require the parent
    51  # directory to exist). Please consider this as deprecated in favor of
    52  # INSTALL_DIRS + dir-chain function.
    53  #
    54  # STAGE1_ENTER_CMD_$(flavor) - an enter command in stage1 to be used
    55  # for the "rkt enter" command.
    56  #
    57  # STAGE1_STOP_CMD_$(flavor) - a stop command in stage1 to be used
    58  # for the "rkt stop" command.
    59  # 
    60  # STAGE1_IMAGES_$(flavor) - list of stage1 images we want to build for
    61  # each flavor. Need to be parsed here. If empty, single $(STAGE1_ACI_IMAGE_$f)
    62  # will be built. Variables $(STAGE1_ACI_IMAGE_$f-$(image)) will be used
    63  # only for aci build rules.
    64  
    65  STAGE1_FLAVORS := $(call commas-to-spaces,$(RKT_STAGE1_ALL_FLAVORS))
    66  STAGE1_BUILT_FLAVORS := $(call commas-to-spaces,$(RKT_STAGE1_FLAVORS))
    67  # filter out the fly flavor - it is special
    68  STAGE1_FLAVORS := $(filter-out fly,$(STAGE1_FLAVORS))
    69  STAGE1_BUILT_FLAVORS := $(filter-out fly,$(STAGE1_BUILT_FLAVORS))
    70  
    71  # hypervisors for kvm stage1
    72  STAGE1_BUILT_KVM_HV := $(call commas-to-spaces,$(RKT_STAGE1_KVM_HV))
    73  
    74  $(foreach f,$(STAGE1_FLAVORS), \
    75  	$(eval STAGE1_COPY_SO_DEPS_$f :=) \
    76  	$(eval STAGE1_USR_STAMPS_$f :=) \
    77  	$(eval STAGE1_SECONDARY_STAMPS_$f :=) \
    78  	$(eval STAGE1_ACIDIR_$f := $(BUILDDIR)/aci-for-$f-flavor) \
    79  	$(eval STAGE1_ACIROOTFSDIR_$f := $(STAGE1_ACIDIR_$f)/rootfs) \
    80  	$(eval STAGE1_ACI_IMAGE_$f := $(TARGET_BINDIR)/stage1-$f.aci) \
    81  	$(eval STAGE1_INSTALL_FILES_$f :=) \
    82  	$(eval STAGE1_INSTALL_SYMLINKS_$f :=) \
    83  	$(eval STAGE1_INSTALL_DIRS_$f :=) \
    84  	$(eval STAGE1_CREATE_DIRS_$f :=) \
    85  	$(eval STAGE1_ENTER_CMD_$f :=) \
    86  	$(eval STAGE1_STOP_CMD_$f :=))
    87  
    88  # Main stamp that tells whether all the ACIs have been built.
    89  $(call setup-stamp-file,_STAGE1_BUILT_ACI_STAMP_,built_aci)
    90  
    91  # List of all the ACIs that the build system will build
    92  _STAGE1_ALL_ACI_ := $(foreach f,$(STAGE1_FLAVORS),$(STAGE1_ACI_IMAGE_$f))
    93  _STAGE1_BUILT_ACI_ := $(foreach f,$(STAGE1_BUILT_FLAVORS),$(STAGE1_ACI_IMAGE_$f))
    94  
    95  # Assign rules for selected kvm hypervisors, fill STAGE1_IMAGES_kvm variable 
    96  # needed by _STAGE1_BUILT_ACI_ variable and _STAGE1_ACI_RULE_ function
    97  $(foreach h,$(STAGE1_BUILT_KVM_HV), \
    98  	$(eval STAGE1_ACI_IMAGE_kvm-$h := $(TARGET_BINDIR)/stage1-kvm-$h.aci) \
    99  	$(eval STAGE1_IMAGES_kvm += $h))
   100  
   101  # Replace stage1-flavor.aci with stage1-flavor-image1.aci,stage1-flavor-image2.aci,...
   102  # for every flavor with more than one image
   103  $(foreach f,$(STAGE1_BUILT_FLAVORS), \
   104  	$(if $(STAGE1_IMAGES_$f), \
   105  		$(eval _STAGE1_BUILT_ACI_ := \
   106  		$(subst $(STAGE1_ACI_IMAGE_$f), $(foreach i,$(STAGE1_IMAGES_$f),$(STAGE1_ACI_IMAGE_$f-$i)), $(_STAGE1_BUILT_ACI_)))))
   107  
   108  # The rootfs.mk file takes care of preparing the initial /usr contents
   109  # of the ACI rootfs of a specific flavor. Basically fills
   110  # STAGE1_USR_STAMPS_$(flavor) variables. Might add something to the
   111  # STAGE1_SECONDARY_STAMPS_$(flavor) or the STAGE1_INSTALL_* variables
   112  # too.
   113  $(foreach flavor,$(STAGE1_FLAVORS), \
   114  	$(eval S1_RF_FLAVOR := $(flavor)) \
   115  	$(call inc-one,rootfs.mk))
   116  
   117  # secondary-stuff.mk takes care of putting additional stuff into
   118  # the ACI rootfs for each flavor. Basically fills the
   119  # STAGE1_SECONDARY_STAMPS_$(flavor) and the STAGE1_INSTALL_*
   120  # variables.
   121  $(call inc-one,secondary-stuff.mk)
   122  
   123  TOPLEVEL_STAMPS += $(_STAGE1_BUILT_ACI_STAMP_)
   124  CLEAN_FILES += $(_STAGE1_ALL_ACI_)
   125  
   126  $(call generate-stamp-rule,$(_STAGE1_BUILT_ACI_STAMP_),$(_STAGE1_BUILT_ACI_))
   127  
   128  # A rule template for building an ACI. To build the ACI we need to
   129  # have the /usr contents prepared and the additional stuff in place as
   130  # well. If a flavor wants to have missing libraries copied, it is done
   131  # here too. If we want to build more than one image for single flavor 
   132  # (with differences in rootfs - i.e. hypervisor binary for kvm flavor), 
   133  # rootfs common part has to be stored in STAGE1_ACIROOTFSDIR_$1, and 
   134  # additional files in STAGE1_ACIROOTFSDIR_$1_$(image), for each $(image)
   135  # entry from $2.
   136  # 1 - flavor
   137  # 2 - images
   138  define _STAGE1_ACI_RULE_
   139  
   140  STAGE1_ALL_STAMPS_$1 := $$(STAGE1_USR_STAMPS_$1) $$(STAGE1_SECONDARY_STAMPS_$1)
   141  
   142  $$(STAGE1_SECONDARY_STAMPS_$1): $$(STAGE1_USR_STAMPS_$1)
   143  
   144  ifeq ($$(STAGE1_COPY_SO_DEPS_$1),)
   145  
   146  # The flavor needs no libraries from the host
   147  
   148  $$(STAGE1_ACI_IMAGE_$1): $$(STAGE1_ALL_STAMPS_$1)
   149  
   150  # Same dependencies has to be fulfilled for every image in given flavor
   151  $(foreach i,$2, \
   152  $$(eval $$(STAGE1_ACI_IMAGE_$1-$i): $$(STAGE1_ALL_STAMPS_$1)))
   153  
   154  else
   155  
   156  # The flavor requires libraries from the host, so depend on the stamp
   157  # generated by find-so-deps.mk, which in turn will depend on the usr
   158  # and the secondary stamps.
   159  
   160  STAGE1_FSD_FLAVOR := $1
   161  
   162  $$(call inc-one,find-so-deps.mk)
   163  
   164  $$(STAGE1_ACI_IMAGE_$1): $$(STAGE1_FSD_STAMP)
   165  
   166  endif
   167  
   168  # The actual rule that builds the ACI. Additional dependencies are
   169  # above.
   170  
   171  # Forward variables to rules that build acis. If more than one image,
   172  # forward to every rule.
   173  $$(call forward-vars,$$(STAGE1_ACI_IMAGE_$1), \
   174  	ACTOOL STAGE1_ACIDIR_$1)
   175  $(foreach i,$2, \
   176  $$(call forward-vars,$$(STAGE1_ACI_IMAGE_$1-$i), \
   177  	ACTOOL STAGE1_ACIDIR_$1))
   178  
   179  # Prepare targets to build images. Also copy common rootfs to each image directory
   180  # and ensure that all of them will be removed
   181  $(if $(strip $2), \
   182          $(eval IMG := $(foreach h,$2,$1-$h)) \
   183          $(foreach s,$(IMG),
   184                  $(call setup-stamp-file,STAGE1_COPY_IMAGE_FILES_$s,/copy-files-$s) \
   185  		$$(STAGE1_COPY_IMAGE_FILES_$s): $$(STAGE1_ALL_STAMPS_$1)
   186  			$(VQ) $(call vb,vt,COPY FILES,$$(call vsp,$s)) cp -rn $(STAGE1_ACIDIR_$1)/rootfs $(STAGE1_ACIDIR_$1)/manifest $(STAGE1_ACIDIR_$1)/$s
   187  		$(eval CLEAN_DIRS += $(STAGE1_ACIDIR_$1)/$s)
   188  		$(call generate-clean-mk-simple,
   189  		        $(STAGE1_ACI_IMAGE_$s),
   190  		        $(STAGE1_ACIDIR_$1)/$s,
   191  		        $(STAGE1_ACIDIR_$1)/$s,
   192  		        $(STAGE1_COPY_IMAGE_FILES_$s),
   193  		        copy-$s)), \
   194          $(eval IMG := $1))
   195  
   196  # Build images. Common files are stored in STAGE1_ACIDIR_$1,
   197  # image specific files in STAGE1_ACIDIR_$1/flavor-image/...
   198  # Add dependency for copying image-specific files, if any ($2 is not empty)
   199  $(foreach s,$(IMG),
   200  $$(STAGE1_ACI_IMAGE_$s): $$(ACTOOL_STAMP) | $$(TARGET_BINDIR) $$(if $(strip $2),$$(STAGE1_COPY_IMAGE_FILES_$s),)
   201  	$(eval ACI_OUTPUT := "$(if $(filter 1,$(words $2)),$(STAGE1_ACI_IMAGE_$1),$(STAGE1_ACI_IMAGE_$s))")
   202  	$(VQ) \
   203  	$(call vb,vt,ACTOOL,$$(call vsp,$(ACI_OUTPUT))) \
   204  	"$$(ACTOOL)" build --overwrite --owner-root "$$(STAGE1_ACIDIR_$1)$(if $(strip $2),/$s,)" $(ACI_OUTPUT)
   205  )
   206  
   207  endef
   208  
   209  $(foreach f,$(STAGE1_FLAVORS), \
   210  	$(eval $(call _STAGE1_ACI_RULE_,$f,$(STAGE1_IMAGES_$f))))
   211  
   212  
   213  # The following piece of wizardry takes the variables
   214  # STAGE1_INSTALL_FILES_$(flavor), STAGE1_INSTALL_SYMLINKS_$(flavor),
   215  # STAGE1_INSTALL_DIRS_$(flavor) and STAGE1_CREATE_DIRS_$(flavor),
   216  # makes their contents to depend on STAGE1_USR_STAMPS_$(flavor) and
   217  # appends their contents to, respectively, INSTALL_FILES,
   218  # INSTALL_SYMLINKS, INSTALL_DIRS and CREATE_DIRS. This is to make sure
   219  # that all the additional stuff will be installed only after the
   220  # initial /usr contents in the ACI rootfs are prepared.
   221  
   222  
   223  # Three fields:
   224  # 1 - base variable name (e.g. INSTALL_FILES)
   225  # 2 - whether it has to be split to get the created entry (elements in
   226  # INSTALL_FILES have to be split, because the created entry is between
   227  # source entry and mode, like src_file:created_entry:mode, elements in
   228  # the CREATE_DIRS variable do not need to be split)
   229  # 3 - if it has to be split, then which item is the created entry
   230  # (index starting from 1)
   231  _STAGE1_FILE_VARS_ := \
   232  	INSTALL_FILES:y:2 \
   233  	INSTALL_SYMLINKS:y:2 \
   234  	INSTALL_DIRS:y:1 \
   235  	CREATE_DIRS:n
   236  
   237  # Generates dependency of a created entry on
   238  # STAGE1_USR_STAMPS_$(flavor)
   239  # 1 - item(s)
   240  # 2 - flavor
   241  define _STAGE1_GEN_DEP_
   242  $(call add-dependency,$1,$(STAGE1_USR_STAMPS_$2))
   243  endef
   244  
   245  # The actual fixup - appending and "dependencing".
   246  $(foreach v,$(_STAGE1_FILE_VARS_), \
   247  	$(eval _S1_FX_VAR_LIST_ := $(subst :, ,$v)) \
   248  	$(eval _S1_FX_NAME_ := $(word 1,$(_S1_FX_VAR_LIST_))) \
   249  	$(eval _S1_FX_SPLIT_ := $(word 2,$(_S1_FX_VAR_LIST_))) \
   250  	$(eval _S1_FX_IDX_ := $(word 3,$(_S1_FX_VAR_LIST_))) \
   251  	$(foreach f,$(STAGE1_FLAVORS), \
   252  		$(eval _S1_FX_VAR_NAME_ := STAGE1_$(_S1_FX_NAME_)_$f) \
   253  		$(eval $(_S1_FX_NAME_) += $($(_S1_FX_VAR_NAME_))) \
   254  		$(eval $(foreach i,$($(_S1_FX_VAR_NAME_)), \
   255  			$(if $(filter y,$(_S1_FX_SPLIT_)), \
   256  				$(eval _S1_FX_LIST_ := $(subst :, ,$i)) \
   257  				$(eval _S1_FX_ITEM_ := $(word $(_S1_FX_IDX_),$(_S1_FX_LIST_))) \
   258  				$(call _STAGE1_GEN_DEP_,$(_S1_FX_ITEM_),$f), \
   259  				$(call _STAGE1_GEN_DEP_,$i,$f))))) \
   260  	$(call undefine-namespaces,_S1_FX))
   261  
   262  $(call undefine-namespaces,STAGE1 _STAGE1)