diff --git a/configure.ac b/configure.ac index de959d58debd6bd5f6d20757965a5f961cd3a3b1_Y29uZmlndXJlLmFj..0d251255bd3273d82aa79fd145141b7b14fa5f89_Y29uZmlndXJlLmFj 100644 --- a/configure.ac +++ b/configure.ac @@ -549,6 +549,7 @@ libexslt/exsltconfig.h xsltproc/Makefile python/Makefile +python/setup.py python/tests/Makefile tests/Makefile tests/xmlspec/Makefile diff --git a/python/Makefile.am b/python/Makefile.am index de959d58debd6bd5f6d20757965a5f961cd3a3b1_cHl0aG9uL01ha2VmaWxlLmFt..0d251255bd3273d82aa79fd145141b7b14fa5f89_cHl0aG9uL01ha2VmaWxlLmFt 100644 --- a/python/Makefile.am +++ b/python/Makefile.am @@ -13,7 +13,8 @@ libxml_wrap.h \ libxslt_wrap.h \ libxsl.py \ - libxslt-python-api.xml + libxslt-python-api.xml \ + setup.py.in if WITH_PYTHON diff --git a/python/setup.py.in b/python/setup.py.in new file mode 100644 index 0000000000000000000000000000000000000000..0d251255bd3273d82aa79fd145141b7b14fa5f89_cHl0aG9uL3NldHVwLnB5Lmlu --- /dev/null +++ b/python/setup.py.in @@ -0,0 +1,203 @@ +#!/usr/bin/python -u +# +# Setup script for libxml2 and libxslt if found +# +import sys, os, subprocess + +try: + import setuptools +except ImportError: + pass + +from distutils.core import setup, Extension + +# Below ROOT, we expect to find include, include/libxml2, lib and bin. +# On *nix, it is not needed (but should not harm), +# on Windows, it is set by configure.js. +ROOT = r'@prefix@' + +# If this flag is set (windows only), +# a private copy of the dlls are included in the package. +# If this flag is not set, the libxml2 and libxslt +# dlls must be found somewhere in the PATH at runtime. +WITHDLLS = 1 and sys.platform.startswith('win') + +def missing(file): + if os.access(file, os.R_OK) == 0: + return 1 + return 0 + +try: + HOME = os.environ['HOME'] +except: + HOME="C:" + +if sys.platform.startswith('win'): + libraryPrefix = 'lib' + platformLibs = [] +else: + libraryPrefix = '' + platformLibs = ["m","z"] + +# those are examined to find +# - libxslt/xsltconfig.h +includes_dir = [ +"/usr/include", +"/usr/local/include", +"/opt/include", +os.path.join(ROOT,'include'), +HOME +]; + +# those are added in the linker search path for libraries +libdirs = [ +os.path.join(ROOT,'lib'), +] + +xslt_files = ["libxslt-api.xml", "libxslt-python-api.xml", + "libxslt.c", "libxsl.py", "libxslt_wrap.h", + "generator.py"] + +if WITHDLLS: + def altImport(s): + s = s.replace("import libxml2mod","from libxmlmods import libxml2mod") + s = s.replace("import libxsltmod","from libxsltmods import libxsltmod") + return s + +if missing("libxslt-py.c") or missing("libxslt.py"): + if missing("generator.py") or missing(os.path.join("..", "doc", "libxslt-api.xml")): + print("libxslt stub generator not found, libxslt not built") + else: + try: + if hasattr(subprocess, 'run'): + subprocess.run([sys.executable, + 'generator.py', + os.path.join('..', 'doc', 'libxslt-api.xml'), + 'libxslt-python-api.xml' + ], check=True) + else: + subprocess.check_output([sys.executable, + 'generator.py', + os.path.join('..', 'doc', 'libxslt-api.xml'), + 'libxslt-python-api.xml']) + except: + print("failed to generate stubs for libxslt, aborting ...") + print(sys.exc_info()[0], sys.exc_info()[1]) + else: + head = open("libxsl.py", "r") + generated = open("libxsltclass.py", "r") + result = open("libxslt.py", "w") + for line in head.readlines(): + if WITHDLLS: + result.write(altImport(line)) + else: + result.write(line) + for line in generated.readlines(): + result.write(line) + head.close() + generated.close() + result.close() + +xml_includes="" +for dir in includes_dir: + if not missing(dir + "/libxml2/libxml/tree.h"): + xml_includes=dir + "/libxml2" + break; + +if xml_includes == "": + print("failed to find headers for libxml2: update includes_dir") + sys.exit(1) + +xslt_includes="" +for dir in includes_dir: + if not missing(dir + "/libxslt/xsltconfig.h"): + xslt_includes=dir + "/libxslt" + break; + +if xslt_includes == "": + print("failed to find headers for libxslt: update includes_dir") + +if WITHDLLS: + # libxslt dlls (expected in ROOT/bin) + dlls = ['libxslt.dll','libexslt.dll'] + + packaged_dlls = [os.path.join(ROOT,'bin',dll) for dll in dlls] + + # create __init__.py for the libxsltmods package + if not os.path.exists("libxsltmods"): + os.mkdir("libxsltmods") + open("libxsltmods/__init__.py","w").close() + + packaged_dlls = [os.path.join(ROOT,'bin',dll) for dll in dlls] + +descr = "libxslt package" +modules = [ 'libxslt'] +if WITHDLLS: + modules.append('libxsltmods.__init__') +c_files = [] +includes= [xslt_includes, xml_includes] +libs = platformLibs +macros = [] + +descr = "libxslt package" +if not sys.platform.startswith('win'): + # + # We are gonna build 2 identical shared libs with merge initializing + # both libxml2mod and libxsltmod + # + c_files = c_files + ['libxslt-py.c', 'libxslt.c'] + xslt_c_files = c_files +else: + # + # On windows the MERGED_MODULE option is not needed + # (and does not work) + # + xslt_c_files = ['libxslt-py.c', 'libxslt.c', 'types.c'] +libs.insert(0, libraryPrefix + 'exslt') +libs.insert(0, libraryPrefix + 'xslt') +libs.insert(0, libraryPrefix + 'xml2') +includes.append(xslt_includes) +modules.append('libxslt') + + +extens=[Extension('libxsltmod', xslt_c_files, include_dirs=includes, + library_dirs=libdirs, + libraries=libs, define_macros=macros)] + +if missing("MANIFEST"): + + manifest = open("MANIFEST", "w") + manifest.write("setup.py\n") + for file in xslt_files: + manifest.write(file + "\n") + manifest.close() + +if WITHDLLS: + ext_package = "libxsltmods" + if sys.version >= "2.2": + base = "lib/site-packages/" + else: + base = "" + data_files = [(base+ext_package,packaged_dlls)] +else: + ext_package = None + data_files = [] + +setup (name = "libxslt-python", + # On *nix, the version number is created from setup.py.in + # On windows, it is set by configure.js + version = "@VERSION@", + description = descr, + author = "Daniel Veillard", + author_email = "veillard@redhat.com", + url = "https://gitlab.gnome.org/GNOME/libxslt", + licence="MIT Licence", + py_modules=modules, + ext_modules=extens, + ext_package=ext_package, + data_files=data_files, + install_requires=['libxml2_python>=@LIBXML_REQUIRED_VERSION@'], + ) + +sys.exit(0) + diff --git a/win32/configure.js b/win32/configure.js index de959d58debd6bd5f6d20757965a5f961cd3a3b1_d2luMzIvY29uZmlndXJlLmpz..0d251255bd3273d82aa79fd145141b7b14fa5f89_d2luMzIvY29uZmlndXJlLmpz 100644 --- a/win32/configure.js +++ b/win32/configure.js @@ -36,6 +36,7 @@ var verMajorExslt; var verMinorExslt; var verMicroExslt; +var verLibxmlReq; var verCvs; var useCvsVer = true; /* Libxslt features. */ @@ -48,6 +49,7 @@ var withCrypto = true; var withModules = false; var withProfiler = true; +var withPython = false; /* Win32 build options. */ var dirSep = "\\"; var compiler = "msvc"; @@ -108,6 +110,7 @@ txt += " crypto: Enable Crypto support (" + (withCrypto? "yes" : "no") + ")\n"; txt += " modules: Enable Module support (" + (withModules? "yes" : "no") + ")\n"; txt += " profiler: Enable Profiler support (" + (withProfiler? "yes" : "no") + ")\n"; + txt += " python: Build Python bindings (" + (withPython? "yes" : "no") + ")\n"; txt += "\nWin32 build options, default value given in parentheses:\n\n"; txt += " compiler: Compiler to be used [msvc|mingw] (" + compiler + ")\n"; txt += " cruntime: C-runtime compiler option (only msvc) (" + cruntime + ")\n"; @@ -169,6 +172,9 @@ } else if(s.search(/^LIBEXSLT_MICRO_VERSION=/) != -1) { vf.WriteLine(s); verMicroExslt = s.substring(s.indexOf("=") + 1, s.length); + } else if(s.search(/^LIBXML_REQUIRED_VERSION=/) != -1) { + vf.WriteLine(s); + verLibxmlReq = s.substring(s.indexOf("=") + 1, s.length); } } cf.Close(); @@ -181,6 +187,7 @@ vf.WriteLine("WITH_CRYPTO=" + (withCrypto? "1" : "0")); vf.WriteLine("WITH_MODULES=" + (withModules? "1" : "0")); vf.WriteLine("WITH_PROFILER=" + (withProfiler? "1" : "0")); + vf.WriteLine("WITH_PYTHON=" + (withPython? "1" : "0")); vf.WriteLine("DEBUG=" + (buildDebug? "1" : "0")); vf.WriteLine("STATIC=" + (buildStatic? "1" : "0")); vf.WriteLine("PREFIX=" + buildPrefix); @@ -251,8 +258,8 @@ while (ofi.AtEndOfStream != true) { ln = ofi.ReadLine(); s = new String(ln); - if (s.search(/\@LIBEXSLT_VERSION\@/) != -1) { - of.WriteLine(s.replace(/\@LIBEXSLT_VERSION\@/, + if (s.search(/\@VERSION\@/) != -1) { + of.WriteLine(s.replace(/\@VERSION\@/, verMajorExslt + "." + verMinorExslt + "." + verMicroExslt)); } else if (s.search(/\@LIBEXSLT_VERSION_NUMBER\@/) != -1) { of.WriteLine(s.replace(/\@LIBEXSLT_VERSION_NUMBER\@/, @@ -270,6 +277,51 @@ of.Close(); } +/* Configures Python bindings. Otherwise identical to the above */ +function configureLibxsltPy() +{ + var pyOptsFileIn = baseDir + "\\python\\setup.py.in"; + var pyOptsFile = baseDir + "\\python\\setup.py"; + var fso, ofi, of, ln, s; + fso = new ActiveXObject("Scripting.FileSystemObject"); + ofi = fso.OpenTextFile(pyOptsFileIn, 1); + of = fso.CreateTextFile(pyOptsFile, true); + while (ofi.AtEndOfStream != true) { + ln = ofi.ReadLine(); + s = new String(ln); + if (s.search(/\@VERSION\@/) != -1) { + of.WriteLine(s.replace(/\@VERSION\@/, + verMajorXslt + "." + verMinorXslt + "." + verMicroXslt)); + } else if (s.search(/\@prefix\@/) != -1) { + of.WriteLine(s.replace(/\@prefix\@/, buildPrefix)); + } else if (s.search(/\@LIBXSLT_VERSION_NUMBER\@/) != -1) { + of.WriteLine(s.replace(/\@LIBXSLT_VERSION_NUMBER\@/, + verMajorXslt*10000 + verMinorXslt*100 + verMicroXslt*1)); + } else if (s.search(/\@LIBXSLT_VERSION_EXTRA\@/) != -1) { + of.WriteLine(s.replace(/\@LIBXSLT_VERSION_EXTRA\@/, verCvs)); + } else if (s.search(/\@WITH_TRIO\@/) != -1) { + of.WriteLine(s.replace(/\@WITH_TRIO\@/, withTrio? "1" : "0")); + } else if (s.search(/\@WITH_XSLT_DEBUG\@/) != -1) { + of.WriteLine(s.replace(/\@WITH_XSLT_DEBUG\@/, withXsltDebug? "1" : "0")); + } else if (s.search(/\@WITH_MEM_DEBUG\@/) != -1) { + of.WriteLine(s.replace(/\@WITH_MEM_DEBUG\@/, withMemDebug? "1" : "0")); + } else if (s.search(/\@WITH_DEBUGGER\@/) != -1) { + of.WriteLine(s.replace(/\@WITH_DEBUGGER\@/, withDebugger? "1" : "0")); + } else if (s.search(/\@WITH_MODULES\@/) != -1) { + of.WriteLine(s.replace(/\@WITH_MODULES\@/, withModules? "1" : "0")); + } else if (s.search(/\@WITH_PROFILER\@/) != -1) { + of.WriteLine(s.replace(/\@WITH_PROFILER\@/, withProfiler? "1" : "0")); + } else if (s.search(/\@LIBXSLT_DEFAULT_PLUGINS_PATH\@/) != -1) { + of.WriteLine(s.replace(/\@LIBXSLT_DEFAULT_PLUGINS_PATH\@/, "NULL")); + } else if (s.search(/\@LIBXML_REQUIRED_VERSION\@/) != -1) { + of.WriteLine(s.replace(/\@LIBXML_REQUIRED_VERSION\@/, verLibxmlReq)); + } else + of.WriteLine(ln); + } + ofi.Close(); + of.Close(); +} + /* Creates the readme file for the binary distribution of 'bname', for the version 'ver' in the file 'file'. This one is called from the Makefile when generating a binary distribution. The parameters are passed by make. */ @@ -336,6 +388,8 @@ withModules = strToBool(arg.substring(opt.length + 1, arg.length)); else if (opt == "profiler") withProfiler = strToBool(arg.substring(opt.length + 1, arg.length)); + else if (opt == "python") + withPython = strToBool(arg.substring(opt.length + 1, arg.length)); else if (opt == "compiler") compiler = arg.substring(opt.length + 1, arg.length); else if (opt == "cruntime") @@ -432,6 +486,15 @@ WScript.Quit(error); } +if (withPython == true) { + configureLibxsltPy(); + if (error != 0) { + WScript.Echo("Configuration failed, aborting."); + WScript.Quit(error); + } + +} + // Configure libexslt. configureExslt(); if (error != 0) { @@ -469,6 +532,7 @@ txtOut += " Crypto: " + boolToStr(withCrypto) + "\n"; txtOut += " Modules: " + boolToStr(withModules) + "\n"; txtOut += " Profiler: " + boolToStr(withProfiler) + "\n"; +txtOut += " Python bindings: " + boolToStr(withPython) + "\n"; txtOut += "\n"; txtOut += "Win32 build configuration\n"; txtOut += "-------------------------\n";