diff --git a/Core/ClientSMLSWIG/Python/Python_sml_ClientInterface.i b/Core/ClientSMLSWIG/Python/Python_sml_ClientInterface.i index 384a15cbf5..1110dfa0c7 100644 --- a/Core/ClientSMLSWIG/Python/Python_sml_ClientInterface.i +++ b/Core/ClientSMLSWIG/Python/Python_sml_ClientInterface.i @@ -12,7 +12,9 @@ %include %begin %{ +#ifdef Soar_Python_ABI3 #define Py_LIMITED_API 0x03050000 +#endif %} %{ diff --git a/Core/ClientSMLSWIG/Python/SConscript b/Core/ClientSMLSWIG/Python/SConscript index 7ce28417a9..9832166a06 100644 --- a/Core/ClientSMLSWIG/Python/SConscript +++ b/Core/ClientSMLSWIG/Python/SConscript @@ -59,6 +59,18 @@ install_source = env.Install(lib_install_dir, source) install_lib = env.Install(lib_install_dir, shlib) install_test = env.Install(lib_install_dir, env.File('TestPythonSML.py')) +if "SOAR_PYTHON_ABI3" in env["ENV"]: + if env["SWIG_VERSION"] >= (4, 2, 0): + print("SOAR_PYTHON_ABI3 defined, building Python Limited API...") + # Signal to SConstruct that we're building the limited API + env["PYTHON_LIMITED_API"] = True + # Signal to the .i file that we're building the limited API + clone.Append(CPPDEFINES = { 'Soar_Python_ABI3': None }) + else: + print("'Requested building Python SML bindings with Python's Limited API, " + "while SWIG does not support it, aborting.'", file=sys.stderr) + Exit(1) + # We add soarlib to the python_sml explicitly, as some operating systems don't pick up on this dependency, # and crash the build. Import('soarlib') diff --git a/Core/ClientSMLSWIG/Python/pyproject.toml b/Core/ClientSMLSWIG/Python/pyproject.toml index a94b06a280..ac6910de91 100644 --- a/Core/ClientSMLSWIG/Python/pyproject.toml +++ b/Core/ClientSMLSWIG/Python/pyproject.toml @@ -127,6 +127,7 @@ skip = [ # # We pick python 3.9, since macOS ARM64 doesn't have 3.8, and so this is the earliest version on all platforms. build = "cp39*" +environment = { SOAR_PYTHON_ABI3="1" } # This test command: # - imports soar_sml # - creates the kernel diff --git a/Core/SConscript b/Core/SConscript index 04eabaca4c..04210628a9 100644 --- a/Core/SConscript +++ b/Core/SConscript @@ -16,21 +16,28 @@ def recursive_glob(treeroot, pattern): return results # ('SoarKernel/SoarKernel.cxx', recursive_glob(kernel_env.Dir('SoarKernel/src').abspath(), '*.cpp')), # Kernel -def CheckSWIG(env): +def SWIGVersion(env): if not env.WhereIs('swig'): - return False - + return None p = sub.Popen('swig -version'.split(), stdout=sub.PIPE) out = p.communicate()[0].decode().split() p.wait() - version = tuple(int(x) for x in out[2].split('.')) + return tuple(int(x) for x in out[2].split('.')) + + +def CheckSWIG(env): + version = SWIGVersion(env) + if version is None: + return False + if version >= (1, 3, 31): return True print('swig version 1.3.31 or higher is required') return False + kernel_env = env.Clone() # Windows DLLs need to get linked to dependencies, whereas Linux and Mac shared objects do not @@ -110,6 +117,7 @@ env.Alias('headers', headers) if not CheckSWIG(env): print('SWIG not found. Will not define sml_* build targets. Install swig to build wrappers for other languages.') else: + env["SWIG_VERSION"] = SWIGVersion(env) for x in 'Python Java Tcl CSharp'.split(): SConscript(os.path.join('ClientSMLSWIG', x, 'SConscript')) diff --git a/SConstruct b/SConstruct index 037efcfdb7..2dcf5fd641 100644 --- a/SConstruct +++ b/SConstruct @@ -421,8 +421,9 @@ if enscons_active: # and so we let it determine the wheel tag by itself. env['ROOT_IS_PURELIB'] = False - # This enables tagging the wheel with the limited api, and also sets the target python version. - env["LIMITED_API_TARGET"] = (3, 5) + if env.get('PYTHON_LIMITED_API', False): + # This enables tagging the wheel with the limited api, and also sets the target python version. + env["LIMITED_API_TARGET"] = (3, 5) # Whl and WhlFile add multiple targets (sdist, dist_info, bdist_wheel, editable) to env # for enscons (python build backend for scons; required for building with cibuildwheel).