bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Makefile: avoid undefined variables


From: Martin D Kealey
Subject: Re: [PATCH] Makefile: avoid undefined variables
Date: Fri, 25 Oct 2024 22:44:56 +1000

On Fri, 25 Oct 2024 at 05:07, Grisha Levit <grishalevit@gmail.com> wrote:

> These are reported by make --warn-undefined-variables.
>
> Most were being set previously (sometimes 20 years ago) and got left
> behind in recepies after their definitions have been removed. Others
> only get set in some configurations so it makes sense to prevent them
> from inheriting stray values from the environment otherwise. A few are
> just typos.
>

I've been looking at the Makefiles as well, and I find I have a lot of
questions, like:

   1. What is the point of ‘$(BUILD_DIR)’?
   When is it not simply ‘$$PWD’ or ‘.’ (prefaced by one or more ‘../’ when
   in a subdirectory)?
   2. Do any of the following *ever* change?
   dot = .
   DEFDIR = builtins
   LIBBUILD = lib
   GLOB_LIBDIR = lib/glob
   INTL_LIBDIR = lib/intl
   ALLOC_LIBDIR = lib/malloc
   RL_LIBDIR = lib/readline
   HIST_LIBDIR = lib/readline *(again)*
   SH_LIBDIR = lib/sh
   TERM_LIBDIR = lib/termcap
   TILDE_LIBDIR = lib/tilde
   3. Are any of these *ever* used?
   ALLOC_ABSSRC = ${topdir}/$(ALLOC_LIBDIR)
   BASE_CFLAGS_FOR_BUILD = @BASE_CFLAGS_FOR_BUILD@
   BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
   BUILTIN_ABSSRC = ${topdir}/builtins
   DEBUGGER_DIR = debugger
   DOCSRC = $(srcdir)/doc
   EXTRASOURCES = *(a long list)*
   GCC_LINT_CFLAGS = $(BASE_CCFLAGS) $(CPPFLAGS) $(GCC_LINT_FLAGS)
   GLOB_ABSSRC = ${topdir}/$(GLOB_LIBDIR)
   GLOB_OBJ = *(a long list)*
   HISTORY_OBJ = *(a long list)*
   HIST_ABSSRC = ${topdir}/$(HIST_LIBDIR)
   HIST_INCLUDEDIR = @HIST_INCLUDEDIR@
   INTLLIBS = @INTLLIBS@
   INTLOBJS = @INTLOBJS@
   INTL_ABSSRC = ${topdir}/$(INTL_LIB)
   LIBINTL = @LIBINTL@
   LTLIBINTL = @LTLIBINTL@
   MALLOC = @MALLOC@
   OTHERS = *(a list)*
   PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
   PACKAGE_NAME = @PACKAGE_NAME@
   PACKAGE_STRING = @PACKAGE_STRING@
   PACKAGE_TARNAME = @PACKAGE_TARNAME@
   PO_SRC = $(srcdir)/po/
   PSIZE_SOURCE    = *(a long list)*
   READLINE_OBJ    = *(a long list)*
   RELOCATABLE_DEFS = -DENABLE_RELOCATABLE=1 -DIN_LIBRARY \
   RL_ABSSRC = ${topdir}/$(RL_LIBDIR)
   RL_INCLUDEDIR = @RL_INCLUDEDIR@
   RL_LIBDOC = $(RL_LIBSRC)/doc
   SH_ABSSRC = ${topdir}/${SH_LIBSRC}
   SIGNAMES_SUPPORT = $(SUPPORT_SRC)mksignames.c
   SRC = *(a short list)*
   SRC1 =  man2html.c
   STATIC_SOURCE   = *(a long list)*
   STUB_SOURCE = stub.c
   SUBDIR_INCLUDES = -I. @RL_INCLUDE@ -I$(topdir) -I$(topdir)/$(LIBSUBDIR)
   TERMCAP_LDFLAGS = -L$(TERM_LIBDIR)
   TERMCAP_OBJ     = $(TERM_LIBDIR)/termcap.o \
   TERM_ABSSRC = ${topdir}/$(TERM_LIBDIR)
   TEX         = tex
   TEXINDEX    = texindex
   TILDE_ABSSRC = ${topdir}/$(TILDE_LIBDIR)
   TILDE_OBJ       = $(TILDE_LIBDIR)/tilde.o
   USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
   datarootdir = @datarootdir@
   host_cpu = @host_cpu@
   host_vendor = @host_vendor@
   l = @INTL_LIBTOOL_SUFFIX_PREFIX@
   transform = @program_transform_name@


I think I may have identified some issues as well.

Firstly, almost all targets are simply given as a path relative to the
current directory (which is fine) but where they're noted as dependencies,
they're often prefaced by some ‘$(FOOLIB)/’.

I'm guessing that the idea was that you could link with a different version
of the library outside the build tree (and outside the source tree), but is
that actually used anywhere?
If it *is* used, I'd ideally like to see all the variables that reference
build directories have trailing slashes, unless they're completely empty
(meaning the current directory). This would probably need some adjustment
to the ‘configure’ script, or to autoconf.

Otherwise I'd rather just hard-code them as relative paths; I have a patch
to that effect if you're interested.

I'm seeing weird errors where generated dependencies wind up including both
'./foo.h' and 'foo.h' separately. Having the wrong one is a problem when
foo.h is actually a generated file, in which case the addition or removal
of './' can thwart the rule intended to build it, or even cause ‘make’ to
abort due to the absence of a stated prerequisite that has no rule.
(Depending on the version of Make, it may or may not normalize file paths.)

Secondly, where targets are built by running a command in another
directory, that secondary build process can inherit paths that no longer
point to the correct place.

If we could be sure that the variables are always relative, then it would
be simple enough to preface them with ‘../’, like this:

   - cd $(@D) && $(MAKE) BUILD_DIR=../$(BUILD_DIR) $(MAKEFLAGS) $(@F)


However if they could be absolute paths, that would clearly be thwarted.

The tricky part is that this may or may not affect variables that point to
the source, depending on how ‘configure’ was invoked:

   - when run in the source tree as ‘./configure’ it sets ‘BUILD_DIR=.’
   (which I would like to see changed to ‘./’ or empty);
   - when run as ‘../bash-source/configure’ it sets
   ‘BUILD_DIR=../bash-source’
   - when run as ‘/home/me/src/bash/configure’ it sets
   ‘BUILD_DIR=/home/me/src/bash’


It might be tempting to thing "always use absolute paths", but that causes
its own problems:

   - it won't work in a sandpit where the current user does not have
   permission to reach $PWD from ‘/’;
   - some of the paths wind up being embedded in the resulting executable,
   and they may contain sensitive information such as a personal username or
   home directory;

So I would like to take the opposite approach: make *maximal* use of
relative paths, and in addition, set either

   - ‘UP=../’ and ‘UPSRC=../’ when running ‘./configure’ or
   ‘../src/configure’; or
   - ‘UP=../’ and ‘UPSRC=’ (empty) when running ‘/path/to/configure’; or
   - ‘UP=’ and ‘UPSRC=’ (both empty) when doing something weird with
   BUILD_DIR

so that

   - cd $(@D) && $(MAKE) BUILD_DIR=$(UP)$(BUILD_DIR)
   top_srcdir=$(UPSRC)$(top_srcdir) $(MAKEFLAGS) $(@F)

will correctly set BUILD_DIR and TOPDIR


-Martin


reply via email to

[Prev in Thread] Current Thread [Next in Thread]