# ----------------------------------------------
# cm3-src/Makefile
# ----------------------------------------------

SHELL = /bin/sh


# =============================================================
# We build the compiler and associated libraries in two stages,
# and a last stage, where we install the final config files.
# This new source may have dependencies not satisfied by the
# current system packages, and so may not all build.  So we
# build into a temporary staging area, to which we have write
# access.
#  1 - The first stage uses the existing compiler, we build the
#      new compiler and install it into the staging area.  This
#      builds an initial set of libraries, ie, m3core, and libm3.
#  2 - The second stage uses the newly built compiler, shipping
#      all m3-packages into the staging area.
#      All source should build.
#  3 - A final step is to change the configuration file to not
#      use the temporary staging area, but rather reflect the
#      final installation directory.
# =============================================================
STAGE = 1   # default value


# ------------------------------------
# Helper Programs
# ------------------------------------
STRIP 	= strip
SED	= sed


# ------------------------------------
# Where do we place (install?) the built
# software.  Is it staging for packaging
# or an actual installation?
# ------------------------------------

# ----------------------------------------------------------
# MASTER PATHS:
# 
# FINAL_INSTALL_ROOT: If defined, this will indicate where
#              the built software, will be eventually
#              installed.  Any hard coded paths, will use
#              this variable.
#
# INSTALLROOT: If defined, this will indicate where to place
#              the final installation.  This takes precidence
#              over everything.
#              A default is provided.
#
# DESTDIR:     Is only defined when packaging, and is a prefix
#              for the staging area.   The FINAL_INSTALL_ROOT
#              will be appended to DESTDIR to make STAGE_DIR.
#
# SETS
#    FINAL_INSTALL_ROOT,  (used in this makefile)
#    STAGE_DIR,           (used in this makefile)
#    CM3_INSTALL_PREFIX,  (used by compiler for shipping)
#    INSTALLROOT.         (used in this makefile)
#    INSTALL_ROOT.        (used by compiler, for linking, and shipping)
# ----------------------------------------------------------
DESTDIR = $(PWD)/debian/tmp
### INSTALLROOT = $(HOME)/opt-m3
### FINAL_INSTALL_ROOT = /usr/local/cm3

ifndef FINAL_INSTALL_ROOT
ifdef INSTALLROOT
# Okay, you told me to install here, so I will.
FINAL_INSTALL_ROOT := $(INSTALLROOT)
else
ifdef DESTDIR
  # We are packaging for a distribution, install to a system dir.
FINAL_INSTALL_ROOT := /usr/lib/cm3
else
  # Just a regular installation, without being told where to install.
  # Use a standard default
FINAL_INSTALL_ROOT := /usr/local/cm3
endif
endif
endif

ifdef DESTDIR
# DESTDIR = $(PWD)/debian/tmp
   # We are staging this (ie, preparing for packaging).
   # Interpret DESTDIR as the root of the system tree
   # for final installation.  DESTDIR is something like
   #   somepath/debian/tmp, or
   #   somepath/rpm/tmp
export STAGE_DIR :=$(DESTDIR)$(FINAL_INSTALL_ROOT)
  # CM3_INSTALL_PREFIX is only defined for staging a distribution package.
# export CM3_INSTALL_PREFIX :=$(DESTDIR)
else
  # this is a real installation, but we haven't been told 
  # where to install everything, so use builtin paths
export STAGE_DIR := $(FINAL_INSTALL_ROOT)
endif

export STAGE1_INSTALL_ROOT := $(DESTDIR)$(FINAL_INSTALL_ROOT)
export STAGE2_INSTALL_ROOT := $(DESTDIR)$(FINAL_INSTALL_ROOT)
#export STAGE1_INSTALL_ROOT := $(CM3_INSTALL_PREFIX)$(FINAL_INSTALL_ROOT)
#export STAGE2_INSTALL_ROOT := $(CM3_INSTALL_PREFIX)$(FINAL_INSTALL_ROOT)
# export STAGE2_INSTALLROOT := $(FINAL_INSTALL_ROOT)


