So my Gentoo now builds with LTO –mostly. A number of packages fail to compile properly with LTO, so I disable it on a per-package basis using portage.env.
Samba (4.2.11) is one of those packages. I get the exact same failure as reported in this thread, which remains unanswered to date.
So I disabled LTO for Samba, but the build kept failing. Though not at the same stage: instead of failing during the compile stage, it now failed during the configure stage. Looking at the log in /var/tmp/portage/net-fs/samba-4.2.11/work/samba-4.2.11-abi_x86_64.amd64/bin/config.log, I saw this:
[1/2] Compiling test.c
['x86_64-pc-linux-gnu-gcc', '-march=core-avx-i', '-O2', '-flto=8', '-pipe', '-fno-lto', '-MD', '-march=core-avx-i', '-flto=8', '-fno-strict-aliasing', '-I/usr/local/include', '-I/usr/include/python2.7', '-I/usr/include/et', '-D_SAMBA_BUILD_=4', '-DHAVE_CONFIG_H=1', '-D_GNU_SOURCE=1', '-D_XOPEN_SOURCE_EXTENDED=1', '../test.c', '-c', '-o', 'default/test_1.o']
[2/2] Linking default/testprog
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/../../../../x86_64-pc-linux-gnu/bin/ld: default/test_1.o: plugin needed to handle lto object
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/../../../../lib64/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
As expected from my /etc/portage/env/no-lto environment file, the -flto=8
in CFLAGS was overridden by a following -fno-lto
. However, where did the last -flto=8
come from?
I noticed that the error did appear at least a few times towards the end of the file, but not at the beginning. So I searched for the first occurrence, and found those lines just above:
Checking for Python version >= 2.5.0
ok 2.7.11
Configuration returned from '/usr/bin/python2.7':
python_prefix = '/usr'
python_SO = '.so'
python_SYSLIBS = '-lm'
python_LDFLAGS = '-Wl,-O1 -Wl,--as-needed -march=core-avx-i -O2 -flto=8 -pipe -L.'
python_SHLIBS = '-lpthread -ldl -lutil'
python_LIBDIR = '/usr/lib64'
python_LIBPL = '/usr/lib64/python2.7/config'
INCLUDEPY = '/usr/include/python2.7'
Py_ENABLE_SHARED = 1
MACOSX_DEPLOYMENT_TARGET = ''
It seemed I had found my culprit: Python was indeed compiled with LTO, and Samba –using the Waf build system– appended Python’s flags after its own CFLAGS/LDFLAGS, re-enabling LTO.
So I took a look at Waf’s handling of Python flags, and found the code that prints the above text around buildtools/wafadmin/Tools/python.py:180 in the Samba source tree.
Poking around, I found this interesting snippet a few lines below:
# Allow some python overrides from env vars for cross-compiling
os_env = dict(os.environ)
override_python_LDFLAGS = os_env.get('python_LDFLAGS', None)
if override_python_LDFLAGS is not None:
conf.log.write("python_LDFLAGS override from environment = %r\n" % (override_python_LDFLAGS))
python_LDFLAGS = override_python_LDFLAGS
Let’s try it out, using the same code as in Waf’s python.py to get the value of python_LDFLAGS:
$ python_LDFLAGS="$(python2 <<< "from distutils.sysconfig import get_config_var ; print get_config_var('LDFLAGS')") -fno-lto" \
> ebuild /usr/portage/net-fs/samba/samba-4.2.11.ebuild compile
It works!
And looking at the log, there is now indeed a new line below all the python_* variables:
python_LDFLAGS override from environment = '-Wl,-O1 -Wl,--as-needed -march=core-avx-i -O2 -flto=8 -pipe -L. -fno-lto'
So there goes, after adding this python_LDFLAGS variable override to my /etc/portage/env/no-lto environment file, Samba builds fine without LTO. :)