8000 Merge pull request #17003 from QuLogic/hidden-visibility · QuLogic/matplotlib@786d18a · GitHub
[go: up one dir, main page]

Skip to content

Commit 786d18a

Browse files
authored
Merge pull request matplotlib#17003 8000 from QuLogic/hidden-visibility
2 parents 4cec73f + fa5059d commit 786d18a

13 files changed

+133
-7
lines changed

setup.py

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
'.'.join(str(n) for n in sys.version_info[:3]))
2323
sys.exit(error)
2424

25+
import os
2526
from pathlib import Path
2627
import shutil
28+
import subprocess
2729
from zipfile import ZipFile
2830

2931
from setuptools import setup, find_packages, Extension
@@ -42,6 +44,7 @@
4244
else:
4345
del sdist.sdist.make_release_tree
4446

47+
from distutils.errors import CompileError
4548
from distutils.dist import Distribution
4649

4750
import setupext
@@ -64,6 +67,19 @@
6467
]
6568

6669

70+
# From https://bugs.python.org/issue26689
71+
def has_flag(self, flagname):
72+
"""Return whether a flag name is supported on the specified compiler."""
73+
import tempfile
74+
with tempfile.NamedTemporaryFile('w', suffix='.cpp') as f:
75+
f.write('int main (int argc, char **argv) { return 0; }')
76+
try:
77+
self.compile([f.name], extra_postargs=[flagname])
78+
except CompileError:
79+
return False
80+
return True
81+
82+
6783
class NoopTestCommand(TestCommand):
6884
def __init__(self, dist):
6985
print("Matplotlib does not support running tests with "
@@ -79,15 +95,85 @@ def finalize_options(self):
7995
]
8096
super().finalize_options()
8197

98+
def add_optimization_flags(self):
99+
"""
100+
Add optional optimization flags to extension.
101+
102+
This adds flags for LTO and hidden visibility to both compiled
103+
extensions, and to the environment variables so that vendored libraries
104+
will also use them. If the compiler does not support these flags, then
105+
none are added.
106+
"""
107+
108+
env = os.environ.copy()
109+
if sys.platform == 'win32':
110+
return env
111+
112+
cppflags = []
113+
if 'CPPFLAGS' in os.environ:
114+
cppflags.append(os.environ['CPPFLAGS'])
115+
cxxflags = []
116+
if 'CXXFLAGS' in os.environ:
117+
cxxflags.append(os.environ['CXXFLAGS'])
118+
ldflags = []
119+
if 'LDFLAGS' in os.environ:
120+
ldflags.append(os.environ['LDFLAGS'])
121+
122+
if has_flag(self.compiler, '-fvisibility=hidden'):
123+
for ext in self.extensions:
124+
ext.extra_compile_args.append('-fvisibility=hidden')
125+
cppflags.append('-fvisibility=hidden')
126+
if has_flag(self.compiler, '-fvisibility-inlines-hidden'):
127+
for ext in self.extensions:
128+
if self.compiler.detect_language(ext.sources) != 'cpp':
129+
continue
130+
ext.extra_compile_args.append('-fvisibility-inlines-hidden')
131+
cxxflags.append('-fvisibility-inlines-hidden')
132+
ranlib = 'RANLIB' in env
133+
if not ranlib and self.compiler.compiler_type == 'unix':
134+
try:
135+
result = subprocess.run(self.compiler.compiler +
136+
['--version'],
137+
stdout=subprocess.PIPE,
138+
stderr=subprocess.STDOUT,
139+
universal_newlines=True)
140+
except Exception as e:
141+
pass
142+
else:
143+
version = result.stdout.lower()
144+
if 'gcc' in version:
145+
ranlib = shutil.which('gcc-ranlib')
146+
elif 'clang' in version:
147+
if sys.platform == 'darwin':
148+
ranlib = True
149+
else:
150+
ranlib = shutil.which('llvm-ranlib')
151+
if ranlib and has_flag(self.compiler, '-flto'):
152+
for ext in self.extensions:
153+
ext.extra_compile_args.append('-flto')
154+
cppflags.append('-flto')
155+
ldflags.append('-flto')
156+
# Needed so FreeType static library doesn't lose its LTO objects.
157+
if isinstance(ranlib, str):
158+
env['RANLIB'] = ranlib
159+
160+
env['CPPFLAGS'] = ' '.join(cppflags)
161+
env['CXXFLAGS'] = ' '.join(cxxflags)
162+
env['LDFLAGS'] = ' '.join(ldflags)
163+
164+
return env
165+
82166
def build_extensions(self):
83167
# Remove the -Wstrict-prototypes option, it's not valid for C++. Fixed
84168
# in Py3.7 as bpo-5755.
85169
try:
86170
self.compiler.compiler_so.remove('-Wstrict-prototypes')
87171
except (ValueError, AttributeError):
88172
pass
173+
174+
env = self.add_optimization_flags()
89175
for package in good_packages:
90-
package.do_custom_build()
176+
package.do_custom_build(env)
91177
return super().build_extensions()
92178

