1/*
2 * srecord - manipulate eprom load files
3 * Copyright (C) 1998, 1999, 2001-2003, 2006-2010, 2012, 2013 Peter Miller
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or (at
8 * your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "functions"
20
21set mkdir;
22set unlink;
23set time-adjust;
24
25awk = gawk;
26
27/*
28 * See how verbose we have decided to be.
29 */
30if [not [defined verbose]] then
31    verbose = [match %1D%2 [version]];
32quiet = [not [verbose]];
33libtool-quiet = ;
34if [quiet] then
35{
36    set silent;
37    libtool-quiet = --quiet;
38    set no-star;
39}
40else
41{
42    set no-silent tell-position;
43    libtool-quiet = ;
44    set star;
45}
46
47function if_quiet =
48{
49    if [quiet] then
50        function print /*[@1]*/ [target];
51    else if [in [count [younger]] 0] then
52        function print Building [target] because it doesn\'t exist yet;
53    else if [in [count [younger]] 0 1 2 3] then
54        function print Building [target] because of [younger];
55    else
56        function print Building [target] because of [wordlist 1 3 [younger]]...;
57}
58
59/*
60 * The first item in search list should be the absolute path of the
61 * current directory.  Assume that it is.
62 */
63search_list = .;
64search_tmp = [tail [split ':' [search_path]]];
65
66/*
67 * Try to shorten the search path in command lines, too.
68 *
69 * This takes a little getting used to....
70 * 1. For development builds, the search path is dev dir, then branch bl,
71 *    then ... project bl.  Thus, bl in a dev dir winds up pointing to
72 *    the branch reporitory.
73 * 2. For integration builds, aegis deliberately omits the branch
74 *    baseline from the path, but include's the branch's parents and
75 *    ancestors.  Thus, bl in an int dir winds up pointing to the
76 *    branch's parent's reporitory.
77 * The idea is that integration builds in a branch are like a
78 * development build of the branch's dev dir.
79 */
80search_name = bl;
81loop
82{
83    search_dir = [head [search_tmp]];
84    if [not [search_dir]] then
85        loopstop;
86    search_tmp = [tail [search_tmp]];
87
88    if [not [exists [search_name]]] then
89        ln -s [search_dir] [search_name]
90            set clearstat;
91    search_list = [search_list] [search_name];
92    search_name = [search_name]bl;
93}
94
95#include-cooked etc/apt-get-depends.cook
96
97/*
98 * determine the short version:
99 * no change or delta number
100 */
101version_short = [fromto %1.C%2 %1 [subst D C [version]]];
102
103version_shorter = [split "." [version_short]] _ _;
104version_shorter = [unsplit "." [word 1 [version_shorter]]
105    [word 2 [version_shorter]]];
106project_short = [fromto %.[version_short] % [project]];
107project_minus = [project_short]-[version_short];
108
109change_source_files = ;
110#include-cooked-nowarn etc/cook/change_files.[version]
111etc/cook/change_files.[version]:
112    set shallow nodefault
113{
114    function if_quiet;
115    echo "'change_source_files ='" > [target];
116    aegis -l cf -p [project] -c [change] -terse >> [target];
117    echo "';'" >> [target];
118}
119project_source_files = ;
120#include-cooked-nowarn etc/cook/project_files.[version]
121etc/cook/project_files.[version]:
122    set shallow nodefault
123{
124    function if_quiet;
125    echo "'project_source_files ='" > [target];
126    aegis -l pf -p [project] -c [change] -terse >> [target];
127    echo "';'" >> [target];
128}
129source_files = [sort [project_source_files] [change_source_files]];
130
131/*
132 * Speed up graph building by stating the leaves explictly.
133 * This also gives more useful error messages.
134 */
135if [count [project_source_files]] then
136if [count [change_source_files]] then
137{
138    leaf_file_accept = [project_source_files] [change_source_files];
139    leaf_pattern_accept = /%0%;
140}
141
142debug = /* -g */ ;      /* g++ takes forever if you say -g for complex
143                        template usage */
144
145all = ;
146
147/* the right hand side is deferred until triggered */
148all: [all];
149
150/*
151 * Howto use GNU Autoconf.
152 */
153#include-cooked etc/autoconf.cook
154
155
156/*
157 * The files which are linked to form the common library for the programs.
158 */
159[arch]/[project_short]/lib[project_short].la_obj =
160    [addprefix [arch]/
161        [fromto %0%.cc %0%.lo
162            [match_mask srecord/%0%.cc [source_files]]
163        ]
164    ];
165
166/*
167 * Generate lists of object files for programs
168 */
169program_list =
170    [stringset /* remove duplicates */
171        [patsubst %0%/main.cc %0% [filter %0%/main.cc [source_files]]]
172    ];
173
174function prog-var-from-prog-path =
175{
176    local prog = [@1];
177    local prog_var =;
178    if [in [substr 1 5 [prog] ] "test/"] then
179        prog_var = [subst "/" "_" [prog]];
180    else
181        prog_var = [subst "/" "-" [prog]];
182    return [prog_var];
183}
184
185loop prog = [program_list]
186{
187    prog_var = [prog-var-from-prog-path [prog]];
188    [prog_var]_obj =
189        [patsubst %0%.cc     %0%.lo [filter [prog]/%0%.cc [source_files]]]
190        [patsubst %0%.y %0%.yacc.lo [filter [prog]/%0%.y  [source_files]]]
191        [patsubst %0%.l  %0%.lex.lo [filter [prog]/%0%.l  [source_files]]]
192        ;
193    [prog_var]_libs = [project_short]/lib[project_short].la;
194    all += [arch]/bin/[prog_var];
195}
196
197integration-build-targets = ;
198integration-build-targets: [integration-build-targets];
199
200if [match %1C%2 [version]] then
201{
202    baseline = bl;
203}
204else
205{
206    /*
207     * this is essential so that aeipass does the right thing
208     *
209     * It also means that generated files (e.g. from objen) have consistent
210     * mod-times after integration, sop everythign does not immediately
211     * re-build.
212     */
213    set time-adjust-back;
214    all += integration-build-targets;
215}
216
217
218/*
219 * Note: this must come *after* the etc/autoconf.cook include.
220 */
221if [not [defined c++]] then
222    c++ = g++;
223cc_include_flags =
224    [prepost "-I" "" [search_list]]
225    [prepost "-I" /[arch] [search_list]]
226    ;
227if [not [defined c++_flags]] then
228    c++_flags = -O [debug];
229c++_flags = [c++_flags] -Wall -Wextra -Werror;
230if [not [defined ld_flags]] then
231    ld_flags = [debug];
232if [not [defined libs]] then
233    libs = ;
234
235cascade %0%.lo = %0%.o %0.libs/%.lo;
236
237[arch]/%0%.lo [arch]/%0%.o [arch]/%0.libs/%.o: %0%.cc [arch]/srecord/config.h
238{
239    function if_quiet Compile;
240
241    rm -f [arch]/%0%.lo [arch]/%0.libs/%.o [arch]/%0.libs/%.lo;
242    libtool [libtool-quiet] --mode\=compile
243    [c++] [c++_flags]
244        [defined-or-null %0%.cc_c++_flags]
245        [defined-or-null [dir %0%.cc]_c++_flags]
246        [cc_include_flags]
247        -c [resolve %0%.cc]
248        -o [target];
249    md5sum [arch]/%0%.o [arch]/%0.libs/%.o | sed "'s|^|# |'" >> [target];
250}
251
252
253c_incl = c_incl;
254
255%0%.h.d: %0%.h
256    set no-cascade
257{
258    function if_quiet Depends;
259    [c_incl] -nc -ns -nrec
260        [cc_include_flags]
261        [resolve %0%.h]
262        -prefix "'cascade %0%.h ='"
263        -suffix "';'"
264        -nsri
265        [prepost "-rlp=" "" [search_list]]
266        -slp [arch] "'[arch]'"
267        -o [target];
268}
269
270%0%.cc.d: %0%.cc
271        set no-cascade
272{
273    function if_quiet Depends;
274    [c_incl] -nc -ns -nrec
275        [cc_include_flags]
276        [resolve %0%.cc]
277        -prefix "'cascade %0%.cc ='"
278        -suffix "';'"
279        -nsri
280        [prepost "-rlp=" "" [search_list]]
281        -slp [arch] "'[arch]'"
282        -o [target];
283}
284
285cc_dep_files =
286        [fromto %0%.c %0%.c.d [match_mask %1/%0%.c [source_files]]]
287        [fromto %0%.h %0%.h.d [match_mask %1/%0%.h [source_files]]]
288        [fromto %0%.cc %0%.cc.d [match_mask %1/%0%.cc [source_files]]]
289        [fromto %0%.y %0%.gen.c.d [match_mask %1/%0%.y [source_files]]]
290        ;
291
292#include-cooked-nowarn [cc_dep_files]
293
294[arch]/bin/% [arch]/bin/.libs/%:
295    [addprefix [arch]/ [%_obj] [defined-or-null %_libs]]
296    set gate-first shallow /* tests need them */
297    if [defined %_obj]
298{
299    function if_quiet Link;
300
301    rm -f bin/.libs/lt-%;
302    libtool [libtool-quiet] --mode\=link
303    [c++] -o [target]
304        [cc_include_flags]
305        [ld_flags]
306        [resolve [addprefix [arch]/ [%_obj] [defined-or-null %_libs]]]
307        [libs]
308        ;
309
310    /*
311     * Libtool makes intermediate shell scripts.
312     * Make sure the fingerprint changes when it rebuilds,
313     * otherwise some tests get confused.
314     */
315    date "'+# %%c'" >> [target]
316        set silent;
317
318    /*
319     * libtool creates bin/% as a script, which, when executed, does the
320     * actual link.  But this link puts its results in bin/.libs, and
321     * that directory will not be writable for executables sourced from
322     * the baseline.  So we goose it into linking now, which would seem
323     * to defeat the purpose.
324     */
325    [target] --version > /dev/null;
326}
327
328[arch]/%/lib%.la [arch]/%/.libs/lib%.a [arch]/%/.libs/lib%.so:
329        [[target]_obj]
330    set unlink ingredients-fingerprint
331
332{
333    function if_quiet Link;
334
335    /*
336     * We include the "hidden" libtool output files because we need to
337     * fingerprint something that actually changes, and the .la file is
338     * pretty much static.
339     */
340    local version-info =
341        [collect aesub "'${project_specific aemakegen:version-info}'" ];
342    libtool [libtool-quiet] --mode\=link
343    [c++] [c++_flags]
344        -o [target]
345        [resolve [[target]_obj]]
346        [libs]
347        -version-info [version-info]
348
349        /*
350         * If you don't specify -rpath it doesn't make the shared library, even
351         * though the Debian people Really Don't Like Rpath.  We really really
352         * want the .so so we can check out version-info using the aede-policy
353         * soname.
354         */
355        -rpath /usr/local/bin
356        ;
357}
358
359[arch]/bin/%: [arch]/script/%.sh
360{
361    function if_quiet Copy;
362    cat [resolve [arch]/script/%.sh] > [target];
363    chmod a+rx [target];
364}
365
366all +=
367    [fromto script/%.sh.in [arch]/bin/%
368        [match_mask script/%.sh.in [source_files]]
369    ];
370
371
372/*
373 * How to build the release sets.
374 */
375#include-cooked etc/archive.cook
376
377/*
378 * How to build the documentation.
379 */
380#include-cooked etc/documentation.cook
381
382/*
383 * Explicit include dependencies.
384 */
385#if [count [cc_dep_files]]
386[cc_dep_files]: [arch]/srecord/config.h;
387#endif
388
389
390/*
391 * The version stamp is to be updated for every
392 * integration and development build.
393 * (The integrate_begin_command in the config file
394 * deletes them for integration builds.)
395 */
396
397srecord/patchlevel.h:
398    set shallow
399{
400    function if_quiet;
401
402    copyright_years =
403        [collect
404            aegis -list version -p [project] -c [change]
405            | [awk] "-F'[[\\\\]]'" "'/^copyright_years/{print $2}'"
406        ];
407    echo "'#define PATCHLEVEL \""[version]"\"'" > [target];
408    echo "'#define COPYRIGHT_YEARS \""[copyright_years]"\"'" >> [target];
409}
410
411/*
412 * Build the version include, but not too often.
413 */
414etc/version.so:
415    set ['if' [or [not [defined baseline] ] [not [exists bl/etc/version.so
416                ] ] ] 'then' shallow]
417{
418    function if_quiet;
419
420    copyright_years =
421        [collect
422            aegis -list version -p [project] -c [change]
423            | [awk] "-F'[[\\\\]]'" "'/^copyright_years/{print $2}'"
424        ];
425    echo "'.ds V) "[version]"'" > [target];
426    echo "'.ds v) "[version_short]"'" >> [target];
427    aegis -list version -p [project] -c [change]
428        | [awk] -F'\'"\'' "'/previous/{print $2}'"
429        | [awk] -F. "'{print \".ds w) \"$1\".\"$2}'"
430        >> [target];
431    echo "'.ds Y) "[copyright_years]"'" >> [target];
432}
433
434
435/*
436 * Catch 22: If the relationship between a target and a derived ingredient
437 * appears only in a derived cookbook, it is likely that a clean build
438 * (solely from primary source files) will fail.  It is recommended that
439 * relationships such as this be placed in a primary source cookbook.
440 */
441cascade etc/BUILDING.man = etc/version.so ;
442cascade etc/README.man = etc/version.so etc/new.so;
443cascade etc/change_log.man = etc/version.so etc/new.so;
444cascade etc/reference.man = etc/version.so ;
445cascade etc/srecord.lsm = etc/version.so ;
446cascade srecord/versn_stamp.cc = srecord/patchlevel.h ;
447cascade man/man1/z_copyright.so = etc/version.so ;
448
449#include [resolve etc/doxygen.cook etc/metrics.cook etc/tags.cook ]
450#include [resolve test_hyphen/module.cook ]
451
452/* vim: set ts=8 sw=4 et : */
453