[Libreoffice-commits] core.git: bin/gla11y config_host.mk.in configure.ac download.lst external/libxslt external/lxml external/Module_external.mk Makefile.fetch RepositoryExternal.mk solenv/gbuild

Samuel Thibault sthibault at hypra.fr
Wed Feb 28 21:54:47 UTC 2018


 Makefile.fetch                          |    1 
 RepositoryExternal.mk                   |    1 
 bin/gla11y                              |  167 ++++++++++++++++++++++++--------
 config_host.mk.in                       |    1 
 configure.ac                            |   36 ++++--
 download.lst                            |    2 
 external/Module_external.mk             |    1 
 external/libxslt/libxslt-config.patch.1 |    6 -
 external/lxml/ExternalProject_lxml.mk   |   42 ++++++++
 external/lxml/Makefile                  |    7 +
 external/lxml/Module_lxml.mk            |   17 +++
 external/lxml/README                    |    7 +
 external/lxml/UnpackedTarball_lxml.mk   |   14 ++
 solenv/gbuild/UIConfig.mk               |   18 +--
 solenv/gbuild/platform/com_GCC_class.mk |    9 +
 solenv/gbuild/platform/com_MSC_class.mk |   14 ++
 solenv/gbuild/platform/macosx.mk        |    2 
 solenv/gbuild/platform/solaris.mk       |    2 
 solenv/gbuild/platform/unxgcc.mk        |    2 
 19 files changed, 280 insertions(+), 69 deletions(-)

New commits:
commit 84ef6d82546b044990f4efd57e51e29c6c6565c8
Author: Samuel Thibault <sthibault at hypra.fr>
Date:   Wed Feb 21 15:51:11 2018 +0100

    Build external lxml if not provided by system
    
    except on windows, where gla11y will resort to python's internal xml parser,
    which does not provide line numbers.
    
    This allows gla11y to be runnable on all systems.
    
    Change-Id: Ica4eb90f59bddfcefd783fc2ed9c8c27357e7572
    Reviewed-on: https://gerrit.libreoffice.org/50115
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>

