4 # Rewrite a gnulib.mk, adding prefixes to work with automake's subdir-objects.
6 # Copyright (C) 2012-2020 Free Software Foundation, Inc.
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <https://www.gnu.org/licenses/>.
21 # Written by Jim Meyering
23 # This is a prologue that allows to run a perl script as an executable
24 # on systems that are compliant to a POSIX version before POSIX:2017.
25 # On such systems, the usual invocation of an executable through execlp()
26 # or execvp() fails with ENOEXEC if it is a script that does not start
27 # with a #! line. The script interpreter mentioned in the #! line has
28 # to be /bin/sh, because on GuixSD systems that is the only program that
29 # has a fixed file name. The second line is essential for perl and is
30 # also useful for editing this file in Emacs. The next two lines below
31 # are valid code in both sh and perl. When executed by sh, they re-execute
32 # the script through the perl program found in $PATH. The '-x' option
33 # is essential as well; without it, perl would re-execute the script
34 # through /bin/sh. When executed by perl, the next two lines are a no-op.
35 eval 'exec perl -wSx "$0" "$@"'
38 my
$VERSION = '2020-04-04 15:07'; # UTC
39 # The definition above must lie within the first 8 lines in order
40 # for the Emacs time-stamp write hook (at end) to update it.
41 # If you change this file with Emacs, please let the write hook
42 # do its job. Otherwise, update this string manually.
47 use File
::Basename
; # for dirname
49 (my
$ME = $0) =~ s|.
*/||
;
57 my
$STREAM = ($exit_code == 0 ?
*STDOUT
: *STDERR
);
60 print
$STREAM "Try '$ME --help' for more information.\n";
65 Usage: $ME --lib-name=NAME FILE
66 or: $ME [--help|--version]
67 Rewrite a gnulib-tool-generated FILE like lib/gnulib.mk to work with
68 automake's subdir-objects.
72 This option must be specified:
74 --lib-name=NAME library name, often "lib\$project"
76 The following are optional:
78 --help display this help and exit
79 --version output version information and exit
86 # contents ($FILE_NAME)
87 # ---------------------
91 local $
/; # Turn on slurp-mode.
92 my
$f = new IO
::File
"< $file" or die
"$file";
93 my
$contents = $f->getline or die
"$file";
100 # Do not prefix special words such as variable dereferences. Also,
101 # "Makefile" is really "Makefile", since precisely there is no
107 unless
(/^
-/ || m
{^\$\
(\w
+\
)} ||
$_ eq
"Makefile" ||
$_ eq
'\\'
108 ||
$_ eq
'@ALLOCA@');
113 # prefix_words ($TEXT)
114 # --------------------
118 s
{(\S
+)}{prefix_word
($1)}gem
;
123 # prefix_assignment ($LHS-AND-ASSIGN-OP, $RHS)
124 # --------------------------------------------
125 sub prefix_assignment
($$
)
127 my
($lhs_and_assign_op, $rhs) = @_
;
129 # Some variables are initialized by gnulib.mk, and we don't want
130 # that. Change '=' to '+='.
131 if ($lhs_and_assign_op =~
/^
(GPERF|V_GPERF.
*) =$
/)
133 # Do not change the RHS, which specifies the GPERF program.
135 # Don't change variables such as HAVE_INCLUDE_NEXT.
136 elsif
($lhs_and_assign_op =~
/^HAVE_
/)
139 elsif
($lhs_and_assign_op =~
140 /^
(SUBDIRS|EXTRA_DIST|BUILT_SOURCES|SUFFIXES|MOSTLYCLEANFILES
141 |CLEANFILES|DISTCLEANFILES|MAINTAINERCLEANFILES
142 |AM_GNU_GETTEXT
)\
=/x
)
144 $lhs_and_assign_op =~ s
/=/+=/;
146 # We don't want things such as AM_CPPFLAGS +=
147 # -DDEFAULT_TEXT_DOMAIN=\"bison-gnulib\" to apply to the whole
148 # Makefile.in: scope it to the library: libbison_a_CPPFLAGS =
149 # $(AM_CPPFLAGS) -DDEFAULT_TEXT_DOMAIN=\"bison-gnulib\".
150 elsif
($lhs_and_assign_op =~
151 /^
(AM_CFLAGS|AM_CPPFLAGS
)\ \
+?
=/x
)
153 $lhs_and_assign_op =~ s
/^AM_
(\w
+)\ \
+?
=/${lib_name}_a_
$1 =/;
154 $rhs = " \$(AM_$1)$rhs";
156 # We don't want to inherit gnulib's AUTOMAKE_OPTIONS, comment them.
157 elsif
($lhs_and_assign_op =~
/^AUTOMAKE_OPTIONS
=/)
159 $lhs_and_assign_op =~ s
/^
/# /;
161 # Elide any SUFFIXES assignment or concatenation.
162 elsif
($lhs_and_assign_op =~
/^SUFFIXES
/)
164 $lhs_and_assign_op =~ s
/^
/# /;
166 # The words are (probably) paths to files in lib/: prefix them.
169 $rhs = prefix_words
($rhs)
172 # Variables whose name depend on the location: libbison_a_SOURCES =>
173 # lib_libbison_a_SOURCES.
174 $lhs_and_assign_op =~ s
/($lib_name)/lib_
$1/g
;
176 $lhs_and_assign_op .
$rhs;
181 # $CONTENTS is a Makefile content. Post-process it so that each file-name
182 # is prefixed with $prefix (e.g., "lib/").
184 # Relies heavily on the regularity of the file generated by gnulib-tool.
190 # Prefix all the occurrence of files in rules. If there is nothing
191 # after in the :, it's probably a phony target, or a suffix rule.
193 s
{^
([-\w
+/]+\.
[-\w.
]+ *: *\S.
*)$
}
194 {prefix_words
($1)}gem
;
196 # Prefix files in variables.
197 s
{^
([\w.
]+\s
*\
+?
=)(.
*)$
}
198 {prefix_assignment
($1, $2)}gem
;
200 # $(srcdir)/ is actually $(top_srcdir)/$prefix/.
201 # The trailing slash is required to avoid matching this rule:
202 # test '$(srcdir)' = . || rm -f $(top_builddir)/GNUmakefile
203 s
{\$\
(srcdir\
)/}{\$
(top_srcdir
)/$prefix}g
;
205 # Sometimes, t-$@ is used instead of $@-t, which, of course, does
206 # not work when we have a $@ with a directory in it.
209 # Some AC_SUBST patterns remain and would better be Make macros.
210 s
{\@
(MKDIR_P
)\@
}{\$
($1)}g
;
212 # Adjust paths in mkdir.
213 s
{(\$\
(MKDIR_P\
))\s
*(\w
+)}{$1 $prefix$2}g
;
223 my
($bak) = "$file.bak";
224 rename
($file, $bak) or die
"$ME: rename $file $bak failed: $!\n";
225 my
$contents = contents
($bak);
226 $contents = prefix
($contents);
227 my
$out = new IO
::File
(">$file")
228 or die
"$ME: $file: failed to open for writing: $!\n";
229 print
$out $contents;
235 'lib-name=s' => \
$lib_name,
236 help => sub
{ usage
0 },
237 version
=> sub
{ print
"$ME version $VERSION\n"; exit },
242 or
(warn
"$ME: no library name; use --lib-name=NAME\n"), $fail = 1;
244 # There must be exactly one argument.
246 and
(warn
"$ME: missing FILE argument\n"), $fail = 1;
248 and
(warn
"$ME: too many arguments:\n", join ("\n", @ARGV
), "\n"),
254 $prefix = (dirname $file) .
'/';
255 warn
"prefix=$prefix\n";
260 ### Setup "GNU" style for perl-mode and cperl-mode.
262 ## perl-indent-level: 2
263 ## perl-continued-statement-offset: 2
264 ## perl-continued-brace-offset: 0
265 ## perl-brace-offset: 0
266 ## perl-brace-imaginary-offset: 0
267 ## perl-label-offset: -2
268 ## cperl-indent-level: 2
269 ## cperl-brace-offset: 0
270 ## cperl-continued-brace-offset: 0
271 ## cperl-label-offset: -2
272 ## cperl-extra-newline-before-brace: t
273 ## cperl-merge-trailing-else: nil
274 ## cperl-continued-statement-offset: 2
275 ## eval: (add-hook 'before-save-hook 'time-stamp)
276 ## time-stamp-line-limit: 50
277 ## time-stamp-start: "my $VERSION = '"
278 ## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
279 ## time-stamp-time-zone: "UTC0"
280 ## time-stamp-end: "'; # UTC"