## a GNU Makefile for building the MELT plugin ## ## Middle End Lisp Translator = MELT ## ## Copyright (C) 2011, 2012 Free Software Foundation, Inc. ## Contributed by Basile Starynkevitch and others ## ## This file contrib/MELT-Plugin-Makefile is part of GCC. ## ## GCC is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3, or (at your option) ## any later version. ## ## GCC is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with GCC; see the file COPYING3. If not see ## . ### Notice that the MELT plugin should be rebuilt even for very minor ### GCC changes, like a patchlevel upgrade, e.g. from GCC 4.6.0 to ### 4.6.1 ## the command to remove files RM ?= rm -vf ## the compiler with which melt.so is used ifndef MELTGCC MELTGCC = $(or $(CC),gcc) endif ## gives yes if MELTGCC has been built with C++ or else the empty string MELTGCC_BUILD_WITH_CXX = $(shell grep -q 'define[[:space:]]\+ENABLE_BUILD_WITH_CXX[[:space:]]\+1' \ `$(MELTGCC) -print-file-name=plugin/include/auto-host.h` && echo yes) ## The compiler and flags used to build the melt.so plugin and to ## compile MELT generated code. Notice that melt-module.mk use the ## same Make variables. For a melt plugin to GCC 4.7 or later, that ## could be a C++ compiler! eg ## make MELTGCC=gcc-4.7 GCCMELT_CC=g++-4.7 ## hence we add a test if $(MELTGCC) was built with C++ or with C ifndef GCCMELT_CC ifeq ($(strip $(MELTGCC_BUILD_WITH_CXX)),) GCCMELT_CC = $(or $(CC),gcc) -Wc++-compat $(info GCCMELT_CC= $(GCCMELT_CC) is a C compiler) else GCCMELT_CC = $(or $(CXX),g++) $(info GCCMELT_CC= $(GCCMELT_CC) is a C++ compiler) endif else $(info GCCMELT_CC= $(GCCMELT_CC) is explicitly given) endif GCCMELT_CFLAGS ?= -g -O -Wall $(info MELT plugin for MELTGCC= $(MELTGCC) to be compiled with GCCMELT_CC= $(GCCMELT_CC) flags $(GCCMELT_CFLAGS) $(if $(MELTGCC_BUILD_WITH_CXX),built with C++ $(MELTGCC_BUILD_WITH_CXX))) # Some versions of `touch' (such as the version on Solaris 2.8) # do not correctly set the timestamp due to buggy versions of `utime' # in the kernel. So, we use `echo' instead. STAMP ?= echo timestamp > # Custom includes to lib needed to built melt.so # ie: -I/path/to/gmp/include LIBS_INCLUDEFLAGS ?= ## the gengtype for that GCC and its flag MELTGCC_GENGTYPE := $(shell $(MELTGCC) -print-file-name=gengtype) MELTGCC_GENGTYPEFLAGS = -v ## its state file MELTGCC_GTYPESTATE := $(shell $(MELTGCC) -print-file-name=gtype.state) ## MELT plugin extra libraries and flags for melt.so; We really need ## the C interface to the Parma Polyhedra Library, even if cc1 don't ## always link it. MELTGCC_LIBES ?= -lppl_c ### Our awk (GNU awk is prefered) AWK?= gawk ### the GNU sed utility SED?= sed ### the GNU tr utility TR?= tr ## the GNU autogen program AUTOGEN?=autogen ## the GNU install utility from coreutils INSTALL?= install ## The GNU texinfo makeinfo command MAKEINFO?= makeinfo ## the GNU texi2pdf utility from makeinfo TEXI2PDF?= texi2pdf ## the GNU texi2html utility from makeinfo TEXI2HTML?= texi2html ## an install driver, which could be sudo or echo, or stay empty INSTALL_DRIVER?= ## the destination directory, where to install, useful e.g., for MELT packagers DESTDIR?= INSTALL_DATA= $(INSTALL_DRIVER) $(INSTALL) -b -p -m 644 INSTALL_PROGRAM= $(INSTALL_DRIVER) $(INSTALL) -b -p -m 755 mkinstalldirs= $(INSTALL_DRIVER) mkdir -p ## ## the existing GCC plugin directory MELTGCC_PLUGIN_DIR:= $(shell $(MELTGCC) -print-file-name=plugin) ### distribution makers might want to override these.... ## the directory where *.info doc files are installed MELTGCC_DOC_INFO_DIR ?= /usr/share/info/gcc/ ## the directory where *.html doc files are installed MELTGCC_DOC_HTML_DIR ?= /usr/share/doc/html/gcc/ ## the directory where *.pdf doc files are installed MELTGCC_DOC_PDF_DIR ?= /usr/share/doc/pdf/gcc/ ## the main source of the runtime MELT_RUNTIME_C= melt-runtime.c ifeq ($(wildcard $(MELTGCC_PLUGIN_DIR)/include/gimple*),) $(error incorrect MELT GCC plugin directory $(MELTGCC_PLUGIN_DIR)) endif ifeq ($(wildcard $(MELTGCC_GTYPESTATE)),) $(error missing MELT GCC gengtype state file) endif ## the version of our GCC getting melt.so, e.g. 4.7.0 MELTGCC_VERSION := $(shell env LANG=C LC_ALL=C $(MELTGCC) -v < /dev/null 2>&1 | $(AWK) '/^gcc version/{print $$3}') ## check that we have a gcc 4.6 or 4.7 ifeq ($(filter 4.6.% 4.7.%, $(MELTGCC_VERSION)),) $(error bad version of MELT GCC $(MELTGCC_VERSION). Needs GCC 4.6 or 4.7) endif ## our included files from melt-runtime.c MELTGCC_RUNTIME_INCLUDES= melt-runtime.h melt/generated/meltrunsup.h ## the optimization flags for melt.so MELTGCC_OPTIMFLAGS= -O2 ## our include flags for melt.so and for MELT generated C code MELTGCC_INCLUDEFLAGS= -I $(MELTGCC_PLUGIN_DIR)/include -I $(MELTGCC_PLUGIN_DIR)/include/c-family $(LIBS_INCLUDEFLAGS) ## the make command started by make.so MELTGCC_MAKE= $(MAKE) .PHONY: all clean doc doc-pdf doc-info doc-html install bootstrap-melt install-melt-includes install-melt-sources install-melt-modules install-melt-mk install-melt-default-modules-list install-melt-so # the GCC compiler into which we plug the MELT metaplugin melt_make_cc1= $(MELTGCC) -c # the make dependencies related to using MELT melt_make_cc1_dependency= melt-runtime.h melt-run.h melt/generated/meltrunsup.h melt/generated/meltrunsup-inc.c melt.so melt_make_gencdeps= $(melt_make_cc1) melt_make_module_makefile= melt-module.mk # the directory containg *.metl files when making. Should be an absolute path melt_make_source_dir=$(realpath melt) melt_make_module_dir= melt_move_if_change= $(SHELL) move-if-change ## Don't use := definitions here! comma= , melt_make_cc1flags= -fplugin=$(realpath melt.so) -I $(realpath .) -o /dev/null melt_cflags= -I $(realpath .) -I $(realpath melt/generated) -DIN_GCC -DMELT_IS_PLUGIN $(MELTGCC_INCLUDEFLAGS) export melt_cflags ## extra cflags are for compiling applicative MELT files, e.g. xtramelt*.c melt_extra_cflags= export melt_extra_cflags melt_installed_cflags= $(MELTGCC_INCLUDEFLAGS) -DIN_GCC -DMELT_IS_PLUGIN -O melt_default_modules_list=melt-default-modules ## this is the installation directory of melt sources (*.melt files ## in MELT dialect and the corresponding *.c files) melt_source_dir=$(MELTGCC_PLUGIN_DIR)/melt-sources ## this is the installation directory of melt dynamic modules (*.so) and module list melt_module_dir=$(MELTGCC_PLUGIN_DIR)/melt-modules ## this is the installed path of the MELT module makefile melt_installed_module_makefile=$(MELTGCC_PLUGIN_DIR)/melt-module.mk ## should be 1 melt_is_plugin=1 # we force the stage0 to be "quicklybuilt" i.e. with constant field offsets. MELT_STAGE_ZERO = melt-stage0-quicklybuilt ## Tell GNU make to not build goals in parallel, that is to ignore any ## -j flag to make. .NOTPARALLEL: all: melt-run.h melt.so bootstrap-melt $(melt_default_modules_list).modlis doc gt-melt-runtime.h: $(MELTGCC_RUNTIME_INCLUDES) $(MELTGCC_GTYPESTATE) \ melt-runtime.c melt/generated/meltrunsup-inc.c $(MELTGCC_GENGTYPE) $(MELTGCC_GENGTYPEFLAGS) \ -r $(MELTGCC_GTYPESTATE) -P $@ $(MELTGCC_RUNTIME_INCLUDES) \ melt-runtime.c melt/generated/meltrunsup-inc.c melt-predef.h: make-melt-predefh.awk melt-predef.list $(AWK) -f $^ > $@-tmp mv $@-tmp $@ .INTERMEDIATE: gfmeltgcc_version_number gfmeltgcc_revision gfmeltgcc_run_md5 melt-run.h melt-run-md5.h: # intermediate file for the version number gfmeltgcc_version_number: echo "$(MELTGCC_VERSION)" | $(AWK) '{split($$1,vertab,"."); printf "%d", vertab[1]*1000+vertab[2]}' > $@ # intermediate file for the revision string gfmeltgcc_revision: GCCMELT-REVISION MELT-Plugin-Makefile $(SED) 's/^ *//' < $< | $(SED) 's/ *$$//'| $(SED) 's/ /_/g' > $@-tmp mv $@-tmp $@ # intermediate file for the md5sum of preprocessed expansion of melt-run.proto.h gfmeltgcc_run_md5: $(MELTGCC_RUNTIME_INCLUDES) MELT-Plugin-Makefile melt-run.proto.h \ $(wildcard $(MELTGCC_PLUGIN_DIR)/include/*.h) melt-runtime.h melt/generated/meltrunsup.h melt-predef.h $(GCCMELT_CC) -C -E -DMELT_IS_PLUGIN -Imelt/generated -I. $(MELTGCC_INCLUDEFLAGS) melt-run.proto.h \ | grep -v '^#' | md5sum | cut -c 1-32 > $@-tmp mv $@-tmp $@ melt-run.h: melt-run.proto.h gfmeltgcc_run_md5 rm -f $@-tmp $(SED) -e 's,#define *MELT_RUN_HASHMD5 *XX,#define MELT_RUN_HASHMD5 \"$(shell cat gfmeltgcc_run_md5)\",' < $< > $@-tmp mv $@-tmp $@ melt-run-md5.h: gfmeltgcc_run_md5 rm -f $@-tmp (date +"/* $@ generated %c */"; \ echo const char melt_run_preprocessed_md5[] \ '=' \"$(shell cat gfmeltgcc_run_md5)\" ';') > $@-tmp mv $@-tmp $@ ## the version number of our GCC getting melt.so, ie 4006 for 4.6 & ## 4007 for 4.7 MELTGCC_VERSION_NUMBER = $(shell cat gfmeltgcc_version_number) melt-runtime-params-inc.c: melt-make-string gfmeltgcc_revision ./melt-make-string \ melt_source_dir '$(melt_source_dir)' \ melt_module_dir '$(melt_module_dir)' \ melt_module_make_command '$(MAKE)' \ melt_module_makefile '$(melt_installed_module_makefile)' \ melt_module_cflags '$(melt_installed_cflags)' \ melt_revision '$(shell head -1 gfmeltgcc_revision)' \ melt_default_modlis '$(melt_default_modules_list)' > $@-tmp mv $@-tmp $@ melt-make-string: melt-make-string.c $(GCCMELT_CC) $^ -o $@ melt.so melt-runtime.args: melt-runtime.c $(MELTGCC_RUNTIME_INCLUDES) \ melt-runtime-params-inc.c \ gt-melt-runtime.h $(wildcard $(MELTGCC_PLUGIN_DIR)/include/*.h) \ melt-predef.h melt-run.h melt-run-md5.h GCCMELT-REVISION \ gfmeltgcc_version_number gfmeltgcc_revision @echo $(MELTGCC_INCLUDEFLAGS) > melt-runtime.args-tmp @echo -I $(realpath melt/generated) >> melt-runtime.args-tmp @echo -I $(realpath .) >> melt-runtime.args-tmp @echo -DMELT_IS_PLUGIN \ -DMELT_GCC_VERSION=$(MELTGCC_VERSION_NUMBER) \ '-DMELT_REVISION=\"$(shell cat gfmeltgcc_revision)\"' \ >> melt-runtime.args-tmp @echo $(MELTGCC_OPTIMFLAGS) >> melt-runtime.args-tmp @echo -Wall melt-runtime.c >> melt-runtime.args-tmp @mv melt-runtime.args-tmp melt-runtime.args $(GCCMELT_CC) $(GCCMELT_CFLAGS) -fPIC -shared @melt-runtime.args \ -o $@ $(MELTGCC_LIBES) melt-build.mk: melt-build.def melt-build.tpl $(AUTOGEN) melt-build.def include melt-build.mk ## melt-clean comes from melt-build.mk clean: melt-clean $(RM) *.o melt.so *~ melt-predef.h gt-melt-runtime.h gfmelt* *tmp stamp-* *.args bootstrap-melt: melt.so warmelt-predef.melt warmelt0 warmelt1 warmelt2 warmelt all-melt warmelt-predef.melt: make-warmelt-predef.awk melt-predef.list $(AWK) -f $^ > $@-tmp mv $@-tmp $@ ################### documentation MELTDOCSRC= meltplugin.texi meltpluginapi.texi MELTDOCPDF= $(patsubst %.texi,%.pdf,$(MELTDOCSRC)) MELTDOCINFO= $(patsubst %.texi,%.info,$(MELTDOCSRC)) MELTDOCHTML= $(patsubst %.texi,%.html,$(MELTDOCSRC)) %.html: %.texi $(TEXI2HTML) $(TEXI2HTML_FLAGS) $< -o $@ %.pdf: %.texi $(TEXI2PDF) $(TEXI2PDF_FLAGS) $< -o $@ doc: meltgendoc.texi meltplugin.texi meltpluginapi.texi doc-pdf doc-info doc-html doc-pdf: $(MELTDOCPDF) doc-info: $(MELTDOCINFO) doc-html: $(MELTDOCHTML) meltplugin.pdf: meltplugin.texi melt.texi meltplugin.html: meltplugin.texi melt.texi meltplugin.info: meltplugin.texi melt.texi meltpluginapi.pdf: meltpluginapi.texi meltgendoc.texi meltpluginapi.html: meltpluginapi.texi meltgendoc.texi meltpluginapi.info: meltpluginapi.texi meltgendoc.texi ################# installation install: all melt.so warmelt \ install-melt-includes install-melt-sources install-melt-modules \ install-melt-mk install-melt-default-modules-list install-melt-so install-melt-includes: melt-runtime.h melt-predef.h melt-run.h melt-run-md5.h melt/generated/meltrunsup.h @echo installing MELT include directory $(MELTGCC_PLUGIN_DIR)/include/ $(mkinstalldirs) $(DESTDIR)$(MELTGCC_PLUGIN_DIR)/include/ for f in $^; do \ $(INSTALL_DATA) $$f $(DESTDIR)$(MELTGCC_PLUGIN_DIR)/include/ ; \ done install-melt-so: melt.so $(INSTALL_PROGRAM) $< $(DESTDIR)$(MELTGCC_PLUGIN_DIR)/melt.so ### notice that melt-sources is a directory, but melt-all-sources is a ### phony makefile target from melt-build.mk install-melt-sources: melt-sources melt-all-sources @echo installing MELT source directory $(melt_source_dir) $(mkinstalldirs) $(DESTDIR)$(melt_source_dir) for f in melt-sources/*.c melt-sources/*.melt ; do \ $(INSTALL_DATA) $$f $(DESTDIR)$(melt_source_dir) ; \ done ### notice that melt-modules is a directory, but melt-all-modules is a ### phony makefile target from melt-build.mk install-melt-modules: melt-modules melt-all-modules @echo installing MELT module directory $(melt_module_dir) $(mkinstalldirs) $(DESTDIR)$(melt_module_dir) for l in $(wildcard melt-modules/*) : ; do \ if [ "$$l" != ":" ]; then \ $(INSTALL_PROGRAM) `readlink $$l` $(DESTDIR)$(melt_module_dir)/$$(basename `readlink $$l`) ; \ fi; \ done ## install the makefile for MELT modules install-melt-mk: melt-module.mk @echo installing MELT plugin dir $(MELTGCC_PLUGIN_DIR) $(mkinstalldirs) $(DESTDIR)$(MELTGCC_PLUGIN_DIR) $(INSTALL_DATA) $< $(DESTDIR)$(melt_installed_module_makefile) ## install the default modules list install-melt-default-modules-list: $(melt_default_modules_list).modlis \ $(melt_default_modules_list)-quicklybuilt.modlis \ $(melt_default_modules_list)-optimized.modlis \ $(melt_default_modules_list)-debugnoline.modlis $(INSTALL_DATA) $^ $(DESTDIR)$(melt_source_dir) ### install the MELT documentation files install-melt-doc: doc doc-info doc-pdf doc-html @echo installing MELT doc info directory $(MELTGCC_DOC_INFO_DIR) $(mkinstalldirs) $(DESTDIR)$(MELTGCC_DOC_INFO_DIR) $(INSTALL_DATA) *.info *.info-*[0-9] $(DESTDIR)$(MELTGCC_DOC_INFO_DIR) @echo installing MELT doc html directory $(MELTGCC_DOC_HTML_DIR) $(mkinstalldirs) $(DESTDIR)$(MELTGCC_DOC_HTML_DIR) $(INSTALL_DATA) *.html $(DESTDIR)$(MELTGCC_DOC_HTML_DIR) @echo installing MELT doc pdf directory $(MELTGCC_DOC_PDF_DIR) $(mkinstalldirs) $(DESTDIR)$(MELTGCC_DOC_PDF_DIR) $(INSTALL_DATA) *.pdf $(DESTDIR)$(MELTGCC_DOC_PDF_DIR)