#!/usr/bin/make -f
# Build script for GPRBuild in Debian.
# Copyright (c) 2009-2012 Stephen Leake <stephen_leake@stephe-leake.org>
# Copyright (c) 2013-2023 Nicolas Boulenguez <nicolas@debian.org>

# This program 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 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.

# On Debian systems, the full text of the GPL is in the file
# /usr/share/common-licenses/GPL-3.

# NOTE:
# In order to prevent a circular build-dependency, the Debian packages
# for XML/Ada and GPRBuild bother to build without project support.
# Please keep the two debian/rules files similar enough to ease
# backport of good ideas.

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

DEB_BUILD_MAINT_OPTIONS := hardening=+all
DEB_ADAFLAGS_MAINT_APPEND := -gnatwa -Wall -gnatn
DEB_LDFLAGS_MAINT_APPEND := \
  -Wl,--no-undefined \
  -Wl,--no-copy-dt-needed-entries \
  -Wl,--no-allow-shlib-undefined
include /usr/share/dpkg/buildflags.mk
include /usr/share/dpkg/buildopts.mk
include $(wildcard /usr/share/ada/packaging.mk)
# wildcard in case only Build-Depends-Indep are installed.

# gprbuild.gpr selects inlining.
# It also selects -E -static binder options, but:
# #666106 affects only kfreebsd-i386, where storing tracebacks in
# exception occurrences causes a segmentation fault.  This prevents
# handling of any exceptions.  gprconfig relies on handling exceptions
# when parsing compilers.xml.
# Author: Ludovic Brenta <lbrenta@debian.org>

######################################################################
%:
	dh $@

# Rewrite upstream configure/make build system.
.PHONY: $(addprefix override_dh_auto_, \
  configure build-arch build-indep test install-arch install-indep clean)

# gnatmake does not support projects anymore, we cannot use xmlada.gpr.
# The priority is to bootstrap, not a complete dependency graph.

override_dh_auto_build-arch::
	ln -fs gpr-util-put_resource_usage__unix.adb gpr/src/gpr-util-put_resource_usage.adb
	mkdir -p obj

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

# For source directories (-aI) and ALI directories (-aO), blindly list
# all build dependencies and append each library once it is
# built. This does not hurt, and covers all direct and indirect
# dependencies.

# For installed shared libraries (-l) and locally built shared
# objects), the same strategy works thanks to --as-needed, which is
# the default since gcc-9, provided a proper ordering.

# Libraries provided by Ada -dev packages in Build-Depends.
ada_build_deps := xmlada_schema xmlada_dom xmlada_sax xmlada_input xmlada_unicode

# These list grow each time the template is expanded.
gnatmakeflags := $(GNATMAKEFLAGS) \
                 $(ada_build_deps:%=-aI/$(DEB_ADA_SOURCE_DIR)/%) \
                 $(ada_build_deps:%=-aO/$(DEB_ADA_LIB_INFO_DIR)/%)
shared_objects_so_far := $(ada_build_deps:%=-l%) \
                         -lgnarl-$(DEB_GNAT_VERSION) \
                         -lgnat-$(DEB_GNAT_VERSION)

