1#---------------------------------------------------------------------------
2#
3# xc-am-iface.m4
4#
5# Copyright (c) 2013 Daniel Stenberg <daniel@haxx.se>
6#
7# Permission to use, copy, modify, and distribute this software for any
8# purpose with or without fee is hereby granted, provided that the above
9# copyright notice and this permission notice appear in all copies.
10#
11# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18#
19#---------------------------------------------------------------------------
20
21# serial 1
22
23
24dnl _XC_AUTOMAKE_BODY
25dnl -------------------------------------------------
26dnl Private macro.
27dnl
28dnl This macro performs embedding of automake initialization
29dnl code into configure script. When automake version 1.14 or
30dnl newer is used at configure script generation time, this
31dnl results in 'subdir-objects' automake option being used.
32dnl When using automake versions older than 1.14 this option
33dnl is not used when generating configure script.
34dnl
35dnl Existence of automake _AM_PROG_CC_C_O m4 private macro
36dnl is used to differentiate automake version 1.14 from older
37dnl ones which lack this macro.
38
39m4_define([_XC_AUTOMAKE_BODY],
40[dnl
41## --------------------------------------- ##
42##  Start of automake initialization code  ##
43## --------------------------------------- ##
44m4_ifdef([_AM_PROG_CC_C_O],
45[
46AM_INIT_AUTOMAKE([subdir-objects])
47],[
48AM_INIT_AUTOMAKE
49])dnl
50## ------------------------------------- ##
51##  End of automake initialization code  ##
52## ------------------------------------- ##
53dnl
54m4_define([$0], [])[]dnl
55])
56
57
58dnl XC_AUTOMAKE
59dnl -------------------------------------------------
60dnl Public macro.
61dnl
62dnl This macro embeds automake machinery into configure
63dnl script regardless of automake version used in order
64dnl to generate configure script.
65dnl
66dnl When using automake version 1.14 or newer, automake
67dnl initialization option 'subdir-objects' is used to
68dnl generate the configure script, otherwise this option
69dnl is not used.
70
71AC_DEFUN([XC_AUTOMAKE],
72[dnl
73AC_PREREQ([2.50])dnl
74dnl
75AC_BEFORE([$0],[AM_INIT_AUTOMAKE])dnl
76dnl
77_XC_AUTOMAKE_BODY
78dnl
79m4_ifdef([AM_INIT_AUTOMAKE],
80  [m4_undefine([AM_INIT_AUTOMAKE])])dnl
81dnl
82m4_define([$0], [])[]dnl
83])
84
85
86dnl _XC_AMEND_DISTCLEAN_BODY ([LIST-OF-SUBDIRS])
87dnl -------------------------------------------------
88dnl Private macro.
89dnl
90dnl This macro performs shell code embedding into
91dnl configure script in order to modify distclean
92dnl and maintainer-clean targets of makefiles which
93dnl are located in given list of subdirs.
94dnl
95dnl See XC_AMEND_DISTCLEAN comments for details.
96
97m4_define([_XC_AMEND_DISTCLEAN_BODY],
98[dnl
99## ---------------------------------- ##
100##  Start of distclean amending code  ##
101## ---------------------------------- ##
102
103for xc_subdir in [$1]
104do
105
106if test ! -f "$xc_subdir/Makefile"; then
107  echo "$xc_msg_err $xc_subdir/Makefile file not found. $xc_msg_abrt" >&2
108  exit 1
109fi
110
111# Fetch dependency tracking file list from Makefile include lines.
112
113xc_inc_lines=`grep '^include .*(DEPDIR)' "$xc_subdir/Makefile" 2>/dev/null`
114xc_cnt_words=`echo "$xc_inc_lines" | wc -w | tr -d "$xc_space$xc_tab"`
115
116# --disable-dependency-tracking might have been used, consequently
117# there is nothing to amend without a dependency tracking file list.
118
119if test $xc_cnt_words -gt 0; then
120
121AC_MSG_NOTICE([amending $xc_subdir/Makefile])
122
123# Build Makefile specific patch hunk.
124
125xc_p="$xc_subdir/xc_patch.tmp"
126
127xc_rm_depfiles=`echo "$xc_inc_lines" \
128  | $SED 's%include%	-rm -f%' 2>/dev/null`
129
130xc_dep_subdirs=`echo "$xc_inc_lines" \
131  | $SED 's%include[[ ]][[ ]]*%%' 2>/dev/null \
132  | $SED 's%(DEPDIR)/.*%(DEPDIR)%' 2>/dev/null \
133  | sort | uniq`
134
135echo "$xc_rm_depfiles" >$xc_p
136
137for xc_dep_dir in $xc_dep_subdirs; do
138  echo "${xc_tab}@xm_dep_cnt=\`ls $xc_dep_dir | wc -l 2>/dev/null\`; \\"            >>$xc_p
139  echo "${xc_tab}if test \$\$xm_dep_cnt -eq 0 && test -d $xc_dep_dir; then \\"      >>$xc_p
140  echo "${xc_tab}  rm -rf $xc_dep_dir; \\"                                          >>$xc_p
141  echo "${xc_tab}fi"                                                                >>$xc_p
142done
143
144# Build Makefile patching sed scripts.
145
146xc_s1="$xc_subdir/xc_script_1.tmp"
147xc_s2="$xc_subdir/xc_script_2.tmp"
148xc_s3="$xc_subdir/xc_script_3.tmp"
149
150cat >$xc_s1 <<\_EOT
151/^distclean[[ ]]*:/,/^[[^	]][[^	]]*:/{
152  s/^.*(DEPDIR)/___xc_depdir_line___/
153}
154/^maintainer-clean[[ ]]*:/,/^[[^	]][[^	]]*:/{
155  s/^.*(DEPDIR)/___xc_depdir_line___/
156}
157_EOT
158
159cat >$xc_s2 <<\_EOT
160/___xc_depdir_line___$/{
161  N
162  /___xc_depdir_line___$/D
163}
164_EOT
165
166cat >$xc_s3 <<_EOT
167/^___xc_depdir_line___/{
168  r $xc_p
169  d
170}
171_EOT
172
173# Apply patch to Makefile and cleanup.
174
175$SED -f "$xc_s1" "$xc_subdir/Makefile"      >"$xc_subdir/Makefile.tmp1"
176$SED -f "$xc_s2" "$xc_subdir/Makefile.tmp1" >"$xc_subdir/Makefile.tmp2"
177$SED -f "$xc_s3" "$xc_subdir/Makefile.tmp2" >"$xc_subdir/Makefile.tmp3"
178
179if test -f "$xc_subdir/Makefile.tmp3"; then
180  mv -f "$xc_subdir/Makefile.tmp3" "$xc_subdir/Makefile"
181fi
182
183test -f "$xc_subdir/Makefile.tmp1" && rm -f "$xc_subdir/Makefile.tmp1"
184test -f "$xc_subdir/Makefile.tmp2" && rm -f "$xc_subdir/Makefile.tmp2"
185test -f "$xc_subdir/Makefile.tmp3" && rm -f "$xc_subdir/Makefile.tmp3"
186
187test -f "$xc_p"  && rm -f "$xc_p"
188test -f "$xc_s1" && rm -f "$xc_s1"
189test -f "$xc_s2" && rm -f "$xc_s2"
190test -f "$xc_s3" && rm -f "$xc_s3"
191
192fi
193
194done
195
196## -------------------------------- ##
197##  End of distclean amending code  ##
198## -------------------------------- ##
199dnl
200m4_define([$0], [])[]dnl
201])
202
203
204dnl XC_AMEND_DISTCLEAN ([LIST-OF-SUBDIRS])
205dnl -------------------------------------------------
206dnl Public macro.
207dnl
208dnl This macro embeds shell code into configure script
209dnl that amends, at configure runtime, the distclean
210dnl and maintainer-clean targets of Makefiles located
211dnl in all subdirs given in the mandatory white-space
212dnl separated list argument.
213dnl
214dnl Embedding only takes place when using automake 1.14
215dnl or newer, otherwise amending code is not included
216dnl in generated configure script.
217dnl
218dnl distclean and maintainer-clean targets are modified
219dnl to avoid unconditional removal of dependency subdirs
220dnl which triggers distclean and maintainer-clean errors
221dnl when using automake 'subdir-objects' option along
222dnl with per-target objects and source files existing in
223dnl multiple subdirs used for different build targets.
224dnl
225dnl New behavior first removes each dependency tracking
226dnl file independently, and only removes each dependency
227dnl subdir when it finds out that it no longer holds any
228dnl dependency tracking file.
229dnl
230dnl When configure option --disable-dependency-tracking
231dnl is used no amending takes place given that there are
232dnl no dependency tracking files.
233
234AC_DEFUN([XC_AMEND_DISTCLEAN],
235[dnl
236AC_PREREQ([2.50])dnl
237dnl
238m4_ifdef([_AC_OUTPUT_MAIN_LOOP],
239  [m4_provide_if([_AC_OUTPUT_MAIN_LOOP], [],
240    [m4_fatal([call to AC_OUTPUT needed before $0])])])dnl
241dnl
242m4_if([$#], [1], [], [m4_fatal([$0: wrong number of arguments])])dnl
243m4_if([$1], [], [m4_fatal([$0: missing argument])])dnl
244dnl
245AC_REQUIRE([XC_CONFIGURE_PREAMBLE])dnl
246dnl
247m4_ifdef([_AM_PROG_CC_C_O],
248[
249_XC_AMEND_DISTCLEAN_BODY([$1])
250])dnl
251m4_define([$0], [])[]dnl
252])
253
254