Many of the GNU toolchain projects are adding zstd compression.  This
is good, but the configure support for this is not ideal.

In particular for GCC, there are a number of issues.

The first problem is that the two subdirectories that use zstd
(libbacktrace and gcc) use very different methods to detect and support
it.


In libbacktrace/configure.ac we have only:

  AC_CHECK_LIB([zstd], [ZSTD_compress],
      [AC_DEFINE(HAVE_ZSTD, 1, [Define if -lzstd is available.])])

This means that the only way to allow libbacktrace to locate the zstd
library, is if it's installed into the base system / sysroot, or else
figuring out what extra global CFLAGS/LDFLAGS/LIBS you need to add. 
And for GCC in particular, since it might be building both stage1 and
stage2, you need to work out how to manage that.

I tried for a number of days and just completely failed to find the
correct incantation, if there even is one: all attempts broke something
somewhere.  It seems that these global variables are not used
everywhere they are needed (during configure tests).  I ended up making
a copy of my sysroot, installing zstd into the copy, and building GCC
with that.


In gcc/configure.ac on the other hand we have:

  AC_ARG_WITH(zstd,
          [AS_HELP_STRING([--with-zstd=PATH],
                  [specify prefix directory for installed zstd library.
                   Equivalent to --with-zstd-include=PATH/include
                   plus --with-zstd-lib=PATH/lib])])
  AC_ARG_WITH(zstd-include,
          [AS_HELP_STRING([--with-zstd-include=PATH],
                  [specify directory for installed zstd include files])])
  AC_ARG_WITH(zstd-lib,
          [AS_HELP_STRING([--with-zstd-lib=PATH],
                  [specify directory for the installed zstd library])])

which, if it worked, seems to give a lot of flexibility.

However, I've not been able to get this to work because it's not clear
to which stage these paths will be applied.  There's also a weird issue
where if you don't provide the PATH (e.g., just use --with-zstd) then
this code in gcc/configure.ac:

  case "x$with_zstd" in
    x) ;;
    xno)
      ZSTD_INCLUDE=
      ZSTD_LIB=
      ;;
    *) ZSTD_INCLUDE=$with_zstd/include
       ZSTD_LIB=$with_zstd/lib
       ;;
  esac

does the wrong thing because $with_zstd is "yes", so it adds
"-Iyes/include" to the compile line etc.  I guess the idea here is that
the GCC configure script would detect zstd and use it if it's present
so you don't need --with-zstd if it's already in the sysroot, but
usually explicitly adding this allows the configure to fail if it's not
found instead of silently continuing.

It definitely breaks to use the sysroot: "--with-zstd=/sysroot/usr"
will cause the configure to fail with obscure errors because the
compile tests add -I/sysroot/usr/include; this doesn't use -isystem
which means that the fix-includes are searched AFTER this, and so the
un-fixed headers are searched first.


Beyond all that, there's the problem that if you build zstd as a static
library with threading support, you can't link it without -pthread on
the link line.  If you don't use -pthread you get linker errors for
pthread_* symbols and configure decides that zstd is not supported.  I
couldn't find any way to successfully pass this through the various
layers during bootstrap etc., so I had to just build zstd without
threading support for use with GCC.


A lot of these issues could be resolved if GCC's configure (both in
libbacktrace and in gcc) used pkg-config to detect zstd.  The
pkg-config files will give you info about the header file location, the
library location, AND the various linker flags like -pthread.

One issue with this is that when building a cross-compiler we'd need to
distinguish between pkg-config run for the host vs. pkg-config run for
the target.  It's not clear how to handle the standard PKG_CONFIG_*
variables in this situation; since it's peculiar to GCC I doubt the
pkg-config folks have an opinion.  Maybe the user would have to define
a _TARGET variation of these variables, and the makefile would have to
swap them so pkg-config finds the correct ones at the correct time.

Reply via email to