#-----------------------------------------------------------------------------#
# Copyright (C) 1995-2004, 2006-2007, 2010, 2012 The University of Melbourne.
# Copyright (C) 2014, 2019, 2022-2023 The Mercury team.
# This file may only be copied under the terms of the GNU General
# Public Licence - see the file COPYING in the Mercury distribution.
#-----------------------------------------------------------------------------#

# Mmake - Mmake file for Hans Boehm's conservative garbage collector.

# The invoker is expected to set GC_GRADE on the command line
# in cases when this default is not appropriate.
GC_GRADE=gc

MAIN_TARGET=lib$(GC_GRADE)

MERCURY_DIR := $(shell pwd)/..
LINK_BOEHM_GC_ONLY=yes
include $(MERCURY_DIR)/Mmake.common

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

.PHONY: lib$(GC_GRADE)

ifneq ("$(filter nogc,$(GC_GRADE))","")

# No need to build the Boehm garbage collector for grades which don't use it
# (this includes the .NET and Java backends, and for the C backend
# grades with `--gc none' or `--gc accurate').

lib$(GC_GRADE):

else

lib$(GC_GRADE): submake

lib$(GC_GRADE).$A: submake

lib$(GC_GRADE).so: submake

lib$(GC_GRADE).dll: submake

lib$(GC_GRADE).dylib: submake

endif

MMAKEFLAGS=

#	We need to export MAKEFLAGS="" to avoid passing the `-r' (suppress
#	builtin rules) supplied by Mmake to the boehm_gc Makefile, which
#	needs the builtin rules. 
#	We don't use `unset', since the Ultrix /bin/sh doesn't have `unset'.
#
#	We also need to explicitly pass `-j1' after MMAKEFLAGS,
#	to avoid doing a parallel make, for reasons explained at the
#	top of Makefile.

ifeq ("$(USING_MICROSOFT_CL_COMPILER)", "yes")

ifeq ("$(GC_GRADE)", "gc_debug")
  CDEBUG=/Z7 -DGC_DEBUG -DKEEP_BACK_PTRS
else
  CDEBUG=
endif

# NOTE: This used to use gc.mak for par_gc but that file was removed in v8.2.
# Now we use NT_MAKEFILE for both gc and par_gc. Thread support is enabled by
# default in NT_MAKEFILE so unless we pass disable_threads=1, there should be
# no difference between gc.lib and par_gc.lib.
submake: force
	MAKEFLAGS=""; export MAKEFLAGS; \
	nmake -f NT_MAKEFILE cdebug="$(CDEBUG)" nodebug=1 CPU="$(BOEHM_WINDOWS_CPU_TYPE)" ENABLE_STATIC=1 gc.lib; \
	cp gc.lib lib$(GC_GRADE).lib

clean_local:
	rm -rf Release/ Debug/
	rm -f *.obj gc.lib libgc.lib libpar_gc.lib libpar_gc.dll libgc_debug.lib
	cd libatomic_ops && $(MAKE) clean
	rm -f libatomic_ops/Makefile libatomic_ops/tests/Makefile
	rm -f libatomic_ops/src/Makefile
	rm -f libatomic_ops/src/atomic_ops/Makefile
	rm -f libatomic_ops/src/config.h
	rm -f libatomic_ops/src/atomic_ops/sysdeps/Makefile
else 

submake: Makefile force 
	MAKEFLAGS=""; export MAKEFLAGS; \
	PATH=../util:$$PATH $(MAKE) $(MMAKEFLAGS) -j1 \
		GRADE=$(GRADE) GC_GRADE=$(GC_GRADE) \
		AR=$(AR) RANLIB=$(RANLIB) \
		lib$(GC_GRADE).$A lib$(GC_GRADE).$(EXT_FOR_SHARED_LIB) \
		FINAL_INSTALL_MERC_GC_LIB_DIR=$(FINAL_INSTALL_MERC_GC_LIB_DIR) \
		$(EXT_FOR_SHARED_LIB)

