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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
|
# -*- makefile -*-
#
# This is the makefile fragment with default rules
# for building things in MCS
#
# To customize the build, you should edit config.make.
# If you need to edit this file, that's a bug; email
# peter@newton.cx about it.
empty :=
space := $(empty) $(empty)
# given $(thisdir), we compute the path to the top directory
#
# split_path = $(filter-out .,$(subst /,$(space),$(1)))
# make_path = ./$(subst $(space),/,$(1))
# dotdottify = $(patsubst %,..,$(1))
# topdir = $(call make_path,$(call dotdottify,$(call split_path,$(thisdir))))
topdir := ./$(subst $(space),/,$(patsubst %,..,$(filter-out .,$(subst /,$(space),$(thisdir)))))
VERSION = 0.93
Q=$(if $(V),,@)
# echo -e "\\t" does not work on some systems, so use 5 spaces
Q_MCS=$(if $(V),,@echo "MCS [$(intermediate)$(PROFILE)] $(notdir $(@))";)
ifndef BUILD_TOOLS_PROFILE
BUILD_TOOLS_PROFILE = build
endif
USE_MCS_FLAGS = /codepage:$(CODEPAGE) $(LOCAL_MCS_FLAGS) $(PLATFORM_MCS_FLAGS) $(PROFILE_MCS_FLAGS) $(MCS_FLAGS)
USE_MBAS_FLAGS = /codepage:$(CODEPAGE) $(LOCAL_MBAS_FLAGS) $(PLATFORM_MBAS_FLAGS) $(PROFILE_MBAS_FLAGS) $(MBAS_FLAGS)
USE_CFLAGS = $(LOCAL_CFLAGS) $(CFLAGS) $(CPPFLAGS)
CSCOMPILE = $(Q_MCS) $(MCS) $(USE_MCS_FLAGS)
BASCOMPILE = $(MBAS) $(USE_MBAS_FLAGS)
CCOMPILE = $(CC) $(USE_CFLAGS)
BOOT_COMPILE = $(Q_MCS) $(BOOTSTRAP_MCS) $(USE_MCS_FLAGS)
INSTALL = $(SHELL) $(topdir)/../mono/install-sh
INSTALL_DATA = $(INSTALL) -c -m 644
INSTALL_BIN = $(INSTALL) -c -m 755
INSTALL_LIB = $(INSTALL_BIN)
MKINSTALLDIRS = $(SHELL) $(topdir)/mkinstalldirs
INTERNAL_MBAS = $(RUNTIME) $(RUNTIME_FLAGS) $(topdir)/mbas/mbas.exe
INTERNAL_GMCS = $(RUNTIME) $(RUNTIME_FLAGS) $(topdir)/class/lib/$(BUILD_TOOLS_PROFILE)/mcs.exe
INTERNAL_ILASM = $(RUNTIME) $(RUNTIME_FLAGS) $(topdir)/class/lib/$(PROFILE)/ilasm.exe
corlib = mscorlib.dll
INTERNAL_RESGEN = $(RUNTIME) $(RUNTIME_FLAGS) $(topdir)/class/lib/$(PROFILE)/resgen.exe
RESGEN = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_RESGEN)
depsdir = $(topdir)/build/deps
# Make sure these propagate if set manually
export PLATFORM
export PROFILE
export MCS
export MCS_FLAGS
export CC
export CFLAGS
export INSTALL
export MKINSTALLDIRS
export BOOTSTRAP_MCS
export DESTDIR
export RESGEN
# Get this so the platform.make platform-check rule doesn't become the
# default target
.DEFAULT: all
default: all
# Get initial configuration. pre-config is so that the builder can
# override PLATFORM or PROFILE
include $(topdir)/build/config-default.make
-include $(topdir)/build/pre-config.make
-include $(topdir)/build/config.make
# Default PLATFORM and PROFILE if they're not already defined.
ifndef PLATFORM
ifeq ($(OS),Windows_NT)
ifneq ($(V),)
$(info *** Assuming PLATFORM is 'win32'.)
endif
PLATFORM = win32
else
ifneq ($(V),)
$(info *** Assuming PLATFORM is 'linux'.)
endif
PLATFORM = linux
endif
endif
# Platform config
include $(topdir)/build/platforms/$(PLATFORM).make
ifdef PLATFORM_CORLIB
corlib = $(PLATFORM_CORLIB)
endif
# Useful
ifeq ($(PLATFORM_RUNTIME),$(RUNTIME))
PLATFORM_MONO_NATIVE = yes
endif
# Rest of the configuration
ifndef PROFILE
PROFILE = $(DEFAULT_PROFILE)
endif
include $(topdir)/build/profiles/$(PROFILE).make
# If the profile is using nunit-lite, use it
ifdef NUNIT_LITE
TEST_HARNESS=$(topdir)/class/lib/$(PROFILE)/nunit-lite-console.exe
endif
# Make sure propagates
export TEST_HARNESS
# If the profile is using nunit-lite, use it
ifdef NUNIT_LITE
TEST_HARNESS=$(topdir)/class/lib/$(PROFILE)/nunit-lite-console.exe
endif
# Make sure propagates
export TEST_HARNESS
# start aot config
# We set the prefix of the aot build flags
# in the profile. This determines the aot type,
# whether it be llvmonly or full. To this we append the
# options which do not change between them, the INVARIANT_AOT_OPTIONS
ifndef AOT_BUILD_FLAGS_PREFIX
AOT_BUILD_FLAGS_PREFIX = --aot=
endif
# Set the options for building and running AOT
# The trampoline numbers are provisional, they are what is required
# to run the corlib test suite. They should be considered a lower bound.
INVARIANT_AOT_OPTIONS=bind-to-runtime-version,nimt-trampolines=900,ntrampolines=8000
ifndef MONO_DISABLE_GSHAREDVT
INVARIANT_AOT_OPTIONS:=$(INVARIANT_AOT_OPTIONS),ngsharedvt-trampolines=900
endif
AOT_BUILD_FLAGS = $(AOT_BUILD_FLAGS_PREFIX)$(INVARIANT_AOT_OPTIONS)
# end AOT config
ifdef BCL_OPTIMIZE
PROFILE_MCS_FLAGS += -optimize
endif
# Design:
# Problem: We want to be able to build aot
# assemblies as part of the build system.
#
# For this to be done safely, we really need two passes. This
# ensures that all of the .dlls are compiled before trying to
# aot them. Because we want this to be the
# default target for some profiles(mobile_static) we have a
# two-level build system. The do-all-aot target is what
# gets invoked at the top-level when someone tries to build with aot.
# It will invoke the do-all target, and will set TOP_LEVEL_DO for this
# recursive make call in order to prevent this recursive call from trying
# to build aot in each of the subdirs. After this is done, we will aot
# everything that our building produced by aoting everything in
# mcs/class/lib/$(PROFILE)/
ifndef TOP_LEVEL_DO
ifdef ALWAYS_AOT
TOP_LEVEL_DO = do-all-aot
else
TOP_LEVEL_DO = do-all
endif # ALWAYS_AOT
endif # !TOP_LEVEL_DO
ifdef OVERRIDE_TARGET_ALL
all: all.override
else
all: $(TOP_LEVEL_DO)
endif
ifdef NO_INSTALL
GACUTIL = :
else
gacutil = $(topdir)/class/lib/$(BUILD_TOOLS_PROFILE)/gacutil.exe
GACUTIL = MONO_PATH="$(topdir)/class/lib/$(BUILD_TOOLS_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(RUNTIME_FLAGS) $(gacutil)
endif
STD_TARGETS = test run-test run-test-ondotnet clean install uninstall doc-update
$(STD_TARGETS): %: do-%
ifdef PLATFORM_AOT_SUFFIX
Q_AOT=$(if $(V),,@echo "AOT [$(PROFILE)] AOT All Assemblies";)
LIST_ALL_PROFILE_ASSEMBLIES = find . | grep -E '(dll|exe)$$' | grep -v -E 'bare|plaincore|secxml'
COMPILE_ALL_PROFILE_ASSEMBLIES = $(LIST_ALL_PROFILE_ASSEMBLIES) | MONO_PATH="./" xargs -I '{}' $(RUNTIME) $(RUNTIME_FLAGS) $(AOT_BUILD_FLAGS) '{}'
do-all-aot:
$(MAKE) do-all TOP_LEVEL_DO=do-all
$(MAKE) aot-all-profile
aot-all-profile:
$(Q_AOT) cd $(topdir)/class/lib/$(PROFILE)/ && $(COMPILE_ALL_PROFILE_ASSEMBLIES) &> $(PROFILE)-aot.log
endif
do-run-test:
ok=:; $(MAKE) run-test-recursive || ok=false; $(MAKE) run-test-local || ok=false; $$ok
do-%: %-recursive
$(MAKE) $*-local
.PHONY: all-local $(STD_TARGETS:=-local)
all-local $(STD_TARGETS:=-local):
csproj: do-csproj
# The way this is set up, any profile-specific subdirs list should
# be listed _before_ including rules.make. However, the default
# SUBDIRS list can come after, so don't use the eager := syntax when
# using the defaults.
PROFILE_SUBDIRS := $($(PROFILE)_SUBDIRS)
ifndef PROFILE_SUBDIRS
PROFILE_SUBDIRS = $(SUBDIRS)
endif
# These subdirs can be built in parallel
PROFILE_PARALLEL_SUBDIRS := $($(PROFILE)_PARALLEL_SUBDIRS)
ifndef PROFILE_PARALLEL_SUBDIRS
PROFILE_PARALLEL_SUBDIRS = $(PARALLEL_SUBDIRS)
endif
ifndef FRAMEWORK_VERSION_MAJOR
FRAMEWORK_VERSION_MAJOR = $(basename $(FRAMEWORK_VERSION))
endif
%-recursive:
@set . $$MAKEFLAGS; final_exit=:; \
case $$2 in --unix) shift ;; esac; \
case $$2 in *=*) dk="exit 1" ;; *k*) dk=: ;; *) dk="exit 1" ;; esac; \
list='$(PROFILE_SUBDIRS)'; for d in $$list ; do \
(cd $$d && $(MAKE) $*) || { final_exit="exit 1"; $$dk; } ; \
done; \
if [ $* = "all" -a -n "$(PROFILE_PARALLEL_SUBDIRS)" ]; then \
$(MAKE) do-all-parallel ENABLE_PARALLEL_SUBDIR_BUILD=1 || { final_exit="exit 1"; $$dk; } ; \
else \
list='$(PROFILE_PARALLEL_SUBDIRS)'; for d in $$list ; do \
(cd $$d && $(MAKE) $*) || { final_exit="exit 1"; $$dk; } ; \
done; \
fi; \
$$final_exit
#
# Parallel build support
#
# The variable $(PROFILE)_PARALLEL_SUBDIRS should be set to the list of directories
# which could be built in parallel. These directories are built after the directories in
# $(PROFILE)_SUBDIRS.
# Parallel building is currently only supported for the 'all' target.
#
# Each directory's Makefile may define DEP_LIBS and DEP_DIRS to specify the libraries and
# directories it depends on.
#
ifneq ($(PROFILE_PARALLEL_SUBDIRS),)
dep_dirs = .dep_dirs-$(PROFILE)
$(dep_dirs):
@echo "Creating $@..."
list='$(PROFILE_PARALLEL_SUBDIRS)'; \
echo > $@; \
for d in $$list; do \
$(MAKE) -C $$d gen-deps DEPS_TARGET_DIR=$$d DEPS_FILE=$(abspath $@); \
done
-include $(dep_dirs)
endif
.PHONY: gen-deps
# The gen-deps target is in library.make/executable.make so it can pick up
# DEP_LIBS/DEP_DIRS
clean-dep-dir:
$(RM) $(dep_dirs)
clean-local: clean-dep-dir
ifdef ENABLE_PARALLEL_SUBDIR_BUILD
.PHONY: do-all-parallel $(PROFILE_PARALLEL_SUBDIRS)
do-all-parallel: $(PROFILE_PARALLEL_SUBDIRS)
$(PROFILE_PARALLEL_SUBDIRS):
@set . $$MAKEFLAGS; \
cd $@ && $(MAKE)
endif
ifndef DIST_SUBDIRS
DIST_SUBDIRS = $(SUBDIRS) $(DIST_ONLY_SUBDIRS)
endif
dist-recursive: dist-local
@case '$(distdir)' in [\\/$$]* | ?:[\\/]* ) reldir='$(distdir)' ;; *) reldir='../$(distdir)' ;; esac ; \
list='$(DIST_SUBDIRS)'; for d in $$list ; do \
(cd $$d && $(MAKE) distdir=$$reldir/$$d $@) || exit 1 ; \
done
# The following target can be used like
#
# dist-local: dist-default
# ... additional commands ...
#
# Notes:
# 1. we invert the test here to not end in an error if ChangeLog doesn't exist.
# 2. we error out if we try to dist a nonexistant file.
# 3. we pick up Makefile, makefile, or GNUmakefile.
dist-default:
-mkdir -p $(distdir)
test '!' -f ChangeLog || cp ChangeLog $(distdir)
if test -f Makefile; then m=M; fi; \
if test -f makefile; then m=m; fi; \
if test -f GNUmakefile; then m=GNUm; fi; \
for f in $${m}akefile $(DISTFILES) ; do \
dest=`dirname "$(distdir)/$$f"` ; \
$(MKINSTALLDIRS) $$dest && cp -p "$$f" $$dest || exit 1 ; \
done
if test -d Documentation ; then \
find . -name '*.xml' > .files ; \
tar cTf .files - | (cd $(distdir); tar xf -) ; \
rm .files ; \
fi
%/.stamp:
$(MKINSTALLDIRS) $(@D)
touch $@
## Documentation stuff
Q_MDOC =$(if $(V),,@echo "MDOC [$(PROFILE)] $(notdir $(@))";)
MDOC =$(Q_MDOC) MONO_PATH="$(topdir)/class/lib/$(DEFAULT_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(topdir)/class/lib/$(DEFAULT_PROFILE)/mdoc.exe
|