2 # GLOBAL Makefile for the whole L4 tree
8 install-dirs = tool pkg
9 clean-dirs = tool pkg doc
10 cleanall-dirs = tool pkg doc
12 BUILD_TOOLS = gawk gcc g++ ld perl pkg-config
14 CMDS_WITHOUT_OBJDIR := checkbuild up update check_build_tools
16 # our default target is all::
23 DROPSCONF_DEFCONFIG ?= $(L4DIR)/mk/defconfig/config.x86
24 #DROPSCONF_CONFIG_IN = $(L4DIR)/mk/config.in
25 DROPSCONF_CONFIG = $(OBJ_BASE)/.kconfig.auto
26 DROPSCONF_CONFIG_H = $(OBJ_BASE)/include/l4/bid_config.h
27 DROPSCONF_CONFIG_MK = $(OBJ_BASE)/.config.all
28 DROPSCONF_DONTINC_MK = y
29 DROPSCONF_HELPFILE = $(L4DIR)/mk/config.help
31 # separation in "dependent" (ie opts the build output depends on) and
32 # "independent" (ie opts the build output does not depend on) opts
33 CONFIG_MK_INDEPOPTS = CONFIG_BID_GENERATE_MAPFILE \
34 CONFIG_DEPEND_VERBOSE \
35 CONFIG_VERBOSE_SWITCH \
36 CONFIG_BID_COLORED_PHASES CONFIG_HAVE_LDSO \
37 CONFIG_INT_CPP_NAME_SWITCH BID_LIBGENDEP_PATHS CONFIG_INT_CPP_.*_NAME \
38 CONFIG_INT_CXX_.*_NAME CONFIG_VERBOSE CONFIG_BID_STRIP_PROGS \
39 CONFIG_INT_LD_NAME_SWITCH CONFIG_INT_LD_.*_NAME
40 CONFIG_MK_REAL = $(OBJ_BASE)/.config
41 CONFIG_MK_INDEP = $(OBJ_BASE)/.config.indep
44 ifneq ($(filter $(CMDS_WITHOUT_OBJDIR),$(MAKECMDGOALS)),)
45 IGNORE_MAKECONF_INCLUDE=1
48 ifneq ($(B)$(BUILDDIR_TO_CREATE),)
49 IGNORE_MAKECONF_INCLUDE=1
52 ifeq ($(IGNORE_MAKECONF_INCLUDE),)
53 ifneq ($(filter help config txtconfig oldconfig,$(MAKECMDGOALS)),)
54 # tweek $(L4DIR)/mk/Makeconf to use the intermediate file
55 export BID_IGN_ROOT_CONF=y
56 BID_ROOT_CONF=$(DROPSCONF_CONFIG_MK)
59 # $(L4DIR)/mk/Makeconf shouln't include Makeconf.local twice
60 MAKECONFLOCAL = /dev/null
61 include $(L4DIR)/mk/Makeconf
64 # after having absfilename, we can export BID_ROOT_CONF
65 ifneq ($(filter config txtconfig oldconfig gconfig qconfig xconfig, $(MAKECMDGOALS)),)
66 export BID_ROOT_CONF=$(call absfilename,$(OBJ_BASE))/.config.all
73 ifneq ($(strip $(B)),)
74 BUILDDIR_TO_CREATE := $(B)
76 ifneq ($(strip $(BUILDDIR_TO_CREATE)),)
77 all:: check_build_tools
78 @echo "Creating build directory \"$(BUILDDIR_TO_CREATE)\"..."
79 @if [ -e "$(BUILDDIR_TO_CREATE)" ]; then \
80 echo "Already exists, aborting."; \
83 @mkdir -p "$(BUILDDIR_TO_CREATE)"
84 @cp $(DROPSCONF_DEFCONFIG) $(BUILDDIR_TO_CREATE)/.kconfig
85 @$(MAKE) B= BUILDDIR_TO_CREATE= O=$(BUILDDIR_TO_CREATE) oldconfig
95 # some more dependencies
96 tool: $(DROPSCONF_CONFIG_MK)
97 pkg: $(DROPSCONF_CONFIG_MK) tool
100 ifneq ($(CONFIG_BID_BUILD_DOC),)
107 $(VERBOSE)svn up mk tool/gendep tool/kconfig tool/elf-patcher doc/source conf $(wildcard tool/bin)
108 $(VERBOSE)$(MAKE) -C pkg up
110 tool ../kernel/fiasco pkg: ../dice
111 $(VERBOSE)if [ -r $@/Makefile ]; then PWD=$(PWD)/$@ $(MAKE) -C $@; fi
114 $(VERBOSE)if [ -r $@/Makefile.drops ]; then \
115 $(MAKE) -C $@ -f Makefile.drops; \
119 $(VERBOSE)for d in tool doc ; do \
120 test ! -r $$d/Makefile || PWD=$(PWD)/$$d $(MAKE) -C $$d $@ ; done
123 $(VERBOSE)test ! -r pkg/Makefile || PWD=$(PWD)/pkg $(MAKE) -C pkg doc
126 $(VERBOSE)$(MAKE) -C pkg cont
128 .PHONY: all clean cleanall install hello pkgdoc up update
129 .PHONY: $(BUILD_DIRS) doc/html check_build_tools cont cleanfast
134 clean cleanall install::
135 $(VERBOSE)set -e; for i in $($@-dirs) ; do \
136 if [ -r $$i/Makefile -o -r $$i/GNUmakefile ] ; then \
137 PWD=$(PWD)/$$i $(MAKE) -C $$i $@ ; fi ; done
140 $(VERBOSE)$(RM) -r $(OBJ_BASE)/{bin,include,pkg,doc,ext-pkg,pc,lib,l4defs.mk.inc,l4defs.sh.inc,images}
143 L4DEF_FILE_MK ?= $(OBJ_BASE)/l4defs.mk.inc
144 L4DEF_FILE_SH ?= $(OBJ_BASE)/l4defs.sh.inc
146 l4defs: $(L4DEF_FILE_MK) $(L4DEF_FILE_SH)
148 generate_l4defs_files = \
149 $(VERBOSE)tmpdir=$(OBJ_BASE)/l4defs.gen.dir && \
150 mkdir -p $$tmpdir && \
151 echo "L4DIR = $(L4DIR_ABS)" > $$tmpdir/Makefile && \
152 echo "OBJ_BASE = $(OBJ_BASE)" >> $$tmpdir/Makefile && \
153 echo "L4_BUILDDIR = $(OBJ_BASE)" >> $$tmpdir/Makefile && \
154 echo "SRC_DIR = $$tmpdir" >> $$tmpdir/Makefile && \
155 echo "PKGDIR_ABS = $(L4DIR_ABS)/l4defs.gen.dir" >> $$tmpdir/Makefile && \
156 cat $(L4DIR)/mk/export_defs.inc >> $$tmpdir/Makefile && \
157 PWD=$$tmpdir $(MAKE) -C $$tmpdir -f $$tmpdir/Makefile \
158 CALLED_FOR=$(1) L4DEF_FILE_MK=$(L4DEF_FILE_MK) L4DEF_FILE_SH=$(L4DEF_FILE_SH) && \
161 $(L4DEF_FILE_MK): $(BUILD_DIRS) $(DROPSCONF_CONFIG_MK) $(L4DIR)/mk/export_defs.inc
162 $(call generate_l4defs_files,prog)
163 $(call generate_l4defs_files,lib)
165 $(L4DEF_FILE_SH): $(L4DEF_FILE_MK)
168 $(call generate_l4defs_files,prog)
169 $(call generate_l4defs_files,lib)
171 .PHONY: l4defs regen_l4defs
173 #####################
174 # config-rules follow
176 HOST_SYSTEM := $(shell uname | tr 'A-Z' 'a-z')
179 # it becomes a bit confusing now: 'make config' results in a config file, which
180 # must be postprocessed. This is done in config.inc. Then,
181 # we evaluate some variables that depend on the postprocessed config file.
182 # The variables are defined in mk/Makeconf, which sources Makeconf.bid.local.
183 # Hence, we have to 1) postprocess, 2) call make again to get the variables.
184 DROPSCONF_CONFIG_MK_POST_HOOK:: check_build_tools $(OBJ_DIR)/Makefile
185 # libgendep must be done before calling make with the local helper
186 $(VERBOSE)$(MAKE) libgendep
187 $(VERBOSE)$(MAKE) Makeconf.bid.local-helper || \
188 (rm -f $(DROPSCONF_CONFIG_MK) $(CONFIG_MK_REAL) $(CONFIG_MK_INDEP); false)
189 $(VEROBSE)$(LN) -snf $(L4DIR_ABS) $(OBJ_BASE)/source
190 $(VERBOSE)$(MAKE) checkconf
193 $(VERBOSE)if [ ! -e $(GCCDIR)/include/stddef.h ]; then \
195 $(ECHO) "$(GCCDIR) seems wrong (stddef.h not found)."; \
196 $(ECHO) "Does it exist?"; \
201 # caching of some variables. Others are determined directly.
202 # The contents of the variables to cache is already defined in mk/Makeconf.
203 .PHONY: Makeconf.bid.local-helper Makeconf.bid.local-internal-names \
206 Makeconf.bid.local-helper:
207 $(VERBOSE)echo BUILD_SYSTEMS="$(strip $(ARCH)_$(CPU) \
208 $(ARCH)_$(CPU)-$(BUILD_ABI))" >> $(DROPSCONF_CONFIG_MK)
209 $(VERBOSE)$(foreach v, GCCLIBDIR GCCDIR GCCLIB GCCLIB_EH GCCVERSION \
210 GCCMAJORVERSION GCCMINORVERSION GCCSUBVERSION \
211 GCCNOSTACKPROTOPT LDVERSION GCCSYSLIBDIRS, \
212 echo $(v)=$(call $(v)_f,$(ARCH)) \
213 >>$(DROPSCONF_CONFIG_MK);)
214 $(VERBOSE)$(foreach v, LD_GENDEP_PREFIX, echo $v=$($(v)) >>$(DROPSCONF_CONFIG_MK);)
215 $(VERBOSE)echo "HOST_SYSTEM=$(HOST_SYSTEM)" >>$(DROPSCONF_CONFIG_MK)
216 $(VERBOSE)echo "COLOR_TERMINAL=$(shell if [ $$(tput colors || echo -1) = '-1' ]; then echo n; else echo y; fi)" >>$(DROPSCONF_CONFIG_MK)
217 $(VERBOSE)echo "LD_HAS_HASH_STYLE_OPTION=$(shell if $(LD) --help 2>&1 | grep -q ' --hash-style='; then echo y; else echo n; fi)" >>$(DROPSCONF_CONFIG_MK)
218 $(VERBOSE)# we need to call make again, because HOST_SYSTEM (set above) must be
219 $(VERBOSE)# evaluated for LD_PRELOAD to be set, which we need in the following
220 $(VERBOSE)$(MAKE) Makeconf.bid.local-internal-names
221 $(VERBOSE)sort <$(DROPSCONF_CONFIG_MK) >$(CONFIG_MK_REAL).tmp
222 $(VERBOSE)echo -e "# Automatically generated. Don't edit\n" >$(CONFIG_MK_INDEP)
223 $(VERBOSE)grep $(addprefix -e ^,$(CONFIG_MK_INDEPOPTS) ) \
224 <$(CONFIG_MK_REAL).tmp >>$(CONFIG_MK_INDEP)
225 $(VERBOSE)echo -e "# Automatically generated. Don't edit\n" >$(CONFIG_MK_REAL).tmp2
226 $(VERBOSE)grep -v $(addprefix -e ^,$$ # $(CONFIG_MK_INDEPOPTS) ) \
227 <$(CONFIG_MK_REAL).tmp >>$(CONFIG_MK_REAL).tmp2
228 $(VERBOSE)echo -e 'include $(call absfilename,$(CONFIG_MK_INDEP))' >>$(CONFIG_MK_REAL).tmp2
229 $(VERBOSE)if [ -e "$(CONFIG_MK_REAL)" ]; then \
230 diff --brief $(CONFIG_MK_REAL) $(CONFIG_MK_REAL).tmp2 || \
231 mv $(CONFIG_MK_REAL).tmp2 $(CONFIG_MK_REAL); \
233 mv $(CONFIG_MK_REAL).tmp2 $(CONFIG_MK_REAL); \
235 $(VERBOSE)$(RM) $(CONFIG_MK_REAL).tmp $(CONFIG_MK_REAL).tmp2
237 Makeconf.bid.local-internal-names:
238 ifneq ($(CONFIG_INT_CPP_NAME_SWITCH),)
239 $(VERBOSE) set -e; X="tmp.$$$$$$RANDOM.c" ; echo 'int main(void){}'>$$X ; \
240 rm -f $$X.out ; $(LD_GENDEP_PREFIX) GENDEP_SOURCE=$$X \
241 GENDEP_OUTPUT=$$X.out $(CC) -c $$X -o $$X.o; \
242 test -e $$X.out; echo INT_CPP_NAME=`cat $$X.out` \
243 >>$(DROPSCONF_CONFIG_MK); \
244 rm -f $$X $$X.{o,out};
245 $(VERBOSE)set -e; X="tmp.$$$$$$RANDOM.cc" ; echo 'int main(void){}'>$$X; \
246 rm -f $$X.out; $(LD_GENDEP_PREFIX) GENDEP_SOURCE=$$X \
247 GENDEP_OUTPUT=$$X.out $(CXX) -c $$X -o $$X.o; \
248 test -e $$X.out; echo INT_CXX_NAME=`cat $$X.out` \
249 >>$(DROPSCONF_CONFIG_MK); \
250 rm -f $$X $$X.{o,out};
252 ifneq ($(CONFIG_INT_LD_NAME_SWITCH),)
253 $(VERBOSE) set -e; echo INT_LD_NAME=$$($(LD) 2>&1 | perl -p -e 's,^(.+/)?(.+):.+,$$2,') >> $(DROPSCONF_CONFIG_MK)
255 $(VERBOSE)emulations=$$(LANG= $(LD) --help | \
256 grep -i "supported emulations:" | \
257 sed -e 's/.*supported emulations: //') ; \
259 for e in $$emulations; do \
260 for c in $(LD_EMULATION_CHOICE_$(ARCH)); do \
261 if [ "$$e" = "$$c" ]; then \
262 echo LD_EMULATION=$$e >> $(DROPSCONF_CONFIG_MK); \
268 if [ "$$found_it" != "1" ]; then \
269 echo "No known ld emulation found"; exit 1; \
273 $(VERBOSE)if [ ! -r tool/gendep/Makefile ]; then \
274 echo "=== l4/tool/gendep missing! ==="; \
277 $(VERBOSE)PWD=$(PWD)/tool/gendep $(MAKE) -C tool/gendep
281 for i in $(BUILD_TOOLS); do \
282 if ! command -v $$i >/dev/null 2>&1; then \
283 [ -n "$$mis" ] && mis="$$mis "; \
287 if [ -n "$$mis" ]; then \
288 echo -e "\033[1;31mProgram(s) \"$$mis\" not found, please install!\033[0m"; \
291 echo "All checked ok."; \
294 define entryselection
296 ml=$(L4DIR_ABS)/conf/modules.list; \
297 [ -n "$(MODULES_LIST)" ] && ml=$(MODULES_LIST); \
298 [ -n "$(ENTRY)" ] && e="$(ENTRY)"; \
299 [ -n "$(E)" ] && e="$(E)"; \
300 if [ -z "$$e" ]; then \
301 BACKTITLE="No entry given. Use 'make $@ E=entryname' to avoid menu." \
302 L4DIR=$(L4DIR) $(L4DIR)/tool/bin/entry-selector $$ml 2> $(OBJ_BASE)/.entry-selector.tmp; \
303 if [ $$? != 0 ]; then \
304 cat $(OBJ_BASE)/.entry-selector.tmp; \
307 e=$$(cat $(OBJ_BASE)/.entry-selector.tmp); \
311 BUILDDIR_SEARCHPATH = $(OBJ_BASE)/bin/$(ARCH)_$(CPU):$(OBJ_BASE)/bin/$(ARCH)_$(CPU)/$(BUILD_ABI):$(OBJ_BASE)/lib/$(ARCH)_$(CPU):$(OBJ_BASE)/lib/$(ARCH)_$(CPU)/$(BUILD_ABI)
313 -include $(L4DIR)/conf/Makeconf.boot
314 -include $(OBJ_BASE)/conf/Makeconf.boot
317 $(VERBOSE)$(entryselection); \
318 PWD=$(PWD)/pkg/bootstrap/server/src \
319 $(MAKE) -C pkg/bootstrap/server/src ENTRY="$$e" \
320 BOOTSTRAP_MODULES_LIST=$$ml \
321 BOOTSTRAP_MODULE_PATH_BINLIB="$(BUILDDIR_SEARCHPATH)" \
322 BOOTSTRAP_SEARCH_PATH="$(MODULE_SEARCH_PATH)"
325 $(VERBOSE)if [ "$(ARCH)" != "x86" -a "$(ARCH)" != "amd64" ]; then \
326 echo "This mode can only be used with architectures x86 and amd64."; \
329 $(VERBOSE)$(entryselection); \
331 if [ -z "$$qemu" ]; then \
332 [ "$(ARCH)" = "amd64" ] && qemu=qemu-system-x86_64; \
333 [ "$(ARCH)" = "x86" ] && qemu=qemu; \
335 QEMU=$$qemu L4DIR=$(L4DIR) \
336 SEARCHPATH="$(MODULE_SEARCH_PATH):$(BUILDDIR_SEARCHPATH)" \
337 $(L4DIR)/tool/bin/qemu-x86-launch $$ml "$$e" $(QEMU_OPTIONS)
340 $(VERBOSE)$(entryselection); \
342 SEARCHPATH="$(MODULE_SEARCH_PATH):$(BUILDDIR_SEARCHPATH)" \
343 $(L4DIR)/tool/bin/kexec-launch $$ml "$$e"
346 $(VERBOSE)if [ "$(ARCH)" != "x86" ]; then \
347 echo "This mode can only be used with architecture x86."; \
350 $(VERBOSE)$(entryselection); \
352 $(if $(UX_GFX),UX_GFX=$(UX_GFX)) \
353 $(if $(UX_GFX_CMD),UX_GFX_CMD=$(UX_GFX_CMD)) \
354 $(if $(UX_NET),UX_NET=$(UX_NET)) \
355 $(if $(UX_NET_CMD),UX_NET_CMD=$(UX_NET_CMD)) \
356 SEARCHPATH="$(MODULE_SEARCH_PATH):$(BUILDDIR_SEARCHPATH)" \
357 $(L4DIR)/tool/bin/ux-launch $$ml "$$e" $(UX_OPTIONS)
360 $(VERBOSE)if [ "$(ARCH)" != "x86" -a "$(ARCH)" != "amd64" ]; then \
361 echo "This mode can only be used with architectures x86 and amd64."; \
364 $(VERBOSE)$(entryselection); \
365 $(MKDIR) $(OBJ_BASE)/images; \
367 SEARCHPATH="$(MODULE_SEARCH_PATH):$(BUILDDIR_SEARCHPATH)" \
368 $(L4DIR)/tool/bin/gengrub1iso --timeout=0 $$ml \
369 $(OBJ_BASE)/images/$$(echo $$e | tr '[ ]' '[_]').iso "$$e"
372 $(VERBOSE)if [ "$(ARCH)" != "x86" -a "$(ARCH)" != "amd64" ]; then \
373 echo "This mode can only be used with architectures x86 and amd64."; \
376 $(VERBOSE)$(entryselection); \
377 $(MKDIR) $(OBJ_BASE)/images; \
379 SEARCHPATH="$(MODULE_SEARCH_PATH):$(BUILDDIR_SEARCHPATH)" \
380 $(L4DIR)/tool/bin/gengrub2iso --timeout=0 $$ml \
381 $(OBJ_BASE)/images/$$(echo $$e | tr '[ ]' '[_]').iso "$$e"
383 .PHONY: image qemu ux switch_ram_base grub1iso grub2iso
386 @echo " ... Regenerating RAM_BASE settings"
387 $(VERBOSE)echo "# File semi-automatically generated by 'make switch_ram_base'" > $(OBJ_BASE)/Makeconf.ram_base
388 $(VERBOSE)echo "RAM_BASE := $(RAM_BASE)" >> $(OBJ_BASE)/Makeconf.ram_base
389 PWD=$(PWD)/pkg/sigma0/server/src $(MAKE) -C pkg/sigma0/server/src
390 PWD=$(PWD)/pkg/moe/server/src $(MAKE) -C pkg/moe/server/src
393 @if [ -z "$(CHECK_BASE_DIR)" ]; then \
394 echo "Need to set CHECK_BASE_DIR variable"; \
397 set -e; for i in $(if $(USE_CONFIGS),$(addprefix mk/defconfig/config.,$(USE_CONFIGS)),mk/defconfig/config.*); do \
398 p=$(CHECK_BASE_DIR)/$$(basename $$i); \
401 cp $$i $$p/.kconfig; \
402 $(MAKE) O=$$p oldconfig; \
403 $(MAKE) O=$$p tool; \
404 $(MAKE) O=$$p USE_CCACHE=$(USE_CCACHE) $(CHECK_MAKE_ARGS); \
408 @echo -e $(EMPHSTART)"============================================================="$(EMPHSTOP)
409 @echo -e $(EMPHSTART)" Note, this report might disclose private information"$(EMPHSTOP)
410 @echo -e $(EMPHSTART)" Please review (and edit) before sending it to public lists"$(EMPHSTOP)
411 @echo -e $(EMPHSTART)"============================================================="$(EMPHSTOP)
416 @echo "CC: $(CC) -v:"
419 @echo "CXX: $(CXX) -v:"
422 @echo "HOST_CC: $(HOST_CC) -v:"
423 @$(HOST_CC) -v || true
425 @echo "HOST_CXX: $(HOST_CXX) -v:"
426 @$(HOST_CXX) -v || true
428 @echo -n "ld: $(LD) -v: "
434 @echo -n "python -V: "
437 @echo "svn --version: "
438 @svn --version || true
441 @ls -la /bin/sh || true
443 @echo "uname -a: "; uname -a
446 @if [ -e "/etc/debian_version" ]; then \
447 if grep -qi ubuntu /etc/issue; then \
448 echo -n "Ubuntu: "; \
451 echo -n "Debian: "; \
453 cat /etc/debian_version; \
454 elif [ -e /etc/gentoo-release ]; then \
455 echo -n "Gentoo: "; \
456 cat /etc/gentoo-release; \
457 elif [ -e /etc/SuSE-release ]; then \
459 cat /etc/SuSE-release; \
460 elif [ -e /etc/fedora-release ]; then \
461 echo -n "Fedora: "; \
462 cat /etc/fedora-release; \
463 elif [ -e /etc/redhat-release ]; then \
464 echo -n "Redhat: "; \
465 cat /etc/redhat-release; \
466 [ -e /etc/redhat_version ] \
467 && echo " Version: `cat /etc/redhat_version`"; \
468 elif [ -e /etc/slackware-release ]; then \
469 echo -n "Slackware: "; \
470 cat /etc/slackware-release; \
471 [ -e /etc/slackware-version ] \
472 && echo " Version: `cat /etc/slackware-version`"; \
473 elif [ -e /etc/mandrake-release ]; then \
474 echo -n "Mandrake: "; \
475 cat /etc/mandrake-release; \
477 echo "Unknown distribution"; \
479 @lsb_release -a || true
481 @echo "Running as PID"
484 @echo "Archive information:"
489 @echo "HOST_CC = $(HOST_CC)"
490 @echo "HOST_CXX = $(HOST_CXX)"
493 @echo "Current: $$(pwd)"
494 @echo "L4DIR: $(L4DIR)"
495 @echo "L4DIR_ABS: $(L4DIR_ABS)"
496 @echo "OBJ_BASE: $(OBJ_BASE)"
497 @echo "OBJ_DIR: $(OBJ_DIR)"
500 ../kernel/fiasco/src/kern/ia32 \
501 ../tools/preprocess/src/preprocess; do \
502 if [ -e $$i ]; then \
503 echo Path $$i found ; \
505 echo PATH $$i IS NOT AVAILABLE; \
510 @for i in $(OBJ_DIR)/.config.all $(OBJ_DIR)/.kconfig \
511 $(OBJ_DIR)/Makeconf.local \
512 $(L4DIR_ABS)/Makeconf.local \
513 $(OBJ_DIR)/conf/Makeconf.boot \
514 $(L4DIR_ABS)/conf/Makeconf.boot; do \
515 if [ -e "$$i" ]; then \
516 echo "______start_______________________________:";\
519 echo "____________________________end___________"; \
521 echo "$$i not found"; \
524 @echo -e $(EMPHSTART)"============================================================="$(EMPHSTOP)
525 @echo -e $(EMPHSTART)" Note, this report might disclose private information"$(EMPHSTOP)
526 @echo -e $(EMPHSTART)" Please review (and edit) before sending it to public lists"$(EMPHSTOP)
527 @echo -e $(EMPHSTART)"============================================================="$(EMPHSTOP)