93179

setupext.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ def get_extensions(self):
262262
"""
263263
return []
264264

265-
def do_custom_build(self):
265+
def do_custom_build(self, env):
266266
"""
267267
If a package needs to do extra custom things, such as building a
268268
third-party library, before building an extension, it should
@@ -538,7 +538,7 @@ def add_flags(self, ext):
538538
0, str(src_path / 'objs' / '.libs' / libfreetype))
539539
ext.define_macros.append(('FREETYPE_BUILD_TYPE', 'local'))
540540

541-
def do_custom_build(self):
541+
def do_custom_build(self, env):
542542
# We're using a system freetype
543543
if options.get('system_freetype'):
544544
return
@@ -586,11 +586,11 @@ def do_custom_build(self):
586586

587587
print(f"Building freetype in {src_path}")
588588
if sys.platform != 'win32': # compilation on non-windows
589-
env = {**os.environ,
590-
"CFLAGS": "{} -fPIC".format(os.environ.get("CFLAGS", ""))}
589+
env = {**env, "CFLAGS": "{} -fPIC".format(env.get("CFLAGS", ""))}
591590
subprocess.check_call(
592591
["./configure", "--with-zlib=no", "--with-bzip2=no",
593-
"--with-png=no", "--with-harfbuzz=no"],
592+
"--with-png=no", "--with-harfbuzz=no", "--enable-static",
593+
"--disable-shared"],
594594
env=env, cwd=src_path)
595595
subprocess.check_call(["make"], env=env, cwd=src_path)
596596
else: # compilation on windows

src/_backend_agg_wrapper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,8 @@ static struct PyModuleDef moduledef = {
672672
NULL
673673
};
674674

675+
#pragma GCC visibility push(default)
676+
675677
PyMODINIT_FUNC PyInit__backend_agg(void)
676678
{
677679
PyObject *m;
@@ -694,3 +696,5 @@ PyMODINIT_FUNC PyInit__backend_agg(void)
694696

695697
return m;
696698
}
699+
700+
#pragma GCC visibility pop

src/_contour_wrapper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ static struct PyModuleDef moduledef = {
164164
NULL
165165
};
166166

167+
#pragma GCC visibility push(default)
168+
167169
PyMODINIT_FUNC PyInit__contour(void)
168170
{
169171
PyObject *m;
@@ -182,3 +184,5 @@ PyMODINIT_FUNC PyInit__contour(void)
182184

183185
return m;
184186
}
187+
188+
#pragma GCC visibility pop

src/_image_wrapper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,8 @@ static struct PyModuleDef moduledef = {
456456
NULL
457457
};
458458

459+
#pragma GCC visibility push(default)
460+
459461
PyMODINIT_FUNC PyInit__image(void)
460462
{
461463
PyObject *m;
@@ -491,3 +493,5 @@ PyMODINIT_FUNC PyInit__image(void)
491493

492494
return m;
493495
}
496+
497+
#pragma GCC visibility pop

