2 # Copyright 2020 nlbuild-autotools Authors. All Rights Reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
19 # This file is the automake header for building foreign make
20 # (that is, outside of the current make directory) dependencies.
22 # Two types of foreign make dependencies are supported:
26 # EXPLICIT dependecies that follow the form '<DIR>/<TARGET>'
27 # where '$(MAKE) -C <DIR> <TARGET>' will produce and satisfy
28 # the desired dependency expected by the current make file
32 # IMPLICIT dependecies that follow the form '<DIR>'
33 # where '$(MAKE) -C <DIR>' will produce and satisfy
34 # the desired dependencies expected by the current
37 # This defines make targets and commands for handling such
38 # foreign make dependencies. overridden by project make files.
41 # The user-supported and -visible targets for foreign dependencies are:
45 # Build all foreign target dependencies, including both files or
48 # * nlforeign-file-deps
50 # Build only foreign file target dependencies.
52 # * nlforeign-subdir-deps
54 # Build only foreign subdirectory target dependencies.
57 .PHONY: nlforeign-file-deps nlforeign-subdir-deps nlforeign-deps
59 nlforeign-deps: nlforeign-file-deps nlforeign-subdir-deps
63 nlforeign-subdir-deps:
66 # if defined(NLFOREIGN_FILE_DEPENDENCIES) || defined(NLFOREIGN_SUBDIR_DEPENDENCIES)
68 ifneq ($(strip $(NLFOREIGN_FILE_DEPENDENCIES)$(NLFOREIGN_SUBDIR_DEPENDENCIES)),)
71 # Foreign target dependency sentinel file management
74 # All foreign target dependency sentinel files are of the form
75 # [.<path>]<sentinel file stem><unique invocation qualifier, where
76 # [.<path>] is only included if the <path> is non-empty.
78 # This defines the <sentinel file stem>.
80 NLFOREIGN_DEPENDENCIES_SENTINEL_STEM := .nlbuild_foreign_deps_
82 # This defines the <unique invocation qualifier>.
84 # Check to see if NLFOREIGN_DEPENDENCIES_SENTINEL_ID has been set for
85 # this make invocation.
87 ifneq ($(origin NLFOREIGN_DEPENDENCIES_SENTINEL_ID),environment)
89 # the parent of this shell is the "root" make invocation
90 override NLFOREIGN_DEPENDENCIES_SENTINEL_ID:=$(shell echo $$PPID)
92 # makes makedirs_id an environment var
93 export NLFOREIGN_DEPENDENCIES_SENTINEL_ID
98 # nlforeign-create-dependencies-sentinel-name <target path> <unique invocation qualifier>
100 # This creates a name for a foreign target dependency sentinel
101 # file using the specified target path and unique invocation
104 # The target path will be transformed by eliding double-dot (..)
105 # sequences, transforming path separators (/) into underscores (_),
106 # and transforming dots (.) into underscores (_).
108 define nlforeign-create-dependencies-sentinel-name
109 $(if $(1),.$(subst .,_,$(subst /,_,$(subst ..,,$(1)))),)$(NLFOREIGN_DEPENDENCIES_SENTINEL_STEM)$(2)
113 # nlforeign-create-unique-dependencies-sentinel-name <target path> <unique invocation qualifier>
115 # This creates a unique name for a foreign target dependency sentinel
116 # file using the specified target path, qualified by the current make
117 # process identifier.
119 define nlforeign-create-unique-dependencies-sentinel-name
120 $(call nlforeign-create-dependencies-sentinel-name,$(1),$(NLFOREIGN_DEPENDENCIES_SENTINEL_ID))
124 # MARK: NLFOREIGN_SUBDIR_DEPENDENCIES
126 ifdef NLFOREIGN_SUBDIR_DEPENDENCIES
128 ifeq ($(MAKECMDGOALS),$(filter-out clean distclean maintainer-clean,$(MAKECMDGOALS)))
130 # Always ensure that nlforeign-subdir-deps runs first against any
131 # non-clean target goals such that make file maintainers do not have
132 # to set up any explicit dependencies when they define
133 # NLFOREIGN_SUBDIR_DEPENDENCIES.
135 # Do this by tricking make into building nlforeign-subdir-deps first
136 # by forcing it to try to make an include file that depends on
137 # nlforeign-subdir-deps.
139 -include .nlforeign_deps_trick_never_exists.min
141 .nlforeign_deps_trick_never_exists.min: nlforeign-subdir-deps
143 endif # ifeq ($(MAKECMDGOALS),$(filter-out clean distclean maintainer-clean,$(MAKECMDGOALS)))
145 define nlforeign-subdir-make
146 $(NL_V_PROGRESS) "MAKE" "$(1)"
147 +$(NL_V_AT)$(MAKE) $(MFLAGS) -C "$(1)"
148 endef # nlforeign-subdir-make
151 # nlforeign-create-unique-subdir-dependencies-sentinel-name <target subdirectory>
153 # This creates the name of a foreign subdirectory dependency sentinel
156 # <target subdirectory>/<sentinel stem><sentinel unique id>
158 define nlforeign-create-unique-subdir-dependencies-sentinel-name
159 $(call Deslashify,$(1))/$(call nlforeign-create-unique-dependencies-sentinel-name,$(notdir $(call Slashify,$(1))))
163 # nlforeign-create-unique-subdir-dependencies-sentinel-name-glob <target subdirectory> <glob pattern>
165 # This creates the glob name pattern of a foreign subdirectory
166 # dependency sentinel file of the form:
168 # <target subdirectory>/<sentinel stem><glob pattern>
170 define nlforeign-create-unique-subdir-dependencies-sentinel-name-glob
171 $(call Deslashify,$(1))/$(call nlforeign-create-dependencies-sentinel-name,$(notdir $(call Slashify,$(1))),$(2))
175 # nlforeign-subdir-dependency-template <foreign subdir target>
177 # This template defines targets and associated commands for building a
178 # foreign subdir target depedendency via a subdirectory make (for
179 # example, `make -C ../foo` for directory '../foo').
181 define nlforeign-subdir-dependency-template
183 # The foreign subdirectory dependency depends on a sentinel for it such that
184 # make is forced to visit the directory (should any of its
185 # dependencies have changed since the last visit).
187 NLFOREIGN_SUBDIR_CLEANFILE_GLOBS += $(call nlforeign-create-unique-subdir-dependencies-sentinel-name-glob,$(1),*)
189 nlforeign-subdir-deps: $(call nlforeign-create-unique-subdir-dependencies-sentinel-name,$(1))
191 $$(call nlforeign-create-unique-subdir-dependencies-sentinel-name,$(1)):
192 $(NL_V_AT)touch "$$(@)"
193 $(call nlforeign-subdir-make,$(1))
194 $(NL_V_AT)$(RM) $(filter-out $$(@),$(wildcard $(call nlforeign-create-unique-subdir-dependencies-sentinel-name-glob,$(1),*)))
196 endef # nlforeign-subdir-dependency-template
198 # Clean up any foreign subdirectory dependency sentinel files by
199 # hooking on any clean target is invoked.
201 # NOTE: We CANNOT just hook on 'clean-local' since it won't be recognized
202 # unless the make file including this one uses it.
204 clean distclean maintainer-clean: nlforeign-subdir-dependency-clean
206 nlforeign-subdir-dependency-clean:
207 $(NL_V_AT)$(RM) $(NLFOREIGN_SUBDIR_CLEANFILE_GLOBS)
209 # Instantiate the foreign subdirectory dependency template for each
210 # subdirectory in NLFOREIGN_SUBDIR_DEPENDENCIES.
212 $(foreach nlforeign-subdir-dependency,$(NLFOREIGN_SUBDIR_DEPENDENCIES),$(eval $(call nlforeign-subdir-dependency-template,$(nlforeign-subdir-dependency))))
214 endif # NLFOREIGN_SUBDIR_DEPENDENCIES
217 # MARK: NLFOREIGN_FILE_DEPENDENCIES
219 ifdef NLFOREIGN_FILE_DEPENDENCIES
221 nlforeign-file-deps: $(NLFOREIGN_FILE_DEPENDENCIES)
223 define nlforeign-file-make
224 $(NL_V_PROGRESS) "MAKE" "$(1)"
225 +$(NL_V_AT)$(MAKE) $(MFLAGS) -C "$(dir $(1))" "$(notdir $(1))"
226 endef # nlforeign-file-make
229 # nlforeign-create-unique-file-dependencies-sentinel-name <target file
231 # This creates the name of a foreign file dependency sentinel file of
234 # $(dir <target file>)/$(notdir <target file>)<sentinel stem><sentinel unique id>
236 define nlforeign-create-unique-file-dependencies-sentinel-name
237 $(call Deslashify,$(dir $(1)))/$(call nlforeign-create-unique-dependencies-sentinel-name,$(notdir $(1)))
241 # nlforeign-create-unique-file-dependencies-sentinel-name-glob <target file <glob pattern>
243 # This creates the glob name pattern of a foreign file dependency
244 # sentinel file of the form:
246 # $(dir <target file>)/$(notdir <target file>)<sentinel stem><glob pattern>
248 define nlforeign-create-unique-file-dependencies-sentinel-name-glob
249 $(call Deslashify,$(dir $(1)))/$(call nlforeign-create-dependencies-sentinel-name,$(notdir $(1)),$(2))
253 # nlforeign-file-dependency-template <foreign file target>
255 # This template defines targets and associated commands for building a
256 # foreign file target depedendency via a subdirectory make (for
257 # example, `make -C ../foo bar` for target 'bar' in directory
260 define nlforeign-file-dependency-template
262 # The foreign file dependency depends on a sentinel for it such that
263 # make is forced to visit the directory that creates it (should any of
264 # its dependencies have changed since the last visit).
266 NLFOREIGN_FILE_CLEANFILE_GLOBS += $(call nlforeign-create-unique-file-dependencies-sentinel-name-glob,$(1),*)
268 $(1): $$(call nlforeign-create-unique-file-dependencies-sentinel-name,$(1))
269 $(call nlforeign-file-make,$(1))
271 $$(call nlforeign-create-unique-file-dependencies-sentinel-name,$(1)):
272 $(NL_V_AT)touch "$$(@)"
273 $(NL_V_AT)$(RM) $(filter-out $$(@),$(wildcard $(call nlforeign-create-unique-file-dependencies-sentinel-name-glob,$(1),*)))
275 endef # nlforeign-file-dependency-template
277 # Clean up any foreign file dependency sentinel files by hooking on
278 # any clean target is invoked.
280 # NOTE: We CANNOT just hook on 'clean-local' since it won't be recognized
281 # unless the make file including this one uses it.
283 clean distclean maintainer-clean: nlforeign-file-dependency-clean
285 nlforeign-file-dependency-clean:
286 $(NL_V_AT)$(RM) $(NLFOREIGN_FILE_CLEANFILE_GLOBS)
288 # Instantiate the foreign file dependency template for each file in
289 # NLFOREIGN_FILE_DEPENDENCIES.
291 $(foreach nlforeign-file-dependency,$(NLFOREIGN_FILE_DEPENDENCIES),$(eval $(call nlforeign-file-dependency-template,$(nlforeign-file-dependency))))
293 endif # NLFOREIGN_FILE_DEPENDENCIES
295 endif # NLFOREIGN_FILE_DEPENDENCIES || NLFOREIGN_SUBDIR_DEPENDENCIES