Bug 103866 - AM_PROG_LIBTOOL not compatible with GCC_NO_EXECUTABLES
Summary: AM_PROG_LIBTOOL not compatible with GCC_NO_EXECUTABLES
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 12.0
: P3 normal
Target Milestone: 12.0
Assignee: Not yet assigned to anyone
URL:
Keywords: build
Depends on:
Blocks:
 
Reported: 2021-12-30 11:04 UTC by Jonathan Wakely
Modified: 2022-08-17 18:57 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-12-30 00:00:00


Attachments
libstdc++: Fix freestanding build using --without-headers (1.53 KB, patch)
2021-12-31 19:01 UTC, Jonathan Wakely
Details | Diff
libstdc++: Fix and simplify freestanding configuration [PR103866] (2.33 KB, patch)
2022-01-06 21:16 UTC, Jonathan Wakely
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2021-12-30 11:04:00 UTC
The libtool setup in the top-level libtool.m4 has this snippet in LT_SYS_DLOPEN_SELF:

  *)
    AC_CHECK_FUNC([shl_load],
	  [lt_cv_dlopen="shl_load"],
      [AC_CHECK_LIB([dld], [shl_load],
	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
	[AC_CHECK_FUNC([dlopen],
	      [lt_cv_dlopen="dlopen"],
	  [AC_CHECK_LIB([dl], [dlopen],
		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
	    [AC_CHECK_LIB([svld], [dlopen],
		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
	      [AC_CHECK_LIB([dld], [dld_link],
		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
	      ])
	    ])
	  ])
	])
      ])
    ;;

This can fail if GCC_NO_EXECUTABLES has been used, e.g. for a mips-none-elf cross-compiler (see Bug 100057 comment 33, but ignore all the other comments there).

It looks like --disable-dlopen will avoid that snippet, but should that be necessary if --disable-shared has been used? If it can't depend on --disable-shared, is there some other flag we can use to infer that the user doesn't want/need those checks for a bare metal build?
Comment 1 Jonathan Wakely 2021-12-30 11:20:59 UTC
libstdc++-v3/configure.ac has:

# Libtool setup.
if test "x${with_newlib}" != "xyes" && test "x${with_avrlibc}" != "xyes"; then
  AC_LIBTOOL_DLOPEN
fi
AM_PROG_LIBTOOL
ACX_LT_HOST_FLAGS
AC_SUBST(enable_shared)
AC_SUBST(enable_static)


Since I actively avoid understanding what libtool actually does I have no idea if/when we can make that AM_PROG_LIBTOOL conditional. Libstdc++ doesn't use dlopen, so maybe we can just add --disable-dlopen. Or maybe --disable-shared should imply --disable-dlopen.
Comment 2 Andrew Pinski 2021-12-30 11:34:59 UTC
(In reply to Jonathan Wakely from comment #1)
> libstdc++-v3/configure.ac has:
> 
> # Libtool setup.
> if test "x${with_newlib}" != "xyes" && test "x${with_avrlibc}" != "xyes";
> then
>   AC_LIBTOOL_DLOPEN
> fi
> AM_PROG_LIBTOOL
> ACX_LT_HOST_FLAGS
> AC_SUBST(enable_shared)
> AC_SUBST(enable_static)
> 
> 
> Since I actively avoid understanding what libtool actually does I have no
> idea if/when we can make that AM_PROG_LIBTOOL conditional. Libstdc++ doesn't
> use dlopen, so maybe we can just add --disable-dlopen. Or maybe
> --disable-shared should imply --disable-dlopen.

I think even after that, cross compile will still fail because GLIBCXX_CROSSCONFIG will do this:
    AC_MSG_ERROR([No support for this host/target combination.])

Which means that might need to be patched checking hosted_libstdcxx before printing out that error message.

Or the person could do --with-newlib and bypass GLIBCXX_CROSSCONFIG .
Comment 3 Jonathan Wakely 2021-12-30 12:01:36 UTC
More generally, it would be good if --with-newlib wasn't needed as a kluge to mean "no libc" as well as "libc is newlib". It's surprising to users that --without-headers doesn't mean "no libc", but --with-newlib does (when the obvious expectation is that --with-newlib means you're using newlib as libc!)

Maybe --disable-hosted-libstdcxx should imply --with-newlib and --disable-dlopen and whatever other options are needed to do this properly, so you don't need to know the right undocumented combination.
Comment 4 Jonathan Wakely 2021-12-30 12:06:19 UTC
--disable-dlopen doesn't help anyway, we still get:

checking whether the /home/jwakely/build-mips-elf/gcc/./gcc/xgcc -B/home/jwakely/build-mips-elf/gcc/./gcc/ -B/home/jwakely/gcc/mips-elf/mipsel-none-elf/bin/ -B/home/jwakely/gcc/mips-elf/mipsel-none-elf/lib/ -isystem /home/jwakely/gcc/mips-elf/mipsel-none-elf/include -isystem /home/jwakely/gcc/mips-elf/mipsel-none-elf/sys-include    linker (/home/jwakely/build-mips-elf/gcc/./gcc/collect-ld) supports shared libraries... yes
checking dynamic linker characteristics... no
checking how to hardcode library paths into programs... immediate
checking for shl_load... configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES.
make[1]: *** [configure-target-libstdc++-v3] Error 1
Comment 5 Jonathan Wakely 2021-12-30 12:11:03 UTC
Ugh, it doesn't work because of this:

if test "x${with_newlib}" != "xyes" && test "x${with_avrlibc}" != "xyes"; then
  AC_LIBTOOL_DLOPEN
fi

where AC_LIBTOOL_DLOPEN expands to enable_dlopen=yes which overrides --disable-dlopen. So you really do need --with-newlib for bare metal.
Comment 6 Nicolas Noble 2021-12-30 18:08:13 UTC
While a bit tangential from the narrow topic of this bug, it may be noteworthy that I just tried using the --with-newlib kludge here, and compilation still fails, with something new:

checking for the value of EOF... configure: error: computing EOF failed


Checking the logs, this fails because it can't find stdio.h. Meaning the --with-newlib kludge isn't an actually valid method towards actual bare metal, and needs something a bit more fleshed out?



My compilation lines (from a clean ubuntu:latest docker image)

apt update
apt -y install wget build-essential libgmp-dev libmpfr-dev libmpc-dev

wget https://ftp.gnu.org/gnu/binutils/binutils-2.37.tar.gz
tar xvfz binutils-2.37.tar.gz
cd binutils-2.37
./configure --target=mipsel-none-elf --disable-multilib --disable-nls --disable-werror
make -j8
make install-strip
cd ..

wget https://ftp.gnu.org/gnu/gcc/gcc-11.2.0/gcc-11.2.0.tar.gz
tar xvfz gcc-11.2.0.tar.gz
cd gcc-11.2.0
mkdir build
cd build
../configure --target=mipsel-none-elf --without-isl --disable-nls --disable-threads --disable-shared --disable-libssp --disable-libstdcxx-pch --disable-libgomp --disable-werror --without-headers --with-as=/usr/local/bin/mipsel-none-elf-as --with-ld=/usr/local/bin/mipsel-none-elf-ld --enable-languages=c,c++ --with-newlib --disable-hosted-libstdcxx --disable-bootstrap
make all-gcc -j8
make install-strip-gcc
make all-target-libgcc -j8
make install-strip-target-libgcc
make all-target-libstdc++-v3
Comment 7 Jonathan Wakely 2021-12-30 19:05:00 UTC
(In reply to Nicolas Noble from comment #6)
> While a bit tangential from the narrow topic of this bug, it may be
> noteworthy that I just tried using the --with-newlib kludge here, and
> compilation still fails, with something new:
> 
> checking for the value of EOF... configure: error: computing EOF failed



Yes, I have a simple patch for that.


> 
> Checking the logs, this fails because it can't find stdio.h. Meaning the
> --with-newlib kludge isn't an actually valid method towards actual bare
> metal, and needs something a bit more fleshed out?


Yes, and even with that fixed, more checks for $is_hosted are needed for stdint.h types. I have a patch for that too, but I'm not happy with it yet.

The same problems with stdio.h are listed in the other bug, but the fixes suggested there are completely wrong, and the abuse is completely unacceptable.
Comment 8 Nicolas Noble 2021-12-30 21:01:24 UTC
> Yes, and even with that fixed, more checks for $is_hosted are needed for
> stdint.h types. I have a patch for that too, but I'm not happy with it yet.

I'm willing to test out patches if you need. In fact, since I'm trying to push a bare metal mips compiler out, I'm happy to host some patches with the scripts too while they're not yet merged upstream. See https://github.com/grumpycoders/pcsx-redux/tree/main/tools where I'm hosting the spawning scripts for various platforms. My target is the r3000 mips CPU that's present in the PlayStation 1.

> The same problems with stdio.h are listed in the other bug, but the fixes
> suggested there are completely wrong, and the abuse is completely
> unacceptable.

That's fair, and hopefully I'm not pushing out the same abusive behavior, but let me know if you need some space.
Comment 9 Jonathan Wakely 2021-12-31 18:58:03 UTC
GCC_HEADER_STDINT is unusable for freestanding, because it uses autoconf's AC_CHECK_SIZEOF with the default includes, which does #include <stdio.h> unconditionally.

But we only use GCC_HEADER_STDINT to create include/gstdint.h which is only needed by src/c++11/compatibility-atomic-c++0x.cc, which could just use <stdint.h> instead.

For now we can just make the use of GCC_HEADER_STDINT depend on $is_hosted, but I think we should just remove it eventually.
Comment 10 Jonathan Wakely 2021-12-31 19:01:00 UTC
Created attachment 52104 [details]
libstdc++: Fix freestanding build using --without-headers
Comment 11 Jonathan Wakely 2022-01-06 21:16:12 UTC
Created attachment 52137 [details]
libstdc++: Fix and simplify freestanding configuration [PR103866]

Updated patch that supports:

/home/jwakely/src/gcc/configure --target=mipsel-none-elf --disable-nls --disable-threads --disable-shared --disable-libstdcxx-pch --disable-werror --without-headers --disable-hosted-libstdcxx
make all-gcc all-target-libstdc++-v3

i.e. no --with-newlib required to trick libstdc++ into skipping the configure checks for various libc features.
Comment 12 GCC Commits 2022-01-10 12:18:42 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:68c2e9e9234cb301e9e81792cad233a41e797792

commit r12-6409-g68c2e9e9234cb301e9e81792cad233a41e797792
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Jan 6 13:54:53 2022 +0000

    libstdc++: Fix and simplify freestanding configuration [PR103866]
    
    This fixes the --disable-hosted-libstdcxx build so that it works with
    --without-headers. Currently you need to also use --with-newlib, which
    is confusing for users who aren't actually using newlib.
    
    The AM_PROG_LIBTOOL checks are currently skipped for --with-newlib and
    --with-avrlibc builds, with this change they are also skipped when using
    --without-headers.  It would be nice if using --disable-hosted-libstdcxx
    automatically skipped those checks, but GLIBCXX_ENABLE_HOSTED comes too
    late to make the AM_PROG_LIBTOOL checks depend on $is_hosted.
    
    The checks for EOF, SEEK_CUR etc. cause the build to fail if there is no
    <stdio.h> available.  Unlike most headers, which get a HAVE_FOO_H macro,
    <stdio.h> is in autoconf's default includes, so every check tries to
    include it unconditionally. This change skips those checks for
    freestanding builds.
    
    Similarly, the checks for <stdint.h> types done by GCC_HEADER_STDINT try
    to include <stdio.h> and fail for --without-headers builds. This change
    skips the use of GCC_HEADER_STDINT for freestanding. We can probably
    stop using GCC_HEADER_STDINT entirely, since only one file uses the
    gstdint.h header that is generated, and that could easily be changed to
    use <stdint.h> instead. That can wait for stage 1.
    
    We also need to skip the GLIBCXX_CROSSCONFIG stage if --without-headers
    was used, since we don't have any of the functions it deals with.
    
    The end result of the changes above is that it should not be necessary
    for a --disable-hosted-libstdcxx --without-headers build to also use
    --with-newlib.
    
    Finally, compile libsupc++ with -ffreestanding when --without-headers is
    used, so that <stdint.h> will use <gcc-stdint.h> instead of expecting it
    to come from libc.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/103866
            * acinclude.m4 (GLIBCXX_COMPUTE_STDIO_INTEGER_CONSTANTS): Do
            nothing for freestanding builds.
            (GLIBCXX_ENABLE_HOSTED): Define FREESTANDING_FLAGS.
            * configure.ac: Do not use AC_LIBTOOL_DLOPEN when configured
            with --without-headers.  Do not use GCC_HEADER_STDINT for
            freestanding builds.
            * libsupc++/Makefile.am (HOSTED_CXXFLAGS): Use -ffreestanding
            for freestanding builds.
            * configure: Regenerate.
            * Makefile.in: Regenerate.
            * doc/Makefile.in: Regenerate.
            * include/Makefile.in: Regenerate.
            * libsupc++/Makefile.in: Regenerate.
            * po/Makefile.in: Regenerate.
            * python/Makefile.in: Regenerate.
            * src/Makefile.in: Regenerate.
            * src/c++11/Makefile.in: Regenerate.
            * src/c++17/Makefile.in: Regenerate.
            * src/c++20/Makefile.in: Regenerate.
            * src/c++98/Makefile.in: Regenerate.
            * src/filesystem/Makefile.in: Regenerate.
            * testsuite/Makefile.in: Regenerate.
Comment 13 Jonathan Wakely 2022-01-10 12:24:46 UTC
This should be fixed on trunk now. Please comment here if it isn't working for you.
Comment 14 Nicolas Noble 2022-01-10 18:33:22 UTC
Thank you, I'll check it out.

On Mon, Jan 10, 2022, 04:24 redi at gcc dot gnu.org <
gcc-bugzilla@gcc.gnu.org> wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103866
>
> Jonathan Wakely <redi at gcc dot gnu.org> changed:
>
>            What    |Removed                     |Added
>
> ----------------------------------------------------------------------------
>    Target Milestone|---                         |12.0
>          Resolution|---                         |FIXED
>              Status|NEW                         |RESOLVED
>
> --- Comment #13 from Jonathan Wakely <redi at gcc dot gnu.org> ---
> This should be fixed on trunk now. Please comment here if it isn't working
> for
> you.
>
> --
> You are receiving this mail because:
> You are on the CC list for the bug.