Subject: bug#50556: Clang retains extraneous references to GCC (and zlib)

From: Sarah Morgensen <[email-masked]>
Date: Sun, 12 Sep 2021 16:22:53 -0700

Hello Guix,

I recently noticed that Clang has some extra references:

--8<---------------cut here---------------start------------->8---
$ guix size clang
store item                                                       total    self
/gnu/store/vn69pklab842xyig8d0c6xq6s9iyqhl0-clang-12.0.0           979.2   496.0  50.7%
/gnu/store/rmc131fpy2hv408a1awd2wm7kiwyf7d7-llvm-12.0.0            234.1   162.7  16.6%
/gnu/store/rn75fm7adgx3pw5j8pg3bczfqq1y17lk-gcc-7.5.0              178.5   107.3  11.0%
/gnu/store/8zvc5mvk0xm3ygrxsgpyy5ilxb5rzjry-perl-5.30.2            146.2    57.1   5.8%
/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31              38.4    36.7   3.8%
/gnu/store/f0ca0lf64bw08srv1bj7gkg6ag0sbdb2-gcc-7.5.0-lib           71.0    32.6   3.3%
/gnu/store/01b4w3m6mp55y531kyi1g8shh722kwqm-gcc-7.5.0-lib           71.0    32.6   3.3%
/gnu/store/nzfhh1rm85lx2p5plbx45qqj82pcv5hp-clang-runtime-12.0.0    95.9    24.9   2.5%
/gnu/store/57xj5gcy1jbl9ai2lnrqnpr0dald9i65-coreutils-8.32          88.0    17.0   1.7%
/gnu/store/c8w9z48vvx2a3q3k44ch9yn00wk1qwhb-libxml2-2.9.10          81.1     7.9   0.8%
/gnu/store/mmhimfwmmidf09jw1plw3aw1g1zn2nkh-bash-static-5.0.16       1.6     1.6   0.2%
/gnu/store/pwcp239kjf7lnj5i4lkdzcfcxwcfyk72-bash-minimal-5.0.16     39.4     1.0   0.1%
/gnu/store/r7k859hmcnkazf492fasqvk25jflnfk6-xz-5.2.4                73.0     0.9   0.1%
/gnu/store/g2s5jfkfd4k973wb58476b1bbv9zpm6m-zlib-1.2.11             38.6     0.2   0.0%
/gnu/store/rykm237xkmq7rl1p0nwass01p090p88x-zlib-1.2.11             71.2     0.2   0.0%
/gnu/store/bw15z9kh9c65ycc2vbhl2izwfwfva7p1-libffi-3.3              71.2     0.2   0.0%
total: 979.2 MiB
--8<---------------cut here---------------end--------------->8---

It retains references two *two* separate gcc-7.5.0-lib outputs, two
separate zlib-1.2.11 outputs, and a gcc-7.5.0 output (clang shouldn't
need GCC, right?)

--8<---------------cut here---------------start------------->8---
$ guix gc --references /gnu/store/vn69pklab842xyig8d0c6xq6s9iyqhl0-clang-12.0.0
/gnu/store/01b4w3m6mp55y531kyi1g8shh722kwqm-gcc-7.5.0-lib
/gnu/store/8zvc5mvk0xm3ygrxsgpyy5ilxb5rzjry-perl-5.30.2
/gnu/store/c8w9z48vvx2a3q3k44ch9yn00wk1qwhb-libxml2-2.9.10
/gnu/store/f0ca0lf64bw08srv1bj7gkg6ag0sbdb2-gcc-7.5.0-lib
/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31
/gnu/store/nzfhh1rm85lx2p5plbx45qqj82pcv5hp-clang-runtime-12.0.0
/gnu/store/rmc131fpy2hv408a1awd2wm7kiwyf7d7-llvm-12.0.0
/gnu/store/rn75fm7adgx3pw5j8pg3bczfqq1y17lk-gcc-7.5.0
/gnu/store/vn69pklab842xyig8d0c6xq6s9iyqhl0-clang-12.0.0
--8<---------------cut here---------------end--------------->8---

Okay, so only the gcc references are direct.  Where is the double
gcc-7.5.0-lib reference coming from?

--8<---------------cut here---------------start------------->8---
$ readelf -d /gnu/store/vn69pklab842xyig8d0c6xq6s9iyqhl0-clang-12.0.0/bin/clang-12 | grep runpath
 0x000000000000001d (RUNPATH)            Library runpath: [/gnu/store/vn69pklab842xyig8d0c6xq6s9iyqhl0-clang-12.0.0/lib:/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib:/gnu/store/01b4w3m6mp55y531kyi1g8shh722kwqm-gcc-7.5.0-lib/lib:/gnu/store/rmc131fpy2hv408a1awd2wm7kiwyf7d7-llvm-12.0.0/lib:/gnu/store/f0ca0lf64bw08srv1bj7gkg6ag0sbdb2-gcc-7.5.0-lib/lib]

