From 4766a7a7a2f23ee10560e1a2a177eec8931d974a Mon Sep 17 00:00:00 2001 From: Björn Persson Date: Wed, 13 Feb 2013 23:17:52 +0100 Subject: Added a convenient and flexible build system. --- comfignat.mk | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 comfignat.mk (limited to 'comfignat.mk') diff --git a/comfignat.mk b/comfignat.mk new file mode 100644 index 0000000..785a9f5 --- /dev/null +++ b/comfignat.mk @@ -0,0 +1,220 @@ +# 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 + +# If GNAT_BUILDER looks like it will invoke Gnatmake, then make the default +# value of GNATFLAGS compatible with Gnatmake. Otherwise make it suitable for +# building multi-language projects with GPRbuild. +ifeq ($(findstring gnatmake,${notdir ${lastword ${GNAT_BUILDER}}}),) + GNATFLAGS ?= ${GNAT_BUILDER_FLAGS} \ + -cargs:Ada ${ADAFLAGS} -cargs:C ${CFLAGS} \ + -cargs:C++ ${CXXFLAGS} -cargs:Fortran ${FFLAGS} \ + -largs ${LDFLAGS} +else + GNATFLAGS ?= ${GNAT_BUILDER_FLAGS} -cargs ${ADAFLAGS} -largs ${LDFLAGS} +endif + +# (DESTDIR is also supported.) + + +# +# 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 directory project if there is one. It +# becomes the Gnatprep symbols Directory_GPR and Directory_Project. + +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 = ${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 = 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 assign or append to these variables as needed: +# + +ifneq (${origin configured_files},file) + configured_files := ${basename ${wildcard *.in}} +endif +# configured_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. + + +# +# Compute the symbol definitions for Gnatprep, and some other data that the +# rules need: +# + +# Convey objdir and stagedir to Gnatprep. +definitions = '-DObjdir="${objdir}"' '-DStagedir="${stagedir}"' + +# Convey the prefix variables too, although they're supposed to be unused when +# the preprocessing is done with Make. +definitions += '-DPrefix="${prefix}"' '-DExec_Prefix="${exec_prefix}"' + +# If a directory project is used, then make project files take the directory +# variables from there. Otherwise convey the ones defined above. +ifeq (${dirgpr},) + definitions += '-DBindir="${bindir}"' '-DLibexecdir="${libexecdir}"' + definitions += '-DIncludedir="${includedir}"' '-DLibdir="${libdir}"' +else + directory_project := ${basename ${notdir ${dirgpr}}} + definitions += '-DDirectory_GPR="${dirgpr}"' + definitions += '-DDirectory_Project=${directory_project}' + definitions += '-DBindir=${directory_project}.Bindir' + definitions += '-DLibexecdir=${directory_project}.Libexecdir' + definitions += '-DIncludedir=${directory_project}.Includedir' + definitions += '-DLibdir=${directory_project}.Libdir' +endif + +# 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}} + +stage_any_GPRs = ${if ${usage_GPRs},stage_GPRs} + +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. Arguments for the +# builder may be appended. + + +# +# Make rules: +# + +.SECONDEXPANSION: + +all: build + +%.gpr: %.gpr.in + "${GNATPREP}" $< $@ ${definitions} + +configure: $${configured_files} + +%.gpr.phony_target: %.gpr configure + ${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 -RPpf "${stagedir}"/* "${DESTDIR}/" +.PHONY: install + +clean:: + rm -Rf ${builddir} ${configured_files} -- cgit v1.2.3