diff --git a/Makefile.fetch b/Makefile.fetch
index 58ed12b8e398..94f697ea9270 100644
--- a/Makefile.fetch
+++ b/Makefile.fetch
@@ -163,6 +163,7 @@ $(WORKDIR)/download: $(BUILDDIR)/config_$(gb_Side).mk $(SRCDIR)/download.lst $(S
 		XMLSEC_TARBALL \
 		$(call fetch_Optional,LIBXSLT,LIBXSLT_TARBALL) \
 		$(call fetch_Optional,LPSOLVE,LPSOLVE_TARBALL) \
+		$(call fetch_Optional,LXML,LXML_TARBALL) \
 		$(call fetch_Optional,MARIADB_CONNECTOR_C,MARIADB_CONNECTOR_C_TARBALL) \
 		$(call fetch_Optional,MDDS,MDDS_TARBALL) \
 		$(call fetch_Optional,MDNSRESPONDER,MDNSRESPONDER_TARBALL) \
diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index 85264b4afdf3..aecbd71b8b43 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -4017,6 +4017,7 @@ else
 
 define gb_ExternalExecutable__register_python
 $(call gb_ExternalExecutable_set_external,python,$(PYTHON_FOR_BUILD))
+$(call gb_ExternalExecutable_set_precommand,python,PYTHONPATH=$$$$PYTHONPATH$$$${PYTHONPATH:+$$$${PYPATH:+:}}$$$$PYPATH)
 
 endef
 
diff --git a/bin/gla11y b/bin/gla11y
index 04d5d83ccd1a..77a84840087a 100755
--- a/bin/gla11y
+++ b/bin/gla11y
@@ -31,33 +31,84 @@ from __future__ import print_function
 import os
 import sys
 import getopt
-import lxml.etree as ET
+try:
+    import lxml.etree as ET
+    lxml = True
+except ImportError:
+    import xml.etree.ElementTree as ET
+    lxml = False
 
 progname = os.path.basename(sys.argv[0])
+outfile = None
 Werror = False
 Wnone = False
 errors = 0
 warnings = 0
 
-
-def errstr(elm):
+def step_elm(elm):
+    """
+    Return the XML class path step corresponding to elm.
+    This can be empty if the elm does not have any class or id.
+    """
+    step = elm.attrib.get('class')
+    if step is None:
+        step = ""
+    oid = elm.attrib.get('id')
+    if oid is not None:
+        oid = oid.encode('ascii','ignore').decode('ascii')
+        step += "[@id='%s']" % oid
+    if len(step) > 0:
+        step += '/'
+    return step
+
+def find_elm(root, elm):
     """
-    Print the line number of the element
+    Return the XML class path of the element from the given root.
+    This is the slow version used when getparent is not available.
     """
+    if root == elm:
+        return ""
+    for o in root:
+        path = find_elm(o, elm)
+        if path is not None:
+            step = step_elm(o)
+            return step + path
+    return None
 
-    return str(elm.sourceline)
 
-def err(filename, elm, msg):
+def elm_prefix(filename, elm):
+    """
+    Return the display prefix of the element
+    """
+    if elm == None or not lxml:
+        return "%s:" % filename
+    else:
+        return "%s:%u" % (filename, elm.sourceline)
+
+def elm_name(elm):
+    """
+    Return a display name of the element
+    """
+    if elm is not None:
+        name = ""
+        if 'class' in elm.attrib:
+            name = "'%s' " % elm.attrib['class']
+        if 'id' in elm.attrib:
+            id = elm.attrib['id'].encode('ascii','ignore').decode('ascii')
+            name += "'%s' " % id
+        return name
+    return ""
+
+def err(filename, tree, elm, msg):
     global errors
 
-    if elm == None:
-        prefix = "%s:" % filename
-    else:
-        prefix = "%s:%s" % (filename, errstr(elm))
+    prefix = elm_prefix(filename, elm)
 
     errors += 1
-    msg = "%s ERROR: %s" % (prefix, msg)
-    print(msg.encode('ascii', 'ignore'))
+    msg = "%s ERROR: %s%s" % (prefix, elm_name(elm), msg)
+    print(msg)
+    if outfile is not None:
+        print(msg, file=outfile)
 
 
 def warn(filename, elm, msg):
@@ -66,61 +117,73 @@ def warn(filename, elm, msg):
     if Wnone:
         return
 
-    prefix = "%s:%s" % (filename, errstr(elm))
+    prefix = elm_prefix(filename, elm)
 
     if Werror:
         errors += 1
     else:
         warnings += 1
 
-    msg = "%s WARNING: %s" % (prefix,  msg)
-    print(msg.encode('ascii', 'ignore'))
+    msg = "%s WARNING: %s%s" % (prefix, elm_name(elm), msg)
+    print(msg)
+    if outfile is not None:
+        print(msg, file=outfile)
 
 
-def check_objects(filename, elm, objects, target):
+def check_objects(filename, tree, elm, objects, target):
     """
     Check that objects contains exactly one object
     """
     length = len(list(objects))
     if length == 0:
-        err(filename, elm, "use of undeclared target '%s'" % target)
+        err(filename, tree, elm, "uses undeclared target '%s'" % target)
     elif length > 1:
-        err(filename, elm, "several targets are named '%s'" % target)
+        err(filename, tree, elm, "several targets are named '%s'" % target)
 
-def check_props(filename, root, props):
+def check_props(filename, tree, root, elm, props):
     """
     Check the given list of relation properties
     """
     for prop in props:
         objects = root.iterfind(".//object[@id='%s']" % prop.text)
-        check_objects(filename, prop, objects, prop.text)
+        check_objects(filename, tree, elm, objects, prop.text)
 
-def check_rels(filename, root, rels):
+def check_rels(filename, tree, root, elm, rels):
     """
     Check the given list of relations
     """
     for rel in rels:
         target = rel.attrib['target']
         targets = root.iterfind(".//object[@id='%s']" % target)
-        check_objects(filename, rel, targets, target)
+        check_objects(filename, tree, elm, targets, target)
 
-def check_a11y_relation(filename, root):
+def elms_lines(elms):
+    """
+    Return the list of lines for the given elements.
+    """
+    if lxml:
+        return ": lines " + ', '.join([str(l.sourceline) for l in elms])
+    else:
+        return ""
+
+def check_a11y_relation(filename, tree):
     """
     Emit an error message if any of the 'object' elements of the XML
     document represented by `root' doesn't comply with Accessibility
     rules.
     """
+    root = tree.getroot()
 
     for obj in root.iter('object'):
 
         label_for = obj.findall("accessibility/relation[@type='label-for']")
-        check_rels(filename, root, label_for)
+        check_rels(filename, tree, root, obj, label_for)
 
         labelled_by = obj.findall("accessibility/relation[@type='labelled-by']")
-        check_rels(filename, root, labelled_by)
+        check_rels(filename, tree, root, obj, labelled_by)
 
         member_of = obj.findall("accessibility/relation[@type='member-of']")
-        check_rels(filename, root, member_of)
+        check_rels(filename, tree, root, obj, member_of)
 
         if obj.attrib['class'] == 'GtkLabel':
             # Case 0: A 'GtkLabel' must contain one or more "label-for"
@@ -130,14 +193,13 @@ def check_a11y_relation(filename, root):
 
             # ...a single "mnemonic_widget"
             properties = obj.findall("property[@name='mnemonic_widget']")
-            check_props(filename, root, properties)
+            check_props(filename, tree, root, obj, properties)
             if len(properties) > 1:
                 # It does not make sense for a label to be a mnemonic for
                 # several actions.
-                lines = ', '.join([str(p.sourceline) for p in properties])
-                err(filename, obj, "too many sub-elements"
+                err(filename, tree, obj, "multiple-mnemonic", "has too many sub-elements"
                     ", expected single <property name='mnemonic_widgets'>"
-                    ": lines %s" % lines)
+                    "%s" % elms_lines(properties))
                 continue
             if len(properties) == 1:
                 continue
@@ -148,10 +210,9 @@ def check_a11y_relation(filename, root):
         children = obj.findall("child[@internal-child='accessible']")
         if children:
             if len(children) > 1:
-                lines = ', '.join([str(c.sourceline) for c in children])
-                err(filename, obj, "too many sub-elements"
+                err(filename, tree, obj, "multiple-accessible", "has too many sub-elements"
                     ", expected single <child internal-child='accessible'>"
-                    ": lines %s" % lines)
+                    "%s" % elms_lines(children))
             continue
 
         # Case 2: has an <accessibility> sub-element with a "labelled-by"
@@ -164,42 +225,66 @@ def check_a11y_relation(filename, root):
 
 
 def usage():
-    print("%s [-W error|none] [file ...]" % progname,
+    print("%s [-W error|none] [-o LOG_FILE] [file ... | -L filelist]" % progname,
           file=sys.stderr)
+    print("  -o Also prints errors and warnings to given file");
     sys.exit(2)
 
 
 def main():
-    global Werror, Wnone, errors
+    global Werror, Wnone, errors, outfile
 
     try:
-        opts, args = getopt.getopt(sys.argv[1:], "pW:")
+        opts, args = getopt.getopt(sys.argv[1:], "W:o:L:")
     except getopt.GetoptError:
         usage()
 
+    out = None
+    filelist = None
     for o, a in opts:
         if o == "-W":
             if a == "error":
                 Werror = True
             elif a == "none":
                 Wnone = True
+        elif o == "-o":
+            out = a
+        elif o == "-L":
+            filelist = a
+
+    if out is not None:
+        outfile = open(out, 'w')
+
+    if filelist is not None:
+        try:
+            filelistfile = open(filelist, 'r')
+            for line in filelistfile.readlines():
+                line = line.strip()
+                if line:
+                    args += line.split(' ')
+            filelistfile.close()
+        except IOError:
+            err(filelist, None, None, "unable to read file list file")
 
     for filename in args:
         try:
             tree = ET.parse(filename)
         except ET.ParseError:
-            err(filename, None, "malformatted xml file")
+            err(filename, None, None, "malformatted xml file")
+            continue
         except IOError:
-            err(filename, None, "unable to read file")
+            err(filename, None, None, "unable to read file")
+            continue
 
         try:
-            check_a11y_relation(filename, tree.getroot())
+            check_a11y_relation(filename, tree)
         except Exception as error:
             import traceback
             traceback.print_exc()
-            err(filename, None, "error parsing file")
-
+            err(filename, None, None, "error parsing file")
 
+    if outfile is not None:
+        outfile.close()
     if errors > 0:
         sys.exit(1)
 
diff --git a/config_host.mk.in b/config_host.mk.in
index f4d7d67a6601..8ce71275ca5c 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -460,7 +460,6 @@ export PTHREAD_LIBS=@PTHREAD_LIBS@
 export PYTHON_CFLAGS=$(gb_SPACE)@PYTHON_CFLAGS@
 export PYTHON_FOR_BUILD=@PYTHON_FOR_BUILD@
 export PYTHON_LIBS=$(gb_SPACE)@PYTHON_LIBS@
-export PYTHON_LXML=@PYTHON_LXML@
 export PYTHON_VERSION=@PYTHON_VERSION@
 export PYTHON_VERSION_MAJOR=@PYTHON_VERSION_MAJOR@
 export PYTHON_VERSION_MINOR=@PYTHON_VERSION_MINOR@
diff --git a/configure.ac b/configure.ac
index 245aa7724434..f407c743babb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8147,19 +8147,36 @@ if test $enable_python = system; then
     PYTHON_FOR_BUILD=$PYTHON
 fi
 
-dnl By now enable_python should be "system", "internal" or "no"
-PYTHON_LXML=
-case $enable_python in
-system)
-    SYSTEM_PYTHON=TRUE
-
+if -z "$PYTHON_FOR_BUILD"; then
+    case $build_os in
+        cygwin)
+            AC_MSG_WARN([No system-provided python lxml, gla11y will only report widget classes and ids])
+            ;;
+        *)
+            BUILD_TYPE="$BUILD_TYPE LXML"
+            ;;
+    esac
+else
     AC_MSG_CHECKING([for python lxml])
