On Fri, 5 Jun 2020 21:07:32 +1000 Peter Johansson wrote: > On 5/6/20 8:57 pm, Florian Weimer wrote: > > I would like to define macros containing the standard paths, like > > this: > > > > #define BINDIR "@bindir@" > > > > It does not work due to this code in lib/autoconf/general.m4 (which > > appears to be predate DESTDIR support): > > > > # Installation directory options. > > # These are left unexpanded so users can "make install exec_prefix=/foo" > > # and all the variables that are supposed to be based on exec_prefix > > # by default will actually change. > > # Use braces instead of parens because sh, perl, etc. also accept them. > > # (The list follows the same order as the GNU Coding Standards.) > > AC_SUBST([bindir], ['${exec_prefix}/bin'])dnl > > AC_SUBST([sbindir], ['${exec_prefix}/sbin'])dnl > > > > Is there are generally approved way to work around this? The manual > > tells us to use -D preprocessor arguments, but I'd prefer the > > explicitness of defining the macros via a header file. > > I have the following in my Makefile.am, which I believe I borrowed > from the manual of autoconf or automake. BUILT_SOURCES makes the > header file be created before any compilation and CLEANFILES makes > the header file be removed by 'make clean'. > > CLEANFILES += configmake.h > > BUILT_SOURCES += configmake.h > > configmake.h: Makefile > echo '#define BINDIR "$(bindir)"' >$@ The above is basically the example from Automake.info subsection "Built Sources Example". Note that the above will *NOT* rebuild if a different bindir value is given on the make command line like "make bindir=/foo/bin". Note also that the above *WILL* cause a rebuild of configmake.h and of everything depending on configmake.h every time Makefile has changed for any reason whatsoever, even if the content of configmake.h has not changed at all. AFAICT, those two issues discount it for Florian Weimer's use case. I have solved similar problems in the past with a dummy stamp file using Automake BUILD_SOURCES and cmp(1). I cannot remember where I picked up that idea, though. Sorry for bringing more Automake stuff to the autoconf list, but it should be possible to adapt the following approach to Autoconf-without-Automake buildsystems by basically adding install-paths.stamp at the beginning of the dependency list of the "all", "check", and "install" targets. If you want to see the following approach in an example package, you can git clone https://github.com/ndim/automake-install-paths-test.git and follow the example build commands in README.md. dnl configure.ac snippet AC_ARG_VAR([CMP], [cmp file compare program]) AC_PATH_PROG([CMP], [cmp], [false]) AS_IF([test "x$CMP" = "xfalse"], [AC_MSG_ERROR([CMP must be a cmp program])]) # Makefile.am snippet CLEANFILES += install-paths.h CLEANFILES += install-paths.stamp BUILT_SOURCES += install-paths.stamp install-paths.stamp: echo '/* Autogenerated file. Do not modify. */' > install-paths.h.tmp echo '#define BINDIR "$(bindir)"' >> install-paths.h.tmp @if test -f install-paths.h \ && $(CMP) install-paths.h.tmp install-paths.h; then \ echo "Not updating install-paths.h: it is up to date"; \ rm -f install-paths.h.tmp; \ else \ echo "Updating install-paths.h"; \ mv -f install-paths.h.tmp install-paths.h; \ fi This uses the bindir value which make actually uses, whether that value is defined in Makefile or given on the make command line. This also only updates the install-paths.h file if it has actually changed, whether that is because the value of bindir has changed or whether we have just added another foobardir to install-paths.h with another "echo" line. Unrelated changes to Makefile will not cause a rebuild of install-paths.h and thus everything depending on install-paths.h will not be rebuilt either. Disadvantage: This requires a "cmp" program at build time. If we were to ignore the absence of a "cmp" program, we would need to either never update the install-paths.h file (even if it would have changed) or always update the install-paths.h file (even if it has not changed). The former would work for single one-off builds where bindir does not change, the latter would always trigger a rebuild on "make install". So the existence of a file comparison program is imperative for this, and cmp(1) appears to be the tool for the job and can probably be considered a standard tool. If there is no cmp(1) available, one could try falling back onto diff(1) or system specific tools. Please keep in mind the Automake section on Built Sources for when install-paths.stamp target is built: "make all", "make check", and "make install" will all update install-paths.h *if it has changed* and thus trigger a rebuild for whatever depends on install-paths.h. If you want to trigger the install-paths.stamp target for executable or library targets, things will become more complicated very quickly. See also the discussion in the Automake.info subsection "Built Sources Example". Personally, I think the other methods generating a header file cause more headaches than the restriction to "make all", "make check", and "make install" causes. Calling the rule "install-paths.stamp" with a trailing ".stamp" might be considered a bit misleading as this stamp file target never generates an actual stamp file. This method of having a dummy BUILT_SOURCES stamp file updating an actual source file based on content with a cmp(1) comparison has served me very well during the last few years, but I am not certain how "generally accepted" this method is. Uli