Rombobjörn

summaryrefslogtreecommitdiff
path: root/comfignat.mk
blob: aea3103d72329aefa1c2933236c01d4f9e9bed14 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# 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        = ${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 = 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.

ifeq (${DESTDIR},)
   install_cp_flags =
else   
   install_cp_flags = --preserve=timestamps
endif
# 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:
#

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 -RPf ${install_cp_flags} "${stagedir}"/* "${DESTDIR}/"
.PHONY: install

clean::
	rm -Rf ${builddir} ${configured_files}