bt2: honor build system compiler/linker preferences
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 1 Apr 2020 14:55:04 +0000 (10:55 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Tue, 23 May 2023 14:35:37 +0000 (10:35 -0400)
commit1d7c6068df5a08524a826c84d4fabdbbbc938a6c
treeb7e8619c0e26b8287df304095c2668a12ae212af
parentd321ba031ba2377b30154e135f3003dd2a1227b8
bt2: honor build system compiler/linker preferences

Cherry-pick note: I see the following build failure on Arch Linux:

    ccache gcc -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -g -ffile-prefix-map=/build/python/src=/usr/src/debug/python -flto=auto -ffat-lto-objects -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -g -ffile-prefix-map=/build/python/src=/usr/src/debug/python -flto=auto -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -g -ffile-prefix-map=/build/python/src=/usr/src/debug/python -flto=auto -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/sysprof-4 -pthread -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/sysprof-4 -pthread -fno-strict-aliasing -Wnested-externs -Wmissing-prototypes -Wstrict-prototypes -Wdeclaration-after-statement -Wimplicit-function-declaration -Wold-style-definition -Wjump-misses-init -Wall -Wextra -Wundef -Wwrite-strings -Wpointer-arith -Wmissing-declarations -Wredundant-decls -Wno-unused-parameter -Wno-missing-field-initializers -Wformat=2 -Wcast-align -Wformat-nonliteral -Wformat-security -Wsign-compare -Wstrict-aliasing -Wshadow -Winline -Wpacked -Wmissing-format-attribute -Wmissing-noreturn -Winit-self -Wmissing-include-dirs -Wunused-but-set-variable -Warray-bounds -Wreturn-type -Wswitch-enum -Wswitch-default -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wrestrict -Wnull-dereference -Wdouble-promotion -Wno-sign-compare -Wno-inline -Wno-declaration-after-statement -Wno-switch-enum -Wno-switch-default -Wno-packed -Wno-pointer-arith -Wno-format-nonliteral -Wno-double-promotion -Wno-cast-align -Wno-cast-function-type -Wno-suggest-attribute=format -Werror -Wno-error=unused-parameter -Wno-error=missing-field-initializers -Wno-error=sign-compare -Wno-error=inline -Wno-error=declaration-after-statement -Wno-error=switch-enum -Wno-error=switch-default -Wno-error=packed -Wno-error=pointer-arith -Wno-error=format-nonliteral -Wno-error=double-promotion -Wno-error=cast-align -Wno-error=cast-function-type -Wold-style-definition -Werror=implicit-function-declaration -g3 -O0 -fmax-errors=1 -fdiagnostics-color=always -Wno-shadow -Wno-null-dereference -Wno-deprecated-declarations -Wno-redundant-decls -I/home/smarchi/src/babeltrace/include -I../../../../src -I/home/smarchi/src/babeltrace/src -include common/config.h -I/home/smarchi/src/babeltrace/src/bindings/python/bt2/bt2 -fPIC -I/usr/include/python3.11 -c /home/smarchi/src/babeltrace/src/bindings/python/bt2/bt2/logging.c -o build/temp.linux-x86_64-3.11/home/smarchi/src/babeltrace/src/bindings/python/bt2/bt2/logging.o
    In file included from /usr/include/errno.h:25,
                     from /home/smarchi/src/babeltrace/src/logging/log.h:12,
                     from /home/smarchi/src/babeltrace/src/bindings/python/bt2/bt2/logging.c:24:
    /usr/include/features.h:413:4: error: #warning _FORTIFY_SOURCE requires compiling with optimization (-O) [-Werror=cpp]
      413 | #  warning _FORTIFY_SOURCE requires compiling with optimization (-O)
          |    ^~~~~~~

Cherry-picking this patch fixes it.  And now the original commit
message:

This is an attempt to fix the dreaded "compiling the Python native
module with a custom compiler or compiler-specific flag" problem.

The problem may arise when building with a CC different than what the
Python interpreter was compiled with.  It can manifests itself in two
different ways, as far as I know.  But in both cases, it's due to us
overriding the compiler and compiler flags when invoking setup.py to
build the native modules, and how distutils invokes the compiler and
linker to build the native modules.

Scenario 1
----------

Things fail when trying to compile with a compiler other than what
Python has been compiled with, and using in `CFLAGS` a compiler flag
unknown to the compiler Python has been compiled with.

For example, on Ubuntu 18.04, we get this when building with CC=clang
(the -Wtautological-constant-out-of-range-compare is a clang-specific
warning flag currently specified in configure.ac):

    x86_64-linux-gnu-gcc ... -Wtautological-constant-out-of-range-compare ... -o build/build_lib/bt2/_native_bt.cpython-38-x86_64-linux-gnu.so
    x86_64-linux-gnu-gcc: error: unrecognized command line option ‘-Wtautological-constant-out-of-range-compare’
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

This is due to the fact that:

- The default link command used by distutils to link shared objects uses
  its default compiler driver (gcc on Linux)
- It passes `CFLAGS` to the linker

Because of this, we end up passing a clang-specific warning flag to gcc,
which proceeds to error out.

To fix this, I have considered setting the LDSHARED variable to
override the command used for linking shared objects.  If the compiler
driver used to drive the linking is the same as the compiler driver used
for compiling, it should understand all the passed flags.

However, it is not obvious to do this right, especially, considering the
various platforms.  But most importantly, it is doesn't help with the
next scenario.

Scenario 2
----------

On Arch Linux (and presumably on Fedora too [1]), the flags passed by
distutils to the compiler contain `-fno-semantic-interposition`, which
is a gcc-specific flag.  When building with CC=clang, we therefore get
this when compiling:

    building 'bt2._native_bt' extension
    clang ... -fno-semantic-interposition ... -c bt2/native_bt.c -o build/temp.linux-x86_64-3.8/bt2/native_bt.o
    clang-9: error: unknown argument: '-fno-semantic-interposition'

clang errors out, because it gets passed a gcc-specific flag.

[1] https://fedoraproject.org/wiki/Changes/PythonNoSemanticInterpositionSpeedup

The fix
-------

Two important distutils configuration variables are at play in this
problem:
  - LDSHARED: defines a command to link a build target
  - CFLAGS: contains the compiler flags used to build the python
    interpreter.

The configuration variables are changed on access by overriding
distutils' get_config_vars().

In the case of `LDSHARED`, distutils allows it to be specified as an
environment variable which would probably be cleaner (if it actually
works, I haven't tested). distutils seems to honor the environment
`CC` _sometimes_ (depending on whether or not it has performed the
`customize_compiler` step?)

The override always uses the environment `CC` and completely foregoes
the `LDSHARED` configuration variable if `LDFLAGS` are provided. If no
`LDFLAGS` are specified, the compiler is replaced in the LDSHARED
command.

Unfortunately, the CFLAGS environment variable is only appended to
the Python interpreter's build-time CFLAGS, which doesn't solve our
problem. get_cflags() completely overrides the CFLAGS configuration
variable to use babeltrace's build system-specified CFLAGS.

Drawbacks
---------

I can't think of a scenario where this doesn't work, but I'm afraid
this will break in non-trivial build environments.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: If3142ddb228758e63a986e735cb8f9d89dd39b67
Reviewed-on: https://review.lttng.org/c/babeltrace/+/3286
Tested-by: jenkins <jenkins@lttng.org>
(cherry picked from commit afdd1f8201f579d81959ce85759dcc62fcc0a85d)
src/bindings/python/bt2/Makefile.am
src/bindings/python/bt2/setup.py.in
This page took 0.026058 seconds and 4 git commands to generate.