#------------------------------------------------------------------------------
# Makefile for GNAT for adabrowse
#
# This makefile assumes that the ASIS libraries are in
# ADA_INCLUDE_PATH and ADA_OBJECTS_PATH. If this is not
# the case, uncomment and edit the alternate definitions
# of GCC_OPTIONS and LD_OPTIONS below, and comment the now
# uncommented ones.
#
# 05-APR-2002  TW  Initial version
# 02-MAY-2002  TW  Added 'nasty', changed the targets so they are macro refs.
# 08-MAY-2002  TW  Changed the makefile so that it uses 'get_gcc' to figure
#                  out the name of the gcc used by GNAT.
# 08-JUN-2003  TW  Added the automatic configuration stuff (with or without
#                  the project manager support).
# 20-NOV-2003  TW  Correction for splitting path lists: Unix has ':' as the
#                  path separator, whereas Windows uses ';'!
# 22-FEB-2005  TW  Make sure to use ./get_gcc instead of plain get_gcc so that
#                  the makefile also works if a user doesn't have the current
#                  directory in the PATH.
#------------------------------------------------------------------------------

# It is assumed that the pathes to your ASIS installation are in your
# ADA_INCLUDE_PATH and ADA_OBJECTS_PATH!

# This makefile has become pretty complicated, mainly because of things
# which we figure out when the makefile is run:
#
# 1. We determine the compiler name used by gnatmake by default, and
#    generate a package spec AD.Setup containing this name.
#
#    This is so because on some Linux installations, the compiler to
#    use for GNAT is not called "gcc" but "gnatgcc", and I want AdaBrowse
#    to default to this name.
#
#    To get the compiler's name and to create AD.Setup, we build a small
#    utility program called get_gcc.
#
# 2. We figure out whether the GNAT sources are available. This is indicated
#    by variable GNATSRC being set to the directory where the GNAT sources
#    are. If this variable is set, and the directory actually contains the
#    GNAT sources, then we try to configure AdaBrowse such that it uses the
#    GNAT project manager.
#
#    This is so because I don't want to distribute parts of the GNAT sources
#    with AdaBrowse. The reason is that the project manager and some files
#    it depends on differ between different GNAT versions, and furthermore
#    I think ACT wouldn't like my distributing extracts from the 3.15p and
#    3.16a sources. Also, I'd have to add more and more extracts as new
#    compiler versions appeared.
#
#    So the way chosen here is actually simpler: the GNAT sources, which
#    contain the project manager, are available from ACT, and users who
#    want project manager support in AdaBrowse can get them and then just
#    tell this makefile where they are. It isn't even necessary to try to
#    build GNAT. The only requiremnet is that the sources are consistent
#    with the GNAT and ASIS version used.
#
#    To configure AdaBrowse, we build a utility program in subdirectory
#    ./config and run it. The program then tries to build (using gnatmake)
#    a dummy application using the project manager. If that succeeds, it
#    configures AdaBrowse by generating two files ad-projects-impl.ads
#    and ad-projects-impl-get_parent.adb. if building the dummy application
#    failes, these files are set up such that AdaBrowse doesn't use the
#    GNAT project manager.
#
# Only after these two configuration steps building of AdaBrowse proper
# begins.
#
# And finally, this makefile is being complicated by the fact that the
# it has to work with the ancient GNU make 3.77 (distributed with GNAT 3.15p).

GCC_OPTIONS = -O2
LD_OPTIONS  = -lasis

host := $(shell gcc -dumpmachine)

RM        := rm -f
CP        := cp
ADABROWSE := adabrowse
NASTY     := nasty
GET_GCC   := get_gcc
EXE       :=
CONFIGURE := adconf
PATH_SEP  := :

ifeq "$(findstring mingw32, $(host))" "mingw32"
   # Assume we're on Windows
   RM        := cmd.exe /c del
   CP        := cmd.exe /c copy
   ADABROWSE := adabrowse.exe
   NASTY     := nasty.exe
   GET_GCC   := get_gcc.exe
   CONFIGURE := adconf.exe
   EXE       := .exe
   PATH_SEP  := ;
