Skip to content

Commit 53e0d81

Browse files
authored
Merge pull request #293 from jonathangreen/feature/macos-static-build
Allow static build from MacOS
2 parents d10cc85 + a51d1ff commit 53e0d81

File tree

1 file changed

+67
-14
lines changed

1 file changed

+67
-14
lines changed

setup.py

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,17 @@ def latest_xmlsec_release():
108108
return latest_release_from_html('https://www.aleksey.com/xmlsec/download/', re.compile('xmlsec1-(?P<version>.*).tar.gz'))
109109

110110

111+
class CrossCompileInfo:
112+
def __init__(self, host, arch, compiler):
113+
self.host = host
114+
self.arch = arch
115+
self.compiler = compiler
116+
117+
@property
118+
def triplet(self):
119+
return "{}-{}-{}".format(self.host, self.arch, self.compiler)
120+
121+
111122
class build_ext(build_ext_orig):
112123
def info(self, message):
113124
self.announce(message, level=log.INFO)
@@ -136,7 +147,9 @@ def run(self):
136147
if sys.platform == 'win32':
137148
self.prepare_static_build_win()
138149
elif 'linux' in sys.platform:
139-
self.prepare_static_build_linux()
150+
self.prepare_static_build(sys.platform)
151+
elif 'darwin' in sys.platform:
152+
self.prepare_static_build(sys.platform)
140153
else:
141154
import pkgconfig
142155

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

270-
def prepare_static_build_linux(self):
283+
def prepare_static_build(self, build_platform):
271284
self.openssl_version = os.environ.get('PYXMLSEC_OPENSSL_VERSION')
272285
self.libiconv_version = os.environ.get('PYXMLSEC_LIBICONV_VERSION')
273286
self.libxml2_version = os.environ.get('PYXMLSEC_LIBXML2_VERSION')
@@ -387,16 +400,42 @@ def prepare_static_build_linux(self):
387400

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

390-
cflags = ['-fPIC']
391403
env = os.environ.copy()
392-
if 'CFLAGS' in env:
393-
env['CFLAGS'].append(' '.join(cflags))
394-
else:
395-
env['CFLAGS'] = ' '.join(cflags)
404+
cflags = []
405+
if env.get('CFLAGS'):
406+
cflags.append(env['CFLAGS'])
407+
cflags.append('-fPIC')
408+
ldflags = []
409+
if env.get('LDFLAGS'):
410+
ldflags.append(env['LDFLAGS'])
411+
412+
cross_compiling = False
413+
if build_platform == 'darwin':
414+
import platform
415+
416+
arch = self.plat_name.rsplit('-', 1)[1]
417+
if arch != platform.machine() and arch in ('x86_64', 'arm64'):
418+
self.info('Cross-compiling for {}'.format(arch))
419+
cflags.append('-arch {}'.format(arch))
420+
ldflags.append('-arch {}'.format(arch))
421+
cross_compiling = CrossCompileInfo('darwin64', arch, 'cc')
422+
major_version, minor_version = tuple(map(int, platform.mac_ver()[0].split('.')[:2]))
423+
if major_version >= 11:
424+
if 'MACOSX_DEPLOYMENT_TARGET' not in env:
425+
env['MACOSX_DEPLOYMENT_TARGET'] = "11.0"
426+
427+
env['CFLAGS'] = ' '.join(cflags)
428+
env['LDFLAGS'] = ' '.join(ldflags)
396429

397430
self.info('Building OpenSSL')
398431
openssl_dir = next(self.build_libs_dir.glob('openssl-*'))
399-
subprocess.check_output(['./config', prefix_arg, 'no-shared', '-fPIC', '--libdir=lib'], cwd=str(openssl_dir), env=env)
432+
openssl_config_cmd = [prefix_arg, 'no-shared', '-fPIC', '--libdir=lib']
433+
if cross_compiling:
434+
openssl_config_cmd.insert(0, './Configure')
435+
openssl_config_cmd.append(cross_compiling.triplet)
436+
else:
437+
openssl_config_cmd.insert(0, './config')
438+
subprocess.check_output(openssl_config_cmd, cwd=str(openssl_dir), env=env)
400439
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(openssl_dir), env=env)
401440
subprocess.check_output(
402441
['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install_sw'], cwd=str(openssl_dir), env=env
@@ -408,10 +447,22 @@ def prepare_static_build_linux(self):
408447
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(zlib_dir), env=env)
409448
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(zlib_dir), env=env)
410449

450+
host_arg = ""
451+
if cross_compiling:
452+
host_arg = '--host={}'.format(cross_compiling.arch)
453+
411454
self.info('Building libiconv')
412455
libiconv_dir = next(self.build_libs_dir.glob('libiconv-*'))
413456
subprocess.check_output(
414-
['./configure', prefix_arg, '--disable-dependency-tracking', '--disable-shared'], cwd=str(libiconv_dir), env=env
457+
[
458+
'./configure',
459+
prefix_arg,
460+
'--disable-dependency-tracking',
461+
'--disable-shared',
462+
host_arg,
463+
],
464+
cwd=str(libiconv_dir),
465+
env=env,
415466
)
416467
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(libiconv_dir), env=env)
417468
subprocess.check_output(
@@ -430,6 +481,7 @@ def prepare_static_build_linux(self):
430481
'--without-python',
431482
'--with-iconv={}'.format(self.prefix_dir),
432483
'--with-zlib={}'.format(self.prefix_dir),
484+
host_arg,
433485
],
434486
cwd=str(libxml2_dir),
435487
env=env,
@@ -450,6 +502,7 @@ def prepare_static_build_linux(self):
450502
'--without-python',
451503
'--without-crypto',
452504
'--with-libxml-prefix={}'.format(self.prefix_dir),
505+
host_arg,
453506
],
454507
cwd=str(libxslt_dir),
455508
env=env,
@@ -460,10 +513,8 @@ def prepare_static_build_linux(self):
460513
)
461514

462515
self.info('Building xmlsec1')
463-
if 'LDFLAGS' in env:
464-
env['LDFLAGS'].append(' -lpthread')
465-
else:
466-
env['LDFLAGS'] = '-lpthread'
516+
ldflags.append('-lpthread')
517+
env['LDFLAGS'] = ' '.join(ldflags)
467518
xmlsec1_dir = next(self.build_libs_dir.glob('xmlsec1-*'))
468519
subprocess.check_output(
469520
[
@@ -480,6 +531,7 @@ def prepare_static_build_linux(self):
480531
'--with-openssl={}'.format(self.prefix_dir),
481532
'--with-libxml={}'.format(self.prefix_dir),
482533
'--with-libxslt={}'.format(self.prefix_dir),
534+
host_arg,
483535
],
484536
cwd=str(xmlsec1_dir),
485537
env=env,
@@ -517,7 +569,8 @@ def prepare_static_build_linux(self):
517569
ext.include_dirs.extend([str(p.absolute()) for p in (self.prefix_dir / 'include').iterdir() if p.is_dir()])
518570

519571
ext.library_dirs = []
520-
ext.libraries = ['m', 'rt']
572+
if build_platform == 'linux':
573+
ext.libraries = ['m', 'rt']
521574
extra_objects = [
522575
'libxmlsec1.a',
523576
'libxslt.a',

0 commit comments

Comments
 (0)