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