-    if $PYTHON_FOR_BUILD -c "import lxml.etree as ET" ; then
-        PYTHON_LXML=TRUE
+    if $PYTHON_FOR_BUILD -c "import lxml.etree as ET" 2> /dev/null ; then
         AC_MSG_RESULT([yes])
     else
-        AC_MSG_RESULT([no, will not be able to check UI accessibility])
+        case $build_os in
+            cygwin)
+                AC_MSG_RESULT([no, gla11y will only report widget classes and ids])
+                ;;
+            *)
+                BUILD_TYPE="$BUILD_TYPE LXML"
+                AC_MSG_RESULT([no, using internal lxml])
+                ;;
+        esac
     fi
+fi
+
+dnl By now enable_python should be "system", "internal" or "no"
+case $enable_python in
+system)
+    SYSTEM_PYTHON=TRUE
 
     dnl Check if the headers really work
     save_CPPFLAGS="$CPPFLAGS"
@@ -8222,7 +8239,6 @@ AC_SUBST(DISABLE_PYTHON)
 AC_SUBST(SYSTEM_PYTHON)
 AC_SUBST(PYTHON_CFLAGS)
 AC_SUBST(PYTHON_LIBS)
-AC_SUBST(PYTHON_LXML)
 AC_SUBST(PYTHON_VERSION)
 AC_SUBST(PYTHON_VERSION_MAJOR)
 AC_SUBST(PYTHON_VERSION_MINOR)