# ------------------------------------
# Varibles for build scripts
# ------------------------------------
export ROOT 		= $(PWD)
export root		= $(ROOT)
#export CM3_DEBUG	= true
# export CM3_INSTALL	= $(STAGE_DIR)
ifeq (STAGE,1)
export CM3_INSTALL	= $(STAGE1_INSTALL_ROOT)
export INSTALL_ROOT	= $(STAGE1_INSTALL_ROOT)
export INSTALLROOT	= $(STAGE1_INSTALL_ROOT)
else
export CM3_INSTALL	= $(STAGE2_INSTALL_ROOT)
export INSTALL_ROOT	= $(STAGE2_INSTALL_ROOT)
export INSTALLROOT	= $(STAGE2_INSTALL_ROOT)
endif

#ifndef INSTALLROOT
#INSTALLROOT := $(FINAL_INSTALL_ROOT)
#endif

# ------------------------------------
# Staging/Installation directories
# ------------------------------------
stage_bin_dir		= $(STAGE_DIR)/bin
stage_etc_dir		= $(STAGE_DIR)/etc
stage_lib_dir		= $(STAGE_DIR)/lib
stage_man_dir		= $(STAGE_DIR)/man
stage_pkg_dir		= $(STAGE_DIR)/pkg


# -------------------------------------------------
# Where is the system Modula-3 compiler.
# -------------------------------------------------
#TRY1_CM3		= $(shell which cm3)
TRY2_CM3		= /usr/lib/cm3/bin/cm3
TRY3_CM3		= /usr/local/cm3/bin/cm3
#ifneq (,$(TRY1_CM3))
#export SYSTEM_CM3	= $(TRY1_CM3)
#else
ifneq ($(shell test -e $(TRY2_CM3)),0)
$(info "SYSTEM_CM3: TRY2")
export SYSTEM_CM3	= $(TRY2_CM3)
else
ifeq ( $(shell test -e $(TRY3_CM3)), 0)
$(info "SYSTEM_CM3: TRY3")
export SYSTEM_CM3	= $(TRY3_CM3)
else
$(error "ERROR: Failed to find cm3 in path or other standard locations.")
endif
endif
#endif

export LOCAL_CM3	= $(stage_bin_dir)/cm3

# -----------------------------------------------
# Use system compiler for stage 1, 
# the new one we just built in stage 2.
# -----------------------------------------------
ifneq (STAGE,1)
    export CM3 := $(SYSTEM_CM3)
else
    export CM3 := $(LOCAL_CM3)
endif
CM3_PATH	=  $(shell dirname $(CM3))
CM3_ROOT	=  $(shell dirname $(CM3_PATH))
export PATH	:= $(CM3_PATH):$(PATH)

# -----------------------------------------------
# Define the TARGET for generating machine code,
# and the name of a config file.
# -----------------------------------------------
export HOST_TARGET=$(shell $(CM3) -version | grep target | cut -d : -f 2 | cut -c 2- )
ifndef TARGET
   export TARGET=$(HOST_TARGET)
endif


# ---------------------------------------------------
# Special suite: in specific build order.
# ---------------------------------------------------
build_compiler_pkgs = m3core \
			libm3 \
			sysutils \
			patternmatching \
			m3bundle \
			m3middle \
			m3objfile \
			m3linker \
			m3back \
			m3front \
			m3quake \
			cm3 \
			m3cc

compiler_pkgs	= m3middle \
		m3scanner \
		m3objfile \
		m3linker \
		m3back \
		m3front \
		m3quake \
		cm3 \
		m3cc


extra_1_pkgs	= m3tools
extra_2_pkgs	= m3gdb pp webcat mtex m3totex
# extra_3_pkgs	= pgodbc
extra_pkgs	= $(extra_1_pkgs) $(extra_2_pkgs) $(extra_2_pkgs)


