8000 FreetypeConfig and PkgConfig share parent · matplotlib/matplotlib@ad7336a · GitHub
[go: up one dir, main page]

Skip to content

Commit ad7336a

Browse files
committed
FreetypeConfig and PkgConfig share parent
1 parent 4daac47 commit ad7336a

File tree

1 file changed

+74
-176
lines changed

1 file changed

+74
-176
lines changed

setupext.py

Lines changed: 74 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -240,98 +240,72 @@ def make_extension(name, files, *args, **kwargs):
240240
return ext
241241

242242

243-
class PkgConfig(object):
243+
class Configurator(object):
244244
"""
245245
This is a class for communicating with pkg-config.
246246
"""
247-
def __init__(self):
247+
def __init__(self, config_command):
248248
"""
249249
Determines whether pkg-config exists on this machine.
250250
"""
251+
self.config_command = config_command
252+
251253
if sys.platform == 'win32':
252-
self.has_pkgconfig = False
254+
self.has_config = False
253255
else:
254-
self.set_pkgconfig_path()
255-
status, output = getstatusoutput("pkg-config --help")
256-
self.has_pkgconfig = (status == 0)
257-
258-
def set_pkgconfig_path(self):
259-
pkgconfig_path = sysconfig.get_config_var('LIBDIR')
260-
if pkgconfig_path is None:
261-
return
256+
self.set_config_path()
257+
status, output = getstatusoutput(self.config_command + ' --help')
258+
self.has_config = (status == 0)
262259

263-
pkgconfig_path = os.path.join(pkgconfig_path, 'pkgconfig')
264-
if not os.path.isdir(pkgconfig_path):
265-
return
266-
267-
try:
268-
os.environ['PKG_CONFIG_PATH'] += ':' + pkgconfig_path
269-
except KeyError:
270-
os.environ['PKG_CONFIG_PATH'] = pkgconfig_path
260+
def set_config_path(self):
261+
"""Use for extra setup"""
262+
pass
271263

272-
def setup_extension(self, ext, package, default_include_dirs=[],
273-
default_library_dirs=[], default_libraries=[],
274-
alt_exec=None):
264+
def setup_extension(self, ext, package,
265+
default_include_dirs=[],
266+
default_library_dirs=[], default_libraries=[]):
275267
"""
276268
Add parameters to the given `ext` for the given `package`.
277269
"""
278270
flag_map = {
279271
'-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries'}
280272

281-
executable = alt_exec
282-
if self.has_pkgconfig:
283-
executable = 'pkg-config {0}'.format(package)
284-
285-
use_defaults = True
286-
287-
if executable is not None:
288-
command = "{0} --libs --cflags ".format(executable)
273+
if self.has_config:
274+
command = "{cfg} {pkg} --libs --cflags".format(
275+
cfg=self.config_command, pkg=package)
289276