$ ldd /gnu/store/vn69pklab842xyig8d0c6xq6s9iyqhl0-clang-12.0.0/bin/clang-12 | grep -v LLVM
	linux-vdso.so.1 (0x00007ffe55cbb000)
	libpthread.so.0 => /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/libpthread.so.0 (0x00007f0cd9d1b000)
	libstdc++.so.6 => /gnu/store/01b4w3m6mp55y531kyi1g8shh722kwqm-gcc-7.5.0-lib/lib/libstdc++.so.6 (0x00007f0cd6f33000)
	libm.so.6 => /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/libm.so.6 (0x00007f0cd6df2000)
	libgcc_s.so.1 => /gnu/store/01b4w3m6mp55y531kyi1g8shh722kwqm-gcc-7.5.0-lib/lib/libgcc_s.so.1 (0x00007f0cd6dd9000)
	libc.so.6 => /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/libc.so.6 (0x00007f0cd6c1c000)
	/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 (0x00007f0cdcf19000)
	librt.so.1 => /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/librt.so.1 (0x00007f0cd64ed000)
	libdl.so.2 => /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/libdl.so.2 (0x00007f0cd64e8000)
	libz.so.1 => /gnu/store/rykm237xkmq7rl1p0nwass01p090p88x-zlib-1.2.11/lib/libz.so.1
    (0x00007f0cd64c8000)
--8<---------------cut here---------------end--------------->8---

It has an extra runpath but doesn't use it... Why does it have it?

--8<---------------cut here---------------start------------->8---
$ rg "db2-gcc-7.5.0-lib" /gnu/store/vn69pklab842xyig8d0c6xq6s9iyqhl0-clang-12.0.0
/gnu/store/vn69pklab842xyig8d0c6xq6s9iyqhl0-clang-12.0.0/include/clang/Config/config.h
58:#define GCC_INSTALL_PREFIX "/gnu/store/f0ca0lf64bw08srv1bj7gkg6ag0sbdb2-gcc-7.5.0-lib"
--8<---------------cut here---------------end--------------->8---

So the configure step is probably putting that in there... but why does
it have access to two different gcc-7.5.0-lib inputs in the first place?

--8<---------------cut here---------------start------------->8---
    (inputs
     `(("libxml2" ,libxml2)
       ("gcc-lib" ,gcc "lib")
       ,@(package-inputs llvm)
--8<---------------cut here---------------end--------------->8---

That's reasonable, for cross-compiling... or should it be
`,(canonical-package gcc)' instead?  It couldn't be that simple, could
it?

But even if that fixes non-cross-compiled builds, the above implies that
cross-compiled Clangs could retain a reference to the native gcc-lib as
well.  That shouldn't be, right?

As for zlib... zlib isn't a direct reference, so where is it coming from?

--8<---------------cut here---------------start------------->8---
$ guix gc --references /gnu/store/c8w9z48vvx2a3q3k44ch9yn00wk1qwhb-libxml2-2.9.10
/gnu/store/01b4w3m6mp55y531kyi1g8shh722kwqm-gcc-7.5.0-lib
/gnu/store/c8w9z48vvx2a3q3k44ch9yn00wk1qwhb-libxml2-2.9.10
/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31
/gnu/store/pwcp239kjf7lnj5i4lkdzcfcxwcfyk72-bash-minimal-5.0.16
/gnu/store/r7k859hmcnkazf492fasqvk25jflnfk6-xz-5.2.4
/gnu/store/rykm237xkmq7rl1p0nwass01p090p88x-zlib-1.2.11

$ guix gc --references /gnu/store/rn75fm7adgx3pw5j8pg3bczfqq1y17lk-gcc-7.5.0
/gnu/store/01b4w3m6mp55y531kyi1g8shh722kwqm-gcc-7.5.0-lib
/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31
/gnu/store/g2s5jfkfd4k973wb58476b1bbv9zpm6m-zlib-1.2.11
/gnu/store/mmhimfwmmidf09jw1plw3aw1g1zn2nkh-bash-static-5.0.16
/gnu/store/rn75fm7adgx3pw5j8pg3bczfqq1y17lk-gcc-7.5.0
--8<---------------cut here---------------end--------------->8---

They use two separate zlibs, even though they both reference the same
zlib package!  Why?

I hope we have a Clang expert here!  What do you think?

--
Sarah