From 2bf0dfd6a04f5dfb9798cabbd56fc49863b64172 Mon Sep 17 00:00:00 2001 From: Björn Persson Date: Sat, 13 Jul 2013 23:56:04 +0200 Subject: Redesigned the handling of relative pathnames. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit · 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. --- INSTALL | 46 ++++---- comfignat.gpr.gp | 248 +++++++++++++++++++++++++++++++++-------- comfignat.mk | 334 ++++++++++++++++++++++++++++++++++--------------------- 3 files changed, 433 insertions(+), 195 deletions(-) diff --git a/INSTALL b/INSTALL index d26f007..e1e95b2 100644 --- a/INSTALL +++ b/INSTALL @@ -65,8 +65,8 @@ are relevant during the build: file. Default: false prefix - A prefix used in the default values of the directory variables listed - below. Default: /usr/local + A prefix used in the default values of almost all of the directory + variables listed below. Default: /usr/local exec_prefix A prefix used in the default locations for programs, binary libraries and @@ -102,7 +102,7 @@ are relevant during the build: statedir The parent of the application-specific directory for idiosyncratic variable - data files for this program. Default: /lib + data files for this software. Default: /lib cachedir The parent of the application-specific directory for cached data files that @@ -112,16 +112,6 @@ are relevant during the build: logdir The top-level directory for log files. Default: /log - runtimedir - The top-level directory for files that describe the state of the system and - that exist only while some subsystem is running, such as process identifier - files and transient Unix-domain sockets. Default: /run - - lockdir - The top-level directory for lock files that are used to prevent multiple - programs from trying to access a device or other resource at the same time. - Default: /lock - includedir The top-level directory for source files to be used in the compilation of software using libraries, used only if no directories project is provided. @@ -155,6 +145,16 @@ are relevant during the build: The parent of the application-specific directory for miscellaneous documentation files. Default: /doc + runtimedir + The top-level directory for files that describe the state of the system and + that exist only while some subsystem is running, such as process identifier + files and transient Unix-domain sockets. Default: /run + + lockdir + The top-level directory for lock files that are used to prevent multiple + programs from trying to access a device or other resource at the same time. + Default: /lock + If you want to install to a staging directory from which the files will later be copied to their final locations, then set DESTDIR to the staging directory. All the other directory variables shall be the final locations. Unlike the @@ -176,16 +176,24 @@ The same defaults as above will be used if the symbols are undefined. Exec_Prefix Bindir Libexecdir + Datarootdir + Datadir + Sysconfdir + Localstatedir + Statedir + Cachedir + Logdir Includedir Libdir + GPRdir + Localedir + Mandir + Infodir + Miscdocdir + Runtimedir + Lockdir These correspond to the like-named Make variables. - Base - If Prefix, Exec_Prefix, Bindir, Libexecdir, Includedir and Libdir are - relative pathnames, then Base shall be the absolute pathname of the - directory that they are relative to. If those variables are absolute - pathnames, then Base shall be undefined. - Optional Features ----------------- diff --git a/comfignat.gpr.gp b/comfignat.gpr.gp index fdbdcba..d5bcd78 100644 --- a/comfignat.gpr.gp +++ b/comfignat.gpr.gp @@ -26,85 +26,239 @@ abstract project Comfignat is - #if Objdir'Defined then - Objdir := $Objdir; - #else - Objdir := "build"; + #if not Invoked_By_Makefile'Defined then + + -- These variables are used in constructing the default values of the + -- directory variables below. They're only needed when this file is + -- preprocessed manually. + + #if Prefix'Defined then + Prefix := $Prefix; + #else + Prefix := "/usr/local"; + #end if; + -- Prefix is used in the default locations for almost all files. + + #if Exec_Prefix'Defined then + Exec_Prefix := $Exec_Prefix; + #else + Exec_Prefix := Prefix; + #end if; + -- Exec_Prefix is used in the default locations for programs, binary + -- libraries and other architecture-specific files. + + #if Datarootdir'Defined then + Datarootdir := $Datarootdir; + #else + Datarootdir := Prefix & "/share"; + #end if; + -- Datarootdir is the root of the directory tree for read-only + -- architecture-independent data files. + + #if Localstatedir'Defined then + Localstatedir := $Localstatedir; + #else + Localstatedir := Prefix & "/var"; + #end if; + -- Localstatedir is the root of the directory tree for data files that + -- programs modify while they run. + #end if; - -- Intermediate files produced during the build shall be kept in Objdir. - #if Directories_Project'Defined then - -- Put intermediate files for different architectures in subdirectories - -- where they won't conflict with each other. (This is useful especially - -- with binder files when they are packaged in debug information packages - -- for multiarch systems.) - Objdir := Objdir & "/" & $Directories_Project.Hardware_Platform; + + -- + -- The following variables may be compiled into programs or libraries to + -- tell them where to find or write different kinds of files at run time. + -- Most of the directory names are relative to Bindir if the software was + -- configured as a relocatable package. Otherwise they are absolute + -- pathnames. + + -- Programs that can be run from a command prompt are in Bindir. This is + -- normally the same directory that the program itself is in, so this + -- variable is probably of little use at run time. + #if Bindir'Defined then + Bindir := $Bindir; + #else + Bindir := Exec_Prefix & "/bin"; #end if; - #if Stagedir'Defined then - Stagedir := $Stagedir; + -- Programs that are intended to be run by other programs rather than by + -- users are under Libexecdir. + #if Libexecdir'Defined then + Libexecdir := $Libexecdir; #else - Stagedir := external("DESTDIR", ""); + Libexecdir := Exec_Prefix & "/libexec"; #end if; - -- Files to be installed shall be placed under Stagedir instead of the root - -- directory. - #if Base'Defined then - Prepath := Stagedir & $Base & "/"; + -- Idiosyncratic read-only architecture-independent data files are under an + -- application-specific subdirectory of Datadir. + #if Datadir'Defined then + Datadir := $Datadir; #else - Prepath := Stagedir; + Datadir := Datarootdir; #end if; - -- If Prefix, Exec_Prefix, Bindir, Libexecdir, Includedir and Libdir are - -- relative pathnames, then Base shall be the absolute pathname of the - -- directory that they are relative to. If those variables are absolute - -- pathnames, then Base shall be undefined. - #if Prefix'Defined then - Prefix := $Prefix; + -- Host-specific configuration files are under Sysconfdir. + #if Sysconfdir'Defined then + Sysconfdir := $Sysconfdir; #else - Prefix := "/usr/local"; + Sysconfdir := Prefix & "/etc"; #end if; - #if Exec_Prefix'Defined then - Exec_Prefix := $Exec_Prefix; + -- Idiosyncratic variable data files shall be kept under an application- + -- specific subdirectory of Statedir. + #if Statedir'Defined then + Statedir := $Statedir; #else - Exec_Prefix := Prefix; + Statedir := Localstatedir & "/lib"; #end if; - #if Bindir'Defined then - Bindir := $Bindir; + -- Cached data files that the application can regenerate if they are deleted + -- shall be kept under an application-specific subdirectory of Cachedir. + #if Cachedir'Defined then + Cachedir := $Cachedir; #else - Bindir := Exec_Prefix & "/bin"; + Cachedir := Localstatedir & "/cache"; #end if; - Stage_Bindir := Prepath & Bindir; - -- Programs that can be run from a command prompt shall be installed in - -- Stage_Bindir. - #if Libexecdir'Defined then - Libexecdir := $Libexecdir; + -- Log files shall be written under Logdir. + #if Logdir'Defined then + Logdir := $Logdir; #else - Libexecdir := Exec_Prefix & "/libexec"; + Logdir := Localstatedir & "/log"; #end if; - Stage_Libexecdir := Prepath & Libexecdir; - -- Programs that are only to be run by other programs, not by users, shall - -- be installed under Stage_Libexecdir. + -- Source files to be used in the compilation of software using libraries + -- are under Includedir. #if Includedir'Defined then Includedir := $Includedir; #else Includedir := Prefix & "/include"; #end if; - Stage_Includedir := Prepath & Includedir; - -- Source files needed for compiling code that uses a library shall be - -- installed under Stage_Includedir. + -- Binary libraries and other architecture-specific files are under Libdir. #if Libdir'Defined then Libdir := $Libdir; #else - Libdir := Prefix & "/lib"; + Libdir := Exec_Prefix & "/lib"; #end if; - Stage_Libdir := Prepath & Libdir; + + -- GNAT project files are under GPRdir. + #if GPRdir'Defined then + GPRdir := $GPRdir; + #else + GPRdir := Datarootdir & "/gpr"; + #end if; + + -- Locale-specific message catalogs are under Localedir. + #if Localedir'Defined then + Localedir := $Localedir; + #else + Localedir := Datarootdir & "/locale"; + #end if; + + -- Documentation in the Man format is under Mandir. + #if Mandir'Defined then + Mandir := $Mandir; + #else + Mandir := Datarootdir & "/man"; + #end if; + + -- Documentation in the Info format is in Infodir. + #if Infodir'Defined then + Infodir := $Infodir; + #else + Infodir := Datarootdir & "/info"; + #end if; + + -- Other documentation files are under an application-specific subdirectory + -- of Miscdocdir. + #if Miscdocdir'Defined then + Miscdocdir := $Miscdocdir; + #else + Miscdocdir := Datarootdir & "/doc"; + #end if; + + -- Small files that take part in describing the state of the system, and + -- that exist only while the program is running, such as process identifier + -- files and transient Unix-domain sockets, shall be created under + -- Runtimedir. (This is NOT the place for temporary files in general.) + #if Runtimedir'Defined then + Runtimedir := $Runtimedir; + #else + Runtimedir := "/run"; + #end if; + + -- Lock files that are used to prevent multiple programs from trying to + -- access a device or other resource at the same time shall be created under + -- Lockdir. + #if Lockdir'Defined then + Lockdir := $Lockdir; + #else + Lockdir := Runtimedir & "/lock"; + #end if; + + + -- + -- The following variables are for use in attributes to control where + -- generated files are placed. + -- + + -- Intermediate files produced during the build shall be kept in Objdir. + #if Objdir'Defined then + Objdir := $Objdir; + #else + Objdir := "build"; + #end if; + + #if Directories_Project'Defined then + -- Put intermediate files for different architectures in subdirectories + -- where they won't conflict with each other. (This is useful especially + -- with binder files when they are packaged in debug information packages + -- for multiarch systems.) + Objdir := Objdir & "/" & $Directories_Project.Hardware_Platform; + #end if; + + -- Files to be installed shall be placed under Stagedir instead of the root + -- directory. (This variable is unused by Comfignat when Make is used and no + -- directories project is provided.) + #if Stagedir'Defined then + Stagedir := $Stagedir; + #else + Stagedir := external("DESTDIR", ""); + #end if; + + -- Programs that can be run from a command prompt shall be installed in + -- Stage_Bindir. + #if Stage_Bindir'Defined then + Stage_Bindir := $Stage_Bindir; + #else + Stage_Bindir := Stagedir & Bindir; + #end if; + + -- Programs that are only to be run by other programs, not by users, shall + -- be installed under Stage_Libexecdir. + #if Stage_Libexecdir'Defined then + Stage_Libexecdir := $Stage_Libexecdir; + #else + Stage_Libexecdir := Stagedir & Libexecdir; + #end if; + + -- Source files needed for compiling code that uses a library shall be + -- installed under Stage_Includedir. + #if Stage_Includedir'Defined then + Stage_Includedir := $Stage_Includedir; + #else + Stage_Includedir := Stagedir & Includedir; + #end if; + -- Binary libraries shall be installed in Stage_Libdir. - -- ALI files shall be installed in a subdirectory of Stage_Libdir. + -- ALI files shall be installed in a library-specific subdirectory of + -- Stage_Libdir. + #if Stage_Libdir'Defined then + Stage_Libdir := $Stage_Libdir; + #else + Stage_Libdir := Stagedir & Libdir; + #end if; end Comfignat; 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} -- cgit v1.2.3