-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for z/OS compilers; Fixes #215
- Loading branch information
Showing
3 changed files
with
239 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
"""distutils.zosccompiler | ||
Contains the selection of the c & c++ compilers on z/OS. There are several | ||
different c compilers on z/OS, all of them are optional, so the correct | ||
one needs to be chosen based on the users input. This is compatible with | ||
the following compilers: | ||
IBM C/C++ For Open Enterprise Languages on z/OS 2.0 | ||
IBM Open XL C/C++ 1.1 for z/OS | ||
IBM XL C/C++ V2.4.1 for z/OS 2.4 and 2.5 | ||
IBM z/OS XL C/C++ | ||
""" | ||
|
||
import os | ||
from .unixccompiler import UnixCCompiler | ||
from . import sysconfig | ||
from .errors import DistutilsExecError, CompileError | ||
|
||
_cc_args = { | ||
'ibm-openxl': [ | ||
'-m64', | ||
'-fvisibility=default', | ||
'-fzos-le-char-mode=ascii', | ||
'-fno-short-enums', | ||
], | ||
'ibm-xlclang': [ | ||
'-q64', | ||
'-qexportall', | ||
'-qascii', | ||
'-qstrict', | ||
'-qnocsect', | ||
'-Wa,asa,goff', | ||
'-Wa,xplink', | ||
'-qgonumber', | ||
'-qenum=int', | ||
'-Wc,DLL', | ||
], | ||
'ibm-xlc': [ | ||
'-q64', | ||
'-qexportall', | ||
'-qascii', | ||
'-qstrict', | ||
'-qnocsect', | ||
'-Wa,asa,goff', | ||
'-Wa,xplink', | ||
'-qgonumber', | ||
'-qenum=int', | ||
'-Wc,DLL', | ||
'-qlanglvl=extc99', | ||
], | ||
} | ||
|
||
_cxx_args = { | ||
'ibm-openxl': [ | ||
'-m64', | ||
'-fvisibility=default', | ||
'-fzos-le-char-mode=ascii', | ||
'-fno-short-enums', | ||
], | ||
'ibm-xlclang': [ | ||
'-q64', | ||
'-qexportall', | ||
'-qascii', | ||
'-qstrict', | ||
'-qnocsect', | ||
'-Wa,asa,goff', | ||
'-Wa,xplink', | ||
'-qgonumber', | ||
'-qenum=int', | ||
'-Wc,DLL', | ||
], | ||
'ibm-xlc': [ | ||
'-q64', | ||
'-qexportall', | ||
'-qascii', | ||
'-qstrict', | ||
'-qnocsect', | ||
'-Wa,asa,goff', | ||
'-Wa,xplink', | ||
'-qgonumber', | ||
'-qenum=int', | ||
'-Wc,DLL', | ||
'-qlanglvl=extended0x', | ||
], | ||
} | ||
|
||
_asm_args = { | ||
'ibm-openxl': ['-fasm', '-fno-integrated-as', '-Wa,--ASA', '-Wa,--GOFF'], | ||
'ibm-xlclang': [], | ||
'ibm-xlc': [], | ||
} | ||
|
||
_ld_args = { | ||
'ibm-openxl': [], | ||
'ibm-xlclang': ['-Wl,dll', '-q64'], | ||
'ibm-xlc': ['-Wl,dll', '-q64'], | ||
} | ||
|
||
|
||
# Python on z/OS is built with no compiler specific options in it's CFLAGS. | ||
# But each compiler requires it's own specific options to build successfully, | ||
# though some of the options are common between them | ||
class zOSCCompiler(UnixCCompiler): | ||
src_extensions = ['.c', '.C', '.cc', '.cxx', '.cpp', '.m', '.s'] | ||
_cpp_extensions = ['.cc', '.cpp', '.cxx', '.C'] | ||
_asm_extensions = ['.s'] | ||
|
||
def _get_zos_compiler_name(self): | ||
zos_compiler_names = [ | ||
os.path.basename(binary) | ||
for envvar in ('CC', 'CXX', 'LDSHARED') | ||
if (binary := os.environ.get(envvar, None)) | ||
] | ||
if len(zos_compiler_names) == 0: | ||
return 'ibm-openxl' | ||
|
||
zos_compilers = {} | ||
for compiler in ( | ||
'ibm-clang', | ||
'ibm-clang64', | ||
'ibm-clang++', | ||
'ibm-clang++64', | ||
'clang', | ||
'clang++', | ||
'clang-14', | ||
): | ||
zos_compilers[compiler] = 'ibm-openxl' | ||
|
||
for compiler in ('xlclang', 'xlclang++', 'njsc', 'njsc++'): | ||
zos_compilers[compiler] = 'ibm-xlclang' | ||
|
||
for compiler in ('xlc', 'xlC', 'xlc++'): | ||
zos_compilers[compiler] = 'ibm-xlc' | ||
|
||
return zos_compilers.get(zos_compiler_names[0], 'ibm-openxl') | ||
|
||
def __init__(self, verbose=0, dry_run=0, force=0): | ||
super().__init__(verbose, dry_run, force) | ||
self.zos_compiler = self._get_zos_compiler_name() | ||
sysconfig.customize_compiler(self) | ||
|
||
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): | ||
local_args = [] | ||
if ext in self._cpp_extensions: | ||
compiler = self.compiler_cxx | ||
local_args.extend(_cxx_args[self.zos_compiler]) | ||
elif ext in self._asm_extensions: | ||
compiler = self.compiler_so | ||
local_args.extend(_cc_args[self.zos_compiler]) | ||
local_args.extend(_asm_args[self.zos_compiler]) | ||
else: | ||
compiler = self.compiler_so | ||
local_args.extend(_cc_args[self.zos_compiler]) | ||
local_args.extend(cc_args) | ||
|
||
try: | ||
self.spawn(compiler + local_args + [src, '-o', obj] + extra_postargs) | ||
except DistutilsExecError as msg: | ||
raise CompileError(msg) | ||
|
||
def runtime_library_dir_option(self, dir): | ||
return '-L' + dir | ||
|
||
def link( | ||
self, | ||
target_desc, | ||
objects, | ||
output_filename, | ||
output_dir=None, | ||
libraries=None, | ||
library_dirs=None, | ||
runtime_library_dirs=None, | ||
export_symbols=None, | ||
debug=0, | ||
extra_preargs=None, | ||
extra_postargs=None, | ||
build_temp=None, | ||
target_lang=None, | ||
): | ||
# For a built module to use functions from cpython, it needs to use Pythons | ||
# side deck file. The side deck is located beside the libpython3.xx.so | ||
ldversion = sysconfig.get_config_var('LDVERSION') | ||
if sysconfig.python_build: | ||
side_deck_path = os.path.join( | ||
sysconfig.get_config_var('abs_builddir'), | ||
f'libpython{ldversion}.x', | ||
) | ||
else: | ||
side_deck_path = os.path.join( | ||
sysconfig.get_config_var('installed_base'), | ||
sysconfig.get_config_var('platlibdir'), | ||
f'libpython{ldversion}.x', | ||
) | ||
|
||
if os.path.exists(side_deck_path): | ||
if extra_postargs: | ||
extra_postargs.append(side_deck_path) | ||
else: | ||
extra_postargs = [side_deck_path] | ||
|
||
# Check and replace libraries included side deck files | ||
if runtime_library_dirs: | ||
for dir in runtime_library_dirs: | ||
for library in libraries[:]: | ||
library_side_deck = os.path.join(dir, f'{library}.x') | ||
if os.path.exists(library_side_deck): | ||
libraries.remove(library) | ||
extra_postargs.append(library_side_deck) | ||
break | ||
|
||
# Any required ld args for the given compiler | ||
extra_postargs.extend(_ld_args[self.zos_compiler]) | ||
|
||
super().link( | ||
target_desc, | ||
objects, | ||
output_filename, | ||
output_dir, | ||
libraries, | ||
library_dirs, | ||
runtime_library_dirs, | ||
export_symbols, | ||
debug, | ||
extra_preargs, | ||
extra_postargs, | ||
build_temp, | ||
target_lang, | ||
) |