Samba with LTO… not!

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'

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/ 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 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. :)

Leave a Reply

Your email address will not be published. Required fields are marked *