3 # This is the makefile fragment with default rules
4 # for building things in MCS
6 # To customize the build, you should edit config.make.
7 # If you need to edit this file, that's a bug; email
8 # peter@newton.cx about it.
11 space
:= $(empty
) $(empty
)
13 _FILTER_OUT
= $(foreach x
,$(2),$(if
$(findstring $(1),$(x
)),,$(x
)))
15 # given $(thisdir), we compute the path to the top directory
17 # split_path = $(filter-out .,$(subst /,$(space),$(1)))
18 # make_path = ./$(subst $(space),/,$(1))
19 # dotdottify = $(patsubst %,..,$(1))
20 # topdir = $(call make_path,$(call dotdottify,$(call split_path,$(thisdir))))
21 topdir
:= .
/$(subst $(space
),/,$(patsubst %,..
,$(filter-out .
,$(subst /,$(space
),$(thisdir
)))))
26 # echo -e "\\t" does not work on some systems, so use 5 spaces
27 Q_MCS
=$(if
$(V
),,@echo
"$(if $(MCS_MODE),MCS,CSC) [$(intermediate)$(PROFILE_DIRECTORY)] $(notdir $(@))";)
28 Q_AOT
=$(if
$(V
),,@echo
"AOT [$(intermediate)$(PROFILE_DIRECTORY)] $(notdir $(@))";)
30 ifndef BUILD_TOOLS_PROFILE
31 BUILD_TOOLS_PROFILE
= build
34 # NOTE: We have to use conditional functions to branch on the state of ENABLE_COMPILER_SERVER
35 # because the value of this flag can change after rules.make is evaluated. If we use regular ifeq
36 # statements our builds will opt to use or not use the compiler server seemingly at random because
37 # we include rules.make many times and the last observed value from rules.make does not match the
38 # value used when actually executing csc. you can observe this by adding an $ ( info here and an
39 # echo above the csc invocation and printing the values.
40 COMPILER_SERVER_ENABLED_ARGS
= /shared
:$(COMPILER_SERVER_PIPENAME
)
41 COMPILER_SERVER_ARGS
= $(if
$(findstring 1,$(ENABLE_COMPILER_SERVER
)),$(COMPILER_SERVER_ENABLED_ARGS
),)
42 CSC_LOCATION
= $(if
$(findstring 1,$(ENABLE_COMPILER_SERVER
)),$(SERVER_CSC_LOCATION
),$(STANDALONE_CSC_LOCATION
))
44 USE_MCS_FLAGS
= $(COMPILER_SERVER_ARGS
) /codepage
:$(CODEPAGE
) /nologo
/noconfig
/deterministic
$(LOCAL_MCS_FLAGS
) $(PLATFORM_MCS_FLAGS
) $(PROFILE_MCS_FLAGS
) $(MCS_FLAGS
)
45 USE_MBAS_FLAGS
= $(COMPILER_SERVER_ARGS
) /codepage
:$(CODEPAGE
) $(LOCAL_MBAS_FLAGS
) $(PLATFORM_MBAS_FLAGS
) $(PROFILE_MBAS_FLAGS
) $(MBAS_FLAGS
)
46 USE_CFLAGS
= $(LOCAL_CFLAGS
) $(CFLAGS
) $(CPPFLAGS
)
47 CSCOMPILE
= $(Q_MCS
) $(MCS
) $(USE_MCS_FLAGS
)
48 CSC_RUNTIME_FLAGS
= --aot-path
=$(abspath
$(topdir
)/class
/lib
/$(BUILD_TOOLS_PROFILE
)) --gc-params
=nursery-size
=64m
49 BASCOMPILE
= $(MBAS
) $(USE_MBAS_FLAGS
)
50 CCOMPILE
= $(CC
) $(USE_CFLAGS
)
51 BOOT_COMPILE
= $(Q_MCS
) $(BOOTSTRAP_MCS
) $(USE_MCS_FLAGS
)
52 INSTALL
= $(SHELL
) $(topdir
)/..
/mono
/install-sh
53 INSTALL_DATA
= $(INSTALL
) -c
-m
644
54 INSTALL_BIN
= $(INSTALL
) -c
-m
755
55 INSTALL_LIB
= $(INSTALL_BIN
)
56 MKINSTALLDIRS
= $(SHELL
) $(topdir
)/mkinstalldirs
57 INTERNAL_MBAS
= $(RUNTIME
) $(RUNTIME_FLAGS
) $(topdir
)/mbas
/mbas.exe
58 INTERNAL_CSC_LOCATION
= $(CSC_LOCATION
)
60 # Using CSC_SDK_PATH_DISABLED for sanity check that all references have path specified
61 INTERNAL_CSC
= CSC_SDK_PATH_DISABLED
= $(RUNTIME
) $(RUNTIME_FLAGS
) $(CSC_RUNTIME_FLAGS
) $(INTERNAL_CSC_LOCATION
)
63 RESGEN
= MONO_PATH
="$(topdir)/class/lib/$(BUILD_TOOLS_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME
) $(RUNTIME_FLAGS
) $(topdir
)/class
/lib
/$(BUILD_TOOLS_PROFILE
)/resgen.exe
64 STRING_REPLACER
= MONO_PATH
="$(topdir)/class/lib/$(BUILD_TOOLS_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME
) $(RUNTIME_FLAGS
) $(topdir
)/class
/lib
/$(BUILD_TOOLS_PROFILE
)/cil-stringreplacer.exe
65 ILASM
= MONO_PATH
="$(topdir)/class/lib/$(BUILD_TOOLS_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME
) $(RUNTIME_FLAGS
) $(topdir
)/class
/lib
/$(BUILD_TOOLS_PROFILE
)/ilasm.exe
66 GENSOURCES
= MONO_PATH
="$(topdir)/class/lib/$(BUILD_TOOLS_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME
) $(RUNTIME_FLAGS
) $(topdir
)/class
/lib
/$(BUILD_TOOLS_PROFILE
)/gensources.exe
68 depsdir
= $(topdir
)/build
/deps
70 # Make sure these propagate if set manually
83 # Get this so the platform.make platform-check rule doesn't become the
89 # Get initial configuration. pre-config is so that the builder can
90 # override BUILD_PLATFORM or PROFILE
92 include $(topdir
)/build
/config-default.make
93 -include $(topdir
)/build
/pre-config.make
94 -include $(topdir
)/build
/config.make
98 include $(topdir
)/build
/platforms
/$(BUILD_PLATFORM
).make
100 PROFILE_PLATFORM
= $(if
$(PLATFORMS
),$(if
$(filter $(PLATFORMS
),$(HOST_PLATFORM
)),$(HOST_PLATFORM
),$(error Unknown platform
"$(HOST_PLATFORM)" for profile
"$(PROFILE)")))
101 PROFILE_DIRECTORY
= $(PROFILE
)$(if
$(PROFILE_PLATFORM
),-$(PROFILE_PLATFORM
))
103 ifdef PLATFORM_CORLIB
104 corlib
= $(PLATFORM_CORLIB
)
108 ifeq ($(PLATFORM_RUNTIME
),$(RUNTIME
))
109 PLATFORM_MONO_NATIVE
= yes
112 # Rest of the configuration
115 PROFILE
= $(DEFAULT_PROFILE
)
118 include $(topdir
)/build
/profiles
/$(PROFILE
).make
121 PROFILE_MCS_FLAGS
+= -optimize
125 INTERNAL_CSC_LOCATION
= $(topdir
)/class
/lib
/$(BOOTSTRAP_PROFILE
)/mcs.exe
127 ifdef PLATFORM_DEBUG_FLAGS
128 PLATFORM_DEBUG_FLAGS
= /debug
:full
134 # Problem: We want to be able to build aot
135 # assemblies as part of the build system.
137 # For this to be done safely, we really need two passes. This
138 # ensures that all of the .dlls are compiled before trying to
139 # aot them. Because we want this to be the
140 # default target for some profiles(testing_aot_full) we have a
141 # two-level build system. The do-all-aot target is what
142 # gets invoked at the top-level when someone tries to build with aot.
143 # It will invoke the do-all target, and will set TOP_LEVEL_DO for this
144 # recursive make call in order to prevent this recursive call from trying
145 # to build aot in each of the subdirs. After this is done, we will aot
146 # everything that our building produced by aoting everything in
147 # mcs/class/lib/$(PROFILE)/
150 ifneq ($(or
$(ALWAYS_AOT_BCL
), $(ALWAYS_AOT_TESTS
)),)
151 TOP_LEVEL_DO
= do-all-aot
153 TOP_LEVEL_DO
= do-all
156 endif # !TOP_LEVEL_DO
158 ifdef OVERRIDE_TARGET_ALL
167 gacutil
= $(topdir
)/class
/lib
/$(BUILD_TOOLS_PROFILE
)/gacutil.exe
168 GACUTIL
= MONO_PATH
="$(topdir)/class/lib/$(BUILD_TOOLS_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME
) $(RUNTIME_FLAGS
) $(gacutil
)
171 STD_TARGETS
= test xunit-test run-test run-xunit-test run-test-ondotnet
clean install uninstall doc-update
173 $(STD_TARGETS
): %: do-
%
175 ifdef PLATFORM_AOT_SUFFIX
178 $(MAKE
) do-all TOP_LEVEL_DO
=do-all
179 $(MAKE
) aot-all-profile
181 # When we recursively call $(MAKE) aot-all-profile
182 # we will have created this directory, and so will
183 # be able to evaluate the .dylibs to make
184 ifneq ("$(wildcard $(topdir)/class/lib/$(PROFILE))","")
187 AOT_PROFILE_ASSEMBLIES
:= $(sort $(patsubst .
//%,%,$(filter-out %.dll.dll
%.exe.dll
%bare
% %plaincore
% %secxml
% %Facades
% %ilasm
%,$(filter %.dll
%.exe
,$(wildcard $(topdir
)/class
/lib
/$(PROFILE
)/*)))))
188 AOT_PROFILE_ASSEMBLIES_OUT
:= $(patsubst %,%$(PLATFORM_AOT_SUFFIX
),$(AOT_PROFILE_ASSEMBLIES
))
190 AOT_PROFILE_FACADES
:= $(sort $(patsubst .
//%,%,$(filter-out %.dll.dll
%.exe.dll
%bare
% %plaincore
% %secxml
% %Facades
% %ilasm
%,$(filter %.dll
%.exe
,$(wildcard $(topdir
)/class
/lib
/$(PROFILE
)/Facades
/*)))))
191 AOT_PROFILE_FACADES_OUT
:= $(patsubst %,%$(PLATFORM_AOT_SUFFIX
),$(AOT_PROFILE_FACADES
))
194 ifdef ALWAYS_AOT_TESTS
195 AOT_PROFILE_TESTS
:= $(sort $(patsubst .
//%,%,$(filter-out %.dll.dll
%.exe.dll
%bare
% %plaincore
% %secxml
% %Facades
% %ilasm
%,$(filter %.dll
%.exe
,$(wildcard $(topdir
)/class
/lib
/$(PROFILE
)/tests
/*)))))
196 AOT_PROFILE_TESTS_OUT
:= $(patsubst %,%$(PLATFORM_AOT_SUFFIX
),$(AOT_PROFILE_TESTS
))
199 # This can run in parallel
200 .PHONY
: aot-all-profile
201 ifdef AOT_BUILD_FLAGS
202 aot-all-profile
: $(AOT_PROFILE_ASSEMBLIES_OUT
) $(AOT_PROFILE_TESTS_OUT
) $(AOT_PROFILE_FACADES_OUT
)
205 echo AOT_BUILD_FLAGS not set
, skipping AOT.
208 %.dll
$(PLATFORM_AOT_SUFFIX
): %.dll
209 @ mkdir
-p
$<_bitcode_tmp
210 $(Q_AOT
) MONO_PATH
="$(topdir)/class/lib/$(PROFILE)" $(RUNTIME
) $(RUNTIME_FLAGS
) $(AOT_BUILD_FLAGS
),temp-path
=$<_bitcode_tmp
$<
211 @
rm -rf
$<_bitcode_tmp
213 %.exe
$(PLATFORM_AOT_SUFFIX
): %.exe
214 @ mkdir
-p
$<_bitcode_tmp
215 $(Q_AOT
) MONO_PATH
="$(topdir)/class/lib/$(PROFILE)" $(RUNTIME
) $(RUNTIME_FLAGS
) $(AOT_BUILD_FLAGS
),temp-path
=$<_bitcode_tmp
$<
216 @
rm -rf
$<_bitcode_tmp
218 endif #ifneq ("$(wildcard $(topdir)/class/lib/$(PROFILE))","")
220 endif # PLATFORM_AOT_SUFFIX
223 ok
=:; $(MAKE
) run-test-recursive || ok
=false
; $(MAKE
) run-test-local || ok
=false
; $$ok
228 .PHONY
: all-local
$(STD_TARGETS
:=-local
)
229 all-local
$(STD_TARGETS
:=-local
):
233 # The way this is set up, any profile-specific subdirs list should
234 # be listed _before_ including rules.make. However, the default
235 # SUBDIRS list can come after, so don't use the eager := syntax when
236 # using the defaults.
237 PROFILE_SUBDIRS
= $(or
$($(PROFILE
)_SUBDIRS
),$(SUBDIRS
))
239 # These subdirs can be built in parallel
240 PROFILE_PARALLEL_SUBDIRS
= $(or
$($(PROFILE
)_PARALLEL_SUBDIRS
),$(PARALLEL_SUBDIRS
))
242 ifndef FRAMEWORK_VERSION_MAJOR
243 FRAMEWORK_VERSION_MAJOR
= $(basename $(FRAMEWORK_VERSION
))
247 @set .
$$MAKEFLAGS; \
248 case
$$2 in
--unix
) shift
;; esac
; \
249 case
$$2 in
*=*) dk
="exit 1" ;; *k
*) dk
=: ;; *) dk
="exit 1" ;; esac
; \
251 $(foreach subdir
,$(PROFILE_SUBDIRS
),$(MAKE
) -C
$(subdir
) $* ||
{ final_exit
="exit 1"; $$dk; };) \
252 $(if
$(PROFILE_PARALLEL_SUBDIRS
), \
253 $(if
$(filter $*,all), \
254 $(MAKE
) $(PROFILE_PARALLEL_SUBDIRS
) ENABLE_PARALLEL_SUBDIR_BUILD
=1 ||
{ final_exit
="exit 1"; $$dk; };, \
255 $(foreach subdir
,$(PROFILE_PARALLEL_SUBDIRS
),$(MAKE
) -C
$(subdir
) $* ||
{ final_exit
="exit 1"; $$dk; };))) \
256 $(if
$(FACADES_FOLDER
), \
257 $(MAKE
) -C
$(FACADES_FOLDER
) $* ||
{ final_exit
="exit 1"; $$dk; }; \
261 ifdef ENABLE_PARALLEL_SUBDIR_BUILD
262 .PHONY
: $(PROFILE_PARALLEL_SUBDIRS
)
263 $(PROFILE_PARALLEL_SUBDIRS
):
264 @set .
$$MAKEFLAGS; \
269 # Parallel build support
271 # The variable $(PROFILE)_PARALLEL_SUBDIRS should be set to the list of directories
272 # which could be built in parallel. These directories are built after the directories in
273 # $(PROFILE)_SUBDIRS.
274 # Parallel building is currently only supported for the 'all' target.
276 # Each directory's Makefile may define DEP_LIBS and DEP_DIRS to specify the libraries and
277 # directories it depends on.
279 ifneq ($(PROFILE_PARALLEL_SUBDIRS
),)
281 dep_dirs
= .dep_dirs-
$(PROFILE
)
284 # This should track dependencies better but the variable can be defined in any
285 # Makefile dependency. On top of that we should also regenerate when any of the
286 # PROFILE_PARALLEL_SUBDIRS Makefile's are changed
288 $(dep_dirs
): Makefile
289 $(if
$(V
),@echo
"Creating $(abspath $@)...",)
290 list
='$(PROFILE_PARALLEL_SUBDIRS)'; \
292 for d in
$$list; do \
293 $(MAKE
) -C
$$d gen-deps DEPS_TARGET_DIR
=$$d DEPS_FILE
=$(abspath
$@
); \
301 # The gen-deps target is in library.make/executable.make so it can pick up
307 clean-local
: clean-dep-dir
310 DIST_SUBDIRS
= $(SUBDIRS
) $(DIST_ONLY_SUBDIRS
)
312 dist-recursive
: dist-local
313 @case
'$(distdir)' in
[\\/$$]* | ?
:[\\/]* ) reldir
='$(distdir)' ;; *) reldir
='../$(distdir)' ;; esac
; \
314 list
='$(DIST_SUBDIRS)'; for d in
$$list ; do \
315 (cd
$$d && $(MAKE
) distdir
=$$reldir/$$d $@
) || exit
1 ; \
318 # function to dist files in groups of 100 entries to make sure we don't exceed shell char limits
319 define distfilesingroups
320 for f in
$(wordlist
1, 100, $(1)) ; do \
321 dest
=`dirname "$(distdir)/$$f"` ; \
322 $(MKINSTALLDIRS
) $$dest && cp
-p
"$$f" $$dest || exit
1 ; \
324 $(if
$(word 101, $(1)), $(call distfilesingroups
, $(wordlist
101, $(words $(1)), $(1))))
327 # The following target can be used like
329 # dist-local: dist-default
330 # ... additional commands ...
333 # 1. we invert the test here to not end in an error if ChangeLog doesn't exist.
334 # 2. we error out if we try to dist a nonexistant file.
335 # 3. we pick up Makefile
338 test '!' -f ChangeLog || cp ChangeLog
$(distdir
)
339 $(call distfilesingroups
, Makefile
$(DISTFILES
))
340 if
test -d Documentation
; then \
341 find .
-name
'*.xml' > .files
; \
342 tar cTf .files
- |
(cd
$(distdir
); tar xf
-) ; \
347 $(MKINSTALLDIRS
) $(@D
)
350 ## Documentation stuff
352 Q_MDOC
=$(if
$(V
),,@echo
"MDOC [$(PROFILE_DIRECTORY)] $(notdir $(@))";)
353 MDOC
=$(Q_MDOC
) MONO_PATH
="$(topdir)/class/lib/$(PROFILE_DIRECTORY)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME
) $(topdir
)/class
/lib
/$(PROFILE_DIRECTORY
)/mdoc.exe
355 Q_MDOC_UP
=$(if
$(V
),,@echo
"MDOC-UP [$(PROFILE_DIRECTORY)] $(notdir $(@))";)
356 MDOC_UP
=$(Q_MDOC_UP
) MONO_PATH
="$(topdir)/class/lib/$(PROFILE_DIRECTORY)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME
) $(topdir
)/class
/lib
/$(PROFILE_DIRECTORY
)/mdoc.exe update
--delete
-o Documentation
/en