Rombobjörn

summaryrefslogtreecommitdiff
path: root/comfignat.mk
diff options
context:
space:
mode:
authorBjörn Persson <bjorn@rombobjörn.se>2013-07-13 23:56:04 +0200
committerBjörn Persson <bjorn@rombobjörn.se>2013-07-13 23:56:04 +0200
commit2bf0dfd6a04f5dfb9798cabbd56fc49863b64172 (patch)
treecb2d3a6bbcbd75b2b6611097882a4ef4b44775ea /comfignat.mk
parent35308529422cf3d8ad818c8a369e5f37818f875a (diff)
Redesigned the handling of relative pathnames.
· Directory variables for embedding and for installation were separated. · Directory variables for embedding are now available in project Comfignat. · Relative pathnames are now relative to gprdir or bindir in different places. · Options are conveyed to build project files as external variables. · Gnatprep_definitions is now Gnatprep_arguments. · preprocess_file and builder_arguments were added.
Diffstat (limited to 'comfignat.mk')
-rw-r--r--comfignat.mk334
1 files changed, 205 insertions, 129 deletions
diff --git a/comfignat.mk b/comfignat.mk
index 49da99f..d24a262 100644
--- a/comfignat.mk
+++ b/comfignat.mk
@@ -82,27 +82,29 @@ relocatable_package = false
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
-statedir = ${localstatedir}/lib
-cachedir = ${localstatedir}/cache
-logdir = ${localstatedir}/log
-runtimedir = /run
-lockdir = ${runtimedir}/lock
-includedir = ${prefix}/include
-libdir = ${exec_prefix}/lib
-gprdir = ${datarootdir}/gpr
-localedir = ${datarootdir}/locale
-mandir = ${datarootdir}/man
-infodir = ${datarootdir}/info
-miscdocdir = ${datarootdir}/doc
-# 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.
+# These variables are used in constructing the default values of the directory
+# variables below.
+
+bindir = ${exec_prefix}/bin
+libexecdir = ${exec_prefix}/libexec
+datadir = ${datarootdir}
+sysconfdir = ${prefix}/etc
+statedir = ${localstatedir}/lib
+cachedir = ${localstatedir}/cache
+logdir = ${localstatedir}/log
+includedir = ${prefix}/include
+libdir = ${exec_prefix}/lib
+gprdir = ${datarootdir}/gpr
+localedir = ${datarootdir}/locale
+mandir = ${datarootdir}/man
+infodir = ${datarootdir}/info
+miscdocdir = ${datarootdir}/doc
+runtimedir = /run
+lockdir = ${runtimedir}/lock
+# These are the directories where different kinds of files will be located on
+# the target system.
builddir = ${CURDIR}/build
objdir = ${builddir}/obj
@@ -114,7 +116,7 @@ stagedir = ${builddir}/stage
# Containing makefiles should avoid modifying the directory variables. Users
# should be able to rely on these defaults.
-install_cp_flags = ${if ${DESTDIR},--preserve=timestamps,}
+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
@@ -134,20 +136,20 @@ endif
# append additional filenames to it.
ifneq (${origin build_GPRs},file)
- build_GPRs :=
+ 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 :=
+ 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 :=
+ 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.
@@ -155,21 +157,30 @@ endif
# 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 :=
+ifneq (${origin Gnatprep_arguments},file)
+ Gnatprep_arguments =
endif
-# Any text assigned to Gnatprep_definitions will be included in the Gnatprep
+# Any text assigned to Gnatprep_arguments will be included in the Gnatprep
# command line. It may be used for additional symbol definitions.
+ifneq (${origin builder_arguments},file)
+ builder_arguments =
+endif
+# Any text assigned to builder_arguments will be included in the GPRbuild or
+# Gnatmake command line. It may be used for external variables for project
+# files or other arguments that are essential for the build to work. Global
+# default values for optional arguments should be set in the options variables
+# instead.
+
configuration_variables += \
GNATPREP GNAT_BUILDER \
GNAT_BUILDER_FLAGS ADAFLAGS CPPFLAGS CFLAGS CXXFLAGS FFLAGS GNATBINDFLAGS \
GNATLINKFLAGS LDFLAGS GNATFLAGS \
DESTDIR \
dirgpr relocatable_package \
- prefix exec_prefix bindir libexecdir datarootdir datadir sysconfdir \
- localstatedir statedir cachedir logdir runtimedir lockdir includedir libdir \
- gprdir localedir mandir infodir miscdocdir \
+ prefix exec_prefix datarootdir localstatedir \
+ bindir libexecdir datadir sysconfdir statedir cachedir logdir includedir \
+ libdir gprdir localedir mandir infodir miscdocdir runtimedir lockdir \
builddir objdir stagedir \
install_cp_flags \
${options}
@@ -179,17 +190,38 @@ configuration_variables += \
#
-# Containing makefiles may use this command variable:
+# Containing makefiles may use these variables in their rules:
#
+stage_bindir = ${stagedir}${bindir}
+stage_libexecdir = ${stagedir}${libexecdir}
+stage_datadir = ${stagedir}${datadir}
+stage_sysconfdir = ${stagedir}${sysconfdir}
+stage_statedir = ${stagedir}${statedir}
+stage_cachedir = ${stagedir}${cachedir}
+stage_logdir = ${stagedir}${logdir}
+stage_includedir = ${stagedir}${includedir}
+stage_libdir = ${stagedir}${libdir}
+stage_gprdir = ${stagedir}${gprdir}
+stage_localedir = ${stagedir}${localedir}
+stage_mandir = ${stagedir}${mandir}
+stage_infodir = ${stagedir}${infodir}
+stage_miscdocdir = ${stagedir}${miscdocdir}
+# These are the directories where different kinds of files to be installed are
+# written during the build.
+
+preprocess_file = \
+ ${if ${filter-out 1,${words $^}}, \
+ ${error preprocess_file takes 1 prerequisite but $@ has ${words $^}}, \
+ "${GNATPREP}" $< $@ ${options_preprocessing} ${Gnatprep_arguments} \
+ ${if ${filter $@,${usage_GPRs}},${usage_directories}}}
+# preprocess_file is a command for use in recipes. It runs the rule's single
+# prerequisite through Gnatprep to produce the target.
+
build_GPR = "${GNAT_BUILDER}" -P ${firstword ${filter %.gpr,$^}} -p \
- ${GNATFLAGS} -margs
+ ${options_building} ${builder_arguments} ${GNATFLAGS}
# build_GPR is a command for use in recipes. 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.
#
@@ -200,8 +232,8 @@ build_GPR = "${GNAT_BUILDER}" -P ${firstword ${filter %.gpr,$^}} -p \
#
-# Compute the symbol definitions for Gnatprep, and some other data that the
-# rules need:
+# Compute symbol definitions for Gnatprep, external variable assignments for
+# build projects, and some other data that the rules need:
#
nil =
@@ -212,110 +244,151 @@ 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.
+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 = \
+ ${or ${call unmung,${patsubst %/,%,${call relativize \
+ ,${call prep,${1}} \
+ ,${call prep,${2}},}}},.}
+# relative_to converts an absolute pathname into a relative one. What it
+# actually does is to prepare the input to relativize and fix up its output.
+# Parameters:
+# 1: an absolute pathname to convert to relative
+# 2: the absolute base pathname that 1 shall be made relative to
+# Processing:
+# · Prepare the two input pathnames with prep.
+# · Call relativize with the prepared pathnames for parameters 1 and 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.
+
+maybe_relative_to = \
+ ${if ${or ${filter-out 1,${words ${relocatable_package}}}, \
+ ${filter-out true false,${relocatable_package}}}, \
+ ${error relocatable_package must be "true" or "false"} \
+ ,${if ${filter true,${relocatable_package}} \
+ ,${call relative_to,${1},${2}},${1}}}
+# maybe_relative_to converts an absolute pathname into a relative one if a
+# relocatable package is desired.
+# Parameters:
+# 1: an absolute pathname to convert to relative
+# 2: the absolute base pathname that 1 may be made relative to
+# First check that the value of relocatable_package is a single word and that
+# that word is either "true" or "false". Complain and stop if that isn't so.
+# Then, if relocatable_package is "true", let relative_to convert the pathname,
+# otherwise return parameter 1 unchanged.
+
+embed_pathname = ${call maybe_relative_to,${1},${bindir}}
+# embed_pathname converts an absolute pathname into the right form for
+# inclusion in a program, which means that it is made relative to bindir if a
+# relocatable package is desired.
+
+usage_pathname = ${call maybe_relative_to,${1},${gprdir}}
+# usage_pathname converts an absolute pathname into the right form for
+# inclusion in a usage project, which means that it is made relative to gprdir
+# if a relocatable package is desired.
+
+# Convey objdir and stagedir to comfignat.gpr.
+all_directories = '-DObjdir="${objdir}"' '-DStagedir="${stagedir}"'
+
+# Convey the builder-irrelevant directory variables, making them available to
+# build projects for inclusion in binaries. Make most of the pathnames relative
+# if a relocatable package is desired.
+all_directories += '-DDatadir="${call embed_pathname,${datadir}}"'
+all_directories += '-DSysconfdir="${call embed_pathname,${sysconfdir}}"'
+all_directories += '-DStatedir="${call embed_pathname,${statedir}}"'
+all_directories += '-DCachedir="${call embed_pathname,${cachedir}}"'
+all_directories += '-DLogdir="${call embed_pathname,${logdir}}"'
+all_directories += '-DGPRdir="${call embed_pathname,${gprdir}}"'
+all_directories += '-DLocaledir="${call embed_pathname,${localedir}}"'
+all_directories += '-DMandir="${call embed_pathname,${mandir}}"'
+all_directories += '-DInfodir="${call embed_pathname,${infodir}}"'
+all_directories += '-DMiscdocdir="${call embed_pathname,${miscdocdir}}"'
+all_directories += '-DRuntimedir="${runtimedir}"'
+all_directories += '-DLockdir="${lockdir}"'
+# runtimedir and lockdir belong to the operating system and are used for
+# communication between subsystems. It wouldn't make sense for an application
+# to have its own runtimedir. Therefore these variables are always absolute
+# pathnames.
+
+ifeq (${dirgpr},)
+
+ # No directories project was provided, so convey even the builder-relevant
+ # directory variables to comfignat.gpr, and convey the usage-relevant ones
+ # to usage projects in the form that usage projects need.
+
+ all_directories += '-DBindir="${call embed_pathname,${bindir}}"'
+ all_directories += '-DLibexecdir="${call embed_pathname,${libexecdir}}"'
+ all_directories += '-DIncludedir="${call embed_pathname,${includedir}}"'
+ all_directories += '-DLibdir="${call embed_pathname,${libdir}}"'
+
+ all_directories += '-DStage_Bindir="${stage_bindir}"'
+ all_directories += '-DStage_Libexecdir="${stage_libexecdir}"'
+ all_directories += '-DStage_Includedir="${stage_includedir}"'
+ all_directories += '-DStage_Libdir="${stage_libdir}"'
+
+ usage_directories = '-DIncludedir="${call usage_pathname,${includedir}}"' \
+ '-DLibdir="${call usage_pathname,${libdir}}"'
-ifneq (${dirgpr},)
+else
- # A directories project is used, so make project files take the directory
- # variables from there.
+ # A directories project is used, so make project files take the builder-
+ # relevant directory variables from there.
directories_project := ${basename ${notdir ${dirgpr}}}
- directories += '-DDirectories_GPR="${dirgpr}"'
- directories += '-DDirectories_Project=${directories_project}'
- directories += '-DPrefix="${prefix}"'
- directories += '-DExec_Prefix="${exec_prefix}"'
- directories += '-DBindir=${directories_project}.Bindir'
- directories += '-DLibexecdir=${directories_project}.Libexecdir'
- directories += '-DIncludedir=${directories_project}.Includedir'
- directories += '-DLibdir=${directories_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
+ all_directories += '-DDirectories_GPR="${dirgpr}"'
+ all_directories += '-DDirectories_Project=${directories_project}'
+ all_directories += '-DBindir=${directories_project}.Bindir'
+ all_directories += '-DLibexecdir=${directories_project}.Libexecdir'
+ all_directories += '-DIncludedir=${directories_project}.Includedir'
+ all_directories += '-DLibdir=${directories_project}.Libdir'
-definitions = ${directories}
-# definitions is recursively expanded so that the options referenced below may
-# be defined in containing makefiles after the inclusion of this file.
+ usage_directories = '-DDirectories_GPR="${dirgpr}"' \
+ '-DIncludedir=${directories_project}.Includedir' \
+ '-DLibdir=${directories_project}.Libdir'
-# Convey boolean options to Gnatprep.
-definitions += \
+endif
+
+option_values = \
${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".}}}
+ ${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;
+# that word is either "true" or "false". If so, output a name/value pair;
# otherwise complain and stop.
-# Convey any additional symbols that the containing makefile has defined.
-definitions += ${Gnatprep_definitions}
+# Convey boolean options to Gnatprep.
+options_preprocessing = ${addprefix -D,${option_values}}
+
+# Convey boolean options to build projects.
+options_building = ${addprefix -X,${option_values}}
build_targets = ${addsuffix .phony_target,${build_GPRs}}
# A phony target is defined for each build project, and the job of determining
@@ -350,8 +423,11 @@ configure::
# configured variable. It is therefore possible to delete a variable V from the
# configuration by running "make configure V_is_configured=false".
+comfignat.gpr: comfignat.gpr.gp
+ "${GNATPREP}" $< $@ -DInvoked_By_Makefile ${all_directories}
+
%.gpr: %.gpr.gp
- "${GNATPREP}" $< $@ ${definitions}
+ ${preprocess_file}
preprocess: $${preprocessed_files}
@@ -361,8 +437,8 @@ preprocess: $${preprocessed_files}
# 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}"
+ mkdir -p "${stage_gprdir}"
+ cp -p ${usage_GPRs} "${stage_gprdir}"
.PHONY: stage_GPRs
build: $${build_targets} $${stage_any_GPRs}