src/_macosx.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2531,6 +2531,8 @@ static void context_cleanup(const void* info)
25312531
NULL
25322532
};
25332533

2534+
#pragma GCC visibility push(default)
2535+
25342536
PyObject* PyInit__macosx(void)
25352537
{
25362538
PyObject *module;
@@ -2556,3 +2558,5 @@ static void context_cleanup(const void* info)
25562558

25572559
return module;
25582560
}
2561+
2562+
#pragma GCC visibility pop

src/_path_wrapper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,8 @@ static struct PyModuleDef moduledef = {
853853
NULL
854854
};
855855

856+
#pragma GCC visibility push(default)
857+
856858
PyMODINIT_FUNC PyInit__path(void)
857859
{
858860
PyObject *m;
@@ -866,3 +868,5 @@ PyMODINIT_FUNC PyInit__path(void)
866868

867869
return m;
868870
}
871+
872+
#pragma GCC visibility pop

src/_tkagg.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ static PyModuleDef _tkagg_module = {
226226
PyModuleDef_HEAD_INIT, "_tkagg", "", -1, functions, NULL, NULL, NULL, NULL
227227
};
228228

229+
#pragma GCC visibility push(default)
230+
229231
PyMODINIT_FUNC PyInit__tkagg(void)
230232
{
231233
load_tkinter_funcs();
@@ -240,3 +242,5 @@ PyMODINIT_FUNC PyInit__tkagg(void)
240242
}
241243
return PyModule_Create(&_tkagg_module);
242244
}
245+
246+
#pragma GCC visibility pop

src/_ttconv.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ static PyModuleDef ttconv_module = {
276276
NULL, NULL, NULL, NULL
277277
};
278278

279+
#pragma GCC visibility push(default)
280+
279281
PyMODINIT_FUNC
280282
PyInit_ttconv(void)
281283
{
@@ -285,3 +287,5 @@ PyInit_ttconv(void)
285287

286288
return m;
287289
}
290+
291+
#pragma GCC visibility pop

src/ft2font.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
FT_Library _ft2Library;
4444

4545
void throw_ft_error(std::string message, FT_Error error) {
46-
std::ostringstream os;
46+
std::ostringstream os("");
4747
os << message << " (error code 0x" << std::hex << error << ")";
4848
throw std::runtime_error(os.str());
4949
}

src/ft2font_wrapper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,6 +1632,8 @@ static struct PyModuleDef moduledef = {
16321632
NULL
16331633
};
16341634

1635+
#pragma GCC visibility push(default)
1636+
16351637
PyMODINIT_FUNC PyInit_ft2font(void)
16361638
{
16371639
PyObject *m;
@@ -1722,3 +1724,5 @@ PyMODINIT_FUNC PyInit_ft2font(void)
17221724

17231725
return m;
17241726
}
1727+
1728+
#pragma GCC visibility pop

src/qhull_wrap.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,8 @@ static struct PyModuleDef qhull_module = {
337337
NULL, NULL, NULL, NULL
338338
};
339339

340+
#pragma GCC visibility push(default)
341+
340342
PyMODINIT_FUNC
341343
PyInit__qhull(void)
342344
{
@@ -352,3 +354,5 @@ PyInit__qhull(void)
352354

353355
return m;
354356
}
357+
358+
#pragma GCC visibility pop

src/tri/_tri_wrapper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,8 @@ static struct PyModuleDef moduledef = {
504504
NULL
505505
};
506506

507+
#pragma GCC visibility push(default)
508+
507509
PyMODINIT_FUNC PyInit__tri(void)
508510
{
509511
PyObject *m;
@@ -528,3 +530,5 @@ PyMODINIT_FUNC PyInit__tri(void)
528530

529531
return m;
530532
}
533+
534+
#pragma GCC visibility pop

0 commit comments

Comments
 (0)
0