clean_local:
	MAKEFLAGS=""; export MAKEFLAGS; \
	$(MAKE) $(BOEHMGC_MAKEFILE) $(MMAKEFLAGS) clean
	-cd libatomic_ops && $(MAKE) $(MMAKEFLAGS) clean
	rm -f libgc.$A libgc.so libgc.dylib libpar_gc.$A libpar_gc.dll
	rm -f libatomic_ops/Makefile libatomic_ops/tests/Makefile
	rm -f libatomic_ops/src/Makefile
	rm -f libatomic_ops/src/atomic_ops/Makefile
	rm -f libatomic_ops/src/config.h
	rm -f libatomic_ops/src/atomic_ops/sysdeps/Makefile
	rm -f Makefile

# Makefile.direct is the makefile supplied with the Boehm tarball.  We have
# to make a copy named Makefile, rather than use make's -f option, because it
# introduces dependencies between the .o files and a file named Makefile.
#
Makefile: Makefile.direct
	cp Makefile.direct Makefile

endif

.PHONY: force
force:

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

# installation rules

.PHONY: install
install: install_headers install_lib install_dll

# As well as installing gc.h (and hence gc_pthread_redirects.h), we also
# install gc_inline.h (and hence gc_tiny_fl.h, gc_priv.h, gc_mark.h,
# gc_hdrs.h, gc_locks.h, and gcconfig.h) for use with `-DINLINE_ALLOC'.
# If we're using DLLs, we also want libgc_dll.h and libgc_globals.h.
#
# IMPORTANT NOTE: the following two lists must include all the header files
# in the boehm_gc system that gc.h includes, directly or indirectly, with
# the settings we use. If such a header file is missing from both these lists,
# then it won't be installed, and Mercury programs compiled in .gc grades will
# all get an error from the C compiler when it can't find the file while
# processing gc.h.

HEADERS= \
	include/gc.h  \
	include/gc_config_macros.h \
	include/gc_pthread_redirects.h \
	include/gc_inline.h \
	include/gc_tiny_fl.h \
	include/gc_mark.h \
	include/gc_version.h \
	$(LIBGC_DLL_H) $(LIBGC_GLOBALS_H)
PRIVATE_HEADERS= \
	include/private/gc_priv.h \
	include/private/gc_hdrs.h \
	include/private/gc_locks.h \
	include/private/gcconfig.h

ifeq ($(USE_DLLS),yes)

LIBGC_DLL_H = libgc_dll.h 
LIBGC_GLOBALS_H = libgc_globals.h 

else

LIBGC_DLL_H =
LIBGC_GLOBALS_H =

endif
#-----------------------------------------------------------------------------#

.PHONY: install_dirs
install_dirs:
	#-[ -d $(INSTALL_INC_DIR) ] || mkdir -p $(INSTALL_INC_DIR)
	-[ -d $(INSTALL_INC_DIR)/private ] || \
		mkdir -p $(INSTALL_INC_DIR)/private
	-[ -d $(INSTALL_MERC_GC_LIB_DIR) ] || \
		mkdir -p $(INSTALL_MERC_GC_LIB_DIR)

ifneq ("$(filter nogc,$(GC_GRADE))","")

# No need to install the Boehm collector for grades which don't use it.

.PHONY: install_headers
install_headers:

.PHONY: install_lib
install_lib:

.PHONY: install_dll
install_dll:

else

.PHONY: install_headers
install_headers: install_dirs
	cp $(HEADERS) $(INSTALL_INC_DIR)
	cp $(PRIVATE_HEADERS) $(INSTALL_INC_DIR)/private


.PHONY: install_lib
install_lib: lib$(GC_GRADE).$A lib$(GC_GRADE).$(EXT_FOR_SHARED_LIB) install_dirs
	cp `vpath_find lib$(GC_GRADE).$A lib$(GC_GRADE).$(EXT_FOR_SHARED_LIB)` \
		$(INSTALL_MERC_GC_LIB_DIR)
	$(RANLIB) $(RANLIBFLAGS) $(INSTALL_MERC_GC_LIB_DIR)/lib$(GC_GRADE).$A

.PHONY: install_dll
install_dll:
	-[ -f libpar_gc.dll ] && cp `vpath_find libpar_gc.dll` $(INSTALL_BINDIR)

endif


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