define InstallSuite
	@echo "********************************************************"
	@echo "* Installing package suite: $(SUITE)."
	@echo "* CM3 = $(CM3)"
	@echo "* INSTALL_ROOT: ${INSTALL_ROOT}"
	@echo "* pkgs: $($(SUITE)_pkgs)"
	@echo "********************************************************"
	@for pkg in $($(SUITE)_pkgs) ; do \
	   echo "searching: $${pkg}" ; \
	   dirs=`find ./m3-* -type d -name $${pkg}` ; \
	   for dir in $${dirs} ; do \
	      if [ -f $${dir}/src/m3makefile ] ; then \
	         echo "Installing pkg: $${pkg}" ; \
	         mkdir -p $(INSTALL_ROOT)/pkg ; \
	         cp -r $${dir}/src $(INSTALL_ROOT)/pkg ; \
	         cp -r $${dir}/$(TARGET) $(INSTALL_ROOT)/pkg ; \
	      fi ; \
	   done ; \
	done
endef

define PurgeSuite
	@echo "********************************************************"
	@echo "* Purging package suite: $(SUITE)."
	@echo "* CM3 = $(CM3)"
	@echo "* pkgs: $($(SUITE)_pkgs)"
	@echo "********************************************************"
	@# CM3=$(CM3) . scripts/do-pkg.sh ; realclean $($(SUITE)_pkg)
	@for pkg in $($(SUITE)_pkgs) ; do \
	   echo "searching: $${pkg}" ; \
	   dirs=`find ./m3-* -type d -name $${pkg}` ; \
	   for dir in $${dirs} ; do \
	      if [ -f $${dir}/src/m3makefile ] ; then \
	         if [ -d $${dir}/$(TARGET) ] ; then \
	            echo "purging $${dir}/$(TARGET)" ; \
	            $(RM) -r $${dir}/$(TARGET) ; \
	         fi ; \
	      fi ; \
	   done ; \
	done
	@echo
	@echo
endef


$(info "DEBUG: STAGE: $(STAGE)")
$(info "DEBUG: DESTDIR: $(DESTDIR)")
$(info "DEBUG: INSTALL_ROOT: $(INSTALL_ROOT)")
$(info "DEBUG: INSTALLROOT: $(INSTALLROOT)")
$(info "DEBUG: FINAL_INSTALL_ROOT: $(FINAL_INSTALL_ROOT)")
$(info "DEBUG: STAGE_DIR: $(STAGE_DIR)")

$(info "DEBUG: CM3: $(CM3)")
$(info "DEBUG: SYSTEM_CM3: $(SYSTEM_CM3)")
$(info "DEBUG: CM3_PATH: $(CM3_PATH)")
$(info "DEBUG: CM3_INSTALL_PREFIX: \"$(CM3_INSTALL_PREFIX)\"")


# **************************************
# <<<<<<<<    MAIN TARGETS    >>>>>>>>>>
# **************************************


# all: all-stages build-extra-packages ship-extra-packages

all: stage1 stage2 stage3


clean: clean-script clean-extra clean-scripts-dir
distclean: realclean

realclean: purge-all purge-extra
	$(RM) *.log

debian-pkgs:
	fakeroot make -f debian/rules binary

doc: install-doc-files

dist:

# install: debug-env
# install: extra-pkgs tree-std
# install: tree-std
# install: all ship-extra-packages

install: stage1 stage2 stage3
# install: ship-stage1 ship-stage2
uninstall:

special: m3tools

# ----------------------------------------------------------------

stage1: 
	@echo "*********************"
	@echo "*** START STAGE 1 ***"
	@echo "*********************"
	$(MAKE) CM3=$(SYSTEM_CM3) STAGE=1 build-stage1
	$(MAKE) CM3=$(SYSTEM_CM3) STAGE=1 ship-stage1

stage2: 
	@echo "*********************"
	@echo "*** START STAGE 2 ***"
	@echo "*********************"
	$(MAKE) CM3=$(LOCAL_CM3) STAGE=2 build-stage2
	$(MAKE) CM3=$(LOCAL_CM3) STAGE=2 ship-stage2
	$(MAKE) CM3=$(LOCAL_CM3) STAGE=2 stage2-extra

