support libxml2 python interface (#652)

* support libxml2 python interface

* upload patch file

* fix libxml2 without iconv

* use package:is_plat

* remove unused PYTHONPATH
pull/653/head
Hoildkv 3 years ago committed by GitHub
parent 8e274ddfe5
commit 86edd27446
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      packages/l/libiconv/port/xmake.lua
  2. 79
      packages/l/libxml2/patches/2.9.12/msvc.patch
  3. 90
      packages/l/libxml2/xmake.lua

@ -198,8 +198,7 @@ int test() { char* cs = nl_langinfo(CODESET); return !cs; }]])
configvar_check_csnippets("HAVE_ENVIRON_DECL=0", [[extern struct {int foo;} environ;
void test() {environ.foo = 1;}]], {includes = has_config("__HAVE_UNISTD_H") and "unistd.h" or "stdlib.h", default = 1})
target("libcharset")
set_prefixname("")
target("charset")
set_kind("$(kind)")
add_defines("HAVE_CONFIG_H")
if is_kind("shared") then
@ -217,10 +216,9 @@ target("libcharset")
end)
target_end()
target("libiconv")
set_prefixname("")
target("iconv")
set_kind("$(kind)")
add_deps("libcharset", {inherit = false})
add_deps("charset", {inherit = false})
add_defines("HAVE_CONFIG_H", "NO_XMALLOC", "IN_LIBRARY")
if is_kind("shared") then
add_defines("BUILDING_LIBICONV", "BUILDING_DLL")
@ -241,8 +239,7 @@ target("libiconv")
end)
target_end()
target("libicrt")
set_prefixname("")
target("icrt")
set_kind("static")
add_includedirs(".", "srclib", {public = true})
set_configdir(".")
@ -257,7 +254,7 @@ target("libicrt")
target("iconv_no_i18n")
set_kind("binary")
add_deps("libiconv", "libicrt")
add_deps("iconv", "icrt")
if has_config("installprefix") then
add_defines("INSTALLDIR=\"" .. path.join(get_config("installprefix"), "bin"):gsub("\\", "\\\\") .. "\"")
add_defines("LOCALEDIR=\"" .. path.join(get_config("installprefix"), "share", "locale"):gsub("\\", "\\\\") .. "\"")

