Skip to content

Commit

Permalink
Merge pull request #293 from jonathangreen/feature/macos-static-build
Browse files Browse the repository at this point in the history
Allow static build from MacOS
  • Loading branch information
mxamin authored Apr 7, 2024
2 parents d10cc85 + a51d1ff commit 53e0d81
Showing 1 changed file with 67 additions and 14 deletions.
81 changes: 67 additions & 14 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,17 @@ def latest_xmlsec_release():
return latest_release_from_html('https://www.aleksey.com/xmlsec/download/', re.compile('xmlsec1-(?P<version>.*).tar.gz'))


class CrossCompileInfo:
def __init__(self, host, arch, compiler):
self.host = host
self.arch = arch
self.compiler = compiler

@property
def triplet(self):
return "{}-{}-{}".format(self.host, self.arch, self.compiler)


class build_ext(build_ext_orig):
def info(self, message):
self.announce(message, level=log.INFO)
Expand Down Expand Up @@ -136,7 +147,9 @@ def run(self):
if sys.platform == 'win32':
self.prepare_static_build_win()
elif 'linux' in sys.platform:
self.prepare_static_build_linux()
self.prepare_static_build(sys.platform)
elif 'darwin' in sys.platform:
self.prepare_static_build(sys.platform)
else:
import pkgconfig

Expand Down Expand Up @@ -267,7 +280,7 @@ def prepare_static_build_win(self):
includes.append(next(p / 'xmlsec' for p in includes if (p / 'xmlsec').is_dir()))
ext.include_dirs = [str(p.absolute()) for p in includes]

def prepare_static_build_linux(self):
def prepare_static_build(self, build_platform):
self.openssl_version = os.environ.get('PYXMLSEC_OPENSSL_VERSION')
self.libiconv_version = os.environ.get('PYXMLSEC_LIBICONV_VERSION')
self.libxml2_version = os.environ.get('PYXMLSEC_LIBXML2_VERSION')
Expand Down Expand Up @@ -387,16 +400,42 @@ def prepare_static_build_linux(self):

prefix_arg = '--prefix={}'.format(self.prefix_dir)

cflags = ['-fPIC']
env = os.environ.copy()
if 'CFLAGS' in env:
env['CFLAGS'].append(' '.join(cflags))
else:
env['CFLAGS'] = ' '.join(cflags)
cflags = []
if env.get('CFLAGS'):
cflags.append(env['CFLAGS'])
cflags.append('-fPIC')
ldflags = []
if env.get('LDFLAGS'):
ldflags.append(env['LDFLAGS'])

cross_compiling = False
if build_platform == 'darwin':
import platform

arch = self.plat_name.rsplit('-', 1)[1]
if arch != platform.machine() and arch in ('x86_64', 'arm64'):
self.info('Cross-compiling for {}'.format(arch))
cflags.append('-arch {}'.format(arch))
ldflags.append('-arch {}'.format(arch))
cross_compiling = CrossCompileInfo('darwin64', arch, 'cc')
major_version, minor_version = tuple(map(int, platform.mac_ver()[0].split('.')[:2]))
if major_version >= 11:
if 'MACOSX_DEPLOYMENT_TARGET' not in env:
env['MACOSX_DEPLOYMENT_TARGET'] = "11.0"

env['CFLAGS'] = ' '.join(cflags)
env['LDFLAGS'] = ' '.join(ldflags)

self.info('Building OpenSSL')
openssl_dir = next(self.build_libs_dir.glob('openssl-*'))
subprocess.check_output(['./config', prefix_arg, 'no-shared', '-fPIC', '--libdir=lib'], cwd=str(openssl_dir), env=env)
openssl_config_cmd = [prefix_arg, 'no-shared', '-fPIC', '--libdir=lib']
if cross_compiling:
openssl_config_cmd.insert(0, './Configure')
openssl_config_cmd.append(cross_compiling.triplet)
else:
openssl_config_cmd.insert(0, './config')
subprocess.check_output(openssl_config_cmd, cwd=str(openssl_dir), env=env)
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(openssl_dir), env=env)
subprocess.check_output(
['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install_sw'], cwd=str(openssl_dir), env=env
Expand All @@ -408,10 +447,22 @@ def prepare_static_build_linux(self):
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(zlib_dir), env=env)
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(zlib_dir), env=env)

host_arg = ""
if cross_compiling:
host_arg = '--host={}'.format(cross_compiling.arch)

self.info('Building libiconv')
libiconv_dir = next(self.build_libs_dir.glob('libiconv-*'))
subprocess.check_output(
['./configure', prefix_arg, '--disable-dependency-tracking', '--disable-shared'], cwd=str(libiconv_dir), env=env
[
'./configure',
prefix_arg,
'--disable-dependency-tracking',
'--disable-shared',
host_arg,
],
cwd=str(libiconv_dir),
env=env,
)
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(libiconv_dir), env=env)
subprocess.check_output(
Expand All @@ -430,6 +481,7 @@ def prepare_static_build_linux(self):
'--without-python',
'--with-iconv={}'.format(self.prefix_dir),
'--with-zlib={}'.format(self.prefix_dir),
host_arg,
],
cwd=str(libxml2_dir),
env=env,
Expand All @@ -450,6 +502,7 @@ def prepare_static_build_linux(self):
'--without-python',
'--without-crypto',
'--with-libxml-prefix={}'.format(self.prefix_dir),
host_arg,
],
cwd=str(libxslt_dir),
env=env,
Expand All @@ -460,10 +513,8 @@ def prepare_static_build_linux(self):
)

self.info('Building xmlsec1')
if 'LDFLAGS' in env:
env['LDFLAGS'].append(' -lpthread')
else:
env['LDFLAGS'] = '-lpthread'
ldflags.append('-lpthread')
env['LDFLAGS'] = ' '.join(ldflags)
xmlsec1_dir = next(self.build_libs_dir.glob('xmlsec1-*'))
subprocess.check_output(
[
Expand All @@ -480,6 +531,7 @@ def prepare_static_build_linux(self):
'--with-openssl={}'.format(self.prefix_dir),
'--with-libxml={}'.format(self.prefix_dir),
'--with-libxslt={}'.format(self.prefix_dir),
host_arg,
],
cwd=str(xmlsec1_dir),
env=env,
Expand Down Expand Up @@ -517,7 +569,8 @@ def prepare_static_build_linux(self):
ext.include_dirs.extend([str(p.absolute()) for p in (self.prefix_dir / 'include').iterdir() if p.is_dir()])

ext.library_dirs = []
ext.libraries = ['m', 'rt']
if build_platform == 'linux':
ext.libraries = ['m', 'rt']
extra_objects = [
'libxmlsec1.a',
'libxslt.a',
Expand Down

0 comments on commit 53e0d81

Please sign in to comment.