stage3: 
	@echo "*****************************"
	@echo "*** START STAGE 3 (final) ***"
	@echo "*****************************"
	$(MAKE) STAGE=3 final-config


.PHONY: build-stage1 build-stage2
build-stage1: 
	@echo "********************************************************"
	@echo "* Building Stage 1"
	@echo "* CM3: $(CM3)"
	@echo "********************************************************"
	$(MAKE) stage1-compiler stage1-extra

ship-stage1: 
	@echo "********************************************************"
	@echo "* Shiping Stage 1"
	@echo "* CM3: $(CM3)"
	@echo "* CM3_INSTALL_PREFIX: $(CM3_INSTALL_PREFIX)"
	@echo "********************************************************"
	$(MAKE) install-compiler stage1-config

build-stage2:
	@echo "********************************************************"
	@echo "* Building Stage 2"
	@echo "* CM3: $(CM3)"
	@echo "********************************************************"
	$(MAKE) stage2-compiler build-script build-extra

.PHONY: ship-stage
ship-stage2: build-stage2
	@echo "********************************************************"
	@echo "* Shiping Stage 2"
	@echo "* CM3: $(CM3)"
	@echo "* CM3_INSTALL_PREFIX: $(CM3_INSTALL_PREFIX)"
	@echo "********************************************************"
	./scripts/do-cm3-all.sh buildship


build: compiler build-script build-extra
ship: install-compiler install-cm3 ship-script ship-extra install-doc-files

# ----------------------------------------------------------------

stage1-extra:
	SUITE=compiler $(MAKE) stage1-extra-1

stage1-extra-1:
	$(InstallSuite)

stage2-extra: stage2-install-extra
# m3tools

stage2-install-extra:
	@echo "************************************************"
	@echo "* stage2-install-extra:"
	@echo "*     install m3cgcat to $(stage_bin_dir) *"
	@echo "*     install m3cggen to $(stage_bin_dir) *"
	@echo "*     install formsview to $(stage_bin_dir) *"
	@echo "*     install vorun to $(stage_bin_dir) *"
	@echo "************************************************"
	cp $(ROOT)/m3-sys/m3cgcat/$(TARGET)/m3cgcat $(stage_bin_dir)/
	cp $(ROOT)/m3-sys/m3cggen/$(TARGET)/m3cggen $(stage_bin_dir)/
	cp $(ROOT)/m3-ui/formsview/$(TARGET)/formsview $(stage_bin_dir)/
	cp $(ROOT)/m3-obliq/vorun/$(TARGET)/vorun $(stage_bin_dir)/



# ----------------------------------------------------------------



# ---------------------------------------------------------------
# Helper targets (not invoked by user)
# ---------------------------------------------------------------

build-script:
	./scripts/do-cm3-all.sh build

ship-script:
	./scripts/do-cm3-all.sh buildship
	
clean-script:
	./scripts/do-cm3-all.sh clean

clean-scripts-dir:
	$(RM) ./scripts/PKGS

purge-all:
	./scripts/do-cm3-all.sh realclean
	
purge-extra:
	./scripts/do-pkg.sh  realclean $(extra_pkgs)
	./scripts/do-pkg.sh  realclean $(build_compiler_pkgs)



# ---------------------------------
# Compiler building
# ---------------------------------

# compiler: clean-cminstall build-compiler install-compiler install-config-file

stage1-compiler: build-compiler
stage2-compiler: build-compiler install-compiler stage2-config install-cm3


build-compiler:
	@echo "********************************************************"
	@echo "* Building packages for CM3 compiler"
	@echo "* STAGE = $(STAGE)"
	@echo "* CM3 = $(CM3)"
	@echo "* $(build_compiler_pkgs)"
	@echo "********************************************************"
	CM3=$(CM3) scripts/do-pkg.sh buildlocal $(build_compiler_pkgs)

