mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 09:23:44 +00:00
The extra targets that this diff puts into .dep files are not yet used,
though they can be (and have been) tested manually.
compiler/generate_mmakefile_fragments.m:
Generate three new mmake rules to do library installs:
- one to install non-grade-specific files
- one to install grade-specific files, and
- one to
- invoke the ngs target once for the current grade, and
- invoke the gs target for each to-be-installed grade.
The code in this last rule that saves and restores the working files
of the current directory is an adapted version of the lib%.install_grades
target in scripts/Mmake.rules.
Add some code to prepare for storing .int and .int2 files in separate
directories.
scripts/Mmake.rules:
scripts/Mmake.vars.in:
Delete code whose job was to install .s and .pic_s files.
Such files were never meant to be installed; their only purpose
was debugging.
Add a conditional definition to shut up a useless warning by gmake.
scripts/mmake_grade_test:
This new script tests whether a given grade targets C, Java or C#,
and if it targets C, whether it is an MLDS or LLDS grade.
It is intended for use by the new make actions generated
by generate_mmakefile_fragments.m.
scripts/mmake_grade_test_test:
This new script tests the operation of mmake_grade_test.
scripts/Mmakefile:
Install mmake_grade_test (but not mmake_grade_test_test) along with
the other scripts.
scripts/ml.in:
Fix the vim modeline.
scripts/mmake.in:
Fix indentation.
476 lines
15 KiB
Makefile
476 lines
15 KiB
Makefile
#-----------------------------------------------------------------------------#
|
|
# vim: ts=8 sw=8 noexpandtab ft=make
|
|
#-----------------------------------------------------------------------------#
|
|
# Copyright (C) 1995-2010 The University of Melbourne.
|
|
# Copyright (C) 2013, 2015-2016, 2022-2024 The Mercury team.
|
|
# This file may only be copied under the terms of the GNU General
|
|
# Public License - see the file COPYING in the Mercury distribution.
|
|
#-----------------------------------------------------------------------------#
|
|
#
|
|
# Mmake.rules - rules for building Mercury programs
|
|
#
|
|
# N.B. All the builtin rules must use $@ as the target, so that they work
|
|
# when $(VPATH) is set.
|
|
#
|
|
# When passing a module to mmc, strip off the directory part of the name.
|
|
# This way the compiler will report an error if the source file is in another
|
|
# directory, rather than generating interface files in the wrong directory.
|
|
|
|
main_target: $(MAIN_TARGET)
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
|
|
# Note that the order of suffixes is significant.
|
|
.SUFFIXES: .m .err \
|
|
.int0 .int .int2 .int3 .opt .trans_opt \
|
|
.dep .depend .depend_ints .dv .doit .ugly \
|
|
.date0 .date .date3 .optdate .trans_opt_date \
|
|
.c .$O .pic_o \
|
|
.i .s .pic_s \
|
|
.java .class \
|
|
.dll .exe .cpp .cs \
|
|
.c_date .java_date .s_date .pic_s_date
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
#
|
|
# Code to set variables based on the setting of MMAKE_USE_SUBDIRS
|
|
# (i.e. --use-subdirs).
|
|
#
|
|
|
|
ifeq ($(MMAKE_USE_SUBDIRS),yes)
|
|
|
|
MCFLAGS += --use-subdirs
|
|
ALL_MGNUCFLAGS += -I. -I$(mhs_subdir). -I$(mihs_subdir).
|
|
|
|
endif
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
|
|
.PRECIOUS: $(date0s_subdir)%.date0
|
|
.PRECIOUS: $(dates_subdir)%.date
|
|
.PRECIOUS: $(date3s_subdir)%.date3
|
|
.PRECIOUS: $(optdates_subdir)%.optdate
|
|
.PRECIOUS: $(trans_opt_dates_subdir)%.trans_opt_date
|
|
.PRECIOUS: $(c_dates_subdir)%.c_date
|
|
.PRECIOUS: $(java_dates_subdir)%.java_date
|
|
.PRECIOUS: $(s_dates_subdir)%.s_date
|
|
.PRECIOUS: $(pic_s_dates_subdir)%.pic_s_date
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
#
|
|
# Rules for building dependency files.
|
|
#
|
|
|
|
# When creating the dependencies with `--use-subdirs' enabled, we need
|
|
# to create the `Mercury/dates' directories manually in order to
|
|
# get things started. This should not be necessary, but there is a bug
|
|
# in GNU Make with regard to directory caching. I have sent off a bug report
|
|
# to the GNU Make maintainers (19 March 1998). -fjh.
|
|
|
|
ifneq ($(MMAKE_USE_MMC_MAKE),yes)
|
|
|
|
# NOTE The next three blocks specify the rules for the targets
|
|
#
|
|
# %.dep and %.dv
|
|
# %.depend
|
|
# %.depend_ints
|
|
#
|
|
# respectively.
|
|
#
|
|
# The reason why the first two blocks were initially duplicated was that
|
|
# making %.dep (which is a real file) the source for the phony target %.depend,
|
|
# which would have avoided the duplication, does not work, for two separate
|
|
# reasons. The first reason is that with this setup, invoking mmake with
|
|
# the .depend target would result in mmake *deleting* the .dep file after
|
|
# making it, considering it to be an "intermediate" file. The second reason
|
|
# is that "mmake depend" won't rebuild the .dep file if it already exists.
|
|
#
|
|
# The reason why the third block is separate from the first is the same as
|
|
# the reason above. The third block is separate from the second because
|
|
# it wants to invoke the Mercury compiler with different arguments.
|
|
#
|
|
# The bulk of each block is actually code for creating directories.
|
|
# The comments on the original versions of these rules say that
|
|
#
|
|
# - the code for creating the classes_subdir is there because javac
|
|
# does not create the destination directory for .class files, while
|
|
#
|
|
# - the code for creating the *other* directories is there to work around
|
|
# a bug in GNU make.
|
|
#
|
|
# The *last* of these comments is from 2005; others are from earlier.
|
|
# I (zs) don't know to what extent, if any, the issues they complain about
|
|
# still exist.
|
|
#
|
|
# This code for creating directories is duplicated *within* each block
|
|
# as well as *across* the blocks. The two copies within each block
|
|
# differ only by a @. I (zs) don't why that is, but it was done intentionally.
|
|
|
|
MMAKE_USE_SUBDIRS_EXPLICIT ?= no
|
|
|
|
# NEARLY-IDENTICAL BLOCK 1
|
|
$(deps_subdir)%.dep $(deps_subdir)%.dv:
|
|
$(MCD) $(ALL_GRADEFLAGS) $(ALL_MCDFLAGS) $* > $(*F).dep_err 2>&1
|
|
ifeq ($(MMAKE_USE_SUBDIRS),yes)
|
|
ifeq ($(MMAKE_USE_SUBDIRS_EXPLICIT),yes)
|
|
-mkdir -p $(classes_subdir) \
|
|
Mercury/dates Mercury/date0s Mercury/date3s \
|
|
Mercury/optdates Mercury/trans_opt_dates \
|
|
Mercury/c_dates
|
|
else
|
|
@-mkdir -p $(classes_subdir) \
|
|
Mercury/dates Mercury/date0s Mercury/date3s \
|
|
Mercury/optdates Mercury/trans_opt_dates \
|
|
Mercury/c_dates
|
|
endif
|
|
endif
|
|
|
|
# NEARLY-IDENTICAL BLOCK 2
|
|
.PHONY: %.depend
|
|
%.depend:
|
|
$(MCD) $(ALL_GRADEFLAGS) $(ALL_MCDFLAGS) $* > $(*F).dep_err 2>&1
|
|
ifeq ($(MMAKE_USE_SUBDIRS),yes)
|
|
ifeq ($(MMAKE_USE_SUBDIRS_EXPLICIT),yes)
|
|
-mkdir -p $(classes_subdir) \
|
|
Mercury/dates Mercury/date0s Mercury/date3s \
|
|
Mercury/optdates Mercury/trans_opt_dates \
|
|
Mercury/c_dates
|
|
else
|
|
@-mkdir -p $(classes_subdir) \
|
|
Mercury/dates Mercury/date0s Mercury/date3s \
|
|
Mercury/optdates Mercury/trans_opt_dates \
|
|
Mercury/c_dates
|
|
endif
|
|
endif
|
|
|
|
# NEARLY-IDENTICAL BLOCK 3
|
|
.PHONY: %.depend_ints
|
|
%.depend_ints:
|
|
$(MCDI) $(ALL_GRADEFLAGS) $(ALL_MCDIFLAGS) $* > $(*F).dep_err 2>&1
|
|
ifeq ($(MMAKE_USE_SUBDIRS),yes)
|
|
ifeq ($(MMAKE_USE_SUBDIRS_EXPLICIT),yes)
|
|
-mkdir -p $(classes_subdir) \
|
|
Mercury/dates Mercury/date0s Mercury/date3s \
|
|
Mercury/optdates Mercury/trans_opt_dates \
|
|
Mercury/c_dates
|
|
else
|
|
@-mkdir -p $(classes_subdir) \
|
|
Mercury/dates Mercury/date0s Mercury/date3s \
|
|
Mercury/optdates Mercury/trans_opt_dates \
|
|
Mercury/c_dates
|
|
endif
|
|
endif
|
|
|
|
endif # MMAKE_USE_MMC_MAKE != yes
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
#
|
|
# Rules for building interface files.
|
|
# WARNING: any changes here will probably need to be duplicated
|
|
# in compiler/write_deps_file.m.
|
|
#
|
|
|
|
ifneq ($(MMAKE_USE_MMC_MAKE),yes)
|
|
|
|
$(date0s_subdir)%.date0: %.m
|
|
$(MCPI) $(ALL_GRADEFLAGS) $(ALL_MCPIFLAGS) $(*F)
|
|
|
|
$(dates_subdir)%.date: %.m
|
|
$(MCI) $(ALL_GRADEFLAGS) $(ALL_MCIFLAGS) $(*F)
|
|
|
|
$(date3s_subdir)%.date3: %.m
|
|
$(MCSI) $(ALL_GRADEFLAGS) $(ALL_MCSIFLAGS) $(*F)
|
|
|
|
$(optdates_subdir)%.optdate: %.m
|
|
$(MCOI) $(ALL_GRADEFLAGS) $(ALL_MCOIFLAGS) $(*F)
|
|
|
|
$(trans_opt_dates_subdir)%.trans_opt_date: %.m
|
|
$(MCTOI) $(ALL_GRADEFLAGS) $(ALL_MCTOIFLAGS) $(*F)
|
|
|
|
# Be very careful about changing the following rules.
|
|
# The `@:' is a silent do-nothing command.
|
|
# It is used to force GNU Make to recheck the timestamp on the target file.
|
|
# (It is a pity that GNU Make doesn't have a way of handling these sorts
|
|
# of rules in a nicer manner.)
|
|
|
|
$(int0s_subdir)%.int0: $(date0s_subdir)%.date0
|
|
@:
|
|
|
|
$(ints_subdir)%.int: $(dates_subdir)%.date
|
|
@:
|
|
|
|
$(int2s_subdir)%.int2: $(dates_subdir)%.date
|
|
@:
|
|
|
|
$(int3s_subdir)%.int3: $(date3s_subdir)%.date3
|
|
@:
|
|
|
|
$(opts_subdir)%.opt: $(optdates_subdir)%.optdate
|
|
@:
|
|
|
|
$(trans_opts_subdir)%.trans_opt: $(trans_opt_dates_subdir)%.trans_opt_date
|
|
@:
|
|
|
|
endif # MMAKE_USE_MMC_MAKE != yes
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
#
|
|
# Rules for compiling Mercury source files.
|
|
# WARNING: any changes here will probably need to be duplicated
|
|
# in compiler/write_deps_file.m.
|
|
#
|
|
|
|
ifneq ($(MMAKE_USE_MMC_MAKE),yes)
|
|
|
|
# C back-end.
|
|
|
|
# When smart recompilation finds that a module does not need to be recompiled,
|
|
# it only touches the `.c_date' file.
|
|
$(cs_subdir)%.c: $(c_dates_subdir)%.c_date
|
|
@:
|
|
|
|
$(c_dates_subdir)%.c_date: %.m
|
|
$(MCG) $(ALL_GRADEFLAGS) $(ALL_MCGFLAGS) $(*F) $(ERR_REDIRECT)
|
|
|
|
# Java back-end.
|
|
|
|
ifeq ($(MMAKE_USE_SUBDIRS),yes)
|
|
|
|
$(classes_subdir)%.class: $(javas_subdir)%.java
|
|
$(JAVAC) $(ALL_JAVACFLAGS) -d $(classes_subdir) $<
|
|
|
|
else
|
|
|
|
$(classes_subdir)%.class: $(javas_subdir)%.java
|
|
$(JAVAC) $(ALL_JAVACFLAGS) $<
|
|
|
|
endif
|
|
|
|
# When smart recompilation finds that a module does not need to be recompiled,
|
|
# it only touches the `.java_date' file.
|
|
$(javas_subdir)%.java: $(java_dates_subdir)%.java_date
|
|
@:
|
|
|
|
$(java_dates_subdir)%.java_date: %.m
|
|
$(MCG) $(ALL_GRADEFLAGS) $(ALL_MCGFLAGS) \
|
|
--java-only $(*F) $(ERR_REDIRECT)
|
|
|
|
# The `touch' is necessary. If it weren't there, and both the old and the
|
|
# new .err files are zero size, the timestamp would not get updated.
|
|
# The timestamp is updated by the write system call: if the new file
|
|
# is zero size, write is never called. `touch' has code to test specifically
|
|
# for this situation, and adds a byte to the file and then removes it.
|
|
|
|
%.err: %.m
|
|
$(MCE) $(ALL_GRADEFLAGS) $(ALL_MCFLAGS) $(*F) $(ERR_REDIRECT)
|
|
@touch $@
|
|
|
|
endif # MMAKE_USE_MMC_MAKE != yes
|
|
|
|
%.ugly: %.m
|
|
$(MC) --convert-to-mercury $(ALL_GRADEFLAGS) $(ALL_MCFLAGS) $(*F)
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
#
|
|
# Rules for compiling C files in the user's source directory.
|
|
#
|
|
# There is a near-identical of the rule for %.$O in ../Mmake.common.in
|
|
# (search for %.pseudo_o). Any changes to the rule here should be made
|
|
# there as well.
|
|
#
|
|
|
|
%.$O: %.c
|
|
$(MGNUC) $(ALL_GRADEFLAGS) $(ALL_MGNUCFLAGS) -c $< $(OBJFILE_OPT)$@
|
|
|
|
%.pic_o: %.c
|
|
$(MGNUC) $(ALL_GRADEFLAGS) $(ALL_MGNUCFLAGS) $(CFLAGS_FOR_PIC) \
|
|
-c $< $(OBJFILE_OPT)$@
|
|
|
|
%.s: %.c
|
|
$(MGNUC) $(ALL_GRADEFLAGS) $(ALL_MGNUCFLAGS) -S $< -o $@
|
|
|
|
%.pic_s: %.c
|
|
$(MGNUC) $(ALL_GRADEFLAGS) $(ALL_MGNUCFLAGS) $(CFLAGS_FOR_PIC) \
|
|
-S $< -o $@
|
|
|
|
%.i: %.c
|
|
$(MGNUC) $(ALL_GRADEFLAGS) $(ALL_MGNUCFLAGS) -E $< > $@
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
#
|
|
# Rules for compiling C files in a subdirectory.
|
|
# Note that we need both these rules and the ones above,
|
|
# since even if the compiler generates all of its files in subdirectories,
|
|
# the user may have some C files of their own which need to be compiled.
|
|
#
|
|
|
|
ifneq ($(MMAKE_USE_MMC_MAKE),yes)
|
|
|
|
ifneq ("$(cs_subdir)","")
|
|
|
|
$(os_subdir)%.$O: $(cs_subdir)%.c
|
|
$(MGNUC) $(ALL_GRADEFLAGS) $(ALL_MGNUCFLAGS) -c $< $(OBJFILE_OPT)$@
|
|
|
|
$(os_subdir)%.pic_o: $(cs_subdir)%.c
|
|
$(MGNUC) $(ALL_GRADEFLAGS) $(ALL_MGNUCFLAGS) $(CFLAGS_FOR_PIC) \
|
|
-c $< -o $@
|
|
|
|
%.s: $(cs_subdir)%.c
|
|
$(MGNUC) $(ALL_GRADEFLAGS) $(ALL_MGNUCFLAGS) -S $< -o $@
|
|
|
|
%.pic_s: $(cs_subdir)%.c
|
|
$(MGNUC) $(ALL_GRADEFLAGS) $(ALL_MGNUCFLAGS) $(CFLAGS_FOR_PIC) \
|
|
-S $< -o $@
|
|
|
|
%.i: $(cs_subdir)%.c
|
|
$(MGNUC) $(ALL_GRADEFLAGS) $(ALL_MGNUCFLAGS) -E $< > $@
|
|
|
|
endif # $(cs_subdir) != ""
|
|
|
|
endif # $(MMAKE_USE_MMC_MAKE) != yes
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
|
|
ifeq ($(MMAKE_USE_MMC_MAKE),yes)
|
|
|
|
# Always attempt to rebuild these files, even if they exist.
|
|
.PHONY: $(ALL_MC_BUILD_FILES) *.err
|
|
$(ALL_MC_BUILD_FILES):
|
|
$(MCM) $@
|
|
|
|
%.err:
|
|
$(MCM) $@
|
|
|
|
# If we don't know how to make the file, try using `mmc --make'.
|
|
.DEFAULT:
|
|
$(MCM) $@
|
|
|
|
clean_local:
|
|
$(MCM) $(MERCURY_MAIN_MODULES:%=%.clean)
|
|
|
|
realclean_local:
|
|
$(MCM) $(MERCURY_MAIN_MODULES:%=%.realclean)
|
|
|
|
endif # $(MMAKE_USE_MMC_MAKE) == yes
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
#
|
|
# Targets for cleaning up.
|
|
#
|
|
# Note that the actions for most of these targets are in the
|
|
# automatically generated `.d' files.
|
|
#
|
|
|
|
.PHONY: clean realclean clean_prof_files
|
|
|
|
clean_prof_files:
|
|
-rm -f Prof.CallPair Prof.Counts Prof.Decl Prof.MemWords Prof.MemCells
|
|
|
|
# The `clean' and `realclean' targets are implemented via `clean_local'
|
|
# and `realclean_local'. This allows a user to add rules in their
|
|
# Mmakefile to do a recursive mmake clean, for example, while still being
|
|
# able to use the local versions in their original form.
|
|
|
|
.PHONY: clean_local realclean_local
|
|
|
|
realclean: realclean_local
|
|
|
|
clean: clean_local
|
|
|
|
realclean_local: clean_local
|
|
|
|
clean_local: clean_prof_files
|
|
|
|
#-----------------------------------------------------------------------------#
|
|
#
|
|
# Targets for building and installing libraries.
|
|
#
|
|
|
|
# Note: the `lib%.install_ints' rule is generated in each module's `.dep'
|
|
# file so it can be more easily customised based on the desired level of
|
|
# intermodule optimisation. Likewise the `lib%.install_grade_hdrs' is also
|
|
# generated in the `.dep' file, since it depends on the setting of
|
|
# the `--high-level-code' option.
|
|
|
|
.PHONY: lib%.install
|
|
lib%.install: lib%.install_ints lib%.install_hdrs lib%.install_library
|
|
$(MMAKE) lib$*.install_grades
|
|
|
|
.PHONY: lib%.install_grade_init
|
|
lib%.install_grade_init: %.init install_grade_dirs
|
|
$(INSTALL) `vpath_find $*.init` $(INSTALL_GRADE_MODULE_DIR)
|
|
|
|
.PHONY: lib%.install_library
|
|
lib%.install_library: lib%.$A lib%.$(EXT_FOR_SHARED_LIB) \
|
|
install_grade_dirs lib%.install_grade_hdrs \
|
|
lib%.install_opts lib%.install_grade_init
|
|
$(INSTALL) `vpath_find lib$*.$A lib$*.$(EXT_FOR_SHARED_LIB)` \
|
|
$(INSTALL_MERC_LIB_DIR)
|
|
$(RANLIB) $(RANLIBFLAGS) $(INSTALL_MERC_LIB_DIR)/lib$*.$A
|
|
|
|
# XXX grade_files only contains the files for the default grade, not the
|
|
# current grade in each iteration of the loop over ALL_LIBGRADES below.
|
|
lib%.install_grades:
|
|
rm -rf tmp_dir && \
|
|
mkdir tmp_dir && \
|
|
grade_files="$(foreach mve,$(GRADE_SUBDIR_MVEXTS),$($*.$(mve)))" && \
|
|
for file in x $$grade_files; do \
|
|
if test "$$file" != "x"; then \
|
|
mv -f $$file tmp_dir > /dev/null 2>&1; \
|
|
true; \
|
|
fi; \
|
|
done && \
|
|
{ mv -f $(deps_subdir)$*.dep $(deps_subdir)$*.dv \
|
|
*.$A *.$(EXT_FOR_SHARED_LIB) tmp_dir || true; } && \
|
|
for grade in $(ALL_LIBGRADES); do \
|
|
if test "$$grade" != "$(GRADE)"; then \
|
|
$(MMAKE) GRADE=$$grade $*.depend || \
|
|
exit 1; \
|
|
$(MMAKE) GRADE=$$grade lib$*.install_library || \
|
|
exit 1; \
|
|
for file in x $$grade_files; do \
|
|
if test "$$file" != "x"; then \
|
|
rm -f $$file; \
|
|
fi; \
|
|
done; \
|
|
rm -f $(deps_subdir)$*.dep $(deps_subdir)$*.dv \
|
|
*.$A *.$(EXT_FOR_SHARED_LIB); \
|
|
fi; \
|
|
done && \
|
|
for file in x $$grade_files; do \
|
|
if test "$$file" != "x"; then \
|
|
mv -f tmp_dir/`basename $$file` $$file > /dev/null 2>&1; \
|
|
true; \
|
|
fi; \
|
|
done && \
|
|
{ mv -f tmp_dir/*.dep tmp_dir/*.dv $(deps_subdir).; \
|
|
mv -f tmp_dir/* .; rmdir tmp_dir; true; }
|
|
|
|
.PHONY: install_lib_dirs
|
|
install_lib_dirs:
|
|
-test -d $(INSTALL_INT_DIR) || $(INSTALL_MKDIR) $(INSTALL_INT_DIR)
|
|
-test -d $(INSTALL_INC_DIR) || $(INSTALL_MKDIR) $(INSTALL_INC_DIR)
|
|
-test -d $(INSTALL_MODULE_DIR) || \
|
|
$(INSTALL_MKDIR) $(INSTALL_MODULE_DIR)
|
|
# The following is needed to support the `--use-subdirs' option.
|
|
-test -d $(INSTALL_INT_DIR)/Mercury || \
|
|
$(INSTALL_MKDIR) $(INSTALL_INT_DIR)/Mercury
|
|
|
|
.PHONY: install_grade_dirs
|
|
install_grade_dirs: #install_lib_dirs
|
|
-test -d $(INSTALL_MERC_LIB_DIR) || \
|
|
$(INSTALL_MKDIR) $(INSTALL_MERC_LIB_DIR)
|
|
-test -d $(INSTALL_GRADE_INC_DIR) || \
|
|
$(INSTALL_MKDIR) $(INSTALL_GRADE_INC_DIR)
|
|
-test -d $(INSTALL_GRADE_INT_DIR) || \
|
|
$(INSTALL_MKDIR) $(INSTALL_GRADE_INT_DIR)
|
|
-test -d $(INSTALL_GRADE_MODULE_DIR) || \
|
|
$(INSTALL_MKDIR) $(INSTALL_GRADE_MODULE_DIR)
|
|
# The following is needed to support the `--use-subdirs' option.
|
|
# XXX Why? Grade-specific directories should not need *additional*
|
|
# non-grade-specific subdirs.
|
|
-test -d $(INSTALL_GRADE_INC_DIR)/Mercury || \
|
|
$(INSTALL_MKDIR) $(INSTALL_GRADE_INC_DIR)/Mercury
|
|
-test -d $(INSTALL_GRADE_INT_DIR)/Mercury || \
|
|
$(INSTALL_MKDIR) $(INSTALL_GRADE_INT_DIR)/Mercury
|