autotest.mk: Fix dependency distribution corner case.
[dxcommon.git] / m4 / gnulib-shared.m4
blob4d2e2731b1f69c4740bd0e640657b6a52c6c5a9e
1 dnl Copyright © 2022-2024 Nick Bowler
2 dnl
3 dnl Hack to reduce glsym transformations to a subset of gnulib sources.
4 dnl
5 dnl License WTFPL2: Do What The Fuck You Want To Public License, version 2.
6 dnl This is free software: you are free to do what the fuck you want to.
7 dnl There is NO WARRANTY, to the extent permitted by law.
9 dnl DX_GNULIB_SYMFILES(filename, [shortname])
10 dnl
11 dnl When using the glconfig symbol-renaming functionality to include gnulib
12 dnl components in a library, it may not be the case that every file is actually
13 dnl used by the library.  In this situation, applying the symbol renaming to
14 dnl every file unconditionally just makes the build take longer for no reason.
15 dnl
16 dnl Using this macro reduces the files processed for renaming to only those
17 dnl source files listed in the specified file, with one source file per line.
18 dnl This file should list every source file that could possibly be included
19 dnl into the library -- one way to generate such a list is by using gnulib-tool
20 dnl on a subset of modules.
21 dnl
22 dnl As the list depends on the results of configure, this works by installing a
23 dnl config.status hook to patch the gnulib_symfiles assignment in the Makefile
24 dnl based on the actually-enabled gnulib objects.
25 dnl
26 dnl The list of leftover objects which are not subject to symbol renaming is
27 dnl then placed in the gnulib_extra_objects make variable.  If shortname is
28 dnl nonempty, these object file names will be prefixed with the specified
29 dnl value followed by a hyphen (to match up with Automake's object file
30 dnl renaming system).
31 AC_DEFUN_ONCE([DX_GNULIB_SYMFILES],
32 [AC_REQUIRE([DX_PROG_JOIN])dnl
33 CONFIGURE_DEPENDENCIES=${CONFIGURE_DEPENDENCIES:+" "}'${top_srcdir}/$1'
34 AC_SUBST([CONFIGURE_DEPENDENCIES])dnl
35 AC_CONFIG_COMMANDS([gnulib-symfiles],
36 [for gl_f in $CONFIG_FILES
38   # Restrict processing to only Automake-generated makefiles.
39   gl_save_IFS=$IFS
40   IFS=:; set x $gl_f
41   gl_of=$[2]; gl_am=$gl_of.am # TODO fully handle user-specified input files
42   IFS=$gl_save_IFS
43   test -f "$gl_am" || test -f "$srcdir/$gl_am" || continue
44   $MAKE -f - glconfig-objects GLCONFIG_OBJECTS="$ac_tmp/gl_objs.lst" \
45     <"$gl_of" >/dev/null 2>&1 && test -f "$ac_tmp/gl_objs.lst" || continue
46   sed 's|[[.][^/.]*$]| &|' "$ac_tmp/gl_objs.lst" | LC_ALL=C sort -u \
47     >"$ac_tmp/gl_syms.1"
48   LC_ALL=C sort -u >"$ac_tmp/gl_syms.2" <<'EOF'
49 dnl hide this include from traces so that aclocal doesn't find it.
50 dnl The required details for rebuild rules are handled by substituting
51 dnl CONFIGURE_DEPENDENCIES above.
52 m4_bpatsubst(m4_indir([m4_include], [$1]), [[.][^/.]*$], [ x])
53 EOF
54   $JOIN -a1 "$ac_tmp/gl_syms.1" "$ac_tmp/gl_syms.2" >"$ac_tmp/gl_syms.3"
55   # Now replace default gnulib_symfiles assignment with the computed list
56   $AWK '$[1] "/" $[2] "/" $[3] == "gnulib_symfiles/=/$(gnulib_all_symfiles)" {
57     objlst = symlst = "";
58     while ((rc = getline < f) > 0) {
59       if ($[3] == "x") {
60         symlst = symlst " " $[1] ".glsym";
61       } else {
62         m4_ifnblank([$2], [sub(/[[^\/]]*$/, "$2-&", $[1]);
63         ])objlst = objlst " " $[1] $[2];
64       }
65     }
67     if (rc < 0)
68       exit 1;
70     print "gnulib_symfiles =" symlst;
71     print "gnulib_extra_objects =" objlst;
72     next;
73   }
74   # add ourself to Automake-generated rebuild rules
75   $[2] == "=" && $[1] ~ /^am__(depfiles_maybe|maybe_remake_depfiles)$/ {
76     for (i = 3; i <= NF; i++)
77       if ($i == "gnulib-symfiles")
78         break;
79     $i = "gnulib-symfiles";
80   }
81   { print; }' f="$ac_tmp/gl_syms.3" "$gl_of" >"$ac_tmp/gl_tmp.mk"
82   mv -f "$ac_tmp/gl_tmp.mk" "$gl_of"
83   break # should be max one makefile needing patching
84 done], [: "\${MAKE=${MAKE-make}}" "\${JOIN=$JOIN}"])])