Rombobjörn

summaryrefslogtreecommitdiff
path: root/comfignat.mk
diff options
context:
space:
mode:
Diffstat (limited to 'comfignat.mk')
-rw-r--r--comfignat.mk371
1 files changed, 371 insertions, 0 deletions
diff --git a/comfignat.mk b/comfignat.mk
new file mode 100644
index 0000000..e64eab6
--- /dev/null
+++ b/comfignat.mk
@@ -0,0 +1,371 @@
+# Comfignat makefile foundation for configuring and building GNAT projects
+# Copyright 2013 B. Persson, Bjorn@Rombobeorn.se
+#
+# This material is provided as is, with absolutely no warranty expressed
+# or implied. Any use is at your own risk.
+#
+# Permission is hereby granted to use or copy this makefile
+# for any purpose, provided the above notices are retained on all copies.
+# Permission to modify the code and to distribute modified code is granted,
+# provided the above notices are retained, and a notice that the code was
+# modified is included with the above copyright notice.
+
+
+# This file contains generic Make code. It is designed to be included by other
+# makefiles, called containing makefiles, which add information specific to the
+# project at hand. Builds are controlled by GNAT project files which import the
+# abstract project Comfignat and use the directory variables it defines. For
+# libraries there shall also be usage projects to be installed on the target
+# system. Usage projects and the Comfignat project will be preprocessed with
+# Gnatprep. (Build projects may also be preprocessed.)
+#
+# If a directory project is provided, then the project files will get the
+# directory variables from there, otherwise the Make variables will be used.
+#
+# This file may not work with other Make clones than GNU Make. (Reusable Make
+# code is pretty much impossible to write without advanced Make features.) If
+# Make cannot be used for whatever reason, then it's not too difficult to run
+# the project files through Gnatprep manually.
+
+
+#
+# Program-name variables and the usual options variables are picked up from the
+# environment or the command line:
+#
+
+GNATPREP ?= gnatprep
+GNAT_BUILDER ?= gprbuild
+
+GNATFLAGS ?= ${if ${findstring gnatmake, \
+ ${notdir ${call mung,${GNAT_BUILDER}}}}, \
+ ${GNAT_BUILDER_FLAGS} \
+ -cargs ${ADAFLAGS} \
+ -bargs ${GNATBINDFLAGS} \
+ -largs ${GNATLINKFLAGS} ${LDFLAGS}, \
+ ${GNAT_BUILDER_FLAGS} \
+ -cargs:Ada ${ADAFLAGS} \
+ -cargs:C ${CPPFLAGS} ${CFLAGS} \
+ -cargs:C++ ${CPPFLAGS} ${CXXFLAGS} \
+ -cargs:Fortran ${FFLAGS} \
+ -bargs ${GNATBINDFLAGS} \
+ -largs ${LDFLAGS}}
+
+# (DESTDIR is also supported.)
+
+# Containing makefiles may assign default values to the options variables
+# GNAT_BUILDER_FLAGS, ADAFLAGS, CFLAGS, CXXFLAGS, FFLAGS, GNATBINDFLAGS,
+# GNATLINKFLAGS and LDFLAGS if they are undefined in the environment, but
+# should expect that users and distributions may override those defaults.
+
+
+#
+# These variables should be overridden on the command line as needed, but will
+# not be picked up from the environment:
+#
+
+dirgpr =
+# dirgpr should be the filename of the target system's directory project if
+# there is one. Project files will be configured to use the directory project,
+# and the Gnatprep symbols Directory_GPR and Directory_Project will be derived
+# from dirgpr.
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+bindir = ${exec_prefix}/bin
+libexecdir = ${exec_prefix}/libexec
+datarootdir = ${prefix}/share
+datadir = ${datarootdir}
+sysconfdir = ${prefix}/etc
+localstatedir = ${prefix}/var
+includedir = ${prefix}/include
+libdir = ${exec_prefix}/lib
+gprdir = ${datarootdir}/gpr
+localedir = ${datarootdir}/locale
+mandir = ${datarootdir}/man
+infodir = ${datarootdir}/info
+# These are the directories where different kinds of files will be installed on
+# the target system. Some of these directory variables aren't used in this file
+# but may be needed in containing makefiles.
+
+builddir = ${CURDIR}/build
+objdir = ${builddir}/obj
+stagedir = ${builddir}/stage
+# Intermediate files produced during the build are kept in objdir. Files to be
+# installed are written to stagedir, and then copied to their destination in
+# the installation step.
+
+# Containing makefiles should avoid modifying the directory variables. Users
+# should be able to rely on these defaults.
+
+relocatable_package = false
+# If relocatable_package is true, then directory variables in project files
+# will be configured with relative pathnames so that the installed directory
+# tree as a whole can be moved to another location in the filesystem without
+# breaking the project files.
+# dirgpr takes precedence over relocatable_package.
+
+install_cp_flags = ${if ${DESTDIR},--preserve=timestamps,}
+# Timestamps are preserved when installation is done to a staging directory.
+# This matters for files that aren't generated during the build but copied from
+# the source tree. Timestamps are not preserved when installation is done
+# directly to the target system, because that would change the timestamps of
+# existing directories.
+
+
+#
+# Containing makefiles should assign or append to these variables as needed:
+#
+
+configuration_variables += \
+ GNATPREP GNAT_BUILDER GNAT_BUILDER_FLAGS ADAFLAGS CPPFLAGS CFLAGS CXXFLAGS \
+ FFLAGS GNATBINDFLAGS GNATLINKFLAGS LDFLAGS GNATFLAGS DESTDIR \
+ dirgpr prefix exec_prefix bindir libexecdir datarootdir datadir sysconfdir \
+ localstatedir includedir libdir gprdir localedir mandir infodir builddir \
+ objdir stagedir relocatable_package install_cp_flags
+# configuration_variables is a list of variables that can be saved in the
+# persistent configuration with "make configure". Containing makefiles may
+# append additional variable names.
+
+ifneq (${origin preprocessed_files},file)
+ preprocessed_files := ${basename ${wildcard *.in}}
+endif
+# preprocessed_files is a list of files to be produced in the preprocessing
+# step at the beginning of the build. Containing makefiles may override it or
+# append additional filenames to it.
+
+ifneq (${origin build_GPRs},file)
+ build_GPRs :=
+endif
+# build_GPRs shall name one or more project files for building the software.
+# These project files will be used when "make" or "make build" is invoked.
+
+ifneq (${origin usage_GPRs},file)
+ usage_GPRs :=
+endif
+# If the build produces libraries, then usage_GPRs shall name the project files
+# that other projects should import to link to the libraries. These project
+# files will be installed to the target system.
+
+ifneq (${origin options},file)
+ options :=
+endif
+# options may be assigned a list of variable names. Those variables may be
+# overridden on the command line, and will be defined as Gnatprep symbols.
+# Their values must be "true" or "false".
+# The containing makefile should assign a default value to each variable unless
+# it shall be mandatory to always set the option on the command line.
+
+ifneq (${origin Gnatprep_definitions},file)
+ Gnatprep_definitions :=
+endif
+# Any text assigned to Gnatprep_definitions will be included in the Gnatprep
+# command line. It may be used for additional symbol definitions.
+
+
+#
+# Containing makefiles may use this command variable:
+#
+
+build_GPR = "${GNAT_BUILDER}" -P ${firstword ${filter %.gpr,$^}} -p \
+ ${GNATFLAGS} -margs
+# build_GPR is a command for use in recipies. It performs a build controlled by
+# the first project file among the rule's prerequisites.
+# Containing makefiles may append additional arguments for the builder, but
+# should ensure that any arguments that aren't essential for the build to work
+# can be overridden from the command line. Global default values for optional
+# arguments should be set in the options variables instead.
+
+
+#
+# Read the configuration file if there is one:
+#
+
+-include comfignat_configuration.mk
+
+
+#
+# Compute the symbol definitions for Gnatprep, and some other data that the
+# rules need:
+#
+
+nil =
+space_sub = _Comfignat_magic_protective_space_character_substitute_
+percent_sub = _Comfignat_magic_protective_percent_character_substitute_
+mung = ${subst %,${percent_sub},${subst ${nil} ,${space_sub},${1}}}
+unmung = ${subst ${percent_sub},%,${subst ${space_sub}, ,${1}}}
+# mung and unmung are used to prevent Make from interpreting space and percent
+# characters in strings.
+
+# Convey objdir and stagedir to Gnatprep.
+directories := '-DObjdir="${objdir}"' '-DStagedir="${stagedir}"'
+# directories is simply expanded as this reduces redundant processing and the
+# directory variables are not to be modified after this point.
+
+ifneq (${dirgpr},)
+
+ # A directory project is used, so make project files take the directory
+ # variables from there.
+
+ directory_project := ${basename ${notdir ${dirgpr}}}
+ directories += '-DDirectory_GPR="${dirgpr}"'
+ directories += '-DDirectory_Project=${directory_project}'
+ directories += '-DPrefix="${prefix}"'
+ directories += '-DExec_Prefix="${exec_prefix}"'
+ directories += '-DBindir=${directory_project}.Bindir'
+ directories += '-DLibexecdir=${directory_project}.Libexecdir'
+ directories += '-DIncludedir=${directory_project}.Includedir'
+ directories += '-DLibdir=${directory_project}.Libdir'
+
+else ifeq (${relocatable_package},true)
+
+ # Make project files use directory names relative to gprdir.
+
+ relativize = ${if ${filter ${2}%,${1}}, \
+ ${3}${1:${2}%=%}, \
+ ${call relativize,${1},${dir ${2:%/=%}},${3}../}}
+ # relativize is the recursive algorithm that converts an absolute pathname
+ # into a relative one.
+ # Parameters:
+ # 1: an absolute pathname to convert to relative
+ # 2: the absolute base pathname, being shortened until it's a prefix of 1
+ # 3: a growing series of "../" to lead the relative pathname with
+ # If 2 is a prefix of 1, then return 3 concatenated with the part of 1 that
+ # differs from 2. Otherwise delete the last element of 2, add one level of
+ # "../" to 3, and repeat.
+ # Within relativize all pathnames have one trailing slash so that only whole
+ # directory names will match. Otherwise "/usr/lib" could match "/usr/lib64"
+ # for example.
+
+ prep = ${subst //,/,${abspath ${call mung,${1}}}/}
+ # prep prepares a pathname for use as a parameter to relativize.
+ # · Protect space and percent characters from interpretation by Make.
+ # · Normalize the pathname, eliminating ".", ".." and "//".
+ # · Append a slash.
+ # · If the input was "/", then it is now "//". Change that back to "/".
+
+ relative_to_gprdir = \
+ ${or ${call unmung,${patsubst %/,%,${call relativize \
+ ,${call prep,${1}} \
+ ,${call prep,${gprdir}},}}},.}
+ # relative_to_gprdir converts an absolute pathname into a pathname relative
+ # to gprdir. What it actually does is to prepare the input to relativize and
+ # fix up its output.
+ # · Prepare the input pathname with prep.
+ # · Prepare gprdir with prep.
+ # · Call relativize with the input for parameter 1, gprdir for 2, and an
+ # empty string for 3.
+ # · Strip the result of surrounding spaces and the trailing slash.
+ # · Reverse the protection of space and percent characters.
+ # · If the result is an empty string, then return "." instead.
+
+ directories += '-DBase="${gprdir}"'
+ directories += '-DPrefix="${call relative_to_gprdir,${prefix}}"'
+ directories += '-DExec_Prefix="${call relative_to_gprdir,${exec_prefix}}"'
+ directories += '-DBindir="${call relative_to_gprdir,${bindir}}"'
+ directories += '-DLibexecdir="${call relative_to_gprdir,${libexecdir}}"'
+ directories += '-DIncludedir="${call relative_to_gprdir,${includedir}}"'
+ directories += '-DLibdir="${call relative_to_gprdir,${libdir}}"'
+
+else ifeq (${relocatable_package},false)
+
+ # Convey the directory variables unmodified to project files.
+
+ directories += '-DPrefix="${prefix}"'
+ directories += '-DExec_Prefix="${exec_prefix}"'
+ directories += '-DBindir="${bindir}"'
+ directories += '-DLibexecdir="${libexecdir}"'
+ directories += '-DIncludedir="${includedir}"'
+ directories += '-DLibdir="${libdir}"'
+
+else
+ ${error relocatable_package must be "true" or "false".}
+endif
+
+definitions = ${directories}
+# definitions is recursively expanded so that the options referenced below may
+# be defined in containing makefiles after the inclusion of this file.
+
+# Convey boolean options to Gnatprep.
+definitions += \
+ ${foreach option,${options}, \
+ ${if ${and ${filter-out environment,${origin ${option}}}, \
+ ${filter 1,${words ${${option}}}}, \
+ ${filter true false,${${option}}}}, \
+ -D${option}=${${option}}, \
+ ${error ${option} must be "true" or "false".}}}
+# For each variable listed in options, check that it didn't come from the
+# environment (to prevent accidents), that its value is a single word, and that
+# that word is either "true" or "false". If so, append a symbol definition;
+# otherwise complain and stop.
+
+# Convey any additional symbols that the containing makefile has defined.
+definitions += ${Gnatprep_definitions}
+
+build_targets = ${addsuffix .phony_target,${build_GPRs}}
+# A phony target is defined for each build project, and the job of determining
+# whether the project needs rebuilding is delegated to the builder.
+
+stage_any_GPRs = ${if ${usage_GPRs},stage_GPRs}
+# The recipie for the target stage_GPRs breaks if usage_GPRs is empty, so it's
+# included as a prerequisite of build only if there are some usage projects.
+
+
+#
+# Make rules:
+#
+
+.SECONDEXPANSION:
+
+all: build
+
+configure::
+ @( ${foreach variable,${configuration_variables}, \
+ ${if ${or ${findstring command line, \
+ ${origin ${variable}}}, \
+ ${filter true,${${variable}_is_configured}}}, \
+ echo '${variable} = ${value ${variable}}'; \
+ echo '${variable}_is_configured = true';}} \
+ ) > comfignat_configuration.mk
+# Out of the variables listed in configuration_variables, all that were
+# overridden on the command line, and all that were previously configured, are
+# written to the configuration file. A variable is considered previously
+# configured if there is another variable with "_is_configured" appended to its
+# name and a value of "true", and such a variable is also written for each
+# configured variable. It is therefore possible to delete a variable V from the
+# configuration by running "make configure V_is_configured=false".
+
+%.gpr: %.gpr.in
+ "${GNATPREP}" $< $@ ${definitions}
+
+preprocess: $${preprocessed_files}
+
+%.gpr.phony_target: %.gpr preprocess
+ ${build_GPR}
+# Instead of tracking dependencies between project files, this rule simply
+# requires that all preprocessing is done before any project is built.
+
+stage_GPRs: $${usage_GPRs}
+ mkdir -p "${stagedir}${gprdir}"
+ cp -p ${usage_GPRs} "${stagedir}${gprdir}"
+.PHONY: stage_GPRs
+
+build: $${build_targets} $${stage_any_GPRs}
+
+${stagedir}:
+ @${MAKE} build --no-print-directory
+# "make install" straight out of a source package triggers a build, but if
+# something has been built then "make install" doesn't rebuild anything, just
+# copies the built files to their destination.
+
+install: ${stagedir}
+ mkdir -p "${DESTDIR}/"
+ cp -RPf ${install_cp_flags} "${stagedir}"/* "${DESTDIR}/"
+.PHONY: install
+
+clean::
+ rm -Rf ${builddir} ${preprocessed_files}
+
+unconfigure::
+ rm -f comfignat_configuration.mk
+
+distclean: clean unconfigure