Search code examples
autotoolsautomake

How to locate binaries during make check?


I'm having troubles running make check due to path issues. Currently my shell script (configured by autoconf) contains

prefix="@prefix@"
exec_prefix="@exec_prefix@"
PATH="@libexecdir@:$PATH"

it later expect to execute binary located in @libexecdir@. This works find after make install, but when it does not work is during make check. Because files are yet not installed, they are not at the expected location.

What is the correct solution to this? I must not be the first one to try to solve this...


Solution

  • To answer my own question, the correct thing to do is RTFM (as it usually is):

    Quote from (emphasis mine): https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/autoconf.html#Installation-Directory-Variables

    Most of these variables have values that rely on prefix or exec_prefix. It is deliberate that the directory output variables keep them unexpanded: typically ‘@datarootdir@’ is replaced by ‘${prefix}/share’, not ‘/usr/local/share’, and ‘@datadir@’ is replaced by ‘${datarootdir}’.

    This behavior is mandated by the GNU Coding Standards, so that when the user runs:

    ‘make’

    she can still specify a different prefix from the one specified to configure, in which case, if needed, the package should hard code dependencies corresponding to the make-specified prefix.

    ‘make install’

    she can specify a different installation location, in which case the package must still depend on the location which was compiled in (i.e., never recompile when ‘make install’ is run). This is an extremely important feature, as many people may decide to install all the files of a package grouped together, and then install links from the final locations to there.

    In order to support these features, it is essential that datarootdir remains defined as ‘${prefix}/share’, so that its value can be expanded based on the current value of prefix.

    A corollary is that you should not use these variables except in makefiles. For instance, instead of trying to evaluate datadir in configure and hard-coding it in makefiles using e.g., ‘AC_DEFINE_UNQUOTED([DATADIR], ["$datadir"], [Data directory.])’, you should add -DDATADIR='$(datadir)' to your makefile's definition of CPPFLAGS (AM_CPPFLAGS if you are also using Automake).

    Similarly, you should not rely on AC_CONFIG_FILES to replace bindir and friends in your shell scripts and other files; instead, let make manage their replacement. For instance Autoconf ships templates of its shell scripts ending with ‘.in’, and uses a makefile snippet similar to the following to build scripts like autoheader and autom4te:

     edit = sed \
             -e 's|@bindir[@]|$(bindir)|g' \
             -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' \
             -e 's|@prefix[@]|$(prefix)|g'
    
     autoheader autom4te: Makefile
             rm -f $@ $@.tmp
             srcdir=''; \
               test -f ./$@.in || srcdir=$(srcdir)/; \
               $(edit) $${srcdir}$@.in >$@.tmp
    
             chmod +x $@.tmp
             chmod a-w $@.tmp
             mv $@.tmp $@
    
     autoheader: $(srcdir)/autoheader.in
     autom4te: $(srcdir)/autom4te.in