On Feb 23, 2024, Jason Merrill <ja...@redhat.com> wrote:

> The problem, as you say, comes when you want to both bootstrap and
> build tools that aren't involved in the bootstrap process.

It's more visible there, because those don't actively refrain from
linking dynamically with libstdc++.  But even bootstrapped matter that
involves exceptions would have to link in libgcc_s, and that would bring
about the same sort of issue.

> To support that perhaps we want POSTBOOTSTRAP_HOST_EXPORTS for host
> modules without the bootstrap tag, and add the TARGET_LIB_PATH
> directories there?

That would be welcome, but it doesn't really address the problem, does
it?  Namely, the problem that we may face two different kinds of
scenarios, and each one calls for an opposite solution.

1. system tools used in the build depend on system libraries that are
newer than the ones we're about to build

This is the scenario that you're attempting to address with these
patches.  The problem here is that the libraries being built are older
than the system libraries, and and system tools won't run if dynamically
linked with the older libraries about to be built.

2. the libraries we're about to build are newer than corresponding
system libraries, if any

This is the scenario that the current build system aims for.  Any build
tools that rely on older system libraries are likely to work just as
well with the newly built libraries.  Any newly built libraries linked
into programs used and run as part of the build have to be present in
LD_LIBRARY_PATH lest we end up trying to use the older system libraries,
which may seem to work in some settings, but is bound to break if the
differences are large enough.


For maximum clarity, consider a bootstrap with LTO using a linker
plugin.  The linker plugin is built against the newly-built libraries.
The linker that attempts to load the plugin also requires the same
libraries.  Do you see how tending to 1. breaks 2., and vice-versa?


Now add ASAN to the picture, for another set of newly-built libraries
used during bootstrap.  Also use a prebuilt linker with ASAN enabled,
for maximum clarity of the problem I'm getting at.  Do you see the
problem?


Do you agree that patching the build system to solve a problem in
scenario 1. *will* cause problems in scenario 2., *unless* the fix can
distinguish the two scenarios and behave accordingly, but that getting
that right is triky and error prone?

Do you agree that, until we get there, it's probably better to optimize
for the more common scenario?

Do you agree that the more common scenario is probably 2.?

Do you agree that, until we get a solution that works for both 1. and 2.
automatically, offering a reasonably simple workaround for 1., while
aiming to work for 2., would be a desirable stopgap?

Do you agree that adding support for users to prepend directories to the
search path, enabling them to preempt build libraries with (symlinks
to?) select newer system libraries, and documenting situations in which
this could be needed, is a reasonably simple and desirable stopgap that
enables 1. to work while defaulting to the presumed more common case 2.?

Here's a patchlet that shows the crux of what I have in mind: (nevermind
we'd make the change elsewhere, document it further elsewhere, set an
empty default and arrange to passed down to sub-$(MAKE)s)

diff --git a/Makefile.in b/Makefile.in
index edb0c8a9a427f..10c7646ef98c4 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -771,7 +771,12 @@ TARGET_LIB_PATH_libatomic = 
$$r/$(TARGET_SUBDIR)/libatomic/.libs:
 
 # This is the list of directories that may be needed in RPATH_ENVVAR
 # so that programs built for the host machine work.
-HOST_LIB_PATH = 
$(HOST_LIB_PATH_gmp)$(HOST_LIB_PATH_mpfr)$(HOST_LIB_PATH_mpc)$(HOST_LIB_PATH_isl)
+# Users may set PREEMPT_HOST_LIB_PATH to a directory holding symlinks
+# to system libraries required by build tools (say the linker) that
+# are newer (as in higher-versioned) than the corresponding libraries
+# we're building.  If older libraries were to override the newer
+# system libraries, that could prevent the build tools from running.
+HOST_LIB_PATH = 
$(PREEMPT_HOST_LIB_PATH):$(HOST_LIB_PATH_gmp)$(HOST_LIB_PATH_mpfr)$(HOST_LIB_PATH_mpc)$(HOST_LIB_PATH_isl)
 
 # Define HOST_LIB_PATH_gcc here, for the sake of TARGET_LIB_PATH, ouch
 @if gcc


Now, for a more general solution that doesn't require user intervention,
configure could go about looking for system libraries in the default
search path, or in RPATH_ENV_VAR, that share the soname with those we're
about to build, identify preexisting libraries that are newer than those
we're about to build, populate a build-tree directory with symlinks to
them, and default PREEMPT_HOST_LIB_PATH to that directory.

WDYT?


-- 
Alexandre Oliva, happy hacker            https://FSFLA.org/blogs/lxo/
   Free Software Activist                   GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity
Excluding neuro-others for not behaving ""normal"" is *not* inclusive

Reply via email to