290277
try:
291-
output = check_output(command, shell=True,
278+
output = check_output(command,
279+
shell=True,
292280
stderr=subprocess.STDOUT)
293281
except subprocess.CalledProcessError:
294282
pass
295283
else:
296284
output = output.decode(sys.getfilesystemencoding())
297-
use_defaults = False
298285
for token in output.split():
299286
attr = flag_map.get(token[:2])
300287
if attr is not None:
301288
getattr(ext, attr).append(token[2:])
302-
303-
if use_defaults:
304-
basedirs = get_base_dirs()
305-
for base in basedirs:
306-
for include in default_include_dirs:
307-
dir = os.path.join(base, include)
308-
if os.path.exists(dir):
309-
ext.include_dirs.append(dir)
310-
for lib in default_library_dirs:
311-
dir = os.path.join(base, lib)
312-
if os.path.exists(dir):
313-
ext.library_dirs.append(dir)
314-
ext.libraries.extend(default_libraries)
315-
return True
316-
317-
return False
289+
return
290+
291+
# couldn't find library, fallback to looking in default paths
292+
basedirs = get_base_dirs()
293+
for base in basedirs:
294+
for include in default_include_dirs:
295+
d = os.path.join(base, include)
296+
if os.path.exists(d):
297+
ext.include_dirs.append(d)
298+
for lib in default_library_dirs:
299+
d = os.path.join(base, lib)
300+
if os.path.exists(d):
301+
ext.library_dirs.append(d)
302+
ext.libraries.extend(default_libraries)
318303

319304
def get_version(self, package):
320-
"""
321-
Get the version of the package from pkg-config.
322-
"""
323-
if not self.ft_config:
324-
return None
305+
raise NotImplementedError()
325306

326-
status, output = getstatusoutput(
327-
"pkg-config %s --modversion" % (package))
328-
if status == 0:
329-
return output
330-
return None
331-
332-
def check_for_pkg_config(self, package, include_file, ext,
333-
min_version=None,
334-
version=None):
307+
def check_for_config(self, package, include_file, ext,
308+
min_version=None, version=None):
335309
"""
336310
A convenience function for writing checks for a
337311
pkg_config-defined dependency.
@@ -350,8 +324,8 @@ def check_for_pkg_config(self, package, include_file, ext,
350324

351325
if version is None:
352326
raise CheckFailed(
353-
"pkg-config information for '%s' could not be found." %
354-
package)
327+
"%s information for '%s' could not be found." %
328+
(self.config_command, package))
355329

356330
if min_version == 'PATCH':
357331
raise CheckFailed(
@@ -372,28 +346,12 @@ def check_for_pkg_config(self, package, include_file, ext,
372346
return 'version %s' % version
373347

374348

375-
# The PkgConfig class should be used through this singleton
376-
pkg_config = PkgConfig()
377-
349+
class PkgConfig(Configurator):
378350

379-
class FTConfig(object):
380-
"""
381-
This is a class for communicating with freetype-config.
382-
"""
383-
def __init__(self):
384-
"""
385-
Determines whether freetype-config exists on this machine.
386-
"""
387-
if sys.platform == 'win32':
388-
self.has_ftconfig = False
389-
else:
390-
self.set_pkgconfig_path()
391-
status, output = getstatusoutput("freetype-config --help")
392-
self.has_ftconfig = (status == 0)
393-
394-
def set_pkgconfig_path(self):
395-
pkgconfig_path = sysconfig.get_config_var('LIBDIR')
396-
if pkgconfig_path is None:
351+
def set_config_path(self):
352+
# ask python if it has a pkg-config libdir
353+
config_path = sysconfig.get_config_var('LIBDIR')
354+
if config_path is None:
397355
return
398356

399357
pkgconfig_path = os.path.join(pkgconfig_path, 'pkgconfig')
@@ -405,109 +363,49 @@ def set_pkgconfig_path(self):
405363
except KeyError:
406364
os.environ['PKG_CONFIG_PATH'] = pkgconfig_path
407365

408-
def setup_extension(self, ext, package, default_include_dirs=[],
409-
default_library_dirs=[], default_libraries=[]):
366+
def get_version(self, package):
410367
"""
411-
Add parameters to the given `ext` for the given `package`.
368+
Get the version of the package from pkg-config.
412369
"""
413-
flag_map = {
414-
'-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries'}
370+
if not self.has_config:
371+
return None
415372

416-
if package != 'freetype2':
417-
raise RuntimeError("FTConfig only works for the freetype2 package")
373+
status, output = getstatusoutput(
374+
"pkg-config %s --modversion" % package)
375+
if status == 0:
376+
return output
377+
return None
418378

419-
use_defaults = True
420379

421-
if self.has_ftconfig:
422-
try:
423-
output = check_output("freetype-config --libs --cflags",
424-
shell=True,
425-
stderr=subprocess.STDOUT)
426-
except subprocess.CalledProcessError:
427-
pass
428-
else:
429-
output = output.decode(sys.getfilesystemencoding())
430-
use_defaults = False
431-
for token in output.split():
432-
attr = flag_map.get(token[:2])
433-
if attr is not None:
434-
getattr(ext, attr).append(token[2:])
380+
class FreetypeConfig(Configurator):
381+
"""This is a class for communicating with freetype-config."""
435382

436-
if use_defaults:
437-
basedirs = get_base_dirs()
438-
for base in basedirs:
439-
for include in default_include_dirs:
440-
dir = os.path.join(base, include)
441-
if os.path.exists(dir):
442-
ext.include_dirs.append(dir)
443-
for lib in default_library_dirs:
444-
dir = os.path.join(base, lib)
445-
if os.path.exists(dir):
446-
ext.library_dirs.append(dir)
447-
ext.libraries.extend(default_libraries)
448-
return True
449-
450-
return False
383+
def setup_extension(self, ext, package, **kw):
384+
"""Add parameters to the given `ext` for the given `package`."""
385+
if package != 'freetype2':
386+
raise RuntimeError('package must be "freetype2"')
387+
package = ''
388+
return super(FreetypeConfig, self).setup_extension(ext, package, **kw)
451389

452390
def get_version(self, package):
453-
"""
454-
Get the version from freetype-config.
455-
"""
391+
"""Get the version from freetype-config."""
456392
if package != 'freetype2':
457-
raise RuntimeError("FTConfig only works for the freetype2 package")
393+
raise RuntimeError('package must be "freetype2"')
458394

459-
if not self.ft_config:
395+
if not self.has_config:
460396
return None
461397

462398
status, output = getstatusoutput("freetype-config --ftversion")
463399
if status == 0:
464400
return output
465401
return None
466402

467-
def check_for_ft_config(self, package, include_file, ext,
468-
min_version=None, version=None):
469-
"""
470-
A convenience function for writing checks for a
471-
pkg_config-defined dependency.
472-
473-
`package` is the ft_config package name.
474-
475-
`include_file` is a top-level include file we expect to find.
476-
477-
`min_version` is the minimum version required.
478-
479-
`version` will override the found version if this package
480-
requires an alternate method for that.
481-
"""
482-
if version is None:
483-
version = self.get_version(package)
484-
485-
if version is None:
486-
raise CheckFailed(
487-
"pkg-config information for '%s' could not be found." %
488-
package)
489403

490-
if min_version == 'PATCH':
491-
raise CheckFailed(
492-
"Requires patches that have not been merged upstream.")
493404

494-
if min_version:
495-
if (not is_min_version(version, min_version)):
496-
raise CheckFailed(
497-
"Requires %s %s or later. Found %s." %
498-
(package, min_version, version))
499-
500-
if ext is None:
501-
ext = make_extension('test', [])
502-
self.setup_extension(ext, package)
503405

504-
check_include_file(ext.include_dirs, include_file, package)
505-
506-
return 'version %s' % version
507-
508-
509-
# The PkgConfig class should be used through this singleton
510-
ft_config = FTConfig()
406+
# The PkgConfig/FreetypeConfig class should be used through singletons
407+
pkg_config = PkgConfig('pkg-config')
408+
ft_config = FreetypeConfig('freetype-config')
511409

512410

513411
class CheckFailed(Exception):
@@ -884,10 +782,10 @@ class LibAgg(SetupPackage):
884782
def check(self):
885783
self.__class__.found_external = True
886784
try:
887-
return pkg_config.check_for_pkg_config('libagg',
888-
'agg2/agg_basics.h',
889-
self.get_ext(),
890-
min_version='PATCH')
785+
return pkg_config.check_for_config('libagg',
786+
'agg2/agg_basics.h',
787+
self.get_ext(),
788+
min_version='PATCH')
891789
except CheckFailed as e:
892790
self.__class__.found_external = False
893791
return str(e) + ' Using local copy.'
@@ -921,19 +819,19 @@ def check(self):
921819
status, version = ge 3AC4 tstatusoutput("freetype-config --version")
922820
if status == 0:
923821
try:
924-
return ft_config.check_for_ft_config(
822+
return ft_config.check_for_config(
925823
'freetype2', 'ft2build.h', self.get_ext(),
926824
min_version='2.4', version=version
927825
)
928826
except CheckFailed:
929827
pass
930828

931-
return pkg_config.check_for_pkg_config(
829+
return pkg_config.check_for_config(
932830
'freetype2', 'ft2build.h', self.get_ext(),
933831
min_version='2.4', version=None)
934832

935833
def add_flags(self, ext):
936-
if ft_config.has_ftconfig:
834+
if ft_config.has_config:
937835
ft_config.setup_extension(
938836
ext, 'freetype2',
939837
default_include_dirs=[
@@ -974,7 +872,7 @@ class Png(SetupPackage):
974872

975873
def check(self):
976874
try:
977-
return pkg_config.check_for_pkg_config(
875+
return pkg_config.check_for_config(
978876
'libpng', 'png.h', self.get_ext(),
979877
min_version='1.2')
980878
except CheckFailed as e:

0 commit comments

Comments
 (0)
0