# Makefile for libgnatvsn.
#   Copyright (c) 2006 Ludovic Brenta <ludovic@ludovic-brenta.org>
#   Copyright (c) 2017 Nicolas Boulenguez <nicolas@debian.org>
#
# This file 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

# Parameters substituted by configure during Makefile generation
prefix                                 := @prefix@
srcdir                                 := @srcdir@
libdir                                 := @libdir@
pkgversion                             := @pkgversion@
bugurl                                 := @bugurl@

# Parameters expected in environment or command line
$(foreach v, \
  ADA_CFLAGS ADAFLAGS CC CFLAGS CPPFLAGS DESTDIR INSTALL INSTALL_DATA LDFLAGS \
 ,$(info $(v) ($(origin $(v))) = $($(v))))
# It seems that both CFLAGS/ADA_CFLAGS should affect both Ada/C.

# Parameters read from external files
BASEVER   := $(shell cat $(srcdir)/../gcc/BASE-VER)
DEVPHASE  := $(shell cat $(srcdir)/../gcc/DEV-PHASE)
DATESTAMP := $(shell cat $(srcdir)/../gcc/DATESTAMP)

# Public and default targets
.PHONY: all install clean
all:

######################################################################

LIB_VERSION := $(shell expr '$(BASEVER)' : '\([0-9]\+\)')

src_inst_dir := $(prefix)/share/ada/adainclude/gnatvsn
gpr_inst_dir := $(prefix)/share/gpr
ali_inst_dir := $(libdir)/ada/adalib/gnatvsn
lib_inst_dir := $(libdir)

# Initial value of variables accumulationg build flags.
adaflags := -gnatn
cflags   :=
cppflags :=
ldflags  := -Wl,--as-needed -Wl,-z,defs
ldlibs   :=

# For use in version.c - double quoted strings, with appropriate
# surrounding punctuation and spaces, and with the datestamp and
# development phase collapsed to the empty string in release mode
# (i.e. if DEVPHASE_c is empty).  The space immediately after the
# comma in the $(if ...) constructs is significant - do not remove it.
cppflags += \
  -DBASEVER="\"$(BASEVER)\"" \
  -DDATESTAMP="\"$(if $(DEVPHASE), $(DATESTAMP))\"" \
  -DDEVPHASE="\"$(if $(DEVPHASE), ($(DEVPHASE)))\"" \
  -DPKGVERSION="\"$(pkgversion)\"" \
  -DBUGURL="\"$(bugurl)\"" \
  -DREVISION=

# Include and link freshly built target RTL instead of the default.
RTL_DIR := ../libada
adaflags += -nostdinc -I$(RTL_DIR)/adainclude
ldlibs   += -L$(RTL_DIR)/adalib -lgnat-$(LIB_VERSION)

# Append user settings last, allowing them to take precedence.
adaflags += $(CFLAGS) $(ADA_CFLAGS) $(ADAFLAGS)
cflags   += $(CFLAGS) $(ADA_CFLAGS)
cppflags += $(CPPFLAGS)
ldflags  += $(LDFLAGS)

# Link wanted Ada sources from source tree, so that gnat fails when new
# dependencies are missing in the current directory, instead of silently
# using the ones in the distant directory.
# Let Make create all symlinks before first ada compilation,
# because they depend on each other.
# snames.ad[bs] is generated in the build tree.

UNITS_BOTH := aspects atree casing csets debug einfo elists fname \
  gnatvsn krunch lib namet nlists opt output repinfo scans sem_aux \
  sinfo sinput stand stringt table tree_in tree_io types uintp \
  uname urealp widechar xutil
UNITS_SPEC := alloc hostparm rident
SEPARATES := lib-list lib-sort
ADA_SRC := $(addsuffix .ads, $(UNITS_BOTH) $(UNITS_SPEC)) \
           $(addsuffix .adb, $(UNITS_BOTH) $(SEPARATES))
OBJECTS := $(addsuffix .o, $(UNITS_BOTH) snames $(UNITS_SPEC) version)

all: libgnatvsn.a libgnatvsn.so.$(LIB_VERSION) gnatvsn.gpr

libgnatvsn.so.$(LIB_VERSION): $(addprefix obj-shared/,$(OBJECTS))
	$(CC) -o $@ -shared -fPIC -Wl,--soname,$@ $^ $(ldflags) $(ldlibs)
	ln -fs libgnatvsn.so.$(LIB_VERSION) libgnatvsn.so
	chmod a=r obj-shared/*.ali
# Make the .ali files, but not the .o files, visible to the gnat tools.
	cp -lp obj-shared/*.ali .

$(foreach u, $(UNITS_BOTH) snames, obj-shared/$(u).o): \
obj-shared/%.o: %.adb $(ADA_SRC) snames.adb snames.ads | obj-shared
	$(CC) -c -fPIC $(adaflags) $< -o $@

$(foreach u, $(UNITS_SPEC), obj-shared/$(u).o): \
obj-shared/%.o: %.ads $(ADA_SRC) snames.adb snames.ads | obj-shared
	$(CC) -c -fPIC $(adaflags) $< -o $@

obj-shared/version.o: version.c version.h | obj-shared
	$(CC) -c -fPIC $(cflags) $(cppflags) $< -o $@

libgnatvsn.a: $(addprefix obj-static/,$(OBJECTS))
	ar rc $@ $^
	ranlib $@

$(foreach u, $(UNITS_BOTH) snames, obj-static/$(u).o): \
obj-static/%.o: %.adb $(ADA_SRC) snames.adb snames.ads | obj-static
	$(CC) -c $(adaflags) $< -o $@

$(foreach u, $(UNITS_SPEC), obj-static/$(u).o): \
obj-static/%.o: %.ads $(ADA_SRC) snames.adb snames.ads | obj-static
	$(CC) -c $(adaflags) $< -o $@

obj-static/version.o: version.c version.h | obj-static
	$(CC) -c $(cflags) $(cppflags) $< -o $@

obj-shared obj-static:
	mkdir $@

$(ADA_SRC):
	ln -s $(srcdir)/../gcc/ada/$@
version.c version.h:
	ln -s $(srcdir)/../gcc/$@
snames.adb snames.ads:
	ln -s ../../gcc/ada/$@

gnatvsn.gpr: $(srcdir)/gnatvsn.gpr.sed
	sed '$(foreach v,src ali lib,s|$(v)_inst_dir|$($(v)_inst_dir)|;)' \
	  $< > $@

install: all
	mkdir -p $(DESTDIR)$(gpr_inst_dir)
	$(INSTALL_DATA) gnatvsn.gpr $(DESTDIR)$(gpr_inst_dir)
	mkdir -p $(DESTDIR)$(lib_inst_dir)
	$(INSTALL_DATA) libgnatvsn.a libgnatvsn.so.* $(DESTDIR)$(lib_inst_dir)
	cd $(DESTDIR)$(lib_inst_dir) && ln -sf libgnatvsn.so.$(LIB_VERSION) libgnatvsn.so
	mkdir -p $(DESTDIR)$(src_inst_dir)
	$(INSTALL_DATA) *.adb *.ads *.c *.h $(DESTDIR)$(src_inst_dir)
	mkdir -p $(DESTDIR)$(ali_inst_dir)
	$(INSTALL) -m 0444 *.ali $(DESTDIR)$(ali_inst_dir)

clean:
	rm -fr obj-static obj-shared
	rm -f *.ali libgnatvsn* *.adb *.ads *.c *.h gnatvsn.gpr
	rm -f Makefile config.log
