539 lines
21 KiB
Makefile
539 lines
21 KiB
Makefile
# Copyright (C) 2012 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
# Definitions of various graph-related generic functions, used by
|
|
# ndk-build internally.
|
|
#
|
|
|
|
# Coding style note:
|
|
#
|
|
# All internal variables in this file begin with '_ndk_mod_'
|
|
# All internal functions in this file begin with '-ndk-mod-'
|
|
#
|
|
|
|
# Set this to true if you want to debug the functions here.
|
|
_ndk_mod_debug := $(if $(NDK_DEBUG_MODULES),true)
|
|
_ndk_topo_debug := $(if $(NDK_DEBUG_TOPO),true)
|
|
|
|
# Use $(call -ndk-mod-debug,<message>) to print a debug message only
|
|
# if _ndk_mod_debug is set to 'true'. Useful for debugging the functions
|
|
# available here.
|
|
#
|
|
ifeq (true,$(_ndk_mod_debug))
|
|
-ndk-mod-debug = $(info $1)
|
|
else
|
|
-ndk-mod-debug := $(empty)
|
|
endif
|
|
|
|
ifeq (true,$(_ndk_topo_debug))
|
|
-ndk-topo-debug = $(info $1)
|
|
else
|
|
-ndk-topo-debug = $(empty)
|
|
endif
|
|
|
|
#######################################################################
|
|
# Filter a list of module with a predicate function
|
|
# $1: list of module names.
|
|
# $2: predicate function, will be called with $(call $2,<name>), if the
|
|
# result is not empty, <name> will be added to the result.
|
|
# Out: subset of input list, where each item passes the predicate.
|
|
#######################################################################
|
|
-ndk-mod-filter = $(strip \
|
|
$(foreach _ndk_mod_filter_n,$1,\
|
|
$(if $(call $2,$(_ndk_mod_filter_n)),$(_ndk_mod_filter_n))\
|
|
))
|
|
|
|
-test-ndk-mod-filter = \
|
|
$(eval -local-func = $$(call seq,foo,$$1))\
|
|
$(call test-expect,,$(call -ndk-mod-filter,,-local-func))\
|
|
$(call test-expect,foo,$(call -ndk-mod-filter,foo,-local-func))\
|
|
$(call test-expect,foo,$(call -ndk-mod-filter,foo bar,-local-func))\
|
|
$(call test-expect,foo foo,$(call -ndk-mod-filter,aaa foo bar foo,-local-func))\
|
|
$(eval -local-func = $$(call sne,foo,$$1))\
|
|
$(call test-expect,,$(call -ndk-mod-filter,,-local-func))\
|
|
$(call test-expect,,$(call -ndk-mod-filter,foo,-local-func))\
|
|
$(call test-expect,bar,$(call -ndk-mod-filter,foo bar,-local-func))\
|
|
$(call test-expect,aaa bar,$(call -ndk-mod-filter,aaa foo bar,-local-func))
|
|
|
|
|
|
#######################################################################
|
|
# Filter out a list of modules with a predicate function
|
|
# $1: list of module names.
|
|
# $2: predicate function, will be called with $(call $2,<name>), if the
|
|
# result is not empty, <name> will be added to the result.
|
|
# Out: subset of input list, where each item doesn't pass the predicate.
|
|
#######################################################################
|
|
-ndk-mod-filter-out = $(strip \
|
|
$(foreach _ndk_mod_filter_n,$1,\
|
|
$(if $(call $2,$(_ndk_mod_filter_n)),,$(_ndk_mod_filter_n))\
|
|
))
|
|
|
|
-test-ndk-mod-filter-out = \
|
|
$(eval -local-func = $$(call seq,foo,$$1))\
|
|
$(call test-expect,,$(call -ndk-mod-filter-out,,-local-func))\
|
|
$(call test-expect,,$(call -ndk-mod-filter-out,foo,-local-func))\
|
|
$(call test-expect,bar,$(call -ndk-mod-filter-out,foo bar,-local-func))\
|
|
$(call test-expect,aaa bar,$(call -ndk-mod-filter-out,aaa foo bar foo,-local-func))\
|
|
$(eval -local-func = $$(call sne,foo,$$1))\
|
|
$(call test-expect,,$(call -ndk-mod-filter-out,,-local-func))\
|
|
$(call test-expect,foo,$(call -ndk-mod-filter-out,foo,-local-func))\
|
|
$(call test-expect,foo,$(call -ndk-mod-filter-out,foo bar,-local-func))\
|
|
$(call test-expect,foo foo,$(call -ndk-mod-filter-out,aaa foo bar foo,-local-func))
|
|
|
|
|
|
#######################################################################
|
|
# Find the first item in a list that checks a valid predicate.
|
|
# $1: list of names.
|
|
# $2: predicate function, will be called with $(call $2,<name>), if the
|
|
# result is not empty, <name> will be added to the result.
|
|
# Out: subset of input list.
|
|
#######################################################################
|
|
-ndk-mod-find-first = $(firstword $(call -ndk-mod-filter,$1,$2))
|
|
|
|
-test-ndk-mod-find-first.empty = \
|
|
$(eval -local-pred = $$(call seq,foo,$$1))\
|
|
$(call test-expect,,$(call -ndk-mod-find-first,,-local-pred))\
|
|
$(call test-expect,,$(call -ndk-mod-find-first,bar,-local-pred))
|
|
|
|
-test-ndk-mod-find-first.simple = \
|
|
$(eval -local-pred = $$(call seq,foo,$$1))\
|
|
$(call test-expect,foo,$(call -ndk-mod-find-first,foo,-local-pred))\
|
|
$(call test-expect,foo,$(call -ndk-mod-find-first,aaa foo bar,-local-pred))\
|
|
$(call test-expect,foo,$(call -ndk-mod-find-first,aaa foo foo bar,-local-pred))
|
|
|
|
########################################################################
|
|
# Many tree walking operations require setting a 'visited' flag on
|
|
# specific graph nodes. The following helper functions help implement
|
|
# this while hiding details to the callers.
|
|
#
|
|
# Technical note:
|
|
# _ndk_mod_tree_visited.<name> will be 'true' if the node was visited,
|
|
# or empty otherwise.
|
|
#
|
|
# _ndk_mod_tree_visitors lists all visited nodes, used to clean all
|
|
# _ndk_mod_tree_visited.<name> variables in -ndk-mod-tree-setup-visit.
|
|
#
|
|
#######################################################################
|
|
|
|
# Call this before tree traversal.
|
|
-ndk-mod-tree-setup-visit = \
|
|
$(foreach _ndk_mod_tree_visitor,$(_ndk_mod_tree_visitors),\
|
|
$(eval _ndk_mod_tree_visited.$$(_ndk_mod_tree_visitor) :=))\
|
|
$(eval _ndk_mod_tree_visitors :=)
|
|
|
|
# Returns non-empty if a node was visited.
|
|
-ndk-mod-tree-is-visited = \
|
|
$(_ndk_mod_tree_visited.$1)
|
|
|
|
# Set the visited state of a node to 'true'
|
|
-ndk-mod-tree-set-visited = \
|
|
$(eval _ndk_mod_tree_visited.$1 := true)\
|
|
$(eval _ndk_mod_tree_visitors += $1)
|
|
|
|
########################################################################
|
|
# Many graph walking operations require a work queue and computing
|
|
# dependencies / children nodes. Here are a few helper functions that
|
|
# can be used to make their code clearer. This uses a few global
|
|
# variables that should be defined as follows during the operation:
|
|
#
|
|
# _ndk_mod_module current graph node name.
|
|
# _ndk_mod_wq current node work queue.
|
|
# _ndk_mod_list current result (list of nodes).
|
|
# _ndk_mod_depends current graph node's children.
|
|
# you must call -ndk-mod-get-depends to set this.
|
|
#
|
|
#######################################################################
|
|
|
|
# Pop first item from work-queue into _ndk_mod_module.
|
|
-ndk-mod-pop-first = \
|
|
$(eval _ndk_mod_module := $$(call first,$$(_ndk_mod_wq)))\
|
|
$(eval _ndk_mod_wq := $$(call rest,$$(_ndk_mod_wq)))
|
|
|
|
-test-ndk-mod-pop-first = \
|
|
$(eval _ndk_mod_wq := A B C)\
|
|
$(call -ndk-mod-pop-first)\
|
|
$(call test-expect,A,$(_ndk_mod_module))\
|
|
$(call test-expect,B C,$(_ndk_mod_wq))\
|
|
|
|
|
|
# Push list of items at the back of the work-queue.
|
|
-ndk-mod-push-back = \
|
|
$(eval _ndk_mod_wq := $(strip $(_ndk_mod_wq) $1))
|
|
|
|
-test-ndk-mod-push-back = \
|
|
$(eval _ndk_mod_wq := A B C)\
|
|
$(call -ndk-mod-push-back, D E)\
|
|
$(call test-expect,A B C D E,$(_ndk_mod_wq))
|
|
|
|
# Set _ndk_mod_depends to the direct dependencies of _ndk_mod_module
|
|
-ndk-mod-get-depends = \
|
|
$(eval _ndk_mod_depends := $$(call $$(_ndk_mod_deps_func),$$(_ndk_mod_module)))
|
|
|
|
# Set _ndk_mod_depends to the direct dependencies of _ndk_mod_module that
|
|
# are not already in _ndk_mod_list.
|
|
-ndk-mod-get-new-depends = \
|
|
$(call -ndk-mod-get-depends)\
|
|
$(eval _ndk_mod_depends := $$(filter-out $$(_ndk_mod_list),$$(_ndk_mod_depends)))
|
|
|
|
##########################################################################
|
|
# Compute the transitive closure
|
|
# $1: list of modules.
|
|
# $2: dependency function, $(call $2,<module>) should return all the
|
|
# module that <module> depends on.
|
|
# Out: transitive closure of all modules from those in $1. Always includes
|
|
# the modules in $1. Order is random.
|
|
#
|
|
# Implementation note:
|
|
# we use the -ndk-mod-tree-xxx functions to flag 'visited' nodes
|
|
# in the graph. A node is visited once it has been put into the work
|
|
# queue. For each item in the work queue, get the dependencies and
|
|
# append all those that were not visited yet.
|
|
#######################################################################
|
|
-ndk-mod-get-closure = $(strip \
|
|
$(eval _ndk_mod_wq :=)\
|
|
$(eval _ndk_mod_list :=)\
|
|
$(eval _ndk_mod_deps_func := $2)\
|
|
$(call -ndk-mod-tree-setup-visit)\
|
|
$(foreach _ndk_mod_module,$1,\
|
|
$(call -ndk-mod-closure-visit,$(_ndk_mod_module))\
|
|
)\
|
|
$(call -ndk-mod-closure-recursive)\
|
|
$(eval _ndk_mod_deps :=)\
|
|
$(_ndk_mod_list)\
|
|
)
|
|
|
|
# Used internally to visit a new node during -ndk-mod-get-closure.
|
|
# This appends the node to the work queue, and set its 'visit' flag.
|
|
-ndk-mod-closure-visit = \
|
|
$(call -ndk-mod-push-back,$1)\
|
|
$(call -ndk-mod-tree-set-visited,$1)
|
|
|
|
-ndk-mod-closure-recursive = \
|
|
$(call -ndk-mod-pop-first)\
|
|
$(eval _ndk_mod_list += $$(_ndk_mod_module))\
|
|
$(call -ndk-mod-get-depends)\
|
|
$(foreach _ndk_mod_dep,$(_ndk_mod_depends),\
|
|
$(if $(call -ndk-mod-tree-is-visited,$(_ndk_mod_dep)),,\
|
|
$(call -ndk-mod-closure-visit,$(_ndk_mod_dep))\
|
|
)\
|
|
)\
|
|
$(if $(_ndk_mod_wq),$(call -ndk-mod-closure-recursive))
|
|
|
|
-test-ndk-mod-get-closure.empty = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(call test-expect,,$(call -ndk-mod-get-closure,,-local-deps))
|
|
|
|
-test-ndk-mod-get-closure.single = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(eval A_depends :=)\
|
|
$(call test-expect,A,$(call -ndk-mod-get-closure,A,-local-deps))
|
|
|
|
-test-ndk-mod-get-closure.double = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(eval A_depends := B)\
|
|
$(eval B_depends :=)\
|
|
$(call test-expect,A B,$(call -ndk-mod-get-closure,A,-local-deps))
|
|
|
|
-test-ndk-mod-get-closure.circular-deps = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(eval A_depends := B)\
|
|
$(eval B_depends := C)\
|
|
$(eval C_depends := A)\
|
|
$(call test-expect,A B C,$(call -ndk-mod-get-closure,A,-local-deps))
|
|
|
|
-test-ndk-mod-get-closure.ABCDE = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(eval A_depends := B C)\
|
|
$(eval B_depends := D)\
|
|
$(eval C_depends := D E)\
|
|
$(eval D_depends :=)\
|
|
$(eval E_depends :=)\
|
|
$(call test-expect,A B C D E,$(call -ndk-mod-get-closure,A,-local-deps))
|
|
|
|
|
|
#########################################################################
|
|
# For topological sort, we need to count the number of incoming edges
|
|
# in each graph node. The following helper functions implement this and
|
|
# hide implementation details.
|
|
#
|
|
# Count the number of incoming edges for each node during topological
|
|
# sort with a string of xxxxs. I.e.:
|
|
# 0 edge -> ''
|
|
# 1 edge -> 'x'
|
|
# 2 edges -> 'xx'
|
|
# 3 edges -> 'xxx'
|
|
# etc.
|
|
#########################################################################
|
|
|
|
# zero the incoming edge counter for module $1
|
|
-ndk-mod-topo-zero-incoming = \
|
|
$(eval _ndk_mod_topo_incoming.$1 :=)
|
|
|
|
# increment the incoming edge counter for module $1
|
|
-ndk-mod-topo-increment-incoming = \
|
|
$(eval _ndk_mod_topo_incoming.$1 := $$(_ndk_mod_topo_incoming.$1)x)
|
|
|
|
# decrement the incoming edge counter for module $1
|
|
-ndk-mod-topo-decrement-incoming = \
|
|
$(eval _ndk_mod_topo_incoming.$1 := $$(_ndk_mod_topo_incoming.$1:%x=%))
|
|
|
|
# return non-empty if the module $1's incoming edge counter is > 0
|
|
-ndk-mod-topo-has-incoming = $(_ndk_mod_topo_incoming.$1)
|
|
|
|
# Find first node in a list that has zero incoming edges.
|
|
# $1: list of nodes
|
|
# Out: first node that has zero incoming edges, or empty.
|
|
-ndk-mod-topo-find-first-zero-incoming = $(firstword $(call -ndk-mod-filter-out,$1,-ndk-mod-topo-has-incoming))
|
|
|
|
# Only use for debugging:
|
|
-ndk-mod-topo-dump-count = \
|
|
$(foreach _ndk_mod_module,$1,\
|
|
$(info .. $(_ndk_mod_module) incoming='$(_ndk_mod_topo_incoming.$(_ndk_mod_module))'))
|
|
|
|
|
|
|
|
#########################################################################
|
|
# Return the topologically ordered closure of all nodes from a top-level
|
|
# one. This means that a node A, in the result, will always appear after
|
|
# node B if A depends on B. Assumes that the graph is a DAG (if there are
|
|
# circular dependencies, this property cannot be guaranteed, but at least
|
|
# the function should not loop infinitely).
|
|
#
|
|
# $1: top-level node name.
|
|
# $2: dependency function, i.e. $(call $2,<name>) returns the children
|
|
# nodes for <name>.
|
|
# Return: list of nodes, include $1, which will always be the first.
|
|
#########################################################################
|
|
-ndk-mod-get-topo-list = $(strip \
|
|
$(eval _ndk_mod_top_module := $1)\
|
|
$(eval _ndk_mod_deps_func := $2)\
|
|
$(eval _ndk_mod_nodes := $(call -ndk-mod-get-closure,$1,$2))\
|
|
$(call -ndk-mod-topo-count,$(_ndk_mod_nodes))\
|
|
$(eval _ndk_mod_list :=)\
|
|
$(eval _ndk_mod_wq := $(call -ndk-mod-topo-find-first-zero-incoming,$(_ndk_mod_nodes)))\
|
|
$(call -ndk-mod-topo-sort)\
|
|
$(_ndk_mod_list) $(_ndk_mod_nodes)\
|
|
)
|
|
|
|
# Given a closure list of nodes, count their incoming edges.
|
|
# $1: list of nodes, must be a graph closure.
|
|
-ndk-mod-topo-count = \
|
|
$(foreach _ndk_mod_module,$1,\
|
|
$(call -ndk-mod-topo-zero-incoming,$(_ndk_mod_module)))\
|
|
$(foreach _ndk_mod_module,$1,\
|
|
$(call -ndk-mod-get-depends)\
|
|
$(foreach _ndk_mod_dep,$(_ndk_mod_depends),\
|
|
$(call -ndk-mod-topo-increment-incoming,$(_ndk_mod_dep))\
|
|
)\
|
|
)
|
|
|
|
-ndk-mod-topo-sort = \
|
|
$(call -ndk-topo-debug,-ndk-mod-topo-sort: wq='$(_ndk_mod_wq)' list='$(_ndk_mod_list)')\
|
|
$(call -ndk-mod-pop-first)\
|
|
$(if $(_ndk_mod_module),\
|
|
$(eval _ndk_mod_list += $(_ndk_mod_module))\
|
|
$(eval _ndk_mod_nodes := $(filter-out $(_ndk_mod_module),$(_ndk_mod_nodes)))\
|
|
$(call -ndk-mod-topo-decrement-incoming,$(_ndk_mod_module))\
|
|
$(call -ndk-mod-get-depends)\
|
|
$(call -ndk-topo-debug,-ndk-mod-topo-sort: deps='$(_ndk_mod_depends)')\
|
|
$(foreach _ndk_mod_dep,$(_ndk_mod_depends),\
|
|
$(call -ndk-mod-topo-decrement-incoming,$(_ndk_mod_dep))\
|
|
$(if $(call -ndk-mod-topo-has-incoming,$(_ndk_mod_dep)),,\
|
|
$(call -ndk-mod-push-back,$(_ndk_mod_dep))\
|
|
)\
|
|
)\
|
|
$(call -ndk-mod-topo-sort)\
|
|
)
|
|
|
|
|
|
-test-ndk-mod-get-topo-list.empty = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(call test-expect,,$(call -ndk-mod-get-topo-list,,-local-deps))
|
|
|
|
-test-ndk-mod-get-topo-list.single = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(eval A_depends :=)\
|
|
$(call test-expect,A,$(call -ndk-mod-get-topo-list,A,-local-deps))
|
|
|
|
-test-ndk-mod-get-topo-list.no-infinite-loop = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(eval A_depends := B)\
|
|
$(eval B_depends := C)\
|
|
$(eval C_depends := A)\
|
|
$(call test-expect,A B C,$(call -ndk-mod-get-topo-list,A,-local-deps))
|
|
|
|
-test-ndk-mod-get-topo-list.ABC = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(eval A_depends := B C)\
|
|
$(eval B_depends :=)\
|
|
$(eval C_depends := B)\
|
|
$(call test-expect,A C B,$(call -ndk-mod-get-topo-list,A,-local-deps))
|
|
|
|
-test-ndk-mod-get-topo-list.ABCD = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(eval A_depends := B C)\
|
|
$(eval B_depends := D)\
|
|
$(eval C_depends := B)\
|
|
$(eval D_depends :=)\
|
|
$(call test-expect,A C B D,$(call -ndk-mod-get-topo-list,A,-local-deps))
|
|
|
|
-test-ndk-mod-get-topo-list.ABC.circular = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(eval A_depends := B)\
|
|
$(eval B_depends := C)\
|
|
$(eval C_depends := B)\
|
|
$(call test-expect,A B C,$(call -ndk-mod-get-topo-list,A,-local-deps))
|
|
|
|
#########################################################################
|
|
# Return the topologically ordered closure of all dependencies from a
|
|
# top-level node.
|
|
#
|
|
# $1: top-level node name.
|
|
# $2: dependency function, i.e. $(call $2,<name>) returns the children
|
|
# nodes for <name>.
|
|
# Return: list of nodes, include $1, which will never be included.
|
|
#########################################################################
|
|
-ndk-mod-get-topological-depends = $(call rest,$(call -ndk-mod-get-topo-list,$1,$2))
|
|
|
|
-test-ndk-mod-get-topological-depends.simple = \
|
|
$(eval -local-get-deps = $$($$1_depends))\
|
|
$(eval A_depends := B)\
|
|
$(eval B_depends :=)\
|
|
$(eval topo_deps := $$(call -ndk-mod-get-topological-depends,A,-local-get-deps))\
|
|
$(call test-expect,B,$(topo_deps),topo dependencies)
|
|
|
|
-test-ndk-mod-get-topological-depends.ABC = \
|
|
$(eval -local-get-deps = $$($$1_depends))\
|
|
$(eval A_depends := B C)\
|
|
$(eval B_depends :=)\
|
|
$(eval C_depends := B)\
|
|
$(eval bfs_deps := $$(call -ndk-mod-get-bfs-depends,A,-local-get-deps))\
|
|
$(eval topo_deps := $$(call -ndk-mod-get-topological-depends,A,-local-get-deps))\
|
|
$(call test-expect,B C,$(bfs_deps),dfs dependencies)\
|
|
$(call test-expect,C B,$(topo_deps),topo dependencies)
|
|
|
|
-test-ndk-mod-get-topological-depends.circular = \
|
|
$(eval -local-get-deps = $$($$1_depends))\
|
|
$(eval A_depends := B)\
|
|
$(eval B_depends := C)\
|
|
$(eval C_depends := B)\
|
|
$(eval bfs_deps := $$(call -ndk-mod-get-bfs-depends,A,-local-get-deps))\
|
|
$(eval topo_deps := $$(call -ndk-mod-get-topological-depends,A,-local-get-deps))\
|
|
$(call test-expect,B C,$(bfs_deps),dfs dependencies)\
|
|
$(call test-expect,B C,$(topo_deps),topo dependencies)
|
|
|
|
#########################################################################
|
|
# Return breadth-first walk of a graph, starting from an arbitrary
|
|
# node.
|
|
#
|
|
# This performs a breadth-first walk of the graph and will return a
|
|
# list of nodes. Note that $1 will always be the first in the list.
|
|
#
|
|
# $1: root node name.
|
|
# $2: dependency function, i.e. $(call $2,<name>) returns the nodes
|
|
# that <name> depends on.
|
|
# Result: list of dependent modules, $1 will be part of it.
|
|
#########################################################################
|
|
-ndk-mod-get-bfs-list = $(strip \
|
|
$(eval _ndk_mod_wq := $(call strip-lib-prefix,$1)) \
|
|
$(eval _ndk_mod_deps_func := $2)\
|
|
$(eval _ndk_mod_list :=)\
|
|
$(call -ndk-mod-tree-setup-visit)\
|
|
$(call -ndk-mod-tree-set-visited,$(_ndk_mod_wq))\
|
|
$(call -ndk-mod-bfs-recursive) \
|
|
$(_ndk_mod_list))
|
|
|
|
# Recursive function used to perform a depth-first scan.
|
|
# Must initialize _ndk_mod_list, _ndk_mod_field, _ndk_mod_wq
|
|
# before calling this.
|
|
-ndk-mod-bfs-recursive = \
|
|
$(call -ndk-mod-debug,-ndk-mod-bfs-recursive wq='$(_ndk_mod_wq)' list='$(_ndk_mod_list)' visited='$(_ndk_mod_tree_visitors)')\
|
|
$(call -ndk-mod-pop-first)\
|
|
$(eval _ndk_mod_list += $$(_ndk_mod_module))\
|
|
$(call -ndk-mod-get-depends)\
|
|
$(call -ndk-mod-debug,. node='$(_ndk_mod_module)' deps='$(_ndk_mod_depends)')\
|
|
$(foreach _ndk_mod_child,$(_ndk_mod_depends),\
|
|
$(if $(call -ndk-mod-tree-is-visited,$(_ndk_mod_child)),,\
|
|
$(call -ndk-mod-tree-set-visited,$(_ndk_mod_child))\
|
|
$(call -ndk-mod-push-back,$(_ndk_mod_child))\
|
|
)\
|
|
)\
|
|
$(if $(_ndk_mod_wq),$(call -ndk-mod-bfs-recursive))
|
|
|
|
-test-ndk-mod-get-bfs-list.empty = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(call test-expect,,$(call -ndk-mod-get-bfs-list,,-local-deps))
|
|
|
|
-test-ndk-mod-get-bfs-list.A = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(eval A_depends :=)\
|
|
$(call test-expect,A,$(call -ndk-mod-get-bfs-list,A,-local-deps))
|
|
|
|
-test-ndk-mod-get-bfs-list.ABCDEF = \
|
|
$(eval -local-deps = $$($$1_depends))\
|
|
$(eval A_depends := B C)\
|
|
$(eval B_depends := D E)\
|
|
$(eval C_depends := F E)\
|
|
$(eval D_depends :=)\
|
|
$(eval E_depends :=)\
|
|
$(eval F_depends :=)\
|
|
$(call test-expect,A B C D E F,$(call -ndk-mod-get-bfs-list,A,-local-deps))
|
|
|
|
#########################################################################
|
|
# Return breadth-first walk of a graph, starting from an arbitrary
|
|
# node.
|
|
#
|
|
# This performs a breadth-first walk of the graph and will return a
|
|
# list of nodes. Note that $1 will _not_ be part of the list.
|
|
#
|
|
# $1: root node name.
|
|
# $2: dependency function, i.e. $(call $2,<name>) returns the nodes
|
|
# that <name> depends on.
|
|
# Result: list of dependent modules, $1 will not be part of it.
|
|
#########################################################################
|
|
-ndk-mod-get-bfs-depends = $(call rest,$(call -ndk-mod-get-bfs-list,$1,$2))
|
|
|
|
-test-ndk-mod-get-bfs-depends.simple = \
|
|
$(eval -local-deps-func = $$($$1_depends))\
|
|
$(eval A_depends := B)\
|
|
$(eval B_depends :=)\
|
|
$(eval deps := $$(call -ndk-mod-get-bfs-depends,A,-local-deps-func))\
|
|
$(call test-expect,B,$(deps))
|
|
|
|
-test-ndk-mod-get-bfs-depends.ABC = \
|
|
$(eval -local-deps-func = $$($$1_depends))\
|
|
$(eval A_depends := B C)\
|
|
$(eval B_depends :=)\
|
|
$(eval C_depends := B)\
|
|
$(eval deps := $$(call -ndk-mod-get-bfs-depends,A,-local-deps-func))\
|
|
$(call test-expect,B C,$(deps))\
|
|
|
|
-test-ndk-mod-get-bfs-depends.ABCDE = \
|
|
$(eval -local-deps-func = $$($$1_depends))\
|
|
$(eval A_depends := B C)\
|
|
$(eval B_depends := D)\
|
|
$(eval C_depends := D E F)\
|
|
$(eval D_depends :=)\
|
|
$(eval E_depends :=)\
|
|
$(eval F_depends :=)\
|
|
$(eval deps := $$(call -ndk-mod-get-bfs-depends,A,-local-deps-func))\
|
|
$(call test-expect,B C D E F,$(deps))\
|
|
|
|
-test-ndk-mod-get-bfs-depends.loop = \
|
|
$(eval -local-deps-func = $$($$1_depends))\
|
|
$(eval A_depends := B)\
|
|
$(eval B_depends := A)\
|
|
$(eval deps := $$(call -ndk-mod-get-bfs-depends,A,-local-deps-func))\
|
|
$(call test-expect,B,$(deps))
|