endif

# GNAT-specific gcc options: enable all warnings, and style checking.
# The style checking flags are nearly as plain "-gnaty", but do not
# check comment format, and do not require explicit specs for all
# subprograms. I chose this setting because these two things do not
# correspond at all to *my* style.

GNAT_OPTIONS := -gnatwa -gnaty3abefhiklmprt

GET_GCC_GEN  = get_gcc.o get_gcc.ali
GET_GCC_FULL = $(GET_GCC_GEN) get_gcc.txt get_gcc.use

ifdef GNATSRC

INTERNAL_GNAT_SRC  := $(subst \,/,$(subst \\,/,$(GNATSRC)))
INTERNAL_GNAT_SRC2 := $(INTERNAL_GNAT_SRC)

# Check that this GNAT source directory is correct:
ifeq "$(strip $(wildcard $(INTERNAL_GNAT_SRC)/prj-env.ads))" ""

INTERNAL_GNAT_SRC := $(INTERNAL_GNAT_SRC2)/ada

ifeq "$(strip $(wildcard $(INTERNAL_GNAT_SRC)/prj-env.ads))" ""

INTERNAL_GNAT_SRC := $(INTERNAL_GNAT_SRC2)/src/ada

ifeq "$(strip $(wildcard $(INTERNAL_GNAT_SRC)/prj-env.ads))" ""

$(error GNAT sources not found)
#
# Unfortunately, the error function doesn't work with GNU make 3.77,
# which is being distributed with GNAT 3.15p. (The GNAT 3.16a distribution
# contains the current GNU make 3.79.1.)
#
# Hence we deliberately use a non-existing dependency to make make stop
# with a halfway sensible message.

adabrowse : Cannot_Find_GNAT_Sources

endif

endif

endif

endif

# Figure out where the ASIS installation is.

Include_Dirs := $(subst \,/, $(subst $(PATH_SEP), ,$(ADA_INCLUDE_PATH)))
A4G_DIR := $(foreach dir,$(Include_Dirs),$(wildcard $(dir)/a4g.ali))

ifeq "$(strip $(A4G_DIR))" ""

# ADA_INCLUDE_PATH had better contain the asis directory.
$(error ADA_INCLUDE_PATH must contain the ASIS installation!)

adabrowse : ASIS_Not_On_ADA_INCLUDE_PATH

endif

ASIS_DIR := $(strip $(dir $(word 1, $(A4G_DIR))))

ifeq "$(ASIS_DIR)" ""

# Something went wrong.
$(error Cannot figure out the ASIS installation directory!)

adabrowse : ASIS_Not_Found

endif

ifdef ADABROWSE_GNATSRC

# Set the pathes so that we can compile files from the GNAT source
# distribution without problems. If we don't do that, we will not be
# able to link, because the GNAT compiler sources also contain
# the library sources. We must therefore make sure that the installed
# library always comes first!

# But don't do this only the variable comes from the command line, and if
# ADABROWSE_GCC_LIB also is defined!

ifneq "$(findstring command,$(origin ADABROWSE_GNATSRC))" ""

ifdef ADABROWSE_GCC_LIB

export ADA_INCLUDE_PATH:=$(ASIS_DIR)$(PATH_SEP)$(ADABROWSE_GCC_LIB)$(PATH_SEP)$(ADABROWSE_GNATSRC)$(PATH_SEP)$(ADA_INCLUDE_PATH)
export ADA_OBJECTS_PATH:=$(ASIS_DIR)$(PATH_SEP)$(subst adainclude,adalib,$(ADABROWSE_GCC_LIB))$(PATH_SEP)$(ADA_OBJECTS_PATH)

endif

endif

# The GNAT sources may of course use internal GNAT units, so we don't
# want that warning. Also, we get spurious warnings on elaboration issues,
# all in GNAT sources. Suppress this warning, too.

