autodetecting libpng installation on macos

This commit is contained in:
Thomas Ferreira de Lima 2023-02-11 17:43:26 -05:00
parent 83ffe53433
commit 81504ecd9b
1 changed files with 88 additions and 48 deletions

View File

@ -66,6 +66,7 @@ import platform
from distutils.errors import CompileError from distutils.errors import CompileError
import distutils.command.build_ext import distutils.command.build_ext
import setuptools.command.build_ext import setuptools.command.build_ext
from setuptools.command.build_ext import build_ext as _build_ext
import multiprocessing import multiprocessing
# for Jenkins we do not want to be greedy # for Jenkins we do not want to be greedy
@ -137,6 +138,24 @@ def quote_path(path):
else: else:
return path return path
import subprocess
def check_libpng():
""" Check if libpng is available (Linux & Macos only)"""
try:
subprocess.check_call(["libpng-config", "--version"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
return True
except FileNotFoundError as e:
# libpng is not present.
if True: # change to False to enable installation without libpng
raise RuntimeError("libpng missing. libpng-config is not available") from e
return False
def libpng_cflags():
return subprocess.check_output(["libpng-config", "--cflags"]).decode().split()
def libpng_ldflags():
return subprocess.check_output(["libpng-config", "--ldflags"]).decode().split()
# TODO: delete (Obsolete) # TODO: delete (Obsolete)
# patch get_ext_filename # patch get_ext_filename
@ -161,6 +180,12 @@ distutils.command.build_ext.build_ext.get_ext_filename = patched_get_ext_filenam
# end patch get_ext_filename # end patch get_ext_filename
# TODO: customize this object instead of introspecting and patching distutils (if possible)
class klayout_build_ext(_build_ext):
""" Customize build extension class to check for dependencies before installing."""
def finalize_options(self) -> None:
ret = super().finalize_options()
return ret
# patch CCompiler's library_filename for _dbpi libraries (SOs) # patch CCompiler's library_filename for _dbpi libraries (SOs)
# Its default is to have .so for shared objects, instead of dylib, # Its default is to have .so for shared objects, instead of dylib,
@ -222,7 +247,6 @@ def always_link_shared_object(
target_lang, target_lang,
) )
setuptools.command.build_ext.libtype = "shared" setuptools.command.build_ext.libtype = "shared"
setuptools.command.build_ext.link_shared_object = always_link_shared_object setuptools.command.build_ext.link_shared_object = always_link_shared_object
@ -321,6 +345,9 @@ class Config(object):
"-Wno-strict-aliasing", # Avoids many "type-punned pointer" warnings "-Wno-strict-aliasing", # Avoids many "type-punned pointer" warnings
"-std=c++11", # because we use unordered_map/unordered_set "-std=c++11", # because we use unordered_map/unordered_set
] ]
if platform.system() == "Darwin" and mod == "_tl":
if check_libpng():
args += libpng_cflags()
return args return args
def libraries(self, mod): def libraries(self, mod):
@ -330,9 +357,14 @@ class Config(object):
if platform.system() == "Windows": if platform.system() == "Windows":
if mod == "_tl": if mod == "_tl":
return ["libcurl", "expat", "pthreadVCE2", "zlib", "wsock32", "libpng16"] return ["libcurl", "expat", "pthreadVCE2", "zlib", "wsock32", "libpng16"]
elif platform.system() == "Darwin":
if mod == "_tl":
libs = ["curl", "expat"] # libpng is included by libpng_ldflags
return libs
else: else:
if mod == "_tl": if mod == "_tl":
return ["curl", "expat", "png"] libs = ["curl", "expat", "png"]
return libs
return [] return []
def link_args(self, mod): def link_args(self, mod):
@ -361,6 +393,8 @@ class Config(object):
"-Wl,-install_name,@rpath/%s" % self.libname_of(mod, is_lib=True), "-Wl,-install_name,@rpath/%s" % self.libname_of(mod, is_lib=True),
] ]
args += ["-Wl,-rpath,@loader_path/"] args += ["-Wl,-rpath,@loader_path/"]
if mod == "_tl" and check_libpng():
args += libpng_ldflags()
return args return args
else: else:
# this makes the libraries suitable for linking with a path - # this makes the libraries suitable for linking with a path -
@ -385,8 +419,7 @@ class Config(object):
""" """
Returns the macros to use for building Returns the macros to use for building
""" """
return [ macros = [
("HAVE_PNG", 1),
("HAVE_CURL", 1), ("HAVE_CURL", 1),
("HAVE_EXPAT", 1), ("HAVE_EXPAT", 1),
("KLAYOUT_MAJOR_VERSION", self.major_version()), ("KLAYOUT_MAJOR_VERSION", self.major_version()),
@ -394,6 +427,12 @@ class Config(object):
("GSI_ALIAS_INSPECT", 1), ("GSI_ALIAS_INSPECT", 1),
] ]
if platform.system() == "Darwin" and check_libpng():
macros += [("HAVE_PNG", 1)]
else:
macros += [("HAVE_PNG", 1)]
return macros
def minor_version(self): def minor_version(self):
""" """
Gets the version string Gets the version string
@ -937,5 +976,6 @@ if __name__ == "__main__":
include_package_data=True, include_package_data=True,
ext_modules=[_tl, _gsi, _pya, _rba, _db, _lib, _rdb, _lym, _laybasic, _layview, _ant, _edt, _img] ext_modules=[_tl, _gsi, _pya, _rba, _db, _lib, _rdb, _lym, _laybasic, _layview, _ant, _edt, _img]
+ db_plugins + db_plugins
+ [tl, db, lib, rdb, lay] + [tl, db, lib, rdb, lay],
cmdclass={'build_ext': klayout_build_ext}
) )