install-compiler:
	@echo "********************************************************"
	@echo "* Installing CM3 compiler into installation directory"
	@echo "* STAGE = $(STAGE)"
	@echo "* CM3 = $(CM3)"
	@echo "* INSTALLROOT: \"${INSTALLROOT}\""
	@echo "********************************************************"
	mkdir -p $(stage_bin_dir)
	cp $(ROOT)/m3-sys/cm3/$(TARGET)/cm3 $(stage_bin_dir)
	-$(STRIP) $(stage_bin_dir)/cm3
	cp $(ROOT)/m3-sys/m3cc/$(TARGET)/cm3cg $(stage_bin_dir)
	-$(STRIP) $(stage_bin_dir)/cm3cg

install-cm3:
	@echo "********************************************************"
	@echo "* Installing CM3 package (man pages, ..., etc)"
	@echo "* STAGE = $(STAGE)"
	@echo "* CM3 = $(CM3)"
	@echo "* INSTALLROOT: ${INSTALLROOT}"
	@echo "********************************************************"
	CM3=$(CM3) scripts/do-pkg.sh buildglobal $(build_compiler_pkgs)
	

stage1-config \
stage2-config:
	@echo "********************************************************"
	@echo "* Installing Stage $(STAGE) CM3 configuration files."
	@echo "* TARGET: $(TARGET)"
	@echo "* INSTALLROOT: $(STAGE1_INSTALLROOT)"
	@echo "* etc: $(etc_dir)"
	@echo "********************************************************"
	mkdir -p $(stage_bin_dir)
	mkdir -p $(stage_etc_dir)
	echo >$(stage_bin_dir)/cm3.cfg "INSTALLROOT=\"$(STAGE1_INSTALLROOT)\""
	echo >>$(stage_bin_dir)/cm3.cfg "include(\"../etc/$(TARGET)\")"
	@for file in $(ROOT)/m3-sys/cminstall/src/config-no-install/$(TARGET) \
		$(ROOT)/m3-sys/cminstall/src/config-no-install/*.common ; do \
	   base=`basename $${file}` ; \
	   echo "Installing $${base}" ; \
	   cp $${file} $(stage_etc_dir) ; \
	done

final-config:
	@echo "********************************************************"
	@echo "* Installing Final CM3 configuration files."
	@echo "* TARGET: $(TARGET)"
	@echo "* INSTALLROOT: $(INSTALLROOT)"
	@echo "* FINAL_INSTALL_ROOT: $(FINAL_INSTALL_ROOT)"
	@echo "* etc: $(etc_dir)"
	@echo "********************************************************"
	mkdir -p $(stage_bin_dir)
	mkdir -p $(stage_etc_dir)
	# NOTE: cm3.cfg should goto $(stage_etc_dir)
	# FIXME: compiler should search ../etc
	echo >$(stage_bin_dir)/cm3.cfg "INSTALLROOT=\"$(FINAL_INSTALL_ROOT)\""
	echo >>$(stage_bin_dir)/cm3.cfg "include(\"../etc/$(TARGET)\")"
	cp $(ROOT)/m3-sys/cminstall/src/config-no-install/$(TARGET) $(stage_etc_dir) ;
	@for file in $(ROOT)/m3-sys/cminstall/src/config-no-install/*.common ; do \
	   base=`basename $${file}` ; \
	   echo "Installing $${base}" ; \
	   cp $${file} $(stage_etc_dir) ; \
	done

install-doc-files:
	@echo "********************************************************"
	@echo "* Installing manual pages for CM3 compiler"
	@echo "* INSTALLROOT: ${INSTALLROOT}"
	@echo "********************************************************"
	mkdir -p $(stage_man_dir)/man1
	cp m3-sys/cm3/$(TARGET)/cm3.1 $(stage_man_dir)/man1
	cp m3-sys/m3gdb/$(TARGET)/m3gdb.1 $(stage_man_dir)/man1


# ---------------------------------

m3tools:
	@echo "********************************************************"
	@echo "* Building/ship the Modula-3 Tools (m3tools)"
	@echo "* CM3 = $(CM3)"
	@echo "********************************************************"
	cd m3-sys/m3tools ; $(CM3) -O -build
	cd m3-sys/m3tools ; $(CM3) -ship
	cd m3-sys/m3tools/$(TARGET) ; cp libm3tools.a $(stage_lib_dir)


build-debugger:
	@echo "********************************************************"
	@echo "* Building the Modula-3 Debugger"
	@echo "* CM3 = $(CM3)"
	@echo "********************************************************"
	cd m3-sys/m3gdb ; $(CM3) -build

ship-debugger:
	@echo "********************************************************"
	@echo "* Shipping the Modula-3 Debugger"
	@echo "* CM3 = $(CM3)"
	@echo "********************************************************"
	cd m3-sys/m3gdb ; $(CM3) -ship




ship-mtex:
	@echo "********************************************************"
	@echo "* Shipping the mtex from doctools"
	@echo "********************************************************"
	$(RM) -fr $(stage_pkg_dir)/mtex
	cp -r m3-tools/mtex $(stage_pkg_dir)

build-stablegen:
	@echo "********************************************************"
	@echo "* Building the package stablegen"
	@echo "********************************************************"
	cd m3-db/stablegen ; $(CM3) -build

ship-stablegen:
	@echo "********************************************************"
	@echo "* Shipping the package stablegen"
	@echo "********************************************************"
	$(RM) -fr $(stage_pkg_dir)/stablegen
	cp -r m3-tools/stablegen/$(TARGET) $(stage_pkg_dir)/stablegen

special-m3config:
	@echo "********************************************************"
	@echo "* Making a special version of the M3Config.i3"
	@echo "********************************************************"
	cd m3-libs/libm3/src/config; cm3 -build

build-extra:
	@echo "********************************************************"
	@echo "* Building extra packages"
	@echo "* CM3 = $(CM3)"
	@echo "********************************************************"
	CM3=$(CM3) . scripts/do-pkg.sh buildlocal $(extra_pkgs)

ship-extra:
	@echo "********************************************************"
	@echo "* Buildi/Ship extra packages"
	@echo "* CM3 = $(CM3)"
	@echo "********************************************************"
	CM3=$(CM3) . scripts/do-pkg.sh buildglobal $(extra_pkgs)




# ---------------------------------

new-debug-env:
	$(MAKE) CM3=$(LOCAL_CM3) debug-env


debug-env:
	@echo "PATH: $(PATH)"
	@echo "CM3: $(CM3)"
	@echo "CM3_INSTALL: $(CM3_INSTALL)"
	@echo "CM3_INSTALL_PREFIX: $(CM3_INSTALL_PREFIX)"
	@echo "SYSTEM_CM3: $(SYSTEM_CM3)"
	@echo "LOCAL_CM3: $(LOCAL_CM3)"
	@echo "HOST_TARGET: \"${HOST_TARGET}\""
	@echo "TARGET: \"${TARGET}\""
	@echo "ROOT: ${ROOT}"
	@echo "INSTALLROOT: ${INSTALLROOT}"
	@echo "INSTALL_ROOT: ${INSTALL_ROOT}"
	@echo "DESTDIR: ${DESTDIR}"
	@echo "FINAL_INSTALL_ROOT: ${FINAL_INSTALL_ROOT}"
	@echo "STAGE_DIR: ${STAGE_DIR}"
	@echo "TMPDIR: ${TMPDIR}"
	@echo "TRY1_CM3: ${TRY1_CM3}"
	@echo "stage_bin_dir: ${stage_bin_dir}"
	@echo "stage_etc_dir: ${stage_etc_dir}"
	@echo "stage_lib_dir: ${stage_lib_dir}"
	@echo "stage_pkg_dir: ${stage_pkg_dir}"
	@echo "stage_man_dir: ${stage_man_dir}"
	$(CM3) -version