GNAT_OPTIONS += -gnatwIL

endif

# MAIN TARGET: (first in this makefile)

all: ./config/$(CONFIGURE) run-conf
	$(MAKE) $(ADABROWSE) \
	ADABROWSE_GCC_LIB=$(dir $(subst \,/,$(shell $(shell ./get_gcc -gcc get_gcc.use) -print-libgcc-file-name)))adainclude \
	ADABROWSE_GNATSRC=$(INTERNAL_GNAT_SRC)

# Configuration stuff. We build an executable adconf, which then figures out
# from its parameters and by trying to compile a certain file whether or not
# we do have project manager support.

./config/$(CONFIGURE): get_gcc.use ./config/adconf.adb
	cd ./config; gnatmake -q -I.. adconf

# If adconf is called with two argument only (i.e., GNATSRC is not set), it
# configures AdaBrowse not to use the project manager.
#
# If adconf is called with four arguments, it configures AdaBrowse such that
# it *does* use the project manager, and then tries to compile the file
# ad-projects-impl_yes.adb. If that fails, it retries again after having
# made one single change to account for a difference between GNAT 3.15p and
# 3.16a. If compilation still fails, it reverts to the configuration not
# using the project manager.

run-conf:
	cd ./config; \
	./$(CONFIGURE) $(shell ./get_gcc -gcc get_gcc.use) \
	               $(ASIS_DIR) \
	               $(INTERNAL_GNAT_SRC) \
	               $(dir $(subst \,/,$(shell $(shell ./get_gcc -gcc get_gcc.use) -print-libgcc-file-name)))adainclude
	-cd ./config; $(CP) ad-projects-impl.ads ..
	-cd ./config; $(CP) ad-projects-impl_yes-get_parent.adb ..

# All this 'get_gcc' stuff here is GNAT specific: we try to dynamically
# figure out the name of the gcc used by GNAT. On some systems, it
# appears that this name is "gnatgcc", not "gcc"!

get_gcc.o :
	gnatmake -q -c -f get_gcc.adb

get_gcc.ali:
	gnatmake -q -c -f get_gcc.adb

$(GET_GCC): get_gcc.o get_gcc.ali get_gcc.adb
	gnatmake -q get_gcc

# Note: the dependency below first ensures that all the files we're
# going to delete in the rm command actually exist. This is a work-
# around for Win 2k, where make stops because cmd.exe /c del returns
# a failure exit code because some files may not exist. However, they
# must not exist when we run gnatmake, or we won't have the desired
# output in get_gcc.err. (The trick is that the first line in that
# file will be the compile command gnatmake uses for get_gcc.adb,
# which will start with the compiler name.)

get_gcc.use: $(GET_GCC)
	$(RM) $(GET_GCC) $(GET_GCC_GEN)
	gnatmake get_gcc 2>get_gcc.use

# Ok, finally we can build adabrowse! The first dependency handles the
# C file in the distribution. All the others may be regenerated.

ifneq "$(EXE)" ""

# On Windows, add a target "adabrowse"

adabrowse: $(ADABROWSE)
	-$(warning AdaBrowse built without reconfiguration)

endif

$(ADABROWSE): util-nl.o \
              ad-setup.ads \
              ad-projects-impl.ads ad-projects-impl_yes-get_parent.adb
	gnatmake $(GCC_OPTIONS) adabrowse -cargs $(GNAT_OPTIONS) \
	                                  -largs $(LD_OPTIONS)
	strip $(ADABROWSE)

$(NASTY): nasty.adb
	gnatmake nasty -cargs $(GCC_OPTIONS)

ad-setup.ads: get_gcc.use
	$(shell ./get_gcc -setup get_gcc.use)

util-nl.o: get_gcc.use util-nl.c
	$(shell ./get_gcc -gcc get_gcc.use) -c $(GCC_OPTIONS) util-nl.c

clean:
	$(RM) $(ADABROWSE) $(NASTY) $(GET_GCC) *.o *.ali

