INSTALL_DEST_DIR=`mktemp -d` make DESTDIR=$INSTALL_DEST_DIR install cd $INSTALL_DEST_DIR/$HOME/.local find . -name > ~/conf/toolchains/powerpc64le-binutils-2.36.1.txt find . > ~/conf/toolchains/powerpc64le-binutils-2.36.1.txt cd ~ cd Projects/toolchains/build-bin-powerpc64le-power8/ make install rm -rf $INSTALL_DEST_DIR unset INSTALL_DEST_DIR xargs rm < ~/conf/toolchains/powerpc64le-binutils-2.36.1.txt Quick review of autotools (it's a mess, but this should cover it): * `configure.ac` generates `configure` and `config.h.in` (?) via `autoconf`. This is done by the gcc devs. * `Makefile.def` and `Makefile.tpl` generate `Makefile.in` via `autogen`. This is done by the gcc devs. * Normally, `Makefile.am` generates `Makefile.in` via `automake`. `automake` is _not_ used by GCC top level. `autoconf` docs describe how to handwrite a `Makefile.in` if necessary. * Running `configure` generates `config.status` _and_ runs it. Also emits a `config.log` * `Makefile.in` and `config.h.in` generate the `Makefile` and `config.h` via `config.status`. * ${target_alias} is the autoconf var set by target. It eventually becomes ${target} after being run through config.guess. * The top-level config script will pass all config args down to each library in gcc. You must specify --help=recursive to see them. * If --disable-threads or --enable-threads isn't specified to gcc, a default thread header will be chosen by config.gcc. It may possibly not make sense for a default compiler. --enable-threads=single is equivalent to --disable-threads. * all-gcc and install-gcc are STILL undocumented. * `: $(MAKE) ; $(unstage)` is an optimization to prevent certain recursive make calls. * There is no "Makefile.am". Makefile.in is either handwritten, or, for the top-level file, generated using autogen from "Makefile.def" and "Makefile.tpl" (think Python's Jinja2 but for C). "Makefile.def/tpl" also generates dependencies between targets. There is some redundancy in dependencies (i.e. a depends on b and c, b depends on c) Pruning targets: * Makefile.tpl/in uses a special set of conditionals @if/@endif @unless/@endunless to further configure the Makefile beyond variables that autoconf sets. They are sed expressions passed to `config.status`, part of the extrasub_{host, build, target} vars. The last expressions in these vars are catch-alls that will delete blocks of text in between @if/@endif and preserve @unless/@endunless. * The `@` _must_ be at the beginning of the line (e.g. no whitespace, including tabs). * This is all to say that `configure` has special logic to remove targets from `Makefile.in` before spitting out a `Makefile`. * `# Skipdirs are removed silently.` * `# Noconfigdirs are removed loudly.` * `$noconfigdirs` eventually becomes `$notsupp`, the latter of which generates the `*** This configuration is not supported` messages. * Manual `--disable-*`/`enable-*=no` args are added to `$noconfigdirs`. * `configure` consults a `configure.tgt` file for some libraries. If `UNSUPPORTED=1`, then the library is added to `$noconfigdirs`. * `skipdirs` is used sparingly. * Top level targets: all, clean, install, distclean, configure * Also applies to subprojects (maybe-) all-gcc, clean-target-libgcc, configure-libiberty * If doing a bootstrap, the subproject make target format is: configure-stage{0,1,2,*}-target-*. * The `maybe-` prefix seems to be "the build will go on if this dep isn't satisfied". At least for anything with the target prefix. See "These Scheme functions build the bulk of the dependencies" string. * Multilib is a clusterf***. It runs while config.status is generating Makefiles for a specific project. Look for something like `ac_file=Makefile . ${multi_basedir}/config-ml.in` in config.status. From adding an echo at the end of config-ml.in and tracing the script, looks like config-ml.in runs configure/config.status for each version of the library, and handles both "in subdirectory of multilib" and "top level of multilib" cases via ml_toplevel_p variable. Therefore if you have, e.g. 15 different multidirs, config-ml.in runs 16 times. config-ml.in cannot handle enable_libstdc++v3=no (typo :P. Also applies to enable_libstdc++-v3=no?). This doesn't appear to affect the script running to completion. How does the build work/configure all the subprojects? And in the correct order? General Build Process: * `make all` ultimately builds two targets: `all-host` and `all-target`. Those two target deps consist of `maybe-all-*` targets (which depend on `all-*`). There is also an `all-build` targeet. * All three types of targets use the same `configure-*` and `all-*` templates in `Makefile.tpl` to generate Makefile targets, with different substitutions as appropriate. * `build` targets are, appropriately, built under the `build-*` subdirectory, where `*` will take the value of your build triplet. `host` targets are built directly in the root of your build tree, where the top-level Makefile lives. `target` targets are built in a directory with the name of your target triple, without any prefix (I don't get it either). * `all-build` is a dependency of `cross`, doesn't seem to be used elsewhere. * `maybe-all-build-*` deps are declared as needed. See Makefile.def for exhaustive list. Many of them can be provided by the host system. * The build does not appear to check for libraries it depends on during configure- deps _appear_ to be implied by Makefile order. # Example (for lm32) * If `make -j1`, `configure-fixincludes` is probably run first. * Building `all-fixincludes` depends on `maybe-all-libiberty`. * Then we go back to compile `fixincludes`. * `gcc` is next. Before we can even configure `gcc`, we have stuff to do: * `configure-intl` * `all-lto-plugin`: This target creates the `gcc` build dir and copies `liblto_plugin` into it. See `$(in_gcc_libs)` and GNU Make Static Patterns. Also called `mkinstalldirs` in GCC source root. * Then call `configure-gcc` * After `gcc` is configured, there's other libraries to build before we run `all-gcc`: * Finish up `all-intl`. For lm32, this appears to be a no-op. * `all-build-libiberty` * `all-build-fixincludes` * `all-build-libcpp` * `all-zlib` (Notice the `build` is missing!) * `all-libbacktrace` * `all-libcpp` * `all-libdecnumber` * `gcc` Makefile: * First thing that's done is to define a number of headers and scripts. I didn't delve deeply into this. * The Makefile defines `LANG_MAKEFRAGS` which provide targets, like `c`, `c++`, and `lto`, to build language support and the actual compiler binaries like `cc1`. The C++ directory is called `cp`; the target is still called `c++`. * `all.cross` is the target we want. It first needs to build `native`. * The `gcc` build creates a number of C programs to generate code to further build the compiler. NEXT: Where is the LTO target? Bootstrap: TODO! LM32: * --disable-libgcc actually _does_ disable libgcc. Why?! There is a catch-all in configure.ac: # Handle --disable- generically. # Remove the entries in $skipdirs and $noconfigdirs from $configdirs It's undocumented and not part of ac_user_opts. Neither is enable-languages (at least part of the top-level make), which the top-level uses but the option is defined in a subproject. AC_DISABLE_OPTION_CHECKING allows this use case. variables called enable_* = {yes, no} are handled internally by the config script. They may be exported as ENABLE_*. Yes, the case matters! * Why is removing libstdc++7 required? Is there another way? configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES. https://gcc.gnu.org/legacy-ml/gcc/2008-03/msg00515.html * Why does removing libstdc++7 all of a sudden cause a separate failure on gcc 10? * Removing before configure seems to work * Removing after configure will cause a "no such file or directory" error as the build attempts to configure anyway :) * If --disable-libstdc++v3 is provided, libquadmath will fail with enable_libstdc++v3=no: command not found. That is a typo :D! But why is eval treating it as a command, not a var? POWER: * ../gcc-10.2.0/configure --prefix=/home/william/.local --target=powerpc64le-linux-gnu --enable-languages=c,c++ POSIX threads are enabled, the build expects them to exist (they won't for a cross w/o a full libc). * ../gcc-10.2.0/configure --prefix=/home/william/.local --target=powerpc64le-linux-gnu --enable-languages=c,c++ --disable-threads --disable-__cxa_atexit Cannot find -lc/crtn.o/etc Configure invocations: LM32: `../gcc-10.2.0/configure --prefix=/home/william/.local --enable-languages=c,c++ --target=lm32-elf --disable-libgcc --disable-libssp --disable-libstdc++-v3 : (reconfigured) ../gcc-10.2.0/configure --prefix=/home/william/.local --enable-languages=c,c++ --target=lm32-elf --disable-libgcc --disable-libssp --disable-libstdc++-v3` POWER: `../gcc-10.2.0/configure --prefix=/home/william/.local --target=powerpc64le-linux-gnu --enable-languages=c,c++ --disable-threads --disable-shared --disable-libssp --disable-libgomp --disable-libstdc++-v3 --disable-libquadmath --disable-libatomic` SH2: `../../gcc-10.2.0/configure --prefix=$HOME/.local --target=sh2eb-none-elf --disable-threads --disable-shared --enable-languages=c,c++ --disable-libstdc++-v3 --disable-libssp` # Open qs 1. How is a cross compiler detected from config options? 2. What happens if sysroot is set for a native compiler or doesn't exist on target?