@ -0,0 +1,79 @@
diff --git a/python/types.c b/python/types.c
--- a/python/types.c
+++ b/python/types.c
@@ -21,16 +21,66 @@
#if PY_MAJOR_VERSION >= 3
#include <stdio.h>
+#ifdef _WIN32
+#include <io.h>
+#else
#include <unistd.h>
#include <fcntl.h>
+#endif
FILE *
libxml_PyFileGet(PyObject *f) {
- int fd, flags;
+ int fd;
FILE *res;
const char *mode;
fd = PyObject_AsFileDescriptor(f);
+#ifdef _WIN32
+ PyObject *modeObj, *modeBytes;
+
+ modeObj = PyObject_GetAttrString(f, "mode");
+ if (!modeObj)
+ return(NULL);
+
+ /* using f.mode to replace posix fcntl(), see
+ * https://gist.github.com/novocaine/09d5c00e67fd0aa13cfc */
+ if (PyUnicode_Check(modeObj)) {
+ modeBytes = PyObject_CallMethod(
+ modeObj, "encode", "ascii", "namereplace");
+ if (!modeBytes) {
+ Py_DECREF(modeObj);
+ return(NULL);
+ }
+ mode = PyBytes_AsString(modeBytes);
+ if (!mode) {
+ Py_DECREF(modeObj);
+ return(NULL);
+ }
+ Py_DECREF(modeBytes);
+ } else if (PyBytes_Check(modeObj)) {
+ mode = PyBytes_AsString(modeObj);
+ if (!mode) {
+ Py_DECREF(modeObj);
+ return(NULL);
+ }
+ } else {
+ Py_DECREF(modeObj);
+ return(NULL);
+ }
+
+ Py_DECREF(modeObj);
+
+ fd = _dup(fd);
+ if (fd == -1)
+ return(NULL);
+ res = _fdopen(fd, mode);
+ if (!res) {
+ _close(fd);
+ return(NULL);
+ }
+ return(res);
+#else
+ int flags;
/*
* Get the flags on the fd to understand how it was opened
*/
@@ -76,6 +126,7 @@ libxml_PyFileGet(PyObject *f) {
return(NULL);
}
return(res);
+#endif
}
void libxml_PyFileRelease(FILE *f) {

@ -11,6 +11,11 @@ package("libxml2")
add_versions("2.9.10", "aafee193ffb8fe0c82d4afef6ef91972cbaf5feea100edc2f262750611b4be1f")
add_versions("2.9.12", "c8d6681e38c56f172892c85ddc0852e1fd4b53b4209e7f4ebf17f7e2eae71d92")
add_patches("2.9.12", path.join(os.scriptdir(), "patches", "2.9.12", "msvc.patch"), "b978048ad1caf9c63e3b2eee685ea2e586812d80deb1e47b18ad2cae36edd201")
add_configs("iconv", {description = "Enable libiconv support.", default = false, type = "boolean"})
add_configs("python", {description = "Enable the python interface.", default = false, type = "boolean"})
add_includedirs("include/libxml2")
if is_plat("windows") then
add_syslinks("wsock32", "ws2_32")
@ -22,22 +27,46 @@ package("libxml2")
add_syslinks("m")
end
on_load("windows", function (package)
on_load("windows", "macosx", "linux", "iphoneos", "android", function (package)
if package:is_plat("windows") then
if not package:config("shared") then
package:add("defines", "LIBXML_STATIC")
end
end)
on_load("macosx", "linux", "iphoneos", "android", function (package)
else
if package:gitref() then
package:add("deps", "autoconf", "automake", "libtool", "pkg-config")
end
end
if package:config("python") then
if not package:is_plat(os.host()) then
raise("libxml2 python interface does not support cross-compilation")
end
if not package:config("iconv") then
raise("libxml2 python interface requires iconv to be enabled")
end
package:add("deps", "python 3.x", {private = true})
end
if package:config("iconv") then
package:add("deps", "libiconv")
end
end)
on_install("windows", function (package)
os.cd("win32")
os.vrun("cscript configure.js iso8859x=yes iconv=no compiler=msvc cruntime=/%s debug=%s prefix=\"%s\"", package:config("vs_runtime"), package:debug() and "yes" or "no", package:installdir())
local args = {"configure.js", "iso8859x=yes", "zlib=no", "compiler=msvc"}
table.insert(args, "cruntime=/" .. package:config("vs_runtime"))
table.insert(args, "debug=" .. (package:debug() and "yes" or "no"))
table.insert(args, "iconv=" .. (package:config("iconv") and "yes" or "no"))
table.insert(args, "python=" .. (package:config("python") and "yes" or "no"))
table.insert(args, "prefix=" .. package:installdir())
if package:config("iconv") then
table.insert(args, "include=" .. package:dep("libiconv"):installdir("include"))
table.insert(args, "lib=" .. package:dep("libiconv"):installdir("lib"))
end
os.vrunv("cscript", args)
import("package.tools.nmake").install(package, {"/f", "Makefile.msvc"})
os.tryrm(path.join(package:installdir("bin"), "run*.exe"))
os.tryrm(path.join(package:installdir("bin"), "test*.exe"))
os.tryrm(path.join(package:installdir("lib"), "libxml2_a_dll.lib"))
if package:config("shared") then
os.tryrm(path.join(package:installdir("lib"), "libxml2_a.lib"))
@ -45,15 +74,28 @@ package("libxml2")
os.tryrm(path.join(package:installdir("lib"), "libxml2.lib"))
os.tryrm(path.join(package:installdir("bin"), "libxml2.dll"))
end
package:addenv("PATH", package:installdir("bin"))
if package:config("python") then
os.cd("../python")
io.replace("setup.py", "/opt/include", package:dep("libiconv"):installdir("include"):gsub("\\", "\\\\"), {plain = true})
io.replace("setup.py", "WITHDLLS = 1", "WITHDLLS = 0", {plain = true})
if not package:config("shared") then
io.replace("setup.py", "libdirs = [", format("libdirs = [\n'%s',", package:dep("libiconv"):installdir("lib"):gsub("\\", "\\\\")), {plain = true})
io.replace("setup.py", "platformLibs = []", "platformLibs = ['iconv','wsock32','ws2_32']", {plain = true})
io.replace("setup.py", "\"xml2\"", "\"xml2_a\"", {plain = true})
io.replace("setup.py", "macros = []", "macros = [('LIBXML_STATIC','1')]", {plain = true})
else
os.cp(path.join(package:installdir("bin"), "libxml2.dll"), path.join(package:installdir("lib"), "site-packages", "libxml2.dll"))
end
os.vrun("python setup.py install --prefix=\"" .. package:installdir() .. "\"")
package:addenv("PYTHONPATH", path.join(package:installdir("lib"), "site-packages"))
end
end)
on_install("macosx", "linux", "iphoneos", "android", function (package)
local configs = {"--disable-dependency-tracking",
"--with-pic",
"--without-python",
"--without-lzma",
"--without-zlib",
"--without-iconv"}
"--without-zlib"}
if package:config("shared") then
table.insert(configs, "--enable-shared=yes")
table.insert(configs, "--enable-static=no")
@ -61,9 +103,39 @@ package("libxml2")
table.insert(configs, "--enable-shared=no")
table.insert(configs, "--enable-static=yes")
end
if package:config("iconv") then
table.insert(configs, "--with-iconv=" .. package:dep("libiconv"):installdir())
else
table.insert(configs, "--without-iconv")
end
if package:config("python") then
table.insert(configs, "--with-python")
else
table.insert(configs, "--without-python")
end
if package:config("pic") ~= false then
table.insert(configs, "--with-pic")
end
import("package.tools.autoconf").install(package, configs)
package:addenv("PATH", package:installdir("bin"))
if package:config("python") then
os.cd("python")
io.replace("setup.py", "\"/usr/include\",\n\"/usr/local/include\",\n\"/opt/include\",", "\"" .. package:dep("libiconv"):installdir("include") .. "\",", {plain = true})
if not package:config("shared") then
io.replace("setup.py", "libdirs = [", format("libdirs = [\n'%s',", package:dep("libiconv"):installdir("lib")), {plain = true})
io.replace("setup.py", "platformLibs = [\"m\",\"z\"]", "platformLibs = [\"iconv\",\"m\"]", {plain = true})
else
io.replace("setup.py", "platformLibs = [\"m\",\"z\"]", "platformLibs = [\"m\"]", {plain = true})
end
os.vrun("python setup.py install --prefix=\"" .. package:installdir() .. "\"")
local pythonver = package:dep("python"):version()
package:addenv("PYTHONPATH", path.join(package:installdir("lib"), format("python%s.%s", pythonver:major(), pythonver:minor()), "site-packages"))
end
end)
on_test(function (package)
if package:config("python") then
os.vrun("python3 -c \"import libxml2\"")
end
assert(package:has_cfuncs("xmlNewNode", {includes = {"libxml/parser.h", "libxml/tree.h"}}))
end)

Loading…
Cancel
Save