Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix build with LTO disabled in environment #19238

Merged
merged 4 commits into from Jan 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Expand Up @@ -32,6 +32,7 @@ jobs:
python-version: 3.7
extra-requirements: '-r requirements/testing/travis_extra.txt'
XVFB_RUN: xvfb-run -a
CFLAGS: "-fno-lto" # Ensure that disabling LTO works.
- os: ubuntu-16.04
python-version: 3.8
extra-requirements: '-r requirements/testing/travis_extra.txt'
Expand Down
38 changes: 26 additions & 12 deletions setup.py
Expand Up @@ -106,20 +106,34 @@ def add_optimization_flags(self):
"""

env = os.environ.copy()
if not setupext.config.getboolean('libs', 'enable_lto', fallback=True):
return env
if sys.platform == 'win32':
return env

cppflags = []
if 'CPPFLAGS' in os.environ:
cppflags.append(os.environ['CPPFLAGS'])
cxxflags = []
if 'CXXFLAGS' in os.environ:
cxxflags.append(os.environ['CXXFLAGS'])
ldflags = []
if 'LDFLAGS' in os.environ:
ldflags.append(os.environ['LDFLAGS'])
enable_lto = setupext.config.getboolean('libs', 'enable_lto',
fallback=None)

def prepare_flags(name, enable_lto):
"""
Prepare *FLAGS from the environment.

If set, return them, and also check whether LTO is disabled in each
one, raising an error if Matplotlib config explicitly enabled LTO.
"""
if name in os.environ:
if '-fno-lto' in os.environ[name]:
if enable_lto is True:
raise ValueError('Configuration enable_lto=True, but '
'{0} contains -fno-lto'.format(name))
enable_lto = False
return [os.environ[name]], enable_lto
return [], enable_lto

_, enable_lto = prepare_flags('CFLAGS', enable_lto) # Only check lto.
cppflags, enable_lto = prepare_flags('CPPFLAGS', enable_lto)
cxxflags, enable_lto = prepare_flags('CXXFLAGS', enable_lto)
ldflags, enable_lto = prepare_flags('LDFLAGS', enable_lto)

if enable_lto is False:
return env

if has_flag(self.compiler, '-fvisibility=hidden'):
for ext in self.extensions:
Expand Down
1 change: 0 additions & 1 deletion setupext.py
Expand Up @@ -447,7 +447,6 @@ def get_extensions(self):
ext = Extension(
"matplotlib.backends._tkagg", [
"src/_tkagg.cpp",
"src/py_converters.cpp",
],
include_dirs=["src"],
# psapi library needed for finding Tcl/Tk at run time.
Expand Down
11 changes: 7 additions & 4 deletions src/_tkagg.cpp
Expand Up @@ -33,14 +33,17 @@
#define dlsym GetProcAddress
#else
#include <dlfcn.h>
// Suppress -Wunused-function on POSIX, but not on Windows where that would
// lead to PY_ARRAY_UNIQUE_SYMBOL being an unresolved external.
#define NO_IMPORT_ARRAY
#endif

// Include our own excerpts from the Tcl / Tk headers
#include "_tkmini.h"
#include "py_converters.h"

static int convert_voidptr(PyObject *obj, void *p)
{
void **val = (void **)p;
*val = PyLong_AsVoidPtr(obj);
return *val != NULL ? 1 : !PyErr_Occurred();
}

// Global vars for Tk functions. We load these symbols from the tkinter
// extension module or loaded Tk libraries at run-time.
Expand Down
7 changes: 0 additions & 7 deletions src/py_converters.cpp
Expand Up @@ -94,13 +94,6 @@ int convert_from_attr(PyObject *obj, const char *name, converter func, void *p)
return 1;
}

int convert_voidptr(PyObject *obj, void *p)
{
void **val = (void **)p;
*val = PyLong_AsVoidPtr(obj);
return *val != NULL ? 1 : !PyErr_Occurred();
}

int convert_double(PyObject *obj, void *p)
{
double *val = (double *)p;
Expand Down
1 change: 0 additions & 1 deletion src/py_converters.h
Expand Up @@ -22,7 +22,6 @@ typedef int (*converter)(PyObject *, void *);
int convert_from_attr(PyObject *obj, const char *name, converter func, void *p);
int convert_from_method(PyObject *obj, const char *name, converter func, void *p);

int convert_voidptr(PyObject *obj, void *p);
int convert_double(PyObject *obj, void *p);
int convert_bool(PyObject *obj, void *p);
int convert_cap(PyObject *capobj, void *capp);
Expand Down