summaryrefslogtreecommitdiff
path: root/makefiles/Makefile.subdir
blob: a8eb92015898e23d8e5f478f42b5451671df7cf1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# Child makefile fragment
#
# Inputs (reset on exit)
#
# DIR_SOURCES		List of source files in this directory
# DIR_TEST_ITEMS	List of test items in this directory
# DIR_INSTALL_ITEMS	Items to install in form <destination>:<file1>;<file2>
#
# Toolchain is provided by top-level makefile
#
# Variables provided by top-level makefile
#
# BUILDDIR		The location of the build tree root
# COMPONENT		The name of the component
# CURDIR		The location of the source tree root
# EXPORTDIR		The location of the export directory
# WANT_TEST		Whether to build testcases
#
# do_include		Canned command sequence to include a child makefile
#
# Variables provided by parent makefile:
#
# DIR			The name of the directory we're in, relative to CURDIR
#
# Variables we can manipulate:
#
# CLEAN_ITEMS		The list of items to remove for "make clean"
# DISTCLEAN_ITEMS	The list of items to remove for "make distclean"
# TEST_ITEMS		The list of items to build for "make test"
# TEST_TARGETS		The list of target names to run for "make test"
# INSTALL_ITEMS		The list of items to (un)install
#
# SOURCES		The list of sources to build for $(COMPONENT)
#
# Plus anything from the toolchain

# Push parent directory onto the directory stack
sp             := $(sp).x
dirstack_$(sp) := $(d)
d              := $(DIR)

# Sources
SRCS_$(d) := $(DIR_SOURCES)
TEST_ITEMS_$(d) :=
INSTALL_ITEMS_$(d) :=

# Append to sources for component
SOURCES := $(SOURCES) $(addprefix $(d), $(SRCS_$(d)))

# Test sources
ifeq ($(WANT_TEST),yes)
  ifneq ($(DIR_TEST_ITEMS),)
    # Extract the binary name from the ITEM
    binary = $(subst /,_,$(addprefix $(d),$(firstword $(subst :, ,$(ITEM)))))
    # Extract the list of sources from the ITEM
    sources = $(subst ;, ,$(lastword $(subst :, ,$(ITEM))))

    # We can't simply use the output of foreach here, 
    # as it space separates its output, which kinda defeats the point.
    define append_test_src
      TEST_ITEMS_$(d) := $$(TEST_ITEMS_$(d))$1;

    endef

    define append_test
      TEST_ITEMS_$(d) := $$(TEST_ITEMS_$(d)) $1:

      $$(eval $$(foreach TSRC,$2, \
		$$(call append_test_src,$$(addprefix $$(d),$$(TSRC)))))

    endef

    # Append test items, prepending $(d) to each source file 
    $(eval $(foreach ITEM,$(DIR_TEST_ITEMS), \
		$(call append_test,$(binary),$(sources))))

    TEST_ITEMS := $(TEST_ITEMS) $(TEST_ITEMS_$(d))

    TEST_TARGETS := $(TEST_TARGETS) test_$(d)

    # Extract the binary name from the TEST
    binary_name = $(firstword $(subst :, ,$(TEST)))

    # Target for tests in this directory
    test_$(d): $(d) $(addprefix $(BUILDDIR)/, \
			$(foreach TEST,$(TEST_ITEMS_$(d)),$(binary_name)))
	$(Q)$(SHAREDLDPATH) $(TESTRUNNER) $(BUILDDIR) \
		$(CURDIR)/$< $(subst /,_,$<) $(EXEEXT)
  endif
endif

# Install items
ifneq ($(DIR_INSTALL_ITEMS),)
  # Extract the destination directory from the variable
  dest_dir = $(firstword $(subst :, ,$(ITEM)))
  # Extract the list of files to install
  files = $(subst ;, ,$(lastword $(subst :, ,$(ITEM))))

  define append_install_file
    INSTALL_ITEMS_$(d) := $$(INSTALL_ITEMS_$(d))$1;

  endef

  define append_install_item
    INSTALL_ITEMS_$(d) := $$(INSTALL_ITEMS_$(d)) $1:

    $$(eval $$(foreach FILE,$2, \
		$$(call append_install_file,$$(addprefix $$(d),$$(FILE)))))

  endef

  # Append items to install (along with install location), prepending $(d)
  # to each item in the file list 
  $(eval $(foreach ITEM,$(DIR_INSTALL_ITEMS), \
		$(call append_install_item,$(dest_dir),$(files))))

  INSTALL_ITEMS := $(INSTALL_ITEMS) $(INSTALL_ITEMS_$(d))
endif

# Reset the inputs
DIR_SOURCES :=
DIR_TEST_ITEMS :=
DIR_INSTALL_ITEMS :=

# Now include any children we may have
MAKE_INCLUDES := $(wildcard $(d)*/Makefile)
$(eval $(foreach INC, $(MAKE_INCLUDES), $(call do_include,$(INC))))

# Pop off the directory stack
d  := $(dirstack_$(sp))
sp := $(basename $(sp))