summaryrefslogtreecommitdiff
path: root/Makefile
blob: 16ee1a4601f44e3c9acb3ad5b4ac8b9c613c2faf (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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
SubDirs := lib

# Set default rule before anything else.
all::

include make/config.mk
include make/util.mk
# If SRCROOT is defined, assume we are doing an Apple style build. We
# should be able to use RC_XBS for this but that is unused during
# "make installsrc".
ifdef SRCROOT
  include make/AppleBI.mk
endif

# Make sure we don't build with a missing ProjObjRoot.
ifeq ($(ProjObjRoot),)
$(error Refusing to build with empty ProjObjRoot variable)
endif

##############

###
# Rules

###
# Top level targets

# Provide default clean target which is extended by other templates.
.PHONY: clean
clean::

# Test
.PHONY: test
test:
	cd test/Unit && ./test

# Template: Config_template Config
#
# This template is used once per Config at the top-level.
define Config_template
$(call Set,ActiveConfig,$1)
$(call Set,ActiveObjPath,$(ProjObjRoot)/$(ActiveConfig))
$(call Set,ActiveLibGen,$(ActiveObjPath)/libcompiler_rt.Generic.a)
$(call Set,ActiveLibOpt,$(ActiveObjPath)/libcompiler_rt.Optimized.a)

# The sublibraries to use for a generic version.
$(call Set,GenericInputs,$(foreach arch,$(Archs),$(ActiveObjPath)/$(arch)/libcompiler_rt.Generic.a))
# The sublibraries to use for an optimized version.
$(call Set,OptimizedInputs,$(foreach arch,$(Archs),$(ActiveObjPath)/$(arch)/libcompiler_rt.Optimized.a))

# Provide top-level fat archive targets.
$(ActiveLibGen): $(GenericInputs) $(ActiveObjPath)/.dir
	$(Summary) "  UNIVERSAL: $(ActiveConfig): $$@"
	-$(Verb) $(RM) $$@
	$(Verb) $(Lipo) -create -output $$@ $(GenericInputs)
$(ActiveLibOpt): $(OptimizedInputs) $(ActiveObjPath)/.dir
	$(Summary) "  UNIVERSAL: $(ActiveConfig): $$@"
	-$(Verb) $(RM) $$@
	$(Verb) $(Lipo) -create -output $$@ $(OptimizedInputs)
.PRECIOUS: $(ActiveObjPath)/.dir

# Add to target lists.
all:: $(ActiveConfig) $(ActiveLibGen) $(ActiveLibOpt)

# Remove entire config directory on clean.
clean:: $(ActiveObjPath)/.remove
endef

# Template: CNA_template Config Arch
# 
# This template is used once per Config/Arch at the top-level.
define CNA_template
$(call Set,ActiveConfig,$1)
$(call Set,ActiveArch,$2)
$(call Set,ActiveObjPath,$(ProjObjRoot)/$(ActiveConfig)/$(ActiveArch))
$(call Set,ActiveLibGen,$(ActiveObjPath)/libcompiler_rt.Generic.a)
$(call Set,ActiveLibOpt,$(ActiveObjPath)/libcompiler_rt.Optimized.a)

# Initialize inputs lists. This are extended by the CNA_subdir
# template. The one tricky bit is that we need to use these quoted,
# because they are not complete until the entire makefile has been
# processed.
$(call Set,GenericInputs.$(ActiveConfig).$(ActiveArch),)
$(call Set,OptimizedInputs.$(ActiveConfig).$(ActiveArch),)
# Final.Inputs is created once we have loaded all the subdirectories
# and know what the correct inputs are.

# Provide top-level archive targets.
$(ActiveLibGen): $(ActiveObjPath)/.dir
	$(Summary) "  ARCHIVE:   $(ActiveConfig)/$(ActiveArch): $$@"
	-$(Verb) $(RM) $$@
	$(Verb) $(Archive) $$@ $$(Generic.Inputs.$(ActiveConfig).$(ActiveArch))
	$(Verb) $(Ranlib) $$@
# FIXME: The dependency on ActiveLibGen is a hack, this picks up the
# dependencies on the generic inputs.
$(ActiveLibOpt): $(ActiveLibGen) $(ActiveObjPath)/.dir
	$(Summary) "  ARCHIVE:   $(ActiveConfig)/$(ActiveArch): $$@"
	-$(Verb) $(RM) $$@
	$(Verb) $(Archive) $$@ $$(Final.Inputs.$(ActiveConfig).$(ActiveArch))
	$(Verb) $(Ranlib) $$@
.PRECIOUS: $(ActiveObjPath)/.dir

# Provide some default "alias" targets.
$(ActiveConfig):: $(ActiveLibGen) $(ActiveLibOpt)
$(ActiveArch):: $(ActiveLibGen) $(ActiveLibOpt)
$(ActiveConfig)-$(ActiveArch):: $(ActiveLibGen) $(ActiveLibOpt)
endef

$(foreach config,$(Configs), \
  $(foreach arch,$(Archs), \
    $(eval $(call CNA_template,$(config),$(arch)))))

$(foreach config,$(Configs), \
  $(eval $(call Config_template,$(config))))

###
# How to build things.

# Define rules for building on each configuration & architecture. This
# is not exactly obvious, but variables inside the template are being
# expanded during the make processing, so automatic variables must be
# quoted and normal assignment cannot be used.

# Template: CNA_template Config Arch Dir
#   Uses: GetArgs, Dependencies, ObjNames
#
# This template is used once per Config/Arch/Dir.
define CNA_subdir_template
$(call Set,ActiveConfig,$1)
$(call Set,ActiveArch,$2)
$(call Set,ActiveDir,$3)
$(call Set,ActiveSrcPath,$(ProjSrcRoot)/$(ActiveDir))
$(call Set,ActiveObjPath,$(ProjObjRoot)/$(ActiveDir)/$(ActiveConfig)/$(ActiveArch))

$(call Set,ActiveFlags,$(call GetArgs,$(ActiveConfig),$(ActiveArch)))
$(call Set,ActiveObjects,$(ObjNames:%=$(ActiveObjPath)/%))

# Add to the input list for the appropriate library and update the
# dependency.
$(call Append,$(Target).Inputs.$(ActiveConfig).$(ActiveArch),$(ActiveObjects))
$(ProjObjRoot)/$(ActiveConfig)/$(ActiveArch)/libcompiler_rt.$(Target).a: $(ActiveObjects)

$(ActiveObjPath)/%.o: $(ActiveSrcPath)/%.s $(Dependencies) $(ActiveObjPath)/.dir
	$(Summary) "  ASSEMBLE:  $(ActiveConfig)/$(ActiveArch): $$<"
	$(Verb) $(CC) -c -o $$@ $(ActiveFlags) $$<
.PRECIOUS: $(ActiveObjPath)/.dir

$(ActiveObjPath)/%.o: $(ActiveSrcPath)/%.c $(Dependencies) $(ActiveObjPath)/.dir
	$(Summary) "  COMPILE:   $(ActiveConfig)/$(ActiveArch): $$<"
	$(Verb) $(CC) -c -o $$@ $(ActiveFlags) $$<
.PRECIOUS: $(ActiveObjPath)/.dir

# Remove entire config directory on clean.
clean:: $(ProjObjRoot)/$(ActiveDir)/$(ActiveConfig)/.remove
endef

###
# Directory handling magic.

# Create directories as needed, and timestamp their creation.
%/.dir:
	$(Summary) "  MKDIR:     $*"
	$(Verb) $(MKDIR) $* > /dev/null
	$(Verb) $(DATE) > $@

# Remove directories
%/.remove:
	$(Verb) $(RM) -r $*

###
# Include child makefile fragments

$(foreach subdir,$(SubDirs),$(eval include $(subdir)/Makefile.mk))

###
# Determine the actual inputs for an optimized library.

# Template: Final_CNA_template Config Arch
#   Uses: GetArgs, Dependencies, ObjNames
#
# This template is used once per Config/Arch.
define Final_CNA_template
$(call Set,ActiveConfig,$1)
$(call Set,ActiveArch,$2)

$(call Set,Final.Inputs.$(ActiveConfig).$(ActiveArch),\
  $(shell make/filter-inputs \
	          $(Optimized.Inputs.$(ActiveConfig).$(ActiveArch)) \
	          $(Generic.Inputs.$(ActiveConfig).$(ActiveArch))))
endef

$(foreach config,$(Configs), \
  $(foreach arch,$(Archs), \
    $(eval $(call Final_CNA_template,$(config),$(arch)))))