define library_template
# Parameters:
# _SRCDIR: directory containing the sources files
# _SO_VERSION : part of the shared object name
# _imported_projects: for the generated project.

  override_dh_auto_build-arch::

	mkdir -p obj/shared_$1 obj/static_$1

  # Build dynamic library.
    # -fPIC/-shared overrides -fPIE/-pie in ADAFLAGS/LDFLAGS.
	gcc-$(DEB_GNAT_VERSION) -c $($1_SRCDIR)/gpr_imports.c \
	  $(CFLAGS) $(CPPFLAGS) -o obj/shared_$1/gpr_imports.o -fPIC
	gnatmake -c `grep -L '^separate ' $($1_SRCDIR)/*.ad[bs] | grep -v __` \
	  $(gnatmakeflags) -D obj/shared_$1 -cargs $(ADAFLAGS) -fPIC
	gcc-$(DEB_GNAT_VERSION) -shared \
	  -o obj/lib$1.so.$($1_SO_VERSION) \
	  -Wl,-soname,lib$1.so.$($1_SO_VERSION) \
	  $(LDFLAGS) obj/shared_$1/*.o $(shared_objects_so_far)

  # Mark ALI files as read-only.
	chmod 444 obj/shared_$1/*.ali

  # Build static library.
	gcc-$(DEB_GNAT_VERSION) -c $($1_SRCDIR)/gpr_imports.c \
	  $(CFLAGS) $(CPPFLAGS) -o obj/static_$1/gpr_imports.o
	gnatmake -c `grep -L '^separate ' $($1_SRCDIR)/*.ad[bs] | grep -v __` \
	  $(gnatmakeflags) -D obj/static_$1 -cargs $(ADAFLAGS)
	ar rc obj/lib$1.a obj/static_$1/*.o
	ranlib obj/lib$1.a

  # Externally built project installed for end users.
	sed ' \
	  /@IMPORTS@/ { \
	    s//$($1_imported_projects:%=with "%.gpr";\n)/; \
	    s/\n /\n/g; }; \
	  s/@library@/$1/; \
	  s|@DEB_LIB_DIR@|$(DEB_LIB_DIR)|; \
	  s|@DEB_ADA_SOURCE_DIR@|$(DEB_ADA_SOURCE_DIR)|; \
	  s|@DEB_ADA_LIB_INFO_DIR@|$(DEB_ADA_LIB_INFO_DIR)|; \
	  ' debian/template.gpr > obj/$1.gpr

  override_dh_auto_install-arch::
	install -m644 -Dtdebian/tmp/$(DEB_ADA_SOURCE_DIR)/$1 $($1_SRCDIR)/*.ad[bs] \
	  $($1_SRCDIR)/gpr_imports.c
	install -m444 -Dtdebian/tmp/$(DEB_ADA_LIB_INFO_DIR)/$1 obj/shared_$1/*.ali
	install -m644 -Dtdebian/tmp/$(DEB_GNAT_PROJECT_DIR) obj/$1.gpr
	install -m644 -Dtdebian/tmp/$(DEB_LIB_DIR) \
	  obj/lib$1.so.$($1_SO_VERSION) obj/lib$1.a
	ln -fs lib$1.so.$($1_SO_VERSION) debian/tmp/$(DEB_LIB_DIR)/lib$1.so

  gnatmakeflags += -aI$($1_SRCDIR) -aOobj/shared_$1
  shared_objects_so_far := obj/lib$1.so.$($1_SO_VERSION) \
                           $(shared_objects_so_far)
endef

gnatprj_SRCDIR := gpr/src
gnatprj_imported_projects := xmlada_schema xmlada_dom xmlada_sax xmlada_input
$(eval $(call library_template,gnatprj))

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

args_for_tools := \
  -D obj $(gnatmakeflags) \
  -cargs $(ADAFLAGS) \
  -largs $(LDFLAGS) $(shared_objects_so_far)

override_dh_auto_build-arch::
	gnatmake src/gprbind.adb         -o obj/gprbind    $(args_for_tools)
	gnatmake src/gprbuild-main.adb   -o obj/gprbuild   $(args_for_tools)
	gnatmake src/gprclean-main.adb   -o obj/gprclean   $(args_for_tools)
	gnatmake src/gprconfig-main.adb  -o obj/gprconfig  $(args_for_tools)
	gnatmake src/gprinstall-main.adb -o obj/gprinstall $(args_for_tools)
	gnatmake src/gprlib.adb          -o obj/gprlib     $(args_for_tools)
	gnatmake src/gprls-main.adb      -o obj/gprls      $(args_for_tools)
	gnatmake src/gprname-main.adb    -o obj/gprname    $(args_for_tools)
	gnatmake src/gprslave.adb        -o obj/gprslave   $(args_for_tools)

######################################################################
override_dh_auto_build-indep:
  ifeq (,$(filter nodoc,$(DEB_BUILD_OPTIONS)))
    # Enable parallelism in sphinx, but not in Make (#1008152).
	$(MAKE) -C doc html pdf txt \
	  $(DEB_BUILD_OPTION_PARALLEL:%=SPHINXOPTS=-j%)
  endif
override_dh_auto_clean:
	$(MAKE) -Cdoc clean

# Compatibility project with upstream name GPR.
execute_after_dh_install-arch:
	dh_install --package=libgnatprj-dev \
	  debian/gpr.gpr \
	  $(DEB_GNAT_PROJECT_DIR)