diff --git a/download.lst b/download.lst
index ba14ad730162..3c29cf127c6e 100644
--- a/download.lst
+++ b/download.lst
@@ -160,6 +160,8 @@ export LIBXSLT_VERSION_MICRO := 32
 export LIBXSLT_TARBALL := libxslt-1.1.$(LIBXSLT_VERSION_MICRO).tar.gz
 export LPSOLVE_SHA256SUM := 171816288f14215c69e730f7a4f1c325739873e21f946ff83884b350574e6695
 export LPSOLVE_TARBALL := 26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz
+export LXML_SHA256SUM := 940caef1ec7c78e0c34b0f6b94fe42d0f2022915ffc78643d28538a5cfd0f40e
+export LXML_TARBALL := lxml-4.1.1.tgz
 export MARIADB_CONNECTOR_C_SHA256SUM := fd2f751dea049c1907735eb236aeace1d811d6a8218118b00bbaa9b84dc5cd60
 export MARIADB_CONNECTOR_C_TARBALL := a233181e03d3c307668b4c722d881661-mariadb_client-2.0.0-src.tar.gz
 export MDDS_SHA256SUM := dcb8cd2425567a5a5ec164afea475bce57784bca3e352ad4cbdd3d1a7e08e5a1
diff --git a/external/Module_external.mk b/external/Module_external.mk
index 41b895751d82..317c14d64d87 100644
--- a/external/Module_external.mk
+++ b/external/Module_external.mk
@@ -64,6 +64,7 @@ $(eval $(call gb_Module_add_moduledirs,external,\
 	$(call gb_Helper_optional,LIBXSLT,libxslt) \
 	$(call gb_Helper_optional,LPSOLVE,lpsolve) \
 	$(call gb_Helper_optional,LIBTOMMATH,libtommath) \
+	$(call gb_Helper_optional,LXML,lxml) \
 	$(call gb_Helper_optional,MARIADB_CONNECTOR_C,mariadb-connector-c) \
 	$(call gb_Helper_optional,MDDS,mdds) \
 	$(call gb_Helper_optional,MDNSRESPONDER,mdnsresponder) \
diff --git a/external/libxslt/libxslt-config.patch.1 b/external/libxslt/libxslt-config.patch.1
index 7e2936357671..5f9d107bd1e7 100644
--- a/external/libxslt/libxslt-config.patch.1
+++ b/external/libxslt/libxslt-config.patch.1
@@ -18,8 +18,8 @@ Hack the xslt-config to return paths into WORKDIR.
  exec_prefix_set=no
 -includedir=@includedir@
 -libdir=@libdir@
-+includedir=${WORKDIR}/UnpackedTarball/libxslt/libxslt
-+libdir=${WORKDIR}/UnpackedTarball/libxslt/libxslt/.libs
++includedir=${WORKDIR}/UnpackedTarball/libxslt
++libdir=${WORKDIR}/UnpackedTarball/libxslt
  
  usage()
  {
@@ -29,7 +29,7 @@ Hack the xslt-config to return paths into WORKDIR.
  
 -the_libs="@XSLT_LIBDIR@ @XSLT_LIBS@ @EXTRA_LIBS@"
 +#the_libs="@XSLT_LIBDIR@ @XSLT_LIBS@ @EXTRA_LIBS@"
-+the_libs="-L${libdir} -lxslt -lm"
++the_libs="-L${libdir}/libxslt/.libs -L${libdir}/libexslt/.libs -lxslt -lm"
  if test "$includedir" != "/usr/include"; then
      the_flags="$the_flags -I$includedir `@XML_CONFIG@ --cflags`"
  else
diff --git a/external/lxml/ExternalProject_lxml.mk b/external/lxml/ExternalProject_lxml.mk
new file mode 100644
index 000000000000..1e479d855ccf
--- /dev/null
+++ b/external/lxml/ExternalProject_lxml.mk
@@ -0,0 +1,42 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,lxml))
+
+$(eval $(call gb_ExternalProject_use_external_project,lxml,python3))
+$(eval $(call gb_ExternalProject_use_external_project,lxml,libxml2))
+$(eval $(call gb_ExternalProject_use_external_project,lxml,libxslt))
+$(eval $(call gb_ExternalProject_use_external_project,lxml,zlib))
+
+$(eval $(call gb_ExternalProject_register_targets,lxml,\
+	build \
+))
+
+lxml_PYTHON := $(call gb_ExternalExecutable_get_command,python)
+
+$(call gb_ExternalProject_get_state_target,lxml,build): \
+	$(call gb_ExternalExecutable_get_dependencies,python)
+	$(call gb_ExternalProject_run,build,\
+		PYPATH=$${PYPATH:+$$PYPATH:}$(call gb_UnpackedTarball_get_dir,lxml)/install && \
+		$(if $(PYTHON_FOR_BUILD), \
+			unset MACOSX_DEPLOYMENT_TARGET && , \
+			CFLAGS="$$CFLAGS -I$(call gb_UnpackedTarball_get_dir,python3)" && \
+			CFLAGS="$$CFLAGS -I$(call gb_UnpackedTarball_get_dir,python3)/Include" && \
+			LDFLAGS="$$LDFLAGS -L$(call gb_UnpackedTarball_get_dir,python3)" && \
+			_PYTHON_PROJECT_BASE=$(call gb_UnpackedTarball_get_dir,python3) && \
+			export CFLAGS LDFLAGS _PYTHON_PROJECT_BASE && ) \
+		$(lxml_PYTHON) setup.py build \
+			$(if $(SYSTEM_LIBXML),,--with-xml2-config=$(call gb_UnpackedTarball_get_dir,libxml2)/xml2-config) \
+			$(if $(SYSTEM_LIBXSLT),,--with-xslt-config=$(call gb_UnpackedTarball_get_dir,libxslt)/xslt-config) && \
+		mkdir install && \
+		$(lxml_PYTHON) setup.py install \
+			--install-lib install \
+	)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lxml/Makefile b/external/lxml/Makefile
new file mode 100644
index 000000000000..e4968cf85fb6
--- /dev/null
+++ b/external/lxml/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lxml/Module_lxml.mk b/external/lxml/Module_lxml.mk
new file mode 100644
index 000000000000..9fe3b85ad170
--- /dev/null
+++ b/external/lxml/Module_lxml.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,lxml))
+
+$(eval $(call gb_Module_add_targets,lxml,\
+	UnpackedTarball_lxml \
+	ExternalProject_lxml \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lxml/README b/external/lxml/README
new file mode 100644
index 000000000000..ad9f0952c6b3
--- /dev/null
+++ b/external/lxml/README
@@ -0,0 +1,7 @@
+LXML XML processing python Library from [http://lxml.de/].
+
+This library is used for the .ui accessibility checker bin/gla11y
+
+The archive was downloaded from:
+[http://lxml.de/files/lxml-4.1.1.tgz]
+on 2018-02-22.
diff --git a/external/lxml/UnpackedTarball_lxml.mk b/external/lxml/UnpackedTarball_lxml.mk
new file mode 100644
index 000000000000..bfb5dc2b046f
--- /dev/null
+++ b/external/lxml/UnpackedTarball_lxml.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,lxml))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,lxml,$(LXML_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/UIConfig.mk b/solenv/gbuild/UIConfig.mk
index e7de81a25839..0de62d712009 100644
--- a/solenv/gbuild/UIConfig.mk
+++ b/solenv/gbuild/UIConfig.mk
@@ -94,7 +94,11 @@ endef
 # * UIConfig/<name> containing all nontranslatable files
 
 gb_UIConfig_INSTDIR := $(LIBO_SHARE_FOLDER)/config/soffice.cfg
-gb_UIConfig_a11yerrors_COMMAND = $(PYTHON_FOR_BUILD) $(SRCDIR)/bin/gla11y
+
+ifneq ($(filter LXML,$(BUILD_TYPE)),)
+gb_UIConfig_LXML_PATH := PYPATH=$${PYPATH:+$$PYPATH:}$(call gb_UnpackedTarball_get_dir,lxml)/install ;
+endif
+gb_UIConfig_gla11y_SCRIPT := $(SRCDIR)/bin/gla11y
 
 $(dir $(call gb_UIConfig_get_target,%)).dir :
 	$(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
@@ -122,17 +126,11 @@ $(call gb_UIConfig_get_clean_target,%) :
 
 define gb_UIConfig_a11yerrors__command
 $(call gb_Output_announce,$(2),$(true),UIA,1)
-$(call gb_Helper_abbreviate_dirs,\
-	$(gb_UIConfig_a11yerrors_COMMAND) -W none $(UIFILES) > $@
-)
+$(call gb_UIConfig__gla11y_command)
 endef
 
-$(call gb_UIConfig_get_a11yerrors_target,%) : $(gb_UIConfig_a11yerrors_COMMAND)
-ifeq ($(PYTHON_LXML),TRUE)
+$(call gb_UIConfig_get_a11yerrors_target,%) : $(call gb_ExternalProject_get_target,lxml) $(call gb_ExternalExecutable_get_dependencies,python) $(gb_UIConfig_gla11y_SCRIPT)
 	$(call gb_UIConfig_a11yerrors__command,$@,$*)
-else
-	touch $@
-endif
 
 gb_UIConfig_get_packagename = UIConfig/$(1)
 gb_UIConfig_get_packagesetname = UIConfig/$(1)
@@ -186,7 +184,7 @@ $(call gb_UIConfig_get_imagelist_target,$(1)) : UI_IMAGELISTS += $(call gb_UIIma
 $(call gb_UIConfig_get_imagelist_target,$(1)) : $(call gb_UIImageListTarget_get_target,$(2))
 $(call gb_UIConfig_get_clean_target,$(1)) : $(call gb_UIImageListTarget_get_clean_target,$(2))
 
-$(call gb_UIConfig_get_a11yerrors_target,$(1)) : UIFILES += $(SRCDIR)/$(2).ui
+$(call gb_UIConfig_get_a11yerrors_target,$(1)) : UIFILES += $(2).ui
 
 endef
 
diff --git a/solenv/gbuild/platform/com_GCC_class.mk b/solenv/gbuild/platform/com_GCC_class.mk
index e2caff2a5a9b..2d4c2cf90a98 100644
--- a/solenv/gbuild/platform/com_GCC_class.mk
+++ b/solenv/gbuild/platform/com_GCC_class.mk
@@ -155,4 +155,13 @@ $(call gb_Helper_abbreviate_dirs,\
 
 endef
 
+define gb_UIConfig__gla11y_command
+$(call gb_Helper_abbreviate_dirs,\
+	$(gb_UIConfig_LXML_PATH) $(gb_Helper_set_ld_path) \
+	$(call gb_ExternalExecutable_get_command,python) \
+	$(gb_UIConfig_gla11y_SCRIPT) -o $@ $(UIFILES)
+)
+
+endef
+
 # vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/com_MSC_class.mk b/solenv/gbuild/platform/com_MSC_class.mk
index 27a0aec80c4b..271459635a3c 100644
--- a/solenv/gbuild/platform/com_MSC_class.mk
+++ b/solenv/gbuild/platform/com_MSC_class.mk
@@ -576,6 +576,18 @@ $(call gb_Helper_abbreviate_dirs,\
 
 endef
 
+# use file list file because swriter has too many files for command line
+define gb_UIConfig__gla11y_command
+$(call gb_ExternalExecutale__check_registration,python)
+$(call gb_Helper_abbreviate_dirs,\
+	FILES=$(call var2file,$(shell $(gb_MKTEMP)),100,$(UIFILES)) && \
+	$(gb_UIConfig_LXML_PATH) $(gb_Helper_set_ld_path) \
+	$(call gb_ExternalExecutable_get_command,python) \
+	$(gb_UIConfig_gla11y_SCRIPT) -o $@ -L $$FILES
+)
+
+endef
+
 # UIMenubarTarget class
 
 define gb_UIMenubarTarget__command
@@ -587,7 +599,7 @@ endef
 gb_UIMenubarTarget_UIMenubarTarget_platform :=
 
 # Python
-gb_Python_PRECOMMAND := PATH="$(shell cygpath -w $(INSTDIR)/program)" PYTHONHOME="$(INSTDIR)/program/python-core-$(PYTHON_VERSION)" PYTHONPATH="$(INSTDIR)/program/python-core-$(PYTHON_VERSION)/lib;$(INSTDIR)/program/python-core-$(PYTHON_VERSION)/lib/lib-dynload:$(INSTDIR)/program"
+gb_Python_PRECOMMAND := PATH="$(shell cygpath -w $(INSTDIR)/program)" PYTHONHOME="$(INSTDIR)/program/python-core-$(PYTHON_VERSION)" PYTHONPATH="$${PYPATH:+$$PYPATH:}$(INSTDIR)/program/python-core-$(PYTHON_VERSION)/lib;$(INSTDIR)/program/python-core-$(PYTHON_VERSION)/lib/lib-dynload:$(INSTDIR)/program"
 gb_Python_INSTALLED_EXECUTABLE := $(INSTROOT)/$(LIBO_BIN_FOLDER)/python.exe
 
 gb_ICU_PRECOMMAND := PATH="$(shell cygpath -w $(WORKDIR_FOR_BUILD)/UnpackedTarball/icu/source/lib)"
diff --git a/solenv/gbuild/platform/macosx.mk b/solenv/gbuild/platform/macosx.mk
index 626f399a42c8..781af67f2268 100644
--- a/solenv/gbuild/platform/macosx.mk
+++ b/solenv/gbuild/platform/macosx.mk
@@ -364,7 +364,7 @@ $(call gb_UIMenubarTarget_get_target,$(1)) :| $(call gb_ExternalExecutable_get_d
 endef
 
 # Python
-gb_Python_PRECOMMAND :=
+gb_Python_PRECOMMAND := PYTHONPATH="$$PYPATH"
 gb_Python_INSTALLED_EXECUTABLE := $(INSTROOT)/$(LIBO_LIB_FOLDER)/LibreOfficePython.framework/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/Resources/Python.app/Contents/MacOS/LibreOfficePython
 # this is passed to gdb as executable when running tests
 gb_Python_INSTALLED_EXECUTABLE_GDB := $(gb_Python_INSTALLED_EXECUTABLE)
diff --git a/solenv/gbuild/platform/solaris.mk b/solenv/gbuild/platform/solaris.mk
index f20ebb9a3db7..2210d4f972d1 100644
--- a/solenv/gbuild/platform/solaris.mk
+++ b/solenv/gbuild/platform/solaris.mk
@@ -359,7 +359,7 @@ endef
 gb_UIMenubarTarget_UIMenubarTarget_platform :=
 
 # Python
-gb_Python_PRECOMMAND := $(gb_Helper_set_ld_path) PYTHONHOME="$(INSTDIR)/program/python-core-$(PYTHON_VERSION)" PYTHONPATH="$(INSTDIR)/program/python-core-$(PYTHON_VERSION)/lib:$(INSTDIR)/program/python-core-$(PYTHON_VERSION)/lib/lib-dynload"
+gb_Python_PRECOMMAND := $(gb_Helper_set_ld_path) PYTHONHOME="$(INSTDIR)/program/python-core-$(PYTHON_VERSION)" PYTHONPATH="$${PYPATH:+$$PYPATH:}$(INSTDIR)/program/python-core-$(PYTHON_VERSION)/lib:$(INSTDIR)/program/python-core-$(PYTHON_VERSION)/lib/lib-dynload:$(INSTDIR)/program"
 gb_Python_INSTALLED_EXECUTABLE := /bin/sh $(INSTROOT)/program/python
 # this is passed to gdb as executable when running tests
 gb_Python_INSTALLED_EXECUTABLE_GDB := $(INSTROOT)/program/python.bin
diff --git a/solenv/gbuild/platform/unxgcc.mk b/solenv/gbuild/platform/unxgcc.mk
index 4a3a189c91e9..8505f9638a19 100644
--- a/solenv/gbuild/platform/unxgcc.mk
+++ b/solenv/gbuild/platform/unxgcc.mk
@@ -386,7 +386,7 @@ endef
 gb_UIMenubarTarget_UIMenubarTarget_platform :=
 
 # Python
-gb_Python_PRECOMMAND := $(gb_Helper_set_ld_path) PYTHONHOME="$(INSTDIR)/program/python-core-$(PYTHON_VERSION)" PYTHONPATH="$(INSTDIR)/program/python-core-$(PYTHON_VERSION)/lib:$(INSTDIR)/program/python-core-$(PYTHON_VERSION)/lib/lib-dynload"
+gb_Python_PRECOMMAND := $(gb_Helper_set_ld_path) PYTHONHOME="$(INSTDIR)/program/python-core-$(PYTHON_VERSION)" PYTHONPATH="$${PYPATH:+$$PYPATH:}$(INSTDIR)/program/python-core-$(PYTHON_VERSION)/lib:$(INSTDIR)/program/python-core-$(PYTHON_VERSION)/lib/lib-dynload"
 gb_Python_INSTALLED_EXECUTABLE := /bin/sh $(INSTROOT)/program/python
 # this is passed to gdb as executable when running tests
 gb_Python_INSTALLED_EXECUTABLE_GDB := $(INSTROOT)/program/python.bin


More information about the Libreoffice-commits mailing list