summaryrefslogtreecommitdiffstats
path: root/solenv/gbuild
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /solenv/gbuild
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--solenv/gbuild/AllLangHelp.mk172
-rw-r--r--solenv/gbuild/AllLangMoTarget.mk100
-rw-r--r--solenv/gbuild/AllLangPackage.mk124
-rw-r--r--solenv/gbuild/AutoInstall.mk76
-rw-r--r--solenv/gbuild/CliAssembly.mk209
-rw-r--r--solenv/gbuild/CliLibrary.mk148
-rw-r--r--solenv/gbuild/CliNativeLibrary.mk111
-rw-r--r--solenv/gbuild/CliUnoApi.mk122
-rw-r--r--solenv/gbuild/CompilerTest.mk53
-rw-r--r--solenv/gbuild/ComponentTarget.mk109
-rw-r--r--solenv/gbuild/Conditions.mk39
-rw-r--r--solenv/gbuild/Configuration.mk456
-rw-r--r--solenv/gbuild/CppunitTest.mk495
-rw-r--r--solenv/gbuild/CustomTarget.mk136
-rw-r--r--solenv/gbuild/Deliver.mk69
-rw-r--r--solenv/gbuild/Dictionary.mk401
-rw-r--r--solenv/gbuild/Executable.mk173
-rw-r--r--solenv/gbuild/Extension.mk494
-rw-r--r--solenv/gbuild/ExtensionPackage.mk95
-rw-r--r--solenv/gbuild/ExternalExecutable.mk216
-rw-r--r--solenv/gbuild/ExternalPackage.mk207
-rw-r--r--solenv/gbuild/ExternalProject.mk238
-rw-r--r--solenv/gbuild/Gallery.mk183
-rw-r--r--solenv/gbuild/GeneratedPackage.mk106
-rw-r--r--solenv/gbuild/HelpTarget.mk836
-rw-r--r--solenv/gbuild/Helper.mk354
-rw-r--r--solenv/gbuild/InstallModule.mk88
-rw-r--r--solenv/gbuild/InstallModuleTarget.mk312
-rw-r--r--solenv/gbuild/InstallScript.mk84
-rw-r--r--solenv/gbuild/InternalUnoApi.mk82
-rw-r--r--solenv/gbuild/Jar.mk287
-rw-r--r--solenv/gbuild/JavaClassSet.mk195
-rw-r--r--solenv/gbuild/JunitTest.mk234
-rw-r--r--solenv/gbuild/Library.mk296
-rw-r--r--solenv/gbuild/LinkTarget.mk2264
-rw-r--r--solenv/gbuild/Module.mk495
-rw-r--r--solenv/gbuild/Output.mk157
-rw-r--r--solenv/gbuild/Package.mk227
-rw-r--r--solenv/gbuild/PackageSet.mk77
-rw-r--r--solenv/gbuild/Pagein.mk61
-rw-r--r--solenv/gbuild/Postprocess.mk56
-rw-r--r--solenv/gbuild/PrecompiledHeaders.mk184
-rw-r--r--solenv/gbuild/PythonTest.mk129
-rw-r--r--solenv/gbuild/Pyuno.mk79
-rw-r--r--solenv/gbuild/README17
-rw-r--r--solenv/gbuild/Rdb.mk75
-rw-r--r--solenv/gbuild/SdiTarget.mk83
-rw-r--r--solenv/gbuild/StaticLibrary.mk118
-rw-r--r--solenv/gbuild/TargetLocations.mk487
-rw-r--r--solenv/gbuild/Tempfile.mk45
-rw-r--r--solenv/gbuild/TestHelpers.mk47
-rw-r--r--solenv/gbuild/Trace.mk61
-rw-r--r--solenv/gbuild/UIConfig.mk358
-rw-r--r--solenv/gbuild/UITest.mk157
-rw-r--r--solenv/gbuild/UnoApi.mk104
-rw-r--r--solenv/gbuild/UnoApiTarget.mk250
-rw-r--r--solenv/gbuild/UnpackedTarball.mk455
-rw-r--r--solenv/gbuild/WinResTarget.mk123
-rw-r--r--solenv/gbuild/Zip.mk154
-rw-r--r--solenv/gbuild/empty.zipbin0 -> 22 bytes
-rw-r--r--solenv/gbuild/extensions/post_Counters.mk22
-rw-r--r--solenv/gbuild/extensions/post_Fuzzers.mk17
-rw-r--r--solenv/gbuild/extensions/post_GbuildToJson.mk202
-rw-r--r--solenv/gbuild/extensions/post_PackageInfo.mk116
-rw-r--r--solenv/gbuild/extensions/post_SpeedUpTargets.mk88
-rw-r--r--solenv/gbuild/extensions/pre_BuildTools.mk54
-rw-r--r--solenv/gbuild/extensions/pre_Counters.mk31
-rw-r--r--solenv/gbuild/extensions/pre_MergedLibsList.mk122
-rw-r--r--solenv/gbuild/gbuild.help.txt159
-rw-r--r--solenv/gbuild/gbuild.mk406
-rw-r--r--solenv/gbuild/gen-autoinstall.py98
-rw-r--r--solenv/gbuild/partial_build.mk46
-rw-r--r--solenv/gbuild/platform/ANDROID_AARCH64_GCC.mk17
-rw-r--r--solenv/gbuild/platform/ANDROID_ARM_GCC.mk17
-rw-r--r--solenv/gbuild/platform/ANDROID_INTEL_GCC.mk17
-rw-r--r--solenv/gbuild/platform/ANDROID_X86_64_GCC.mk15
-rw-r--r--solenv/gbuild/platform/DRAGONFLY_INTEL_GCC.mk18
-rw-r--r--solenv/gbuild/platform/DRAGONFLY_X86_64_GCC.mk16
-rw-r--r--solenv/gbuild/platform/DeclareDPIAware.manifest7
-rw-r--r--solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk95
-rw-r--r--solenv/gbuild/platform/FREEBSD_AARCH64_GCC.mk14
-rw-r--r--solenv/gbuild/platform/FREEBSD_INTEL_GCC.mk16
-rw-r--r--solenv/gbuild/platform/FREEBSD_POWERPC64_GCC.mk17
-rw-r--r--solenv/gbuild/platform/FREEBSD_POWERPC_GCC.mk16
-rw-r--r--solenv/gbuild/platform/FREEBSD_X86_64_GCC.mk14
-rw-r--r--solenv/gbuild/platform/HAIKU_INTEL_GCC.mk16
-rw-r--r--solenv/gbuild/platform/HAIKU_X86_64_GCC.mk14
-rw-r--r--solenv/gbuild/platform/LINUX_AARCH64_GCC.mk12
-rw-r--r--solenv/gbuild/platform/LINUX_ARM_GCC.mk16
-rw-r--r--solenv/gbuild/platform/LINUX_AXP_GCC.mk16
-rw-r--r--solenv/gbuild/platform/LINUX_GODSON64_GCC.mk16
-rw-r--r--solenv/gbuild/platform/LINUX_GODSON_GCC.mk16
-rw-r--r--solenv/gbuild/platform/LINUX_HPPA_GCC.mk14
-rw-r--r--solenv/gbuild/platform/LINUX_IA64_GCC.mk14
-rw-r--r--solenv/gbuild/platform/LINUX_INTEL_GCC.mk16
-rw-r--r--solenv/gbuild/platform/LINUX_M68K_GCC.mk15
-rw-r--r--solenv/gbuild/platform/LINUX_POWERPC64_GCC.mk15
-rw-r--r--solenv/gbuild/platform/LINUX_POWERPC_GCC.mk15
-rw-r--r--solenv/gbuild/platform/LINUX_S390X_GCC.mk14
-rw-r--r--solenv/gbuild/platform/LINUX_S390_GCC.mk14
-rw-r--r--solenv/gbuild/platform/LINUX_SPARC64_GCC.mk15
-rw-r--r--solenv/gbuild/platform/LINUX_SPARC_GCC.mk15
-rw-r--r--solenv/gbuild/platform/LINUX_X86_64_GCC.mk14
-rw-r--r--solenv/gbuild/platform/MACOSX_AARCH64_GCC.mk13
-rw-r--r--solenv/gbuild/platform/MACOSX_X86_64_GCC.mk13
-rw-r--r--solenv/gbuild/platform/NETBSD_INTEL_GCC.mk21
-rw-r--r--solenv/gbuild/platform/NETBSD_X86_64_GCC.mk20
-rw-r--r--solenv/gbuild/platform/OPENBSD_INTEL_GCC.mk17
-rw-r--r--solenv/gbuild/platform/OPENBSD_X86_64_GCC.mk16
-rw-r--r--solenv/gbuild/platform/SOLARIS_INTEL_GCC.mk14
-rw-r--r--solenv/gbuild/platform/SOLARIS_SPARC_GCC.mk16
-rw-r--r--solenv/gbuild/platform/WNT_AARCH64_MSC.mk26
-rw-r--r--solenv/gbuild/platform/WNT_INTEL_MSC.mk26
-rw-r--r--solenv/gbuild/platform/WNT_X86_64_MSC.mk26
-rw-r--r--solenv/gbuild/platform/android.mk129
-rw-r--r--solenv/gbuild/platform/com_GCC_class.mk255
-rw-r--r--solenv/gbuild/platform/com_GCC_defs.mk335
-rw-r--r--solenv/gbuild/platform/com_MSC_class.mk742
-rw-r--r--solenv/gbuild/platform/com_MSC_defs.mk352
-rwxr-xr-xsolenv/gbuild/platform/filter-creatingLibrary.awk46
-rwxr-xr-xsolenv/gbuild/platform/filter-showIncludes.awk99
-rwxr-xr-xsolenv/gbuild/platform/filter-sourceName.awk32
-rw-r--r--solenv/gbuild/platform/iOS.mk269
-rw-r--r--solenv/gbuild/platform/iOS_AARCH64_GCC.mk22
-rw-r--r--solenv/gbuild/platform/iOS_X86_64_GCC.mk22
-rw-r--r--solenv/gbuild/platform/linux.mk24
-rw-r--r--solenv/gbuild/platform/macosx.mk381
-rw-r--r--solenv/gbuild/platform/solaris.mk357
-rwxr-xr-xsolenv/gbuild/platform/unittest-failed-MACOSX.sh46
-rwxr-xr-xsolenv/gbuild/platform/unittest-failed-WNT.sh47
-rwxr-xr-xsolenv/gbuild/platform/unittest-failed-default.sh51
-rw-r--r--solenv/gbuild/platform/unxgcc.mk427
-rw-r--r--solenv/gbuild/platform/win_compatibility.manifest15
-rw-r--r--solenv/gbuild/platform/windows.mk60
-rw-r--r--solenv/gbuild/static.mk247
-rwxr-xr-xsolenv/gbuild/uitest-failed-default.sh45
-rw-r--r--solenv/gbuildtojson/gbuildtojson.cxx74
137 files changed, 19755 insertions, 0 deletions
diff --git a/solenv/gbuild/AllLangHelp.mk b/solenv/gbuild/AllLangHelp.mk
new file mode 100644
index 000000000..32d38166d
--- /dev/null
+++ b/solenv/gbuild/AllLangHelp.mk
@@ -0,0 +1,172 @@
+# -*- 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/.
+#
+
+# class AllLangHelp
+
+# Creates and delivers all language versions of a module.
+
+gb_AllLangHelp_HELPDIRNAME := helpcontent2
+gb_AllLangHelp_AUXDIRNAME := auxiliary
+gb_AllLangHelp_HELPDIR := $(gb_AllLangHelp_HELPDIRNAME)/source
+gb_AllLangHelp_AUXDIR := $(gb_AllLangHelp_HELPDIR)/$(gb_AllLangHelp_AUXDIRNAME)
+
+gb_AllLangHelp__get_helpname = $(1)/$(2)
+
+ifneq ($(ENABLE_HTMLHELP),)
+$(call gb_AllLangHelp_get_helpfiles_target,%): | \
+ $(dir $(call gb_AllLangHelp_get_helpfiles_target,%)).dir
+ touch $@
+endif
+
+$(dir $(call gb_AllLangHelp_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_AllLangHelp_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_AllLangHelp_get_target,%) :
+ifeq ($(ENABLE_HTMLHELP),)
+ $(call gb_Output_announce,$*,$(true),ALH,5)
+ $(call gb_Trace_MakeMark,$*,ALH)
+endif
+ touch $@
+
+$(call gb_AllLangHelp_get_clean_target,%) :
+ifeq ($(ENABLE_HTMLHELP),)
+ $(call gb_Output_announce,$*,$(false),ALH,5)
+endif
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_AllLangHelp_get_target,$*) $(call gb_AllLangHelp_get_helpfiles_target,$*) \
+ )
+
+# gb_AllLangHelp_AllLangHelp__one_lang module lang helpname
+define gb_AllLangHelp_AllLangHelp__one_lang
+$(call gb_HelpTarget_HelpTarget,$(3),$(1),$(2))
+$(call gb_HelpTarget_set_helpdir,$(3),$(gb_AllLangHelp_HELPDIR))
+
+$(call gb_AllLangHelp_get_target,$(1)) : $(call gb_HelpTarget_get_target,$(3))
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_AllLangHelp_get_target,$(1)) : $(call gb_Package_get_target,$(call gb_HelpTarget_get_packagename,$(3)))
+endif
+$(call gb_AllLangHelp_get_clean_target,$(1)) : $(call gb_HelpTarget_get_clean_target,$(3))
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_AllLangHelp_get_clean_target,$(1)) : $(call gb_Package_get_clean_target,$(call gb_HelpTarget_get_packagename,$(3)))
+endif
+
+endef
+
+# Create and deliver help packs for a module for all languages.
+#
+# gb_AllLangHelp_AllLangHelp module
+gb_AllLangHelp_ALLTARGETS :=
+
+define gb_AllLangHelp_AllLangHelp
+gb_AllLangHelp_ALLTARGETS += $(1)
+$(foreach lang,$(gb_HELP_LANGS),\
+ $(call gb_AllLangHelp_AllLangHelp__one_lang,$(1),$(lang),$(call gb_AllLangHelp__get_helpname,$(1),$(lang))))
+
+$(call gb_AllLangHelp_get_target,$(1)) :| $(dir $(call gb_AllLangHelp_get_target,$(1))).dir
+
+$$(eval $$(call gb_Module_register_target,$(call gb_AllLangHelp_get_target,$(1)),$(call gb_AllLangHelp_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),AllLangHelp)
+
+endef
+
+# gb_AllLangHelp_set_treefile module treefile
+define gb_AllLangHelp_set_treefile
+$(foreach lang,$(gb_HELP_LANGS),\
+ $(call gb_HelpTarget_set_treefile,$(call gb_AllLangHelp__get_helpname,$(1),$(lang)),$(2),$(gb_AllLangHelp_HELPDIR)/text) \
+)
+
+endef
+
+# Add one or more help files.
+#
+# gb_AllLangHelp_add_helpfiles module file(s) [optional bookmark token]
+define gb_AllLangHelp_add_helpfiles
+$(foreach lang,$(gb_HELP_LANGS),\
+ $(call gb_HelpTarget_add_helpfiles,$(call gb_AllLangHelp__get_helpname,$(1),$(lang)),$(2)) \
+)
+ifneq ($(ENABLE_HTMLHELP),)
+gb_AllLangHelp_$(1)_HELPFILES += $(addsuffix .xhp,$(2))
+gb_AllLangHelp_$(or $(3),$(1))_BOOKMARK_HELPFILES += $(addsuffix .xhp,$(2))
+$(call gb_AllLangHelp_get_helpfiles_target,$(1)): $(addprefix $(SRCDIR)/,$(addsuffix .xhp,$(2)))
+endif
+
+endef
+
+# Add additional localized file(s) to the help pack.
+#
+# gb_AllLangHelp_add_localized_files module basedir file(s)
+define gb_AllLangHelp_add_localized_files
+$(foreach lang,$(gb_HELP_LANGS),\
+ $(call gb_HelpTarget_add_files,$(call gb_AllLangHelp__get_helpname,$(1),$(lang)),$(addprefix $(2)/$(lang)/,$(3))) \
+)
+
+endef
+
+# Add a localized file from helpdir under a new name.
+#
+# This is a hack needed for err.html in shared help module.
+#
+# gb_AllLangHelp_add_helpdir_file module filename file
+define gb_AllLangHelp_add_helpdir_file
+$(foreach lang,$(gb_HELP_LANGS),\
+ $(call gb_HelpTarget_add_helpdir_file,$(call gb_AllLangHelp__get_helpname,$(1),$(lang)),$(2),$(3)) \
+)
+
+endef
+
+# gb_AllLangHelp__use_module module other-module lang
+define gb_AllLangHelp__use_module
+$(call gb_HelpTarget_use_module,$(call gb_AllLangHelp__get_helpname,$(1),$(3)),$(call gb_AllLangHelp__get_helpname,$(2),$(3)))
+
+endef
+
+# Use references from another help module's files.
+#
+# gb_AllLangHelp_use_module module other-module
+define gb_AllLangHelp_use_module
+$(foreach lang,$(gb_HELP_LANGS),$(call gb_AllLangHelp__use_module,$(1),$(2),$(lang)))
+
+endef
+
+# Use references from other help modules' files.
+#
+# gb_AllLangHelp_use_module module other-module(s)
+define gb_AllLangHelp_use_modules
+$(foreach module,$(2),$(call gb_AllLangHelp_use_module,$(1),$(module)))
+
+endef
+
+# gb_AllLangHelp__use_linked_module module other-module lang
+define gb_AllLangHelp__use_linked_module
+$(call gb_HelpTarget_use_linked_module,$(call gb_AllLangHelp__get_helpname,$(1),$(3)),$(call gb_AllLangHelp__get_helpname,$(2),$(3)))
+$(call gb_HelpTarget_set_indexed,$(call gb_AllLangHelp__get_helpname,$(1),$(3)))
+$(call gb_HelpTarget_set_configfile,$(call gb_AllLangHelp__get_helpname,$(1),$(3)),$(gb_AllLangHelp_AUXDIR)/$(3)/$(1))
+
+endef
+
+# Link with another help module.
+#
+# gb_AllLangHelp_use_linked_module module other-module
+define gb_AllLangHelp_use_linked_module
+$(foreach lang,$(gb_HELP_LANGS),$(call gb_AllLangHelp__use_linked_module,$(1),$(2),$(lang)))
+
+endef
+
+# Link with other help module(s).
+#
+# gb_AllLangHelp_use_linked_module module other-module(s)
+define gb_AllLangHelp_use_linked_modules
+$(foreach module,$(2),$(call gb_AllLangHelp_use_linked_module,$(1),$(module)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/AllLangMoTarget.mk b/solenv/gbuild/AllLangMoTarget.mk
new file mode 100644
index 000000000..ec05985d5
--- /dev/null
+++ b/solenv/gbuild/AllLangMoTarget.mk
@@ -0,0 +1,100 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# Overview of dependencies and tasks of AllLangMoTarget
+#
+# target task depends on
+# AllLangMoTarget nothing MoTarget for all active langs
+# MoTarget running msgfmt
+
+# MoTarget
+
+$(call gb_MoTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),RES,2)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f \
+ $(call gb_MoTarget_get_target,$*) \
+ $(call gb_MoTarget_get_install_target,$*))
+
+$(call gb_MoTarget_get_target,%) : $(gb_Helper_MISCDUMMY)
+ $(call gb_Output_announce,$*,$(true),MO ,2)
+ $(call gb_Trace_StartRange,$*,MO )
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && \
+ $(MSGUNIQ) --force-po $(gb_POLOCATION)/$(LANGUAGE)/$(POLOCATION)/messages.po | $(MSGFMT) - -o $@)
+ $(call gb_Trace_EndRange,$*,MO )
+
+#$(info $(call gb_MoTarget_get_target,$(1)))
+define gb_MoTarget_MoTarget
+$(call gb_MoTarget_get_target,$(1)) : LIBRARY = $(2)
+$(call gb_MoTarget_get_target,$(1)) : LANGUAGE = $(3)
+$(call gb_MoTarget_get_target,$(1)) : POLOCATION = $(2)
+$(call gb_AllLangMoTarget_get_clean_target,$(2)) : $(call gb_MoTarget_get_clean_target,$(1))
+
+endef
+
+define gb_MoTarget_set_polocation
+$(call gb_MoTarget_get_target,$(1)) : POLOCATION = $(2)
+
+endef
+
+# AllLangMoTarget
+
+gb_AllLangMoTarget_LANGS := $(filter-out qtz,$(filter-out en-US,$(gb_WITH_LANG)))
+
+define gb_AllLangMoTarget_set_langs
+gb_AllLangMoTarget_LANGS := $(1)
+endef
+
+$(call gb_AllLangMoTarget_get_clean_target,%) :
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_AllLangMoTarget_get_target,$*))
+
+$(call gb_AllLangMoTarget_get_target,%) :
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && touch $@)
+
+gb_MoTarget_get_install_target = $(INSTROOT)/$(LIBO_SHARE_RESOURCE_FOLDER)/$(1).mo
+
+define gb_AllLangMoTarget_AllLangMoTarget
+ifeq (,$$(filter $(1),$$(gb_AllLangMoTarget_REGISTERED)))
+$$(eval $$(call gb_Output_info,Currently known AllLangMoTargets are: $(sort $(gb_AllLangMoTarget_REGISTERED)),ALL))
+$$(eval $$(call gb_Output_error,AllLangMoTarget $(1) must be registered in Repository.mk))
+endif
+$(foreach lang,$(gb_AllLangMoTarget_LANGS),\
+ $(call gb_MoTarget_MoTarget,$(1)$(lang),$(1),$(lang)))
+
+$(foreach lang,$(gb_AllLangMoTarget_LANGS),\
+$(call gb_Helper_install,$(call gb_AllLangMoTarget_get_target,$(1)), \
+ $(call gb_MoTarget_get_install_target,$(shell $(SRCDIR)/solenv/bin/localestr $(lang))/LC_MESSAGES/$(1)), \
+ $(call gb_MoTarget_get_target,$(1)$(lang))))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_AllLangMoTarget_get_target,$(1)),$(call gb_AllLangMoTarget_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),AllLangMoTarget)
+$(call gb_Postprocess_register_target,AllResources,AllLangMoTarget,$(1))
+
+endef
+
+define gb_AllLangMoTarget_set_polocation
+$(foreach lang,$(gb_AllLangMoTarget_LANGS),\
+ $(call gb_MoTarget_set_polocation,$(1)$(lang),$(2)))
+
+endef
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/AllLangPackage.mk b/solenv/gbuild/AllLangPackage.mk
new file mode 100644
index 000000000..092716b37
--- /dev/null
+++ b/solenv/gbuild/AllLangPackage.mk
@@ -0,0 +1,124 @@
+# -*- 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/.
+#
+
+# AllLangPackage class
+
+# Handles creation of a bunch of packages with content dependent on
+# language. The package files are placed into $(INSTROOT).
+
+gb_AllLangPackage_LANGS := $(if $(strip $(gb_WITH_LANG)),$(gb_WITH_LANG),en-US)
+
+$(dir $(call gb_AllLangPackage_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_AllLangPackage_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),ALP,3)
+ $(call gb_Trace_MakeMark,$*,ALP)
+ touch $@
+
+.PHONY : $(call gb_AllLangPackage_get_clean_target,%)
+$(call gb_AllLangPackage_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),ALP,3)
+ rm -f $(call gb_AllLangPackage_get_target,$*)
+
+# Define a new package group.
+#
+# gb_AllLangPackage_AllLangPackage group srcdir
+define gb_AllLangPackage_AllLangPackage
+$(foreach lang,$(gb_AllLangPackage_LANGS),$(call gb_AllLangPackage__AllLangPackage_onelang,$(1),$(1)_$(lang),$(2)))
+
+$(call gb_AllLangPackage_get_target,$(1)) :| $(dir $(call gb_AllLangPackage_get_target,$(1))).dir
+
+$$(eval $$(call gb_Module_register_target,$(call gb_AllLangPackage_get_target,$(1)),$(call gb_AllLangPackage_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),AllLangPackage)
+
+endef
+
+# Define a package for one lang.
+#
+# gb_AllLangPackage__AllLangPackage_lang group package srcdir
+define gb_AllLangPackage__AllLangPackage_onelang
+$(call gb_Package_Package_internal,$(2),$(3))
+$(call gb_AllLangPackage_get_target,$(1)) : $(call gb_Package_get_target,$(2))
+$(call gb_AllLangPackage_get_clean_target,$(1)) : $(call gb_Package_get_clean_target,$(2))
+
+endef
+
+# gb_AllLangPackage__add_to_package target package destination source
+define gb_AllLangPackage__add_to_package
+$(call gb_Package_add_file,$(2),$(3),$(4))
+
+endef
+
+# gb_AllLangPackage__add_file target destination source lang
+define gb_AllLangPackage__add_file
+$(if $(filter $(4),$(gb_AllLangPackage_LANGS)),$(call gb_AllLangPackage__add_to_package,$(1),$(1)_$(4),$(2),$(3)))
+
+endef
+
+# Add a file to one of the child packages.
+#
+# If 'lang' is empty, the language is taken from the first component of the 'source' file name. The
+# file is only added if there is a package defined for the language
+# (i.e., if we are building with the language).
+#
+# gb_AllLangPackage_add_file target destination source lang
+gb_AllLangPackage_ALLDIRS :=
+define gb_AllLangPackage_add_file
+gb_AllLangPackage_ALLDIRS := $(sort $(gb_AllLangPackage_ALLDIRS) $(patsubst %$(3),%,$(2)))
+$(call gb_AllLangPackage__add_file,$(1),$(2),$(3),$(or $(4),$(firstword $(subst /, ,$(3)))))
+
+endef
+
+# Add several files to the child packages at once.
+#
+# gb_AllLangPackage_add_files target destination-dir file(s)
+define gb_AllLangPackage_add_files
+$(if $(strip $(2)),,$(call gb_Output_error,gb_AllLangPackage_add_files: destination dir cannot be empty))
+$(foreach file,$(3),$(call gb_AllLangPackage_add_file,$(1),$(2)/$(file),$(file)))
+
+endef
+
+# gb_AllLangPackage_add_files_for_lang target lang destination-dir file(s)
+define gb_AllLangPackage_add_files_for_lang
+$(if $(strip $(3)),,$(call gb_Output_error,gb_AllLangPackage_add_files: destination dir cannot be empty))
+$(foreach file,$(4),$(call gb_AllLangPackage_add_file,$(1),$(3)/$(file),$(file),$(2)))
+
+endef
+
+# Add several files to the child packages at once.
+#
+# The files are placed into subdir under the language-dependent path.
+#
+# Example:
+# $(eval $(call # gb_AllLangPackage_add_files_with_subdir,foo,destdir,subdir,cs/file.ext))
+# # -> destdir/cs/subdir/file.ext
+#
+# gb_AllLangPackage_add_files_with_subdir target destination-dir subdir file(s)
+define gb_AllLangPackage_add_files_with_subdir
+$(if $(strip $(2)),,$(call gb_Output_error,gb_AllLangPackage_add_files_with_subdir: destination dir cannot be empty))
+$(if $(strip $(3)),,$(call gb_Output_error,gb_AllLangPackage_add_files_with_subdir: there is no subdir, just use gb_AllLangPackage_add_files))
+$(foreach file,$(4),$(call gb_AllLangPackage_add_file,$(1),$(2)/$(dir $(file))$(3)/$(notdir $(file)),$(file)))
+
+endef
+
+# Use unpacked tarball.
+#
+# gb_AllLangPackage_add_dependency target unpacked
+define gb_AllLangPackage_use_unpacked
+$(foreach lang,$(gb_AllLangPackage_LANGS),$(call gb_Package_use_unpacked,$(1)_$(lang),$(2)))
+
+endef
+
+define gb_AllLangPackage_use_customtarget
+$(foreach lang,$(gb_AllLangPackage_LANGS),$(call gb_Package_use_customtarget,$(1)_$(lang),$(2)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/AutoInstall.mk b/solenv/gbuild/AutoInstall.mk
new file mode 100644
index 000000000..aee2750e9
--- /dev/null
+++ b/solenv/gbuild/AutoInstall.mk
@@ -0,0 +1,76 @@
+# -*- 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/.
+#
+
+# AutoInstall class
+
+$(dir $(call gb_AutoInstall_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_AutoInstall_get_target,%) : $(GBUILDDIR)/AutoInstall.mk \
+ $(SRCDIR)/Repository.mk $(SRCDIR)/RepositoryExternal.mk \
+ $(BUILDDIR)/config_host.mk \
+ $(GBUILDDIR)/gen-autoinstall.py \
+ $(call gb_ExternalExecutable_get_dependencies,python)
+ $(call gb_Output_announce,$*,$(true),AIN,3)
+ $(call gb_Trace_StartRange,$*,AIN)
+ SDKLIBFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,\
+ $(foreach lib,$(gb_SdkLinkLibrary_MODULE_$*),\
+ $(lib) \
+ $(notdir $(call gb_Library_get_sdk_link_lib,$(lib))) \
+ ../../program/$(call gb_Library_get_runtime_filename,$(lib)))) \
+ && LIBFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,\
+ $(foreach lib,$(gb_Library_MODULE_$*),\
+ $(lib) \
+ $(call gb_Library_get_runtime_filename,$(lib)))) \
+ && EXEFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,\
+ $(foreach exe,$(gb_Executable_MODULE_$*),\
+ $(exe) \
+ $(call gb_Executable_get_filename,$(exe)))) \
+ && JARFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(gb_Jar_MODULE_$*)) \
+ && PKGFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(gb_Package_MODULE_$*)) \
+ && $(call gb_ExternalExecutable_get_command,python) \
+ $(GBUILDDIR)/gen-autoinstall.py \
+ '$*' '$(SCP2COMPONENTCONDITION)' \
+ '$(SCP2LIBTEMPLATE)' '$(SCP2EXETEMPLATE)' '$(SCP2JARTEMPLATE)' \
+ '$(SCP2PKGTEMPLATE)' \
+ $${SDKLIBFILE} $${LIBFILE} $${EXEFILE} $${JARFILE} $${PKGFILE} \
+ > $@ \
+ && rm -f $${SDKLIBFILE} $${LIBFILE} $${EXEFILE} $${JARFILE} $${PKGFILE}
+ $(call gb_Trace_EndRange,$*,AIN)
+
+
+$(call gb_AutoInstall_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),AIL,3)
+ rm -f $(call gb_AutoInstall_get_target,$*)
+
+define gb_AutoInstall_AutoInstall
+$(call gb_AutoInstall_get_target,all) :| $(dir $(call gb_AutoInstall_get_target,all)).dir
+
+$$(eval $$(call gb_Module_register_target,$(call gb_AutoInstall_get_target,all),$(call gb_AutoInstall_get_clean_target,all)))
+$(call gb_Helper_make_userfriendly_targets,all,AutoInstall)
+
+endef
+
+# gb_AutoInstall_add_module module lib_template exe_template jar_template package_template componentcondition
+define gb_AutoInstall_add_module
+$(call gb_AutoInstall_get_target,all) : $(call gb_AutoInstall_get_target,$(1))
+$(call gb_AutoInstall_get_clean_target,all) : $(call gb_AutoInstall_get_clean_target,$(1))
+$(call gb_Helper_make_userfriendly_targets,$(1),AutoInstall)
+
+$(call gb_AutoInstall_get_target,$(1)) : $(gb_Module_CURRENTMAKEFILE)
+$(call gb_AutoInstall_get_target,$(1)) :| $(dir $(call gb_AutoInstall_get_target,$(1))).dir
+$(call gb_AutoInstall_get_target,$(1)) : SCP2LIBTEMPLATE := $(2)
+$(call gb_AutoInstall_get_target,$(1)) : SCP2EXETEMPLATE := $(3)
+$(call gb_AutoInstall_get_target,$(1)) : SCP2JARTEMPLATE := $(4)
+$(call gb_AutoInstall_get_target,$(1)) : SCP2PKGTEMPLATE := $(5)
+$(call gb_AutoInstall_get_target,$(1)) : SCP2COMPONENTCONDITION := $(6)
+
+endef
+
+# vim: set shiftwidth=4 tabstop=4 noexpandtab:
diff --git a/solenv/gbuild/CliAssembly.mk b/solenv/gbuild/CliAssembly.mk
new file mode 100644
index 000000000..9c97e036f
--- /dev/null
+++ b/solenv/gbuild/CliAssembly.mk
@@ -0,0 +1,209 @@
+# -*- 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/.
+#
+
+# CliConfigTarget class
+
+gb_CliConfigTarget_TARGET := $(SRCDIR)/solenv/bin/clipatchconfig.pl
+gb_CliConfigTarget_COMMAND := $(PERL) -w $(gb_CliConfigTarget_TARGET)
+
+define gb_CliConfigTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ $(gb_CliConfigTarget_COMMAND) $(3) $(CLI_CONFIG_VERSIONFILE) $(1) \
+)
+endef
+
+$(dir $(call gb_CliConfigTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_CliConfigTarget_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),CPA,1)
+ $(call gb_Trace_StartRange,$*,CPA)
+ $(call gb_CliConfigTarget__command,$@,$*,$<)
+ $(call gb_Trace_EndRange,$*,CPA)
+
+$(call gb_CliConfigTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),CPA,1)
+ rm -f $(call gb_CliConfigTarget_get_target,$*)
+
+# Subst. variables in a config file
+#
+# gb_CliConfigTarget_CliConfigTarget target source
+define gb_CliConfigTarget_CliConfigTarget
+$(call gb_CliConfigTarget_get_target,$(1)) : CLI_CONFIG_VERSIONFILE := $(3)
+
+$(call gb_CliConfigTarget_get_target,$(1)) : $(2)
+$(call gb_CliConfigTarget_get_target,$(1)) : $(gb_CliConfigTarget_TARGET)
+$(call gb_CliConfigTarget_get_target,$(1)) : $(3)
+$(call gb_CliConfigTarget_get_target,$(1)) :| $(dir $(call gb_CliConfigTarget_get_target,$(1))).dir
+
+endef
+
+# CliAssemblyTarget class
+
+# platform:
+# CliAssemblyTarget_POLICYEXT
+# CliAssemblyTarget_get_dll
+
+gb_CliAssemblyTarget_KEYFILE_DEFAULT := $(SRCDIR)/cli_ure/source/cliuno.snk
+
+define gb_CliAssemblyTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ $(GNUCOPY) $(CLI_ASSEMBLY_KEYFILE) $(1).tmp.snk && \
+ al \
+ -nologo \
+ -out:$(CLI_ASSEMBLY_OUTFILE) \
+ -version:$(CLI_ASSEMBLY_VERSION) \
+ -keyfile:$(1).tmp.snk \
+ -link:$(CLI_ASSEMBLY_CONFIGFILE) \
+ $(if $(CLI_ASSEMBLY_PLATFORM),-platform:$(CLI_ASSEMBLY_PLATFORM)) && \
+ rm -f $(1).tmp.snk && \
+ touch $(1) \
+)
+endef
+
+$(dir $(call gb_CliAssemblyTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_CliAssemblyTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_CliAssemblyTarget_get_target,%) :
+ $(if $(strip $(CLI_ASSEMBLY_VERSION)),,$(call gb_Output_error,assembly version not set))
+ $(if $(strip $(CLI_ASSEMBLY_CONFIGFILE)),,$(call gb_Output_error,assembly configuration file not set))
+ $(if $(strip $(CLI_ASSEMBLY_OUTFILE)),,$(call gb_Output_error,assembly name not set))
+ $(call gb_Output_announce,$*,$(true),AL ,2)
+ $(call gb_Trace_StartRange,$*,AL )
+ $(call gb_CliAssemblyTarget__command,$@,$*,$<)
+ $(call gb_Trace_EndRange,$*,AL )
+
+$(call gb_CliAssemblyTarget_get_assembly_target,%) :
+ touch $@
+
+.PHONY : $(call gb_CliAssemblyTarget_get_clean_target,%)
+$(call gb_CliAssemblyTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),AL ,2)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_CliAssemblyTarget_get_target,$*) $(CLI_ASSEMBLY_OUTFILE) \
+ )
+
+# Create a CLI assembly
+define gb_CliAssemblyTarget_CliAssemblyTarget
+$(call gb_CliAssemblyTarget_get_target,$(1)) : CLI_ASSEMBLY_CONFIGFILE :=
+$(call gb_CliAssemblyTarget_get_target,$(1)) : CLI_ASSEMBLY_KEYFILE := $(gb_CliAssemblyTarget_KEYFILE_DEFAULT)
+$(call gb_CliAssemblyTarget_get_target,$(1)) : CLI_ASSEMBLY_OUTFILE :=
+$(call gb_CliAssemblyTarget_get_target,$(1)) : CLI_ASSEMBLY_PLATFORM :=
+$(call gb_CliAssemblyTarget_get_target,$(1)) : CLI_ASSEMBLY_VERSION :=
+
+$(call gb_CliAssemblyTarget_get_clean_target,$(1)) : CLI_ASSEMBLY_OUTFILE :=
+
+$(call gb_CliAssemblyTarget_get_target,$(1)) :| $(dir $(call gb_CliAssemblyTarget_get_target,$(1))).dir
+
+endef
+
+define gb_CliAssemblyTarget_set_configfile
+$(call gb_CliAssemblyTarget_get_target,$(1)) : CLI_ASSEMBLY_CONFIGFILE := $(2)
+$(call gb_CliAssemblyTarget_get_target,$(1)) : $(2)
+$(call gb_CliAssemblyTarget_get_clean_target,$(1)) : $(3)
+
+endef
+
+define gb_CliAssemblyTarget_set_keyfile
+$(call gb_CliAssemblyTarget_get_target,$(1)) : CLI_ASSEMBLY_KEYFILE := $(2)
+$(call gb_CliAssemblyTarget_get_target,$(1)) : $(2)
+
+endef
+
+define gb_CliAssemblyTarget_set_name
+$(call gb_CliAssemblyTarget_get_target,$(1)) \
+$(call gb_CliAssemblyTarget_get_clean_target,$(1)) : \
+ CLI_ASSEMBLY_OUTFILE := $(call gb_CliAssemblyTarget_get_assembly_target,$(2))
+$(call gb_CliAssemblyTarget_get_assembly_target,$(2)) : $(call gb_CliAssemblyTarget_get_target,$(1))
+
+endef
+
+define gb_CliAssemblyTarget_set_platform
+$(call gb_CliAssemblyTarget_get_target,$(1)) : CLI_ASSEMBLY_PLATFORM := $(2)
+
+endef
+
+define gb_CliAssemblyTarget_set_version
+$(call gb_CliAssemblyTarget_get_target,$(1)) : CLI_ASSEMBLY_VERSION := $(2)
+
+endef
+
+# CliAssembly class
+
+gb_CliAssembly_KEYFILE_DEFAULT := $(gb_CliAssemblyTarget_KEYFILE_DEFAULT)
+gb_CliAssembly_POLICYEXT := $(gb_CliAssemblyTarget_POLICYEXT)
+
+gb_CliAssembly_get_dll = $(call gb_CliAssemblyTarget_get_dll,$(1))
+
+$(call gb_CliAssembly_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),CLA,3)
+ $(call gb_Trace_MakeMark,$*,CLA)
+ mkdir -p $(dir $@) && touch $@
+
+.PHONY : $(call gb_CliAssembly_get_clean_target,%)
+$(call gb_CliAssembly_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),CLA,3)
+ rm -f $(call gb_CliAssembly_get_target,$*)
+
+# call gb_CliAssembly_CliAssembly,dllname,dlltarget
+define gb_CliAssembly_CliAssembly
+$(call gb_CliAssemblyTarget_CliAssemblyTarget,$(1))
+$(call gb_Package_Package_internal,$(1)_assembly,$(WORKDIR))
+$(call gb_Package_set_outdir,$(1)_assembly,$(dir $(2)))
+
+$(call gb_CliAssembly_get_target,$(1)) : $(call gb_CliAssemblyTarget_get_target,$(1))
+$(call gb_CliAssembly_get_target,$(1)) :| $(call gb_Package_get_target,$(1)_assembly)
+$(call gb_CliAssembly_get_clean_target,$(1)) : $(call gb_CliAssemblyTarget_get_clean_target,$(1))
+$(call gb_CliAssembly_get_clean_target,$(1)) : $(call gb_Package_get_clean_target,$(1)_assembly)
+
+endef
+
+define gb_CliAssembly__add_file
+$(call gb_Package_add_file,$(1)_assembly,$(notdir $(2)),$(subst $(WORKDIR)/,,$(2)))
+
+endef
+
+define gb_CliAssembly__set_configfile_impl
+$(call gb_CliAssemblyTarget_set_configfile,$(1),$(2),$(3))
+$(call gb_CliAssembly__add_file,$(1),$(2))
+
+endef
+
+define gb_CliAssembly__set_configfile
+$(call gb_CliConfigTarget_CliConfigTarget,$(2),$(3),$(4))
+$(call gb_CliAssembly__set_configfile_impl,$(1),$(call gb_CliConfigTarget_get_target,$(2)),$(call gb_CliConfigTarget_get_clean_target,$(2)))
+
+endef
+
+define gb_CliAssembly_set_configfile
+$(call gb_CliAssembly__set_configfile,$(1),$(patsubst %_config,%,$(2)),$(SRCDIR)/$(2),$(SRCDIR)/$(3))
+
+endef
+
+define gb_CliAssembly_set_keyfile
+$(call gb_CliAssemblyTarget_set_keyfile,$(1),$(2))
+
+endef
+
+define gb_CliAssembly_set_platform
+$(call gb_CliAssemblyTarget_set_platform,$(1),$(2))
+
+endef
+
+define gb_CliAssembly_set_policy
+$(call gb_CliAssemblyTarget_set_version,$(1),$(3))
+$(call gb_CliAssemblyTarget_set_name,$(1),$(2))
+$(call gb_CliAssembly__add_file,$(1),$(call gb_CliAssemblyTarget_get_assembly_target,$(2)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/CliLibrary.mk b/solenv/gbuild/CliLibrary.mk
new file mode 100644
index 000000000..4abd34b42
--- /dev/null
+++ b/solenv/gbuild/CliLibrary.mk
@@ -0,0 +1,148 @@
+# -*- 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/.
+#
+
+# CliLibrary class
+
+gb_CliLibrary_EXT := $(gb_CliAssembly_POLICYEXT)
+
+gb_CliLibrary_CSCFLAGS := \
+ -noconfig \
+ -nologo \
+
+gb_CliLibrary_CSCFLAGS_DEBUG := \
+ -checked+ \
+ -define:DEBUG \
+ -define:TRACE \
+
+ifeq ($(strip $(debug)),)
+ifeq ($(strip $(ENABLE_DBGUTIL)),TRUE)
+gb_CliLibrary__get_csflags = $(gb_CliLibrary_CSCFLAGS) $(gb_CliLibrary_CSCFLAGS_DEBUG)
+else
+gb_CliLibrary__get_csflags = $(gb_CliLibrary_CSCFLAGS) -o
+endif
+else
+gb_CliLibrary__get_csflags = $(gb_CliLibrary_CSCFLAGS) $(gb_CliLibrary_CSCFLAGS_DEBUG) -debug+
+endif
+
+gb_CliLibrary__get_source = $(SRCDIR)/$(1).cs
+gb_CliLibrary__get_generated_source = $(WORKDIR)/$(1).cs
+
+# csc has silly problems handling files passed on command line
+define gb_CliLibrary__command
+ csc \
+ $(call gb_CliLibrary__get_csflags) \
+ $(CLI_CSCFLAGS) \
+ -target:library \
+ -out:$(1) \
+ $(if $(call gb_target_symbols_enabled,$(1)),\
+ -debug:pdbonly \
+ -pdb:$(call gb_LinkTarget__get_pdb_filename,$(WORKDIR)/LinkTarget/Library/$(notdir $(1)))) \
+ -keyfile:$(CLI_KEYFILE) \
+ -reference:System.dll \
+ $(foreach assembly,$(CLI_ASSEMBLIES),-reference:$(assembly)) \
+ $(subst /,\,$(CLI_SOURCES)) \
+
+
+endef
+
+.PHONY : $(call gb_CliLibrary_get_clean_target,%)
+$(call gb_CliLibrary_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),CSC,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_CliLibrary_get_target,$*) \
+ )
+
+
+# Compiles one or more C# source files
+#
+# gb_CliLibrary_CliLibrary target
+define gb_CliLibrary_CliLibrary
+$(call gb_CliAssembly_CliAssembly,$(1),$(call gb_CliLibrary_get_target,$(1)))
+
+$(call gb_CliLibrary_get_target,$(1)) : CLI_ASSEMBLIES :=
+$(call gb_CliLibrary_get_target,$(1)) : CLI_SOURCES :=
+$(call gb_CliLibrary_get_target,$(1)) : CLI_CSCFLAGS :=
+$(call gb_CliLibrary_get_target,$(1)) : CLI_KEYFILE :=
+
+
+$(call gb_CliLibrary_get_target,$(1)) :| $(call gb_CliAssembly_get_target,$(1))
+$(call gb_CliLibrary_get_target,$(1)) :| $(dir $(call gb_CliLibrary_get_target,$(1))).dir
+$(call gb_CliLibrary_get_clean_target,$(1)) : $(call gb_CliAssembly_get_clean_target,$(1))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_CliLibrary_get_target,$(1)),$(call gb_CliLibrary_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),CliLibrary)
+
+$(call gb_CliLibrary_get_target,$(1)) :
+ $$(call gb_Output_announce,$(1),$(true),CSC,3)
+ $$(call gb_Trace_StartRange,$(1),CSC)
+ $$(call gb_CliLibrary__command,$$@,$(1))
+ $$(call gb_Trace_EndRange,$(1),CSC)
+
+endef
+
+define gb_CliLibrary_set_configfile
+$(call gb_CliAssembly_set_configfile,$(1),$(2),$(3))
+
+endef
+
+define gb_CliLibrary_set_keyfile
+$(call gb_CliLibrary_get_target,$(1)) : CLI_KEYFILE := $(2)
+$(call gb_CliAssembly_set_keyfile,$(1),$(2))
+
+endef
+
+define gb_CliLibrary_set_policy
+$(call gb_CliAssembly_set_policy,$(1),$(2),$(3))
+
+endef
+
+define gb_CliLibrary_use_assembly
+$(call gb_CliLibrary_get_target,$(1)) : CLI_ASSEMBLIES += $(call gb_CliLibrary_get_target,$(2))
+$(call gb_CliLibrary_get_target,$(1)) : $(call gb_CliLibrary_get_target,$(2))
+
+endef
+
+define gb_CliLibrary_use_assemblies
+$(foreach assembly,$(2),$(call gb_CliLibrary_use_assembly,$(1),$(assembly)))
+
+endef
+
+# Add a source file to compile
+define gb_CliLibrary_add_csfile
+$(call gb_CliLibrary_get_target,$(1)) : CLI_SOURCES += $(call gb_CliLibrary__get_source,$(2))
+$(call gb_CliLibrary_get_target,$(1)) : $(call gb_CliLibrary__get_source,$(2))
+
+endef
+
+# Add source files to compile
+define gb_CliLibrary_add_csfiles
+$(foreach csfile,$(2),$(call gb_CliLibrary_add_csfile,$(1),$(csfile)))
+
+endef
+
+# Add a generated source file to compile
+define gb_CliLibrary_add_generated_csfile
+$(call gb_CliLibrary_get_target,$(1)) : CLI_SOURCES += $(call gb_CliLibrary__get_generated_source,$(2))
+$(call gb_CliLibrary_get_target,$(1)) : $(call gb_CliLibrary__get_generated_source,$(2))
+
+endef
+
+# Add generated source files to compile
+define gb_CliLibrary_add_generated_csfiles
+$(foreach csfile,$(2),$(call gb_CliLibrary_add_generated_csfile,$(1),$(csfile)))
+
+endef
+
+# Add flags used for compilation
+define gb_CliLibrary_add_csflags
+$(call gb_CliLibrary_get_target,$(1)) : CLI_CSCFLAGS += $(2)
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/CliNativeLibrary.mk b/solenv/gbuild/CliNativeLibrary.mk
new file mode 100644
index 000000000..9e19ccd70
--- /dev/null
+++ b/solenv/gbuild/CliNativeLibrary.mk
@@ -0,0 +1,111 @@
+# -*- 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/.
+#
+
+# CliNativeLibrary class
+
+gb_CliNativeLibrary_PLATFORM_DEFAULT := x86
+gb_CliNativeLibrary_EXT := $(gb_CliAssembly_POLICYEXT)
+
+gb_CliNativeLibrary__get_library = $(call gb_CliAssembly_get_dll,$(1))
+
+define gb_CliNativeLibrary__command
+$(call gb_Helper_abbreviate_dirs,\
+ $(GNUCOPY) $(CLI_NATIVE_LIBRARY) $(1).tmp && \
+ sn -R $(1).tmp $(CLI_NATIVE_KEYFILE) && \
+ mv $(1).tmp $(1) \
+)
+endef
+
+$(call gb_CliNativeLibrary_get_preparation_target,%) :
+ mkdir -p $(dir $@) && touch $@
+
+.PHONY : $(call gb_CliNativeLibrary_get_clean_target,%)
+$(call gb_CliNativeLibrary_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),SN ,4)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf $(call gb_CliNativeLibrary_get_target,$*) \
+ $(call gb_CliNativeLibrary_get_preparation_target,$*) \
+ )
+
+
+# Create a CLI library for a native library
+#
+# CliNativeLibrary target
+define gb_CliNativeLibrary_CliNativeLibrary
+$(call gb_CliAssembly_CliAssembly,$(1),$(call gb_CliNativeLibrary_get_target,$(1)))
+
+$(call gb_CliNativeLibrary_get_target,$(1)) : CLI_NATIVE_ASSEMBLIES := $(gb_Helper_MISCDUMMY)
+$(call gb_CliNativeLibrary_get_target,$(1)) : CLI_NATIVE_KEYFILE :=
+$(call gb_CliNativeLibrary_get_target,$(1)) : CLI_NATIVE_LIBRARY :=
+
+
+$(call gb_CliNativeLibrary_set_keyfile,$(1),$(gb_CliAssembly_KEYFILE_DEFAULT))
+$(call gb_CliAssembly_set_platform,$(1),$(gb_CliNativeLibrary_PLATFORM_DEFAULT))
+
+$(call gb_CliNativeLibrary_get_target,$(1)) :| $(call gb_CliAssembly_get_target,$(1))
+$(call gb_CliNativeLibrary_get_target,$(1)) :| $(dir $(call gb_CliNativeLibrary_get_target,$(1))).dir
+$(call gb_CliNativeLibrary_get_clean_target,$(1)) : $(call gb_CliAssembly_get_clean_target,$(1))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_CliNativeLibrary_get_target,$(1)),$(call gb_CliNativeLibrary_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),CliNativeLibrary)
+
+$(call gb_CliNativeLibrary_get_target,$(1)) :
+ $$(call gb_Output_announce,$(1),$(true),SN ,4)
+ $$(call gb_Trace_StartRange,$(1),SN )
+ $$(call gb_CliNativeLibrary__command,$$@,$(1))
+ $$(call gb_Trace_EndRange,$(1),SN )
+
+endef
+
+define gb_CliNativeLibrary_set_configfile
+$(call gb_CliAssembly_set_configfile,$(1),$(2),$(3))
+
+endef
+
+define gb_CliNativeLibrary_set_keyfile
+$(call gb_CliAssembly_set_keyfile,$(1),$(2))
+$(call gb_CliNativeLibrary_get_target,$(1)) : CLI_NATIVE_KEYFILE := $(2)
+$(call gb_CliNativeLibrary_get_target,$(1)) : $(2)
+
+endef
+
+define gb_CliNativeLibrary_set_platform
+$(call gb_CliAssembly_set_platform,$(1),$(2))
+
+endef
+
+define gb_CliNativeLibrary_set_policy
+$(call gb_CliAssembly_set_policy,$(1),$(2),$(3))
+
+endef
+
+define gb_CliNativeLibrary_wrap_library
+$(call gb_CliNativeLibrary_get_target,$(1)) : \
+ CLI_NATIVE_LIBRARY := $(call gb_CliNativeLibrary__get_library,$(2))
+$(call gb_CliNativeLibrary_get_target,$(1)) : \
+ $(call gb_Library_get_target,$(2))
+$(call gb_Library_get_headers_target,$(2)) : \
+ $(call gb_CliNativeLibrary_get_preparation_target,$(1))
+
+endef
+
+define gb_CliNativeLibrary_use_assembly
+$(call gb_CliNativeLibrary_get_target,$(1)) : \
+ CLI_NATIVE_ASSEMBLIES += $(call gb_CliLibrary_get_target,$(2))
+$(call gb_CliNativeLibrary_get_preparation_target,$(1)) : \
+ $(call gb_CliLibrary_get_target,$(2))
+
+endef
+
+define gb_CliNativeLibrary_use_assemblies
+$(foreach assembly,$(2),$(call gb_CliNativeLibrary_use_assembly,$(1),$(assembly)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/CliUnoApi.mk b/solenv/gbuild/CliUnoApi.mk
new file mode 100644
index 000000000..db8401d0c
--- /dev/null
+++ b/solenv/gbuild/CliUnoApi.mk
@@ -0,0 +1,122 @@
+# -*- 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/.
+#
+
+# CliUnoApi class
+
+gb_CliUnoApi_EXT := $(gb_CliAssembly_POLICYEXT)
+
+gb_CliUnoApi_KEYFILE_DEFAULT := $(gb_CliAssembly_KEYFILE_DEFAULT)
+
+gb_CliUnoApi_DEPS := $(call gb_Executable_get_runtime_dependencies,climaker)
+gb_CliUnoApi_COMMAND := $(call gb_Executable_get_command,climaker)
+
+define gb_CliUnoApi__command
+$(call gb_Helper_abbreviate_dirs,\
+ $(gb_CliUnoApi_COMMAND) \
+ --out $(1) \
+ --assembly-company "LibreOffice" \
+ --assembly-description "This assembly contains metadata for the LibreOffice API." \
+ --assembly-version $(CLI_UNOAPI_VERSION) \
+ --keyfile $(CLI_UNOAPI_KEYFILE) \
+ $(if $(gb_VERBOSE),--verbose) \
+ $(foreach api,$(CLI_UNOAPI_DEPS),-X $(api)) \
+ $(foreach assembly,$(CLI_UNOAPI_ASSEMBLIES),-r $(assembly)) \
+ $(CLI_UNOAPI_API) \
+)
+endef
+
+.PHONY : $(call gb_CliUnoApi_get_clean_target,%)
+$(call gb_CliUnoApi_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),CLI,4)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_CliUnoApi_get_target,$*) \
+ )
+
+
+# Create a CLI library for UNO API
+#
+# gb_CliUnoApi_CliUnoApi target
+define gb_CliUnoApi_CliUnoApi
+$(call gb_CliAssembly_CliAssembly,$(1),$(call gb_CliUnoApi_get_target,$(1)))
+
+$(call gb_CliUnoApi_get_target,$(1)) : CLI_UNOAPI_API :=
+$(call gb_CliUnoApi_get_target,$(1)) : CLI_UNOAPI_ASSEMBLIES :=
+$(call gb_CliUnoApi_get_target,$(1)) : CLI_UNOAPI_DEPS :=
+$(call gb_CliUnoApi_get_target,$(1)) : CLI_UNOAPI_KEYFILE :=
+$(call gb_CliUnoApi_get_target,$(1)) : CLI_UNOAPI_VERSION :=
+
+$(call gb_CliUnoApi_set_keyfile,$(1),$(gb_CliUnoApi_KEYFILE_DEFAULT))
+
+$(call gb_CliUnoApi_get_target,$(1)) :| $(call gb_CliAssembly_get_target,$(1))
+$(call gb_CliUnoApi_get_target,$(1)) :| $(dir $(call gb_CliUnoApi_get_target,$(1))).dir
+$(call gb_CliUnoApi_get_clean_target,$(1)) : $(call gb_CliAssembly_get_clean_target,$(1))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_CliUnoApi_get_target,$(1)),$(call gb_CliUnoApi_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),CliUnoApi)
+
+
+$(call gb_CliUnoApi_get_target,$(1)) : $(gb_CliUnoApi_DEPS)
+ $$(call gb_Output_announce,$(1),$(true),CLI,4)
+ $$(call gb_Trace_StartRange,$(1),CLI)
+ $$(call gb_CliUnoApi__command,$$@,$(1))
+ $$(call gb_Trace_EndRange,$(1),CLI)
+
+endef
+
+define gb_CliUnoApi_set_configfile
+$(call gb_CliAssembly_set_configfile,$(1),$(2),$(3))
+
+endef
+
+define gb_CliUnoApi_set_keyfile
+$(call gb_CliAssembly_set_keyfile,$(1),$(2))
+$(call gb_CliUnoApi_get_target,$(1)) : CLI_UNOAPI_KEYFILE := $(2)
+$(call gb_CliUnoApi_get_target,$(1)) : $(2)
+
+endef
+
+define gb_CliUnoApi_set_assembly_version
+$(call gb_CliUnoApi_get_target,$(1)) : CLI_UNOAPI_VERSION := $(2)
+
+endef
+
+define gb_CliUnoApi_set_policy
+$(call gb_CliAssembly_set_policy,$(1),$(2),$(3))
+
+endef
+
+define gb_CliUnoApi_wrap_api
+$(call gb_CliUnoApi_get_target,$(1)) : CLI_UNOAPI_API := $(call gb_UnoApiTarget_get_target,$(2))
+$(call gb_CliUnoApi_get_target,$(1)) : $(call gb_UnoApiTarget_get_target,$(2))
+
+endef
+
+define gb_CliUnoApi__use_api
+$(call gb_CliUnoApi_get_target,$(1)) : CLI_UNOAPI_DEPS += $(2)
+$(call gb_CliUnoApi_get_target,$(1)) : $(2)
+
+endef
+
+define gb_CliUnoApi_use_api
+$(foreach api,$(2),$(call gb_CliUnoApi__use_api,$(1),$(call gb_UnoApiTarget_get_target,$(api))))
+
+endef
+
+define gb_CliUnoApi_use_assembly
+$(call gb_CliUnoApi_get_target,$(1)) : CLI_UNOAPI_ASSEMBLIES += $(call gb_CliUnoApi_get_target,$(2))
+$(call gb_CliUnoApi_get_target,$(1)) : $(call gb_CliUnoApi_get_target,$(2))
+
+endef
+
+define gb_CliUnoApi_use_assemblies
+$(foreach assembly,$(2),$(call gb_CliUnoApi_use_assembly,$(1),$(assembly)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/CompilerTest.mk b/solenv/gbuild/CompilerTest.mk
new file mode 100644
index 000000000..fb5150f2c
--- /dev/null
+++ b/solenv/gbuild/CompilerTest.mk
@@ -0,0 +1,53 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# 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/.
+#
+
+define gb_CompilerTest_CompilerTest
+$(call gb_CompilerTest__CompilerTest_impl,$(1),$(call gb_CompilerTest_get_linktarget,$(1)))
+
+endef
+
+# call gb_CompilerTest__CompilerTest_impl,compilertest,linktarget
+define gb_CompilerTest__CompilerTest_impl
+$(call gb_LinkTarget_LinkTarget,$(2),CompilerTest_$(1),NONE)
+$(call gb_LinkTarget_set_targettype,$(2),CompilerTest)
+$(call gb_LinkTarget_get_target,$(2)): COMPILER_TEST := $(true)
+$(call gb_LinkTarget_get_target,$(2)): ENABLE_WERROR := $(true)
+$(call gb_CompilerTest_get_target,$(1)): $(call gb_LinkTarget_get_target,$(2))
+$(call gb_CompilerTest_get_clean_target,$(1)): $(call gb_LinkTarget_get_clean_target,$(2))
+$$(eval $$(call gb_Module_register_target,$(call gb_CompilerTest_get_target,$(1)),$(call gb_CompilerTest_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),CompilerTest)
+
+endef
+
+# forward the call to the gb_LinkTarget implementation
+# (note: because the function name is in $(1), the other args are shifted by 1)
+define gb_CompilerTest__forward_to_Linktarget
+$(call gb_LinkTarget_$(subst gb_CompilerTest_,,$(1)),$(call gb_CompilerTest_get_linktarget,$(2)),$(3),$(4),CompilerTest_$(2))
+
+endef
+
+# copy pasta for forwarding: this could be (and was) done more elegantly, but
+# these here can be found by both git grep and ctags
+gb_CompilerTest_add_cobject = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_add_cobjects = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_add_cxxobject = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_add_cxxobjects = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_add_exception_objects = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_add_objcobject = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_add_objcobjects = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_add_objcxxobject = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_add_objcxxobjects = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_add_cxxclrobject = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_add_cxxclrobjects = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_add_cxxflags = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_set_external_code = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_use_externals = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CompilerTest_use_udk_api = $(call gb_CompilerTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/ComponentTarget.mk b/solenv/gbuild/ComponentTarget.mk
new file mode 100644
index 000000000..d317f1b05
--- /dev/null
+++ b/solenv/gbuild/ComponentTarget.mk
@@ -0,0 +1,109 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+gb_ComponentTarget__ALLCOMPONENTS :=
+
+gb_ComponentTarget_XSLT_CREATE_COMPONENT := $(SRCDIR)/solenv/bin/createcomponent.xslt
+gb_ComponentTarget_XSLT_DUMP_OPTIONALS := $(SRCDIR)/solenv/bin/optionalimplementations.xslt
+gb_ComponentTarget_get_source = $(SRCDIR)/$(1).component
+
+# Some comment on the prerequisite handling for gb_ComponentTarget__command:
+# The whole setup feels - once again - much more complicated then it should be; for an IMHO simple task.
+# We can't just add all the $(call gb_ComponentTarget_get_target,%).* target commands to gb_ComponentTarget__command,
+# because $(shell cat $(1).filtered) is then evaluated too early, cat'ing a non-existing file.
+# Same happens if you add them to a gb_ComponentTarget__pre_command, run before the gb_ComponentTarget__command.
+# The various other "macros" add new rules to "expand" the pattern rules with normal rules and prerequisites.
+# As a result, the files from the pattern rules aren't cleaned up automagically, which I consider a plus point.
+# So the intermediate files must be explicitly added to $(call gb_ComponentTarget_get_clean_target,%).
+
+# In the DISABLE_DYNLOADING case we don't need any COMPONENTPREFIX, we
+# put just the static library filename into the uri parameter. For
+# each statically linked app using some subset of LO components, there
+# is a mapping from library filenames to direct pointers to the
+# corresponding PREFIX_component_getFactory functions.
+define gb_ComponentTarget__command
+$(if $(LIBFILENAME),,$(call gb_Output_error,No LIBFILENAME set at component target: $(1)))
+ $(call gb_ExternalExecutable_get_command,xsltproc) --nonet \
+ --stringparam uri '$(if $(filter TRUE,$(DISABLE_DYNLOADING)),,$(subst \d,$$,$(COMPONENTPREFIX)))$(LIBFILENAME)' \
+ --stringparam cppu_env $(CPPU_ENV) \
+ --stringparam filtered '$(shell cat $(1).filtered)' \
+ -o $(1) $(gb_ComponentTarget_XSLT_CREATE_COMPONENT) $(COMPONENTSOURCE)
+endef
+
+$(call gb_ComponentTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),CMP,1)
+ rm -f $(call gb_ComponentTarget_get_target,$*) \
+ $(call gb_ComponentTarget_get_target,$*).filtered \
+ $(call gb_ComponentTarget_get_target,$*).optionals \
+
+$(call gb_ComponentTarget_get_target,%).dir:
+ mkdir -p $(dir $@)
+
+# %.optionals : list of all optional implementations marked <optional/> in the component file
+$(call gb_ComponentTarget_get_target,%).optionals : \
+ $(gb_ComponentTarget_XSLT_DUMP_OPTIONALS) \
+ | $(call gb_ComponentTarget_get_target,%).dir \
+ $(call gb_ExternalExecutable_get_dependencies,xsltproc)
+ $(call gb_ExternalExecutable_get_command,xsltproc) --nonet \
+ $(gb_ComponentTarget_XSLT_DUMP_OPTIONALS) $(COMPONENTSOURCE) > $@ 2>&1
+
+# %.filtered : list of all optional implementations we don't build
+.PRECIOUS: $(call gb_ComponentTarget_get_target,%).filtered
+$(call gb_ComponentTarget_get_target,%).filtered : $(call gb_ComponentTarget_get_target,%).optionals
+ cat $< $(COMPONENTIMPL) | sed -e '/^#\|^\s*$$/d' | sort | uniq -u > $@
+
+# when a library is renamed, the component file needs to be rebuilt to match.
+# hence simply depend on Repository{,Fixes}.mk since the command runs quickly.
+$(call gb_ComponentTarget_get_target,%) : \
+ $(SRCDIR)/Repository.mk \
+ $(SRCDIR)/RepositoryFixes.mk \
+ $(gb_ComponentTarget_XSLT_CREATE_COMPONENT) \
+ $(call gb_ComponentTarget_get_target,%).filtered \
+ | $(call gb_ExternalExecutable_get_dependencies,xsltproc)
+ $(call gb_Output_announce,$*,$(true),CMP,1)
+ $(call gb_Trace_StartRange,$*,CMP)
+ $(call gb_ComponentTarget__command,$@)
+ $(call gb_Trace_EndRange,$*,CMP)
+
+define gb_ComponentTarget_ComponentTarget
+$(call gb_ComponentTarget_get_target,$(1)) : COMPONENTPREFIX := $(2)
+$(call gb_ComponentTarget_get_target,$(1)) : LIBFILENAME := $(3)
+$(call gb_ComponentTarget_get_target,$(1)) : COMPONENTSOURCE := $(call gb_ComponentTarget_get_source,$(patsubst CppunitTest/%,%,$(1)))
+$(call gb_ComponentTarget_get_target,$(1)) : COMPONENTIMPL :=
+
+$(call gb_ComponentTarget_get_target,$(1)) : $(call gb_ComponentTarget_get_source,$(patsubst CppunitTest/%,%,$(1)))
+$(call gb_ComponentTarget_get_target,$(1)).optionals : $(call gb_ComponentTarget_get_source,$(patsubst CppunitTest/%,%,$(1)))
+
+$(call gb_Helper_make_userfriendly_targets,$(1),ComponentTarget,$(call gb_ComponentTarget_get_target,$(1)))
+
+ifneq ($(4),)
+$$(eval $$(call gb_Rdb_add_component,$(4),$(1)))
+endif
+$(if $(4),$(eval gb_ComponentTarget__ALLCOMPONENTS += $(1)))
+
+endef
+
+# call gb_ComponentTarget_add_componentimpl,componentfile,implid
+define gb_ComponentTarget_add_componentimpl
+$(call gb_ComponentTarget_get_target,$(1)) : COMPONENTIMPL += $(call gb_ComponentTarget_get_source,$(1)).$(2)
+$(call gb_ComponentTarget_get_target,$(1)).filtered : $(call gb_ComponentTarget_get_source,$(1)).$(2)
+
+endef
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/Conditions.mk b/solenv/gbuild/Conditions.mk
new file mode 100644
index 000000000..0a7b88969
--- /dev/null
+++ b/solenv/gbuild/Conditions.mk
@@ -0,0 +1,39 @@
+# -*- 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/.
+#
+
+# IMPORTANT NOTE: make sure, the "else" part works as expected. This normally
+# means, that the condition ends with "$(1),$(2))" or the reverse. It should
+# just end in two (!) braces, otherwise you may need to use either the $(1)
+# or the $(2) multiple times.
+
+define gb_CondExeLockfile
+$(if $(and $(filter-out ANDROID MACOSX iOS WNT,$(OS))),$(1),$(2))
+endef
+
+define gb_CondExeRegistryTools
+$(if $(or $(DISABLE_DYNLOADING),$(ENABLE_MACOSX_SANDBOX)),$(2),$(1))
+endef
+
+define gb_CondExeSp2bv
+$(if $(and $(filter WNT,$(OS)),$(call gb_Helper_optionals_and,DESKTOP ODK,$(true))),$(1),$(2))
+endef
+
+define gb_CondExeUno
+$(if $(and $(filter DESKTOP,$(BUILD_TYPE)),$(if $(DISABLE_DYNLOADING),,$(true))),$(1),$(2))
+endef
+
+define gb_CondExeUnopkg
+$(if $(and $(filter DESKTOP,$(BUILD_TYPE)),$(if $(DISABLE_DYNLOADING),,$(true))),$(1),$(2))
+endef
+
+define gb_CondLibSalTextenc
+$(if $(or $(filter ANDROID,$(OS)),$(DISABLE_DYNLOADING)),$(2),$(1))
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/Configuration.mk b/solenv/gbuild/Configuration.mk
new file mode 100644
index 000000000..5459b9132
--- /dev/null
+++ b/solenv/gbuild/Configuration.mk
@@ -0,0 +1,456 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# Configuration files: a bit of an overview of the targets:
+#
+# Configuration
+# => XcsTarget: schemas
+# => buildtools
+# => Xcs source
+# => XcuDataTarget: data
+# => buildtools
+# => XcsTarget (schema)
+# => Xcu data source
+# => XcuModuleTaret: modules
+# => buildtools
+# => Xcu data source
+# => XcuLangpackTarget: langpack (per lang)
+# => buildtools
+# => Xcu data source
+# => XcuResTarget: resources (per lang)
+# => buildtools
+# => XcuMergeTarget: merge
+# => buildtools (cfgex)
+# => Xcu data source
+# => *.po
+# => XcsTarget (schema)
+
+# The main LibreOffice registry (cf. officecfg/Configuration_officecfg.mk):
+gb_Configuration_PRIMARY_REGISTRY_NAME := registry
+gb_Configuration_PRIMARY_REGISTRY_SCHEMA_ROOT = \
+ $(SRCDIR)/officecfg/registry/schema
+
+gb_Configuration__stringparam_schemaRoot = --stringparam schemaRoot \
+ $(if $(PRIMARY_REGISTRY), \
+ $(gb_Configuration_PRIMARY_REGISTRY_SCHEMA_ROOT), \
+ $(call gb_XcsTarget_get_target,))
+
+gb_Configuration_XSLTCOMMAND = $(call gb_ExternalExecutable_get_command,xsltproc)
+gb_Configuration_XSLTCOMMAND_DEPS = $(call gb_ExternalExecutable_get_dependencies,xsltproc)
+
+# XcsTarget class
+
+# need to locate a schema file corresponding to some XCU file in the outdir
+define gb_XcsTarget_for_XcuTarget
+$(call gb_XcsTarget_get_target,$(basename $(1)).xcs)
+endef
+
+gb_Configuration_LANGS := en-US $(filter-out en-US,$(gb_WITH_LANG))
+
+gb_XcsTarget_XSLT_SchemaVal := $(SRCDIR)/officecfg/util/schema_val.xsl
+gb_XcsTarget_XSLT_Sanity := $(SRCDIR)/officecfg/util/sanity.xsl
+gb_XcsTarget_XSLT_SchemaTrim := $(SRCDIR)/officecfg/util/schema_trim.xsl
+gb_XcsTarget_DTD_Schema := $(SRCDIR)/officecfg/registry/component-schema.dtd
+
+define gb_XcsTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) && \
+ $(gb_Configuration_XSLTCOMMAND) --nonet \
+ --noout \
+ --stringparam componentName $(subst /,.,$(basename $(2))) \
+ --stringparam root $(subst $(2),,$(3)) \
+ $(gb_Configuration__stringparam_schemaRoot) \
+ $(gb_XcsTarget_XSLT_SchemaVal) \
+ $(3) && \
+ $(gb_Configuration_XSLTCOMMAND) --nonet \
+ --noout \
+ $(gb_XcsTarget_XSLT_Sanity) \
+ $(3) && \
+ $(gb_Configuration_XSLTCOMMAND) --nonet \
+ -o $(1) \
+ --stringparam LIBO_SHARE_FOLDER $(LIBO_SHARE_FOLDER) \
+ --stringparam LIBO_SHARE_HELP_FOLDER $(LIBO_SHARE_HELP_FOLDER) \
+ $(gb_XcsTarget_XSLT_SchemaTrim) \
+ $(3))
+endef
+
+$(call gb_XcsTarget_get_target,%) : \
+ $(gb_XcsTarget_XSLT_SchemaVal) $(gb_XcsTarget_XSLT_Sanity) \
+ $(gb_XcsTarget_XSLT_SchemaTrim) $(gb_XcsTarget_DTD_Schema) \
+ | $(gb_Configuration_XSLTCOMMAND_DEPS)
+ $(call gb_Output_announce,$*,$(true),XCS,1)
+ $(call gb_Trace_StartRange,$*,XCS)
+ $(call gb_XcsTarget__command,$@,$*,$(filter %.xcs,$^))
+ $(call gb_Trace_EndRange,$*,XCS)
+
+$(call gb_XcsTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),XCS,1)
+ rm -f $(call gb_XcsTarget_get_target,$*)
+
+
+# XcuDataTarget class
+
+gb_XcuTarget_XSLT_AllLang := $(SRCDIR)/officecfg/util/alllang.xsl
+gb_XcuDataTarget_XSLT_DataVal := $(SRCDIR)/officecfg/util/data_val.xsl
+gb_XcuDataTarget_DTD_ComponentUpdate := $(SRCDIR)/officecfg/registry/component-update.dtd
+
+define gb_XcuDataTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) && \
+ $(gb_Configuration_XSLTCOMMAND) --nonet \
+ --noout \
+ --stringparam xcs $(call gb_XcsTarget_for_XcuTarget,$(XCUFILE)) \
+ $(gb_Configuration__stringparam_schemaRoot) \
+ --path $(SRCDIR)/officecfg/registry \
+ $(gb_XcuDataTarget_XSLT_DataVal) \
+ $(3) && \
+ $(gb_Configuration_XSLTCOMMAND) --nonet \
+ -o $(1) \
+ --stringparam xcs $(call gb_XcsTarget_for_XcuTarget,$(XCUFILE)) \
+ $(gb_Configuration__stringparam_schemaRoot) \
+ --stringparam LIBO_SHARE_FOLDER $(LIBO_SHARE_FOLDER) \
+ --stringparam LIBO_SHARE_HELP_FOLDER $(LIBO_SHARE_HELP_FOLDER) \
+ --path $(SRCDIR)/officecfg/registry \
+ $(gb_XcuTarget_XSLT_AllLang) \
+ $(3))
+endef
+
+$(call gb_XcuDataTarget_get_target,%) : $(gb_XcuDataTarget_XSLT_DataVal) \
+ $(gb_XcuTarget_XSLT_AllLang) $(gb_XcuDataTarget_DTD_ComponentUpdate) \
+ | $(gb_Configuration_XSLTCOMMAND_DEPS)
+ $(call gb_Output_announce,$*,$(true),XCU,2)
+ $(call gb_Trace_StartRange,$*,XCU)
+ $(call gb_XcuDataTarget__command,$@,$*,$(filter %.xcu,$^))
+ $(call gb_Trace_EndRange,$*,XCU)
+
+$(call gb_XcuDataTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),XCU,2)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_XcuDataTarget_get_target,$*))
+
+
+# XcuModuleTarget class
+
+define gb_XcuDataSource_for_XcuModuleTarget
+$(SRCDIR)/$(basename $(subst -,.,$(basename $(1)))).xcu
+endef
+
+define gb_XcsTarget_for_XcuModuleTarget
+$(call gb_XcsTarget_get_target,$(basename $(subst -,.,$(basename $(1)))).xcs)
+endef
+
+define gb_XcuModuleTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) && \
+ $(gb_Configuration_XSLTCOMMAND) --nonet \
+ -o $(1) \
+ --stringparam xcs $(4) \
+ $(gb_Configuration__stringparam_schemaRoot) \
+ --stringparam module $(notdir $(subst -,/,$(basename $(notdir $(2))))) \
+ --stringparam LIBO_SHARE_FOLDER $(LIBO_SHARE_FOLDER) \
+ --stringparam LIBO_SHARE_HELP_FOLDER $(LIBO_SHARE_HELP_FOLDER) \
+ $(gb_XcuTarget_XSLT_AllLang) \
+ $(3))
+endef
+
+$(call gb_XcuModuleTarget_get_target,%) : $(gb_XcuTarget_XSLT_AllLang) \
+ | $(gb_Configuration_XSLTCOMMAND_DEPS)
+ $(if $(filter %.xcu,$^),,$(error There is no target $(call gb_XcuModuleTarget_get_target,$*)))
+ $(call gb_Output_announce,$*,$(true),XCM,3)
+ $(call gb_Trace_StartRange,$*,XCM)
+ $(call gb_XcuModuleTarget__command,$@,$*,$(filter %.xcu,$^),$(filter %.xcs,$^))
+ $(call gb_Trace_EndRange,$*,XCM)
+
+$(call gb_XcuModuleTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),XCM,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_XcuModuleTarget_get_target,$*))
+
+
+# XcuLangpackTarget class
+
+gb_XcuLangpackTarget__get_name_with_lang = $(basename $(1))-$(2)$(suffix $(1))
+
+gb_XcuLangpackTarget__get_target_with_lang = \
+ $(call gb_XcuLangpackTarget_get_target,$(call gb_XcuLangpackTarget__get_name_with_lang,$(1),$(2)))
+
+gb_XcuLangpackTarget_SED_delcomment := $(SRCDIR)/officecfg/util/delcomment.sed
+
+define gb_XcuLangpackTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) && \
+ sed -e "s/__LANGUAGE__/$(LANGUAGE)/" -f $(gb_XcuLangpackTarget_SED_delcomment)\
+ $(3) > $(1))
+endef
+
+$(call gb_XcuLangpackTarget_get_target,%) : \
+ $(gb_XcuLangpackTarget_SED_delcomment)
+ $(call gb_Output_announce,$*,$(true),XCL,1)
+ $(call gb_Trace_StartRange,$*,XCL)
+ $(call gb_XcuLangpackTarget__command,$@,$*,$(filter %.tmpl,$^))
+ $(call gb_Trace_EndRange,$*,XCL)
+
+$(call gb_XcuLangpackTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),XCL,1)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(foreach lang,$(gb_Configuration_LANGS),\
+ $(call gb_XcuLangpackTarget__get_target_with_lang,$*,$(lang))))
+
+
+# XcuMergeTarget class
+
+gb_XcuMergeTarget_CFGEXDEPS := $(call gb_Executable_get_runtime_dependencies,cfgex)
+gb_XcuMergeTarget_CFGEXCOMMAND := $(call gb_Executable_get_command,cfgex)
+
+define gb_XcuMergeTarget__command
+MERGEINPUT=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(POFILES)) && \
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) && \
+ $(gb_XcuMergeTarget_CFGEXCOMMAND) \
+ -i $(3) \
+ -o $(1) \
+ -m $${MERGEINPUT} \
+ -l all) && \
+rm -rf $${MERGEINPUT}
+
+endef
+
+$(call gb_XcuMergeTarget_get_target,%) : $(gb_XcuMergeTarget_CFGEXDEPS)
+ $(if $(filter $(words $(POFILES)),$(words $(wildcard $(POFILES)))),\
+ $(call gb_Output_announce,$*,$(true),XCX,1) \
+ $(call gb_Trace_StartRange,$*,XCX) \
+ $(call gb_XcuMergeTarget__command,$@,$*,$(filter %.xcu,$^)),\
+ $(call gb_Trace_EndRange,$*,XCX) \
+ mkdir -p $(dir $@) && cp $(filter %.xcu,$^) $@)
+
+$(call gb_XcuMergeTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),XCX,1)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_XcuMergeTarget_get_target,$*))
+
+# $(call gb_XcuMergeTarget_XcuMergeTarget,target,configuration,prefix,xcufile)
+define gb_XcuMergeTarget_XcuMergeTarget
+$(call gb_XcuMergeTarget_get_target,$(1)) : \
+ $(SRCDIR)/$(3)/$(4) \
+ $(wildcard $(foreach lang,$(gb_TRANS_LANGS),$(gb_POLOCATION)/$(lang)/$(patsubst %/,%,$(dir $(1))).po))
+$(call gb_XcuMergeTarget_get_target,$(1)) : \
+ POFILES := $(foreach lang,$(gb_TRANS_LANGS),$(gb_POLOCATION)/$(lang)/$(patsubst %/,%,$(dir $(1))).po)
+$(foreach lang,$(gb_TRANS_LANGS),$(gb_POLOCATION)/$(lang)/$(patsubst %/,%,$(dir $(1))).po) :
+endef
+
+
+# XcuResTarget class
+
+# locale is extracted from the stem (parameter $(2))
+define gb_XcuResTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) && \
+ $(gb_Configuration_XSLTCOMMAND) --nonet \
+ -o $(1) \
+ --stringparam xcs $(call gb_XcsTarget_for_XcuTarget,$(XCUFILE)) \
+ $(gb_Configuration__stringparam_schemaRoot) \
+ --stringparam locale $(word 2,$(subst /, ,$(2))) \
+ --stringparam LIBO_SHARE_FOLDER $(LIBO_SHARE_FOLDER) \
+ --stringparam LIBO_SHARE_HELP_FOLDER $(LIBO_SHARE_HELP_FOLDER) \
+ --path $(SRCDIR)/officecfg/registry \
+ $(gb_XcuTarget_XSLT_AllLang) \
+ $(3))
+endef
+
+$(call gb_XcuResTarget_get_target,%) : $(gb_XcuTarget_XSLT_AllLang) \
+ | $(gb_Configuration_XSLTCOMMAND_DEPS)
+ $(call gb_Output_announce,$*,$(true),XCR,2)
+ $(call gb_Trace_StartRange,$*,XCR)
+ $(call gb_XcuResTarget__command,$@,$*,$(filter %.xcu,$^))
+ $(call gb_Trace_EndRange,$*,XCR)
+
+$(call gb_XcuResTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),XCR,2)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_XcuResTarget_get_target,$*))
+
+# $(call gb_XcuResTarget_XcuResTarget,target,configuration,prefix,xcufile,lang)
+# this depends either on the source or on the merge target (if WITH_LANG)
+define gb_XcuResTarget_XcuResTarget
+ifeq ($(strip $(gb_WITH_LANG)),)
+$(call gb_XcuResTarget_get_target,$(1)) : $(SRCDIR)/$(3)/$(4)
+else
+$(call gb_XcuResTarget_get_target,$(1)) : \
+ $(call gb_XcuMergeTarget_get_target,$(3)/$(4))
+endif
+$(call gb_XcuResTarget_get_target,$(1)) : \
+ $(call gb_XcsTarget_for_XcuTarget,$(4))
+$(call gb_XcuResTarget_get_target,$(1)) : PRIMARY_REGISTRY := $(filter $(2),$(gb_Configuration_PRIMARY_REGISTRY_NAME))
+$(call gb_XcuResTarget_get_target,$(1)) : XCUFILE := $(4)
+endef
+
+
+# Configuration class
+
+$(call gb_Configuration_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),CFG,4)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_Configuration_get_target,$*) $(call gb_Configuration_get_preparation_target,$*))
+
+$(call gb_Configuration_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),CFG,4)
+ $(call gb_Trace_MakeMark,$*,CFG)
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && touch $@)
+
+$(call gb_Configuration_get_preparation_target,%) :
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && touch $@)
+
+# $(call gb_Configuration_Configuration,configuration,nodeliver)
+# last parameter may be used to turn off delivering of files
+# FIXME: not anymore, no files are delivered now
+define gb_Configuration_Configuration
+$(eval gb_Configuration_NODELIVER_$(1) := $(2))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_Configuration_get_target,$(1)),$(call gb_Configuration_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),Configuration)
+
+endef
+
+# $(call gb_Configuration_add_schema,configuration,prefix,xcsfile)
+# hopefully extensions do not need to add schemas with same name as officecfg
+define gb_Configuration_add_schema
+$(call gb_Configuration_get_clean_target,$(1)) : \
+ $(call gb_XcsTarget_get_clean_target,$(3))
+$(call gb_XcsTarget_get_target,$(3)) : \
+ $(SRCDIR)/$(2)/$(3) \
+ $(call gb_Configuration_get_preparation_target,$(1))
+$(call gb_XcsTarget_get_target,$(3)) : PRIMARY_REGISTRY := $(filter $(1),$(gb_Configuration_PRIMARY_REGISTRY_NAME))
+$(call gb_Configuration_get_target,$(1)) : \
+ $(call gb_XcsTarget_get_target,$(3))
+
+endef
+
+#$(call gb_Configuration_add_schemas,configuration,prefix,xcsfiles)
+define gb_Configuration_add_schemas
+$(foreach xcs,$(3),$(call gb_Configuration_add_schema,$(1),$(2),$(xcs)))
+
+endef
+
+# $(call gb_Configuration_add_data,configuration,prefix,xcufile)
+define gb_Configuration_add_data
+$(call gb_Configuration_get_clean_target,$(1)) : \
+ $(call gb_XcuDataTarget_get_clean_target,$(2)/$(3))
+$(call gb_XcuDataTarget_get_target,$(2)/$(3)) : \
+ $(SRCDIR)/$(2)/$(3) \
+ $(call gb_Configuration_get_preparation_target,$(1)) \
+ $(call gb_XcsTarget_for_XcuTarget,$(3))
+$(call gb_XcuDataTarget_get_target,$(2)/$(3)) : PRIMARY_REGISTRY := $(filter $(1),$(gb_Configuration_PRIMARY_REGISTRY_NAME))
+$(call gb_XcuDataTarget_get_target,$(2)/$(3)) : XCUFILE := $(3)
+$(call gb_Configuration_get_target,$(1)) : \
+ $(call gb_XcuDataTarget_get_target,$(2)/$(3))
+
+endef
+
+#$(call gb_Configuration_add_datas,configuration,prefix,xcufiles)
+define gb_Configuration_add_datas
+$(foreach xcu,$(3),$(call gb_Configuration_add_data,$(1),$(2),$(xcu)))
+
+endef
+
+# $(call gb_Configuration_add_spool_module,configuration,prefix,xcufile)
+define gb_Configuration_add_spool_module
+$(call gb_Configuration_get_clean_target,$(1)) : \
+ $(call gb_XcuModuleTarget_get_clean_target,$(2)/$(3))
+$(call gb_XcuModuleTarget_get_target,$(2)/$(3)) : \
+ $(call gb_XcuDataSource_for_XcuModuleTarget,$(2)/$(3)) \
+ $(call gb_Configuration_get_preparation_target,$(1)) \
+ $(call gb_XcsTarget_for_XcuModuleTarget,$(3))
+$(call gb_XcuModuleTarget_get_target,$(2)/$(3)) : PRIMARY_REGISTRY := $(filter $(1),$(gb_Configuration_PRIMARY_REGISTRY_NAME))
+$(call gb_Configuration_get_target,$(1)) : \
+ $(call gb_XcuModuleTarget_get_target,$(2)/$(3))
+
+endef
+
+# $(call gb_Configuration_add_spool_modules,configuration,prefix,xcufiles)
+define gb_Configuration_add_spool_modules
+$(foreach xcu,$(3),$(call gb_Configuration_add_spool_module,$(1),$(2),$(xcu)))
+
+endef
+
+define gb_Configuration__add_langpack
+$(if $(gb_Configuration_NODELIVER_$(1)),\
+ $(error TODO not needed yet: cannot add langpack if nodeliver))
+$(call gb_Configuration_get_target,$(1)) : \
+ $(call gb_XcuLangpackTarget__get_target_with_lang,$(3),$(4))
+$(call gb_XcuLangpackTarget__get_target_with_lang,$(3),$(4)) : \
+ $(SRCDIR)/$(2)/$(3).tmpl
+$(call gb_XcuLangpackTarget__get_target_with_lang,$(3),$(4)) : LANGUAGE := $(4)
+
+endef
+
+# $(call gb_Configuration_add_spool_langpack,configuration,prefix,xcufile)
+define gb_Configuration_add_spool_langpack
+$(foreach lang,$(gb_Configuration_LANGS),$(eval \
+ $(call gb_Configuration__add_langpack,$(1),$(2),$(strip $(3)),$(lang))))
+$(call gb_Configuration_get_clean_target,$(1)) : \
+ $(call gb_XcuLangpackTarget_get_clean_target,$(strip $(3)))
+
+endef
+
+# $(call gb_Configuration_add_localized_data,configuration,prefix,xcufile)
+define gb_Configuration_add_localized_data
+$(eval $(call gb_Configuration_add_data,$(1),$(2),$(3)))
+ifneq ($(strip $(gb_WITH_LANG)),)
+$(eval $(call gb_XcuMergeTarget_XcuMergeTarget,$(2)/$(3),$(1),$(2),$(3)))
+$(eval $(call gb_Configuration_get_clean_target,$(1)) : \
+ $(call gb_XcuMergeTarget_get_clean_target,$(2)/$(3)))
+endif
+$(foreach lang,$(gb_Configuration_LANGS),$(eval \
+ $(call gb_XcuResTarget_XcuResTarget,$(1)/$(lang)/$(3),$(1),$(2),$(3),$(lang))))
+$(foreach lang,$(gb_Configuration_LANGS),$(eval \
+ $(call gb_Configuration_get_target,$(1)) : \
+ $(call gb_XcuResTarget_get_target,$(1)/$(lang)/$(3))))
+$(foreach lang,$(gb_Configuration_LANGS),$(eval \
+ $(call gb_Configuration_get_clean_target,$(1)) : \
+ $(call gb_XcuResTarget_get_clean_target,$(1)/$(lang)/$(3))))
+
+endef
+
+# $(call gb_Configuration_add_localized_datas,configuration,prefix,xcufile)
+define gb_Configuration_add_localized_datas
+$(foreach xcu,$(3),$(call gb_Configuration_add_localized_data,$(1),$(2),$(xcu)))
+
+endef
+
+# Set extra registry this configuration can use schemas from.
+#
+# Example:
+# # foo needs schemas from the main configuration
+# $(eval $(call gb_Configuration_use_configuration,foo,registry))
+define gb_Configuration_use_configuration
+$(call gb_Configuration_get_preparation_target,$(1)) : $(call gb_Configuration_get_target,$(2))
+
+endef
+
+# apparently extensions package the XcuMergeTarget directly...
+# trivial convenience function to get the right file:
+ifeq ($(gb_WITH_LANG),)
+gb_XcuFile_for_extension = $(SRCDIR)/$(1)
+else
+gb_XcuFile_for_extension = $(call gb_XcuMergeTarget_get_target,$(1))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/CppunitTest.mk b/solenv/gbuild/CppunitTest.mk
new file mode 100644
index 000000000..9545f0c52
--- /dev/null
+++ b/solenv/gbuild/CppunitTest.mk
@@ -0,0 +1,495 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# CppunitTest class
+
+gb_CppunitTest_UNITTESTFAILED ?= $(GBUILDDIR)/platform/unittest-failed-default.sh
+gb_CppunitTest_PYTHONDEPS ?= $(call gb_Library_get_target,pyuno_wrapper) $(if $(SYSTEM_PYTHON),,$(call gb_Package_get_target,python3))
+
+ifneq ($(strip $(CPPUNITTRACE)),)
+ifneq ($(filter gdb,$(CPPUNITTRACE)),)
+# sneak (a) setting the LD_LIBRARY_PATH, and (b) setting malloc debug flags, into the "gdb --args" command line
+gb_CppunitTest_GDBTRACE := $(subst gdb,\
+ PYTHONWARNINGS=default gdb -return-child-result -ex "add-auto-load-safe-path $(INSTDIR)" -ex "set environment $(subst =, ,$(gb_CppunitTest_CPPTESTPRECOMMAND))" $(if $(PYTHONWARNINGS),-ex 'set environment PYTHONWARNINGS $(PYTHONWARNINGS)') $(gb_CppunitTest_malloc_check) $(gb_CppunitTest_DEBUGCPPUNIT),\
+ $(CPPUNITTRACE))
+gb_PythonTest_GDBTRACE := $(subst gdb,\
+ PYTHONWARNINGS=default gdb -return-child-result -ex "add-auto-load-safe-path $(INSTDIR)" -ex "set environment $(subst =, ,$(gb_PythonTest_PRECOMMAND))" $(if $(PYTHONWARNINGS),-ex 'set environment PYTHONWARNINGS $(PYTHONWARNINGS)') $(gb_CppunitTest_malloc_check) $(gb_CppunitTest_DEBUGCPPUNIT),\
+ $(CPPUNITTRACE))
+else ifneq ($(filter lldb,$(CPPUNITTRACE)),)
+gb_CppunitTest_GDBTRACE := $(subst lldb,\
+ lldb -o "env $(gb_CppunitTest_CPPTESTPRECOMMAND)" $(gb_CppunitTest_malloc_check),\
+ $(CPPUNITTRACE))
+gb_PythonTest_GDBTRACE := $(gb_CppunitTest_GDBTRACE)
+else
+gb_CppunitTest_GDBTRACE := $(CPPUNITTRACE)
+gb_PythonTest_GDBTRACE := $(gb_CppunitTest_GDBTRACE)
+endif
+ifneq ($(strip $(DEBUGCPPUNIT)),TRUE)
+gb_CppunitTest__interactive := $(true)
+endif
+endif
+
+ifneq ($(strip $(VALGRIND)),)
+gb_CppunitTest_VALGRINDTOOL := valgrind --tool=$(VALGRIND) --num-callers=50 --error-exitcode=1 --trace-children=yes --trace-children-skip='*/java,*/gij'
+ifneq ($(strip $(VALGRIND_GDB)),)
+gb_CppunitTest_VALGRINDTOOL += --vgdb=yes --vgdb-error=0
+endif
+ifeq ($(strip $(VALGRIND)),memcheck)
+G_SLICE := always-malloc
+GLIBCXX_FORCE_NEW := 1
+endif
+endif
+
+ifneq (,$(filter perfcheck,$(MAKECMDGOALS)))
+$(if $(ENABLE_VALGRIND),,$(call gb_Output_error,Running performance tests with empty $$(ENABLE_VALGRIND) does not make sense. Please install valgrind-dev and re-run autogen.))
+gb_CppunitTest_VALGRINDTOOL := valgrind --tool=callgrind --dump-instr=yes --instr-atstart=no --simulate-cache=yes --dump-instr=yes --collect-bus=yes --branch-sim=yes
+ifneq ($(strip $(VALGRIND_GDB)),)
+gb_CppunitTest_VALGRINDTOOL += --vgdb=yes --vgdb-error=0
+endif
+endif
+
+ifneq ($(strip $(RR)),)
+gb_CppunitTest_RR := rr record
+endif
+
+# defined by platform
+# gb_CppunitTest_get_filename
+gb_CppunitTest_RUNTIMEDEPS := $(call gb_Executable_get_runtime_dependencies,cppunittester)
+gb_CppunitTest_CPPTESTCOMMAND := $(call gb_Executable_get_target_for_build,cppunittester)
+
+# i18npool dlopens localedata_* libraries.
+gb_CppunitTest_RUNTIMEDEPS += \
+ $(call gb_Library_get_target,localedata_en) \
+ $(call gb_Library_get_target,localedata_es) \
+ $(call gb_Library_get_target,localedata_euro) \
+ $(call gb_Library_get_target,localedata_others) \
+ $(call gb_Package_get_target,test_unittest) \
+
+define gb_CppunitTest__make_args
+$(HEADLESS) \
+"-env:BRAND_BASE_DIR=$(call gb_Helper_make_url,$(INSTROOT))" \
+"-env:BRAND_SHARE_SUBDIR=$(LIBO_SHARE_FOLDER)" \
+"-env:BRAND_SHARE_RESOURCE_SUBDIR=$(LIBO_SHARE_RESOURCE_FOLDER)" \
+"-env:UserInstallation=$(call gb_Helper_make_url,$(call gb_CppunitTest_get_target,$*).user)" \
+$(if $(URE),\
+ $(if $(strip $(CONFIGURATION_LAYERS)),\
+ "-env:CONFIGURATION_LAYERS=$(strip $(CONFIGURATION_LAYERS))") \
+ $(if $(strip $(UNO_TYPES)),\
+ "-env:UNO_TYPES=$(foreach item,$(UNO_TYPES),$(call gb_Helper_make_url,$(item)))") \
+ $(if $(strip $(UNO_SERVICES)),\
+ "-env:UNO_SERVICES=$(foreach item,$(UNO_SERVICES),$(call gb_Helper_make_url,$(item)))" -env:URE_BIN_DIR=$(call gb_Helper_make_url,$(INSTROOT)/$(LIBO_URE_BIN_FOLDER))) \
+ -env:URE_INTERNAL_LIB_DIR=$(call gb_Helper_make_url,$(INSTROOT)/$(LIBO_URE_LIB_FOLDER)) \
+ -env:LO_LIB_DIR=$(call gb_Helper_make_url,$(INSTROOT)/$(LIBO_LIB_FOLDER)) \
+ -env:LO_JAVA_DIR=$(call gb_Helper_make_url,$(INSTROOT)/$(LIBO_SHARE_JAVA_FOLDER)) \
+ --protector $(call gb_Library_get_target,unoexceptionprotector) unoexceptionprotector \
+ --protector $(call gb_Library_get_target,unobootstrapprotector) unobootstrapprotector \
+ ) \
+$(if $(VCL),\
+ --protector $(call gb_Library_get_target,vclbootstrapprotector) vclbootstrapprotector \
+ ) \
+$(ARGS)
+endef
+
+.PHONY : $(call gb_CppunitTest_get_clean_target,%)
+$(call gb_CppunitTest_get_clean_target,%) :
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_CppunitTest_get_target,$*) $(call gb_CppunitTest_get_target,$*).log)
+
+.PHONY : $(call gb_CppunitTest_get_target,%)
+$(call gb_CppunitTest_get_target,%) :| $(gb_CppunitTest_RUNTIMEDEPS)
+ifneq ($(gb_SUPPRESS_TESTS),)
+ @true
+else
+ $(call gb_Output_announce,$*,$(true),CUT,2)
+ $(call gb_Trace_StartRange,$*,CUT)
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && \
+ rm -fr $@.user && cp -r $(WORKDIR)/unittest $@.user && \
+ $(if $(gb_CppunitTest__use_confpreinit), \
+ $(INSTDIR)/program/lokconf_init $(call gb_CppunitTest__make_args) &&) \
+ $(if $(gb_CppunitTest__interactive),, \
+ $(if $(value gb_CppunitTest_postprocess), \
+ rm -fr $@.core && mkdir $@.core && cd $@.core &&)) \
+ ( \
+ $(if $(gb_CppunitTest_localized),for l in $(WITH_LANG_LIST) ; do \
+ printf 'LO_TEST_LOCALE=%s\n' "$$l" && LO_TEST_LOCALE="$$l" ) \
+ $(if $(gb_CppunitTest__vcl_no_svp), \
+ $(filter-out SAL_USE_VCLPLUGIN=svp,$(gb_TEST_ENV_VARS)),$(gb_TEST_ENV_VARS)) \
+ $(EXTRA_ENV_VARS) \
+ $(if $(filter gdb,$(gb_CppunitTest_GDBTRACE)),,$(gb_CppunitTest_CPPTESTPRECOMMAND)) \
+ $(if $(G_SLICE),G_SLICE=$(G_SLICE)) \
+ $(if $(GLIBCXX_FORCE_NEW),GLIBCXX_FORCE_NEW=$(GLIBCXX_FORCE_NEW)) \
+ $(if $(strip $(PYTHON_URE)),\
+ PYTHONDONTWRITEBYTECODE=1) \
+ $(ICECREAM_RUN) $(gb_CppunitTest_GDBTRACE) $(gb_CppunitTest_VALGRINDTOOL) $(gb_CppunitTest_RR) \
+ $(gb_CppunitTest_CPPTESTCOMMAND) \
+ $(call gb_CppunitTest_get_linktarget_target,$*) \
+ $(call gb_CppunitTest__make_args) "-env:CPPUNITTESTTARGET=$@" \
+ $(if $(gb_CppunitTest_localized),|| exit $$?; done) \
+ ) \
+ $(if $(gb_CppunitTest__interactive),, \
+ > $@.log 2>&1 \
+ || ($(if $(value gb_CppunitTest_postprocess), \
+ RET=$$?; \
+ $(call gb_CppunitTest_postprocess,$(gb_CppunitTest_CPPTESTCOMMAND),$@.core,$$RET) >> $@.log 2>&1;) \
+ cat $@.log; $(gb_CppunitTest_UNITTESTFAILED) Cppunit $*)))
+ $(call gb_Trace_EndRange,$*,CUT)
+endif
+
+define gb_CppunitTest_CppunitTest
+$(call gb_CppunitTest__CppunitTest_impl,$(1),$(call gb_CppunitTest_get_linktarget,$(1)))
+
+endef
+
+define gb_CppunitTest_CppunitScreenShot
+$(call gb_CppunitTest_get_target,$(1)) : gb_CppunitTest_localized := $(true)
+$(call gb_CppunitTest__CppunitTest_impl,$(1),$(call gb_CppunitTest_get_linktarget,$(1)))
+
+endef
+
+define gb_CppunitTest_register_target
+endef
+
+# call gb_CppunitTest__CppunitTest_impl,cppunittest,linktarget
+define gb_CppunitTest__CppunitTest_impl
+$(call gb_CppunitTest_register_target, $(1), $(2), "test")
+$(call gb_LinkTarget_LinkTarget,$(2),CppunitTest_$(1),NONE)
+$(call gb_LinkTarget_set_targettype,$(2),CppunitTest)
+$(call gb_LinkTarget_add_libs,$(2),$(gb_STDLIBS))
+$(call gb_LinkTarget_add_defs,$(2),\
+ $(gb_CppunitTest_DEFS) \
+)
+$(call gb_LinkTarget_use_external,$(2),cppunit)
+$(call gb_LinkTarget_set_include,$(2),\
+ $$(INCLUDE) \
+ $(filter -I%,$(CPPUNIT_CFLAGS)) \
+)
+$(call gb_LinkTarget_add_defs,$(2), \
+ $(filter-out -I%,$(CPPUNIT_CFLAGS)) \
+ -DCPPUNIT_PLUGIN_EXPORT='extern "C" SAL_DLLPUBLIC_EXPORT' \
+)
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_LinkTarget_get_target,$(2))
+$(call gb_CppunitTest_get_clean_target,$(1)) : $(call gb_LinkTarget_get_clean_target,$(2))
+$(call gb_CppunitTest_CppunitTest_platform,$(1),$(2),$(gb_CppunitTest_DLLDIR)/$(call gb_CppunitTest_get_ilibfilename,$(1)))
+$(call gb_CppunitTest_get_target,$(1)) : ARGS :=
+$(call gb_CppunitTest_get_target,$(1)) : CONFIGURATION_LAYERS :=
+$(call gb_CppunitTest_get_target,$(1)) : PYTHON_URE := $(false)
+$(call gb_CppunitTest_get_target,$(1)) : URE := $(false)
+$(call gb_CppunitTest_get_target,$(1)) : VCL := $(false)
+$(call gb_CppunitTest_get_target,$(1)) : UNO_SERVICES :=
+$(call gb_CppunitTest_get_target,$(1)) : UNO_TYPES :=
+$(call gb_CppunitTest_get_target,$(1)) : HEADLESS := --headless
+$(call gb_CppunitTest_get_target,$(1)) : EXTRA_ENV_VARS :=
+$$(eval $$(call gb_Module_register_target,$(call gb_CppunitTest_get_target,$(1)),$(call gb_CppunitTest_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),CppunitTest)
+
+endef
+
+# Add additional command line arguments for the test.
+#
+# You should practically never need to use this, as there are special
+# functions for adding many commonly used arguments.
+define gb_CppunitTest_add_arguments
+$(call gb_CppunitTest_get_target,$(1)) : ARGS += $(2)
+
+endef
+
+define gb_CppunitTest_use_ure
+$(call gb_CppunitTest_use_rdb,$(1),ure/services)
+$(call gb_CppunitTest_get_target,$(1)) : URE := $(true)
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_Library_get_target,$(CPPU_ENV)_uno)
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_Library_get_target,affine_uno)
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_Library_get_target,unobootstrapprotector)
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_Library_get_target,unoexceptionprotector)
+
+endef
+
+# $(2) == $(true) if headless:
+define gb_CppunitTest__use_vcl
+$(call gb_CppunitTest_get_target,$(1)) : VCL := $(true)
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_Library_get_target,vclbootstrapprotector)
+ifeq ($(USING_X11),TRUE)
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_Library_get_target,desktop_detector)
+$(call gb_CppunitTest_get_target,$(1)) : $(if $(filter $(2),$(true)),, \
+ $(call gb_Library_get_target,vclplug_gen) \
+ $(if $(ENABLE_GTK3),$(call gb_Library_get_target,vclplug_gtk3)) \
+ $(if $(ENABLE_GTK4),$(call gb_Library_get_target,vclplug_gtk4)) \
+ $(if $(ENABLE_QT5),$(call gb_Library_get_target,vclplug_qt5)) \
+ $(if $(ENABLE_QT6),$(call gb_Library_get_target,vclplug_qt6)) \
+ )
+else ifeq ($(OS),MACOSX)
+$(call gb_CppunitTest_get_target,$(1)): $(call gb_Library_get_target,vclplug_osx)
+else ifeq ($(OS),WNT)
+$(call gb_CppunitTest_get_target,$(1)): $(call gb_Library_get_target,vclplug_win)
+endif
+
+endef
+
+define gb_CppunitTest_use_confpreinit
+$(call gb_CppunitTest_use_executable,$(1),lokconf_init)
+$(call gb_CppunitTest_get_target,$(1)) : gb_CppunitTest__use_confpreinit := TRUE
+
+endef
+
+define gb_CppunitTest_use_vcl
+$(call gb_CppunitTest__use_vcl,$(1),$(true))
+
+endef
+
+define gb_CppunitTest_use_vcl_non_headless
+$(call gb_CppunitTest_get_target,$(1)) : gb_CppunitTest__vcl_no_svp := $(true)
+$(call gb_CppunitTest__use_vcl,$(1),$(false))
+
+endef
+
+define gb_CppunitTest_use_vcl_non_headless_with_windows
+$(call gb_CppunitTest_get_target,$(1)) : HEADLESS :=
+$(call gb_CppunitTest_get_target,$(1)) : gb_CppunitTest__vcl_no_svp := $(true)
+$(call gb_CppunitTest__use_vcl,$(1),$(false))
+
+endef
+
+define gb_CppunitTest_localized_run
+$(call gb_CppunitTest_get_target,$(1)) : gb_CppunitTest_localized := $(true)
+
+endef
+
+define gb_CppunitTest__use_api
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_UnoApi_get_target,$(2))
+$(call gb_CppunitTest_get_target,$(1)) : UNO_TYPES += $(call gb_UnoApi_get_target,$(2))
+
+endef
+
+define gb_CppunitTest_use_api
+$(call gb_LinkTarget_use_api,$(call gb_CppunitTest_get_linktarget,$(1)),$(2))
+$(foreach rdb,$(2),$(call gb_CppunitTest__use_api,$(1),$(rdb)))
+
+endef
+
+define gb_CppunitTest_use_udk_api
+$(call gb_CppunitTest_use_api,$(1),udkapi)
+
+endef
+
+define gb_CppunitTest_use_sdk_api
+$(call gb_CppunitTest_use_api,$(1),udkapi offapi)
+
+endef
+
+define gb_CppunitTest_use_rdb
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_Rdb_get_target_for_build,$(2))
+$(call gb_CppunitTest_get_target,$(1)) : UNO_SERVICES += $(call gb_Rdb_get_target_for_build,$(2))
+
+endef
+
+define gb_CppunitTest_use_rdbs
+$(foreach rdb,$(2),$(call gb_CppunitTest_use_rdb,$(1),$(rdb)))
+
+endef
+
+define gb_CppunitTest_use_component
+$(call gb_CppunitTest_get_target,$(1)) : \
+ $(call gb_ComponentTarget_get_target,$(2))
+$(call gb_CppunitTest_get_target,$(1)) : \
+ UNO_SERVICES += $(call gb_ComponentTarget_get_target,$(2))
+
+endef
+
+define gb_CppunitTest_set_componentfile
+$(call gb_ComponentTarget_ComponentTarget,CppunitTest/$(2),\
+ $(call gb_Helper_make_url,$(gb_CppunitTest_DLLDIR))/,\
+ $(call gb_CppunitTest_get_filename,$(1)))
+$(call gb_CppunitTest_get_target,$(1)) : \
+ $(call gb_ComponentTarget_get_target,CppunitTest/$(2))
+$(call gb_CppunitTest_get_clean_target,$(1)) : \
+ $(call gb_ComponentTarget_get_clean_target,CppunitTest/$(2))
+$(call gb_CppunitTest_use_component,$(1),CppunitTest/$(2))
+
+endef
+
+# Given a list of component files, filter out those corresponding
+# to libraries not built in this configuration.
+define gb_CppunitTest__filter_not_built_components
+$(filter-out \
+ $(if $(filter SCRIPTING,$(BUILD_TYPE)),, \
+ basic/util/sb \
+ sw/util/vbaswobj \
+ scripting/source/basprov/basprov \
+ scripting/util/scriptframe) \
+ $(if $(filter DBCONNECTIVITY,$(BUILD_TYPE)),, \
+ dbaccess/util/dba \
+ forms/util/frm),$(1))
+endef
+
+define gb_CppunitTest_use_components
+$(foreach component,$(call gb_CppunitTest__filter_not_built_components,$(2)),$(call gb_CppunitTest_use_component,$(1),$(component)))
+
+endef
+
+define gb_CppunitTest__use_configuration
+$(call gb_CppunitTest_get_target,$(1)) : CONFIGURATION_LAYERS += $(2):$(call gb_Helper_make_url,$(3))
+
+endef
+
+# Use instdir configuration
+define gb_CppunitTest_use_instdir_configuration
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_Package_get_target,postprocess_registry)
+$(call gb_CppunitTest__use_configuration,$(1),xcsxcu,$(INSTROOT)/$(LIBO_SHARE_FOLDER)/registry)
+
+endef
+
+# Use configuration in $(WORKDIR)/unittest/registry.
+define gb_CppunitTest_use_unittest_configuration
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_Package_get_target,test_unittest)
+$(call gb_CppunitTest__use_configuration,$(1),xcsxcu,$(WORKDIR)/unittest/registry)
+
+endef
+
+# Use standard configuration: instdir config + unittest config (in this order!)
+define gb_CppunitTest_use_configuration
+$(call gb_CppunitTest_use_instdir_configuration,$(1))
+$(call gb_CppunitTest_use_unittest_configuration,$(1))
+
+endef
+
+define gb_CppunitTest_use_executable
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_Executable_get_target,$(2))
+
+endef
+
+define gb_CppunitTest_use_more_fonts
+ifneq ($(filter MORE_FONTS,$(BUILD_TYPE)),)
+$(call gb_CppunitTest_get_target,$(1)) : \
+ $(foreach font,$(gb_Package_MODULE_ooo_fonts),$(call gb_Package_get_target,$(font)))
+endif
+
+endef
+
+define gb_CppunitTest__use_java_ure
+$(call gb_CppunitTest_get_target,$(1)) : \
+ $(foreach jar,java_uno libreoffice unoloader,$(call gb_Jar_get_target,$(jar))) \
+ $(call gb_Library_get_target,affine_uno_uno) \
+ $(call gb_Library_get_target,java_uno) \
+ $(call gb_Library_get_target,jpipe) \
+ $(call gb_Library_get_target,juhx) \
+ $(call gb_Library_get_target,juhx) \
+ $(call gb_Library_get_target,jvmaccess) \
+ $(call gb_Library_get_target,jvmfwk) \
+ $(call gb_Package_get_target,jvmfwk_javavendors) \
+ $(call gb_Package_get_target,jvmfwk_jreproperties) \
+ $(call gb_Package_get_target,jvmfwk_jvmfwk3_ini) \
+
+endef
+
+define gb_CppunitTest_use_jar
+$(call gb_CppunitTest__use_java_ure,$(1))
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_Jar_get_target,$(2))
+
+endef
+
+define gb_CppunitTest_use_jars
+$(foreach jar,$(2),$(call gb_CppunitTest_use_jar,$(1),$(jar)))
+
+endef
+
+define gb_CppunitTest_use_python_ure
+$(call gb_CppunitTest_get_target,$(1)) : PYTHON_URE := $(true)
+$(call gb_CppunitTest_get_target,$(1)) :\
+ $(call gb_Library_get_target,pythonloader) \
+ $(call gb_Library_get_target,pyuno) \
+ $(gb_CppunitTest_PYTHONDEPS) \
+ $(call gb_Package_get_target,pyuno_python_scripts)
+
+endef
+
+define gb_CppunitTest_use_uiconfig
+$(call gb_CppunitTest_get_target,$(1)) : $(call gb_UIConfig_get_target,$(2))
+
+endef
+
+define gb_CppunitTest_use_uiconfigs
+$(foreach uiconfig,$(2),$(call gb_CppunitTest_use_uiconfig,$(1),$(uiconfig)))
+
+endef
+
+# forward the call to the gb_LinkTarget implementation
+# (note: because the function name is in $(1), the other args are shifted by 1)
+define gb_CppunitTest__forward_to_Linktarget
+$(call gb_LinkTarget_$(subst gb_CppunitTest_,,$(1)),$(call gb_CppunitTest_get_linktarget,$(2)),$(3),$(4),CppunitTest_$(2))
+
+endef
+
+# copy pasta for forwarding: this could be (and was) done more elegantly, but
+# these here can be found by both git grep and ctags
+gb_CppunitTest_add_cobject = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_cobjects = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_cxxobject = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_cxxobjects = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_exception_objects = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_executable_objects = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_library_objects = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_libraries = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_static_libraries = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_objcobject = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_objcobjects = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_objcxxobject = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_objcxxobjects = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_cxxclrobject = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_cxxclrobjects = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_asmobject = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_asmobjects = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_package = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_packages = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_set_precompiled_header = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_reuse_precompiled_header = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_common_precompiled_header = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_sdi_headers = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_cflags = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_set_cflags = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_cxxflags = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_set_yaccflags = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_objcflags = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_objcxxflags = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_cxxclrflags = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_defs = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_set_include = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_ldflags = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_set_ldflags = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_libs = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_disable_standard_system_libs = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_system_darwin_frameworks = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_system_win32_libs = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_internal_api = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_internal_bootstrap_api = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_internal_comprehensive_api = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_set_library_path_flags = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_external = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_externals = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_custom_headers = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_set_visibility_default = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_set_warnings_not_errors = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_set_warnings_disabled = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_set_external_code = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_set_generated_cxx_suffix = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_clang = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_set_clang_precompiled_header = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_use_vclmain = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_CppunitTest_add_prejs = $(call gb_CppunitTest__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/CustomTarget.mk b/solenv/gbuild/CustomTarget.mk
new file mode 100644
index 000000000..1ea43aa12
--- /dev/null
+++ b/solenv/gbuild/CustomTarget.mk
@@ -0,0 +1,136 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# the .dir is for make 3.81, which ignores trailing /
+$(call gb_CustomTarget_get_workdir,%)/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_CustomTarget_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),CUS,3)
+ $(call gb_Trace_MakeMark,$*,CUS)
+ touch $@
+
+.PHONY: $(call gb_CustomTarget_get_clean_target,%)
+$(call gb_CustomTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),CUS,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf $(call gb_CustomTarget_get_workdir,$*) && \
+ rm -f $(call gb_CustomTarget_get_target,$*))
+
+define gb_CustomTarget_CustomTarget
+$(eval $(call gb_Module_register_target,$(call gb_CustomTarget_get_target,$(1)),$(call gb_CustomTarget_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),CustomTarget)
+$(call gb_CustomTarget_get_target,$(1)) :| $(dir $(call gb_CustomTarget_get_target,$(1))).dir
+
+endef
+
+define gb_CustomTarget_register_target
+$(call gb_CustomTarget_get_target,$(1)) : $(call gb_CustomTarget_get_workdir,$(1))/$(2)
+$(call gb_CustomTarget_get_workdir,$(1))/$(2) :| $(dir $(call gb_CustomTarget_get_workdir,$(1))/$(2)).dir
+
+endef
+
+define gb_CustomTarget_register_targets
+$(foreach target,$(2),$(call gb_CustomTarget_register_target,$(1),$(target)))
+
+endef
+
+ifneq ($(WITH_LANG),)
+
+# $(call gb_CustomTarget_ulfex__command,ulftarget,ulfsource,pofiles)
+define gb_CustomTarget_ulfex__command
+$(call gb_Output_announce,$(1),$(true),ULF,1)
+ $(call gb_Trace_StartRange,$(1),ULF)
+MERGEINPUT=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(3)) && \
+$(call gb_Helper_abbreviate_dirs,\
+ $(call gb_Executable_get_command,ulfex) -i $(2) -o $(1) -m $${MERGEINPUT} -l all) && \
+rm -rf $${MERGEINPUT}
+ $(call gb_Trace_EndRange,$(1),ULF)
+endef
+
+else
+
+define gb_CustomTarget_ulfex__command
+cp $(2) $(1)
+endef
+
+endif
+
+# $(call gb_CustomTarget_ulfex_rule,ulftargetpattern,ulfsource,pofiles)
+define gb_CustomTarget_ulfex_rule
+$(1) : $(2) $(if $(WITH_LANG),$(call gb_Executable_get_runtime_dependencies,ulfex)) | $(dir $(1)).dir
+ $$(call gb_CustomTarget_ulfex__command,$$@,$(subst %,$$*,$(strip $(2))),$(strip $(3)))
+
+endef
+
+#$(call gb_CustomTarget_token_hash,oox/generated,tokenhash.inc,tokenhash.gperf)
+define gb_CustomTarget_token_hash
+$(call gb_CustomTarget_get_target,$(1)) : $(call gb_CustomTarget_get_workdir,$(1))/$(2)
+$(call gb_CustomTarget_get_workdir,$(1))/$(2) : $(call gb_CustomTarget_get_workdir,$(1))/misc/$(3)
+ $$(call gb_Output_announce,$$(subst $(WORKDIR)/,,$$@),build,GPF,1)
+ $(GPERF) --compare-strncmp --switch=2 --readonly-tables $$< \
+ | sed -e 's/char\*)0/(char\*)0, 0/g' | grep -v '^#line' > $$@
+
+endef
+
+#$(call gb_CustomTarget_generate_tokens,oox/generated,oox,oox/source/token,
+#namespaces,namespace,namespaces.txt,namespaces-strict,namespaces.pl)
+define gb_CustomTarget_generate_tokens
+$(call gb_CustomTarget_get_workdir,$(1))/misc/$(5)ids.inc \
+$(call gb_CustomTarget_get_workdir,$(1))/$(5)names.inc \
+$(if $(6),$(call gb_CustomTarget_get_workdir,$(1))/misc/$(6)) \
+$(if $(7),$(call gb_CustomTarget_get_workdir,$(1))/$(7)names.inc) : \
+ $(call gb_CustomTarget_get_workdir,$(1))/$(2)/token/$(4).hxx
+ touch $$@
+
+$(call gb_CustomTarget_get_workdir,$(1))/$(2)/token/$(4).hxx : \
+ $(call gb_ExternalExecutable_get_dependencies,python) \
+ $(if $(7),$(SRCDIR)/$(3)/$(7).txt) \
+ $(if $(8),$(SRCDIR)/$(3)/$(8),$(SRCDIR)/solenv/bin/generate-tokens.py) \
+ $(SRCDIR)/$(3)/$(4).txt \
+ $(SRCDIR)/$(3)/$(4).hxx.head \
+ $(SRCDIR)/$(3)/$(4).hxx.tail
+ $$(call gb_Output_announce,$$(subst $(WORKDIR)/,,$$@),build,PRL,1)
+ $$(call gb_Trace_StartRange,$$(subst $(WORKDIR)/,,$$@),PRL)
+ mkdir -p $(call gb_CustomTarget_get_workdir,$(1))/misc \
+ $(call gb_CustomTarget_get_workdir,$(1)) \
+ $(call gb_CustomTarget_get_workdir,$(1))/$(2)/token
+ $(call gb_ExternalExecutable_get_command,python) $(if $(8),$(SRCDIR)/$(3)/$(8),$(SRCDIR)/solenv/bin/generate-tokens.py) \
+ $(SRCDIR)/$(3)/$(4).txt \
+ $(call gb_CustomTarget_get_workdir,$(1))/misc/$(5)ids.inc \
+ $(call gb_CustomTarget_get_workdir,$(1))/$(5)names.inc \
+ $(if $(6), $(call gb_CustomTarget_get_workdir,$(1))/misc/$(6)) \
+ $(if $(7), $(SRCDIR)/$(3)/$(7).txt \
+ $(call gb_CustomTarget_get_workdir,$(1))/$(7)names.inc) \
+ && cat $(SRCDIR)/$(3)/$(4).hxx.head \
+ $(call gb_CustomTarget_get_workdir,$(1))/misc/$(5)ids.inc \
+ $(SRCDIR)/$(3)/$(4).hxx.tail \
+ > $(call gb_CustomTarget_get_workdir,$(1))/$(2)/token/$(4).hxx \
+ && touch $$@
+ $$(call gb_Trace_EndRange,$$(subst $(WORKDIR)/,,$$@),PRL)
+
+$(call gb_CustomTarget_get_target,$(1)) : \
+ $(call gb_CustomTarget_get_workdir,$(1))/$(5)names.inc \
+ $(if $(7),$(call gb_CustomTarget_get_workdir,$(1))/$(7)names.inc) \
+ $(call gb_CustomTarget_get_workdir,$(1))/$(2)/token/$(4).hxx \
+ $(if $(6),$(call gb_CustomTarget_get_workdir,$(1))/misc/$(6)) \
+
+endef
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/Deliver.mk b/solenv/gbuild/Deliver.mk
new file mode 100644
index 000000000..a3e85f30c
--- /dev/null
+++ b/solenv/gbuild/Deliver.mk
@@ -0,0 +1,69 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+gb_Deliver_GNUCOPY := $(GNUCOPY)
+
+define gb_Deliver_init
+gb_Deliver_DELIVERABLES :=
+gb_Deliver_DELIVERABLES_INDEX :=
+
+endef
+
+define gb_Deliver_register_deliverable
+gb_Deliver_DELIVERABLES_$(notdir $(3)) += $(2):$(1)
+gb_Deliver_DELIVERABLES_INDEX := $$(sort $$(gb_Deliver_DELIVERABLES_INDEX) $(notdir $(3)))
+$(if $(gb_LOWRESTIME),.LOW_RESOLUTION_TIME : $(1),)
+
+endef
+
+define gb_Deliver_add_deliverable
+$$(if $(3),,$$(error - missing third parameter for deliverable $(1)))
+ifeq ($(MAKECMDGOALS),showdeliverables)
+$(call gb_Deliver_register_deliverable,$(1),$(2),$(3))
+endif
+
+endef
+
+define gb_Deliver__deliver
+$(if $(gb_Deliver_CLEARONDELIVER),rm -f $(2) &&) cp -P -f $(1) $(2) && $(TOUCH) -hr $(1) $(2)
+endef
+
+ifneq ($(strip $(gb_Deliver_GNUCOPY)),)
+define gb_Deliver__deliver
+$(gb_Deliver_GNUCOPY) $(if $(gb_Deliver_CLEARONDELIVER),--remove-destination) --no-dereference --force --preserve=timestamps $(1) $(2)
+endef
+endif
+
+define gb_Deliver_deliver
+$(if $(1),$(call gb_Deliver__deliver,$(1),$(2)),\
+ $(error gb_Deliver_deliver:\
+ file does not exist in instdir, and cannot be delivered: $(2)))
+endef
+
+define gb_Deliver_print_deliverable
+$(info $(1) $(2))
+endef
+
+showdeliverables :
+ $(eval MAKEFLAGS := s)
+ $(foreach deliverable,$(sort $(foreach list,$(gb_Deliver_DELIVERABLES_INDEX),$(gb_Deliver_DELIVERABLES_$(list)))),\
+ $(call gb_Deliver_print_deliverable,$(firstword $(subst :, ,$(deliverable))),$(lastword $(subst :, ,$(deliverable)))))
+ @true
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/Dictionary.mk b/solenv/gbuild/Dictionary.mk
new file mode 100644
index 000000000..b86f1b493
--- /dev/null
+++ b/solenv/gbuild/Dictionary.mk
@@ -0,0 +1,401 @@
+# -*- 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/.
+#
+
+# ThesaurusIndexTarget class
+
+gb_ThesaurusIndexTarget_CHECK_TARGET := $(SRCDIR)/dictionaries/util/th_check.pl
+gb_ThesaurusIndexTarget_CHECK_COMMAND := PERL_UNICODE=0 $(PERL) -w $(gb_ThesaurusIndexTarget_CHECK_TARGET)
+gb_ThesaurusIndexTarget_INDEX_DEPS := $(call gb_Executable_get_runtime_dependencies,idxdict)
+gb_ThesaurusIndexTarget_INDEX_COMMAND := $(call gb_Executable_get_command,idxdict)
+
+define gb_ThesaurusIndexTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ $(gb_ThesaurusIndexTarget_INDEX_COMMAND) -o $(1) < $(THESAURUS_FILE) \
+)
+endef
+ #$(gb_ThesaurusIndexTarget_CHECK_COMMAND) $(THESAURUS_FILE) && \
+
+$(dir $(call gb_ThesaurusIndexTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_ThesaurusIndexTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_ThesaurusIndexTarget_get_target,%) : $(gb_ThesaurusIndexTarget_INDEX_DEPS) | $(gb_ThesaurusIndexTarget_CHECK_TARGET)
+ $(call gb_Output_announce,$*,$(true),THI,1)
+ $(call gb_Trace_StartRange,$*,THI)
+ $(call gb_ThesaurusIndexTarget__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,THI)
+
+.PHONY : $(call gb_ThesaurusIndexTarget_get_clean_target,%)
+$(call gb_ThesaurusIndexTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),THI,1)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_ThesaurusIndexTarget_get_target,$*) \
+ )
+
+# Creates an index for a given thesaurus
+#
+# The thesaurus' file path is relative to $(SRCDIR).
+#
+# gb_ThesaurusIndexTarget_ThesaurusIndexTarget thesaurus
+define gb_ThesaurusIndexTarget_ThesaurusIndexTarget
+$(call gb_ThesaurusIndexTarget_get_target,$(1)) : THESAURUS_FILE := $(SRCDIR)/$(1)
+$(call gb_ThesaurusIndexTarget_get_target,$(1)) : $(SRCDIR)/$(1)
+$(call gb_ThesaurusIndexTarget_get_target,$(1)) :| $(dir $(call gb_ThesaurusIndexTarget_get_target,$(1))).dir
+
+endef
+
+# PropertiesTranslateTarget class
+
+# Handles translation of .properties files in dictionaries.
+
+gb_PropertiesTranslateTarget_COMMAND := $(call gb_Executable_get_command,propex)
+gb_PropertiesTranslateTarget_DEPS := $(call gb_Executable_get_runtime_dependencies,propex)
+
+define gb_PropertiesTranslateTarget__command
+$(call gb_Helper_abbreviate_dirs, \
+ $(if $(filter-out qtz,$(LANGUAGE)), \
+ MERGEINPUT=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(POFILE)) && \
+ $(gb_PropertiesTranslateTarget_COMMAND) \
+ -i $(PROPERTIES_FILE) \
+ -l $(LANGUAGE) \
+ -m $${MERGEINPUT} \
+ -o $(1) && \
+ rm -f $${MERGEINPUT} \
+ , \
+ $(gb_PropertiesTranslateTarget_COMMAND) \
+ -i $(PROPERTIES_FILE) \
+ -l $(LANGUAGE) \
+ -m \
+ -o $(1) \
+ ) \
+)
+endef
+
+$(dir $(call gb_PropertiesTranslateTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_PropertiesTranslateTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_PropertiesTranslateTarget_get_target,%) : $(gb_PropertiesTranslateTarget_DEPS)
+ $(call gb_Output_announce,$*,$(true),PRP,1)
+ $(call gb_Trace_StartRange,$*,PRP)
+ $(call gb_PropertiesTranslateTarget__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,PRP)
+
+.PHONY : $(call gb_PropertiesTranslateTarget_get_clean_target,%)
+$(call gb_PropertiesTranslateTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),PRP,1)
+ rm -f $(call gb_PropertiesTranslateTarget_get_target,$*)
+
+# gb_PropertiesTranslateTarget_PropertiesTranslateTarget target source lang
+define gb_PropertiesTranslateTarget_PropertiesTranslateTarget
+$(call gb_PropertiesTranslateTarget_get_target,$(1)) : LANGUAGE := $(3)
+$(call gb_PropertiesTranslateTarget_get_target,$(1)) : POFILE := $(gb_POLOCATION)/$(3)/$(patsubst %/,%,$(dir $(2))).po
+$(call gb_PropertiesTranslateTarget_get_target,$(1)) : PROPERTIES_FILE := $(SRCDIR)/$(2)
+
+$(call gb_PropertiesTranslateTarget_get_target,$(1)) : $(SRCDIR)/$(2)
+$(call gb_PropertiesTranslateTarget_get_target,$(1)) :| $(dir $(call gb_PropertiesTranslateTarget_get_target,$(1))).dir
+
+$(if $(filter-out qtz,$(3)),\
+ $(call gb_PropertiesTranslateTarget__PropertiesTranslateTarget_onelang,$(1),$(gb_POLOCATION)/$(3)/$(patsubst %/,%,$(dir $(2))).po) \
+)
+
+endef
+
+# gb_PropertiesTranslateTarget__PropertiesTranslateTarget_onelang target pofile
+define gb_PropertiesTranslateTarget__PropertiesTranslateTarget_onelang
+$(call gb_PropertiesTranslateTarget_get_target,$(1)) : $(2)
+$(2) :
+
+endef
+
+# DescriptionTranslateTarget class
+
+# Handles translation of description.xml files in dictionaries.
+
+gb_DescriptionTranslateTarget_COMMAND := $(call gb_Executable_get_command,xrmex)
+gb_DescriptionTranslateTarget_DEPS := $(call gb_Executable_get_runtime_dependencies,xrmex)
+
+define gb_DescriptionTranslateTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ MERGEINPUT=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(POFILES)) && \
+ $(gb_DescriptionTranslateTarget_COMMAND) \
+ -i $(DESCRIPTION_XML) \
+ -l all \
+ -m $${MERGEINPUT} \
+ -o $(1) && \
+ rm -f $${MERGEINPUT} \
+)
+endef
+
+$(dir $(call gb_DescriptionTranslateTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_DescriptionTranslateTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_DescriptionTranslateTarget_get_target,%) : $(gb_DescriptionTranslateTarget_DEPS)
+ $(call gb_Output_announce,$*,$(true),XRM,1)
+ $(call gb_Trace_StartRange,$*,XRM)
+ $(call gb_DescriptionTranslateTarget__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,XRM)
+
+.PHONY : $(call gb_DescriptionTranslateTarget_get_clean_target,%)
+$(call gb_DescriptionTranslateTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),XRM,1)
+ rm -f $(call gb_DescriptionTranslateTarget_get_target,$*)
+
+# gb_DescriptionTranslateTarget_DescriptionTranslateTarget target source langs
+define gb_DescriptionTranslateTarget_DescriptionTranslateTarget
+$(call gb_DescriptionTranslateTarget_get_target,$(1)) : DESCRIPTION_XML := $(SRCDIR)/$(2)
+$(call gb_DescriptionTranslateTarget_get_target,$(1)) : POFILES :=
+
+$(call gb_DescriptionTranslateTarget_get_target,$(1)) : $(SRCDIR)/$(2)
+$(call gb_DescriptionTranslateTarget_get_target,$(1)) :| $(dir $(call gb_DescriptionTranslateTarget_get_target,$(1))).dir
+
+$(foreach lang,$(3),\
+ $(call gb_DescriptionTranslateTarget__DescriptionTranslateTarget_onelang,$(1),$(patsubst %/,%,$(dir $(2))),$(lang)) \
+)
+
+endef
+
+# gb_DescriptionTranslateTarget__DescriptionTranslateTarget_onelang target pobase lang
+define gb_DescriptionTranslateTarget__DescriptionTranslateTarget_onelang
+$(call gb_DescriptionTranslateTarget_get_target,$(1)) : POFILES += $(if $(filter-out qtz,$(3)),$(gb_POLOCATION)/$(3)/$(2).po)
+$(if $(filter-out qtz,$(3)),\
+ $(call gb_DescriptionTranslateTarget__DescriptionTranslateTarget_onelang_podeps,$(1),$(gb_POLOCATION)/$(3)/$(2).po))
+
+endef
+
+# gb_DescriptionTranslateTarget__DescriptionTranslateTarget_onelang_podeps target pofile
+define gb_DescriptionTranslateTarget__DescriptionTranslateTarget_onelang_podeps
+$(call gb_DescriptionTranslateTarget_get_target,$(1)) : $(2)
+$(2) :
+
+endef
+
+# Dictionary class
+
+# Handles creation and delivery of dictionary extensions.
+#
+# This class provides a filelist called Dictionary/<name> that contains
+# all installed files of the dictionary.
+
+gb_Dictionary_ALL_LANGS := $(filter-out en-US,$(gb_WITH_LANG))
+gb_Dictionary_INSTDIR := $(LIBO_SHARE_FOLDER)/extensions
+
+$(dir $(call gb_Dictionary_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_Dictionary_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_Dictionary_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),DIC,3)
+ $(call gb_Trace_MakeMark,$*,DIC)
+ touch $@
+
+.PHONY : $(call gb_Dictionary_get_clean_target,%)
+$(call gb_Dictionary_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),DIC,3)
+ rm -f $(call gb_Dictionary_get_target,$*)
+
+gb_Dictionary_get_packagename = Dictionary/$(1)
+gb_Dictionary_get_packagesetname = Dictionary/$(1)
+
+# Creates a dictionary extension
+#
+# gb_Dictionary_Dictionary dictionary srcdir
+define gb_Dictionary_Dictionary
+$(call gb_Package_Package_internal,$(call gb_Dictionary_get_packagename,$(1)),$(SRCDIR))
+$(call gb_Package_Package_internal,$(call gb_Dictionary_get_packagename,$(1)_generated),$(WORKDIR))
+$(call gb_PackageSet_PackageSet_internal,$(call gb_Dictionary_get_packagesetname,$(1)))
+
+$(call gb_PackageSet_add_package,$(call gb_Dictionary_get_packagesetname,$(1)),$(call gb_Dictionary_get_packagename,$(1)))
+
+ifeq (,$(gb_Dictionary_ALL_LANGS))
+$(call gb_Dictionary_add_root_file,$(1),$(2)/description.xml)
+else
+$(call gb_Dictionary__add_description_translations,$(1),$(2)/description.xml)
+endif
+$(call gb_Dictionary_add_root_file,$(1),$(2)/dictionaries.xcu)
+$(call gb_Dictionary_add_file,$(1),META-INF/manifest.xml,$(2)/META-INF/manifest.xml)
+
+$(call gb_Dictionary_get_target,$(1)) : $(call gb_PackageSet_get_target,$(call gb_Dictionary_get_packagesetname,$(1)))
+$(call gb_Dictionary_get_target,$(1)) :| $(dir $(call gb_Dictionary_get_target,$(1))).dir
+$(call gb_Dictionary_get_clean_target,$(1)) : $(call gb_PackageSet_get_clean_target,$(call gb_Dictionary_get_packagesetname,$(1)))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_Dictionary_get_target,$(1)),$(call gb_Dictionary_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),Dictionary)
+
+endef
+
+# gb_Dictionary__add_description_translation_impl dictionary desctarget descxml
+define gb_Dictionary__add_description_translation_impl
+$(call gb_DescriptionTranslateTarget_DescriptionTranslateTarget,$(2),$(3),$(gb_Dictionary_ALL_LANGS))
+$(call gb_Dictionary_add_generated_file,$(1),description.xml,$(call gb_DescriptionTranslateTarget_get_target,$(2)))
+
+$(call gb_Dictionary_get_target,$(1)) : $(call gb_DescriptionTranslateTarget_get_target,$(2))
+$(call gb_Dictionary_get_clean_target,$(1)) : $(call gb_DescriptionTranslateTarget_get_clean_target,$(2))
+
+endef
+
+# gb_Dictionary__add_description_translations dictionary descxml
+define gb_Dictionary__add_description_translations
+$(call gb_Dictionary__add_description_translation_impl,$(1),$(basename $(2)),$(2))
+
+endef
+
+# gb_Dictionary__add_file dictionary package-base destfile sourcefile
+define gb_Dictionary__add_file
+$(call gb_Package_add_file,$(call gb_Dictionary_get_packagename,$(2)),$(gb_Dictionary_INSTDIR)/$(1)/$(3),$(4))
+
+endef
+
+# Adds a file from $(SRCDIR) to the dictionary under chosen name
+#
+# gb_Dictionary_add_file dictionary destfile sourcefile
+define gb_Dictionary_add_file
+$(call gb_Dictionary__add_file,$(1),$(1),$(2),$(3))
+
+endef
+
+# Adds several files from $(SRCDIR) to the dictionary at once
+#
+# The files are put into the chosen directory.
+#
+# gb_Dictionary_add_files dictionary destdir file(s)
+define gb_Dictionary_add_files
+$(foreach file,$(3),$(call gb_Dictionary_add_file,$(1),$(2)/$(notdir $(file)),$(file)))
+
+endef
+
+# Adds an arbitrary file to the dictionary under chosen name
+#
+# gb_Dictionary_add_file dictionary destfile sourcefile
+define gb_Dictionary_add_generated_file
+$(call gb_Dictionary__add_file,$(1),$(1)_generated,$(2),$(subst $(WORKDIR)/,,$(3)))
+$(call gb_PackageSet_add_package,$(call gb_Dictionary_get_packagesetname,$(1)),$(call gb_Dictionary_get_packagename,$(1)_generated))
+
+endef
+
+# Adds several arbitrary files to the dictionary at once
+#
+# The files are put into the chosen directory.
+#
+# gb_Dictionary_add_files dictionary destdir file(s)
+define gb_Dictionary_add_generated_files
+$(foreach file,$(3),$(call gb_Dictionary_add_generated_file,$(1),$(2)/$(notdir $(file)),$(file)))
+
+endef
+
+# Adds a localized xcu file, which needs special handling because it may be
+# in $(WORKDIR) or $(SRCDIR) depending on whether translations are built.
+#
+# gb_Dictionary_add_localized_xcu_file dictionary destdir file
+define gb_Dictionary_add_localized_xcu_file
+ifeq ($(gb_WITH_LANG),)
+$(call gb_Dictionary__add_file,$(1),$(1),$(2)/$(notdir $(3)),$(strip $(3)))
+else
+$(call gb_Dictionary__add_file,$(1),$(1)_generated,$(2)/$(notdir $(3)),$(subst $(WORKDIR)/,,$(call gb_XcuFile_for_extension,$(strip $(3)))))
+$(call gb_PackageSet_add_package,$(call gb_Dictionary_get_packagesetname,$(1)),$(call gb_Dictionary_get_packagename,$(1)_generated))
+endif
+
+endef
+
+# Adds a file to the root dir of the dictionary
+#
+# gb_Dictionary_add_root_file dictionary file
+define gb_Dictionary_add_root_file
+$(call gb_Dictionary_add_file,$(1),$(notdir $(2)),$(2))
+
+endef
+
+# Adds several files to the root dir of the dictionary
+#
+# gb_Dictionary_add_root_files dictionary file(s)
+define gb_Dictionary_add_root_files
+$(foreach file,$(2),$(call gb_Dictionary_add_root_file,$(1),$(file)))
+
+endef
+
+define gb_Dictionary__add_thesaurus
+$(call gb_Dictionary__add_file,$(1),$(1)_generated,$(notdir $(3)),$(subst $(WORKDIR)/,,$(3)))
+$(call gb_PackageSet_add_package,$(call gb_Dictionary_get_packagesetname,$(1)),$(call gb_Dictionary_get_packagename,$(1)_generated))
+
+endef
+
+# Adds a thesaurus to the dictionary
+#
+# An index for the thesaurus is generated and added to the dictionary as
+# well.
+#
+# gb_Dictionary_add_thesaurus dictionary thesaurus
+define gb_Dictionary_add_thesaurus
+$(call gb_ThesaurusIndexTarget_ThesaurusIndexTarget,$(2))
+$(call gb_Dictionary_add_root_file,$(1),$(2))
+$(call gb_Dictionary__add_thesaurus,$(1),$(2),$(call gb_ThesaurusIndexTarget_get_target,$(2)))
+
+endef
+
+# Adds several thesauri to the dictionary at once
+#
+# Indexes for the thesauri are generated and added to the dictionary as
+# well.
+#
+# gb_Dictionary_add_thesauri dictionary thesauri
+define gb_Dictionary_add_thesauri
+$(foreach thesaurus,$(2),$(call gb_Dictionary_add_thesaurus,$(1),$(thesaurus)))
+
+endef
+
+# gb_Dictionary__translate_propertyfile_impl dictionary destfile propertyfile propertyname lang
+define gb_Dictionary__translate_propertyfile_impl
+$(call gb_PropertiesTranslateTarget_PropertiesTranslateTarget,$(4),$(3),$(5))
+$(call gb_Dictionary_add_generated_file,$(1),$(2),$(call gb_PropertiesTranslateTarget_get_target,$(4)))
+
+endef
+
+# gb_Dictionary__translate_propertyfile dictionary destdir propertyfile propertyname lang
+define gb_Dictionary__translate_propertyfile
+$(call gb_Dictionary__translate_propertyfile_impl,$(1),$(2)$(notdir $(4)).properties,$(3),$(4),$(5))
+
+endef
+
+# gb_Dictionary__add_propertyfile_translations dictionary destfile propertyfile
+define gb_Dictionary__add_propertyfile_translations
+$(foreach lang,$(gb_Dictionary_ALL_LANGS),$(call gb_Dictionary__translate_propertyfile,$(1),$(dir $(2)),$(3),$(subst en_US,$(subst -,_,$(lang)),$(basename $(3))),$(lang)))
+
+endef
+
+# Adds a .property file to the dictionary under chosen name
+#
+# The file is localized automatically.
+#
+# gb_Dictionary_add_propertyfile dictionary destfile propertyfile
+define gb_Dictionary_add_propertyfile
+$(call gb_Dictionary__add_file,$(1),$(1),$(2),$(3))
+$(call gb_Dictionary__add_propertyfile_translations,$(1),$(2),$(3))
+
+endef
+
+# Adds several .property files to the dictionary at once
+#
+# The files are put into chosen directory. They are localized automatically.
+#
+# gb_Dictionary_add_propertyfiles dictionary destdir propertyfile(s)
+define gb_Dictionary_add_propertyfiles
+$(foreach propertyfile,$(3),$(call gb_Dictionary_add_propertyfile,$(1),$(2)/$(notdir $(propertyfile)),$(propertyfile)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/Executable.mk b/solenv/gbuild/Executable.mk
new file mode 100644
index 000000000..7c8cf1994
--- /dev/null
+++ b/solenv/gbuild/Executable.mk
@@ -0,0 +1,173 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# Executable class
+
+# defined by platform
+# gb_Executable_Executable_platform
+
+gb_Executable_LAYER_DIRS := \
+ UREBIN:$(INSTROOT)/$(LIBO_URE_BIN_FOLDER) \
+ OOO:$(INSTROOT)/$(LIBO_BIN_FOLDER) \
+ SDKBIN:$(INSTDIR)/$(SDKDIRNAME)/bin \
+ NONE:$(gb_Executable_BINDIR) \
+
+gb_Executable_LAYER_DIRS_FOR_BUILD := \
+ UREBIN:$(INSTROOT_FOR_BUILD)/$(LIBO_URE_BIN_FOLDER_FOR_BUILD) \
+ OOO:$(INSTROOT_FOR_BUILD)/$(LIBO_BIN_FOLDER_FOR_BUILD) \
+ SDKBIN:$(INSTDIR_FOR_BUILD)/$(SDKDIRNAME_FOR_BUILD)/bin \
+ NONE:$(gb_Executable_BINDIR_FOR_BUILD) \
+
+$(dir $(call gb_Executable_get_runtime_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_Executable_get_runtime_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_Executable_get_runtime_target,%) :
+ touch $@
+
+.PHONY : $(call gb_Executable_get_clean_target,%)
+$(call gb_Executable_get_clean_target,%) :
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_Executable_get_target,$*) \
+ $(call gb_Executable_get_runtime_target,$*) \
+ $(AUXTARGETS))
+
+gb_Executable__get_dir_for_layer = $(patsubst $(1):%,%,$(filter $(1):%,$(call gb_Executable_LAYER_DIRS)))
+gb_Executable__get_dir_for_layer_for_build = $(patsubst $(1):%,%,$(filter $(1):%,$(call gb_Executable_LAYER_DIRS_FOR_BUILD)))
+gb_Executable__get_dir_for_exe = $(call gb_Executable__get_dir_for_layer,$(call gb_Executable_get_layer,$(1)))
+gb_Executable__get_dir_for_exe_for_build = $(call gb_Executable__get_dir_for_layer_for_build,$(call gb_Executable_get_layer,$(1)))
+
+define gb_Executable_Executable
+$(call gb_Postprocess_register_target,AllExecutables,Executable,$(1))
+ifeq (,$$(findstring $(1),$$(gb_Executable_KNOWN)))
+$$(eval $$(call gb_Output_info,Currently known executables: $(sort $(gb_Executable_KNOWN)),ALL))
+$$(eval $$(call gb_Output_error,Executable $(1) must be registered in Repository.mk or RepositoryExternal.mk))
+endif
+$(call gb_Executable__Executable_impl,$(1),$(call gb_Executable_get_linktarget,$(1)))
+
+endef
+
+# call gb_Executable__Executable_impl,exe,linktarget
+define gb_Executable__Executable_impl
+$(call gb_LinkTarget_LinkTarget,$(2),Executable_$(1),$(call gb_Executable_get_layer,$(1)))
+$(call gb_LinkTarget_set_targettype,$(2),Executable)
+$(call gb_LinkTarget_add_libs,$(2),$(gb_STDLIBS))
+$(call gb_Executable_get_runtime_target,$(1)) :| $(dir $(call gb_Executable_get_runtime_target,$(1))).dir
+$(call gb_Executable_get_runtime_target,$(1)) : $(call gb_Executable_get_target_for_build,$(1))
+$(call gb_Executable_get_clean_target,$(1)) : $(call gb_LinkTarget_get_clean_target,$(2))
+$(call gb_Executable_get_clean_target,$(1)) : AUXTARGETS :=
+$(call gb_Executable_Executable_platform,$(1),$(2),$(gb_Executable_BINDIR)/$(1).lib)
+ifeq ($(OS),EMSCRIPTEN)
+$(call gb_LinkTarget_get_target,$(call gb_Executable_get_linktarget,$(1))) : $(call gb_CustomTarget_get_workdir,static/emscripten_fs_image)/soffice.data.js.link
+endif
+
+$$(eval $$(call gb_Module_register_target,$(call gb_Executable_get_target,$(1)),$(call gb_Executable_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),Executable)
+
+endef
+
+define gb_Executable_set_targettype_gui
+$(call gb_Executable_get_linktarget_target,$(1)) : TARGETGUI := $(2)
+endef
+
+# forward the call to the gb_LinkTarget implementation
+# (note: because the function name is in $(1), the other args are shifted by 1)
+define gb_Executable__forward_to_Linktarget
+$(call gb_LinkTarget_$(subst gb_Executable_,,$(1)),$(call gb_Executable_get_linktarget,$(2)),$(3),$(4),Executable_$(2))
+
+endef
+
+# copy pasta for forwarding: this could be (and was) done more elegantly, but
+# these here can be found by both git grep and ctags
+gb_Executable_add_cobject = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_cobjects = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_cxxobject = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_cxxobjects = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_objcobject = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_objcobjects = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_objcxxobject = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_objcxxobjects = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_cxxclrobject = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_cxxclrobjects = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_grammar = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_grammars = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_scanner = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_scanners = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_exception_objects = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_generated_cobjects = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_generated_exception_objects = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_generated_objcobjects = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_generated_objcxxobjects = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_cflags = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_cxxflags = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_objcflags = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_objcxxflags = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_cxxclrflags = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_defs = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_set_include = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_ldflags = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_set_ldflags = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_set_x86 = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_libs = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_disable_standard_system_libs = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_system_darwin_frameworks = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_system_win32_libs = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_set_library_path_flags = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_api = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_sdk_api = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_udk_api = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_internal_api = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_internal_bootstrap_api = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_internal_comprehensive_api = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_library_objects = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_libraries = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_static_libraries = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_external = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_externals = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_custom_headers = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_package = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_packages = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_unpacked = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_sdi_headers = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_set_precompiled_header = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_reuse_precompiled_header = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_common_precompiled_header = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_nativeres = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_set_warnings_not_errors = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_set_warnings_disabled = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_set_external_code = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_set_generated_cxx_suffix = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_clang = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_set_clang_precompiled_header = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_use_vclmain = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Executable_add_prejs = $(call gb_Executable__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+
+# Run-time use
+
+# Add dependencies needed for running the executable
+#
+# gb_Executable_add_runtime_dependencies executable dependencies
+define gb_Executable_add_runtime_dependencies
+$(call gb_Executable_get_runtime_target,$(1)) : $(2)
+
+endef
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/Extension.mk b/solenv/gbuild/Extension.mk
new file mode 100644
index 000000000..0dce9757b
--- /dev/null
+++ b/solenv/gbuild/Extension.mk
@@ -0,0 +1,494 @@
+# -*- 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/.
+#
+
+# Extension class
+
+# platform
+# gb_Extension_LICENSEFILE_DEFAULT
+
+gb_Extension__get_preparation_target = $(WORKDIR)/Extension/$(1).prepare
+
+gb_Extension_ZIPCOMMAND := zip $(if $(findstring s,$(MAKEFLAGS)),-q)
+gb_Extension_XRMEXDEPS := $(call gb_Executable_get_runtime_dependencies,xrmex)
+gb_Extension_XRMEXCOMMAND := $(call gb_Executable_get_command,xrmex)
+
+gb_Extension_PROPMERGEDEPS := $(call gb_Executable_get_runtime_dependencies,propex)
+gb_Extension_PROPMERGECOMMAND := $(call gb_Executable_get_command,propex)
+
+gb_Extension_TREEXDEPS := $(call gb_Executable_get_runtime_dependencies,treex)
+gb_Extension_TREEXCOMMAND := $(call gb_Executable_get_command,treex)
+
+gb_Extension_HELPEXDEPS := $(call gb_Executable_get_runtime_dependencies,helpex)
+gb_Extension_HELPEXCOMMAND := $(call gb_Executable_get_command,helpex)
+gb_Extension_HELPINDEXERDEPS := $(call gb_Executable_get_runtime_dependencies,HelpIndexer)
+gb_Extension_HELPINDEXERCOMMAND := $(call gb_Executable_get_command,HelpIndexer)
+gb_Extension_HELPLINKERDEPS := $(call gb_Executable_get_runtime_dependencies,HelpLinker)
+gb_Extension_HELPLINKERCOMMAND := $(call gb_Executable_get_command,HelpLinker)
+# does not contain en-US because it is special cased in gb_Extension_Extension
+gb_Extension_TRANS_LANGS := $(filter-out en-US,$(gb_WITH_LANG))
+gb_Extension_ALL_LANGS := en-US $(gb_Extension_TRANS_LANGS)
+
+# target ensuring delivery of the extension to instdir
+gb_Extension__get_final_target = $(WORKDIR)/Extension/$(1).final
+
+# Substitute platform or copy if no platform has been set
+define gb_Extension__subst_platform
+$(if $(PLATFORM),\
+ sed \
+ -e 's/@PLATFORM@/$(PLATFORM)/' \
+ -e 's/@EXEC_EXTENSION@/$(gb_Executable_EXT)/' \
+ -e 's/@SHARED_EXTENSION@/$(gb_Library_DLLEXT)/' \
+ $(1) > $(2),\
+ cp -f $(1) $(2))
+endef
+
+$(call gb_Extension_get_workdir,%)/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+# remove extension directory in workdir and oxt file in workdir
+$(call gb_Extension_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),OXT,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f -r $(call gb_Extension_get_workdir,$*) && \
+ rm -f $(call gb_Extension__get_preparation_target,$*) \
+ $(call gb_Extension_get_target,$*) \
+ )
+
+$(call gb_Extension__get_final_target,%) :
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && touch $@)
+
+# preparation target to delay adding files produced by e.g. UnpackedTarball
+$(call gb_Extension__get_preparation_target,%) :
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && touch $@)
+
+ifeq ($(strip $(gb_WITH_LANG)),)
+$(call gb_Extension_get_workdir,%)/description.xml : $(gb_Helper_LANGSTARGET)
+ $(call gb_Output_announce,$*/description.xml,$(true),CPY,3)
+ $(call gb_Trace_StartRange,$*/description.xml,CPY)
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(call gb_Extension_get_workdir,$*) && \
+ cp -f $(LOCATION)/description.xml $@)
+ $(call gb_Trace_EndRange,$*/description.xml,CPY)
+else
+$(call gb_Extension_get_workdir,%)/description.xml : $(gb_Extension_XRMEXDEPS) $(gb_Helper_LANGSTARGET)
+ $(call gb_Output_announce,$*/description.xml,$(true),XRM,3)
+ $(call gb_Trace_StartRange,$*/description.xml,XRM)
+ MERGEINPUT=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(POFILES)) && \
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(call gb_Extension_get_workdir,$*) && \
+ $(gb_Extension_XRMEXCOMMAND) \
+ -i $(filter %.xml,$^) \
+ -o $@ \
+ -m $${MERGEINPUT} \
+ -l all) && \
+ rm -rf $${MERGEINPUT}
+ $(call gb_Trace_EndRange,$*/description.xml,XRM)
+
+endif
+
+# rule to create oxt package in workdir
+# --filesync makes sure that all files in the oxt package will be removed that no longer are in $(FILES)
+$(call gb_Extension_get_target,%) : \
+ $(call gb_Extension_get_workdir,%)/description.xml
+ $(call gb_Output_announce,$*,$(true),OXT,3)
+ $(call gb_Trace_StartRange,$*,OXT)
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(call gb_Extension_get_rootdir,$*)/META-INF \
+ $(if $(LICENSE),$(call gb_Extension_get_rootdir,$*)/registration) && \
+ $(call gb_Extension__subst_platform,$(call gb_Extension_get_workdir,$*)/description.xml,$(call gb_Extension_get_rootdir,$*)/description.xml) && \
+ $(call gb_Extension__subst_platform,$(LOCATION)/META-INF/manifest.xml,$(call gb_Extension_get_rootdir,$*)/META-INF/manifest.xml) && \
+ $(if $(LICENSE),cp -f $(LICENSE) $(call gb_Extension_get_rootdir,$*)/registration &&) \
+ $(if $(and $(gb_Extension_TRANS_LANGS),$(DESCRIPTION)),cp $(foreach lang,$(gb_Extension_TRANS_LANGS),$(call gb_Extension_get_workdir,$*)/description-$(lang).txt) $(call gb_Extension_get_rootdir,$*) &&) \
+ cd $(call gb_Extension_get_rootdir,$*) && \
+ ZIPFILES=$(call gb_var2file,$(shell $(gb_MKTEMP)),500,$(sort $(FILES))) && \
+ $(gb_Extension_ZIPCOMMAND) -rX --filesync --must-match \
+ $(call gb_Extension_get_target,$*) \
+ `cat $${ZIPFILES} | tr -d '\r'` && rm $${ZIPFILES})
+ $(call gb_Trace_EndRange,$*,OXT)
+
+# set file list and location of manifest and description files
+# register target and clean target
+# add deliverable
+# add dependency for outdir target to workdir target (pattern rule for delivery is in Package.mk)
+#
+# gb_Extension_Extension extension srcdir nodeliver
+define gb_Extension_Extension
+$(call gb_Extension_get_target,$(1)) : DESCRIPTION :=
+$(call gb_Extension_get_target,$(1)) : FILES := META-INF description.xml
+$(call gb_Extension_get_target,$(1)) : LICENSE :=
+$(call gb_Extension_get_target,$(1)) : LOCATION := $(SRCDIR)/$(2)
+$(call gb_Extension_get_target,$(1)) : PLATFORM := $(PLATFORMID)
+$(call gb_Extension_get_target,$(1)) : $(SRCDIR)/$(2)/META-INF/manifest.xml
+$(call gb_Extension_get_workdir,$(1))/description.xml : \
+ $(SRCDIR)/$(2)/description.xml
+$(call gb_Extension_get_workdir,$(1))/description.xml :| \
+ $(call gb_Extension__get_preparation_target,$(1))
+$(call gb_Extension__get_final_target,$(1)) : $(call gb_Extension_get_target,$(1))
+
+$(if $(filter nodeliver,$(3)),,$(call gb_Extension__Extension_deliver,$(1),Extension/$(1)))
+
+ifneq ($(strip $(gb_WITH_LANG)),)
+$(call gb_Extension_get_target,$(1)) : \
+ POFILES := $(wildcard $(foreach lang,$(gb_TRANS_LANGS),$(gb_POLOCATION)/$(lang)/$(2).po))
+$(call gb_Extension_get_workdir,$(1))/description.xml : \
+ $(wildcard $(foreach lang,$(gb_TRANS_LANGS),$(gb_POLOCATION)/$(lang)/$(2).po))
+$(foreach lang,$(gb_TRANS_LANGS),$(gb_POLOCATION)/$(lang)/$(2).po) :
+endif
+
+$(foreach lang,$(gb_Extension_ALL_LANGS), \
+ $(call gb_Extension__compile_help_onelang,$(1),$(lang)))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_Extension__get_final_target,$(1)),$(call gb_Extension_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),Extension,$(call gb_Extension__get_final_target,$(1)))
+
+endef
+
+# Ensure delivery of the extension to instdir.
+#
+# gb_Extension__Extension_deliver extension package-name
+define gb_Extension__Extension_deliver
+$(call gb_GeneratedPackage_GeneratedPackage,$(2),$(dir $(call gb_Extension_get_rootdir,$(1))))
+$(call gb_GeneratedPackage_add_dir,$(2),$(INSTROOT)/$(LIBO_SHARE_FOLDER)/extensions/$(1),$(notdir $(call gb_Extension_get_rootdir,$(1))))
+
+$(call gb_GeneratedPackage_get_target,$(2)) : $(call gb_Extension_get_target,$(1))
+$(call gb_Extension__get_final_target,$(1)) : $(call gb_GeneratedPackage_get_target,$(2))
+
+endef
+
+# adding a file creates a dependency to it
+# file is copied to $(WORKDIR)
+define gb_Extension_add_file
+$(call gb_Extension_get_target,$(1)) : FILES += $(2)
+$(call gb_Extension_get_target,$(1)) : $(call gb_Extension_get_rootdir,$(1))/$(2)
+$(3) :| $(call gb_Extension__get_preparation_target,$(1))
+$(call gb_Extension_get_rootdir,$(1))/$(2) : $(3)
+ mkdir -p $$(dir $$@) && \
+ cp -f $(3) $$@
+
+endef
+
+# Add several files at once
+#
+# This function avoids the need to specify each file's name twice. The
+# files are added directly under specified path in the extension,
+# without any subpath. If no path is specified, they are added directly
+# to the root dir of the extension.
+define gb_Extension_add_files
+$(foreach file,$(3),$(call gb_Extension_add_file,$(1),$(if $(strip $(2)),$(strip $(2))/)$(notdir $(file)),$(file)))
+
+endef
+
+# add a library from workdir; DO NOT use gb_Library_get_target
+define gb_Extension_add_library
+$(call gb_Extension_add_file,$(1),$(call gb_Library_get_runtime_filename,$(2)),\
+ $(call gb_Library_get_linktarget_target,$(2)))
+
+endef
+
+define gb_Extension_add_libraries
+$(foreach lib,$(2),$(call gb_Extension_add_library,$(1),$(lib)))
+
+endef
+
+# add an executable
+define gb_Extension_add_executable
+$(call gb_Extension_add_file,$(1),$(notdir $(call gb_Executable_get_target,$(2))),\
+ $(call gb_Executable_get_target,$(2)))
+
+endef
+
+define gb_Extension_add_executables
+$(foreach exe,$(2),$(call gb_Extension_add_executable,$(1),$(exe)))
+
+endef
+
+# localize .properties file
+# source file is copied to $(WORKDIR)
+define gb_Extension_localize_properties
+$(foreach lang,$(gb_Extension_ALL_LANGS),\
+ $(call gb_Extension__localize_properties_onelang,$(1),$(subst en_US,$(subst -,_,$(lang)),$(2)),$(3),$(lang)))
+
+endef
+
+
+# add an .xhp help file, to be localized and compiled
+# $(1): extension identifier
+# $(2): absolute path prefix of en-US source file without $(3) (resp. $(4))
+# suffix
+# $(3): relative path of (target) .xhp file (e.g.,
+# com.sun.wiki-publisher/wiki.xhp)
+# $(4): optional relative path of source .xhp file, when it differs from $(3)
+# (i.e., if $(4) is empty the en-US source file is $(2)/$(3), otherwise it
+# is $(2)/$(4))
+define gb_Extension_add_helpfile
+$(foreach lang,$(gb_Extension_ALL_LANGS), \
+ $(call gb_Extension__localize_helpfile_onelang,$(1),$(2),$(3),$(4),$(lang)) \
+ $(call gb_Extension__add_compiled_help_dependency_onelang,$(1),$(lang)))
+
+endef
+
+# add a list of .xhp help files, to be localized and compiled
+# $(1): extension identifier
+# $(2): absolute path prefix of en-US source files without $(3) suffixes
+# $(3): list of relative paths of .xhp files (see gb_Extension_add_helpfile)
+define gb_Extension_add_helpfiles
+$(foreach helpfile,$(3), \
+ $(call gb_Extension_add_helpfile,$(1),$(2),$(helpfile),))
+
+endef
+
+# add a help.tree file, to be localized and compiled
+# $(1): extension identifier
+# $(2): absolute path prefix of en-US source file without $(3) (resp. $(4))
+# suffix
+# $(3): relative path of (target) help.tree file (e.g.,
+# com.sun.wiki-publisher/help.tree)
+# $(4): relative path of source help.tree file
+# $(5): relative path of localized xhp files (PlatformID included)
+define gb_Extension_add_helptreefile
+$(foreach lang,$(gb_Extension_ALL_LANGS), \
+ $(call gb_Extension__localize_helptreefile_onelang,$(1),$(2),$(3),$(4),$(lang),$(5)) \
+ $(call gb_Extension__add_compiled_help_dependency_onelang,$(1),$(lang)))
+
+endef
+
+# Use the given file as description-en-US.txt
+define gb_Extension_use_default_description
+$(call gb_Extension_add_file,$(1),description-en-US.txt,$(SRCDIR)/$(2))
+$(call gb_Extension_get_target,$(1)) : DESCRIPTION := $(true)
+ifneq ($(strip $(gb_WITH_LANG)),)
+$(call gb_Extension_get_target,$(1)) : FILES += $(foreach lang,$(gb_Extension_TRANS_LANGS),description-$(lang).txt)
+endif
+
+endef
+
+# Use the default license file
+define gb_Extension_use_default_license
+$(call gb_Extension_get_target,$(1)) : FILES += registration
+$(call gb_Extension_get_target,$(1)) : LICENSE := $(gb_Extension_LICENSEFILE_DEFAULT)
+$(call gb_Extension_get_target,$(1)) : $(gb_Extension_LICENSEFILE_DEFAULT)
+
+endef
+
+define gb_Extension_use_unpacked
+$(call gb_Extension__get_preparation_target,$(1)) \
+ :| $(call gb_UnpackedTarball_get_final_target,$(2))
+
+endef
+
+# Add a dependency on an ExternalProject.
+#
+# call gb_Extension_use_external_project,extension,externalproject
+define gb_Extension_use_external_project
+$(call gb_Extension__get_preparation_target,$(1)) \
+ :| $(call gb_ExternalProject_get_target,$(2))
+
+endef
+
+define gb_Extension__localize_properties_onelang
+$(call gb_Extension_get_target,$(1)) : FILES += $(2)
+ifneq ($(filter-out en-US,$(4)),)
+ifneq ($(filter-out qtz,$(4)),)
+$(call gb_Extension_get_rootdir,$(1))/$(2) : \
+ POFILE := $(gb_POLOCATION)/$(or $(5),$(4))/$(patsubst /%/,%,$(subst $(SRCDIR),,$(dir $(3)))).po
+$(call gb_Extension_get_rootdir,$(1))/$(2) : \
+ $(gb_POLOCATION)/$(or $(5),$(4))/$(patsubst /%/,%,$(subst $(SRCDIR),,$(dir $(3)))).po
+$(gb_POLOCATION)/$(or $(5),$(4))/$(patsubst /%/,%,$(subst $(SRCDIR),,$(dir $(3)))).po :
+endif
+endif
+$(call gb_Extension_get_target,$(1)) : $(call gb_Extension_get_rootdir,$(1))/$(2)
+$(call gb_Extension_get_rootdir,$(1))/$(2) \
+ :| $(call gb_Extension__get_preparation_target,$(1))
+$(call gb_Extension_get_rootdir,$(1))/$(2) : $(3) \
+ $(gb_Extension_PROPMERGEDEPS)
+ $$(call gb_Output_announce,$(2),$(true),PRP,3)
+ $$(call gb_Trace_StartRange,$(2),PRP)
+ $$(call gb_Helper_abbreviate_dirs, \
+ mkdir -p $$(dir $$@) && \
+ $(if $(filter qtz,$(4)), \
+ $(subst $$,$$$$,$(gb_Extension_PROPMERGECOMMAND)) -i $$< -o $$@ -m -l $(4) \
+ , \
+ $(if $(filter-out en-US,$(4)), \
+ MERGEINPUT=`$(gb_MKTEMP)` && \
+ echo $$(POFILE) > $$$${MERGEINPUT} && \
+ $(subst $$,$$$$,$(gb_Extension_PROPMERGECOMMAND)) -i $$< -o $$@ -m $$$${MERGEINPUT} -l $(4) && \
+ rm -rf $$$${MERGEINPUT} \
+ , \
+ cp -f $$< $$@ \
+ ) \
+ ) \
+ )
+ $$(call gb_Trace_EndRange,$(2),PRP)
+
+endef
+
+# localize one .xhp help file for one language; the result is stored as
+# help/$(4)/$(3) in the extension's workdir; as a special case, if $(4) is
+# "en-US", the source file is just copied, not passed through helpex
+# $(1): extension identifier
+# $(2): absolute path prefix of en-US source file without $(3) (resp. $(4))
+# suffix
+# $(3): relative path of (target) .xhp file (see
+# gb_Extension_add_helpfile)
+# $(4): optional relative path of source .xhp file (see
+# gb_Extension_add_helpfile)
+# $(5): language
+define gb_Extension__localize_helpfile_onelang
+$(call gb_Extension_get_rootdir,$(1))/help/$(5).done : HELPFILES += $(3)
+$(call gb_Extension_get_rootdir,$(1))/help/$(5).done : \
+ $(call gb_Extension_get_workdir,$(1))/help/$(5)/$(3)
+$(call gb_Extension_get_rootdir,$(1))/help/$(5)-xhp.done : \
+ $(call gb_Extension_get_workdir,$(1))/help/$(5)/$(3)
+ifneq ($(filter-out en-US,$(5)),)
+ifneq ($(filter-out qtz,$(5)),)
+$(call gb_Extension_get_workdir,$(1))/help/$(5)/$(3) : \
+ POFILE := $(gb_POLOCATION)/$(5)$(subst $(SRCDIR),,$(2))$(patsubst %/,/%.po,$(patsubst ./,.po,$(dir $(or $(4),$(3)))))
+$(call gb_Extension_get_workdir,$(1))/help/$(5)/$(3) : \
+ $(gb_POLOCATION)/$(5)$(subst $(SRCDIR),,$(2))$(patsubst %/,/%.po,$(patsubst ./,.po,$(dir $(or $(4),$(3)))))
+$(gb_POLOCATION)/$(5)$(subst $(SRCDIR),,$(2))$(patsubst %/,/%.po,$(patsubst ./,.po,$(dir $(or $(4),$(3))))) :
+endif
+endif
+$(call gb_Extension_get_workdir,$(1))/help/$(5)/$(3) : \
+ $(if $(filter-out en-US,$(5)),$(gb_Extension_HELPEXDEPS)) | \
+ $(call gb_Extension_get_workdir,$(1))/help/.dir
+$(call gb_Extension_get_workdir,$(1))/help/$(5)/$(3) : \
+ $(2)/$(or $(4),$(3))
+ $$(call gb_Output_announce,$(1) $(3) $(5),$(true),XHP,3)
+ $$(call gb_Trace_StartRange,$(1) $(3) $(5),XHP)
+ $$(call gb_Helper_abbreviate_dirs, \
+ mkdir -p $$(dir $$@) && \
+ $(if $(filter qtz,$(5)), \
+ $$(gb_Extension_HELPEXCOMMAND) -i $$< -o $$@ -l $(5) -m \
+ , \
+ $(if $(filter-out en-US,$(5)), \
+ MERGEINPUT=`$(gb_MKTEMP)` && \
+ echo $$(POFILE) > $$$${MERGEINPUT} && \
+ $$(gb_Extension_HELPEXCOMMAND) -i $$< -o $$@ -l $(5) \
+ -m $$$${MERGEINPUT} && \
+ rm -rf $$$${MERGEINPUT} \
+ , \
+ cp $$< $$@ \
+ ) \
+ ) && \
+ touch $(call gb_Extension_get_rootdir,$(1))/help/$(5)-xhp.done \
+ )
+ $$(call gb_Trace_EndRange,$(1) $(3) $(5),XHP)
+
+endef
+
+# localize one help.tree for one language; the result is stored as
+# help/$(4)/$(3) in the extension's workdir;
+# $(1): extension identifier
+# $(2): absolute path prefix of en-US source file without $(3) (resp. $(4))
+# suffix
+# $(3): relative path of (target) help.tree file (see
+# gb_Extension_add_helptreefile)
+# $(4): relative path of source help.tree file (see
+# gb_Extension_add_helptreefile)
+# $(5): language
+# $(6): relative path of localized xhp files (PlatformID included)
+define gb_Extension__localize_helptreefile_onelang
+$(call gb_Extension_get_rootdir,$(1))/help/$(5).done : \
+ $(call gb_Extension_get_rootdir,$(1))/help/$(5)/$(3)
+ifneq ($(filter-out en-US,$(5)),)
+ifneq ($(filter-out qtz,$(5)),)
+$(call gb_Extension_get_rootdir,$(1))/help/$(5)/$(3) : \
+ POFILE := $(gb_POLOCATION)/$(5)$(subst $(SRCDIR),,$(2))$(patsubst %/,/%.po,$(patsubst ./,.po,$(dir $(4))))
+$(call gb_Extension_get_rootdir,$(1))/help/$(5)/$(3) : \
+ $(gb_POLOCATION)/$(5)$(subst $(SRCDIR),,$(2))$(patsubst %/,/%.po,$(patsubst ./,.po,$(dir $(4))))
+$(gb_POLOCATION)/$(5)$(subst $(SRCDIR),,$(2))$(patsubst %/,/%.po,$(patsubst ./,.po,$(dir $(4)))) :
+endif
+endif
+$(call gb_Extension_get_rootdir,$(1))/help/$(5)/$(3) : \
+ $(call gb_Extension_get_rootdir,$(1))/help/$(5)-xhp.done
+$(call gb_Extension_get_rootdir,$(1))/help/$(5)/$(3) : \
+ $(gb_Extension_TREEXDEPS) | \
+ $(2)/$(4)
+$(call gb_Extension_get_rootdir,$(1))/help/$(5)/$(3) : \
+ $(2)/$(or $(4),$(3))
+ $$(call gb_Output_announce,$(1) $(3) $(5),$(true),TRE,3)
+ $$(call gb_Trace_StartRange,$(1) $(3) $(5),TRE)
+ $$(call gb_Helper_abbreviate_dirs, \
+ mkdir -p $$(dir $$@) && \
+ $(if $(filter qtz,$(5)), \
+ $(subst $$,$$$$,$(gb_Extension_TREEXCOMMAND)) -i $$< -o $$@ -l $(5) -m \
+ -r $$(call gb_Extension_get_workdir,$(1))/help/$(5)/$(6) \
+ , \
+ $(if $(filter-out en-US,$(5)), \
+ MERGEINPUT=`$(gb_MKTEMP)` && \
+ echo $$(POFILE) > $$$${MERGEINPUT} && \
+ $(subst $$,$$$$,$(gb_Extension_TREEXCOMMAND)) -i $$< -o $$@ -l $(5) \
+ -m $$$${MERGEINPUT} \
+ -r $$(call gb_Extension_get_workdir,$(1))/help/$(5)/$(6) && \
+ rm -rf $$$${MERGEINPUT} \
+ , \
+ $(subst $$,$$$$,$(gb_Extension_TREEXCOMMAND)) -i $$< -o $$@ -l $(5) \
+ -r $$(call gb_Extension_get_workdir,$(1))/help/$(5)/$(6) \
+ ) \
+ ) \
+ )
+ $$(call gb_Trace_EndRange,$(1) $(3) $(5),XHP)
+
+endef
+
+# compile help for one language; the result is stored as help/$(3)/ in the
+# extension's rootdir and marked for zipping into the .oxt
+# $(1): extension identifier
+# $(2): language
+# Target-specific HELPFILES: list of relative paths of .xhp files (see
+# gb_Extension_add_helpfile)
+define gb_Extension__compile_help_onelang
+$(call gb_Extension_get_rootdir,$(1))/help/$(2).done : \
+ $(gb_Extension_HELPINDEXERDEPS) \
+ $(gb_Extension_HELPLINKERDEPS) \
+ $(SRCDIR)/xmlhelp/util/embed.xsl \
+ $(SRCDIR)/xmlhelp/util/idxcaption.xsl \
+ $(SRCDIR)/xmlhelp/util/idxcontent.xsl | \
+ $(call gb_Extension_get_rootdir,$(1))/help/.dir
+ $$(call gb_Output_announce,$(1) $(2),$(true),XHC,3)
+ $$(call gb_Trace_StartRange,$(1) $(2),XHC)
+ $$(call gb_Helper_abbreviate_dirs, \
+ mkdir -p $$(basename $$@) && \
+ $$(gb_Extension_HELPLINKERCOMMAND) -mod help \
+ -extlangsrc $(call gb_Extension_get_workdir,$(1))/help/$(2) \
+ -sty $(SRCDIR)/xmlhelp/util/embed.xsl \
+ -extlangdest $$(basename $$@) \
+ -idxcaption $(SRCDIR)/xmlhelp/util/idxcaption.xsl \
+ -idxcontent $(SRCDIR)/xmlhelp/util/idxcontent.xsl \
+ $$(HELPFILES) && \
+ (cd $(call gb_Extension_get_workdir,$(1))/help/$(2) && \
+ $$(gb_Extension_ZIPCOMMAND) -r $$(basename $$@)/help.jar \
+ $$(HELPFILES)) && \
+ $$(gb_Extension_HELPINDEXERCOMMAND) -lang $(2) -mod help \
+ -dir $$(basename $$@) && \
+ rm -fr $$(basename $$@)/caption $$(basename $$@)/content && \
+ touch $$@)
+ $$(call gb_Trace_EndRange,$(1) $(2),XHC)
+
+endef
+
+# establish the dependency that actually causes inclusion of the compiled help
+# into the .oxt, for one language; in principle, this would only need to be done
+# once per language iff the extension uses any help -- currently it is done from
+# each individual gb_Extension_add_helpfile call (and thus requires $strip
+# to remove duplicates from FILES)
+# $(1): extension identifier
+# $(2): language
+define gb_Extension__add_compiled_help_dependency_onelang
+$(call gb_Extension_get_target,$(1)) : FILES += help/$(2)
+$(call gb_Extension_get_target,$(1)) : \
+ $(call gb_Extension_get_rootdir,$(1))/help/$(2).done
+$(call gb_Extension_get_rootdir,$(1))/help/$(2).done \
+ :| $(call gb_Extension__get_preparation_target,$(1))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/ExtensionPackage.mk b/solenv/gbuild/ExtensionPackage.mk
new file mode 100644
index 000000000..6a86aa027
--- /dev/null
+++ b/solenv/gbuild/ExtensionPackage.mk
@@ -0,0 +1,95 @@
+# -*- 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/.
+#
+
+# ExtensionPackage class
+#
+# Unpacks a binary .oxt file into the instdir extension directory and
+# writes a file-list.
+
+$(call gb_ExtensionPackage_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),OXP,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf $(INSTROOT)/$(LIBO_SHARE_FOLDER)/extensions/$* \
+ $(call gb_ExtensionPackage_get_target,$*))
+
+$(call gb_ExtensionPackage_get_preparation_target,%) :
+ mkdir -p $(dir $@) && touch $@
+
+$(call gb_ExtensionPackage_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),OXP,3)
+ $(call gb_Trace_StartRange,$*,OXP)
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) \
+ && rm -rf $(INSTROOT)/$(LIBO_SHARE_FOLDER)/extensions/$* \
+ && unzip -q $(ZIPFILE) -d $(INSTROOT)/$(LIBO_SHARE_FOLDER)/extensions/$* \
+ && zipinfo -1 $(ZIPFILE) | grep -v '/$$' \
+ | sed s+^+$(INSTROOT)/$(LIBO_SHARE_FOLDER)/extensions/$*/+ > $@)
+ $(call gb_Trace_EndRange,$*,OXP)
+
+# call gb_ExtensionPackage_ExtensionPackage_internal,package,oxt
+define gb_ExtensionPackage_ExtensionPackage_internal
+$(if $(2),,$(call gb_Output_error,need 2 parameters))
+$(call gb_ExtensionPackage_get_target,$(1)) : ZIPFILE := $(2)
+$(call gb_ExtensionPackage_get_target,$(1)) : $(2)
+$(call gb_ExtensionPackage_get_target,$(1)) :| \
+ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/extensions/.dir
+
+endef
+
+# call gb_ExtensionPackage_ExtensionPackage,package,oxt
+define gb_ExtensionPackage_ExtensionPackage
+$(call gb_ExtensionPackage_ExtensionPackage_internal,$(1),$(2))
+$(2) : $(call gb_ExtensionPackage_get_preparation_target,$(1))
+ touch $$@
+
+$$(eval $$(call gb_Module_register_target,$(call gb_ExtensionPackage_get_target,$(1)),$(call gb_ExtensionPackage_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),ExtensionPackage)
+
+endef
+
+# call gb_ExtensionPackage_use_external_project,package,externalproject
+define gb_ExtensionPackage_use_external_project
+$(call gb_ExtensionPackage_get_preparation_target,$(1)) : \
+ $(call gb_ExternalProject_get_target,$(2))
+
+endef
+
+# ExtensionPackage class
+#
+# This is less boring than writing a dozen 1-line ExtensionPackage files.
+
+$(call gb_ExtensionPackageSet_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),OXS,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf $(call gb_ExtensionPackageSet_get_target,$*))
+
+$(call gb_ExtensionPackageSet_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),OXS,3)
+ $(call gb_Trace_MakeMark,$*,OXS)
+ mkdir -p $(dir $@) && touch $@
+
+# call gb_ExtensionPackageSet_ExtensionPackageSet,set
+define gb_ExtensionPackageSet_ExtensionPackageSet
+$$(eval $$(call gb_Module_register_target,$(call gb_ExtensionPackageSet_get_target,$(1)),$(call gb_ExtensionPackageSet_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),ExtensionPackageSet)
+
+endef
+
+# call gb_ExtensionPackageSet_add_extension,set,package,oxt-filename
+define gb_ExtensionPackageSet_add_extension
+$(call gb_ExtensionPackage_ExtensionPackage_internal,$(2),$(TARFILE_LOCATION)/$(3))
+
+$(call gb_ExtensionPackageSet_get_target,$(1)) : \
+ $(call gb_ExtensionPackage_get_target,$(2))
+$(call gb_ExtensionPackageSet_get_clean_target,$(1)) : \
+ $(call gb_ExtensionPackage_get_clean_target,$(2))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/ExternalExecutable.mk b/solenv/gbuild/ExternalExecutable.mk
new file mode 100644
index 000000000..7a0fd996d
--- /dev/null
+++ b/solenv/gbuild/ExternalExecutable.mk
@@ -0,0 +1,216 @@
+# -*- 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/.
+#
+
+# class ExternalExecutable
+
+# ExternalExecutable is a little helper for using executables that might
+# either come from system or be built internally.
+#
+# === Setup ===
+#
+# An ExternalExecutable command consists of 4 parts:
+# * precommand: any command line variables that need to be set
+# * internal: unspecified command(s), possibly including calls of gdb,
+# valgrind or icerun
+# * executable: the executable, with or without path
+# * arguments: command line arguments that are specific for either
+# external or internal call, or that are common for _all_ uses of the
+# executable
+#
+# The configuration is done in RepositoryExternal.mk by defining function
+# gb_ExternalExecutable__register_EXECUTABLE, which can call up to 4
+# functions:
+# * gb_ExternalExecutable_set_external / gb_ExternalExecutable_set_internal
+# * gb_ExternalExecutable_set_precommand
+# * gb_ExternalExecutable_add_dependencies
+# * gb_ExternalExecutable_add_arguments.
+# If neither gb_ExternalExecutable_set_external nor
+# gb_ExternalExecutable_set_internal is used, the executable defaults to
+# the ExternalExecutable's name. Due to that, nothing needs to be set
+# for an external executable in the typical case.
+#
+# All external executables must be registered (by listing the executable
+# name in gb_ExternalExecutable_register_executables call). This is done in
+# Repository.mk .
+#
+# === Usage ===
+#
+# The call site(s) should always use both of the following functions:
+# * gb_ExternalExecutable_get_command: the complete command for the
+# executable
+# * gb_ExternalExecutable_get_dependencies: all run-time dependencies
+# needed by the command.
+
+## Infrastructure functions
+
+# The list of registered executables.
+gb_ExternalExecutable_REGISTERED_EXECUTABLES :=
+
+define gb_ExternalExecutable__add_executable
+$(if $(filter $(executable),$(gb_ExternalExecutable_REGISTERED_EXECUTABLES)),\
+ $(call gb_Output_error,external executable $(executable) has already been registered) \
+)
+gb_ExternalExecutable_REGISTERED_EXECUTABLES += $(1)
+
+endef
+
+# Register one or more external executables.
+#
+# gb_ExternalExecutable_register_executables executable(s)
+define gb_ExternalExecutable_register_executables
+$(foreach executable,$(1),$(call gb_ExternalExecutable__add_executable,$(executable)))
+
+endef
+
+define gb_ExternalExecutable__process_registration
+$(if $(filter undefined,$(origin gb_ExternalExecutable__register_$(executable))),\
+ $(call gb_Output_error,there is no definition for external executable $(executable)) \
+)
+$(call gb_ExternalExecutable__register_$(executable))
+
+endef
+
+# Collect definitions for registered executables.
+#
+# The registration functions will be run.
+#
+# gb_ExternalExecutable_collect_registrations
+define gb_ExternalExecutable_collect_registrations
+$(eval $(foreach executable,$(gb_ExternalExecutable_REGISTERED_EXECUTABLES),\
+ $(call gb_ExternalExecutable__process_registration,$(executable)))
+)
+
+endef
+
+define gb_ExternalExecutale__check_registration
+$(if $(filter $(1),$(gb_ExternalExecutable_REGISTERED_EXECUTABLES)),,\
+ $(call gb_Output_error,external executable $(1) has not been registered) \
+)
+
+endef
+
+## Setup functions
+
+# Set the executable as external
+#
+# Optionally set a specific executable call to use.
+# Example:
+# $(call gb_ExternalExecutable_set_external,genbrk,$(SYSTEM_GENBRK))
+#
+# gb_ExternalExecutable_set_external executable call?
+define gb_ExternalExecutable_set_external
+$(if $(2),gb_ExternalExecutable_$(1)_EXECUTABLE := $(2))
+
+endef
+
+# FIXME need to subst in some more $$ in gb_Helper_set_ld_path here - ugly
+# but other uses (gb_CppunitTest_CPPTESTPRECOMMAND) require less $$ - ugly
+define gb_ExternalExecutable__set_internal
+$(if $(3),,$(if $(filter $(WORKDIR_FOR_BUILD)/UnpackedTarball,$(2)),\
+ $(call gb_Output_error,depending directly on executable $(2) from UnpackedTarball is not allowed. Use the UnpackedTarball target as dependency.)))
+gb_ExternalExecutable_$(1)_EXECUTABLE := $(2)
+gb_ExternalExecutable_$(1)_DEPENDENCIES := $(if $(3),$(call gb_Executable_get_target_for_build,$(3)),$(2))
+gb_ExternalExecutable_$(1)_PRECOMMAND := $(subst $$,$$$$,$(gb_Helper_set_ld_path)) $(BUILDTOOLTRACE)
+
+endef
+
+# Set the executable as internal
+#
+# Optionally set a specific executable target to use (if the target
+# $(gb_Executable_BINDIR_FOR_BUILD)/$(1)$(gb_Executable_EXT_for_build) is
+# not suitable). Also optionally, set the ExternalProject that builds
+# the executable. This is needed to create proper dependency for
+# executables that are not bundled # with libreoffice, so they are used
+# directly from workdir/UnpackedTarball/*.
+#
+# gb_ExternalExecutable_set_internal executable call? external?
+define gb_ExternalExecutable_set_internal
+$(call gb_ExternalExecutable__set_internal,$(1),$(if $(strip $(2)),$(2),$(gb_Executable_BINDIR_FOR_BUILD)/$(1)$(gb_Executable_EXT_for_build)),$(strip $(3)))
+
+endef
+
+# Set pre-command for the executable
+#
+# This call should set any command line variables needed for the
+# executable to run.
+#
+# gb_ExternalExecutable_set_precommand executable precommand
+define gb_ExternalExecutable_set_precommand
+gb_ExternalExecutable_$(1)_PRECOMMAND := $(2) $(BUILDTOOLTRACE)
+
+endef
+
+# Add dependencies needed for running the executable
+#
+# Note that the dependencies should in most (if not all) cases be
+# _for_build targets, or there might be problems in cross-compilation
+# Specifically, not using _for_build target would mean either:
+# * the target is built before the command even if it is not necessary
+# (not really a problem, but might be a nuisance)
+# * the build breaks because the target is not known. This might happen
+# if there is a difference in configuration between build and host
+# phases.
+#
+# gb_ExternalExecutable_add_dependencies executable dependencies
+define gb_ExternalExecutable_add_dependencies
+gb_ExternalExecutable_$(1)_DEPENDENCIES += $(2)
+
+endef
+
+# Add arguments needed for running the executable
+#
+# This should only contain arguments that differ between external and
+# internal executable call or that are common for all call sites.
+#
+# gb_ExternalExecutable_add_arguments executable arguments
+define gb_ExternalExecutable_add_arguments
+gb_ExternalExecutable_$(1)_ARGUMENTS += $(2)
+
+endef
+
+## User functions
+
+gb_ExternalExecutable__get_internal := $(ICECREAM_RUN)
+
+define gb_ExternalExecutable__get_executable
+$(if $(gb_ExternalExecutable_$(1)_EXECUTABLE),$(gb_ExternalExecutable_$(1)_EXECUTABLE),$(1))
+endef
+
+define gb_ExternalExecutable__get_command
+$(call gb_ExternalExecutale__check_registration,$(1))
+$(gb_ExternalExecutable_$(1)_PRECOMMAND) \
+ $(call gb_ExternalExecutable__get_internal,$(1)) \
+ $(call gb_ExternalExecutable__get_executable,$(1)) \
+ $(gb_ExternalExecutable_$(1)_ARGUMENTS)
+endef
+
+# Return the command for running an external executable.
+#
+# The command includes the required shell variables, if any (e.g.,
+# LD_LIBRARY_PATH for internally built executables), and icerun wrapper
+# for limiting the maximum number of processes, if available.
+#
+# gb_ExternalExecutable_get_command executable
+define gb_ExternalExecutable_get_command
+$(strip $(call gb_ExternalExecutable__get_command,$(1)))
+endef
+
+define gb_ExternalExecutable__get_dependencies
+$(call gb_ExternalExecutale__check_registration,$(1))
+$(gb_ExternalExecutable_$(1)_DEPENDENCIES)
+endef
+
+# Return the dependencies needed for running an external executable.
+#
+# gb_ExternalExecutable_get_dependencies executable
+define gb_ExternalExecutable_get_dependencies
+$(strip $(call gb_ExternalExecutable__get_dependencies,$(1)))
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/ExternalPackage.mk b/solenv/gbuild/ExternalPackage.mk
new file mode 100644
index 000000000..05bfa6d0c
--- /dev/null
+++ b/solenv/gbuild/ExternalPackage.mk
@@ -0,0 +1,207 @@
+# -*- 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/.
+#
+
+# ExternalPackage class
+
+# This class extends Package to reliably deliver header files (and
+# possibly other kinds of files) from unpacked tarballs. The problem
+# with using Package is that the unpacked files' timestamps do not
+# depend on the extraction time; when the project's tarball is updated,
+# some header files might have been changed, but it is likely their
+# timestamps will be older than these of the headers delivered from the
+# previous version, so the delivered headers will not be updated.
+#
+# Uff, I hope this is at least partially understandable :-)
+#
+# Note: An ExternalPackage object can be used in functions that expect a
+# Package (e.g., gb_LinkTarget_use_package(s)).
+
+$(dir $(call gb_ExternalPackage_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_ExternalPackage_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_ExternalPackage_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),EPK,2)
+ $(call gb_Trace_MakeMark,$*,EPK)
+ touch $@
+
+$(call gb_ExternalPackage_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),EPK,2)
+ rm -f $(call gb_ExternalPackage_get_target,$*)
+
+# Create and register a new ExternalPackage
+#
+# The base directory of the package is the directory of the unpacked
+# tarball.
+#
+# gb_ExternalPackage_ExternalPackage name unpacked
+define gb_ExternalPackage_ExternalPackage
+$(call gb_ExternalPackage_ExternalPackage_internal,$(1),$(2))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_ExternalPackage_get_target,$(1)),$(call gb_ExternalPackage_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),ExternalPackage)
+
+endef
+
+# Create a new ExternalPackage
+#
+# This function should only be used in implementations of other gbuild
+# classes.
+#
+# gb_ExternalPackage_ExternalPackage_internal name unpacked
+define gb_ExternalPackage_ExternalPackage_internal
+$(call gb_Package_Package_internal,$(1),$(call gb_UnpackedTarball_get_dir,$(2)))
+$(call gb_Package_use_unpacked,$(1),$(2))
+
+$(call gb_ExternalPackage_get_target,$(1)) : $(call gb_Package_get_target,$(1))
+$(call gb_ExternalPackage_get_target,$(1)) :| $(dir $(call gb_ExternalPackage_get_target,$(1))).dir
+$(call gb_ExternalPackage_get_clean_target,$(1)) : $(call gb_Package_get_clean_target,$(1))
+
+gb_ExternalPackage_UNPACKED_$(1) := $(2)
+
+endef
+
+# Set output dir for the package's files.
+#
+# Default is $(INSTROOT).
+#
+# gb_ExternalPackage_set_outdir package outdir
+define gb_ExternalPackage_set_outdir
+$(call gb_Package_set_outdir,$(1),$(2))
+
+endef
+
+# Mark a source file to be used outside of this module
+#
+# This results in the timestamp of the file being updated, so a possible
+# change is recognized properly by other files depending on it.
+#
+# gb_ExternalPackage_mark_generated_file package file
+define gb_ExternalPackage_mark_generated_file
+$(call gb_UnpackedTarball_get_dir,$(gb_ExternalPackage_UNPACKED_$(1)))/$(2) : \
+ $(call gb_ExternalProject_get_target,$(gb_ExternalPackage_PROJECT_$(1)))
+$(if $(suffix $(2)),\
+ $(call gb_UnpackedTarbal__ensure_pattern_rule,$(gb_ExternalPackage_UNPACKED_$(1)),$(suffix $(2))),\
+ $(call gb_UnpackedTarbal__make_file_rule,$(gb_ExternalPackage_UNPACKED_$(1)),$(2)) \
+)
+
+endef
+
+# Mark several source files to be used outside of this module
+#
+# gb_ExternalProject_mark_generated_files package file(s)
+define gb_ExternalPackage_mark_generated_files
+$(foreach file,$(2),$(call gb_ExternalPackage_mark_generated_file,$(1),$(file)))
+
+endef
+
+define gb_ExternalPackage_add_symbolic_link
+$(call gb_Package_add_symbolic_link,$(1),$(2),$(3))
+
+endef
+
+# Add a file
+#
+# See gb_Package_add_file for details.
+#
+# gb_ExternalPackage_add_file package dest src
+define gb_ExternalPackage_add_file
+$(if $(4),$(call gb_Output_error,gb_ExternalPackage_add_file: $(1) 4: $(4)))
+$(call gb_ExternalPackage_mark_generated_file,$(1),$(3))
+$(call gb_Package_add_file,$(1),$(2),$(3))
+
+endef
+
+# Add several files at once
+#
+# See gb_Package_add_files for details.
+#
+# gb_ExternalPackage_add_files package destdir file(s)
+define gb_ExternalPackage_add_files
+$(call gb_ExternalPackage_mark_generated_files,$(1),$(3))
+$(call gb_Package_add_files,$(1),$(2),$(3))
+
+endef
+
+# Add several files at once
+#
+# See gb_Package_add_files_with_dir for details.
+#
+# gb_ExternalPackage_add_files_with_dir package destdir file(s)
+define gb_ExternalPackage_add_files_with_dir
+$(call gb_ExternalPackage_mark_generated_files,$(1),$(3))
+$(call gb_Package_add_files_with_dir,$(1),$(2),$(3))
+
+endef
+
+define gb_ExternalPackage__add_file
+$(call gb_UnpackedTarball_mark_output_file,$(gb_ExternalPackage_UNPACKED_$(1)),$(2))
+
+endef
+
+# Add an unpacked file
+#
+# See gb_Package_add_file for details.
+#
+# gb_ExternalPackage_add_unpacked_file package dest src
+define gb_ExternalPackage_add_unpacked_file
+$(call gb_Package_add_file,$(1),$(2),$(3))
+$(call gb_ExternalPackage__add_file,$(1),$(3))
+
+endef
+
+define gb_ExternalPackage__add_files
+$(foreach file,$(2),$(call gb_ExternalPackage__add_file,$(1),$(file)))
+
+endef
+
+# Add several unpacked files at once
+#
+# See gb_Package_add_files for details.
+#
+# gb_ExternalPackage_add_unpacked_files package destdir file(s)
+define gb_ExternalPackage_add_unpacked_files
+$(call gb_Package_add_files,$(1),$(2),$(3))
+$(call gb_ExternalPackage__add_files,$(1),$(3))
+
+endef
+
+# Add several unpacked files at once
+#
+# See gb_Package_add_files_with_dir for details.
+#
+# gb_ExternalPackage_add_unpacked_files_with_dir package destdir file(s)
+define gb_ExternalPackage_add_unpacked_files_with_dir
+$(call gb_Package_add_files_with_dir,$(1),$(2),$(3))
+$(call gb_ExternalPackage__add_files,$(1),$(3))
+
+endef
+
+# Package files from unpacked tarball of an external project
+#
+# gb_ExternalPackage_use_unpacked package unpacked
+define gb_ExternalPackage_use_unpacked
+$(call gb_Package_use_unpacked,$(1),$(2))
+
+endef
+
+# Package files from build of an external project
+#
+# gb_ExternalPackage_use_external_project package external
+define gb_ExternalPackage_use_external_project
+$(call gb_Package_use_external_project,$(1),$(2))
+
+$(if $(gb_ExternalPackage_PROJECT_$(1)),$(call gb_Output_error,gb_ExternalPackage_use_external_project: only one project allowed))
+gb_ExternalPackage_PROJECT_$(1) := $(2)
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/ExternalProject.mk b/solenv/gbuild/ExternalProject.mk
new file mode 100644
index 000000000..5227e6c13
--- /dev/null
+++ b/solenv/gbuild/ExternalProject.mk
@@ -0,0 +1,238 @@
+# -*- 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/.
+#
+
+# class ExternalProject
+
+# Handles build of an external project
+
+# Build of an external typically uses three gbuild classes:
+# ExternalProject, ExternalPackage or Package, and UnpackedTarball. The
+# first step is to prepare sources using UnpackedTarball. The tarball is
+# passed to an ExternalProject, which handles the build proper and the
+# results are delivered by an ExternalPackage (or Package, again;
+# Package is sufficient if no files--e.g., headers--from the unpacked
+# tarball need to be delivered.)
+#
+# An ExternalProject always uses one UnpackedTarball with the same name.
+# The dependency structure ensures that any change on a dependency
+# of the ExternalProject will cause the UnpackedTarball to be unpacked
+# again, so the ExternalProject always does a clean build and is not at
+# the mercy of the external's build system's dubious incremental builds.
+#
+# ExternalProject target
+# => ExternalProject state target(s) (these actually build stuff)
+# => UnpackedTarball target (unpack the tarball)
+# => UnpackedTarball prepare target
+# => ExternalProject prepare target
+# => stuff the external depends upon
+#
+# ExternalProject has no gbuild abstraction for actually building the
+# external code, so it is necessary to define rule(s) and recipe(s) to
+# handle it. It does not matter if there are several rules handling
+# separate phases of the build (e.g., configure, build, install) or if
+# the whole build is handled by one rule.
+#
+# ExternalProject uses two directories during the build: state dir
+# serves to keep file targets that mark state of the build progress
+# (e.g., "configure done", "build done") and the targets are accessible
+# via gb_ExternalProject_get_state_target. It is highly advised to
+# register them using gb_ExternalProject_register_targets. The second
+# directory is work dir, accessible only from recipes via variable
+# $(EXTERNAL_WORKDIR).
+
+$(dir $(call gb_ExternalProject_get_statedir,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_ExternalProject_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_ExternalProject_get_preparation_target,%) :
+ touch $@
+
+$(call gb_ExternalProject_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),PRJ,3)
+ $(call gb_Trace_MakeMark,$*,PRJ)
+ touch $@
+
+.PHONY : $(call gb_ExternalProject_get_clean_target,%)
+$(call gb_ExternalProject_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),PRJ,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf \
+ $(call gb_ExternalProject_get_target,$*) \
+ $(call gb_ExternalProject_get_statedir,$*) \
+ )
+
+# Define a new external project, using an unpacked tarball of the same name
+#
+# gb_ExternalProject_ExternalProject project
+define gb_ExternalProject_ExternalProject
+$(call gb_ExternalProject_get_target,$(1)) : EXTERNAL_WORKDIR := $(call gb_UnpackedTarball_get_dir,$(1))
+
+$(call gb_ExternalProject_get_preparation_target,$(1)) : $(gb_Module_CURRENTMAKEFILE)
+$(call gb_ExternalProject_get_preparation_target,$(1)) :| $(dir $(call gb_ExternalProject_get_target,$(1))).dir
+$(call gb_UnpackedTarball_get_preparation_target,$(1)) : $(call gb_ExternalProject_get_preparation_target,$(1))
+$(call gb_ExternalProject_get_clean_target,$(1)) : $(call gb_UnpackedTarball_get_clean_target,$(1))
+$(call gb_ExternalProject_get_target,$(1)) : $(call gb_UnpackedTarball_get_target,$(1))
+$(call gb_ExternalProject_get_target,$(1)) :| $(dir $(call gb_ExternalProject_get_target,$(1))).dir
+
+$$(eval $$(call gb_Module_register_target,$(call gb_ExternalProject_get_target,$(1)),$(call gb_ExternalProject_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),ExternalProject)
+
+endef
+
+# Depend on an unpacked tarball
+#
+# This is needed to express dependencies on header-only projects, which
+# do not have any ExternalProject.
+#
+# gb_ExternalProject_use_unpacked project unpacked
+define gb_ExternalProject_use_unpacked
+$(call gb_ExternalProject_get_preparation_target,$(1)) : $(call gb_UnpackedTarball_get_target,$(2))
+
+endef
+
+# Register a target in state directory
+#
+# This function defines proper dependencies for the target to ensure
+# that:
+# * the main target is updated if this target is updated
+# * this target is updated if the unpacked tarball has changed.
+#
+# gb_ExternalProject_register_target project target
+define gb_ExternalProject_register_target
+$(call gb_ExternalProject_get_target,$(1)) : $(call gb_ExternalProject_get_state_target,$(1),$(2))
+$(call gb_ExternalProject_get_state_target,$(1),$(2)) : $(call gb_UnpackedTarball_get_target,$(1))
+$(call gb_ExternalProject_get_state_target,$(1),$(2)) :| $(dir $(call gb_ExternalProject_get_state_target,$(1),$(2))).dir
+
+endef
+
+# Register several targets at once
+#
+# gb_ExternalProject_register_targets project target(s)
+define gb_ExternalProject_register_targets
+$(foreach target,$(2),$(call gb_ExternalProject_register_target,$(1),$(target)))
+
+endef
+
+# Make an external Project depend on another ExternalProject
+define gb_ExternalProject_use_external_project
+$(call gb_ExternalProject_get_preparation_target,$(1)) : $(call gb_ExternalProject_get_target,$(2))
+
+endef
+
+# call gb_ExternalProject_use_external_projects,project,projects
+define gb_ExternalProject_use_external_projects
+$(foreach ext,$(2),$(call gb_ExternalProject_use_external_project,$(1),$(ext)))
+endef
+
+# Make an ExternalProject depend on an external
+#
+# this forwards to functions that must be defined in RepositoryExternal.mk.
+# $(eval $(call gb_ExternalProject_use_external,library,external))
+define gb_ExternalProject_use_external
+$(if $(filter undefined,$(origin gb_ExternalProject__use_$(2))),\
+ $(error gb_ExternalProject_use_external: unknown external: $(2)),\
+ $(call gb_ExternalProject__use_$(2),$(1)))
+endef
+
+define gb_ExternalProject_use_externals
+$(foreach external,$(2),$(call gb_ExternalProject_use_external,$(1),$(external)))
+endef
+
+# Make an external project depend on a package
+#
+# This is most useful for depending on output files created by another
+# ExternalProject.
+#
+# gb_ExternalProject_use_package external package
+define gb_ExternalProject_use_package
+$(call gb_ExternalProject_get_preparation_target,$(1)) : $(call gb_Package_get_target,$(2))
+
+endef
+
+# Make an external project depend on several packages at once
+#
+# gb_ExternalProject_use_packages external package(s)
+define gb_ExternalProject_use_packages
+$(foreach package,$(2),$(call gb_ExternalProject_use_package,$(1),$(package)))
+
+endef
+
+# Make an external project depend on a StaticLibrary
+#
+# Realistically there are some externals that do not have a usable build
+# system, and other externals that do may depend on those.
+#
+# gb_ExternalProject_use_static_libraries external staticlibraries
+define gb_ExternalProject_use_static_libraries
+$(call gb_ExternalProject_get_preparation_target,$(1)) : \
+ $(foreach lib,$(2),$(call gb_StaticLibrary_get_target,$(lib)))
+
+endef
+
+# Make an external project depend on a Library
+#
+# Realistically there are some externals that do not have a usable build
+# system, and other externals that do may depend on those.
+#
+# gb_ExternalProject_use_libraries external libraries
+define gb_ExternalProject_use_libraries
+ifneq (,$$(filter-out $(gb_Library_KNOWNLIBS) $(gb_LinkTarget__syslib),$(2)))
+$$(eval $$(call gb_Output_info,currently known libraries are: $(sort $(gb_Library_KNOWNLIBS)),ALL))
+$$(eval $$(call gb_Output_error,Cannot link against library/libraries $$(filter-out $(gb_Library_KNOWNLIBS) $(gb_LinkTarget__syslib),$(2)). Libraries must be registered in Repository.mk or RepositoryExternal.mk))
+endif
+ifneq (,$$(filter $$(gb_MERGEDLIBS),$(2)))
+$$(eval $$(call gb_Output_error,Cannot link against library/libraries $$(filter $$(gb_MERGEDLIBS),$(2)) because they are merged.))
+endif
+
+$(call gb_ExternalProject_get_preparation_target,$(1)) : \
+ $(foreach lib,$(2),$(call gb_Library_get_target,$(lib)))
+
+endef
+
+# Make an external project depend on a Jar file
+#
+# gb_ExternalProject_use_jars external jars
+define gb_ExternalProject_use_jars
+$(call gb_ExternalProject_get_preparation_target,$(1)) : \
+ $(foreach jar,$(2),$(call gb_Jar_get_target,$(jar)))
+
+endef
+
+# Returns flags to include in CFLAGS/CXXFLAGS to enable optimizations and/or debugging.
+# gb_ExternalProject_get_build_flags project
+gb_ExternalProject_get_build_flags = $(call gb_LinkTarget__get_debugflags,ExternalProject_$(1))
+
+# Returns flags to include in LDFLAGS to enable optimizations and/or debugging.
+# gb_ExternalProject_get_link_flags project
+gb_ExternalProject_get_link_flags = $(LDFLAGS) $(USE_LD) $(call gb_LinkTarget__get_debugldflags,ExternalProject_$(1))
+
+# Run a target command
+#
+# This provides a wrapper that changes to the right directory,
+# touches the 'target' if successful and also provides
+# the ability to hide the output if there is no failure
+# gb_ExternalProject_run,run_target,command,optional_extra_sub_directory,optional_log_filename)
+# default log_filename is <run_target>.log
+#
+
+define gb_ExternalProject_run
+$(if $(findstring YES,$(UNPACKED_IS_BIN_TARBALL)),\
+ touch $@,
+$(call gb_Helper_print_on_error,cd $(EXTERNAL_WORKDIR)/$(3) && \
+ unset Platform && \
+ $(if $(WRAPPERS),export $(WRAPPERS) &&) \
+ $(if $(NMAKE),export $(NMAKE) &&) \
+ $(if $(gb_COMPILER_SETUP),export $(gb_COMPILER_SETUP) &&) \
+ $(2) && touch $@,$(EXTERNAL_WORKDIR)/$(if $(3),$(3)/,)$(if $(4),$(4),$(1).log))
+)
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/Gallery.mk b/solenv/gbuild/Gallery.mk
new file mode 100644
index 000000000..56d5157ef
--- /dev/null
+++ b/solenv/gbuild/Gallery.mk
@@ -0,0 +1,183 @@
+# -*- 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/.
+#
+
+# class Gallery
+
+# Handles creation of image galleries.
+
+gb_Gallery_TRANSLATE := $(SRCDIR)/solenv/bin/desktop-translate.py
+gb_Gallery_INSTDIR := $(LIBO_SHARE_FOLDER)/gallery
+
+define gb_Gallery__command
+$(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_Gallery_get_workdir,$(2))/* && \
+ RESPONSEFILE=$(call gb_var2file,$(shell $(call gb_MKTEMP)),100,$(GALLERY_FILES)) && \
+ $(call gb_Helper_print_on_error,\
+ $(call gb_Executable_get_command,gengal,$(ICECREAM_RUN)) \
+ --build-tree \
+ --destdir $(GALLERY_BASEDIR) \
+ --name "$(GALLERY_NAME)" \
+ --path $(call gb_Gallery_get_workdir,$(2)) \
+ --filenames $(call gb_Helper_make_url,$$RESPONSEFILE) \
+ -env:UserInstallation=$(call gb_Helper_make_url,$(call gb_Gallery_get_workdir,$(2))/user),\
+ $@.log \
+ ) && \
+ rm $$RESPONSEFILE && \
+ touch $@ \
+)
+endef
+
+define gb_Gallery__command_str
+cp -f $(GALLERY_STRFILE) $@ && \
+$(call gb_ExternalExecutable_get_command,python) \
+ $(gb_Gallery_TRANSLATE) \
+ --ext "str" --key "name" \
+ -d $(GALLERY_WORKDIR) \
+ $(GALLERY_ULFFILE)
+endef
+
+gb_Gallery__get_final_target = $(WORKDIR)/Gallery/$(1).final
+
+$(dir $(call gb_Gallery_get_target,$(1))).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_Gallery_get_target,$(1)))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_Gallery_get_target,%) : \
+ $(call gb_Executable_get_runtime_dependencies,gengal)
+ $(call gb_Output_announce,$*,$(true),GAL,1)
+ $(call gb_Trace_StartRange,$*,GAL)
+ $(call gb_Gallery__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,GAL)
+
+$(call gb_Gallery__get_final_target,%) :
+ touch $@
+
+# difficult to determine source dep for this one...
+$(call gb_Gallery_get_workdir,%).ulf : \
+ $(call gb_Executable_get_runtime_dependencies,ulfex)
+ $(call gb_CustomTarget_ulfex__command,$@,$(GALLERY_ULFFILE),\
+ $(foreach lang,$(gb_TRANS_LANGS),\
+ $(gb_POLOCATION)/$(lang)/extras/source/gallery/share.po))
+
+$(call gb_Gallery_get_workdir,%).str : $(gb_Gallery_TRANSLATE) \
+ $(call gb_ExternalExecutable_get_dependencies,python)
+ $(call gb_Output_announce,$*,$(true),STR,1)
+ $(call gb_Trace_StartRange,$*,STR)
+ $(call gb_Gallery__command_str,$@,$*)
+ $(call gb_Trace_EndRange,$*,STR)
+
+# there must be a rule for these since they are targets due to Package
+$(call gb_Gallery_get_workdir,%).sdg :
+ touch $@
+$(call gb_Gallery_get_workdir,%).sdv :
+ touch $@
+$(call gb_Gallery_get_workdir,%).thm :
+ touch $@
+
+.PHONY : $(call gb_Gallery_get_clean_target,%)
+$(call gb_Gallery_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),GAL,1)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf \
+ $(call gb_Gallery__get_final_target,$*) \
+ $(call gb_Gallery_get_target,$*) \
+ $(call gb_Gallery_get_target,$*).log \
+ $(call gb_Gallery_get_workdir,$*) \
+ )
+
+# the theme package
+gb_Gallery_get_packagename = Gallery/$(1)
+# the files package
+gb_Gallery_get_files_packagename = Gallery/Files/$(1)
+
+# Create a gallery.
+#
+# basedir less one directory will be stripped from paths of the files when they are
+# inserted into the gallery.
+#
+# gb_Gallery_Gallery gallery basedir name
+define gb_Gallery_Gallery
+$(call gb_Gallery__Gallery_impl,$(1),$(call gb_Gallery_get_packagename,$(1)),$(2),$(3))
+
+# setup the files package - we install all of these too
+$(call gb_Package_Package_internal,$(call gb_Gallery_get_files_packagename,$(1)),$(SRCDIR)/$(2))
+$(call gb_Gallery__get_final_target,$(1)) : $(call gb_Package_get_target,$(call gb_Gallery_get_files_packagename,$(1)))
+$(call gb_Gallery_get_clean_target,$(1)) : $(call gb_Package_get_clean_target,$(call gb_Gallery_get_files_packagename,$(1)))
+
+endef
+
+
+gb_Gallery_basedir = $(patsubst %/,%,$(dir $(SRCDIR)/$(1)))
+
+# TODO: we process the same ulf file for every gallery. That does not
+# make sense.
+#
+# gb_Gallery__Gallery_impl gallery package basedir name
+define gb_Gallery__Gallery_impl
+$(call gb_Package_Package_internal,$(2),$(call gb_Gallery_get_workdir,$(1)))
+$(call gb_Package_add_file,$(2),$(gb_Gallery_INSTDIR)/$(1).sdg,$(1).sdg)
+$(call gb_Package_add_file,$(2),$(gb_Gallery_INSTDIR)/$(1).sdv,$(1).sdv)
+$(call gb_Package_add_file,$(2),$(gb_Gallery_INSTDIR)/$(1).thm,$(1).thm)
+$(call gb_Package_add_file,$(2),$(gb_Gallery_INSTDIR)/$(1).str,$(1).str)
+
+# strip URL, without / to help the internal gallery system
+$(call gb_Gallery_get_target,$(1)) : GALLERY_BASEDIR := $(call gb_Helper_make_url,$(call gb_Gallery_basedir,$(3)))
+$(call gb_Gallery_get_target,$(1)) : GALLERY_FILES :=
+$(call gb_Gallery_get_target,$(1)) : GALLERY_NAME := $(1)
+$(call gb_Gallery_get_workdir,$(1))/$(1).str : GALLERY_STRFILE := $(SRCDIR)/$(3)/$(1).str
+$(call gb_Gallery_get_workdir,$(1))/$(1).str : GALLERY_ULFFILE := $(call gb_Gallery_get_workdir,$(1))/$(1).ulf
+$(call gb_Gallery_get_workdir,$(1))/$(1).str : GALLERY_WORKDIR := $(call gb_Gallery_get_workdir,$(1))
+$(call gb_Gallery_get_workdir,$(1))/$(1).ulf : GALLERY_BASEDIR := $(3)
+$(call gb_Gallery_get_workdir,$(1))/$(1).ulf : GALLERY_ULFFILE := $(call gb_Gallery_basedir,$(3))/share/gallery_names.ulf
+
+$(call gb_Gallery_get_workdir,$(1))/$(1).ulf : \
+ $(call gb_Gallery_basedir,$(3))/share/gallery_names.ulf \
+ $(call gb_Gallery_get_target,$(1)) # that rule pre-cleans our output directory
+
+$(call gb_Gallery_get_workdir,$(1))/$(1).str : $(call gb_Gallery_get_workdir,$(1))/$(1).ulf
+
+$(call gb_Gallery_get_workdir,$(1))/$(1).sdg \
+$(call gb_Gallery_get_workdir,$(1))/$(1).sdv \
+$(call gb_Gallery_get_workdir,$(1))/$(1).thm : $(call gb_Gallery_get_target,$(1))
+$(call gb_Gallery__get_final_target,$(1)) : $(call gb_Package_get_target,$(2))
+
+$(call gb_Gallery_get_clean_target,$(1)) : $(call gb_Package_get_clean_target,$(2))
+$(call gb_Gallery_get_target,$(1)) :| $(dir $(call gb_Gallery_get_target,$(1))).dir \
+ $(call gb_Gallery_get_workdir,$(1))/.dir
+
+$$(eval $$(call gb_Module_register_target,$(call gb_Gallery__get_final_target,$(1)),$(call gb_Gallery_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),Gallery,$(call gb_Gallery__get_final_target,$(1)))
+
+endef
+
+# Add a file to the gallery.
+#
+# The file is given by path relative to $(SRCDIR).
+#
+# gb_Gallery_add_file gallery file
+define gb_Gallery_add_file
+$(call gb_Gallery_get_target,$(1)) : $(SRCDIR)/$(3)
+$(call gb_Gallery_get_target,$(1)) : GALLERY_FILES += $(call gb_Helper_make_url,$(SRCDIR)/$(3))
+$(call gb_Package_add_file,$(call gb_Gallery_get_files_packagename,$(1)),$(2)/$(notdir $(3)),$(notdir $(3)))
+
+endef
+
+# Add several files to the gallery at once.
+#
+# The files are given by path relative to $(SRCDIR).
+#
+# gb_Gallery_add_files gallery file(s)
+define gb_Gallery_add_files
+$(foreach fname,$(3),$(call gb_Gallery_add_file,$(1),$(2),$(fname)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/GeneratedPackage.mk b/solenv/gbuild/GeneratedPackage.mk
new file mode 100644
index 000000000..92f176436
--- /dev/null
+++ b/solenv/gbuild/GeneratedPackage.mk
@@ -0,0 +1,106 @@
+# -*- 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/.
+#
+
+# class GeneratedPackage
+
+# Enables to deliver whole directories (of generated files) to instdir.
+#
+# GeneratedPackage shall be used as a substitution for Package when the
+# names of the produced files are not known in advance (in older times,
+# we used Zip in these places). It shall only be used to deliver files
+# for installation.
+#
+# If you know the filenames in advance, use Package. Laziness is not an
+# excuse.
+
+gb_GeneratedPackage__get_srcdir = $(lastword $(subst <>, ,$(1)))
+gb_GeneratedPackage__get_destdir = $(firstword $(subst <>, ,$(1)))
+
+$(dir $(call gb_GeneratedPackage_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_GeneratedPackage_get_target,%))%.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+# require all added directories to exist
+$(call gb_GeneratedPackage_get_target,%) :| $(foreach pair,$(PACKAGE_DIRS),$(PACKAGE_SOURCEDIR)/$(call gb_GeneratedPackage__get_srcdir,$(pair)))
+
+# split in two commands to avoid running into commandline/environment size limits
+# on windows with all languages the processing of help can truncate the find command otherwise
+$(call gb_GeneratedPackage_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),GPK,2)
+ $(call gb_Trace_StartRange,$*,GPK)
+ $(if $(PACKAGE_DIRS),,$(call gb_Output_error,no dirs were added))
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf $(foreach pair,$(PACKAGE_DIRS),$(call gb_GeneratedPackage__get_destdir,$(pair))) \
+ && mkdir -p $(foreach pair,$(PACKAGE_DIRS),$(dir $(call gb_GeneratedPackage__get_destdir,$(pair)))) \
+ $(foreach pair,$(PACKAGE_DIRS),&& cp -R $(PACKAGE_SOURCEDIR)/$(call gb_GeneratedPackage__get_srcdir,$(pair)) $(call gb_GeneratedPackage__get_destdir,$(pair))) \
+ )
+ $(call gb_Helper_abbreviate_dirs,\
+ $(FIND) $(foreach pair,$(PACKAGE_DIRS),$(call gb_GeneratedPackage__get_destdir,$(pair))) \( -type f -o -type l \) -print | LC_ALL=C $(SORT) > $@ \
+ )
+ $(call gb_Trace_EndRange,$*,GPK)
+
+.PHONY : $(call gb_GeneratedPackage_get_clean_target,%)
+$(call gb_GeneratedPackage_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),GPK,2)
+ rm -rf $(call gb_GeneratedPackage_get_target,$*) $(PACKAGE_DIRS)
+
+# Create a generated package.
+#
+# gb_GeneratedPackage_GeneratedPackage package srcdir
+define gb_GeneratedPackage_GeneratedPackage
+$(call gb_GeneratedPackage_get_target,$(1)) : PACKAGE_DIRS :=
+$(call gb_GeneratedPackage_get_target,$(1)) : PACKAGE_SOURCEDIR := $(2)
+$(call gb_GeneratedPackage_get_clean_target,$(1)) : PACKAGE_DIRS :=
+
+$(call gb_GeneratedPackage_get_target,$(1)) : $(gb_Module_CURRENTMAKEFILE)
+$(call gb_GeneratedPackage_get_target,$(1)) :| $(dir $(call gb_GeneratedPackage_get_target,$(1))).dir
+
+$$(eval $$(call gb_Module_register_target,$(call gb_GeneratedPackage_get_target,$(1)),$(call gb_GeneratedPackage_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),GeneratedPackage)
+
+endef
+
+# Depend on a custom target.
+#
+# gb_GeneratedPackage_use_customtarget package custom-target
+define gb_GeneratedPackage_use_customtarget
+$(call gb_GeneratedPackage_get_target,$(1)) : $(call gb_CustomTarget_get_target,$(2))
+
+endef
+
+# Depend on an unpacked tarball.
+#
+# gb_GeneratedPackage_use_unpacked package unpacked
+define gb_GeneratedPackage_use_unpacked
+$(call gb_GeneratedPackage_get_target,$(1)) : $(call gb_UnpackedTarball_get_target,$(2))
+
+endef
+
+# Depend on an external project.
+#
+# gb_GeneratedPackage_use_external_project package project
+define gb_GeneratedPackage_use_external_project
+$(call gb_GeneratedPackage_get_target,$(1)) : $(call gb_ExternalProject_get_target,$(2))
+
+endef
+
+# Add a dir to the package.
+#
+# The srcdir will be copied to instdir as destdir.
+#
+# gb_GeneratedPackage_add_dir package destdir srcdir
+define gb_GeneratedPackage_add_dir
+$(call gb_GeneratedPackage_get_target,$(1)) : PACKAGE_DIRS += $(strip $(2))<>$(strip $(3))
+$(call gb_GeneratedPackage_get_clean_target,$(1)) : PACKAGE_DIRS += $(2)
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/HelpTarget.mk b/solenv/gbuild/HelpTarget.mk
new file mode 100644
index 000000000..64ec6e278
--- /dev/null
+++ b/solenv/gbuild/HelpTarget.mk
@@ -0,0 +1,836 @@
+# -*- 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/.
+#
+
+# This gbuild module handles building of localized help packs. The main
+# entry point is class HelpTarget; the other classes should be
+# considered private implementation details and not used directly from
+# outside of this file.
+#
+# All defined objects must be named <help-module>/<lang>. If this naming
+# scheme is not followed, bad things will happen!
+
+# Overview of classes and dependencies
+
+# class task depends on
+# HelpTranslatePartTarget l10n of xhp files in one dir xhp file(s)
+# HelpTranslateTarget l10n of xhp files HelpTranslatePartTarget
+# HelpTreeTarget l10n of tree file tree file
+# HelpLinkTarget linking help module HelpTranslateTarget
+# HelpTreeTarget
+# HelpJarTarget creating jar of xhp files HelpLinkTarget
+# HelpIndexTarget indexing help module HelpLinkTarget
+# HelpTarget creating help pack HelpIndexTarget
+# HelpJarTarget
+# extra added files
+
+# class HelpTranslatePartTarget
+
+# Translates .xhp files in one directory.
+
+gb_HelpTranslatePartTarget_DEPS := $(call gb_Executable_get_runtime_dependencies,helpex)
+gb_HelpTranslatePartTarget_COMMAND := $(call gb_Executable_get_command,helpex)
+
+define gb_HelpTranslatePartTarget__command
+HELPFILES=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(sort $(filter %.xhp,$(3)))) && \
+$(call gb_Helper_abbreviate_dirs, \
+ $(if $(filter-out qtz,$(HELP_LANG)), \
+ POFILES=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(sort $(POFILES))) && \
+ $(gb_HelpTranslatePartTarget_COMMAND) \
+ -l $(HELP_LANG) \
+ -mi $${HELPFILES} \
+ -m $${POFILES} \
+ -o $(call gb_HelpTranslatePartTarget_get_workdir,$(2)) && \
+ rm -f $${POFILES} \
+ , \
+ $(gb_HelpTranslatePartTarget_COMMAND) \
+ -l $(HELP_LANG) \
+ -mi $${HELPFILES} \
+ -m \
+ -o $(call gb_HelpTranslatePartTarget_get_workdir,$(2)) \
+ ) \
+) && \
+touch $@ && \
+rm -f $${HELPFILES}
+
+endef
+
+$(dir $(call gb_HelpTranslatePartTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_HelpTranslatePartTarget_get_target,%) : $(gb_HelpTranslatePartTarget_DEPS)
+ $(call gb_Output_announce,$*,$(true),HPX,1)
+ $(call gb_Trace_StartRange,$*,HPX)
+ $(call gb_HelpTranslatePartTarget__command,$@,$*,$^)
+ $(call gb_Trace_EndRange,$*,HPX)
+
+.PHONY : $(call gb_HelpTranslatePartTarget_get_clean_target,%)
+$(call gb_HelpTranslatePartTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),HPX,1)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf \
+ $(call gb_HelpTranslatePartTarget_get_target,$*) \
+ $(call gb_HelpTranslatePartTarget_get_workdir,$*) \
+ )
+
+# Translate a set of .xhp files from one directory.
+#
+# gb_HelpTranslatePartTarget_HelpTranslatePartTarget target lang dir
+define gb_HelpTranslatePartTarget_HelpTranslatePartTarget
+$(call gb_HelpTranslatePartTarget_get_target,$(1)) : HELP_LANG := $(2)
+$(call gb_HelpTranslatePartTarget_get_target,$(1)) : POFILES := $(3)
+
+$(call gb_HelpTranslatePartTarget_get_target,$(1)) : $(gb_Module_CURRENTMAKEFILE)
+$(call gb_HelpTranslatePartTarget_get_target,$(1)) : $(3)
+$(call gb_HelpTranslatePartTarget_get_target,$(1)) :| $(dir $(call gb_HelpTranslatePartTarget_get_target,$(1))).dir
+$(call gb_HelpTranslatePartTarget_get_target,$(1)) :| $(call gb_HelpTranslatePartTarget_get_workdir,$(1))/.dir
+
+endef
+
+define gb_HelpTranslatePartTarget_add_file
+$(call gb_HelpTranslatePartTarget_get_target,$(1)) : $(2)
+
+endef
+
+# class HelpTranslateTarget
+
+# Translates a set of .xhp files.
+
+gb_HelpTranslateTarget__get_lang = $(lastword $(subst /, ,$(1)))
+
+gb_HelpTranslateTarget__get_partname = $(call gb_HelpTranslateTarget__get_lang,$(1))/$(patsubst %/,%,$(2))
+gb_HelpTranslateTarget__get_part_workdir = $(call gb_HelpTranslatePartTarget_get_workdir,$(call gb_HelpTranslateTarget__get_partname,$(1),$(2)))
+
+gb_HelpTranslateTarget_get_translated_target = $(call gb_HelpTranslatePartTarget_get_translated_target,$(call gb_HelpTranslateTarget__get_partname,$(1),$(dir $(2))),$(notdir $(2)))
+gb_HelpTranslateTarget__get_any_translated_target = $(abspath $(call gb_HelpTranslatePartTarget_get_translated_target,,$(1)))
+gb_HelpTranslateTarget_get_workdir = $(call gb_HelpTranslateTarget__get_part_workdir,$(1),$(2))
+
+$(dir $(call gb_HelpTranslateTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_HelpTranslateTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_HelpTranslateTarget_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),XHP,2)
+ $(call gb_Trace_MakeMark,$*,XHP)
+ touch $@
+
+$(call gb_HelpTranslateTarget__get_any_translated_target,%) :
+ touch $@
+
+.PHONY : $(call gb_HelpTranslateTarget_get_clean_target,%)
+$(call gb_HelpTranslateTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),XHP,2)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_HelpTranslateTarget_get_target,$*) \
+ )
+
+# Localizes a set of .xhp files to one language.
+#
+# gb_HelpTranslateTarget_HelpTranslateTarget module
+define gb_HelpTranslateTarget_HelpTranslateTarget
+$(call gb_HelpTranslateTarget_get_target,$(1)) :| $(dir $(call gb_HelpTranslateTarget_get_target,$(1))).dir
+
+endef
+
+# use wildcard to avoid spurious rebuilds if translation is missing
+# gb_HelpTranslateTarget__make_part module part lang dir
+define gb_HelpTranslateTarget__make_part
+$(call gb_HelpTranslatePartTarget_HelpTranslatePartTarget,$(2),$(3),$(wildcard $(gb_POLOCATION)/$(3)/$(patsubst %/,%,$(4)).po))
+
+$(call gb_HelpTranslateTarget_get_target,$(1)) : $(call gb_HelpTranslatePartTarget_get_target,$(2))
+$(call gb_HelpTranslateTarget_get_clean_target,$(1)) : $(call gb_HelpTranslatePartTarget_get_clean_target,$(2))
+
+endef
+
+# gb_HelpTranslateTarget__add_file module dir file
+define gb_HelpTranslateTarget__add_file
+$(call gb_HelpTranslatePartTarget_add_file,$(call gb_HelpTranslateTarget__get_partname,$(1),$(2)),$(SRCDIR)/$(3).xhp)
+$(call gb_HelpTranslateTarget_get_translated_target,$(1),$(3)) : $(call gb_HelpTranslateTarget_get_target,$(1))
+
+endef
+
+# gb_HelpTranslateTarget__add_files_impl module lang dir(s) file(s)
+define gb_HelpTranslateTarget__add_files_impl
+$(foreach part,$(3),$(call gb_HelpTranslateTarget__make_part,$(1),$(call gb_HelpTranslateTarget__get_partname,$(1),$(part)),$(2),$(part)))
+$(foreach file,$(4),$(call gb_HelpTranslateTarget__add_file,$(1),$(dir $(file)),$(file)))
+
+endef
+
+# gb_HelpTranslateTarget__add_files module file(s)
+define gb_HelpTranslateTarget__add_files
+$(call gb_HelpTranslateTarget__add_files_impl,$(1),$(call gb_HelpTranslateTarget__get_lang,$(1)),$(sort $(dir $(2))),$(2))
+
+endef
+
+# gb_HelpTranslateTarget_add_file module file
+define gb_HelpTranslateTarget_add_file
+$(call gb_HelpTranslateTarget__add_files,$(1),$(2))
+
+endef
+
+# gb_HelpTranslateTarget_add_files module file(s)
+define gb_HelpTranslateTarget_add_files
+$(call gb_HelpTranslateTarget__add_files,$(1),$(2))
+
+endef
+
+# class HelpTree
+
+# Translates a .tree file.
+
+gb_HelpTreeTarget_DEPS := $(call gb_Executable_get_runtime_dependencies,treex)
+gb_HelpTreeTarget_COMMAND := $(call gb_Executable_get_command,treex)
+
+define gb_HelpTreeTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ $(if $(filter-out qtz,$(HELP_LANG)), \
+ POFILES=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(POFILES)) && \
+ $(gb_HelpTreeTarget_COMMAND) \
+ -i $(HELP_TREE) \
+ -l $(HELP_LANG) \
+ -m $${POFILES} \
+ -o $@ \
+ -r $(HELP_TEXTDIR) && \
+ rm -f $${POFILES} \
+ , \
+ $(gb_HelpTreeTarget_COMMAND) \
+ -i $(HELP_TREE) \
+ -l $(HELP_LANG) \
+ -m \
+ -o $@ \
+ -r $(HELP_TEXTDIR) \
+ ) \
+)
+
+endef
+
+$(dir $(call gb_HelpTreeTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_HelpTreeTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_HelpTreeTarget_get_target,%) : $(gb_HelpTreeTarget_DEPS)
+ $(if $(HELP_TEXTDIR),,$(call gb_Output_error,HelpTreeTarget: no help text dir for .tree was set))
+ $(if $(HELP_TREE),,$(call gb_Output_error,HelpTreeTarget: no .tree file to translate was set))
+ $(call gb_Output_announce,$*,$(true),TRE,1)
+ $(call gb_Trace_StartRange,$*,TRE)
+ $(call gb_HelpTreeTarget__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,TRE)
+
+.PHONY : $(call gb_HelpTreeTarget_get_clean_target,%)
+$(call gb_HelpTreeTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),TRE,1)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_HelpTreeTarget_get_target,$*) \
+ )
+
+# Translate a .tree file.
+#
+# gb_HelpTreeTarget_HelpTreeTarget target lang
+define gb_HelpTreeTarget_HelpTreeTarget
+$(call gb_HelpTreeTarget_get_target,$(1)) : HELP_LANG := $(2)
+$(call gb_HelpTreeTarget_get_target,$(1)) : HELP_TEXTDIR :=
+$(call gb_HelpTreeTarget_get_target,$(1)) : HELP_TREE :=
+$(call gb_HelpTreeTarget_get_target,$(1)) : POFILES :=
+
+$(call gb_HelpTreeTarget_get_target,$(1)) :| $(dir $(call gb_HelpTreeTarget_get_target,$(1))).dir
+
+endef
+
+# gb_HelpTreeTarget__set_pofiles target pofiles
+define gb_HelpTreeTarget__set_pofiles
+$(call gb_HelpTreeTarget_get_target,$(1)) : POFILES := $(2)
+$(call gb_HelpTreeTarget_get_target,$(1)) : $(2)
+
+endef
+
+# use wildcard to avoid spurious rebuilds if translation is missing
+# gb_HelpTreeTarget_set_treefile target treefile
+define gb_HelpTreeTarget_set_treefile
+$(call gb_HelpTreeTarget__set_pofiles,$(1),$(wildcard $(gb_POLOCATION)/$(lastword $(subst /, ,$(1)))/$(patsubst %/,%,$(dir $(2))).po))
+
+$(call gb_HelpTreeTarget_get_target,$(1)) : HELP_TREE := $(SRCDIR)/$(2).tree
+$(call gb_HelpTreeTarget_get_target,$(1)) : $(SRCDIR)/$(2).tree
+
+endef
+
+# gb_HelpTreeTarget_set_helptextdir target dir
+define gb_HelpTreeTarget_set_helptextdir
+$(call gb_HelpTreeTarget_get_target,$(1)) : HELP_TEXTDIR := $(2)
+
+endef
+
+# class HelpLinkTarget
+
+# Links a help module.
+
+gb_HelpLinkTarget_HELPLINKERDEPS := $(call gb_Executable_get_runtime_dependencies,HelpLinker)
+gb_HelpLinkTarget_HELPLINKERCOMMAND := $(call gb_Executable_get_command,HelpLinker)
+gb_HelpLinkTarget_COMPACTTARGET := $(SRCDIR)/xmlhelp/util/compact.xsl
+gb_HelpLinkTarget_EMBEDTARGET := $(SRCDIR)/xmlhelp/util/embed.xsl
+gb_HelpLinkTarget_IDXCAPTIONTARGET := $(SRCDIR)/xmlhelp/util/idxcaption.xsl
+gb_HelpLinkTarget_IDXCONTENTTARGET := $(SRCDIR)/xmlhelp/util/idxcontent.xsl
+gb_HelpLinkTarget_DEPS := \
+ $(gb_HelpLinkTarget_HELPLINKERDEPS) \
+ $(gb_HelpLinkTarget_COMPACTTARGET) \
+ $(gb_HelpLinkTarget_EMBEDTARGET) \
+ $(gb_HelpLinkTarget_IDXCAPTIONTARGET) \
+ $(gb_HelpLinkTarget_IDXCONTENTTARGET)
+
+# delete index files here too just to be on the safe side...
+# the index files in the .idxl dir are created by HelpIndexer,
+# the ones outside the dir by HelpLinker
+define gb_HelpLinkTarget__command
+ $(if $(HELP_INDEXED),rm -rf $(addprefix $(HELP_WORKDIR)/,$(HELP_INDEXED)) && \)
+RESPONSEFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,\
+ -lang $(HELP_LANG) \
+ -mod $(HELP_MODULE) \
+ $(if $(HELP_INDEXED),,-noindex) \
+ -nolangroot \
+ -o $(WORKDIR)/dummy.zip \
+ -src $(HELP_SRCDIR) \
+ -zipdir $(HELP_WORKDIR) \
+ -compact $(gb_HelpLinkTarget_COMPACTTARGET) \
+ -idxcaption $(gb_HelpLinkTarget_IDXCAPTIONTARGET) \
+ -idxcontent $(gb_HelpLinkTarget_IDXCONTENTTARGET) \
+ -sty $(gb_HelpLinkTarget_EMBEDTARGET) \
+ $(if $(HELP_CONFIGFILE),-add $(HELP_MODULE).cfg $(HELP_CONFIGFILE)) \
+ $(if $(HELP_TREE),-add $(HELP_MODULE).tree $(HELP_TREE)) \
+ $(foreach file,$(HELP_ADD_FILES),-add $(notdir $(file)) $(file)) \
+ $(foreach extra,$(HELP_EXTRA_ADD_FILES),-add $(subst $(COMMA), ,$(extra))) \
+ $(HELP_FILES) \
+ $(if $(HELP_LINKED_MODULES),\
+ $(shell cat $(foreach module,$(HELP_LINKED_MODULES),$(call gb_HelpTarget_get_filelist,$(module)))) \
+ ) \
+) && \
+$(gb_HelpLinkTarget_HELPLINKERCOMMAND) @$${RESPONSEFILE} && \
+touch $@ && \
+rm -f $${RESPONSEFILE}
+endef
+
+
+$(dir $(call gb_HelpLinkTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_HelpLinkTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_HelpLinkTarget_get_target,%) : $(gb_HelpLinkTarget_DEPS)
+ $(call gb_Output_announce,$*,$(true),HLK,3)
+ $(call gb_Trace_StartRange,$*,HLK)
+ $(call gb_HelpLinkTarget__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,HLK)
+
+.PHONY : $(call gb_HelpLinkTarget_get_clean_target,%)
+$(call gb_HelpLinkTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),HLK,3)
+ rm -f $(call gb_HelpLinkTarget_get_target,$*)
+
+# Create a help linking target.
+#
+# depend on makefile to re-build when files are removed
+#
+# gb_HelpLinkTarget_HelpLinkTarget name module lang workdir
+define gb_HelpLinkTarget_HelpLinkTarget
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_ADD_FILES :=
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_CONFIGFILE :=
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_EXTRA_ADD_FILES :=
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_FILES :=
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_INDEXED :=
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_MODULE := $(2)
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_LANG := $(3)
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_LINKED_MODULES :=
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_SRCDIR :=
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_TREE :=
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_WORKDIR := $(4)
+
+$(call gb_HelpLinkTarget_get_target,$(1)) : $(gb_Module_CURRENTMAKEFILE)
+$(call gb_HelpLinkTarget_get_target,$(1)) :| $(dir $(call gb_HelpLinkTarget_get_target,$(1))).dir
+
+$(4)/$(2).tree : $(call gb_HelpLinkTarget_get_target,$(1))
+
+endef
+
+# gb_HelpLinkTarget_set_configfile target configfile
+define gb_HelpLinkTarget_set_configfile
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_CONFIGFILE := $(2)
+$(call gb_HelpLinkTarget_get_target,$(1)) : $(2)
+
+endef
+
+# gb_HelpLinkTarget_set_sourcedir target source
+define gb_HelpLinkTarget_set_sourcedir
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_SRCDIR := $(2)
+
+endef
+
+# gb_HelpLinkTarget_set_treefile target treefile
+define gb_HelpLinkTarget_set_treefile
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_TREE := $(2)
+$(call gb_HelpLinkTarget_get_target,$(1)) : $(2)
+
+endef
+
+# gb_HelpLinkTarget_set_indexed target indexfiles
+define gb_HelpLinkTarget_set_indexed
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_INDEXED := $(2)
+$(addprefix $(call gb_HelpTarget_get_workdir,$(1))/,$(2)) : $(call gb_HelpIndexTarget_get_target,$(1))
+
+endef
+
+# gb_HelpLinkTarget_add_helpfile target helpfile
+define gb_HelpLinkTarget_add_helpfile
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_FILES += $(2)
+$(call gb_HelpLinkTarget_get_target,$(1)) : $(2)
+
+endef
+
+# Add an arbitrary file to the help pack.
+#
+# The file will be added to the root directory of the pack.
+#
+# gb_HelpLinkTarget_add_file target file
+define gb_HelpLinkTarget_add_file
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_ADD_FILES += $(2)
+$(call gb_HelpLinkTarget_get_target,$(1)) : $(2)
+
+endef
+
+# Add an arbitrary file to the help pack under a new name.
+#
+# The file will be added to the root directory of the pack.
+#
+# gb_HelpLinkTarget_add_renamed_file target filename file
+define gb_HelpLinkTarget_add_renamed_file
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_EXTRA_ADD_FILES += $(strip $(2)),$(strip $(3))
+$(call gb_HelpLinkTarget_get_target,$(1)) : $(3)
+$(call gb_HelpTarget_get_workdir,$(1))/$(2) : $(call gb_HelpLinkTarget_get_target,$(1))
+ touch $$@
+
+endef
+
+# Link with help files from another help module.
+#
+# gb_HelpLinkTarget_use_linked_module target help
+define gb_HelpLinkTarget_use_linked_module
+$(call gb_HelpLinkTarget_get_target,$(1)) : HELP_LINKED_MODULES += $(2)
+
+endef
+
+# class HelpIndexTarget
+
+# Creates a full-text search index for a help module.
+
+gb_HelpIndexTarget_DEPS := $(call gb_Executable_get_runtime_dependencies,HelpIndexer)
+gb_HelpIndexTarget_COMMAND := $(call gb_Executable_get_command,HelpIndexer)
+
+# first delete the index stuff since when it is generated an existing _0.cfs
+# will not be overwritten; instead a new _1.cfs etc. created until disk is full
+define gb_HelpIndexTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ (\
+ rm -rf $(HELP_WORKDIR)/$(HELP_MODULE).idxl \
+ && $(gb_HelpIndexTarget_COMMAND) \
+ -dir $(HELP_WORKDIR) \
+ -lang $(HELP_LANG) \
+ -mod $(HELP_MODULE) \
+ && touch $@ \
+ ) \
+ || ( rm -rf $(HELP_MODULE).* ; false )
+)
+endef
+
+$(dir $(call gb_HelpIndexTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_HelpIndexTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_HelpIndexTarget_get_target,%) : $(gb_HelpIndexTarget_DEPS)
+ $(call gb_Output_announce,$*,$(true),HIX,3)
+ $(call gb_Trace_StartRange,$*,HIX)
+ $(call gb_HelpIndexTarget__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,HIX)
+
+.PHONY : $(call gb_HelpIndexTarget_get_clean_target,%)
+$(call gb_HelpIndexTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),HIX,3)
+ rm -f $(call gb_HelpIndexTarget_get_target,$*)
+
+# Create a help indexing target.
+#
+# gb_HelpIndexTarget_HelpIndexTarget target module lang workdir
+define gb_HelpIndexTarget_HelpIndexTarget
+$(call gb_HelpIndexTarget_get_target,$(1)) : HELP_LANG := $(3)
+$(call gb_HelpIndexTarget_get_target,$(1)) : HELP_MODULE := $(2)
+$(call gb_HelpIndexTarget_get_target,$(1)) : HELP_WORKDIR := $(4)
+
+$(call gb_HelpIndexTarget_get_target,$(1)) :| $(dir $(call gb_HelpIndexTarget_get_target,$(1))).dir
+
+endef
+
+# class HelpJarTarget
+
+# Packs help files processed by HelpLinker into a jar in the workdir.
+
+gb_HelpJarTarget_COMMAND := zip
+
+define gb_HelpJarTarget__get_command
+cd $(HELP_WORKDIR) && \
+$(gb_HelpJarTarget_COMMAND) -q -0 -rX --filesync --must-match $(HELP_MODULE).jar text/$(HELP_MODULE) && \
+touch $@
+endef
+
+$(dir $(call gb_HelpJarTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_HelpJarTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_HelpJarTarget_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),HEJ,3)
+ $(call gb_Trace_StartRange,$*,HEJ)
+ $(call gb_HelpJarTarget__get_command,$@,$*)
+ $(call gb_Trace_EndRange,$*,HEJ)
+
+$(call gb_HelpJarTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),HEJ,3)
+ rm -f $(call gb_HelpJarTarget_get_target,$*)
+
+# gb_HelpJarTarget_HelpJarTarget target module workdir
+define gb_HelpJarTarget_HelpJarTarget
+$(call gb_HelpJarTarget_get_target,$(1)) : HELP_MODULE := $(2)
+$(call gb_HelpJarTarget_get_target,$(1)) : HELP_WORKDIR := $(3)
+
+$(call gb_HelpJarTarget_get_target,$(1)) :| $(dir $(call gb_HelpJarTarget_get_target,$(1))).dir
+
+$(3)/$(2).jar : $(call gb_HelpJarTarget_get_target,$(1))
+
+endef
+
+# class HelpTarget
+
+# Creates one language version of a help module.
+#
+# Provides a filelist called HelpTarget/<name>, that is not built by
+# default (i.e., the user of HelpTarget has to explicitly depend on the
+# Package).
+
+gb_HelpTarget_DEFAULT_LANG := en-US
+
+gb_HelpTarget__get_module = $(patsubst %/$(call gb_HelpTarget__get_lang,$(1)),%,$(1))
+gb_HelpTarget__get_lang = $(lastword $(subst /, ,$(1)))
+gb_HelpTarget__test_default_lang = $(filter $(gb_HelpTarget_DEFAULT_LANG),$(1))
+gb_HelpTarget__is_default_lang = $(call gb_HelpTarget__test_default_lang,$(call gb_HelpTarget__get_lang,$(1)))
+
+define gb_HelpTarget__get_helpdir
+$(if $(call gb_HelpTarget__is_default_lang,$(1)) \
+ ,$(SRCDIR)/$(2) \
+ ,$(call gb_HelpTranslateTarget_get_workdir,$(1),$(2)) \
+)
+endef
+
+define gb_HelpTarget__get_helpfile
+$(if $(call gb_HelpTarget__is_default_lang,$(1)) \
+ ,$(SRCDIR)/$(2).xhp \
+ ,$(call gb_HelpTranslateTarget_get_translated_target,$(1),$(2)) \
+)
+endef
+
+define gb_HelpTarget__get_treefile
+$(if $(call gb_HelpTarget__is_default_lang,$(1)) \
+ ,$(SRCDIR)/$(2).tree \
+ ,$(call gb_HelpTreeTarget_get_target,$(1)) \
+)
+endef
+
+define gb_HelpTarget__command
+$(if $(ENABLE_HTMLHELP),,$(call gb_Output_announce,$(2),$(true),HLP,4))
+$(if $(ENABLE_HTMLHELP),,$(call gb_Trace_MakeMark,$(2),HLP))
+touch $@
+endef
+
+$(dir $(call gb_HelpTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_HelpTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+# Translation of the module's .xhp files and all used modules is done.
+# Also creates the list for gb_HelpTarget_get_filelist.
+$(call gb_HelpTarget_get_translation_target,%) :
+ rm -f $@ && mv $(call gb_var2file,$@.tmp,100,$(strip $(HELP_FILES))) $@
+
+# Translation of the module's .xhp files and all used and linked modules
+# is done.
+$(call gb_HelpTarget_get_linked_target,%) :
+ touch $@
+
+$(call gb_HelpTarget_get_target,%) :
+ $(call gb_HelpTarget__command,$@,$*)
+
+.PHONY : $(call gb_HelpTarget_get_clean_target,%)
+$(call gb_HelpTarget_get_clean_target,%) :
+ifeq ($(ENABLE_HTMLHELP),)
+ $(call gb_Output_announce,$*,$(false),HLP,4)
+endif
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf \
+ $(call gb_HelpTarget_get_linked_target,$*) \
+ $(call gb_HelpTarget_get_target,$*) \
+ $(call gb_HelpTarget_get_translation_target,$*) \
+ $(call gb_HelpTarget_get_workdir,$*) \
+ )
+
+gb_HelpTarget_get_packagename = HelpTarget/$(1)
+
+# Create a help target.
+#
+# depend on makefile to re-build filelist when files are removed
+#
+# gb_HelpTarget_HelpTarget target module lang
+define gb_HelpTarget_HelpTarget
+$(call gb_HelpTarget_get_target,$(1)) : HELP_MODULE := $(2)
+$(call gb_HelpTarget_get_target,$(1)) : HELP_LANG := $(3)
+
+$(call gb_HelpTarget_get_translation_target,$(1)) : HELP_FILES :=
+$(call gb_HelpTarget_get_translation_target,$(1)) : $(gb_Module_CURRENTMAKEFILE)
+
+$(call gb_HelpTarget__HelpTarget_impl,$(1),$(2),$(3),$(call gb_HelpTarget_get_workdir,$(1)),$(call gb_HelpTarget_get_packagename,$(1)))
+
+endef
+
+# gb_HelpTarget__HelpTarget_impl target module lang workdir package
+define gb_HelpTarget__HelpTarget_impl
+$(if $(call gb_HelpTarget__test_default_lang,$(3)),,$(call gb_HelpTarget__HelpTarget_impl_lang,$(1),$(2),$(3),$(4)))
+
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpLinkTarget_HelpLinkTarget,$(1),$(2),$(3),$(4))
+$(call gb_HelpIndexTarget_HelpIndexTarget,$(1),$(2),$(3),$(4))
+$(call gb_HelpJarTarget_HelpJarTarget,$(1),$(2),$(4))
+$(call gb_Package_Package_internal,$(5),$(4))
+endif
+
+$(call gb_HelpTarget_get_linked_target,$(1)) : $(call gb_HelpTarget_get_translation_target,$(1))
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpLinkTarget_get_target,$(1)) : $(call gb_HelpTarget_get_linked_target,$(1))
+$(call gb_HelpLinkTarget_get_target,$(1)) :| $(call gb_HelpTarget_get_workdir,$(1))/.dir
+$(call gb_HelpTarget_get_target,$(1)) : $(call gb_HelpLinkTarget_get_target,$(1))
+$(call gb_Package_get_preparation_target,$(5)) : $(call gb_HelpTarget_get_target,$(1))
+endif
+
+$(call gb_HelpTarget_get_linked_target,$(1)) :| $(dir $(call gb_HelpTarget_get_linked_target,$(1))).dir
+$(call gb_HelpTarget_get_target,$(1)) :| $(dir $(call gb_HelpTarget_get_target,$(1))).dir
+$(call gb_HelpTarget_get_translation_target,$(1)) :| $(dir $(call gb_HelpTarget_get_translation_target,$(1))).dir
+
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpTarget_get_clean_target,$(1)) : $(call gb_HelpLinkTarget_get_clean_target,$(1))
+endif
+
+endef
+
+# gb_HelpTarget__HelpTarget_impl_lang target module lang workdir
+define gb_HelpTarget__HelpTarget_impl_lang
+$(call gb_HelpTranslateTarget_HelpTranslateTarget,$(1),$(3))
+$(call gb_HelpTreeTarget_HelpTreeTarget,$(1),$(3))
+
+$(call gb_HelpTarget_get_translation_target,$(1)) : $(call gb_HelpTranslateTarget_get_target,$(1))
+$(call gb_HelpTreeTarget_get_target,$(1)) : $(call gb_HelpTarget_get_linked_target,$(1))
+
+$(call gb_HelpTarget_get_clean_target,$(1)) : $(call gb_HelpTranslateTarget_get_clean_target,$(1))
+$(call gb_HelpTarget_get_clean_target,$(1)) : $(call gb_HelpTreeTarget_get_clean_target,$(1))
+
+endef
+
+# need a rule for these because these are targets for the Package
+$(WORKDIR)/HelpTarget/%.tree :
+ touch $@
+$(WORKDIR)/HelpTarget/%.jar :
+ touch $@
+$(WORKDIR)/HelpTarget/%.db :
+ touch $@
+$(WORKDIR)/HelpTarget/%.ht :
+ touch $@
+$(WORKDIR)/HelpTarget/%.key :
+ touch $@
+$(WORKDIR)/HelpTarget/%.idxl/_0.cfs :
+ touch $@
+$(WORKDIR)/HelpTarget/%.idxl/segments_3 :
+ touch $@
+$(WORKDIR)/HelpTarget/%.idxl/segments.gen :
+ touch $@
+
+# Get list of the various index files.
+#
+# gb_HelpTarget__add_index_files target module
+define gb_HelpTarget__get_index_files
+$(foreach suffix,.db .ht .idxl/_0.cfs .idxl/segments_3 .idxl/segments.gen .key,$(addsuffix $(suffix),$(call gb_HelpTarget__get_module,$(1))))
+endef
+
+# gb_HelpTarget__add_file target file
+define gb_HelpTarget__add_file
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_Package_add_file,$(call gb_HelpTarget_get_packagename,$(1)),$(LIBO_SHARE_HELP_FOLDER)/$(call gb_HelpTarget__get_lang,$(1))/$(2),$(2))
+endif
+
+endef
+
+# Set config. file used for the help module.
+#
+# The configfile is relative to $(SRCDIR) and without extension.
+#
+# gb_HelpTarget_set_configfile target configfile
+define gb_HelpTarget_set_configfile
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpLinkTarget_set_configfile,$(1),$(SRCDIR)/$(2).cfg)
+$(call gb_HelpTarget__add_file,$(1),$(call gb_HelpTarget__get_module,$(1)).cfg)
+endif
+
+endef
+
+# gb_HelpTarget_set_helpdir target helpdir
+define gb_HelpTarget_set_helpdir
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpLinkTarget_set_sourcedir,$(1),$(call gb_HelpTarget__get_helpdir,$(1),$(2)))
+endif
+
+endef
+
+# gb_HelpTarget_set_treefile target treefile textdir
+define gb_HelpTarget_set_treefile
+$(if $(call gb_HelpTarget__is_default_lang,$(1)),,\
+ $(call gb_HelpTreeTarget_set_treefile,$(1),$(2)) \
+ $(call gb_HelpTreeTarget_set_helptextdir,$(1),$(call gb_HelpTarget__get_helpdir,$(1),$(3))) \
+)
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpLinkTarget_set_treefile,$(1),$(call gb_HelpTarget__get_treefile,$(1),$(2)))
+$(call gb_HelpTarget__add_file,$(1),$(call gb_HelpTarget__get_module,$(1)).tree)
+endif
+
+endef
+
+# Produce full text search index, bookmark list, etc.
+#
+# gb_HelpTarget_set_indexed target
+define gb_HelpTarget_set_indexed
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpLinkTarget_set_indexed,$(1),$(call gb_HelpTarget__get_index_files,$(1)))
+$(foreach file,$(call gb_HelpTarget__get_index_files,$(1)),$(call gb_HelpTarget__add_file,$(1),$(file)))
+
+$(call gb_HelpIndexTarget_get_target,$(1)) : $(call gb_HelpLinkTarget_get_target,$(1))
+$(call gb_HelpTarget_get_target,$(1)) : $(call gb_HelpIndexTarget_get_target,$(1))
+$(call gb_HelpTarget_get_clean_target,$(1)) : $(call gb_HelpIndexTarget_get_clean_target,$(1))
+endif
+
+endef
+
+# gb_HelpTarget__add_jar target
+define gb_HelpTarget__add_jar
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpTarget__add_file,$(1),$(call gb_HelpTarget__get_module,$(1)).jar)
+$(call gb_HelpJarTarget_get_target,$(1)) : $(call gb_HelpLinkTarget_get_target,$(1))
+$(call gb_HelpTarget_get_target,$(1)) : $(call gb_HelpJarTarget_get_target,$(1))
+$(call gb_HelpTarget_get_clean_target,$(1)) : $(call gb_HelpJarTarget_get_clean_target,$(1))
+endif
+
+endef
+
+define gb_HelpTarget__add_helpfile_impl
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpLinkTarget_add_helpfile,$(1),$(2))
+endif
+
+$(call gb_HelpTarget_get_translation_target,$(1)) : HELP_FILES += $(2)
+
+endef
+
+# gb_HelpTarget__add_helpfile target helpfile
+define gb_HelpTarget__add_helpfile
+$(call gb_HelpTarget__add_helpfile_impl,$(1),$(call gb_HelpTarget__get_helpfile,$(1),$(2)))
+
+endef
+
+# gb_HelpTarget_add_helpfile target helpfile
+define gb_HelpTarget_add_helpfile
+$(call gb_HelpTranslateTarget_add_file,$(1),$(2))
+$(call gb_HelpTarget__add_helpfile,$(1),$(2))
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpTarget__add_jar,$(1))
+endif
+
+endef
+
+# gb_HelpTarget_add_helpfiles target helpfile(s)
+define gb_HelpTarget_add_helpfiles
+$(call gb_HelpTranslateTarget_add_files,$(1),$(2))
+$(foreach helpfile,$(2),$(call gb_HelpTarget__add_helpfile,$(1),$(helpfile)))
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpTarget__add_jar,$(1))
+endif
+
+endef
+
+# gb_HelpTarget_add_file target file
+define gb_HelpTarget_add_file
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpLinkTarget_add_file,$(1),$(SRCDIR)/$(2))
+$(call gb_HelpTarget__add_file,$(1),$(notdir $(2)))
+endif
+
+endef
+
+# gb_HelpTarget_add_files target file(s)
+define gb_HelpTarget_add_files
+$(foreach file,$(2),$(call gb_HelpTarget_add_file,$(1),$(file)))
+
+endef
+
+# Add a localized file from helpdir under a new name.
+#
+# This is a hack needed for err.html in shared help module.
+#
+# gb_HelpTarget_add_helpdir_file target filename file
+define gb_HelpTarget_add_helpdir_file
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpLinkTarget_add_renamed_file,$(1),$(2),$(call gb_HelpTarget__get_helpfile,$(1),$(3)))
+$(call gb_HelpTarget__add_file,$(1),$(2))
+endif
+
+endef
+
+# gb_HelpTarget_use_module target module
+define gb_HelpTarget_use_module
+$(call gb_HelpTarget_get_translation_target,$(1)) : $(call gb_HelpTarget_get_translation_target,$(2))
+
+endef
+
+# gb_HelpTarget_use_modules target module(s)
+define gb_HelpTarget_use_modules
+$(foreach module,$(2),$(call gb_HelpTarget_use_module,$(1),$(module)))
+
+endef
+
+# gb_HelpTarget_use_linked_module target module
+define gb_HelpTarget_use_linked_module
+ifeq ($(ENABLE_HTMLHELP),)
+$(call gb_HelpLinkTarget_use_linked_module,$(1),$(2))
+$(call gb_HelpTarget_get_linked_target,$(1)) : $(call gb_HelpTarget_get_translation_target,$(2))
+endif
+
+endef
+
+# gb_HelpTarget_use_linked_modules target module(s)
+define gb_HelpTarget_use_linked_modules
+$(foreach module,$(2),$(call gb_HelpTarget_use_linked_module,$(1),$(module)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/Helper.mk b/solenv/gbuild/Helper.mk
new file mode 100644
index 000000000..a0441dc3a
--- /dev/null
+++ b/solenv/gbuild/Helper.mk
@@ -0,0 +1,354 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+gb_Helper_MISC := $(WORKDIR)/Misc
+
+# general purpose phony target
+gb_Helper_PHONY := $(gb_Helper_MISC)/PHONY
+
+# general purpose empty dummy target
+gb_Helper_MISCDUMMY := $(gb_Helper_MISC)/DUMMY
+
+# target for reacting to changes in the list of configured languages
+gb_Helper_LANGSTARGET := $(BUILDDIR)/config_$(gb_Side)_lang.mk.stamp
+
+.PHONY : $(WORKDIR)/Misc/PHONY
+$(gb_Helper_MISCDUMMY) :
+ @mkdir -p $(dir $@) && touch $@
+
+ifeq ($(SRCDIR),$(BUILDDIR))
+define gb_Helper_abbreviate_dirs
+S=$(SRCDIR) && \
+$(subst $(SRCDIR)/,$$S/,I=$(INSTDIR)) && \
+$(subst $(SRCDIR)/,$$S/,W=$(WORKDIR)) && \
+$(subst $(SRCDIR)/,$$S/,$(subst $(INSTDIR)/,$$I/,$(subst $(WORKDIR)/,$$W/,$(1))))
+endef
+else
+define gb_Helper_abbreviate_dirs
+S=$(SRCDIR) && \
+$(subst $(SRCDIR)/,$$S/,B=$(BUILDDIR)) && \
+$(subst $(SRCDIR)/,$$S/,$(subst $(BUILDDIR)/,$$B/,I=$(INSTDIR))) && \
+$(subst $(SRCDIR)/,$$S/,$(subst $(BUILDDIR)/,$$B/,W=$(WORKDIR))) && \
+$(subst $(SRCDIR)/,$$S/,$(subst $(BUILDDIR)/,$$B/,$(subst $(INSTDIR)/,$$I/,$(subst $(WORKDIR)/,$$W/,$(1)))))
+endef
+endif
+
+define gb_Helper_abbreviate_dirs_native
+$(call gb_Output_error,gb_Helper_abbreviate_dirs_native: use gb_Helper_abbreviate_dirs instead.)
+endef
+
+define gb_Helper_native_path
+$(call gb_Output_error,gb_Helper_native_path: Do not use. Should not be necessary.)
+endef
+
+# cygwin seems to eat one backslash when executing command, thus replace with '\\'
+define gb_Helper_windows_path
+$(subst /,\\,$(1))
+endef
+
+define gb_Helper_make_clean_target
+gb_$(1)_get_clean_target = $(WORKDIR)/Clean/$(1)/$$(1)
+
+endef
+
+define gb_Helper_make_dep_target
+gb_$(1)_get_dep_target = $(WORKDIR)/Dep/$(1)/$$(1).d
+
+endef
+
+define gb_Helper_make_clean_targets
+$(foreach targettype,$(1),\
+ $(call gb_Helper_make_clean_target,$(targettype)))
+
+endef
+
+define gb_Helper_make_dep_targets
+$(foreach targettype,$(1),\
+ $(call gb_Helper_make_dep_target,$(targettype)))
+
+endef
+
+# e.g. 'make CppunitTest_sw_macros_test'
+#
+# gb_Helper_make_userfriendly_targets target class build-target? clean-target?
+define gb_Helper_make_userfriendly_targets
+.PHONY: $(2) $(2)_$(1) $(2)_$(1).clean
+$(2): $(2)_$(1)
+$(2)_$(1) : $(if $(3),$(3),$(call gb_$(2)_get_target,$(1)))
+$(2)_$(1).clean : $(if $(4),$(4),$(call gb_$(2)_get_clean_target,$(1)))
+
+endef
+
+define gb_Helper_init_registries
+gb_Executable_VALIDGROUPS_INSTALLED := UREBIN SDK OOO
+gb_Executable_VALIDGROUPS_NOTINSTALLED := NONE
+gb_Executable_VALIDGROUPS := UREBIN SDK OOO NONE
+gb_Library_VALIDGROUPS_INSTALLED := OOOLIBS PLAINLIBS_URE PLAINLIBS_OOO PRIVATELIBS_URE RTVERLIBS UNOVERLIBS PLAINLIBS_SHLXTHDL
+gb_Library_VALIDGROUPS_NOTINSTALLED := PLAINLIBS_NONE PLAINLIBS_OXT EXTENSIONLIBS
+gb_Library_VALIDGROUPS := OOOLIBS PLAINLIBS_URE PLAINLIBS_OOO PRIVATELIBS_URE RTVERLIBS UNOVERLIBS PLAINLIBS_SHLXTHDL PLAINLIBS_NONE PLAINLIBS_OXT EXTENSIONLIBS
+gb_Jar_VALIDGROUPS_INSTALLED := URE OOO
+gb_Jar_VALIDGROUPS_NOTINSTALLED := OXT NONE
+gb_Jar_VALIDGROUPS := URE OOO OXT NONE
+
+$$(foreach group,$$(gb_Executable_VALIDGROUPS),$$(eval gb_Executable_$$(group) :=))
+$$(foreach group,$$(gb_Library_VALIDGROUPS),$$(eval gb_Library_$$(group) :=))
+$$(foreach group,$$(gb_Jar_VALIDGROUPS),$$(eval gb_Jar_$$(group) :=))
+
+endef
+
+define gb_Helper_collect_knownlibs
+gb_Library_KNOWNLIBS := $$(foreach group,$$(gb_Library_VALIDGROUPS),$$(gb_Library_$$(group)))
+gb_Executable_KNOWN := $$(foreach group,$$(gb_Executable_VALIDGROUPS),$$(gb_Executable_$$(group)))
+gb_Jar_KNOWN := $$(foreach group,$$(gb_Jar_VALIDGROUPS),$$(gb_Jar_$$(group)))
+gb_Fuzzers_KNOWN := $$(filter %fuzzer,$$(foreach group,$$(gb_Executable_VALIDGROUPS),$$(gb_Executable_$$(group))))
+
+endef
+
+define gb_Helper_process_executable_registrations
+$(foreach group,$(gb_Executable_VALIDGROUPS),\
+ $(foreach executable,$(gb_Executable_$(group)),\
+ $(if $(filter-out undefined,$(origin gb_Executable__register_$(executable))),\
+ $(call gb_Executable__register_$(executable)))))
+
+endef
+
+define gb_Helper__register_executables
+$(foreach group,$(gb_Executable_VALIDGROUPS),\
+ $(foreach target,$(2),\
+ $(if $(filter $(target),$(gb_Executable_$(group))),\
+ $(call gb_Output_error,gb_Helper_register_executables: already registered: $(target)))))
+$(if $(filter-out $(words $(2)),$(words $(sort $(2)))),\
+ $(call gb_Output_error,gb_Helper_register_executables: contains duplicates: $(2)))
+
+gb_Executable_$(1) += $(2)
+
+endef
+
+# $(call gb_Helper_register_executables,layer,exes)
+define gb_Helper_register_executables
+ifeq ($$(filter $(1),$$(gb_Executable_VALIDGROUPS_NOTINSTALLED)),)
+$$(eval $$(call gb_Output_error,$(1) is not a valid group for executables that are not installed. Valid groups are: $$(gb_Executable_VALIDGROUPS_NOTINSTALLED). Use gb_Helper_register_executables_for_install for installed executables.))
+endif
+$(call gb_Helper__register_executables,$(1),$(2))
+
+endef
+
+# $(call gb_Helper_register_executables_for_install,layer,installmodule,exes)
+define gb_Helper_register_executables_for_install
+$(if $(3),,$(call gb_Output_error,gb_Helper_register_executables_for_install: no executables - need 3 parameters))
+ifeq ($$(filter $(1),$$(gb_Executable_VALIDGROUPS_INSTALLED)),)
+$$(eval $$(call gb_Output_error,$(1) is not a valid group for installed executables. Valid groups are: $$(gb_Executable_VALIDGROUPS_INSTALLED). Use gb_Helper_register_executables for executables that are not installed.))
+endif
+$(call gb_Helper__register_executables,$(1),$(3))
+
+gb_Executable_MODULE_$(2) += $(3)
+
+endef
+
+define gb_Helper__register_libraries
+$(foreach group,$(gb_Library_VALIDGROUPS),\
+ $(foreach target,$(2),\
+ $(if $(filter $(target),$(gb_Library_$(group))),\
+ $(call gb_Output_error,gb_Helper_register_libraries: already registered: $(target)))))
+$(if $(filter-out $(words $(2)),$(words $(sort $(2)))),\
+ $(call gb_Output_error,gb_Helper_register_libraries: contains duplicates: $(2)))
+
+gb_Library_$(1) += $(2)
+
+endef
+
+# $(call gb_Helper_register_libraries,layer,libs)
+define gb_Helper_register_libraries
+ifeq ($$(filter $(1),$$(gb_Library_VALIDGROUPS_NOTINSTALLED)),)
+$$(eval $$(call gb_Output_error,$(1) is not a valid group for libraries that are not installed. Valid groups are: $$(gb_Library_VALIDGROUPS_NOTINSTALLED). Use gb_Helper_register_libraries_for_install for installed libraries.))
+endif
+$(call gb_Helper__register_libraries,$(1),$(2))
+
+endef
+
+# the first argument is the group, which sets rpaths etc.
+# the second argument is the install module, which describes in which distro package/msi a lib should show up
+# UGLY: for versioned libraries "sdk" module is hard-coded for now
+# $(call gb_Helper_register_libraries_for_install,layer,installmodule,libs)
+define gb_Helper_register_libraries_for_install
+$(if $(3),,$(call gb_Output_error,gb_Helper_register_libraries_for_install: no libraries - need 3 parameters))
+ifeq ($$(filter $(1),$$(gb_Library_VALIDGROUPS_INSTALLED)),)
+$$(eval $$(call gb_Output_error,$(1) is not a valid group for installed libraries. Valid groups are: $$(gb_Library_VALIDGROUPS_INSTALLED). Use gb_Helper_register_libraries for libraries that are not installed.))
+endif
+$(call gb_Helper__register_libraries,$(1),$(3))
+
+gb_Library_MODULE_$(2) += $(filter-out $(gb_MERGEDLIBS),$(3))
+
+$(if $(filter UNOVERLIBS RTVERLIBS,$(1)),\
+ gb_SdkLinkLibrary_MODULE_sdk += $(3))
+
+endef
+
+# a plugin is a library, why can't be dynamically linked and must be dlopen'd, but must be linked static
+define gb_Helper_register_plugins_for_install
+$(call gb_Helper_register_libraries_for_install,$(1),$(2),$(3))
+gb_Library_KNOWNPLUGINS += $(3)
+
+endef
+
+define gb_Helper__register_jars
+$(foreach group,$(gb_Jar_VALIDGROUPS),\
+ $(foreach target,$(2),\
+ $(if $(filter $(target),$(gb_Jar_$(group))),\
+ $(call gb_Output_error,gb_Helper_register_jars: already registered: $(target)))))
+$(if $(filter-out $(words $(2)),$(words $(sort $(2)))),\
+ $(call gb_Output_error,gb_Helper_register_jars: contains duplicates: $(2)))
+
+gb_Jar_$(1) += $(2)
+
+endef
+
+# $(call gb_Helper_register_jars,layer,jars)
+define gb_Helper_register_jars
+ifeq ($$(filter $(1),$$(gb_Jar_VALIDGROUPS_NOTINSTALLED)),)
+$$(eval $$(call gb_Output_error,$(1) is not a valid group for jars that are not installed. Valid groups are: $$(gb_Jar_VALIDGROUPS_NOTINSTALLED). Use gb_Helper_register_jars_for_install for installed jars.))
+endif
+$(call gb_Helper__register_jars,$(1),$(2))
+
+endef
+
+# $(call gb_Helper_register_jars_for_install,layer,installmodule,jars)
+define gb_Helper_register_jars_for_install
+$(if $(3),,$(call gb_Output_error,gb_Helper_register_jars_for_install: no jars - need 3 parameters))
+ifeq ($$(filter $(1),$$(gb_Jar_VALIDGROUPS_INSTALLED)),)
+$$(eval $$(call gb_Output_error,$(1) is not a valid group for installed jars. Valid groups are: $$(gb_Jar_VALIDGROUPS_INSTALLED). Use gb_Helper_register_jars for jars that are not installed.))
+endif
+$(call gb_Helper__register_jars,$(1),$(3))
+
+gb_Jar_MODULE_$(2) += $(3)
+
+endef
+
+define gb_Helper__register_packages
+$(foreach target,$(1),\
+ $(if $(filter $(target),$(gb_Package_REGISTERED)),\
+ $(call gb_Output_error,gb_Helper_register_packages: already registered: $(target))))
+$(if $(filter-out $(words $(1)),$(words $(sort $(1)))),\
+ $(call gb_Output_error,gb_Helper_register_packages: contains duplicates: $(1)))
+
+gb_Package_REGISTERED += $(1)
+
+endef
+
+# $(call gb_Helper_register_packages,packages)
+define gb_Helper_register_packages
+$(call gb_Helper__register_packages,$(1))
+
+endef
+
+# $(call gb_Helper_register_packages_for_install,installmodule,packages)
+define gb_Helper_register_packages_for_install
+$(if $(2),,$(call gb_Output_error,gb_Helper_register_packages_for_install: no packages - need 2 parameters))
+$(call gb_Helper__register_packages,$(2))
+
+gb_Package_MODULE_$(1) += $(2)
+
+endef
+
+define gb_Helper_register_mos
+gb_AllLangMoTarget_REGISTERED += $(1)
+
+endef
+
+# TODO: this should be extended to handle auto-installation.
+define gb_Helper_register_uiconfigs
+gb_UIConfig_REGISTERED += $(1)
+
+endef
+
+define gb_Helper_get_imagelists
+$(foreach ui,$(gb_UIConfig_REGISTERED),$(call gb_UIConfig_get_imagelist_target,$(ui)))
+endef
+
+# call gb_Helper_replace_if_different_and_touch,source,target,optional-touch-reference-file
+define gb_Helper_replace_if_different_and_touch
+if cmp -s $(1) $(2); then rm $(1); \
+else mv $(1) $(2) $(if $(3),&& touch -r $(3) $(2)); \
+fi
+endef
+
+# call gb_Helper_copy_if_different_and_touch,source,target,optional-touch-reference-file
+define gb_Helper_copy_if_different_and_touch
+if ! cmp -s $(1) $(2); then \
+ cp $(1) $(2) $(if $(3),&& touch -r $(3) $(2)); \
+fi
+endef
+
+define gb_Helper_define_if_set
+$(foreach def,$(1),$(if $(filter TRUE YES,$($(def))),-D$(def)))
+endef
+
+define gb_Helper_execute
+$(call gb_Executable_get_command,$(firstword $(1))) $(wordlist 2,$(words $(1)),$(1))
+endef
+
+# define gb_Helper_install registered-target target-to-install target-from-workdir
+define gb_Helper_install
+$(1) :| $(2)
+$(2) : $(3) | $(dir $(2)).dir
+$(call gb_Deliver_add_deliverable,$(2),$(3),$(2))
+endef
+
+# use if the installed target is the final target
+define gb_Helper_install_final
+$(1) : $(2) | $(dir $(1)).dir
+$(call gb_Deliver_add_deliverable,$(1),$(2),$(1))
+endef
+
+# call gb_Helper_optional,build_type,if-true,if-false
+define gb_Helper_optional
+$(if $(filter $(1),$(BUILD_TYPE)),$(2),$(3))
+endef
+
+# call gb_Helper_optionals_or,build_types,if-true,if-false
+define gb_Helper_optionals_or
+$(call gb_Helper_optional,$(1),$(2),$(3))
+endef
+
+# call gb_Helper_optionals_and,build_types,if-true,if-false
+define gb_Helper_optionals_and
+$(if $(strip $(filter-out $(filter $(1),$(BUILD_TYPE)),$(1))),$(3),$(2))
+endef
+
+ifeq ($(WITH_LOCALES),)
+define gb_Helper_optional_locale
+$(2)
+endef
+else
+define gb_Helper_optional_locale
+$(if $(filter $(1) $(1)_%,$(WITH_LOCALES)),$(2))
+endef
+endif
+
+define gb_Helper_print_on_error
+$(if $(gb_QUIET_EXTERNAL), \
+ $(if $(2), \
+ ( ( $(1) ) > $(2) 2>&1 || ( cat $(2) && false ) ), \
+ ( TEMPFILE=$(shell $(gb_MKTEMP)) && ( $(1) ) > $$TEMPFILE 2>&1 \
+ && rm $$TEMPFILE \
+ || ( cat $$TEMPFILE && rm $$TEMPFILE && false ) )), \
+ ( $(1) ))
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/InstallModule.mk b/solenv/gbuild/InstallModule.mk
new file mode 100644
index 000000000..ba009e030
--- /dev/null
+++ b/solenv/gbuild/InstallModule.mk
@@ -0,0 +1,88 @@
+# -*- 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/.
+#
+
+# InstallModule class
+
+$(dir $(call gb_InstallModule_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_InstallModule_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),IMO,3)
+ $(call gb_Trace_MakeMark,$*,IMO)
+ $(if $(INSTALL_MODULE_DEFINED),,$(call gb_Output_error,Something depends on install module $* which does not exist.))
+ touch $@
+
+$(call gb_InstallModule_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),IMO,3)
+ rm -f $(call gb_InstallModule_get_target,$*)
+
+define gb_InstallModule_InstallModule
+$(call gb_InstallModuleTarget_InstallModuleTarget,$(1))
+
+$(call gb_InstallModule_get_target,$(1)) : INSTALL_MODULE_DEFINED := $(true)
+$(call gb_InstallModule_get_target,$(1)) : $(call gb_InstallModuleTarget_get_target,$(1))
+$(call gb_InstallModule_get_target,$(1)) :| $(dir $(call gb_InstallModule_get_target,$(1))).dir
+$(call gb_InstallModule_get_clean_target,$(1)) : $(call gb_InstallModuleTarget_get_clean_target,$(1))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_InstallModule_get_target,$(1)),$(call gb_InstallModule_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),InstallModule)
+
+endef
+
+define gb_InstallModule_use_auto_install_libs
+$(call gb_InstallModuleTarget_use_auto_install_libs,$(1),$(2))
+
+endef
+
+define gb_InstallModule_add_defs
+$(call gb_InstallModuleTarget_add_defs,$(1),$(2))
+
+endef
+
+define gb_InstallModule_define_if_set
+$(call gb_InstallModuleTarget_define_if_set,$(1),$(2))
+
+endef
+
+define gb_InstallModule_define_value_if_set
+$(call gb_InstallModuleTarget_define_value_if_set,$(1),$(2))
+
+endef
+
+define gb_InstallModule_add_scpfile
+$(call gb_InstallModuleTarget_add_scpfile,$(1),$(2))
+
+endef
+
+define gb_InstallModule_add_scpfiles
+$(call gb_InstallModuleTarget_add_scpfiles,$(1),$(2))
+
+endef
+
+define gb_InstallModule_add_localized_scpfile
+$(call gb_InstallModuleTarget_add_localized_scpfile,$(1),$(2))
+
+endef
+
+define gb_InstallModule_add_localized_scpfiles
+$(call gb_InstallModuleTarget_add_localized_scpfiles,$(1),$(2))
+
+endef
+
+define gb_InstallModule_add_template
+$(call gb_InstallModuleTarget_add_template,$(1),$(2))
+
+endef
+
+define gb_InstallModule_add_templates
+$(call gb_InstallModuleTarget_add_templates,$(1),$(2))
+
+endef
+
+# vim: set shiftwidth=4 tabstop=4 noexpandtab:
diff --git a/solenv/gbuild/InstallModuleTarget.mk b/solenv/gbuild/InstallModuleTarget.mk
new file mode 100644
index 000000000..3ae5f67e0
--- /dev/null
+++ b/solenv/gbuild/InstallModuleTarget.mk
@@ -0,0 +1,312 @@
+# -*- 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/.
+#
+
+# Overview of dependencies and tasks of InstallModuleTarget
+# target task depends on
+
+# ScpTemplateTarget class
+
+gb_ScpTemplateTarget_TARGET := $(SRCDIR)/scp2/source/templates/modules.pl
+gb_ScpTemplateTarget_COMMAND := $(PERL) -w $(gb_ScpTemplateTarget_TARGET)
+
+gb_ScpTemplateTarget_LANGS := $(sort $(ALL_LANGS))
+
+# Pass first arg if make is running in silent mode, second arg otherwise
+define gb_ScpTemplateTarget__if_silent
+$(if $(findstring s,$(filter-out --%,$(MAKEFLAGS))),$(1),$(2))
+endef
+
+gb_ScpTemplateTarget_get_source = $(SRCDIR)/$(1).sct
+
+define gb_ScpTemplateTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ export COMPLETELANGISO_VAR='$(gb_ScpTemplateTarget_LANGS)' && \
+ $(gb_ScpTemplateTarget_COMMAND) \
+ $(call gb_ScpTemplateTarget__if_silent,,-verbose) \
+ -i $(SCP_TEMPLATE) \
+ -o $(1) \
+)
+endef
+
+$(dir $(call gb_ScpTemplateTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+# depend on configure output to rebuild everything
+$(call gb_ScpTemplateTarget_get_target,%) : \
+ $(gb_ScpTemplateTarget_TARGET) $(BUILDDIR)/config_$(gb_Side).mk
+ $(call gb_Output_announce,$*,$(true),SCT,1)
+ $(call gb_Trace_StartRange,$*,SCT)
+ $(call gb_ScpTemplateTarget__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,SCT)
+
+.PHONY : $(call gb_ScpTemplateTarget_get_clean_target,%)
+$(call gb_ScpTemplateTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),SCT,1)
+ rm -f $(call gb_ScpTemplateTarget_get_target,$*)
+
+# gb_ScpTemplateTarget_ScpTemplateTarget(<target>)
+define gb_ScpTemplateTarget_ScpTemplateTarget
+$(call gb_ScpTemplateTarget_get_target,$(1)) : $(call gb_ScpTemplateTarget_get_source,$(1))
+$(call gb_ScpTemplateTarget_get_target,$(1)) :| $(dir $(call gb_ScpTemplateTarget_get_target,$(1))).dir
+$(call gb_ScpTemplateTarget_get_target,$(1)) : SCP_TEMPLATE := $(call gb_ScpTemplateTarget_get_source,$(1))
+
+endef
+
+# ScpPreprocessTarget class
+
+gb_ScpPreprocessTarget_DEPS := $(call gb_Executable_get_runtime_dependencies,cpp)
+gb_ScpPreprocessTarget_COMMAND := $(call gb_Executable_get_command,cpp)
+
+gb_ScpPreprocessTarget_get_source = $(SRCDIR)/$(1).scp
+
+define gb_ScpPreprocessTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ $(gb_ScpPreprocessTarget_COMMAND) \
+ -+ -P \
+ $(SCPDEFS) $(SCP_DEFS) \
+ $(SCP_INCLUDE) $(SCP_TEMPLATE_INCLUDE) \
+ $(if $(ENABLE_JAVA),-DENABLE_JAVA) \
+ $(SCP_SOURCE) > $(1) \
+)
+endef
+
+$(dir $(call gb_ScpPreprocessTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+# depend on configure output to rebuild everything
+$(call gb_ScpPreprocessTarget_get_target,%) : \
+ $(gb_ScpPreprocessTarget_DEPS) $(BUILDDIR)/config_$(gb_Side).mk
+ $(call gb_Output_announce,$*,$(true),SPP,2)
+ $(call gb_Trace_StartRange,$*,SPP)
+ $(call gb_ScpPreprocessTarget__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,SPP)
+
+.PHONY : $(call gb_ScpPreprocessTarget_get_clean_target,%)
+$(call gb_ScpPreprocessTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),SPP,2)
+ rm -f $(call gb_ScpPreprocessTarget_get_target,$*)
+
+# gb_ScpPreprocessTarget_ScpPreprocessTarget(<target>)
+define gb_ScpPreprocessTarget_ScpPreprocessTarget
+$(call gb_ScpPreprocessTarget_get_target,$(1)) : SCP_SOURCE := $(call gb_ScpPreprocessTarget_get_source,$(1))
+$(call gb_ScpPreprocessTarget_get_target,$(1)) : $(call gb_ScpPreprocessTarget_get_source,$(1))
+$(call gb_ScpPreprocessTarget_get_target,$(1)) :| $(dir $(call gb_ScpPreprocessTarget_get_target,$(1))).dir
+
+endef
+
+# ScpMergeTarget class
+
+gb_ScpMergeTarget_get_source = $(SRCDIR)/$(1).ulf
+
+$(dir $(call gb_ScpMergeTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_ScpMergeTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(eval $(call gb_CustomTarget_ulfex_rule,\
+ $(call gb_ScpMergeTarget_get_target,%),\
+ $(call gb_ScpMergeTarget_get_source,%),\
+ $$(SCP_POFILES)))
+
+.PHONY : $(call gb_ScpMergeTarget_get_clean_target,%)
+$(call gb_ScpMergeTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),SUM,1)
+ rm -f $(call gb_ScpMergeTarget_get_target,$*)
+
+# gb_ScpMergeTarget_ScpMergeTarget(<target>)
+define gb_ScpMergeTarget_ScpMergeTarget
+$(call gb_ScpMergeTarget_get_target,$(1)) :| $(dir $(call gb_ScpMergeTarget_get_target,$(1))).dir
+$(call gb_ScpMergeTarget_get_target,$(1)) : \
+ SCP_POFILES := $(foreach lang,$(gb_TRANS_LANGS),$(gb_POLOCATION)/$(lang)/$(patsubst %/,%,$(dir $(1))).po)
+$(call gb_ScpMergeTarget_get_target,$(1)) : \
+ $(foreach lang,$(gb_TRANS_LANGS),$(gb_POLOCATION)/$(lang)/$(patsubst %/,%,$(dir $(1))).po)
+$(foreach lang,$(gb_TRANS_LANGS),$(gb_POLOCATION)/$(lang)/$(patsubst %/,%,$(dir $(1))).po) :
+
+endef
+
+# ScpTarget class
+
+gb_ScpTarget_TARGET := $(SRCDIR)/solenv/bin/pre2par.pl
+gb_ScpTarget_COMMAND := $(PERL) $(gb_ScpTarget_TARGET)
+
+define gb_ScpTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ $(gb_ScpTarget_COMMAND) -l $(SCP_ULF) -s $(SCP_SOURCE) -o $(1) \
+)
+endef
+
+$(dir $(call gb_ScpTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_ScpTarget_get_target,%) : $(gb_ScpTarget_TARGET)
+ $(call gb_Output_announce,$*,$(true),SCP,2)
+ $(call gb_Trace_StartRange,$*,SCP)
+ $(call gb_ScpTarget__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,SCP)
+
+$(call gb_ScpTarget_get_external_target,%) :
+ touch $@
+
+.PHONY : $(call gb_ScpTarget_get_clean_target,%)
+$(call gb_ScpTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),SCP,2)
+ rm -f \
+ $(call gb_ScpTarget_get_target,$*) \
+ $(call gb_ScpTarget_get_external_target,$*)
+
+# gb_ScpTarget_ScpTarget(<target>)
+define gb_ScpTarget_ScpTarget
+$(call gb_ScpPreprocessTarget_ScpPreprocessTarget,$(1))
+
+$(call gb_ScpTarget_get_target,$(1)) : $(call gb_ScpPreprocessTarget_get_target,$(1))
+$(call gb_ScpTarget_get_target,$(1)) : $(call gb_ScpTarget_get_external_target,$(1))
+$(call gb_ScpTarget_get_external_target,$(1)) :| $(dir $(call gb_ScpTarget_get_target,$(1))).dir
+$(call gb_ScpPreprocessTarget_get_target,$(1)) : $(call gb_ScpTarget_get_external_target,$(1))
+$(call gb_ScpTarget_get_clean_target,$(1)) : $(call gb_ScpPreprocessTarget_get_clean_target,$(1))
+$(call gb_ScpTarget_get_target,$(1)) : SCP_SOURCE := $(call gb_ScpPreprocessTarget_get_target,$(1))
+$(call gb_ScpTarget_get_target,$(1)) : SCP_ULF := $(gb_Helper_PHONY)
+
+endef
+
+define gb_ScpTarget_set_localized
+ifneq ($(gb_WITH_LANG),)
+$(call gb_ScpMergeTarget_ScpMergeTarget,$(1))
+$(call gb_ScpTarget_get_target,$(1)) : SCP_ULF := $(call gb_ScpMergeTarget_get_target,$(1))
+$(call gb_ScpTarget_get_target,$(1)) : $(call gb_ScpMergeTarget_get_target,$(1))
+$(call gb_ScpTarget_get_clean_target,$(1)) : $(call gb_ScpMergeTarget_get_clean_target,$(1))
+else
+$(call gb_ScpTarget_get_target,$(1)) : SCP_ULF := $(call gb_ScpMergeTarget_get_source,$(1))
+$(call gb_ScpTarget_get_target,$(1)) : $(call gb_ScpMergeTarget_get_source,$(1))
+endif
+
+endef
+
+# InstallModuleTarget class
+
+# platform:
+# gb_InstallModuleTarget_InstallModuleTarget_platform
+
+define gb_InstallModuleTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ rm -f $(1) \
+ $(foreach scpfile,$(SCP_FILES),&& echo $(scpfile) >> $(1)) \
+)
+endef
+
+$(dir $(call gb_InstallModuleTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_InstallModuleTarget_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),INM,3)
+ $(call gb_Trace_StartRange,$*,INM)
+ $(call gb_InstallModuleTarget__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,INM)
+
+$(call gb_InstallModuleTarget_get_external_target,%) :
+ touch $@
+
+.PHONY : $(call gb_InstallModuleTarget_get_clean_target,%)
+$(call gb_InstallModuleTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),INM,3)
+ rm -rf \
+ $(call gb_InstallModuleTarget_get_target,$*) \
+ $(call gb_InstallModuleTarget_get_external_target,$*)
+
+define gb_InstallModuleTarget_InstallModuleTarget
+$(call gb_InstallModuleTarget_get_target,$(1)) : \
+ $(call gb_InstallModuleTarget_get_external_target,$(1))
+$(call gb_InstallModuleTarget_get_external_target,$(1)) :| \
+ $(dir $(call gb_InstallModuleTarget_get_target,$(1))).dir
+
+$(call gb_InstallModuleTarget_get_target,$(1)) : SCP_FILES :=
+$(call gb_InstallModuleTarget_get_target,$(1)) : SCP_DEFS :=
+$(call gb_InstallModuleTarget_get_target,$(1)) : SCP_INCLUDE := -I$(SRCDIR)/scp2/inc -I$(WORKDIR) -I$(BUILDDIR)/config_$(gb_Side)
+$(call gb_InstallModuleTarget_get_target,$(1)) : SCP_TEMPLATE_INCLUDE :=
+$(call gb_InstallModuleTarget_use_custom_headers,$(1),scp2/macros)
+
+$(call gb_InstallModuleTarget_InstallModuleTarget_platform,$(1))
+
+endef
+
+define gb_InstallModuleTarget_add_defs
+$(call gb_InstallModuleTarget_get_target,$(1)) : SCP_DEFS += $(2)
+
+endef
+
+define gb_InstallModuleTarget_define_if_set
+$(call gb_InstallModuleTarget_add_defs,$(1),\
+ $(foreach def,$(2),$(if $(filter TRUE YES,$($(def))),-D$(def))) \
+)
+
+endef
+
+define gb_InstallModuleTarget_define_value_if_set
+$(call gb_InstallModuleTarget_add_defs,$(1),\
+ $(foreach def,$(2),$(if $($(def)),-D$(def)=\""$($(def))"\")) \
+)
+
+endef
+
+define gb_InstallModuleTarget_use_auto_install_libs
+$(call gb_InstallModuleTarget_get_external_target,$(1)) : $(foreach ai,$(2),$(call gb_AutoInstall_get_target,$(ai)))
+
+endef
+
+define gb_InstallModuleTarget_use_custom_header
+$(call gb_InstallModuleTarget_get_external_target,$(1)) : $(call gb_CustomTarget_get_target,$(2))
+$(call gb_InstallModuleTarget_get_target,$(1)) : SCP_INCLUDE += -I$(call gb_CustomTarget_get_workdir,$(2)) \
+
+endef
+
+define gb_InstallModuleTarget_use_custom_headers
+$(foreach customtarget,$(2),$(call gb_InstallModuleTarget_use_custom_header,$(1),$(customtarget)))
+
+endef
+
+define gb_InstallModuleTarget_add_scpfile
+$(call gb_ScpTarget_ScpTarget,$(2))
+$(call gb_InstallModuleTarget_get_target,$(1)) : $(call gb_ScpTarget_get_target,$(2))
+$(call gb_InstallModuleTarget_get_clean_target,$(1)) : $(call gb_ScpTarget_get_clean_target,$(2))
+$(call gb_InstallModuleTarget_get_target,$(1)) : SCP_FILES += $(call gb_ScpTarget_get_target,$(2))
+$(call gb_ScpTarget_get_external_target,$(2)) : $(call gb_InstallModuleTarget_get_external_target,$(1))
+
+endef
+
+define gb_InstallModuleTarget_add_scpfiles
+$(foreach scpfile,$(2),$(call gb_InstallModuleTarget_add_scpfile,$(1),$(scpfile)))
+
+endef
+
+define gb_InstallModuleTarget_add_localized_scpfile
+$(call gb_InstallModuleTarget_add_scpfile,$(1),$(2))
+$(call gb_ScpTarget_set_localized,$(2))
+
+endef
+
+define gb_InstallModuleTarget_add_localized_scpfiles
+$(foreach scpfile,$(2),$(call gb_InstallModuleTarget_add_localized_scpfile,$(1),$(scpfile)))
+
+endef
+
+define gb_InstallModuleTarget_add_template
+$(call gb_ScpTemplateTarget_ScpTemplateTarget,$(2))
+$(call gb_InstallModuleTarget_get_external_target,$(1)) : $(call gb_ScpTemplateTarget_get_target,$(2))
+$(call gb_InstallModuleTarget_get_clean_target,$(1)) : $(call gb_ScpTemplateTarget_get_clean_target,$(2))
+$(call gb_InstallModuleTarget_get_target,$(1)) : \
+ SCP_TEMPLATE_INCLUDE := $$(sort $$(SCP_TEMPLATE_INCLUDE) -I$(call gb_ScpTemplateTarget_get_dir,$(2)))
+
+endef
+
+define gb_InstallModuleTarget_add_templates
+$(foreach template,$(2),$(call gb_InstallModuleTarget_add_template,$(1),$(template)))
+
+endef
+
+# vim: set shiftwidth=4 tabstop=4 noexpandtab:
diff --git a/solenv/gbuild/InstallScript.mk b/solenv/gbuild/InstallScript.mk
new file mode 100644
index 000000000..096b3f4e5
--- /dev/null
+++ b/solenv/gbuild/InstallScript.mk
@@ -0,0 +1,84 @@
+# -*- 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/.
+#
+
+# InstallScript class
+
+gb_InstallScript_TARGET := $(SRCDIR)/solenv/bin/par2script.pl
+gb_InstallScript_COMMAND := $(PERL) $(gb_InstallScript_TARGET)
+
+gb_InstallScript__make_arglist = $(subst $(WHITESPACE),$(COMMA),$(strip $(1)))
+
+define gb_InstallScript__get_files
+$(notdir $(shell cat $(foreach module,$(1),$(call gb_InstallModule_get_filelist,$(module)))))
+endef
+
+define gb_InstallScript__get_dirs
+$(sort $(dir $(shell cat $(foreach module,$(1),$(call gb_InstallModule_get_filelist,$(module))))))
+endef
+
+# Pass first arg if make is running in silent mode, second arg otherwise
+define gb_InstallScript__if_silent
+$(if $(findstring s,$(filter-out --%,$(MAKEFLAGS))),$(1),$(2))
+endef
+
+define gb_InstallScript__command
+$(call gb_Helper_abbreviate_dirs,\
+ RESPONSEFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,\
+ $(call gb_InstallScript__make_arglist,\
+ $(call gb_InstallScript__get_files,$(SCP_MODULES))) \
+ ) && \
+ $(gb_InstallScript_COMMAND) \
+ $(call gb_InstallScript__if_silent,-q) \
+ -i $(call gb_InstallScript__make_arglist,$(call gb_InstallScript__get_dirs,$(SCP_MODULES))) \
+ -o $(1) \
+ @@$${RESPONSEFILE} && \
+ rm -f $${RESPONSEFILE} \
+)
+endef
+
+$(dir $(call gb_InstallScript_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_InstallScript_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_InstallScript_get_target,%) : $(gb_InstallScript_TARGET)
+ $(call gb_Output_announce,$*,$(true),INS,4)
+ $(call gb_Trace_StartRange,$*,INS)
+ $(call gb_InstallScript__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,INS)
+
+.PHONY : $(call gb_InstallScript_get_clean_target,%)
+$(call gb_InstallScript_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),INS,4)
+ rm -f $(call gb_InstallScript_get_target,$*)
+
+# gb_InstallScript_InstallScript(<target>)
+define gb_InstallScript_InstallScript
+$(call gb_InstallScript_get_target,$(1)) :| $(dir $(call gb_InstallScript_get_target,$(1))).dir
+$(call gb_InstallScript_get_target,$(1)) : SCP_MODULES :=
+
+$$(eval $$(call gb_Module_register_target,$(call gb_InstallScript_get_target,$(1)),$(call gb_InstallScript_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),InstallScript)
+
+endef
+
+define gb_InstallScript_use_module
+$(call gb_InstallScript_get_target,$(1)) : $(call gb_InstallModule_get_target,$(2))
+$(call gb_InstallScript_get_clean_target,$(1)) : $(call gb_InstallModule_get_clean_target,$(2))
+$(call gb_InstallScript_get_target,$(1)) : SCP_MODULES += $(2)
+
+endef
+
+define gb_InstallScript_use_modules
+$(foreach module,$(2),$(call gb_InstallScript_use_module,$(1),$(module)))
+
+endef
+
+# vim: set shiftwidth=4 tabstop=4 noexpandtab:
diff --git a/solenv/gbuild/InternalUnoApi.mk b/solenv/gbuild/InternalUnoApi.mk
new file mode 100644
index 000000000..dae0cb503
--- /dev/null
+++ b/solenv/gbuild/InternalUnoApi.mk
@@ -0,0 +1,82 @@
+# -*- 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/.
+#
+
+$(dir $(call gb_InternalUnoApi_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $(@)))
+
+$(dir $(call gb_InternalUnoApi_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $(@)))
+
+$(call gb_InternalUnoApi_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),UNI,5) \
+ $(call gb_Trace_MakeMark,$*,UNI)
+ touch $@
+
+.PHONY : $(call gb_InternalUnoApi_get_clean_target,%)
+$(call gb_InternalUnoApi_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),UNI,5) \
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_InternalUnoApi_get_target,$*))
+
+define gb_InternalUnoApi_InternalUnoApi
+$(call gb_UnoApiTarget_UnoApiTarget,$(1),$(2))
+$(call gb_UnoApiHeadersTarget_UnoApiHeadersTarget,$(1))
+
+$(call gb_InternalUnoApi_get_target,$(1)) : $(call gb_UnoApiTarget_get_target,$(1))
+$(call gb_InternalUnoApi_get_target,$(1)) :| $(dir $(call gb_InternalUnoApi_get_target,$(1))).dir
+$(call gb_InternalUnoApi_get_clean_target,$(1)) : $(call gb_UnoApiHeadersTarget_get_clean_target,$(1))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_InternalUnoApi_get_target,$(1)),$(call gb_InternalUnoApi_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),InternalUnoApi)
+
+endef
+
+define gb_InternalUnoApi_add_idlfile
+$(call gb_UnoApiTarget_add_idlfile,$(1),$(2),$(3))
+
+endef
+
+define gb_InternalUnoApi_add_idlfiles
+$(call gb_UnoApiTarget_add_idlfiles,$(1),$(2),$(3))
+
+endef
+
+define gb_InternalUnoApi__use_api
+$(call gb_UnoApiTarget_use_api,$(1),$(2))
+$(call gb_UnoApiHeadersTarget_use_api,$(1),$(2))
+$(call gb_InternalUnoApi_get_target,$(1)) : $(call gb_UnoApiTarget_get_target,$(2))
+
+endef
+
+define gb_InternalUnoApi_use_api
+$(foreach rdb,$(2),$(call gb_InternalUnoApi__use_api,$(1),$(rdb)))
+
+endef
+
+# Express that the rdb $(2) depends on rdb $(3).
+#
+# This information is already available in the UnoApiTarget definition
+# for $(2), but this may not be loaded if we are building from a
+# different module. Thus, this is a necessary hack to make generation of
+# headers on demand work.
+#
+# I suppose it would be possible to store the list of required rdbs for
+# a rdb to a file and then load it when headers' generation is requested,
+# but it feels like overkill...
+define gb_InternalUnoApi_define_api_dependency
+$(call gb_UnoApiHeadersTarget_use_api,$(2),$(3))
+
+endef
+
+define gb_InternalUnoApi_define_api_dependencies
+$(foreach dep,$(3),$(call gb_InternalUnoApi_define_api_dependency,$(1),$(2),$(dep)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/Jar.mk b/solenv/gbuild/Jar.mk
new file mode 100644
index 000000000..d1a84ceba
--- /dev/null
+++ b/solenv/gbuild/Jar.mk
@@ -0,0 +1,287 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# Jar class
+
+gb_Jar_JARCOMMAND := jar
+
+gb_Jar_LAYER_DIRS := \
+ URE:$(INSTROOT)/$(LIBO_URE_SHARE_JAVA_FOLDER) \
+ OOO:$(INSTROOT)/$(LIBO_SHARE_JAVA_FOLDER) \
+ OXT:$(WORKDIR)/Jar \
+ NONE:$(WORKDIR)/Jar \
+
+
+# location of files going to be packed into .jar file
+define gb_Jar_get_workdir
+$(call gb_JavaClassSet_get_classdir,$(call gb_Jar_get_classsetname,$(1)))
+endef
+
+# location of manifest file in workdir
+define gb_Jar_get_manifest_target
+$(call gb_Jar_get_workdir,$(1))/META-INF/MANIFEST.MF
+endef
+
+gb_Jar__get_layer = $(strip $(foreach group,$(gb_Jar_VALIDGROUPS),$(if $(filter $(1),$(gb_Jar_$(group))),$(group))))
+gb_Jar__get_dir_for_layer = $(patsubst $(1):%,%,$(filter $(1):%,$(gb_Jar_LAYER_DIRS)))
+gb_Jar_get_install_target = $(call gb_Jar__get_dir_for_layer,$(call gb_Jar__get_layer,$(1)))/$(1).jar
+
+# creates classset and META-INF folders if they don't exist
+# adds manifest version, class path, solarversion and content from sources to manifest file
+# creates the target folder of the jar file if it doesn't exist
+# creates the jar file
+# jar program does not remove the target in case of error, so rm it manually
+# XXX: PACKAGEDIRS need special treatment, because sometimes we need to
+# add into the jar another class hierarchy created outside of our class
+# set (e.g., by javamaker). Because jar does not allow two same root dirs
+# when creating the archive, we work around this deficiency by creating
+# the archive with the main class hierarchy and then updating it from
+# the other one(s), which seems to work .-)
+define gb_Jar__command
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(call gb_Jar_get_workdir,$(1))/META-INF && \
+ echo Manifest-Version: 1.0 > $(call gb_Jar_get_manifest_target,$(1)) && \
+ $(if $(JARCLASSPATH),$(SRCDIR)/solenv/bin/write_classpath.sh "$(call gb_Jar_get_manifest_target,$(1))" $(strip $(JARCLASSPATH)) &&) \
+ echo "Solar-Version: $(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" >> $(call gb_Jar_get_manifest_target,$(1)) && \
+ $(if $(MANIFEST),cat $(MANIFEST) >> $(call gb_Jar_get_manifest_target,$(1)) &&) \
+ mkdir -p $(dir $(2)) && cd $(call gb_Jar_get_workdir,$(1)) && \
+ $(gb_Jar_JARCOMMAND) cfm $(2) $(call gb_Jar_get_manifest_target,$(1)) \
+ META-INF $(PACKAGEROOTS) $(PACKAGEFILES) \
+ $(foreach root,$(PACKAGEDIRS),&& cd $(dir $(root)) && $(gb_Jar_JARCOMMAND) uf $(2) $(notdir $(root))) \
+ || (rm -f $(2); false) )
+endef
+
+# clean target reuses clean target of ClassSet
+.PHONY : $(call gb_Jar_get_clean_target,%)
+$(call gb_Jar_get_clean_target,%) : $(call gb_JavaClassSet_get_clean_target,$(call gb_Jar_get_classsetname,%))
+ $(call gb_Output_announce,$*,$(false),JAR,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_Jar_get_target,$*))
+
+# the workdir target is created by cd'ing to the target directory and adding/updating the files
+
+# rule for creating the jar file using the command defined above
+$(WORKDIR)/Jar/%.jar :
+ $(call gb_Output_announce,$*,$(true),JAR,3)
+ $(call gb_Trace_StartRange,$*,JAR)
+ $(call gb_Jar__command,$*,$@)
+ $(call gb_Trace_EndRange,$*,JAR)
+
+# call gb_Jar__make_installed_rule,jar
+define gb_Jar__make_installed_rule
+$(call gb_Jar_get_target,$(1)) :
+ $$(call gb_Jar__command,$(1),$(call gb_Jar_get_target,$(1)))
+
+endef
+
+# resets scoped variables (see explanations where they are set)
+# creates a class set and a dependency to it
+# registers target and clean target
+# adds jar files to DeliverLogTarget
+# call gb_Jar_Jar,jarname,java9modulename
+define gb_Jar_Jar
+ifeq (,$$(findstring $(1),$$(gb_Jar_KNOWN)))
+$$(eval $$(call gb_Output_info,Currently known jars are: $(sort $(gb_Jar_KNOWN)),ALL))
+$$(eval $$(call gb_Output_error,Jar $(1) must be registered in Repository.mk or RepositoryExternal.mk))
+endif
+$(call gb_Jar_get_target,$(1)) : MANIFEST :=
+$(call gb_Jar_get_target,$(1)) : JARCLASSPATH :=
+$(call gb_Jar_get_target,$(1)) : PACKAGEROOTS :=
+$(call gb_Jar_get_target,$(1)) : PACKAGEDIRS :=
+$(call gb_Jar_get_target,$(1)) : PACKAGEFILES :=
+$(call gb_Jar_get_target,$(1)) : \
+ $(call gb_JavaClassSet_get_target,$(call gb_Jar_get_classsetname,$(1)))
+$(call gb_JavaClassSet_JavaClassSet,$(call gb_Jar_get_classsetname,$(1)),$(2))
+$(eval $(call gb_Module_register_target,$(call gb_Jar_get_target,$(1)),$(call gb_Jar_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),Jar,$(call gb_Jar_get_target,$(1)))
+
+# installed jars need a rule to build!
+$(if $(findstring $(INSTDIR),$(call gb_Jar_get_target,$(1))),$(call gb_Jar__make_installed_rule,$(1)))
+
+endef
+
+# source files are forwarded to the ClassSet
+define gb_Jar_add_sourcefile
+$(call gb_JavaClassSet_add_sourcefile,$(call gb_Jar_get_classsetname,$(1)),$(2))
+
+endef
+
+define gb_Jar_add_sourcefile_java9
+$(call gb_JavaClassSet_add_sourcefile_java9,$(call gb_Jar_get_classsetname,$(1)),$(2))
+
+endef
+
+
+# PACKAGEROOTS is the list of all root folders created by the JavaClassSet to pack into the jar (without META-INF as this is added automatically)
+define gb_Jar_set_packageroot
+$(call gb_Jar_get_target,$(1)) : PACKAGEROOTS := $(2)
+
+endef
+#
+# PACKAGEDIRS is the list of additional root directories to pack into the jar
+define gb_Jar_add_packagedir
+$(call gb_Jar_get_target,$(1)) : PACKAGEDIRS += $(2)
+
+endef
+
+define gb_Jar_add_packagedirs
+$(foreach packagedir,$(2),$(call gb_Jar_add_packagedir,$(1),$(packagedir)))
+
+endef
+
+# PACKAGEFILES is the list of all root files to pack into the jar
+define gb_Jar_add_packagefile
+$(call gb_Jar_get_target,$(1)) : PACKAGEFILES += $(2)
+$(call gb_Jar_get_target,$(1)) : $(call gb_Jar_get_workdir,$(1))/$(strip $(2))
+$(call gb_Jar_get_workdir,$(1))/$(strip $(2)) : $(3) $(call gb_JavaClassSet_get_target,$(call gb_Jar_get_classsetname,$(1)))
+ mkdir -p $$(dir $$@)
+ cp -rf $(3) $$@
+
+endef
+
+# gb_Jar_add_packagefiles jar target-dir file(s)
+define gb_Jar_add_packagefiles
+$(foreach file,$(3),$(call gb_Jar_add_packagefile,$(1),$(if $(strip $(2)),$(strip $(2))/)$(notdir $(file)),$(file)))
+
+endef
+
+define gb_Jar_add_sourcefiles
+$(foreach sourcefile,$(2),$(call gb_Jar_add_sourcefile,$(1),$(sourcefile)))
+
+endef
+
+define gb_Jar_add_sourcefiles_java9
+$(foreach sourcefile,$(2),$(call gb_Jar_add_sourcefile_java9,$(1),$(sourcefile)))
+
+endef
+
+define gb_Jar_add_generated_sourcefile
+$(call gb_JavaClassSet_add_generated_sourcefile,$(call gb_Jar_get_classsetname,$(1)),$(2))
+
+endef
+
+define gb_Jar_add_generated_sourcefiles
+$(foreach sourcefile,$(2),$(call gb_Jar_add_generated_sourcefile,$(1),$(sourcefile)))
+
+endef
+
+# JARCLASSPATH is the class path that is written to the manifest of the jar
+define gb_Jar_add_manifest_classpath
+$(call gb_Jar_get_target,$(1)) : JARCLASSPATH += $(2)
+
+endef
+
+# provide a manifest template containing jar specific information to be written into the manifest
+# it will be appended to the standard content that is written in the build command explicitly
+# the jar file gets a dependency to the manifest template
+define gb_Jar_set_manifest
+$(call gb_Jar_get_target,$(1)) : MANIFEST := $(2)
+$(call gb_Jar_get_target,$(1)) : $(2)
+
+endef
+
+# URE jars are not added to manifest classpath:
+gb_Jar_default_jars := $(gb_Jar_URE)
+
+# remember: classpath is "inherited" to ClassSet
+define gb_Jar_use_jar
+$(call gb_JavaClassSet_use_jar,$(call gb_Jar_get_classsetname,$(1)),$(2))
+$(if $(filter-out $(gb_Jar_default_jars),$(2)),\
+ $(call gb_Jar_add_manifest_classpath,$(1),$(2).jar))
+
+endef
+
+define gb_Jar_use_system_jar
+$(call gb_JavaClassSet_use_system_jar,$(call gb_Jar_get_classsetname,$(1)),$(2))
+$(call gb_Jar_add_manifest_classpath,$(1),$(call gb_Helper_make_url,$(2)))
+
+endef
+
+# call gb_Jar_use_external_jar,jar,externaljarfullpath,manifestentry
+define gb_Jar_use_external_jar
+$(if $(3),,$(call gb_Output_error,gb_Jar_use_external_jar: manifest entry missing))
+$(call gb_JavaClassSet_use_system_jar,$(call gb_Jar_get_classsetname,$(1)),$(2))
+$(call gb_Jar_add_manifest_classpath,$(1),$(3))
+
+endef
+
+# specify jars with imported modules
+define gb_Jar_use_jars
+$(foreach jar,$(2),$(call gb_Jar_use_jar,$(1),$(jar)))
+
+endef
+
+define gb_Jar_use_system_jars
+$(foreach jar,$(2),$(call gb_Jar_use_system_jar,$(1),$(jar)))
+
+endef
+
+# this forwards to functions that must be defined in RepositoryExternal.mk.
+# $(eval $(call gb_Jar_use_external,jar,external))
+define gb_Jar_use_external
+$(if $(value gb_Jar__use_$(2)),\
+ $(call gb_Jar__use_$(2),$(1)),\
+ $(error gb_Jar_use_external: unknown external: $(2)))
+
+endef
+
+define gb_Jar_use_externals
+$(foreach external,$(2),$(call gb_Jar_use_external,$(1),$(external)))
+
+endef
+
+define gb_Jar_use_customtarget
+$(call gb_JavaClassSet_use_customtarget,$(call gb_Jar_get_classsetname,$(1)),$(2))
+
+endef
+
+define gb_Jar_use_customtargets
+$(foreach customtarget,$(2),$(call gb_Jar_use_customtarget,$(1),$(customtarget)))
+
+endef
+
+# Add a dependency on an ExternalProject.
+#
+# call gb_Jar_use_external_project,jar,externalproject
+define gb_Jar_use_external_project
+$(call gb_JavaClassSet_use_external_project,$(call gb_Jar_get_classsetname,$(1)),$(2))
+endef
+
+# possible directories for jar files containing UNO services
+gb_Jar_COMPONENTPREFIXES := \
+ OOO:vnd.sun.star.expand:\dLO_JAVA_DIR/ \
+ URE:vnd.sun.star.expand:\dURE_INTERNAL_JAVA_DIR/ \
+ OXT:./ \
+ NONE:$(call gb_Helper_make_url,$(WORKDIR)/Jar/) \
+
+# get component prefix from layer name ("OOO", "URE", "OXT", "NONE")
+gb_Jar__get_componentprefix = \
+ $(patsubst $(1):%,%,$(or \
+ $(filter $(1):%,$(gb_Jar_COMPONENTPREFIXES)), \
+ $(call gb_Output_error,no ComponentTarget native prefix for layer '$(1)')))
+
+# layer must be specified explicitly in this macro (different to libraries)
+define gb_Jar_set_componentfile
+$(call gb_ComponentTarget_ComponentTarget,$(2),$(call gb_Jar__get_componentprefix,$(3)),$(notdir $(call gb_Jar_get_target,$(1))),$(4))
+$(call gb_Jar_get_target,$(1)) : $(call gb_ComponentTarget_get_target,$(2))
+$(call gb_Jar_get_clean_target,$(1)) : $(call gb_ComponentTarget_get_clean_target,$(2))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/JavaClassSet.mk b/solenv/gbuild/JavaClassSet.mk
new file mode 100644
index 000000000..0e402db67
--- /dev/null
+++ b/solenv/gbuild/JavaClassSet.mk
@@ -0,0 +1,195 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+gb_JavaClassSet_JAVACCOMMAND = $(ICECREAM_RUN) $(JAVACOMPILER) $(JAVACFLAGS) \
+ -encoding utf8 \
+ --release $(1) \
+ $(if $(JAVA_CLASSPATH_NOT_SET),-Xlint:-options)
+
+gb_JavaClassSet_JAVACDEBUG :=
+
+# Enforces correct dependency order for possibly generated stuff:
+# generated sources, jars/classdirs etc.
+gb_JavaClassSet_get_preparation_target = $(WORKDIR)/JavaClassSet/$(1).prepared
+
+ifneq ($(gb_DEBUGLEVEL),0)
+gb_JavaClassSet_JAVACDEBUG := -g
+endif
+
+# $(PACKAGEDIRS) inherited from Jar -- assumption is the last part of the path
+# is top-level java package directory
+# for Java 9 modules, invoke javac another time, with --patch-module so that
+# it finds all the class files for whose packages the module-info contains a
+# declaration
+define gb_JavaClassSet__command
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) && \
+ $(if $(filter-out $(JARDEPS),$(4)), \
+ rm -rf $(call gb_JavaClassSet_get_classdir,$(2))/* && \
+ RESPONSEFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),500,\
+ $(filter-out $(JARDEPS) $(T_JAVA9FILES),$(4))) && \
+ $(if $(3),$(call gb_JavaClassSet_JAVACCOMMAND,$(JAVA_TARGET_VER)) \
+ $(gb_JavaClassSet_JAVACDEBUG) \
+ -classpath "$(T_CP)$(gb_CLASSPATHSEP)$(call gb_JavaClassSet_get_classdir,$(2))" \
+ -d $(call gb_JavaClassSet_get_classdir,$(2)) \
+ @$$RESPONSEFILE &&) \
+ rm -f $$RESPONSEFILE &&) \
+ $(if $(T_MODULENAME),\
+ RESPONSEFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),500,\
+ $(T_JAVA9FILES)) && \
+ $(if $(3),$(call gb_JavaClassSet_JAVACCOMMAND,9) \
+ $(gb_JavaClassSet_JAVACDEBUG) \
+ -classpath "$(T_CP)$(gb_CLASSPATHSEP)$(call gb_JavaClassSet_get_classdir,$(2))" \
+ --module-path "$(T_CP)$(gb_CLASSPATHSEP)$(call gb_JavaClassSet_get_classdir,$(2))" \
+ $(if $(T_MODULENAME),--patch-module $(T_MODULENAME)="$(subst $(WHITESPACE),$(gb_CLASSPATHSEP),$(strip $(dir $(PACKAGEDIRS))))") \
+ -d $(call gb_JavaClassSet_get_classdir,$(2)) \
+ @$$RESPONSEFILE &&) \
+ rm -f $$RESPONSEFILE &&) \
+ touch $(1))
+
+endef
+
+$(call gb_JavaClassSet_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),JCS,3)
+ $(call gb_Trace_StartRange,$*,JCS)
+ $(call gb_JavaClassSet__command,$@,$*,$?,$^)
+ $(call gb_Trace_EndRange,$*,JCS)
+
+$(call gb_JavaClassSet_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),JCS,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf $(dir $(call gb_JavaClassSet_get_target,$*))) \
+ $(call gb_JavaClassSet_get_preparation_target,$*)
+
+$(call gb_JavaClassSet_get_preparation_target,%) :
+ mkdir -p $(dir $@) && touch $@
+
+# depend on makefile to enforce a rebuild if files are removed from the classset
+# call gb_JavaClassSet_JavaClassSet,csname,java9modulename
+define gb_JavaClassSet_JavaClassSet
+$(call gb_JavaClassSet_get_target,$(1)) : \
+ $(gb_Module_CURRENTMAKEFILE) \
+ $(call gb_JavaClassSet_get_preparation_target,$(1))
+$(call gb_JavaClassSet_get_target,$(1)) : JARDEPS := \
+ $(gb_Module_CURRENTMAKEFILE) \
+ $(call gb_JavaClassSet_get_preparation_target,$(1))
+$(call gb_JavaClassSet_get_target,$(1)) : T_MODULENAME := $(2)
+$(call gb_JavaClassSet_get_target,$(1)) : T_JAVA9FILES :=
+
+endef
+
+define gb_JavaClassSet__get_sourcefile
+$(SRCDIR)/$(1).java
+endef
+
+define gb_JavaClassSet__get_generated_sourcefile
+$(WORKDIR)/$(1).java
+endef
+
+define gb_JavaClassSet_add_sourcefile
+$(call gb_JavaClassSet_get_target,$(1)) : $(call gb_JavaClassSet__get_sourcefile,$(2))
+
+endef
+
+define gb_JavaClassSet_add_sourcefiles
+$(foreach sourcefile,$(2),$(call gb_JavaClassSet_add_sourcefile,$(1),$(sourcefile)))
+
+endef
+
+define gb_JavaClassSet_add_sourcefile_java9
+$(call gb_JavaClassSet_get_target,$(1)) : $(call gb_JavaClassSet__get_sourcefile,$(2))
+$(call gb_JavaClassSet_get_target,$(1)) : T_JAVA9FILES += $(call gb_JavaClassSet__get_sourcefile,$(2))
+
+endef
+
+define gb_JavaClassSet_add_sourcefiles_java9
+$(foreach sourcefile,$(2),$(call gb_JavaClassSet_add_sourcefile_java9,$(1),$(sourcefile)))
+
+endef
+
+define gb_JavaClassSet_add_generated_sourcefile
+$(call gb_JavaClassSet_get_target,$(1)) : $(call gb_JavaClassSet__get_generated_sourcefile,$(2))
+$(call gb_JavaClassSet__get_generated_sourcefile,$(2)) :| $(call gb_JavaClassSet_get_preparation_target,$(1))
+
+endef
+
+define gb_JavaClassSet_add_generated_sourcefiles
+$(foreach sourcefile,$(2),$(call gb_JavaClassSet_add_generated_sourcefile,$(1),$(sourcefile)))
+
+endef
+
+define gb_JavaClassSet_add_classpath
+$(call gb_JavaClassSet_get_target,$(1)) : T_CP := $$(if $$(T_CP),$$(T_CP)$$(gb_CLASSPATHSEP))$(strip $(2))
+
+endef
+
+define gb_JavaClassSet_use_jar
+ifneq (,$$(filter-out $(gb_Jar_KNOWN),$(2)))
+$$(eval $$(call gb_Output_info,currently known jars are: $(sort $(gb_Jar_KNOWN)),ALL))
+$$(eval $$(call gb_Output_error,Cannot link against jar $$(filter-out $(gb_Jar_KNOWN),$(2)). Jars must be registered in Repository.mk or RepositoryExternal.mk))
+endif
+$(call gb_JavaClassSet_get_target,$(1)) : $(call gb_Jar_get_target,$(2))
+$(call gb_JavaClassSet_get_target,$(1)) : JARDEPS += $(call gb_Jar_get_target,$(2))
+$(call gb_JavaClassSet_add_classpath,$(1),$(call gb_Jar_get_target,$(2)))
+
+endef
+
+# this does not generate dependency on the jar
+define gb_JavaClassSet_use_system_jar
+$(call gb_JavaClassSet_add_classpath,$(1),$(2))
+
+endef
+
+define gb_JavaClassSet_use_jars
+$(foreach jar,$(2),$(call gb_JavaClassSet_use_jar,$(1),$(jar)))
+
+endef
+
+define gb_JavaClassSet_use_system_jars
+$(foreach jar,$(2),$(call gb_JavaClassSet_use_system_jar,$(1),$(jar)))
+
+endef
+
+# gb_JavaClassSet_use_jar_classset: Like gb_JavaClassSet_use_jar, but instead of
+# using the jar, use the directory tree with the class files that make up the
+# jar. This is sometimes necessary in JunitTests that have test classes in
+# packages that belong to a sealed jar.
+# $1: token identifying this JavaClassSet
+# $2: token identifying the Jar being used
+define gb_JavaClassSet_use_jar_classset
+$(call gb_JavaClassSet_get_target,$(1)) : $(call gb_JavaClassSet_get_target,$(call gb_Jar_get_classsetname,$(2)))
+$(call gb_JavaClassSet_get_target,$(1)) : JARDEPS += $(call gb_JavaClassSet_get_target,$(call gb_Jar_get_classsetname,$(2)))
+$(call gb_JavaClassSet_add_classpath,$(1),$(call gb_JavaClassSet_get_classdir,$(call gb_Jar_get_classsetname,$(2))))
+
+endef
+
+define gb_JavaClassSet_use_customtarget
+$(call gb_JavaClassSet_get_preparation_target,$(1)) : \
+ $(call gb_CustomTarget_get_target,$(2))
+$(call gb_JavaClassSet_add_classpath,$(1),$(call gb_CustomTarget_get_workdir,$(2)))
+
+endef
+
+define gb_JavaClassSet_use_external_project
+$(call gb_JavaClassSet_get_preparation_target,$(1)) : \
+ $(call gb_ExternalProject_get_target,$(2))
+
+endef
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/JunitTest.mk b/solenv/gbuild/JunitTest.mk
new file mode 100644
index 000000000..401c8ff5c
--- /dev/null
+++ b/solenv/gbuild/JunitTest.mk
@@ -0,0 +1,234 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+
+# JunitTest class
+
+gb_JunitTest_JAVACOMMAND := $(JAVAINTERPRETER) $(JAVAIFLAGS)
+
+
+.PHONY : $(call gb_JunitTest_get_clean_target,%)
+$(call gb_JunitTest_get_clean_target,%) : $(call gb_JavaClassSet_get_clean_target,$(call gb_JunitTest_get_classsetname,%))
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $@ $@.log)
+
+ifneq (,$(strip $(OOO_JUNIT_JAR)))
+
+.PHONY : $(call gb_JunitTest_get_target,%)
+$(call gb_JunitTest_get_target,%) :
+ifneq ($(gb_SUPPRESS_TESTS),)
+ @true
+else
+ $(call gb_Output_announce,$*,$(true),JUT,2)
+ $(call gb_Trace_StartRange,$*,JUT)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf $(call gb_JunitTest_get_userdir,$*) && \
+ mkdir -p $(call gb_JunitTest_get_userdir,$*)/user && \
+ cp $(SRCDIR)/qadevOOo/qa/registrymodifications.xcu $(call gb_JunitTest_get_userdir,$*)/user/ && \
+ ($(gb_TEST_ENV_VARS) $(ICECREAM_RUN) $(gb_JunitTest_JAVACOMMAND) \
+ -classpath "$(T_CP)" \
+ $(DEFS) \
+ org.junit.runner.JUnitCore \
+ $(CLASSES) > $@.log 2>&1 || \
+ (cat $@.log \
+ && echo "to rerun just this failed test without all others, run:" \
+ && echo && echo " make JunitTest_$*" && echo \
+ && echo "cd into the module dir to run the tests faster" \
+ && echo "Or to do interactive debugging, run two shells with:" \
+ && echo \
+ && echo " make debugrun" \
+ && echo " make gb_JunitTest_DEBUGRUN=T JunitTest_$*" \
+ && echo \
+ && false)))
+ $(CLEAN_CMD)
+ $(call gb_Trace_EndRange,$*,JUT)
+endif
+
+define gb_JunitTest_JunitTest
+$(call gb_JunitTest_get_target,$(1)) : T_CP := $(call gb_JavaClassSet_get_classdir,$(call gb_JunitTest_get_classsetname,$(1)))$$(gb_CLASSPATHSEP)$(OOO_JUNIT_JAR)$(if $(HAMCREST_JAR),$$(gb_CLASSPATHSEP)$(HAMCREST_JAR))$$(gb_CLASSPATHSEP)$(INSTROOT)/$(LIBO_URE_LIB_FOLDER)
+$(call gb_JunitTest_get_target,$(1)) : CLASSES :=
+$(eval $(call gb_JunitTest_JunitTest_platform,$(1)))
+
+$(call gb_JavaClassSet_JavaClassSet,$(call gb_JunitTest_get_classsetname,$(1)))
+$(call gb_JavaClassSet_use_system_jar,$(call gb_JunitTest_get_classsetname,$(1)),$(OOO_JUNIT_JAR))
+$(if $(HAMCREST_JAR),$(call gb_JavaClassSet_use_system_jar,$(call gb_JunitTest_get_classsetname,$(1)),$(HAMCREST_JAR)))
+$(call gb_JunitTest_get_target,$(1)) : $(call gb_JavaClassSet_get_target,$(call gb_JunitTest_get_classsetname,$(1)))
+$(eval $(call gb_Module_register_target,$(call gb_JunitTest_get_target,$(1)),$(call gb_JunitTest_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),JunitTest)
+
+endef
+
+define gb_JunitTest_set_defs
+$(call gb_JunitTest_get_target,$(1)) : DEFS := $(2)
+
+endef
+
+define gb_JunitTest_add_classes
+$(call gb_JunitTest_get_target,$(1)) : CLASSES += $(2)
+
+endef
+
+define gb_JunitTest_add_class
+$(call gb_JunitTest_add_classes,$(1),$(2))
+
+endef
+
+
+define gb_JunitTest_add_sourcefile
+$(call gb_JavaClassSet_add_sourcefile,$(call gb_JunitTest_get_classsetname,$(1)),$(2))
+
+endef
+
+define gb_JunitTest_add_sourcefiles
+$(foreach sourcefile,$(2),$(call gb_JunitTest_add_sourcefile,$(1),$(sourcefile)))
+
+endef
+
+define gb_JunitTest_use_jar
+$(call gb_JavaClassSet_use_jar,$(call gb_JunitTest_get_classsetname,$(1)),$(2))
+$(call gb_JunitTest_get_target,$(1)) : T_CP := $$(T_CP)$$(gb_CLASSPATHSEP)$(call gb_Jar_get_target,$(2))
+$(call gb_JunitTest_get_target,$(1)) : $(call gb_Jar_get_target,$(2))
+
+endef
+
+define gb_JunitTest_use_jars
+$(foreach jar,$(2),$(call gb_JunitTest_use_jar,$(1),$(jar)))
+
+endef
+
+# see gb_JavaClassSet_use_jar_classset
+define gb_JunitTest_use_jar_classset
+$(call gb_JavaClassSet_use_jar_classset,$(call gb_JunitTest_get_classsetname,$(1)),$(2))
+$(call gb_JunitTest_get_target,$(1)) : T_CP := $$(T_CP)$$(gb_CLASSPATHSEP)$(call gb_JavaClassSet_get_classdir,$(call gb_Jar_get_classsetname,$(2)))
+
+endef
+
+define gb_JunitTest_add_classpath
+$(call gb_JavaClassSet_add_classpath,$(call gb_JunitTest_get_classsetname,$(1)),$(2))
+$(call gb_JunitTest_get_target,$(1)) : T_CP := $$(T_CP)$$(gb_CLASSPATHSEP)$(2)
+
+endef
+
+define gb_JunitTest_use_system_jar
+$(call gb_JavaClassSet_use_system_jar,$(call gb_JunitTest_get_classsetname,$(1)),$(2))
+
+endef
+
+define gb_JunitTest_use_system_jars
+$(foreach jar,$(2),$(call gb_JunitTest_use_system_jar,$(1),$(jar)))
+
+endef
+
+# this forwards to functions that must be defined in RepositoryExternal.mk.
+# $(eval $(call gb_JunitTest_use_external,jar,external))
+define gb_JunitTest_use_external
+$(if $(value gb_JunitTest__use_$(2)),\
+ $(call gb_JunitTest__use_$(2),$(1)),\
+ $(error gb_JunitTest_use_external: unknown external: $(2)))
+
+endef
+
+define gb_JunitTest_use_externals
+$(foreach external,$(2),$(call gb_JunitTest_use_external,$(1),$(external)))
+
+endef
+
+define gb_JunitTest_use_customtarget
+$(call gb_JavaClassSet_use_customtarget,$(call gb_JunitTest_get_classsetname,$(1)),$(2))
+$(call gb_JunitTest_get_target,$(1)) : T_CP := $$(T_CP)$$(gb_CLASSPATHSEP)$(call gb_CustomTarget_get_workdir,$(2))
+
+endef
+
+define gb_JunitTest_use_customtargets
+$(foreach dependency,$(2),$(call gb_JunitTest_use_customtarget,$(1),$(dependency)))
+
+endef
+
+define gb_JunitTest_use_unoapi_jars
+$(eval $(call gb_JunitTest_use_jars,$(1),\
+ OOoRunner \
+ libreoffice \
+ test \
+))
+
+endef
+
+define gb_JunitTest_use_unoapi_test_class
+$(eval $(call gb_JunitTest_add_classes,$(1),\
+ org.openoffice.test.UnoApiTest \
+))
+
+endef
+
+# To be used by gb_JunitTest_set_unoapi_test_defaults
+# <module>_unoapi_1 => <module>_1 => <module> => <module>/qa/unoapi
+gb_JunitTest__unoapi_iter = $(subst _unoapi,,$(1))
+gb_JunitTest__unoapi_module = $(firstword $(subst _, ,$(gb_JunitTest__unoapi_iter)))
+gb_JunitTest__unoapi_dir = $(if $(2),$(2),$(gb_JunitTest__unoapi_module)/qa/unoapi)
+
+# $(1) = test name (prefer <module>_unoapi for defaults, example <module>_unoapi_1)
+# $(2) = test directory base (def: <module>_unoapi_1 => <module>_1/qa/unoapi)
+# $(3) = SCE file (def: <module>_1.sce)
+# $(4) = XCL file (def: knownissues.xcl)
+# $(5) = test document directory (def: testdocuments; use . for base)
+define gb_JunitTest_set_unoapi_test_defaults
+$(eval $(call gb_JunitTest_set_defs,$(1),\
+ $$(DEFS) \
+ -Dorg.openoffice.test.arg.sce=$(SRCDIR)/$(gb_JunitTest__unoapi_dir)/$(if $(3),$(3),$(gb_JunitTest__unoapi_iter).sce) \
+ -Dorg.openoffice.test.arg.xcl=$(SRCDIR)/$(gb_JunitTest__unoapi_dir)/$(if $(4),$(4),knownissues.xcl) \
+ -Dorg.openoffice.test.arg.tdoc=$(SRCDIR)/$(gb_JunitTest__unoapi_dir)/$(if $(5),$(5),testdocuments) \
+))
+
+$(eval $(call gb_JunitTest_use_unoapi_jars,$(1)))
+$(eval $(call gb_JunitTest_use_unoapi_test_class,$(1)))
+
+endef
+
+else # OOO_JUNIT_JAR
+
+.PHONY : $(call gb_JunitTest_get_target,$(1))
+$(call gb_JunitTest_get_target,%) :
+ifeq ($(gb_SUPPRESS_TESTS),)
+ $(call gb_Output_announce,$* (skipped - no Junit),$(true),JUT,2)
+endif
+ @true
+
+define gb_JunitTest_JunitTest
+$(eval $(call gb_Module_register_target,$(call gb_JunitTest_get_target,$(1)),$(call gb_JunitTest_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),JunitTest)
+
+endef
+
+gb_JunitTest_set_defs :=
+gb_JunitTest_add_classes :=
+gb_JunitTest_add_class :=
+gb_JunitTest_add_sourcefile :=
+gb_JunitTest_add_sourcefiles :=
+gb_JunitTest_use_jar :=
+gb_JunitTest_use_jars :=
+gb_JunitTest_use_jar_classset :=
+gb_JunitTest_use_system_jar :=
+gb_JunitTest_use_system_jars :=
+gb_JunitTest_use_external :=
+gb_JunitTest_use_externals :=
+gb_JunitTest_use_customtarget :=
+gb_JunitTest_use_customtargets :=
+
+endif # OOO_JUNIT_JAR
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/Library.mk b/solenv/gbuild/Library.mk
new file mode 100644
index 000000000..d82a261e0
--- /dev/null
+++ b/solenv/gbuild/Library.mk
@@ -0,0 +1,296 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+
+# Library class
+
+# defined globally in TargetLocations.mk
+# gb_Library_DLLDIR := $(WORKDIR)/LinkTarget/Library
+# defined by platform
+# gb_Library_DEFS
+# gb_Library_ILIBFILENAMES
+# gb_Library_FILENAMES
+# gb_Library_Library_platform
+
+gb_Library_LAYER_DIRS := \
+ URELIB:$(INSTROOT)/$(LIBO_URE_LIB_FOLDER) \
+ OOO:$(INSTROOT)/$(LIBO_LIB_FOLDER) \
+ SHLXTHDL:$(INSTROOT)/$(LIBO_LIB_FOLDER)/shlxthdl \
+ OXT:$(WORKDIR)/LinkTarget/ExtensionLibrary \
+ NONE:$(gb_Library_DLLDIR) \
+
+gb_Library_LAYER_DIRS_FOR_BUILD := \
+ URELIB:$(INSTROOT_FOR_BUILD)/$(LIBO_URE_LIB_FOLDER_FOR_BUILD) \
+ OOO:$(INSTROOT_FOR_BUILD)/$(LIBO_LIB_FOLDER_FOR_BUILD) \
+ SHLXTHDL:$(INSTROOT_FOR_BUILD)/$(LIBO_LIB_FOLDER_FOR_BUILD)/shlxthdl \
+ OXT:$(WORKDIR_FOR_BUILD)/LinkTarget/ExtensionLibrary \
+ NONE:$(gb_Library_DLLDIR_FOR_BUILD) \
+
+# EVIL: gb_StaticLibrary and gb_Library need the same deliver rule because they are indistinguishable on windows
+.PHONY : $(WORKDIR)/Clean/Library/%
+$(WORKDIR)/Clean/Library/% :
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_Library_get_exports_target,$*) \
+ $(AUXTARGETS))
+
+gb_Library__get_dir_for_layer = $(patsubst $(1):%,%,$(filter $(1):%,$(gb_Library_LAYER_DIRS)))
+gb_Library__get_dir_for_layer_for_build = $(patsubst $(1):%,%,$(filter $(1):%,$(call gb_Library_LAYER_DIRS_FOR_BUILD)))
+gb_Library_get_instdir = $(call gb_Library__get_dir_for_layer,$(call gb_Library_get_layer,$(1)))
+gb_Library_get_instdir_for_build = $(call gb_Library__get_dir_for_layer_for_build,$(call gb_Library_get_layer,$(1)))
+
+gb_Library_get_ilib_target = $(if $(filter $(1),$(gb_Library_RTVERLIBS) $(gb_Library_UNOVERLIBS)),$(call gb_Library_get_sdk_link_dir)/$(call gb_Library_get_ilibfilename,$(1)),$(gb_Library_DLLDIR)/$(call gb_Library_get_ilibfilename,$(1)))
+
+define gb_Library_Library
+$(call gb_Postprocess_register_target,AllLibraries,Library,$(1))
+ifeq (,$$(filter $(1),$$(gb_Library_KNOWNLIBS)))
+$$(eval $$(call gb_Output_info,Currently known libraries are: $(sort $(gb_Library_KNOWNLIBS)),ALL))
+$$(eval $$(call gb_Output_error,Library $(1) must be registered in Repository.mk or RepositoryExternal.mk))
+endif
+
+$(if $(gb_Package_PRESTAGEDIR),\
+ $(if $(wildcard $(gb_Package_PRESTAGEDIR)/$(call gb_Library_get_instdir,$(1))/$(call gb_Library_get_runtime_filename,$(1))),\
+ $(call gb_Library__Library_impl_copy,$(0),$(call gb_Library_get_instdir,$(1))/$(call gb_Library_get_runtime_filename,$(1))),\
+ $(call gb_Library__Library_impl,$(1),$(call gb_Library_get_linktarget,$(1)))\
+ ),
+ $(call gb_Library__Library_impl,$(1),$(call gb_Library_get_linktarget,$(1)))\
+)
+
+endef
+
+define gb_Library__Library_impl_copy
+$(call gb_Package_Package,Library_Copy_$(1),$(gb_Package_PRESTAGEDIR))
+$(call gb_Package_add_file,Library_Copy_$(1),$(2),$(2))
+endef
+
+# Note: there may be targets in 3 different directories: the library itself,
+# the exports target (and other misc. MSVC files) (always in
+# $(WORKDIR)/LinkTarget), and the import library, which may be in SDK;
+# the first 2 are always created by gb_LinkTarget_LinkTarget
+# Also: the directory dependencies must be on the headers_target because
+# MSVC will write a PDB file when compiling objects.
+#
+# call gb_Library__Library_impl,library,linktarget
+define gb_Library__Library_impl
+$(call gb_LinkTarget_LinkTarget,$(2),Library_$(1),$(call gb_Library_get_layer,$(1)))
+$(call gb_LinkTarget_set_targettype,$(2),Library)
+$(call gb_LinkTarget_add_libs,$(2),$(gb_STDLIBS))
+$(call gb_LinkTarget_add_defs,$(2),\
+ $(gb_Library_DEFS) \
+)
+$(call gb_Library_get_exports_target,$(1)) : $(call gb_Library_get_target,$(1))
+$(call gb_LinkTarget_get_headers_target,$(2)) : \
+ | $(dir $(call gb_Library_get_ilib_target,$(1))).dir
+$(call gb_Library_get_clean_target,$(1)) : $(call gb_LinkTarget_get_clean_target,$(2))
+$(call gb_Library_get_clean_target,$(1)) : AUXTARGETS :=
+$(call gb_Library_Library_platform,$(1),$(2),$(call gb_Library_get_ilib_target,$(1)))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_Library_get_exports_target,$(1)),$(call gb_Library_get_clean_target,$(1))))
+
+$(call gb_Helper_make_userfriendly_targets,$(1),Library,$(call gb_Library_get_exports_target,$(1)))
+
+endef
+
+# we actually (ab)use ILIBTARGET here to store the unversioned symlink -
+# it serves a similar purpose to an MSVC import library, as input for linker
+# call gb_Library__add_soversion_link,library,linkname
+define gb_Library__add_soversion_link
+$(call gb_LinkTarget_set_ilibtarget,$(call gb_Library_get_linktarget,$(1)),$(2))
+
+endef
+
+define gb_Library__set_soversion_script
+$(call gb_LinkTarget_set_soversion_script,$(call gb_Library_get_linktarget,$(1)),$(2))
+$(call gb_Library__add_soversion_link,$(1),$(call gb_Library_get_versionlink_target,$(1)))
+
+endef
+
+# for libraries that maintain stable ABI: set SOVERSION and version script
+# $(call gb_Library_set_soversion_script,versionscript)
+define gb_Library_set_soversion_script
+$(if $(2),,$(call gb_Output_error,gb_Library_set_soversion_script: no script))
+$(if $(3),$(call gb_Output_error,gb_Library_set_soversion_script: too many arguments))
+$(call gb_Library__set_soversion_script_platform,$(1),$(2))
+endef
+
+gb_Library__get_component_var = $(call gb_Library__get_workdir_linktargetname,$(1))<>COMPONENTFILE
+gb_Library__get_component = $($(call gb_Library__get_component_var,$(1)))
+
+# The dependency from workdir component target to outdir library should ensure
+# that gb_CppunitTest_use_component can transitively depend on the library.
+# But the component target also must be delivered; use the target
+# gb_Library_get_exports_target for that purpose, since it is already
+# the "final" target of the Library...
+#
+# call gb_Library_set_componentfile,library,componentfile,rdb
+define gb_Library_set_componentfile
+$(call gb_ComponentTarget_ComponentTarget,$(2),\
+ $(call gb_Library__get_componentprefix,$(gb_Library__get_name)),\
+ $(call gb_Library_get_runtime_filename,$(gb_Library__get_name)),$(3))
+$(call gb_Library_get_exports_target,$(gb_Library__get_name)) :| \
+ $(call gb_ComponentTarget_get_target,$(2))
+$(call gb_ComponentTarget_get_target,$(2)) :| \
+ $(call gb_Library_get_target,$(gb_Library__get_name))
+$(call gb_Library_get_clean_target,$(gb_Library__get_name)) : \
+ $(call gb_ComponentTarget_get_clean_target,$(2))
+
+$(if $(call gb_Library__get_component,$(1)),$(error Can't have multiple component files per library))
+$(eval $(call gb_Library__get_component_var,$(1)) = $(2))
+
+endef
+
+# The implid is appended to the component file, separated by a dot.
+#
+# call gb_Library_add_componentimpl,library,implid
+define gb_Library_add_componentimpl
+$(if $(call gb_Library__get_component,$(1)),, \
+ $(error Set gb_Library_set_componentfile before using gb_Library_add_componentimpl))
+$(call gb_ComponentTarget_add_componentimpl,$(call gb_Library__get_component,$(1)),$(2))
+
+endef
+
+# call gb_Library_add_componentimpls,library,implids
+define gb_Library_add_componentimpls
+$(foreach comp,$(2),$(call gb_Library_add_componentimpl,$(1),$(comp)))
+endef
+
+gb_Library__get_name = $(if $(filter $(1),$(gb_MERGEDLIBS)),merged,$(1))
+
+gb_Library__get_componentprefix = \
+ $(call gb_Library__get_layer_componentprefix,$(call \
+ gb_Library_get_layer,$(1)))
+
+gb_Library__get_layer_componentprefix = \
+ $(patsubst $(1):%,%,$(or \
+ $(filter $(1):%,$(gb_Library__COMPONENTPREFIXES)), \
+ $(call gb_Output_error,no ComponentTarget native prefix for layer '$(1)')))
+
+# The \d gets turned into a dollar sign by a $(subst) call in
+# gb_ComponentTarget__command in ComponentTarget.mk. As far as I
+# understand, there is nothing magic to it, it is not some
+# Make/awk/sed/whatever syntax.
+
+gb_Library__COMPONENTPREFIXES := \
+ NONE:vnd.sun.star.expand:\dLO_BUILD_LIB_DIR/ \
+ OOO:vnd.sun.star.expand:\dLO_LIB_DIR/ \
+ URELIB:vnd.sun.star.expand:\dURE_INTERNAL_LIB_DIR/ \
+ OXT:./ \
+ SHLXTHDL:ERROR_NOT_ALLOWED \
+
+
+gb_Library_get_runtime_filename = $(call gb_Library_get_filename,$(1))
+gb_Library_get_runtime_filename_for_build = $(call gb_Library_get_filename_for_build,$(1))
+
+# instead of setting nodep use gb_Library_set_plugin_for_nodep
+#
+# call gb_Library_set_plugin_for,library,loader,nodep
+define gb_Library_set_plugin_for
+ifneq (,$$(filter-out $(gb_Library_KNOWNPLUGINS),$(1)))
+$$(eval $$(call gb_Output_info,currently known plugins are: $(sort $(gb_Library_KNOWNPLUGINS)),ALL))
+$$(eval $$(call gb_Output_error,Unknown plugin(s) '$$(filter-out $(gb_Library_KNOWNPLUGINS),$(1)))'. Plugins must be registered in Repository.mk or RepositoryExternal.mk))
+endif
+
+$(call gb_Library_get_linktarget_target,$(2)) : PLUGINS += $(1)
+$(eval $(call gb_LinkTarget__add_plugin,$(call gb_Library_get_linktarget,$(2)),$(1)))
+$(eval $(call gb_LinkTarget__set_plugin_for,$(call gb_Library_get_linktarget,$(1)),$(2),$(3),Library_$(1)))
+endef
+
+# call gb_Library_set_plugin_for_nodep,library,loader
+gb_Library_set_plugin_for_nodep = $(call gb_Library_set_plugin_for,$(1),$(2),$(true))
+
+# forward the call to the gb_LinkTarget implementation
+# (note: because the function name is in $(1), the other args are shifted by 1)
+define gb_Library__forward_to_Linktarget
+$(call gb_LinkTarget_$(subst gb_Library_,,$(1)),$(call gb_Library_get_linktarget,$(2)),$(3),$(4),Library_$(2))
+
+endef
+
+# copy pasta for forwarding: this could be (and was) done more elegantly, but
+# these here can be found by both git grep and ctags
+gb_Library_add_cobject = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_cobjects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_cxxobject = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_cxxobjects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_objcobject = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_objcobjects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_objcxxobject = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_objcxxobjects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_cxxclrobject = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_cxxclrobjects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_generated_cxxclrobjects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_asmobject = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_asmobjects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_exception_objects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_x64_generated_exception_objects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_generated_cobjects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_generated_exception_objects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_generated_objcobjects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_generated_objcxxobjects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_library_objects = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_grammar = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_grammars = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_scanner = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_scanners = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_cflags = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_cxxflags = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_objcxxflags = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_objcflags = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_cxxclrflags = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_defs = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_include = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_ldflags = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_ldflags = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_x64 = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_x86 = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_libs = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_disable_standard_system_libs = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_system_darwin_frameworks = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_system_win32_libs = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_library_path_flags = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_api = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_sdk_api = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_udk_api = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_internal_api = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_internal_bootstrap_api = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_internal_comprehensive_api = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_libraries = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_static_libraries = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_external = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_externals = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_custom_headers = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_package = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_packages = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_unpacked = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_sdi_headers = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_precompiled_header = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_reuse_precompiled_header = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_common_precompiled_header = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_export_objects_list = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_add_nativeres = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_nativeres = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_visibility_default = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_warnings_not_errors = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_warnings_disabled = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_external_code = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_generated_cxx_suffix = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_clang = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_clang_precompiled_header = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_use_vclmain = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_Library_set_is_ure_library_or_dependency = $(call gb_Library__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/LinkTarget.mk b/solenv/gbuild/LinkTarget.mk
new file mode 100644
index 000000000..cc98d18bd
--- /dev/null
+++ b/solenv/gbuild/LinkTarget.mk
@@ -0,0 +1,2264 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+#the following user-defined variables are supported:
+# YACCFLAGS
+# LEXFLAGS
+# CPPFLAGS
+# CFLAGS
+# CXXFLAGS
+# OBJCFLAGS
+# OBJCXXFLAGS
+# LDFLAGS
+
+# defined by platform
+# gb_AsmObject_get_source (.asm on Windows, .s elsewhere)
+# gb_AsmObject__command
+# gb_CObject__command_pattern
+# gb_LinkTarget_CXXFLAGS
+# gb_LinkTarget_LDFLAGS
+# gb_LinkTarget_INCLUDE
+# gb_YaccTarget__command(grammar-file, stem-for-message, source-target, include-target)
+
+# Same happens for the gb_LinkTarget_add_libs calls from RepositoryExternal.mk. But we have no real
+# way to separate for gbuild internal and external gb_LinkTarget_add_libs calls.
+# So this flags these call parameters with an @ postfix. But now these must be filtered out, so this
+# defines that filter, just in case we need to change it because it conflicts with some parameters.
+# FYI: on Windows, gb_Library_use_system_win32_libs also calls gb_LinkTarget_add_libs; easy to miss.
+gb_LinkTarget__syslib = %@
+
+# debug flags, if the LinkTarget is named in the list of libraries of ENABLE_SYMBOLS_FOR
+gb_LinkTarget__get_debugflags= \
+ $(if $(ENABLE_OPTIMIZED),$(gb_COMPILEROPTFLAGS), \
+ $(if $(ENABLE_OPTIMIZED_DEBUG),$(gb_COMPILERDEBUGOPTFLAGS),$(gb_COMPILERNOOPTFLAGS))) \
+ $(if $(call gb_target_symbols_enabled,$(1)),$(gb_DEBUGINFO_FLAGS))
+
+# T_LDFLAGS is just expanded once. Override the flags here, so that the linker and compiler use the same.
+ifeq (EMSCRIPTEN,$(OS))
+gb_LinkTarget__get_debugldflags=$(call gb_LinkTarget__get_debugflags,$1)
+else
+# similar for LDFLAGS, use linker optimization flags in non-debug case,
+# but moreover strip debug from libraries for which debuginfo is not wanted
+# (some libraries reuse .o files from other libraries, notably unittests)
+gb_LinkTarget__get_stripldflags=$(if $(strip $(CFLAGS)$(CXXFLAGS)$(OBJCFLAGS)$(OBJCXXFLAGS)$(LDFLAGS)),,$(gb_LINKERSTRIPDEBUGFLAGS))
+gb_LinkTarget__get_debugldflags=$(if $(call gb_target_symbols_enabled,$(1)),$(gb_LINKER_DEBUGINFO_FLAGS),$(gb_LINKEROPTFLAGS) $(call gb_LinkTarget__get_stripldflags,$(1)))
+endif
+
+# generic cflags/cxxflags to use (optimization flags, debug flags)
+# user supplied CFLAGS/CXXFLAGS override default debug/optimization flags
+# call gb_LinkTarget__get_cflags,linktargetmakefilename
+gb_LinkTarget__get_cflags=$(if $(CFLAGS),$(CFLAGS),$(call gb_LinkTarget__get_debugflags,$(1)))
+gb_LinkTarget__get_objcflags=$(if $(OBJCFLAGS),$(OBJCFLAGS),$(call gb_LinkTarget__get_debugflags,$(1)))
+gb_LinkTarget__get_cxxflags=$(if $(CXXFLAGS),$(CXXFLAGS),$(call gb_LinkTarget__get_debugflags,$(1)))
+gb_LinkTarget__get_objcxxflags=$(if $(OBJCXXFLAGS),$(OBJCXXFLAGS),$(call gb_LinkTarget__get_debugflags,$(1)))
+gb_LinkTarget__get_cxxclrflags=$(call gb_LinkTarget__get_debugflags,$(1))
+# call gb_LinkTarget__get_ldflags,linktargetmakefilename
+gb_LinkTarget__get_ldflags=$(if $(LDFLAGS),$(LDFLAGS),$(call gb_LinkTarget__get_debugldflags,$(1)))
+
+gb_LinkTarget_LAYER_LINKPATHS := \
+ URELIB:URELIB. \
+ UREBIN:URELIB. \
+ SDKBIN:URELIB. \
+ OOO:URELIB+OOO. \
+ SHLXTHDL:. \
+ OXT:OXT. \
+ NONE:URELIB+OOO+NONE. \
+
+
+# Used to run a compiler plugin tool.
+#
+# At least for now, these definitions are generic enough so that they can be
+# shared across all current use cases (COMPILER_EXTERNAL_TOOL,
+# COMPILER_PLUGIN_TOOL) on all relevant toolchains (GCC?, Clang, clang-cl). If
+# it ever becomes necessary, they can be moved to e.g.
+# platform/com_{GCC,MSC}_class.mk and made different there.
+#
+# $(call gb_CObject__tool_command,relative-source,source,compiler-plugins)
+define gb_CObject__tool_command
+$(call gb_Helper_abbreviate_dirs,\
+ ICECC=no CCACHE_DISABLE=1 \
+ $(gb_CC) \
+ $(DEFS) \
+ $(T_LTOFLAGS) \
+ $(if $(VISIBILITY),,$(gb_VISIBILITY_FLAGS)) \
+ $(if $(WARNINGS_NOT_ERRORS),$(if $(ENABLE_WERROR),$(if $(PLUGIN_WARNINGS_AS_ERRORS),$(gb_COMPILER_PLUGINS_WARNINGS_AS_ERRORS))),$(gb_CFLAGS_WERROR)) \
+ $(if $(3),$(gb_COMPILER_PLUGINS)) \
+ $(T_CFLAGS) $(T_CFLAGS_APPEND) \
+ $(if $(EXTERNAL_CODE),$(gb_CXXFLAGS_Wundef),$(gb_DEFS_INTERNAL)) \
+ -c $(2) \
+ $(INCLUDE) \
+ )
+endef
+define gb_ObjCObject__tool_command
+$(call gb_Helper_abbreviate_dirs,\
+ ICECC=no CCACHE_DISABLE=1 \
+ $(gb_CC) \
+ $(DEFS) \
+ $(T_LTOFLAGS) \
+ $(if $(VISIBILITY),,$(gb_VISIBILITY_FLAGS)) \
+ $(if $(WARNINGS_NOT_ERRORS),$(if $(ENABLE_WERROR),$(if $(PLUGIN_WARNINGS_AS_ERRORS),$(gb_COMPILER_PLUGINS_WARNINGS_AS_ERRORS))),$(gb_CFLAGS_WERROR)) \
+ $(if $(3),$(gb_COMPILER_PLUGINS)) \
+ $(T_OBJCFLAGS) $(T_OBJCFLAGS_APPEND) \
+ $(if $(EXTERNAL_CODE),$(gb_CXXFLAGS_Wundef),$(gb_DEFS_INTERNAL)) \
+ -c $(2) \
+ $(INCLUDE) \
+ )
+endef
+define gb_CxxObject__tool_command
+$(call gb_Helper_abbreviate_dirs,\
+ ICECC=no CCACHE_DISABLE=1 \
+ $(gb_CXX) \
+ $(DEFS) \
+ $(T_LTOFLAGS) \
+ $(if $(VISIBILITY),,$(gb_VISIBILITY_FLAGS)) \
+ $(if $(WARNINGS_NOT_ERRORS),$(if $(ENABLE_WERROR),$(if $(PLUGIN_WARNINGS_AS_ERRORS),$(gb_COMPILER_PLUGINS_WARNINGS_AS_ERRORS))),$(gb_CFLAGS_WERROR)) \
+ $(if $(3),$(gb_COMPILER_PLUGINS)) \
+ $(T_CXXFLAGS) $(T_CXXFLAGS_APPEND) \
+ $(if $(EXTERNAL_CODE),$(gb_CXXFLAGS_Wundef),$(gb_DEFS_INTERNAL)) \
+ -c $(2) \
+ $(INCLUDE) \
+ )
+endef
+define gb_ObjCxxObject__tool_command
+$(call gb_Helper_abbreviate_dirs,\
+ ICECC=no CCACHE_DISABLE=1 \
+ $(gb_CXX) \
+ $(DEFS) \
+ $(T_LTOFLAGS) \
+ $(if $(VISIBILITY),,$(gb_VISIBILITY_FLAGS)) \
+ $(if $(WARNINGS_NOT_ERRORS),$(if $(ENABLE_WERROR),$(if $(PLUGIN_WARNINGS_AS_ERRORS),$(gb_COMPILER_PLUGINS_WARNINGS_AS_ERRORS))),$(gb_CFLAGS_WERROR)) \
+ $(if $(3),$(gb_COMPILER_PLUGINS)) \
+ $(T_OBJCXXFLAGS) $(T_OBJCXXFLAGS_APPEND) \
+ $(if $(EXTERNAL_CODE),$(gb_CXXFLAGS_Wundef),$(gb_DEFS_INTERNAL)) \
+ -c $(2) \
+ $(INCLUDE) \
+ )
+endef
+define gb_CxxClrObject__tool_command
+$(call gb_Helper_abbreviate_dirs,\
+ ICECC=no CCACHE_DISABLE=1 \
+ $(gb_CXX) \
+ $(DEFS) \
+ $(T_LTOFLAGS) \
+ $(if $(VISIBILITY),,$(gb_VISIBILITY_FLAGS)) \
+ $(if $(WARNINGS_NOT_ERRORS),$(if $(ENABLE_WERROR),$(if $(PLUGIN_WARNINGS_AS_ERRORS),$(gb_COMPILER_PLUGINS_WARNINGS_AS_ERRORS))),$(gb_CFLAGS_WERROR)) \
+ $(if $(3),$(gb_COMPILER_PLUGINS)) \
+ $(T_CXXCLRFLAGS) $(T_CXXCLRFLAGS_APPEND) \
+ $(if $(EXTERNAL_CODE),$(gb_CXXFLAGS_Wundef),$(gb_DEFS_INTERNAL)) \
+ -c $(2) \
+ $(INCLUDE) \
+ )
+endef
+
+
+# Overview of dependencies and tasks of LinkTarget
+#
+# target task depends on
+# LinkTarget linking AsmObject CObject CxxObject GenCObject GenCxxObject ObjCObject ObjCxxObject GenObjCObject GenObjCxxObject GenNasmObject CxxClrObject
+# LinkTarget/headers
+# LinkTarget/dep joined dep file AsmObject/dep CObject/dep CxxObject/dep GenCObject/dep GenCxxObject/dep ObjCObject/dep ObjCxxObject/dep GenObjCObject/dep GenObjCxxObject/dep GenNasmObject/dep CxxClrObject/dep GenCxxClrObject/dep
+# | LinkTarget/headers
+# LinkTarget/headers all headers available
+# including own generated
+# PCH precompiled headers LinkTarget/headers
+# CObject plain c compile | LinkTarget/headers
+# CxxObject c++ compile | LinkTarget/headers PCH
+# GenCObject plain c compile from | LinkTarget/headers
+# generated source
+# GenCxxObject C++ compile from | LinkTarget/headers PCH
+# generated source
+# ObjCObject objective c compile | LinkTarget/headers
+# ObjCxxObject objective c++ compile | LinkTarget/headers
+# GenObjCObject objective c compile from | LinkTarget/headers
+# generated source
+# GenObjCxxObject objective c++ compile from | LinkTarget/headers
+# generated source
+# GenNasmObject nasm compile from | LinkTarget/headers
+# generated source
+# CxxClrObject C++ CLR compile | LinkTarget/headers
+# GenCxxClrObject C++ CLR compile from | LinkTarget/headers
+# generated source
+#
+# AsmObject asm compile | LinkTarget
+#
+# CObject/dep dependencies these targets generate empty dep files
+# CxxObject/dep dependencies that are populated upon compile
+# GenCObject/dep dependencies
+# GenCxxObject/dep dependencies
+# ObjCObject/dep dependencies
+# ObjCxxObject/dep dependencies
+# GenObjCObject/dep dependencies
+# GenObjCxxObject/dep dependencies
+# GenNasmObject/dep dependencies
+# CxxClrObject/dep dependencies
+# GenCxxClrObject/dep dependencies
+# AsmObject/dep dependencies
+
+# LinkTarget/headers means gb_LinkTarget_get_headers_target etc.
+# dependencies prefixed with | are build-order only dependencies
+
+
+# check that objects are only linked into one link target:
+# multiple linking may cause problems because different link targets may
+# require different compiler flags
+define gb_Object__owner
+$$(if $$(OBJECTOWNER),\
+ $$(call gb_Output_error,fdo#47246: $(1) is linked in by $$(OBJECTOWNER) $(2)))$(2)
+endef
+
+# For every object there is a dep file (if gb_FULLDEPS is active).
+# The dep file depends on the object: the Object__command also updates the
+# dep file as a side effect.
+# In the dep file rule just touch it so it's newer than the object.
+
+# Setting FORCE_COMPILE allows forcing compilation for specific sources,
+# usually used to force running a tool on the sources (see compilerplugins/README).
+# If set, it'll force all considered sources for rebuild. But it's possible
+# to explicitly specify gbuild build targets where running of the tool will be skipped
+# (where 'all' means everything, '-' prepended means to not enable, '/' appended means
+# everything in the directory; there is no ordering, more specific overrides
+# more general, and disabling takes precedence).
+# Example: FORCE_COMPILE="all -sw/ -Library_sc"
+
+# Detect whether forced compile should be used for the given gbuild target.
+# enable if: no "-TARGET" defined AND [module is enabled OR "TARGET" defined]
+# call gb_LinkTarget__force_compile,linktargetmakefilename
+gb_LinkTarget__force_compile = \
+ $(and $(if $(filter -$(1),$(FORCE_COMPILE)),,$(true)),\
+ $(or $(gb_Module_CURRENTMODULE_FORCE_COMPILE),\
+ $(filter $(1),$(FORCE_COMPILE))))
+
+# This one only exists to force .c/.cxx "rebuilds" when running a compiler tool.
+.PHONY: force_compile_target
+force_compile_target:
+ifneq ($(FORCE_COMPILE),)
+gb_FORCE_COMPILE_TARGET := force_compile_target
+endif
+
+# A tool is run either if FORCE_COMPILE is not set (in that case it's always run,
+# because the target is not up to date), or if FORCE_COMPILE is set then
+# the tool is run only if the value of FORCE_COMPILE includes the target.
+gb_LinkTarget__tool_compile_enabled = \
+ $(if $(FORCE_COMPILE),$(T_FORCE_COMPILE),$(true))
+
+# CObject class
+
+gb_CObject_get_source = $(1)/$(2).c
+
+ifneq ($(COMPILER_EXTERNAL_TOOL)$(COMPILER_PLUGIN_TOOL),)
+$(call gb_CObject_get_target,%) : $(call gb_CObject_get_source,$(SRCDIR),%) $(gb_FORCE_COMPILE_TARGET)
+ $(call gb_Output_announce,$*.c,$(true),C ,3)
+ $(call gb_Trace_StartRange,$*.c,C )
+ $(if $(call gb_LinkTarget__tool_compile_enabled),$(call gb_CObject__tool_command,$*,$<,$(COMPILER_PLUGINS)))
+ $(call gb_Trace_EndRange,$*.c,C )
+else
+$(call gb_CObject_get_target,%) : $(call gb_CObject_get_source,$(SRCDIR),%)
+ $(call gb_Output_announce,$*.c,$(true),$(if $(COMPILER_TEST),C? ,C ),3)
+ $(call gb_Trace_StartRange,$*.c,$(if $(COMPILER_TEST),C? ,C ))
+ $(call gb_CObject__command_pattern,$@,$(T_CFLAGS) $(T_CFLAGS_APPEND),$<,$(call gb_CObject_get_dep_target,$*),$(COMPILER_PLUGINS),$(T_CC))
+ $(call gb_Trace_EndRange,$*.c,$(if $(COMPILER_TEST),C? ,C ))
+endif
+
+# Note: if the *Object_dep_target does not exist it will be created by
+# concat-deps as PHONY
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_CObject_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_CObject_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_CObject_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+
+endif
+
+
+# CxxObject class
+
+gb_CxxObject_get_source = $(1)/$(2).cxx
+
+# Only enable PCH if the PCH_CXXFLAGS and the PCH_DEFS (from the linktarget)
+# are the same as the T_CXXFLAGS and DEFS we want to use for this object. This
+# should usually be the case. The DEFS/T_CXXFLAGS would have to be manually
+# overridden for one object file for them to differ. PCH_CXXFLAGS/PCH_DEFS
+# should never be overridden on an object -- they should be the same as for the
+# whole linktarget. In general it should be cleaner to use a static library
+# compiled with different flags and link that in rather than mixing different
+# flags in one linktarget. If OBJECT_HAS_EXTRA_CXXFLAGS is set, the object
+# has explicitly set additional CXXFLAGS, so in that case avoid using the PCH.
+# T_PCH_EXTRA_CXXFLAGS is used when some object requires extra flags when using
+# the PCH, but they are intended (gb_PrecompiledHeader_pch_with_obj).
+define gb_CxxObject__set_pchflags
+ifneq ($(gb_ENABLE_PCH),)
+ifneq ($(strip $$(PCH_NAME)),)
+ifeq ($(OBJECT_HAS_EXTRA_CXXFLAGS),)
+ifeq ($$(sort $$(PCH_CXXFLAGS) $$(PCH_DEFS)),$$(sort $$(T_CXXFLAGS) $$(T_CXXFLAGS_APPEND) $$(DEFS)))
+$$@ : PCHFLAGS := $$(call gb_PrecompiledHeader_get_enableflags,$$(PCH_NAME),$$(PCH_LINKTARGETMAKEFILENAME),$$(PCH_HEADER)) $$(T_PCH_EXTRA_CXXFLAGS)
+else
+$$(warning No precompiled header available for $$*.cxx .)
+$$(info precompiled header flags : $$(sort $$(PCH_CXXFLAGS) $$(PCH_DEFS)))
+$$(info . object flags : $$(sort $$(T_CXXFLAGS) $$(T_CXXFLAGS_APPEND) $$(DEFS)))
+$$(error Incorrect precompiled header setup or internal gbuild error.)
+$$@ : PCHFLAGS :=
+endif
+endif
+endif
+endif
+endef
+
+ifneq ($(COMPILER_EXTERNAL_TOOL)$(COMPILER_PLUGIN_TOOL),)
+$(call gb_CxxObject_get_target,%) : $(call gb_CxxObject_get_source,$(SRCDIR),%) $(gb_FORCE_COMPILE_TARGET)
+ $(call gb_Output_announce,$*.cxx,$(true),CXX,3)
+ $(call gb_Trace_StartRange,$*.cxx,CXX)
+ $(if $(call gb_LinkTarget__tool_compile_enabled),$(call gb_CxxObject__tool_command,$*,$<,$(COMPILER_PLUGINS)))
+ $(call gb_Trace_EndRange,$*.cxx,CXX)
+else
+$(call gb_CxxObject_get_target,%) : $(call gb_CxxObject_get_source,$(SRCDIR),%)
+ $(call gb_Output_announce,$*.cxx,$(true),$(if $(COMPILER_TEST),CPT,CXX),3)
+ $(call gb_Trace_StartRange,$*.cxx,$(if $(COMPILER_TEST),CPT,CXX))
+ $(eval $(gb_CxxObject__set_pchflags))
+ $(call gb_CObject__command_pattern,$@,$(T_CXXFLAGS) $(T_CXXFLAGS_APPEND) $(if $(COMPILER_TEST),$(gb_COMPILER_TEST_FLAGS)),$<,$(call gb_CxxObject_get_dep_target,$*),$(COMPILER_PLUGINS),$(T_CXX))
+ $(call gb_Trace_EndRange,$*.cxx,$(if $(COMPILER_TEST),CPT,CXX))
+endif
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_CxxObject_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_CxxObject_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_CxxObject_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+
+endif
+
+
+# GenCObject class
+
+gb_GenCObject_get_source = $(WORKDIR)/$(1).c
+
+ifneq ($(COMPILER_EXTERNAL_TOOL)$(COMPILER_PLUGIN_TOOL),)
+$(call gb_GenCObject_get_target,%) : $(gb_FORCE_COMPILE_TARGET)
+ $(call gb_Output_announce,$*.c,$(true),C ,3)
+ $(call gb_Trace_StartRange,$*.c,C )
+ test -f $(call gb_GenCObject_get_source,$*) || (echo "Missing generated source file $(call gb_GenCObject_get_source,$*)" && false)
+ $(if $(call gb_LinkTarget__tool_compile_enabled),$(call gb_CObject__tool_command,$*,$(call gb_GenCObject_get_source,$*),$(COMPILER_PLUGINS)))
+ $(call gb_Trace_EndRange,$*.c,C )
+else
+$(call gb_GenCObject_get_target,%) :
+ $(call gb_Output_announce,$*.c,$(true),C ,3)
+ $(call gb_Trace_StartRange,$*.c,C )
+ test -f $(call gb_GenCObject_get_source,$*) || (echo "Missing generated source file $(call gb_GenCObject_get_source,$*)" && false)
+ $(call gb_CObject__command_pattern,$@,$(T_CFLAGS) $(T_CFLAGS_APPEND),$(call gb_GenCObject_get_source,$*),$(call gb_GenCObject_get_dep_target,$*),$(COMPILER_PLUGINS),$(T_CC))
+ $(call gb_Trace_EndRange,$*.c,C )
+endif
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_GenCObject_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_GenCObject_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_GenCObject_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+
+endif
+
+
+# GenCxxObject class
+
+gb_GenCxxObject_get_source = $(WORKDIR)/$(1).$(gb_LinkTarget_CXX_SUFFIX_$(call gb_LinkTarget__get_workdir_linktargetname,$(2)))
+
+ifneq ($(COMPILER_EXTERNAL_TOOL)$(COMPILER_PLUGIN_TOOL),)
+$(call gb_GenCxxObject_get_target,%) : $(gb_FORCE_COMPILE_TARGET)
+ $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$(GEN_CXX_SOURCE)),$(true),CXX,3)
+ $(call gb_Trace_StartRange,$(subst $(BUILDDIR)/,,$(GEN_CXX_SOURCE)),CXX)
+ test -f $(GEN_CXX_SOURCE) || (echo "Missing generated source file $(GEN_CXX_SOURCE)" && false)
+ $(if $(call gb_LinkTarget__tool_compile_enabled),$(call gb_CxxObject__tool_command,$*,$(GEN_CXX_SOURCE),$(COMPILER_PLUGINS)))
+ $(call gb_Trace_EndRange,$(subst $(BUILDDIR)/,,$(GEN_CXX_SOURCE)),CXX)
+else
+$(call gb_GenCxxObject_get_target,%) :
+ $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$(GEN_CXX_SOURCE)),$(true),CXX,3)
+ $(call gb_Trace_StartRange,$(subst $(BUILDDIR)/,,$(GEN_CXX_SOURCE)),CXX)
+ test -f $(GEN_CXX_SOURCE) || (echo "Missing generated source file $(GEN_CXX_SOURCE)" && false)
+ $(eval $(gb_CxxObject__set_pchflags))
+ $(call gb_CObject__command_pattern,$@,$(T_CXXFLAGS) $(T_CXXFLAGS_APPEND),$(GEN_CXX_SOURCE),$(call gb_GenCxxObject_get_dep_target,$*),$(COMPILER_PLUGINS),$(T_CXX))
+ $(call gb_Trace_EndRange,$(subst $(BUILDDIR)/,,$(GEN_CXX_SOURCE)),CXX)
+endif
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_GenCxxObject_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_GenCxxObject_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_GenCxxObject_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+
+endif
+
+
+# GenCxxClrObject class
+
+gb_GenCxxClrObject_get_source = $(WORKDIR)/$(1).$(gb_LinkTarget_CXX_SUFFIX_$(call gb_LinkTarget__get_workdir_linktargetname,$(2)))
+
+ifneq ($(COMPILER_EXTERNAL_TOOL)$(COMPILER_PLUGIN_TOOL),)
+$(call gb_GenCxxClrObject_get_target,%) : $(gb_FORCE_COMPILE_TARGET)
+ $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$(GEN_CXXCLR_SOURCE)),$(true),CLR,3)
+ $(call gb_Trace_StartRange,$(subst $(BUILDDIR)/,,$(GEN_CXXCLR_SOURCE)),CLR)
+ test -f $(GEN_CXXCLR_SOURCE) || (echo "Missing generated source file $(GEN_CXXCLR_SOURCE)" && false)
+ $(if $(call gb_LinkTarget__tool_compile_enabled),$(call gb_CxxClrObject__tool_command,$*,$(GEN_CXXCLR_SOURCE),$(COMPILER_PLUGINS)))
+ $(call gb_Trace_EndRange,$(subst $(BUILDDIR)/,,$(GEN_CXXCLR_SOURCE)),CLR)
+else
+$(call gb_GenCxxClrObject_get_target,%) :
+ $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$(GEN_CXXCLR_SOURCE)),$(true),CLR,3)
+ $(call gb_Trace_StartRange,$(subst $(BUILDDIR)/,,$(GEN_CXXCLR_SOURCE)),CLR)
+ test -f $(GEN_CXXCLR_SOURCE) || (echo "Missing generated source file $(GEN_CXXCLR_SOURCE)" && false)
+ $(call gb_CObject__command_pattern,$@,$(T_CXXCLRFLAGS) $(T_CXXCLRFLAGS_APPEND),$(GEN_CXXCLR_SOURCE),$(call gb_GenCxxClrObject_get_dep_target,$*),$(COMPILER_PLUGINS),)
+ $(call gb_Trace_EndRange,$(subst $(BUILDDIR)/,,$(GEN_CXXCLR_SOURCE)),CLR)
+endif
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_GenCxxClrObject_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_GenCxxClrObject_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_GenCxxClrObject_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+
+endif
+
+
+# YaccTarget class
+
+# XXX: This is more complicated than necessary, but we cannot just use
+# the generated C++ file as the main target, because we need to let the
+# header depend on that to ensure the header is present before anything
+# tries to use it.
+
+gb_YaccTarget_get_source = $(1)/$(2).y
+
+.PHONY : $(call gb_YaccTarget_get_clean_target,%)
+$(call gb_YaccTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),YAC,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_YaccTarget_get_grammar_target,$*) $(call gb_YaccTarget_get_header_target,$*) $(call gb_YaccTarget_get_target,$*))
+
+$(call gb_YaccTarget_get_target,%) : $(call gb_YaccTarget_get_source,$(SRCDIR),%)
+ $(call gb_YaccTarget__command,$<,$*,$@,$(call gb_YaccTarget_get_header_target,$*),$(call gb_YaccTarget_get_grammar_target,$*))
+
+# call gb_YaccTarget_YaccTarget,yacctarget
+define gb_YaccTarget_YaccTarget
+$(call gb_YaccTarget_get_grammar_target,$(1)) : $(call gb_YaccTarget_get_target,$(1))
+ touch $$@
+$(call gb_YaccTarget_get_header_target,$(1)) : $(call gb_YaccTarget_get_target,$(1))
+ touch $$@
+
+endef
+
+# LexTarget class
+
+gb_LexTarget_get_source = $(1)/$(2).l
+
+.PHONY : $(call gb_LexTarget_get_clean_target,%)
+$(call gb_LexTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),LEX,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_LexTarget_get_scanner_target,$*) $(call gb_LexTarget_get_target,$*))
+
+$(call gb_LexTarget_get_target,%) : $(call gb_LexTarget_get_source,$(SRCDIR),%)
+ $(call gb_Output_announce,$*,$(true),LEX,3)
+ $(call gb_Trace_StartRange,$*,LEX)
+ $(call gb_LexTarget__command,$<,$*,$@,$(call gb_LexTarget_get_scanner_target,$*))
+ $(call gb_Trace_EndRange,$*,LEX)
+
+# gb_LexTarget_LexTarget(scanner-file)
+define gb_LexTarget_LexTarget
+$(call gb_LexTarget_get_scanner_target,$(1)) : $(call gb_LexTarget_get_target,$(1))
+ touch $$@
+
+endef
+
+# gb_LexTarget__command(scanner-file, stem-for-message, done-pseudo-target, source-target)
+define gb_LexTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(3)) && \
+ $(FLEX) $(T_LEXFLAGS) -o$(4) $(1) && touch $(3) )
+endef
+
+
+# ObjCxxObject class
+#
+
+gb_ObjCxxObject_get_source = $(1)/$(2).mm
+
+ifneq ($(COMPILER_EXTERNAL_TOOL)$(COMPILER_PLUGIN_TOOL),)
+$(call gb_ObjCxxObject_get_target,%) : $(call gb_ObjCxxObject_get_source,$(SRCDIR),%) $(gb_FORCE_COMPILE_TARGET)
+ $(call gb_Output_announce,$*.mm,$(true),OCX,3)
+ $(call gb_Trace_StartRange,$*.mm,OCX)
+ $(if $(call gb_LinkTarget__tool_compile_enabled),$(call gb_ObjCxxObject__tool_command,$*,$<,$(COMPILER_PLUGINS)))
+ $(call gb_Trace_EndRange,$*.mm,OCX)
+else
+$(call gb_ObjCxxObject_get_target,%) : $(call gb_ObjCxxObject_get_source,$(SRCDIR),%)
+ $(call gb_Output_announce,$*.mm,$(true),$(if $(COMPILER_TEST),O?X,OCX),3)
+ $(call gb_Trace_StartRange,$*.mm,$(if $(COMPILER_TEST),O?X,OCX))
+ $(call gb_CObject__command_pattern,$@,$(T_OBJCXXFLAGS) $(T_OBJCXXFLAGS_APPEND),$<,$(call gb_ObjCxxObject_get_dep_target,$*),$(COMPILER_PLUGINS),)
+ $(call gb_Trace_EndRange,$*.mm,$(if $(COMPILER_TEST),O?X,OCX))
+endif
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_ObjCxxObject_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_ObjCxxObject_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_ObjCxxObject_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+
+endif
+
+
+# ObjCObject class
+#
+
+gb_ObjCObject_get_source = $(1)/$(2).m
+
+ifneq ($(COMPILER_EXTERNAL_TOOL)$(COMPILER_PLUGIN_TOOL),)
+$(call gb_ObjCObject_get_target,%) : $(call gb_ObjCObject_get_source,$(SRCDIR),%) $(gb_FORCE_COMPILE_TARGET)
+ $(call gb_Output_announce,$*.m,$(true),OCC,3)
+ $(call gb_Trace_StartRange,$*.m,OCC)
+ $(if $(call gb_LinkTarget__tool_compile_enabled),$(call gb_ObjCObject__tool_command,$*,$<,$(COMPILER_PLUGINS)))
+ $(call gb_Trace_EndRange,$*.m,OCC)
+else
+$(call gb_ObjCObject_get_target,%) : $(call gb_ObjCObject_get_source,$(SRCDIR),%)
+ $(call gb_Output_announce,$*.m,$(true),$(if $(COMPILER_TEST),O?C,OCC),3)
+ $(call gb_Trace_StartRange,$*.m,$(if $(COMPILER_TEST),O?C,OCC))
+ $(call gb_CObject__command_pattern,$@,$(T_OBJCFLAGS) $(T_OBJCFLAGS_APPEND),$<,$(call gb_ObjCObject_get_dep_target,$*),$(COMPILER_PLUGINS),)
+ $(call gb_Trace_EndRange,$*.m,$(if $(COMPILER_TEST),O?C,OCC))
+endif
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_ObjCObject_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_ObjCObject_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_ObjCObject_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+
+endif
+
+
+# GenObjCObject class
+
+gb_GenObjCObject_get_source = $(WORKDIR)/$(1).m
+
+ifneq ($(COMPILER_EXTERNAL_TOOL)$(COMPILER_PLUGIN_TOOL),)
+$(call gb_GenObjCObject_get_target,%) : $(gb_FORCE_COMPILE_TARGET)
+ $(call gb_Output_announce,$*.m,$(true),OCC,3)
+ $(call gb_Trace_StartRange,$*.m,OCC)
+ test -f $(call gb_GenObjCObject_get_source,$*) || (echo "Missing generated source file $(call gb_GenObjCObject_get_source,$*)" && false)
+ $(if $(call gb_LinkTarget__tool_compile_enabled),$(call gb_ObjCObject__tool_command,$*,$(call gb_GenObjCObject_get_source,$*),$(COMPILER_PLUGINS)))
+ $(call gb_Trace_EndRange,$*.m,OCC)
+else
+$(call gb_GenObjCObject_get_target,%) :
+ $(call gb_Output_announce,$*.m,$(true),OCC,3)
+ $(call gb_Trace_StartRange,$*.m,OCC)
+ test -f $(call gb_GenObjCObject_get_source,$*) || (echo "Missing generated source file $(call gb_GenObjCObject_get_source,$*)" && false)
+ $(call gb_CObject__command_pattern,$@,$(T_OBJCFLAGS) $(T_OBJCFLAGS_APPEND),$(call gb_GenObjCObject_get_source,$*),$(call gb_GenObjCObject_get_dep_target,$*),$(COMPILER_PLUGINS),)
+ $(call gb_Trace_EndRange,$*.m,OCC)
+endif
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_GenObjCObject_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_GenObjCObject_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_GenObjCObject_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+
+endif
+
+
+# GenObjCxxObject class
+
+gb_GenObjCxxObject_get_source = $(WORKDIR)/$(1).mm
+
+ifneq ($(COMPILER_EXTERNAL_TOOL)$(COMPILER_PLUGIN_TOOL),)
+$(call gb_GenObjCxxObject_get_target,%) : $(gb_FORCE_COMPILE_TARGET)
+ $(call gb_Output_announce,$*.mm,$(true),OCX,3)
+ $(call gb_Trace_StartRange,$*.mm,OCX)
+ test -f $(call gb_GenObjCxxObject_get_source,$*) || (echo "Missing generated source file $(call gb_GenObjCxxObject_get_source,$*)" && false)
+ $(if $(call gb_LinkTarget__tool_compile_enabled),$(call gb_ObjCxxObject__tool_command,$*,$(call gb_GenObjCxxObject_get_source,$*),$(COMPILER_PLUGINS)))
+ $(call gb_Trace_EndRange,$*.mm,OCX)
+else
+$(call gb_GenObjCxxObject_get_target,%) :
+ $(call gb_Output_announce,$*.mm,$(true),OCX,3)
+ $(call gb_Trace_StartRange,$*.mm,OCX)
+ test -f $(call gb_GenObjCxxObject_get_source,$*) || (echo "Missing generated source file $(call gb_GenObjCxxObject_get_source,$*)" && false)
+ $(call gb_CObject__command_pattern,$@,$(T_OBJCXXFLAGS) $(T_OBJCXXFLAGS_APPEND),$(call gb_GenObjCxxObject_get_source,$*),$(call gb_GenObjCxxObject_get_dep_target,$*),$(COMPILER_PLUGINS),)
+ $(call gb_Trace_EndRange,$*.mm,OCX)
+endif
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_GenObjCxxObject_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_GenObjCxxObject_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_GenObjCxxObject_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+
+endif
+
+# GenNasmObject class
+
+gb_GenNasmObject_get_source = $(WORKDIR)/$(1)
+
+$(call gb_GenNasmObject_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),ASM,3)
+ $(call gb_Trace_StartRange,$*,ASM)
+ test -f $(call gb_GenNasmObject_get_source,$*) || (echo "Missing generated source file $(call gb_GenNasmObject_get_source,$*)" && false)
+ mkdir -p $(dir $@) $(dir $(call gb_GenNasmObject_get_dep_target,$*)) && cd $(SRCDIR) && \
+ $(NASM) $(T_NASMFLAGS) $(T_NASMFLAGS_APPEND) -I$(dir $(call gb_GenNasmObject_get_source,$*)) \
+ $(call gb_GenNasmObject_get_source,$*) -o $@ && \
+ echo "$@ : $(call gb_GenNasmObject_get_source,$*)" > $(call gb_GenNasmObject_get_dep_target,$*)
+ $(call gb_Trace_EndRange,$*,ASM)
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_GenNasmObject_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_GenNasmObject_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_GenNasmObject_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+
+endif
+
+
+# CxxClrObject class
+#
+
+gb_CxxClrObject_get_source = $(1)/$(2).cxx
+
+ifneq ($(COMPILER_EXTERNAL_TOOL)$(COMPILER_PLUGIN_TOOL),)
+$(call gb_CxxClrObject_get_target,%) : $(call gb_CxxClrObject_get_source,$(SRCDIR),%) $(gb_FORCE_COMPILE_TARGET)
+ $(call gb_Output_announce,$*.cxx,$(true),CLR,3)
+ $(call gb_Trace_StartRange,$*.cxx,CLR)
+ $(if $(call gb_LinkTarget__tool_compile_enabled),$(call gb_CxxClrObject__tool_command,$*,$<,$(COMPILER_PLUGINS)))
+ $(call gb_Trace_EndRange,$*.cxx,CLR)
+else
+$(call gb_CxxClrObject_get_target,%) : $(call gb_CxxClrObject_get_source,$(SRCDIR),%)
+ $(call gb_Output_announce,$*.cxx,$(true),$(if $(COMPILER_TEST),C?R,CLR),3)
+ $(call gb_Trace_StartRange,$*.cxx,$(if $(COMPILER_TEST),C?R,CLR))
+ $(call gb_CObject__command_pattern,$@,$(T_CXXCLRFLAGS) $(T_CXXCLRFLAGS_APPEND),$<,$(call gb_CxxClrObject_get_dep_target,$*),$(COMPILER_PLUGINS),)
+ $(call gb_Trace_EndRange,$*.cxx,$(if $(COMPILER_TEST),C?R,CLR))
+endif
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_CxxClrObject_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_CxxClrObject_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_CxxClrObject_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+
+endif
+
+
+# AsmObject class
+
+$(call gb_AsmObject_get_target,%) : $(call gb_AsmObject_get_source,$(SRCDIR),%)
+ $(call gb_AsmObject__command,$@,$*,$<,$(call gb_AsmObject_get_dep_target,$*))
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_AsmObject_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_AsmObject_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_AsmObject_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+
+endif
+
+
+# LinkTarget class
+
+gb_LinkTarget_DEFAULTDEFS := $(gb_GLOBALDEFS)
+
+.PHONY : $(WORKDIR)/Clean/LinkTarget/%
+$(WORKDIR)/Clean/LinkTarget/% :
+ $(call gb_Output_announce,$(LINKTARGETMAKEFILENAME),$(false),LNK,4)
+ RESPONSEFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),200,\
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_target,$(object))) \
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_dep_target,$(object))) \
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_dwo_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_dep_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_dwo_target,$(object))) \
+ $(foreach object,$(OBJCOBJECTS),$(call gb_ObjCObject_get_target,$(object))) \
+ $(foreach object,$(OBJCOBJECTS),$(call gb_ObjCObject_get_dep_target,$(object))) \
+ $(foreach object,$(OBJCOBJECTS),$(call gb_ObjCObject_get_dwo_target,$(object))) \
+ $(foreach object,$(OBJCXXOBJECTS),$(call gb_ObjCxxObject_get_target,$(object))) \
+ $(foreach object,$(OBJCXXOBJECTS),$(call gb_ObjCxxObject_get_dep_target,$(object))) \
+ $(foreach object,$(OBJCXXOBJECTS),$(call gb_ObjCxxObject_get_dwo_target,$(object))) \
+ $(foreach object,$(CXXCLROBJECTS),$(call gb_CxxClrObject_get_target,$(object))) \
+ $(foreach object,$(CXXCLROBJECTS),$(call gb_CxxClrObject_get_dep_target,$(object))) \
+ $(foreach object,$(CXXCLROBJECTS),$(call gb_CxxClrObject_get_dwo_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_dep_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_dwo_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_dep_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_dwo_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_dep_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_dwo_target,$(object))) \
+ $(foreach object,$(GENOBJCOBJECTS),$(call gb_GenObjCObject_get_target,$(object))) \
+ $(foreach object,$(GENOBJCOBJECTS),$(call gb_GenObjCObject_get_dep_target,$(object))) \
+ $(foreach object,$(GENOBJCOBJECTS),$(call gb_GenObjCObject_get_dwo_target,$(object))) \
+ $(foreach object,$(GENOBJCXXOBJECTS),$(call gb_GenObjCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENOBJCXXOBJECTS),$(call gb_GenObjCxxObject_get_dep_target,$(object))) \
+ $(foreach object,$(GENOBJCXXOBJECTS),$(call gb_GenObjCxxObject_get_dwo_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_dep_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_dwo_target,$(object))) \
+ $(foreach object,$(GENCXXCLROBJECTS),$(call gb_GenCxxClrObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXCLROBJECTS),$(call gb_GenCxxClrObject_get_dep_target,$(object))) \
+ $(foreach object,$(GENCXXCLROBJECTS),$(call gb_GenCxxClrObject_get_dwo_target,$(object))) \
+ $(call gb_LinkTarget_get_target,$(LINKTARGET)) \
+ $(call gb_LinkTarget_get_dep_target,$(LINKTARGET)) \
+ $(if $(gb_PARTIAL_BUILD),, \
+ $(call gb_LinkTarget_get_dep_libraries_target,$(LINKTARGET)) \
+ $(call gb_LinkTarget_get_dep_externals_target,$(LINKTARGET)) \
+ $(call gb_LinkTarget_get_dep_statics_target,$(LINKTARGET)) \
+ ) \
+ $(call gb_LinkTarget_get_headers_target,$(LINKTARGET)) \
+ $(call gb_LinkTarget_get_objects_list,$(LINKTARGET)) \
+ $(call gb_LinkTarget_get_pch_timestamp,$(LINKTARGETMAKEFILENAME)) \
+ $(call gb_LinkTarget_get_pch_reuse_timestamp,$(LINKTARGETMAKEFILENAME)) \
+ $(ILIBTARGET) \
+ $(AUXTARGETS)) && \
+ cat $${RESPONSEFILE} /dev/null | $(if $(filter WNT,$(OS)),env -i PATH="$$PATH") xargs -n 200 rm -fr && \
+ rm -f $${RESPONSEFILE}
+
+
+# cat the deps of all objects in one file, then we need only open that one file
+# call gb_LinkTarget__command_dep,dep_target,linktargetname
+define gb_LinkTarget__command_dep
+$(call gb_Output_announce,LNK:$(2).d,$(true),DEP,1)
+ $(call gb_Trace_StartRange,LNK:$(2),DEP)
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) && \
+ RESPONSEFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),200,\
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_dep_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_dep_target,$(object))) \
+ $(foreach object,$(OBJCOBJECTS),$(call gb_ObjCObject_get_dep_target,$(object)))\
+ $(foreach object,$(OBJCXXOBJECTS),$(call gb_ObjCxxObject_get_dep_target,$(object)))\
+ $(foreach object,$(CXXCLROBJECTS),$(call gb_CxxClrObject_get_dep_target,$(object)))\
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_dep_target,$(object)))\
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_dep_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_dep_target,$(object))) \
+ $(foreach object,$(GENOBJCOBJECTS),$(call gb_GenObjCObject_get_dep_target,$(object))) \
+ $(foreach object,$(GENOBJCXXOBJECTS),$(call gb_GenObjCxxObject_get_dep_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_dep_target,$(object))) \
+ $(foreach object,$(GENCXXCLROBJECTS),$(call gb_GenCxxClrObject_get_dep_target,$(object))) \
+ ) && \
+ $(call gb_Executable_get_command,concat-deps) $${RESPONSEFILE} > $(1)) && \
+ rm -f $${RESPONSEFILE}
+ $(call gb_Trace_EndRange,LNK:$(2),DEP)
+
+endef
+
+# call gb_LinkTarget__command_objectlist,linktarget
+define gb_LinkTarget__command_objectlist
+TEMPFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),200,\
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_target,$(object))) \
+ $(foreach object,$(OBJCOBJECTS),$(call gb_ObjCObject_get_target,$(object))) \
+ $(foreach object,$(OBJCXXOBJECTS),$(call gb_ObjCxxObject_get_target,$(object))) \
+ $(foreach object,$(CXXCLROBJECTS),$(call gb_CxxClrObject_get_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENOBJCOBJECTS),$(call gb_GenObjCObject_get_target,$(object))) \
+ $(foreach object,$(GENOBJCXXOBJECTS),$(call gb_GenObjCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXCLROBJECTS),$(call gb_GenCxxClrObject_get_target,$(object))) \
+ $(PCHOBJS) \
+ $(foreach extraobjectlist,$(EXTRAOBJECTLISTS),$(shell cat $(extraobjectlist)))) && \
+mv $${TEMPFILE} $(1)
+
+endef
+
+$(WORKDIR)/LinkTarget/%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+# Target for the .exports of the shared library, to speed up incremental build.
+# This deliberately does nothing if the file exists; the file is actually
+# written in gb_LinkTarget__command_dynamiclink.
+# Put this pattern rule here so it overrides the one below.
+# (this is rather ugly: because of % the functions cannot be used)
+$(WORKDIR)/LinkTarget/Library/%.exports :
+ $(if $(wildcard $@),,mkdir -p $(dir $@) && touch $@)
+
+# This recipe actually also builds the dep-target as a side-effect, which
+# is an optimization to reduce incremental build time.
+# (with exception for concat-dep executable itself which does not exist yet...)
+$(WORKDIR)/LinkTarget/% : $(gb_Helper_MISCDUMMY)
+ $(call gb_LinkTarget__command_impl,$@,$*)
+
+# call gb_LinkTarget__make_installed_rule,linktarget
+define gb_LinkTarget__make_installed_rule
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_LinkTarget_get_headers_target,$(1))
+ $$(call gb_LinkTarget__command_impl,$(call gb_LinkTarget_get_target,$(1)),$(call gb_LinkTarget__get_workdir_linktargetname,$(1)))
+
+endef
+
+define gb_LinkTarget__add_linked_libs
+$(call gb_LinkTarget_get_target,$(1)) : LINKED_LIBS += $(2)
+
+endef
+
+# it's not possible to use a pattern rule for files in INSTDIR because
+# it would inevitably conflict with the pattern rule for Package
+# (especially since external libraries are delivered via Package)
+# call gb_LinkTarget__command_impl,linktargettarget,linktargetname
+define gb_LinkTarget__command_impl
+ $(if $(gb_FULLDEPS),
+ $(if $(ENABLE_CUSTOMTARGET_COMPONENTS),$(if $(gb_PARTIAL_BUILD),,
+ $(call gb_LinkTarget__command_dep_libraries,$(call gb_LinkTarget_get_dep_libraries_target,$(2)).tmp,$(2))
+ mv $(call gb_LinkTarget_get_dep_libraries_target,$(2)).tmp $(call gb_LinkTarget_get_dep_libraries_target,$(2))
+ $(call gb_LinkTarget__command_dep_externals,$(call gb_LinkTarget_get_dep_externals_target,$(2)).tmp,$(2))
+ mv $(call gb_LinkTarget_get_dep_externals_target,$(2)).tmp $(call gb_LinkTarget_get_dep_externals_target,$(2))
+ $(call gb_LinkTarget__command_dep_statics,$(call gb_LinkTarget_get_dep_statics_target,$(2)).tmp,$(2))
+ mv $(call gb_LinkTarget_get_dep_statics_target,$(2)).tmp $(call gb_LinkTarget_get_dep_statics_target,$(2))))
+ $(if $(findstring concat-deps,$(2)),,
+ $(call gb_LinkTarget__command_dep,$(call gb_LinkTarget_get_dep_target,$(2)).tmp,$(2))
+ mv $(call gb_LinkTarget_get_dep_target,$(2)).tmp $(call gb_LinkTarget_get_dep_target,$(2))))
+ $(if $(filter $(2),$(foreach lib,$(gb_MERGEDLIBS),$(call gb_Library__get_workdir_linktargetname,$(lib)))),
+ $(if $(filter $(true),$(call gb_LinkTarget__is_build_lib,$(2))),
+ $(call gb_LinkTarget__command,$(1),$(2)),
+ mkdir -p $(dir $(1)) && echo invalid - merged lib > $(1)
+ $(if $(SOVERSIONSCRIPT),&& echo invalid - merged lib > $(WORKDIR)/LinkTarget/$(2))),
+ $(if $(filter-out CompilerTest,$(TARGETTYPE)),
+ $(call gb_LinkTarget__command,$(1),$(2))))
+ $(call gb_LinkTarget__command_objectlist,$(WORKDIR)/LinkTarget/$(2).objectlist)
+endef
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,%) : $(call gb_Executable_get_runtime_dependencies,concat-deps)
+ $(call gb_LinkTarget__command_dep,$@,$*)
+
+$(dir $(call gb_LinkTarget_get_dep_target,%))/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+ifeq ($(ENABLE_CUSTOMTARGET_COMPONENTS),TRUE)
+ifeq (,$(gb_PARTIAL_BUILD))
+
+define gb_LinkTarget__static_dep_x_template
+
+define gb_LinkTarget__command_dep_$(1)
+$$(call gb_Output_announce,LNK:$$(2).d.$(1),$$(true),DEP,1)
+mkdir -p $$(dir $$(1)) && \
+TEMPFILE=$$(call gb_var2file,$$(shell $$(gb_MKTEMP)),200,\
+ $$(call gb_LinkTarget__get_all_$(1),$$(2))) && \
+ $$(call gb_Helper_replace_if_different_and_touch,$$$${TEMPFILE},$$(1))
+
+endef
+
+$$(call gb_LinkTarget_get_dep_$(1)_target,%) : ;
+ $$(call gb_LinkTarget__command_dep_$(1),$$@,$$*)
+
+endef # gb_LinkTarget__static_dep_x_template
+
+$(eval $(call gb_LinkTarget__static_dep_x_template,libraries))
+$(eval $(call gb_LinkTarget__static_dep_x_template,externals))
+$(eval $(call gb_LinkTarget__static_dep_x_template,statics))
+
+endif # !gb_PARTIAL_BUILD
+endif # ENABLE_CUSTOMTARGET_COMPONENTS
+endif # gb_FULLDEPS
+
+# Ok, this is some dark voodoo: When declaring a linktarget with
+# gb_LinkTarget_LinkTarget we set SELF in the headertarget to name of the
+# target. When the rule for the headertarget is executed and SELF does not
+# match the target name, we are depending on a linktarget that was never
+# declared. In a full build exclusively in gbuild that should never happen.
+define gb_LinkTarget__get_headers_check
+ifneq ($$(SELF),$$*)
+$$(eval $$(call gb_Output_error,used LinkTarget $$* not defined))
+endif
+$$@ : COMMAND := $$(call gb_Helper_abbreviate_dirs, touch $$@)
+
+endef
+
+$(WORKDIR)/Headers/%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+# sadly because of the subdirectories can't have pattern deps on .dir here
+$(WORKDIR)/Headers/% :
+ $(eval $(gb_LinkTarget__get_headers_check))
+ $(COMMAND)
+
+# Explanation of some of the targets:
+# - gb_LinkTarget_get_headers_target is the target that guarantees all headers
+# from the linked against libraries and the linktargets own generated headers
+# are generated.
+# - gb_LinkTarget_get_target links the objects into a file in WORKDIR.
+# gb_LinkTarget_get_target depends on gb_LinkTarget_get_headers_target.
+# gb_LinkTarget_get_target depends additionally on the objects, which in turn
+# depend build-order only on the gb_LinkTarget_get_headers_target. The build
+# order-only dependency ensures all headers to be there for compiling and
+# dependency generation without causing all objects to be rebuild when one
+# header changes. Only the ones with an explicit dependency in their generated
+# dependency file will be rebuild.
+#
+# gb_LinkTarget_get_target is the target that links the objects into a file in
+# WORKDIR
+# Explanation of some of the variables:
+# - AUXTARGETS are the additionally generated files that need to be cleaned out
+# on clean.
+# - PCH_CXXFLAGS and PCH_DEFS are the flags that the precompiled headers will
+# be compiled with. They should never be overridden in a single object
+# files.
+# - TARGETTYPE is the type of linktarget as some platforms need very different
+# command to link different targettypes.
+# - LIBRARY_X64 is only relevant for building a x64 library on windows.
+# - PE_X86 is only relevant for building a x86 binaries on Windows.
+#
+# Since most variables are set on the linktarget and not on the object, the
+# object learns about these setting via GNU makes scoping of target variables.
+# Therefore it is important that objects are only directly depended on by the
+# linktarget. This for example means that you cannot build a single object
+# alone, because then you would directly depend on the object.
+#
+# A note about flags: because the overriding the global variables with a target
+# local variable of the same name is considered obscure, the target local
+# variables have a T_ prefix.
+#
+# call gb_LinkTarget_LinkTarget,linktarget,linktargetmakefilename,layer
+define gb_LinkTarget_LinkTarget
+$(call gb_LinkTarget_get_clean_target,$(1)) : LINKTARGET := $(1)
+$(call gb_LinkTarget_get_clean_target,$(1)) : LINKTARGETMAKEFILENAME := $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : AUXTARGETS :=
+$(call gb_LinkTarget_get_headers_target,$(1)) : SELF := $(call gb_LinkTarget__get_workdir_linktargetname,$(1))
+$(call gb_LinkTarget_get_headers_target,$(1)) : \
+ | $(dir $(call gb_LinkTarget_get_headers_target,$(1))).dir \
+ $(dir $(call gb_LinkTarget_get_target,$(1))).dir \
+ $(dir $(WORKDIR)/LinkTarget/$(call gb_LinkTarget__get_workdir_linktargetname,$(1))).dir
+$(call gb_LinkTarget_get_target,$(1)) : ILIBTARGET :=
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : COBJECTS :=
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : CXXOBJECTS :=
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : YACCOBJECT :=
+$(call gb_LinkTarget_get_target,$(1)) : T_YACCFLAGS := $$(gb_LinkTarget_YYACFLAGS) $(YACCFLAGS)
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : LEXOBJECT :=
+$(call gb_LinkTarget_get_target,$(1)) : T_LEXFLAGS := $$(gb_LinkTarget_LEXFLAGS) $(LEXFLAGS)
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : OBJCOBJECTS :=
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : OBJCXXOBJECTS :=
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : CXXCLROBJECTS :=
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : ASMOBJECTS :=
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : GENCOBJECTS :=
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : GENCXXOBJECTS :=
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : GENOBJCOBJECTS :=
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : GENNASMOBJECTS :=
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : GENOBJCXXOBJECTS :=
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : GENCXXCLROBJECTS :=
+$(call gb_LinkTarget_get_target,$(1)) : T_CFLAGS := $$(gb_LinkTarget_CFLAGS)
+$(call gb_LinkTarget_get_target,$(1)) : T_CFLAGS_APPEND :=
+$(call gb_LinkTarget_get_target,$(1)) : T_CXXFLAGS := $$(gb_LinkTarget_CXXFLAGS)
+$(call gb_LinkTarget_get_target,$(1)) : T_CXXFLAGS_APPEND :=
+$(call gb_LinkTarget_get_target,$(1)) : PCH_CXXFLAGS := $$(gb_LinkTarget_CXXFLAGS)
+$(call gb_LinkTarget_get_target,$(1)) : OBJECT_HAS_EXTRA_CXXFLAGS :=
+$(call gb_LinkTarget_get_target,$(1)) : T_OBJCXXFLAGS := $$(gb_LinkTarget_OBJCXXFLAGS)
+$(call gb_LinkTarget_get_target,$(1)) : T_OBJCXXFLAGS_APPEND :=
+$(call gb_LinkTarget_get_target,$(1)) : T_OBJCFLAGS := $$(gb_LinkTarget_OBJCFLAGS)
+$(call gb_LinkTarget_get_target,$(1)) : T_OBJCFLAGS_APPEND :=
+$(call gb_LinkTarget_get_target,$(1)) : T_NASMFLAGS := $$(NAFLAGS)
+$(call gb_LinkTarget_get_target,$(1)) : T_NASMFLAGS_APPEND :=
+$(call gb_LinkTarget_get_target,$(1)) : T_CXXCLRFLAGS := $$(gb_LinkTarget_CXXCLRFLAGS)
+$(call gb_LinkTarget_get_target,$(1)) : T_CXXCLRFLAGS_APPEND :=
+$(call gb_LinkTarget_get_target,$(1)) : DEFS := $$(gb_LinkTarget_DEFAULTDEFS) $(CPPFLAGS)
+$(call gb_LinkTarget_get_target,$(1)) : PCH_DEFS := $$(gb_LinkTarget_DEFAULTDEFS) $(CPPFLAGS)
+$(call gb_LinkTarget_get_target,$(1)) : INCLUDE := -I$$(SRCDIR)/include $$(gb_LinkTarget_INCLUDE)
+$(call gb_LinkTarget_get_target,$(1)) : T_LDFLAGS := $$(gb_LinkTarget_LDFLAGS) $(call gb_LinkTarget_get_linksearchpath_for_layer,$(3)) $(call gb_LinkTarget__get_ldflags,$(2))
+$(call gb_LinkTarget_get_target,$(1)) : LINKED_LIBS :=
+$(call gb_LinkTarget_get_target,$(1)) : LINKED_STATIC_LIBS :=
+$(call gb_LinkTarget_get_target,$(1)) : T_LIBS :=
+$(call gb_LinkTarget_get_target,$(1)) : T_STDLIBS_CXX := $(gb_STDLIBS_CXX)
+$(call gb_LinkTarget_get_target,$(1)) : TARGETTYPE :=
+$(call gb_LinkTarget_get_target,$(1)) : LIBRARY_X64 :=
+$(call gb_LinkTarget_get_target,$(1)) : PCH_NAME :=
+$(call gb_LinkTarget_get_target,$(1)) : PCH_HEADER :=
+$(call gb_LinkTarget_get_target,$(1)) : PCH_LINKTARGETMAKEFILENAME :=
+$(call gb_LinkTarget_get_target,$(1)) : PCHOBJS :=
+$(call gb_LinkTarget_get_target,$(1)) : PCHOBJEX :=
+$(call gb_LinkTarget_get_target,$(1)) : PCHOBJNOEX :=
+$(call gb_LinkTarget_get_target,$(1)) : T_PCH_EXTRA_CXXFLAGS :=
+$(call gb_LinkTarget_get_target,$(1)) : PE_X86 :=
+$(call gb_LinkTarget_get_target,$(1)) : PDBFILE :=
+$(call gb_LinkTarget_get_target,$(1)) : TARGETGUI :=
+$(call gb_LinkTarget_get_target,$(1)) : EXTRAOBJECTLISTS :=
+$(call gb_LinkTarget_get_target,$(1)) : NATIVERES :=
+$(call gb_LinkTarget_get_target,$(1)) : VISIBILITY :=
+$(call gb_LinkTarget_get_target,$(1)) : WARNINGS_NOT_ERRORS :=
+$(call gb_LinkTarget_get_target,$(1)) : WARNINGS_DISABLED :=
+$(call gb_LinkTarget_get_target,$(1)) : PLUGIN_WARNINGS_AS_ERRORS :=
+$(call gb_LinkTarget_get_target,$(1)) : EXTERNAL_CODE :=
+$(call gb_LinkTarget_get_target,$(1)) : SOVERSIONSCRIPT :=
+$(call gb_LinkTarget_get_target,$(1)) : COMPILER_TEST :=
+$(call gb_LinkTarget_get_target,$(1)) : T_SYMBOLS := $(if $(call gb_target_symbols_enabled,$(2)),$(true),$(false))
+$(call gb_LinkTarget_get_target,$(1)) : T_FORCE_COMPILE := $(if $(call gb_LinkTarget__force_compile,$(2)),$(true),$(false))
+$(call gb_LinkTarget_get_target,$(1)) : T_CC :=
+$(call gb_LinkTarget_get_target,$(1)) : T_CXX :=
+$(call gb_LinkTarget_get_target,$(1)) : T_USE_LD := $(USE_LD)
+$(call gb_LinkTarget_get_target,$(1)) : T_LTOFLAGS := $(gb_LTOFLAGS)
+$(call gb_LinkTarget_get_target,$(1)) : T_PREJS :=
+
+ifeq ($(gb_FULLDEPS),$(true))
+ifeq (depcache:,$(filter depcache,$(.FEATURES)):$(gb_PARTIAL_BUILD))
+-includedepcache $(call gb_LinkTarget_get_dep_target,$(1))
+else
+-include $(call gb_LinkTarget_get_dep_target,$(1))
+endif
+$(call gb_LinkTarget_get_dep_target,$(1)) : COBJECTS :=
+$(call gb_LinkTarget_get_dep_target,$(1)) : CXXOBJECTS :=
+$(call gb_LinkTarget_get_dep_target,$(1)) : OBJCOBJECTS :=
+$(call gb_LinkTarget_get_dep_target,$(1)) : OBJCXXOBJECTS :=
+$(call gb_LinkTarget_get_dep_target,$(1)) : CXXCLROBJECTS :=
+$(call gb_LinkTarget_get_dep_target,$(1)) : ASMOBJECTS :=
+$(call gb_LinkTarget_get_dep_target,$(1)) : GENCOBJECTS :=
+$(call gb_LinkTarget_get_dep_target,$(1)) : GENCXXOBJECTS :=
+$(call gb_LinkTarget_get_dep_target,$(1)) : GENOBJCOBJECTS :=
+$(call gb_LinkTarget_get_dep_target,$(1)) : GENOBJCXXOBJECTS :=
+$(call gb_LinkTarget_get_dep_target,$(1)) : GENNASMOBJECTS :=
+$(call gb_LinkTarget_get_dep_target,$(1)) : GENCXXCLROBJECTS :=
+$(call gb_LinkTarget_get_dep_target,$(1)) : YACCOBJECTS :=
+endif # gb_FULLDEPS
+
+gb_LinkTarget_CXX_SUFFIX_$(call gb_LinkTarget__get_workdir_linktargetname,$(1)) := cxx
+
+# installed linktargets need a rule to build!
+$(if $(findstring $(INSTDIR),$(1)),$(call gb_LinkTarget__make_installed_rule,$(1)))
+
+$(call gb_PrecompiledHeader_generate_timestamp_rule,$(2))
+
+endef # gb_LinkTarget_LinkTarget
+
+# call gb_LinkTarget_set_soversion_script,linktarget,soversionscript
+define gb_LinkTarget_set_soversion_script
+$(call gb_LinkTarget_get_target,$(1)) : $(2)
+$(call gb_LinkTarget_get_target,$(1)) : SOVERSIONSCRIPT := $(2)
+
+endef
+
+# call gb_LinkTarget_add_defs,linktarget,defines
+define gb_LinkTarget_add_defs
+$(call gb_LinkTarget_get_target,$(1)) : DEFS += $(2)
+$(call gb_LinkTarget_get_target,$(1)) : PCH_DEFS += $(2)
+endef
+
+# call gb_LinkTarget_add_cflags,linktarget,cflags
+define gb_LinkTarget_add_cflags
+$(call gb_LinkTarget_get_target,$(1)) : T_CFLAGS_APPEND += $(2)
+endef
+
+# call gb_LinkTarget_add_cxxflags,linktarget,cxxflags
+define gb_LinkTarget_add_cxxflags
+$(call gb_LinkTarget_get_target,$(1)) : T_CXXFLAGS_APPEND += $(2)
+$(call gb_LinkTarget_get_target,$(1)) : PCH_CXXFLAGS += $(2)
+endef
+
+# call gb_LinkTarget_add_objcxxflags,linktarget,objcxxflags
+define gb_LinkTarget_add_objcxxflags
+$(call gb_LinkTarget_get_target,$(1)) : T_OBJCXXFLAGS_APPEND += $(2)
+endef
+
+# call gb_LinkTarget_add_objcflags,linktarget,objcflags
+define gb_LinkTarget_add_objcflags
+$(call gb_LinkTarget_get_target,$(1)) : T_OBJCFLAGS_APPEND += $(2)
+
+endef
+
+# call gb_LinkTarget_add_nasmflags,linktarget,nasmflags
+define gb_LinkTarget_add_nasmflags
+$(call gb_LinkTarget_get_target,$(1)) : T_NASMFLAGS_APPEND += $(2)
+endef
+
+# call gb_LinkTarget_add_cxxclrflags,linktarget,cxxclrflags
+define gb_LinkTarget_add_cxxclrflags
+$(call gb_LinkTarget_get_target,$(1)) : T_CXXCLRFLAGS_APPEND += $(2)
+endef
+
+# call gb_LinkTarget__add_include,linktarget,includes
+define gb_LinkTarget__add_include
+$(call gb_LinkTarget_get_target,$(1)) : INCLUDE += -I$(2)
+
+endef
+
+# call gb_LinkTarget__check_srcdir_paths,linktarget,includepaths
+define gb_LinkTarget__check_srcdir_paths
+$(if $(filter-out $(wildcard $(2)),$(2)),\
+ $(call gb_Output_error,gb_LinkTarget_set_include: include paths $(filter-out $(wildcard $(2)),$(2)) do not exist) \
+)
+endef
+
+# call gb_LinkTarget_set_include,linktarget,includes
+define gb_LinkTarget_set_include
+$(call gb_LinkTarget__check_srcdir_paths,$(1),\
+ $(patsubst -I%,%,$(filter -I$(SRCDIR)/%,$(filter-out -I$(INSTDIR)/% -I$(WORKDIR)/%,$(2)))))
+$(call gb_LinkTarget_get_target,$(1)) : INCLUDE := $(2)
+
+endef
+
+# call gb_LinkTarget_add_ldflags,linktarget,ldflags
+define gb_LinkTarget_add_ldflags
+$(call gb_LinkTarget_get_target,$(1)) : T_LDFLAGS += $(2)
+
+endef
+
+# real use in RepositoryExternal.mk
+# call gb_LinkTarget_set_ldflags,linktarget,ldflags
+define gb_LinkTarget_set_ldflags
+$(call gb_LinkTarget_get_target,$(1)) : T_LDFLAGS := $(2)
+
+endef
+
+# call gb_LinkTarget_add_libs,linktarget,libs
+define gb_LinkTarget_add_libs
+$(call gb_LinkTarget_get_target,$(1)) : T_LIBS += $(2)
+$(if $(call gb_LinkTarget__is_merged,$(1)),\
+ $(call gb_Library_get_linktarget_target,merged) : T_LIBS += $(2))
+ifeq ($(ENABLE_CUSTOMTARGET_COMPONENTS),TRUE)
+$(if $(gb_DEBUG_STATIC),$$(info $$(call gb_LinkTarget__get_all_libraries_var,$(1)) += $(filter-out $(call gb_LinkTarget__get_all_libraries,$(1)),$(patsubst %,$(gb_LinkTarget__syslib),$(2)))))
+$$(eval $$(call gb_LinkTarget__get_all_libraries_var,$(1)) += $(filter-out $(call gb_LinkTarget__get_all_libraries,$(1)),$(patsubst %,$(gb_LinkTarget__syslib),$(2))))
+ifeq (,$(gb_PARTIAL_BUILD))
+$(call gb_LinkTarget_get_target,$(1)) : LINKED_LIBS += $(filter-out $(call gb_LinkTarget__get_all_libraries,$(1)),$(patsubst %,$(gb_LinkTarget__syslib),$(2)))
+endif
+endif
+
+endef
+
+# remove platform specific standard libraries for linktarget $(1)
+# assumption is that adding these standard libs is always useful, but in very
+# exceptional cases this disable method may be used
+# call gb_LinkTarget_disable_standard_system_libs,linktarget
+define gb_LinkTarget_disable_standard_system_libs
+$(call gb_LinkTarget_get_target,$(1)) : T_LIBS := $$(filter-out $$(gb_STDLIBS),$$(T_LIBS))
+$(call gb_LinkTarget_get_target,$(1)) : T_STDLIBS_CXX :=
+
+endef
+
+# call gb_LinkTarget__use_api,linktarget,api
+define gb_LinkTarget__use_api
+$(call gb_LinkTarget_get_headers_target,$(1)) : $(call gb_UnoApiHeadersTarget_get_target,$(2))
+$(call gb_LinkTarget__add_include,$(1),$(call gb_UnoApiHeadersTarget_get_dir,$(2)))
+
+endef
+
+# call gb_LinkTarget_use_api,linktarget,apis
+define gb_LinkTarget_use_api
+$(foreach api,$(2),$(call gb_LinkTarget__use_api,$(1),$(api)))
+
+endef
+
+# call gb_LinkTarget_use_udk_api,linktarget
+define gb_LinkTarget_use_udk_api
+$(call gb_LinkTarget__use_api,$(1),udkapi)
+endef
+
+# call gb_LinkTarget_use_sdk_api,linktarget
+define gb_LinkTarget_use_sdk_api
+$(call gb_LinkTarget__use_api,$(1),udkapi)
+$(call gb_LinkTarget__use_api,$(1),offapi)
+endef
+
+# call gb_LinkTarget__use_internal_api_one,linktarget,api,apiprefix
+define gb_LinkTarget__use_internal_api_one
+$(call gb_LinkTarget_get_headers_target,$(1)) :| \
+ $(call gb_UnoApiHeadersTarget_get_$(3)target,$(2))
+$(call gb_LinkTarget__add_include,$(1),$(call gb_UnoApiHeadersTarget_get_$(3)dir,$(2)))
+
+endef
+
+# call gb_LinkTarget__use_internal_api,linktarget,apis,apiprefix
+define gb_LinkTarget__use_internal_api
+$(foreach api,$(2),$(call gb_LinkTarget__use_internal_api_one,$(1),$(api),$(3)))
+
+endef
+
+# call gb_LinkTarget_use_internal_api,linktarget,api
+define gb_LinkTarget_use_internal_api
+$(call gb_LinkTarget__use_internal_api,$(1),$(2))
+
+endef
+
+# call gb_LinkTarget_use_internal_bootstrap_api,linktarget,api
+define gb_LinkTarget_use_internal_bootstrap_api
+$(call gb_LinkTarget__use_internal_api,$(1),$(2),bootstrap_)
+
+endef
+
+# call gb_LinkTarget_use_internal_comprehensive_api,linktarget,api
+define gb_LinkTarget_use_internal_comprehensive_api
+$(call gb_LinkTarget__use_internal_api,$(1),$(2),comprehensive_)
+
+endef
+
+define gb_PrintDeps_info
+$(info LibraryDep: $(1) links against $(2))
+endef
+
+# returns $(true), if the target class really calls a linker.
+# call gb_LinkTarget_does_real_link,linktarget
+gb_LinkTarget_does_real_link = $(if $(filter Executable CppunitTest $(if $(DISABLE_DYNLOADING),,Library), \
+ $(call gb_LinkTarget__get_workdir_linktargetclass,$(1))),$(true))
+
+# avoid problem when a module is built partially but other modules that define
+# needed libraries is not yet built: prevent invocation of pattern rule
+# for library with invalid parameters by depending on the header target
+define gb_LinkTarget__lib_dummy_depend
+$(call gb_Library_get_target,$(1)) :| $(call gb_Library_get_headers_target,$(1))
+
+endef
+
+define gb_LinkTarget__generate_all_x_accessors
+gb_LinkTarget__get_all_$(1)_var = $$(call gb_LinkTarget__get_workdir_linktargetname,$$(1))<>ALL_$(2)
+gb_LinkTarget__get_all_$(1) = $$($$(call gb_LinkTarget__get_all_$(1)_var,$$(1)))
+gb_Library__get_all_$(1) = $$($$(call gb_LinkTarget__get_all_$(1)_var,$$(call gb_Library_get_linktarget,$$(1))))
+gb_Executable__get_all_$(1) = $$($$(call gb_LinkTarget__get_all_$(1)_var,$$(call gb_Executable_get_linktarget,$$(1))))
+gb_ExternalProject__get_all_$(1) = $$($$(call gb_LinkTarget__get_all_$(1)_var,$$(call gb_ExternalProject__get_workdir_linktargetname,$$(1))))
+gb_CppunitTest__get_all_$(1) = $$($$(call gb_LinkTarget__get_all_$(1)_var,$$(call gb_CppunitTest__get_workdir_linktargetname,$$(1))))
+
+endef
+
+$(eval $(call gb_LinkTarget__generate_all_x_accessors,libraries,LIBRARIES))
+gb_LinkTarget__filter_lo_libraries = $(filter-out $(gb_LinkTarget__syslib),$(1))
+gb_LinkTarget__get_all_lo_libraries = $(call gb_LinkTarget__filter_lo_libraries,$(call gb_LinkTarget__get_all_libraries,$(1)))
+gb_LinkTarget__filter_sys_libraries = $(filter $(gb_LinkTarget__syslib),$(1))
+gb_LinkTarget__get_all_sys_libraries = $(call gb_LinkTarget__filter_sys_libraries,$(call gb_LinkTarget__get_all_libraries,$(1)))
+$(eval $(call gb_LinkTarget__generate_all_x_accessors,externals,EXTERNALS))
+$(eval $(call gb_LinkTarget__generate_all_x_accessors,statics,STATICS))
+
+# call gb_LinkTarget__register_type,type,linktarget,type list
+define gb_LinkTarget__register_type
+ifeq ($(ENABLE_CUSTOMTARGET_COMPONENTS),TRUE)
+ifeq (,$(DISABLE_DYNLOADING))
+$$(error ENABLE_CUSTOMTARGET_COMPONENTS just works with DISABLE_DYNLOADING)
+endif
+$(foreach type,$(3),$(if $(filter $(type),$(call gb_LinkTarget__get_all_$(1),$(2))),, \
+ $(if $(gb_DEBUG_STATIC),$$(info $(call gb_LinkTarget__get_all_$(1)_var,$(2)) += $(type))) \
+ $$(eval $(call gb_LinkTarget__get_all_$(1)_var,$(2)) += $(type)) \
+))
+endif
+
+endef
+
+# call gb_LinkTarget__use_libraries,linktarget,requestedlibs,actuallibs,linktargetmakefilename
+define gb_LinkTarget__use_libraries
+
+# used by bin/module-deps.pl
+ifneq ($(ENABLE_PRINT_DEPS),)
+# exclude libraries in Library_merged
+ifeq ($(filter $(1),$(foreach lib,$(gb_MERGEDLIBS),$(call gb_Library_get_linktarget,$(lib)))),)
+$$(eval $$(call gb_PrintDeps_info,$(4),$(3)))
+endif
+endif
+
+$(call gb_LinkTarget_get_target,$(1)) : LINKED_LIBS += $(3)
+
+ifeq (,$(DISABLE_DYNLOADING))
+# depend on the exports of the library, not on the library itself
+# for faster incremental builds when the ABI is unchanged.
+# export files are created from the library, so this also ensures the library exists.
+$(foreach lib,$(call gb_LinkTarget__filter_lo_libraries,$(3)),$(if $(filter $(lib),$(gb_Library_KNOWNLIBS)), \
+ $$(eval $(call gb_LinkTarget_get_target,$(1)) : $(call gb_Library_get_exports_target,$(lib))) \
+))
+
+else # DISABLE_DYNLOADING
+# depend on the now-static libraries themself, but only if the target actually links to it
+ifneq (,$(call gb_LinkTarget_does_real_link,$(1)))
+$(call gb_LinkTarget_get_target,$(1)) : T_LIBS += $(call gb_LinkTarget__filter_sys_libraries,$(3))
+$(if $(filter-out Library,gb_LinkTarget__get_workdir_linktargetclass,$(1)), \
+ $(foreach lib,$(call gb_LinkTarget__filter_lo_libraries,$(3)),$(if $(filter $(lib),$(gb_Library_KNOWNLIBS)), \
+ $$(eval $(call gb_LinkTarget_get_target,$(1)) : $(call gb_Library_get_linktarget_target,$(lib))) \
+ )))
+endif
+endif # DISABLE_DYNLOADING
+
+$(call gb_LinkTarget__register_type,libraries,$(1),$(3))
+
+$(foreach lib,$(call gb_LinkTarget__filter_lo_libraries,$(2)),$(if $(filter $(lib),$(gb_Library_KNOWNLIBS)), \
+ $(eval $(call gb_LinkTarget_get_headers_target,$(1)) : $(call gb_Library_get_headers_target,$(lib))) \
+ $(call gb_LinkTarget__lib_dummy_depend,$(lib)) \
+))
+
+endef # gb_LinkTarget__use_libraries
+
+# libraries which are merged but need to be built for gb_BUILD_HELPER_TOOLS
+gb_BUILD_HELPER_LIBS := $(foreach lib, \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ i18nlangtag \
+ reg \
+ sal \
+ salhelper \
+ sax \
+ store \
+ tl \
+ ucbhelper \
+ unoidl \
+ xmlreader \
+ , $(call gb_Library__get_workdir_linktargetname,$(lib)))
+
+# tools libmerged depends on, so they link against gb_BUILD_HELPER_LIBS
+gb_BUILD_HELPER_TOOLS := $(foreach exe,\
+ cppumaker \
+ svidl \
+ unoidl-check \
+ unoidl-write \
+ , $(call gb_Executable__get_workdir_linktargetname,$(exe)))
+
+# call gb_LinkTarget__is_build_lib,linktargetname
+define gb_LinkTarget__is_build_lib
+$(if $(filter $(call gb_LinkTarget__get_workdir_linktargetname,$(1)),$(call gb_BUILD_HELPER_LIBS)),$(true))
+endef
+
+# call gb_LinkTarget__is_build_tool,linktargetname
+define gb_LinkTarget__is_build_tool
+$(if $(filter $(call gb_LinkTarget__get_workdir_linktargetname,$(1)),$(call gb_BUILD_HELPER_TOOLS)),$(true))
+endef
+
+define gb_LinkTarget__is_merged
+$(filter $(1),$(foreach lib,$(gb_MERGEDLIBS),$(call gb_Library_get_linktarget,$(lib))))
+endef
+
+# call gb_LinkTarget_use_libraries,linktarget,libs
+define gb_LinkTarget_use_libraries
+ifneq (,$$(filter-out $(gb_Library_KNOWNLIBS) $(gb_LinkTarget__syslib),$(2)))
+$$(eval $$(call gb_Output_info,currently known libraries are: $(sort $(gb_Library_KNOWNLIBS)),ALL))
+$$(eval $$(call gb_Output_error,Cannot link against library/libraries '$$(filter-out $(gb_Library_KNOWNLIBS) $(gb_LinkTarget__syslib),$(2))'. Libraries must be registered in Repository.mk or RepositoryExternal.mk))
+endif
+ifneq (,$$(filter $(2),$(gb_Library_KNOWNPLUGINS)))
+ifneq (,$$(filter $(1),$$(foreach plugin,$(gb_Library_KNOWNPLUGINS),$(call gb_Library__get_workdir_linktargetname,$(plugin)))))
+$$(eval $$(call gb_Output_error,Cannot link against plugin library/libraries '$$(filter $(2),$(gb_Library_KNOWNPLUGINS))'. Only plugins are allowed to do that.))
+endif
+endif
+
+ifeq ($(call gb_LinkTarget__is_build_tool,$(1))$(call gb_LinkTarget__is_build_lib,$(1)),$(true))
+$(call gb_LinkTarget__use_libraries,$(1),$(2),$(2),$(4))
+else
+# $$(3) = Always just depend on non-merged libs. If any dependency is merged, but you aren't, also depend on "merged".
+$(call gb_LinkTarget__use_libraries,$(1),$(2),$(strip \
+ $(filter-out $(gb_MERGEDLIBS),$(2)) \
+ $(if $(filter $(gb_MERGEDLIBS),$(2)),$(if $(call gb_LinkTarget__is_merged,$(1)),,merged)) \
+ ),$(4))
+endif
+
+endef
+
+# avoid problem when a module is built partially but other modules that define
+# needed static libraries is not yet built: prevent invocation of pattern rule
+# for static library with invalid parameters by depending on the header target
+define gb_LinkTarget__static_lib_dummy_depend
+$(call gb_StaticLibrary_get_target,$(1)) :| \
+ $(call gb_StaticLibrary_get_headers_target,$(1))
+
+endef
+
+# for a StaticLibrary, dependent libraries are not actually linked in
+# call gb_LinkTarget_use_static_libraries,linktarget,staticlibs
+define gb_LinkTarget_use_static_libraries
+$(call gb_LinkTarget_get_target,$(1)) : LINKED_STATIC_LIBS += $$(if $$(filter-out StaticLibrary,$$(TARGETTYPE)),$(2))
+$(if $(call gb_LinkTarget__is_merged,$(1)),\
+ $(call gb_Library_get_linktarget_target,merged) : \
+ LINKED_STATIC_LIBS += $$(if $$(filter-out StaticLibrary,$$(TARGETTYPE)),$(2)))
+
+# depend on the static libraries, but only if the target actually links to it
+ifneq (,$(call gb_LinkTarget_does_real_link,$(1)))
+# make has a size limit for the prerequisites string, which will be exceeded for some larger static links,
+# like soffice.bin, but there seems to be no limit for makefile lines...
+$(foreach lib,$(2), \
+ $$(eval $(call gb_LinkTarget_get_target,$(1)): $(call gb_StaticLibrary_get_linktarget_target,$(lib))))
+endif
+
+$(call gb_LinkTarget__register_type,statics,$(1),$(2))
+
+$(call gb_LinkTarget_get_headers_target,$(1)) : \
+ $(foreach lib,$(2),$(call gb_StaticLibrary_get_headers_target,$(lib)))
+$(foreach lib,$(2),$(call gb_LinkTarget__static_lib_dummy_depend,$(lib)))
+
+endef # gb_LinkTarget_use_static_libraries
+
+# call gb_LinkTarget_add_cobject,linktarget,sourcefile,cflags,linktargetmakefilename
+define gb_LinkTarget_add_cobject
+$(if $(wildcard $(call gb_CObject_get_source,$(SRCDIR),$(2))),,$(eval $(call gb_Output_error,No such source file $(call gb_CObject_get_source,$(SRCDIR),$(2)))))
+$(call gb_LinkTarget_get_target,$(1)) : COBJECTS += $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : COBJECTS += $(2)
+
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_CObject_get_target,$(2))
+$(call gb_CObject_get_target,$(2)) : | $(call gb_LinkTarget_get_headers_target,$(1))
+$(call gb_CObject_get_target,$(2)) : T_CFLAGS += $(call gb_LinkTarget__get_cflags,$(4)) $(3)
+$(call gb_CObject_get_target,$(2)) : \
+ OBJECTOWNER := $(call gb_Object__owner,$(2),$(1))
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,$(1)) : COBJECTS += $(2)
+$(call gb_LinkTarget_get_dep_target,$(1)) : $(call gb_CObject_get_dep_target,$(2))
+$(call gb_CObject_get_dep_target,$(2)) :| $(dir $(call gb_CObject_get_dep_target,$(2))).dir
+$(call gb_CObject_get_target,$(2)) :| $(dir $(call gb_CObject_get_dep_target,$(2))).dir
+endif
+
+endef
+
+# call gb_LinkTarget_add_cxxobject_internal,linktarget,sourcefile,cxxflags,linktargetmakefilename,exceptionflags
+# The purpose of the exceptionflags extra argument is to differentiate between usage that just needs
+# exception flags and usage that adds other flags. Using a PCH requires the same cxxflags as the ones used
+# to create the PCH, so non-empty cxxflags here mean the object cannot use the PCH, and the add_exception_cxxobject
+# variant passes the necessary flags by setting the extra argument.
+define gb_LinkTarget_add_cxxobject_internal
+$(if $(wildcard $(call gb_CxxObject_get_source,$(SRCDIR),$(2))),,$(eval $(call gb_Output_error,No such source file $(call gb_CxxObject_get_source,$(SRCDIR),$(2)))))
+$(call gb_LinkTarget_get_target,$(1)) : CXXOBJECTS += $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : CXXOBJECTS += $(2)
+
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_CxxObject_get_target,$(2))
+$(call gb_CxxObject_get_target,$(2)) : | $(call gb_LinkTarget_get_headers_target,$(1))
+$(call gb_CxxObject_get_target,$(2)) : T_CXXFLAGS += $(call gb_LinkTarget__get_cxxflags,$(4)) $(3) $(5)
+$(call gb_CxxObject_get_target,$(2)) : OBJECT_HAS_EXTRA_CXXFLAGS := $(if $(strip $(3)),1)
+$(call gb_CxxObject_get_target,$(2)) : \
+ OBJECTOWNER := $(if $(6),,$(call gb_Object__owner,$(2),$(1)))
+ifneq ($(gb_ENABLE_PCH),)
+ifeq ($(6),)
+$(call gb_CxxObject_get_target,$(2)) : $(call gb_LinkTarget_get_pch_timestamp,$(4))
+endif
+endif
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,$(1)) : CXXOBJECTS += $(2)
+$(call gb_LinkTarget_get_dep_target,$(1)) : $(call gb_CxxObject_get_dep_target,$(2))
+$(call gb_CxxObject_get_dep_target,$(2)) :| $(dir $(call gb_CxxObject_get_dep_target,$(2))).dir
+$(call gb_CxxObject_get_target,$(2)) :| $(dir $(call gb_CxxObject_get_dep_target,$(2))).dir
+endif
+
+endef
+
+# call gb_LinkTarget_add_cxxobject,linktarget,sourcefile,cxxflags,linktargetmakefilename
+define gb_LinkTarget_add_cxxobject
+$(call gb_LinkTarget_add_cxxobject_internal,$(1),$(2),$(3),$(4))
+endef
+
+# call gb_LinkTarget_add_objcobject,linktarget,sourcefile,objcflags,linktargetmakefilename
+define gb_LinkTarget_add_objcobject
+$(if $(wildcard $(call gb_ObjCObject_get_source,$(SRCDIR),$(2))),,$(eval $(call gb_Output_error,No such source file $(call gb_ObjCObject_get_source,$(SRCDIR),$(2)))))
+$(call gb_LinkTarget_get_target,$(1)) : OBJCOBJECTS += $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : OBJCOBJECTS += $(2)
+
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_ObjCObject_get_target,$(2))
+$(call gb_ObjCObject_get_target,$(2)) : | $(call gb_LinkTarget_get_headers_target,$(1))
+$(call gb_ObjCObject_get_target,$(2)) : T_OBJCFLAGS += $(call gb_LinkTarget__get_objcflags,$(4)) $(3)
+$(call gb_ObjCObject_get_target,$(2)) : \
+ OBJECTOWNER := $(call gb_Object__owner,$(2),$(1))
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,$(1)) : OBJCOBJECTS += $(2)
+$(call gb_LinkTarget_get_dep_target,$(1)) : $(call gb_ObjCObject_get_dep_target,$(2))
+$(call gb_ObjCObject_get_dep_target,$(2)) :| $(dir $(call gb_ObjCObject_get_dep_target,$(2))).dir
+$(call gb_ObjCObject_get_target,$(2)) :| $(dir $(call gb_ObjCObject_get_dep_target,$(2))).dir
+endif
+
+endef
+
+# call gb_LinkTarget_add_objcxxobject,linktarget,sourcefile,objcxxflags,linktargetmakefilename
+define gb_LinkTarget_add_objcxxobject
+$(if $(wildcard $(call gb_ObjCxxObject_get_source,$(SRCDIR),$(2))),,$(eval $(call gb_Output_error,No such source file $(call gb_ObjCxxObject_get_source,$(SRCDIR),$(2)))))
+$(call gb_LinkTarget_get_target,$(1)) : OBJCXXOBJECTS += $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : OBJCXXOBJECTS += $(2)
+
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_ObjCxxObject_get_target,$(2))
+$(call gb_ObjCxxObject_get_target,$(2)) : | $(call gb_LinkTarget_get_headers_target,$(1))
+$(call gb_ObjCxxObject_get_target,$(2)) : T_OBJCXXFLAGS += $(call gb_LinkTarget__get_objcxxflags,$(4)) $(3)
+$(call gb_ObjCxxObject_get_target,$(2)) : \
+ OBJECTOWNER := $(call gb_Object__owner,$(2),$(1))
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,$(1)) : OBJCXXOBJECTS += $(2)
+$(call gb_LinkTarget_get_dep_target,$(1)) : $(call gb_ObjCxxObject_get_dep_target,$(2))
+$(call gb_ObjCxxObject_get_dep_target,$(2)) :| $(dir $(call gb_ObjCxxObject_get_dep_target,$(2))).dir
+$(call gb_ObjCxxObject_get_target,$(2)) :| $(dir $(call gb_ObjCxxObject_get_dep_target,$(2))).dir
+endif
+
+endef
+
+# call gb_LinkTarget_add_cxxclrobject,linktarget,sourcefile,cxxclrflags,linktargetmakefilename
+define gb_LinkTarget_add_cxxclrobject
+$(if $(wildcard $(call gb_CxxClrObject_get_source,$(SRCDIR),$(2))),,$(eval $(call gb_Output_error,No such source file $(call gb_CxxClrObject_get_source,$(SRCDIR),$(2)))))
+$(call gb_LinkTarget_get_target,$(1)) : CXXCLROBJECTS += $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : CXXCLROBJECTS += $(2)
+
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_CxxClrObject_get_target,$(2))
+$(call gb_CxxClrObject_get_target,$(2)) : | $(call gb_LinkTarget_get_headers_target,$(1))
+$(call gb_CxxClrObject_get_target,$(2)) : T_CXXCLRFLAGS += $(call gb_LinkTarget__get_cxxclrflags,$(4)) $(3)
+$(call gb_CxxClrObject_get_target,$(2)) : \
+ OBJECTOWNER := $(call gb_Object__owner,$(2),$(1))
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,$(1)) : CXXCLROBJECTS += $(2)
+$(call gb_LinkTarget_get_dep_target,$(1)) : $(call gb_CxxClrObject_get_dep_target,$(2))
+$(call gb_CxxClrObject_get_dep_target,$(2)) :| $(dir $(call gb_CxxClrObject_get_dep_target,$(2))).dir
+$(call gb_CxxClrObject_get_target,$(2)) :| $(dir $(call gb_CxxClrObject_get_dep_target,$(2))).dir
+endif
+
+endef
+
+# call gb_LinkTarget_add_asmobject,linktarget,sourcefile
+define gb_LinkTarget_add_asmobject
+$(if $(wildcard $(call gb_AsmObject_get_source,$(SRCDIR),$(2))),,$(eval $(call gb_Output_error,No such source file $(call gb_AsmObject_get_source,$(SRCDIR),$(2)))))
+$(call gb_LinkTarget_get_target,$(1)) : ASMOBJECTS += $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : ASMOBJECTS += $(2)
+
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_AsmObject_get_target,$(2))
+$(call gb_AsmObject_get_target,$(2)) : | $(call gb_LinkTarget_get_headers_target,$(1))
+$(call gb_AsmObject_get_target,$(2)) : \
+ OBJECTOWNER := $(call gb_Object__owner,$(2),$(1))
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,$(1)) : ASMOBJECTS += $(2)
+$(call gb_LinkTarget_get_dep_target,$(1)) : $(call gb_AsmObject_get_dep_target,$(2))
+$(call gb_AsmObject_get_dep_target,$(2)) :| $(dir $(call gb_AsmObject_get_dep_target,$(2))).dir
+$(call gb_AsmObject_get_target,$(2)) :| $(dir $(call gb_AsmObject_get_dep_target,$(2))).dir
+endif
+
+endef
+
+# call gb_LinkTarget_add_generated_c_object,linktarget,sourcefile,cflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_c_object
+$(call gb_LinkTarget_get_target,$(1)) : GENCOBJECTS += $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : GENCOBJECTS += $(2)
+
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_GenCObject_get_target,$(2))
+$(call gb_GenCObject_get_target,$(2)) : $(call gb_GenCObject_get_source,$(2))
+# Often gb_GenCObject_get_source does not have its own rule and is only a byproduct.
+# That's why we need this order-only dependency on gb_Helper_MISCDUMMY
+$(call gb_GenCObject_get_source,$(2)) : | $(gb_Helper_MISCDUMMY)
+$(call gb_GenCObject_get_target,$(2)) : | $(call gb_LinkTarget_get_headers_target,$(1))
+$(call gb_GenCObject_get_target,$(2)) : WARNINGS_NOT_ERRORS := $(true)
+$(call gb_GenCObject_get_target,$(2)) : T_CFLAGS += $(call gb_LinkTarget__get_cflags,$(4)) $(3)
+$(call gb_GenCObject_get_target,$(2)) : \
+ OBJECTOWNER := $(call gb_Object__owner,$(2),$(1))
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,$(1)) : GENCOBJECTS += $(2)
+$(call gb_LinkTarget_get_dep_target,$(1)) : $(call gb_GenCObject_get_dep_target,$(2))
+$(call gb_GenCObject_get_dep_target,$(2)) :| $(dir $(call gb_GenCObject_get_dep_target,$(2))).dir
+$(call gb_GenCObject_get_target,$(2)) :| $(dir $(call gb_GenCObject_get_dep_target,$(2))).dir
+endif
+
+endef
+
+# call gb_LinkTarget_add_generated_cxx_object_internal,linktarget,sourcefile,cxxflags,linktargetmakefilename,exceptionflags
+define gb_LinkTarget_add_generated_cxx_object_internal
+$(call gb_LinkTarget_get_target,$(1)) : GENCXXOBJECTS += $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : GENCXXOBJECTS += $(2)
+
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_GenCxxObject_get_target,$(2))
+$(call gb_GenCxxObject_get_target,$(2)) : $(call gb_GenCxxObject_get_source,$(2),$(1))
+# Often gb_GenCxxObject_get_source does not have its own rule and is only a byproduct.
+# That's why we need this order-only dependency on gb_Helper_MISCDUMMY
+$(call gb_GenCxxObject_get_source,$(2),$(1)) : | $(gb_Helper_MISCDUMMY)
+$(call gb_GenCxxObject_get_target,$(2)) : | $(call gb_LinkTarget_get_headers_target,$(1))
+$(call gb_GenCxxObject_get_target,$(2)) : WARNINGS_NOT_ERRORS := $(true)
+$(call gb_GenCxxObject_get_target,$(2)) : T_CXXFLAGS += $(call gb_LinkTarget__get_cxxflags,$(4)) $(3) $(5)
+$(call gb_GenCxxObject_get_target,$(2)) : OBJECT_HAS_EXTRA_CXXFLAGS := $(if $(strip $(3)),1)
+$(call gb_GenCxxObject_get_target,$(2)) : \
+ OBJECTOWNER := $(call gb_Object__owner,$(2),$(1))
+$(call gb_GenCxxObject_get_target,$(2)) : GEN_CXX_SOURCE := $(call gb_GenCxxObject_get_source,$(2),$(1))
+ifneq ($(gb_ENABLE_PCH),)
+$(call gb_GenCxxObject_get_target,$(2)) : $(call gb_LinkTarget_get_pch_timestamp,$(4))
+endif
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,$(1)) : GENCXXOBJECTS += $(2)
+$(call gb_LinkTarget_get_dep_target,$(1)) : $(call gb_GenCxxObject_get_dep_target,$(2))
+$(call gb_GenCxxObject_get_dep_target,$(2)) :| $(dir $(call gb_GenCxxObject_get_dep_target,$(2))).dir
+$(call gb_GenCxxObject_get_target,$(2)) :| $(dir $(call gb_GenCxxObject_get_dep_target,$(2))).dir
+endif
+
+endef
+
+# call gb_LinkTarget_add_generated_cxx_object,linktarget,sourcefile,cxxflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_cxx_object
+$(call gb_LinkTarget_add_generated_cxx_object_internal,$(1),$(2),$(3),$(4))
+endef
+
+# call gb_LinkTarget_add_generated_objc_object,linktarget,sourcefile,cflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_objc_object
+$(call gb_LinkTarget_get_target,$(1)) : GENOBJCOBJECTS += $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : GENOBJCOBJECTS += $(2)
+
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_GenObjCObject_get_target,$(2))
+$(call gb_GenObjCObject_get_target,$(2)) : $(call gb_GenObjCObject_get_source,$(2))
+# Often gb_GenObjCObject_get_source does not have its own rule and is only a byproduct.
+# That's why we need this order-only dependency on gb_Helper_MISCDUMMY
+$(call gb_GenObjCObject_get_source,$(2)) : | $(gb_Helper_MISCDUMMY)
+$(call gb_GenObjCObject_get_target,$(2)) : | $(call gb_LinkTarget_get_headers_target,$(1))
+$(call gb_GenObjCObject_get_target,$(2)) : WARNINGS_NOT_ERRORS := $(true)
+$(call gb_GenObjCObject_get_target,$(2)) : T_OBJCFLAGS += $(call gb_LinkTarget__get_objcflags,$(4)) $(3)
+$(call gb_GenObjCObject_get_target,$(2)) : \
+ OBJECTOWNER := $(call gb_Object__owner,$(2),$(1))
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,$(1)) : GENOBJCOBJECTS += $(2)
+$(call gb_LinkTarget_get_dep_target,$(1)) : $(call gb_GenObjCObject_get_dep_target,$(2))
+$(call gb_GenObjCObject_get_dep_target,$(2)) :| $(dir $(call gb_GenObjCObject_get_dep_target,$(2))).dir
+$(call gb_GenObjCObject_get_target,$(2)) :| $(dir $(call gb_GenObjCObject_get_dep_target,$(2))).dir
+endif
+
+endef
+
+# call gb_LinkTarget_add_generated_nasm_object,linktarget,sourcefile,nasmflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_nasm_object
+$(call gb_LinkTarget_get_target,$(1)) : GENNASMOBJECTS += $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : GENNASMOBJECTS += $(2)
+
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_GenNasmObject_get_target,$(2))
+$(call gb_GenNasmObject_get_target,$(2)) : $(call gb_GenNasmObject_get_source,$(2))
+# Often gb_GenNasmObject_get_source does not have its own rule and is only a byproduct.
+# That's why we need this order-only dependency on gb_Helper_MISCDUMMY
+$(call gb_GenNasmObject_get_source,$(2)) : | $(gb_Helper_MISCDUMMY)
+$(call gb_GenNasmObject_get_target,$(2)) : | $(call gb_LinkTarget_get_headers_target,$(1))
+$(call gb_GenNasmObject_get_target,$(2)) : T_NASMFLAGS += $(call gb_LinkTarget__get_nasmflags,$(4)) $(3)
+$(call gb_GenNasmObject_get_target,$(2)) : \
+ OBJECTOWNER := $(call gb_Object__owner,$(2),$(1))
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,$(1)) : GENNASMOBJECTS += $(2)
+$(call gb_LinkTarget_get_dep_target,$(1)) : $(call gb_GenNasmObject_get_dep_target,$(2))
+$(call gb_GenNasmObject_get_dep_target,$(2)) :| $(dir $(call gb_GenNasmObject_get_dep_target,$(2))).dir
+$(call gb_GenNasmObject_get_target,$(2)) :| $(dir $(call gb_GenNasmObject_get_dep_target,$(2))).dir
+endif
+
+endef
+
+# call gb_LinkTarget_add_generated_objcxx_object,linktarget,sourcefile,cflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_objcxx_object
+$(call gb_LinkTarget_get_target,$(1)) : GENOBJCXXOBJECTS += $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : GENOBJCXXOBJECTS += $(2)
+
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_GenObjCxxObject_get_target,$(2))
+$(call gb_GenObjCxxObject_get_target,$(2)) : $(call gb_GenObjCxxObject_get_source,$(2))
+# Often gb_GenObjCxxObject_get_source does not have its own rule and is only a byproduct.
+# That's why we need this order-only dependency on gb_Helper_MISCDUMMY
+$(call gb_GenObjCxxObject_get_source,$(2)) : | $(gb_Helper_MISCDUMMY)
+$(call gb_GenObjCxxObject_get_target,$(2)) : | $(call gb_LinkTarget_get_headers_target,$(1))
+$(call gb_GenObjCxxObject_get_target,$(2)) : WARNINGS_NOT_ERRORS := $(true)
+$(call gb_GenObjCxxObject_get_target,$(2)) : T_OBJCXXFLAGS += $(call gb_LinkTarget__get_objcxxflags,$(4)) $(3)
+$(call gb_GenObjCxxObject_get_target,$(2)) : \
+ OBJECTOWNER := $(call gb_Object__owner,$(2),$(1))
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,$(1)) : GENOBJCXXOBJECTS += $(2)
+$(call gb_LinkTarget_get_dep_target,$(1)) : $(call gb_GenObjCxxObject_get_dep_target,$(2))
+$(call gb_GenObjCxxObject_get_dep_target,$(2)) :| $(dir $(call gb_GenObjCxxObject_get_dep_target,$(2))).dir
+$(call gb_GenObjCxxObject_get_target,$(2)) :| $(dir $(call gb_GenObjCxxObject_get_dep_target,$(2))).dir
+endif
+
+endef
+
+# call gb_LinkTarget_add_generated_cxxclrobject,linktarget,sourcefile,cxxclrflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_cxxclrobject
+$(call gb_LinkTarget_get_target,$(1)) : GENCXXCLROBJECTS += $(2)
+$(call gb_LinkTarget_get_clean_target,$(1)) : GENCXXCLROBJECTS += $(2)
+
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_GenCxxClrObject_get_target,$(2))
+$(call gb_GenCxxClrObject_get_target,$(2)) : $(call gb_GenCxxClrObject_get_source,$(2),$(1))
+$(call gb_GenCxxClrObject_get_target,$(2)) : | $(call gb_LinkTarget_get_headers_target,$(1))
+$(call gb_GenCxxClrObject_get_target,$(2)) : T_CXXCLRFLAGS += $(call gb_LinkTarget__get_cxxclrflags,$(4)) $(3)
+$(call gb_GenCxxClrObject_get_target,$(2)) : \
+ OBJECTOWNER := $(call gb_Object__owner,$(2),$(1))
+$(call gb_GenCxxClrObject_get_target,$(2)) : GEN_CXXCLR_SOURCE := $(call gb_GenCxxClrObject_get_source,$(2),$(1))
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_LinkTarget_get_dep_target,$(1)) : GENCXXCLROBJECTS += $(2)
+$(call gb_LinkTarget_get_dep_target,$(1)) : $(call gb_GenCxxClrObject_get_dep_target,$(2))
+$(call gb_GenCxxClrObject_get_dep_target,$(2)) :| $(dir $(call gb_GenCxxClrObject_get_dep_target,$(2))).dir
+$(call gb_GenCxxClrObject_get_target,$(2)) :| $(dir $(call gb_GenCxxClrObject_get_dep_target,$(2))).dir
+endif
+
+endef
+
+# Add a bison grammar to the build.
+# call gb_LinkTarget_add_grammar,linktarget,yaccfile,cxxflags,linktargetmakefilename
+define gb_LinkTarget_add_grammar
+$(call gb_YaccTarget_YaccTarget,$(2))
+$(call gb_LinkTarget_add_generated_exception_object,$(1),YaccTarget/$(2),$(3) $(if $(filter GCC,$(COM)),-Wno-unused-macros),$(4))
+$(call gb_GenCxxObject_get_target,YaccTarget/$(2)): PLUGIN_WARNINGS_AS_ERRORS := $(true)
+$(call gb_LinkTarget_get_clean_target,$(1)) : $(call gb_YaccTarget_get_clean_target,$(2))
+$(call gb_LinkTarget_get_headers_target,$(1)) : $(call gb_YaccTarget_get_header_target,$(2))
+$(call gb_LinkTarget__add_include,$(1),$(dir $(call gb_YaccTarget_get_header_target,$(2))))
+
+endef
+
+# Add bison grammars to the build.
+# call gb_LinkTarget_add_grammars,linktarget,yaccfiles,cxxflags,linktargetmakefilename
+define gb_LinkTarget_add_grammars
+$(foreach grammar,$(2),$(call gb_LinkTarget_add_grammar,$(1),$(grammar),$(3),$(4)))
+endef
+
+# Add a flex scanner to the build.
+# call gb_LinkTarget_add_scanner,linktarget,lexfile,cxxflags,linktargetmakefilename
+define gb_LinkTarget_add_scanner
+$(call gb_LexTarget_LexTarget,$(2))
+$(call gb_LinkTarget_add_generated_exception_object,$(1),LexTarget/$(2),$(3) $(if $(filter GCC,$(COM)),-Wno-unused-macros),$(4))
+$(call gb_LinkTarget_get_clean_target,$(1)) : $(call gb_LexTarget_get_clean_target,$(2))
+
+endef
+
+# Add flex scanners to the build.
+# call gb_LinkTarget_add_scanners,linktarget,lexfiles,cxxflags,linktargetmakefilename
+define gb_LinkTarget_add_scanners
+$(foreach scanner,$(2),$(call gb_LinkTarget_add_scanner,$(1),$(scanner),$(3),$(4)))
+
+endef
+
+# call gb_LinkTarget_add_exception_object,linktarget,sourcefile,cxxflags,linktargetmakefilename
+define gb_LinkTarget_add_exception_object
+$(call gb_LinkTarget_add_cxxobject_internal,$(1),$(2),$(3),$(4),$(gb_LinkTarget_EXCEPTIONFLAGS))
+endef
+
+# call gb_LinkTarget__use_linktarget_objects,linktarget,linktargets
+define gb_LinkTarget__use_linktarget_objects
+$(call gb_LinkTarget_get_target,$(1)) : $(foreach linktarget,$(2),$(call gb_LinkTarget_get_target,$(linktarget)))
+ifneq ($(OS),iOS)
+$(call gb_LinkTarget_get_target,$(1)) : EXTRAOBJECTLISTS += $(foreach linktarget,$(2),$(call gb_LinkTarget_get_objects_list,$(linktarget)))
+endif
+
+endef
+
+# call gb_LinkTarget_use_library_objects,linktarget,libs
+define gb_LinkTarget_use_library_objects
+ifneq (,$$(filter-out $(gb_Library_KNOWNLIBS),$(2)))
+$$(eval $$(call gb_Output_info,currently known libraries are: $(sort $(gb_Library_KNOWNLIBS)),ALL))
+$$(eval $$(call gb_Output_error,Cannot import objects library/libraries $$(filter-out $(gb_Library_KNOWNLIBS),$(2)). Libraries must be registered in Repository.mk or RepositoryExternal.mk))
+endif
+$(call gb_LinkTarget__use_linktarget_objects,$(1),$(foreach lib,$(2),$(call gb_Library_get_linktarget,$(lib))))
+$(call gb_LinkTarget_get_headers_target,$(1)) : \
+ $(foreach lib,$(2),$(call gb_Library_get_headers_target,$(lib)))
+
+endef
+
+# call gb_LinkTarget_use_executable_objects,linktarget,exes
+define gb_LinkTarget_use_executable_objects
+$(call gb_LinkTarget__use_linktarget_objects,$(1),$(foreach exe,$(2),$(call gb_Executable_get_linktarget,$(exe))))
+
+endef
+
+# call gb_LinkTarget_add_cobjects,linktarget,sourcefiles,cflags,linktargetmakefilename
+define gb_LinkTarget_add_cobjects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_cobject,$(1),$(obj),$(3),$(4)))
+endef
+
+# call gb_LinkTarget_add_cxxobjects,linktarget,sourcefiles,cxxflags,linktargetmakefilename
+define gb_LinkTarget_add_cxxobjects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_cxxobject,$(1),$(obj),$(3),$(4)))
+endef
+
+# call gb_LinkTarget_add_objcobjects,linktarget,sourcefiles,objcflags,linktargetmakefilename
+define gb_LinkTarget_add_objcobjects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_objcobject,$(1),$(obj),$(3),$(4)))
+endef
+
+# call gb_LinkTarget_add_objcxxobjects,linktarget,sourcefiles,objcxxflags,linktargetmakefilename
+define gb_LinkTarget_add_objcxxobjects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_objcxxobject,$(1),$(obj),$(3),$(4)))
+endef
+
+# call gb_LinkTarget_add_cxxclrobjects,linktarget,sourcefiles,cxxclrflags,linktargetmakefilename
+define gb_LinkTarget_add_cxxclrobjects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_cxxclrobject,$(1),$(obj),$(3),$(4)))
+endef
+
+# call gb_LinkTarget_add_asmobjects,linktarget,sourcefiles,asmflags,linktargetmakefilename
+define gb_LinkTarget_add_asmobjects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_asmobject,$(1),$(obj),$(3),$(4)))
+endef
+
+# call gb_LinkTarget_add_exception_objects,linktarget,sourcefiles,cxxflags,linktargetmakefilename
+define gb_LinkTarget_add_exception_objects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_exception_object,$(1),$(obj),$(3),$(4)))
+endef
+
+#only useful for building x64 libraries on windows
+# call gb_LinkTarget_add_x64_generated_exception_objects,linktarget,sourcefiles,cxxflags,linktargetmakefilename
+define gb_LinkTarget_add_x64_generated_exception_objects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_generated_exception_object,$(1),$(obj),$(3),$(4)))
+$(foreach obj,$(2),$(eval $(call gb_GenCxxObject_get_target,$(obj)) : CXXOBJECT_X64 := YES))
+endef
+
+# call gb_LinkTarget_add_generated_cobjects,linktarget,sourcefiles,cflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_cobjects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_generated_c_object,$(1),$(obj),$(3),$(4)))
+endef
+
+#only useful for building x64 libraries on windows
+# call gb_LinkTarget_add_x64_generated_cobjects,linktarget,sourcefiles,cflags,linktargetmakefilename
+define gb_LinkTarget_add_x64_generated_cobjects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_generated_c_object,$(1),$(obj),$(3),$(4)))
+endef
+
+# call gb_LinkTarget_add_generated_exception_object,linktarget,sourcefile,cxxflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_exception_object
+$(call gb_LinkTarget_add_generated_cxx_object_internal,$(1),$(2),$(3),$(4),$(gb_LinkTarget_EXCEPTIONFLAGS))
+endef
+
+# call gb_LinkTarget_add_generated_exception_objects,linktarget,sourcefile,cxxflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_exception_objects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_generated_exception_object,$(1),$(obj),$(3),$(4)))
+endef
+
+# call gb_LinkTarget_add_generated_objcobjects,linktarget,sourcefiles,cflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_objcobjects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_generated_objc_object,$(1),$(obj),$(3),$(4)))
+endef
+
+# call gb_LinkTarget_add_generated_objcxxobjects,linktarget,sourcefiles,cflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_objcxxobjects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_generated_objcxx_object,$(1),$(obj),$(3),$(4)))
+endef
+
+# call gb_LinkTarget_add_generated_nasmobjects,linktarget,sourcefiles,cflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_nasmobjects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_generated_nasm_object,$(1),$(obj),$(3),$(4)))
+endef
+
+# call gb_LinkTarget_add_generated_cxxclrobjects,linktarget,sourcefiles,cxxclrflags,linktargetmakefilename
+define gb_LinkTarget_add_generated_cxxclrobjects
+$(foreach obj,$(2),$(call gb_LinkTarget_add_generated_cxxclrobject,$(1),$(obj),$(3),$(4)))
+endef
+
+# call gb_LinkTarget_set_targettype,linktarget,targettype
+define gb_LinkTarget_set_targettype
+$(call gb_LinkTarget_get_target,$(1)) : TARGETTYPE := $(2)
+
+endef
+
+# call gb_LinkTarget_set_x64,linktarget,boolean
+define gb_LinkTarget_set_x64
+$(call gb_LinkTarget_get_target,$(1)) : LIBRARY_X64 := $(2)
+
+endef
+
+# call gb_LinkTarget_set_x86,linktarget,boolean
+define gb_LinkTarget_set_x86
+$(call gb_LinkTarget_get_target,$(1)) : PE_X86 := $(2)
+
+endef
+
+# call gb_LinkTarget_set_ilibtarget,linktarget,ilibfilename
+define gb_LinkTarget_set_ilibtarget
+ifeq (,$(DISABLE_DYNLOADING))
+$(call gb_LinkTarget_get_clean_target,$(1)) \
+$(call gb_LinkTarget_get_target,$(1)) : ILIBTARGET := $(2)
+endif
+
+endef
+
+# Add a file that is built by the LinkTarget command and define
+# a dummy touch rule for it so it can be tracked via dependencies.
+# The assumption is that the file is created by linking; in case it does not
+# exist there is some problem. This can be caused on WNT by re-naming DLL
+# files (which are aux-targets) but not the import .lib files (which
+# are the LinkTargets) and doing an incremental build.
+# call gb_LinkTarget_add_auxtarget,linktarget,auxtarget
+define gb_LinkTarget_add_auxtarget
+$(2) : $(call gb_LinkTarget_get_target,$(1))
+ if test -e $$@; then \
+ touch -r $$< $$@; \
+ else \
+ rm -f $$<; \
+ echo "ERROR: aux-target $$@ missing, library deleted, please try running make again"; \
+ false; \
+ fi
+
+$(call gb_LinkTarget_get_clean_target,$(1)) : AUXTARGETS += $(2)
+
+endef
+
+# call gb_LinkTarget_add_auxtargets,linktarget,auxtargets
+define gb_LinkTarget_add_auxtargets
+$(foreach aux,$(2),$(call gb_LinkTarget_add_auxtarget,$(1),$(aux)))
+
+endef
+
+# call gb_LinkTarget__use_custom_headers,linktarget,customtarget
+define gb_LinkTarget__use_custom_headers
+$(call gb_LinkTarget_get_headers_target,$(1)) :| \
+ $(call gb_CustomTarget_get_target,$(2))
+$(call gb_LinkTarget__add_include,$(1),$(call gb_CustomTarget_get_workdir,$(2)))
+
+endef
+
+# call gb_LinkTarget_use_custom_headers,linktarget,customtargets
+define gb_LinkTarget_use_custom_headers
+$(foreach customtarget,$(2),$(call gb_LinkTarget__use_custom_headers,$(1),$(customtarget)))
+
+endef
+
+# add SDI (svidl) headers
+# call gb_LinkTarget_add_sdi_headers,linktarget,sditargets
+define gb_LinkTarget_add_sdi_headers
+$(call gb_LinkTarget_get_headers_target,$(1)) : $(foreach sdi,$(2),$(call gb_SdiTarget_get_target,$(sdi)))
+$(call gb_LinkTarget_get_clean_target,$(1)) : $(foreach sdi,$(2),$(call gb_SdiTarget_get_clean_target,$(sdi)))
+
+endef
+
+# call gb_LinkTarget__set_precompiled_header_variables,linktarget,pchcxxfile,pchtarget,linktargetmakefilename
+define gb_LinkTarget__set_precompiled_header_variables
+$(call gb_LinkTarget_get_target,$(1)) : PCH_NAME := $(3)
+$(call gb_LinkTarget_get_target,$(1)) : PCH_HEADER := $(patsubst %.cxx,%.hxx,$(2))
+$(call gb_LinkTarget_get_target,$(1)) : PCH_LINKTARGETMAKEFILENAME := $(4)
+
+$(call gb_LinkTarget_get_target,$(1)) : PCH_DEFS := $$(DEFS)
+$(call gb_LinkTarget_get_target,$(1)) : PCH_CXXFLAGS := $$(T_CXXFLAGS) $(call gb_LinkTarget__get_cxxflags,$(4)) $(gb_LinkTarget_EXCEPTIONFLAGS)
+
+$(call gb_LinkTarget_get_target,$(1)) : DEFS += -DPCH_LEVEL=$(gb_ENABLE_PCH)
+$(call gb_LinkTarget_get_target,$(1)) : PCH_DEFS += -DPCH_LEVEL=$(gb_ENABLE_PCH)
+
+endef
+
+# call gb_LinkTarget__set_precompiled_header_impl,linktarget,pchcxxfile,pchtarget,linktargetmakefilename
+define gb_LinkTarget__set_precompiled_header_impl
+$(call gb_LinkTarget_get_clean_target,$(1)) : $(call gb_PrecompiledHeader_get_clean_target,$(3))
+$(call gb_PrecompiledHeader_get_target,$(3),$(4)) : $(call gb_CxxObject_get_source,$(SRCDIR),$(2))
+$(call gb_PrecompiledHeader_get_target,$(3),$(4)) : $(patsubst %.cxx,%.hxx,$(call gb_CxxObject_get_source,$(SRCDIR),$(2)))
+$(call gb_PrecompiledHeader_get_target,$(3),$(4)) : $(call gb_PrecompiledHeader_get_flags_file,$(3),$(4))
+
+$(call gb_PrecompiledHeader_get_target,$(3),$(4)) : $(call gb_LinkTarget_get_headers_target,$(1))
+
+$(call gb_PrecompiledHeader_get_target,$(3),$(4)) : VISIBILITY :=
+
+$(call gb_LinkTarget_get_pch_timestamp,$(4)) : $(call gb_PrecompiledHeader_get_target,$(3),$(4))
+
+$(call gb_LinkTarget__set_precompiled_header_variables,$(1),$(2),$(3),$(4))
+
+ifeq ($(gb_FULLDEPS),$(true))
+-include $(call gb_PrecompiledHeader_get_dep_target,$(3),$(4))
+endif
+
+endef
+
+# call gb_LinkTarget__add_precompiled_header_object,linktarget,pchcxxfile,pchtarget,linktargetmakefilename
+define gb_LinkTarget__add_precompiled_header_object
+# Clang-style
+ifneq ($(BUILDING_PCH_WITH_OBJ),)
+$(call gb_LinkTarget_add_exception_object,$(1),$(2),,$(4))
+$(call gb_CxxObject_get_target,$(2)) : T_PCH_EXTRA_CXXFLAGS += $(gb_PrecompiledHeader_pch_with_obj)
+endif
+# MSVC-style
+$(call gb_LinkTarget_get_target,$(1)) : PCHOBJEX = $(call gb_PrecompiledHeader_get_objectfile, $(call gb_PrecompiledHeader_get_target,$(3),$(4)))
+$(call gb_LinkTarget_get_target,$(1)) : PCHOBJS = $$(PCHOBJEX)
+
+endef
+
+# 'compiler' set comes only from gb_LinkTarget_set_clang_precompiled_header
+# call gb_LinkTarget_set_precompiled_header,linktarget,pchcxxfile,,linktargetmakefilename,compiler
+define gb_LinkTarget_set_precompiled_header
+ifneq ($(gb_ENABLE_PCH),)
+$(call gb_LinkTarget__set_precompiled_header_impl,$(1),$(2),$(notdir $(2)),$(4))
+$(call gb_PrecompiledHeader_generate_rules,$(notdir $(2)),$(1),$(4),$(2),$(5))
+endif
+ifneq ($(gb_ENABLE_PCH)$(BLOCK_PCH),)
+$(call gb_LinkTarget__add_precompiled_header_object,$(1),$(2),$(notdir $(2)),$(4))
+endif
+
+endef
+
+# It seems complicated to forward the clang setting to the PCH rules, so use an extra
+# function to set it manually. This variant should be used if gb_LinkTarget_use_clang is used.
+# call gb_LinkTarget_set_clang_precompiled_header,linktarget,pchcxxfile,,linktargetmakefilename
+define gb_LinkTarget_set_clang_precompiled_header
+$(call gb_LinkTarget_set_precompiled_header,$(1),$(2),$(3),$(4),$(LO_CLANG_CXX))
+endef
+
+# call gb_LinkTarget__reuse_precompiled_header_impl,linktarget,pchcxxfile,pchtarget,linktargetmakefilename
+# Use the PCH as if it was LinkTarget's own, but do nothing with the PCH itself, just depend on it.
+define gb_LinkTarget__reuse_precompiled_header_impl
+$(call gb_LinkTarget__set_precompiled_header_variables,$(1),$(2),$(3),$(4))
+
+$(call gb_LinkTarget_get_pch_timestamp,$(4)) : $(call gb_LinkTarget_get_pch_reuse_timestamp,$(4))
+
+# We need to depend on a special for_reuse target that depends on the linktarget that owns the PCH.
+# Depending directly on the PCH could cause that PCH to be built with this linktarget's flags.
+$(call gb_LinkTarget_get_pch_reuse_timestamp,$(4)) : $(call gb_PrecompiledHeader_get_for_reuse_target,$(3),$(4))
+ $(call gb_PrecompiledHeader_check_flags,$(4),$(2),\
+ $(call gb_PrecompiledHeader_get_target,$(3),$(4)),\
+ $(call gb_PrecompiledHeader_get_flags_file,$(3),$(4)),\
+ $(gb_PrecompiledHeader_cxxflags_includes))
+ $$(call gb_PrecompiledHeader__copy_reuse_files,$(1),$(3),$(4))
+ mkdir -p $$(dir $$@) && touch $$@
+
+endef
+
+# call gb_LinkTarget__add_reuse_precompiled_header_object,linktarget,pchcxxfile,pchtarget,linktargetmakefilename
+define gb_LinkTarget__add_reuse_precompiled_header_object
+# Clang-style
+ifneq ($(BUILDING_PCH_WITH_OBJ),)
+# We need to link in also the PCH's object file. Again, rely on a special for_reuse target for dependencies.
+$(if $(wildcard $(call gb_CxxObject_get_source,$(SRCDIR),$(2))),,$(eval $(call gb_Output_error,No such source file $(call gb_CxxObject_get_source,$(SRCDIR),$(2)))))
+$(call gb_LinkTarget_get_target,$(1)) : CXXOBJECTS += $(2)
+endif
+# MSVC-style
+$(call gb_LinkTarget_get_target,$(1)) : PCHOBJEX = $(call gb_PrecompiledHeader_get_objectfile, $(call gb_PrecompiledHeader_get_target,$(3),$(4)))
+$(call gb_LinkTarget_get_target,$(1)) : PCHOBJS = $$(PCHOBJEX)
+
+endef
+
+# call gb_LinkTarget__reuse_precompiled_header_workarounds,linktarget,pchcxxfile,pchtarget,linktargetmakefilename
+define gb_LinkTarget__reuse_precompiled_header_workarounds
+ifeq ($(COM_IS_CLANG),TRUE)
+$(call gb_LinkTarget_add_defs,$(1),$(gb_CXXFLAGS_include)$(SRCDIR)/pch/inc/clangfix.hxx)
+$(call gb_LinkTarget_add_defs,$(1),$(gb_CXXFLAGS_no_pch_warnings))
+endif
+$(if $(filter precompiled_system,$(3)), $(call gb_LinkTarget_add_defs,$(1),-DBOOST_ALL_NO_LIB))
+endef
+
+# call gb_LinkTarget_reuse_precompiled_header,linktarget,pchcxxfile,,linktargetmakefilename
+define gb_LinkTarget_reuse_precompiled_header
+ifeq ($(gb_DISABLE_PCH_REUSE),$(false))
+ifneq ($(gb_ENABLE_PCH),)
+$(call gb_LinkTarget__reuse_precompiled_header_impl,$(1),$(2),$(notdir $(2)),$(4))
+$(call gb_LinkTarget__reuse_precompiled_header_workarounds,$(1),$(2),$(notdir $(2)),$(4))
+endif
+ifneq ($(gb_ENABLE_PCH)$(BLOCK_PCH),)
+$(call gb_LinkTarget__add_reuse_precompiled_header_object,$(1),$(2),$(notdir $(2)),$(4))
+endif
+endif
+
+endef
+
+# call gb_LinkTarget_use_common_precompiled_header,linktarget,,,linktargetmakefilename
+define gb_LinkTarget_use_common_precompiled_header
+$(call gb_LinkTarget_reuse_precompiled_header,$(1),pch/inc/pch/precompiled_system,,$(4))
+
+endef
+
+# use a header package, possibly from another module
+# call gb_LinkTarget_use_package,linktarget,package
+define gb_LinkTarget_use_package
+$(call gb_LinkTarget_get_headers_target,$(1)) :| \
+ $(call gb_Package_get_target,$(strip $(2)))
+$(call gb_Package_get_target,$(strip $(2))): RDEPENDS += $(call gb_LinkTarget__get_workdir_linktargetname,$(1))
+
+endef
+
+# call gb_LinkTarget_use_packages,linktarget,packages
+define gb_LinkTarget_use_packages
+$(foreach package,$(2),$(call gb_LinkTarget_use_package,$(1),$(package)))
+endef
+
+# use a GeneratedPackage, possibly from another module
+# call gb_LinkTarget_use_generated_package,linktarget,package
+define gb_LinkTarget_use_generated_package
+$(call gb_LinkTarget_get_headers_target,$(1)) :| \
+ $(call gb_GeneratedPackage_get_target,$(strip $(2)))
+
+endef
+
+# Use sources from unpacked tarball of an external project
+# call gb_LinkTarget_use_unpacked,linktarget,unpackedtarget
+define gb_LinkTarget_use_unpacked
+$(call gb_LinkTarget_get_headers_target,$(1)) :| $(call gb_UnpackedTarball_get_final_target,$(2))
+
+endef
+
+# Use artifacts from ExternalProject (i. e. configure) of an external project
+# example in expat: StaticLibrary depends on ExternalProject outcome
+# call gb_LinkTarget_use_external_project,linktarget,externalproject,full-dep
+define gb_LinkTarget_use_external_project
+$(call gb_LinkTarget_get_target,$(1)) :| $(call gb_ExternalProject_get_target,$(2))
+$(call gb_LinkTarget_get_headers_target,$(1)) :| \
+ $(if $(3),$(call gb_ExternalProject_get_target,$(2)),$(call gb_UnpackedTarball_get_final_target,$(2)))
+
+endef
+
+# this forwards to functions that must be defined in RepositoryExternal.mk.
+# Automatically forward for libmerged library too when linktarget is merged.
+#
+# call gb_LinkTarget_use_external,linktarget,external
+define gb_LinkTarget_use_external
+$(if $(filter undefined,$(origin gb_LinkTarget__use_$(2))),\
+ $(error gb_LinkTarget_use_external: unknown external: $(2)) \
+, \
+ $(if $(gb_PARTIAL_BUILD),,$(if $(call gb_LinkTarget__is_merged,$(1)), \
+ $(call gb_LinkTarget__use_$(2),$(call gb_Library_get_linktarget,merged)))) \
+ $(call gb_LinkTarget__use_$(2),$(1)) \
+)
+
+$(call gb_LinkTarget__register_type,externals,$(1),$(2))
+
+endef
+
+# $(call gb_LinkTarget_use_externals,library,externals)
+gb_LinkTarget_use_externals = \
+ $(foreach external,$(2),$(call gb_LinkTarget_use_external,$(1),$(external)))
+
+# call gb_LinkTarget_set_visibility_default,linktarget
+define gb_LinkTarget_set_visibility_default
+$(call gb_LinkTarget_get_target,$(1)) : VISIBILITY := default
+ifneq ($(gb_ENABLE_PCH),)
+ifneq ($(strip $$(PCH_NAME)),)
+$(call gb_PrecompiledHeader_get_target,$$(PCH_NAME),$$(PCH_LINKTARGETMAKEFILENAME)) : VISIBILITY := default
+endif
+endif
+
+endef
+
+# call gb_LinkTarget_set_warnings_not_errors,linktarget
+define gb_LinkTarget_set_warnings_not_errors
+$(call gb_LinkTarget_get_target,$(1)) : WARNINGS_NOT_ERRORS := $(true)
+
+endef
+
+# call gb_LinkTarget_set_warnings_disabled,linktarget
+define gb_LinkTarget_set_warnings_disabled
+$(call gb_LinkTarget_get_target,$(1)) : WARNINGS_DISABLED := $(true)
+
+endef
+
+# call gb_LinkTarget_set_external_code,linktarget
+define gb_LinkTarget_set_external_code
+$(call gb_LinkTarget_get_target,$(1)) : EXTERNAL_CODE := $(true)
+
+endef
+
+# Set suffix of C++ files, if different from 'cxx'
+#
+# This is useful for external libraries.
+#
+# call gb_LinkTarget_set_generated_cxx_suffix,linktarget,used-suffix
+define gb_LinkTarget_set_generated_cxx_suffix
+gb_LinkTarget_CXX_SUFFIX_$(call gb_LinkTarget__get_workdir_linktargetname,$(1)) := $(2)
+
+endef
+
+# C/C++ files will be build with Clang (if possible) instead of the default compiler.
+# call gb_LinkTarget_use_clang,linktarget,,linktargetmakefilename
+define gb_LinkTarget_use_clang
+$(call gb_LinkTarget_get_target,$(1)) : T_CC := $(LO_CLANG_CC)
+$(call gb_LinkTarget_get_target,$(1)) : T_CXX := $(LO_CLANG_CXX)
+$(call gb_LinkTarget_get_target,$(1)) : T_USE_CLANG := $(true)
+$(call gb_LinkTarget_get_target,$(1)) : T_USE_LD := $(or $(CLANG_USE_LD),$(USE_LD))
+$(call gb_LinkTarget_get_target,$(1)) : T_LTOFLAGS := $(if $(LO_CLANG_CXX),$(gb_CLANG_LTOFLAGS),$(gb_LTOFLAGS))
+endef
+
+# call gb_LinkTarget_use_vclmain,linktarget
+define gb_LinkTarget_use_vclmain
+$(call gb_LinkTarget_use_static_libraries,$(1),vclmain)
+
+endef # gb_LinkTarget_use_vclmain
+
+# Used by URE libraries that need to keep binary compatibility.
+# Reset some flags that make sense for our internal libraries but might
+# break public ABI.
+# (clang-cl's -Zc:dllexportInlines- would not only be a problem for the URE libraries themselves but
+# also for any libraries they depend on. While that does not appear to be a problem for -Zc:inline
+# for neither MSVC nor clang-cl, it should not really hurt to also switch that off not only for the
+# URE libraries themselves but also for their dependencies.)
+# call gb_LinkTarget_set_is_ure_library_or_dependency,linktarget,,linktargetmakefilename
+define gb_LinkTarget_set_is_ure_library_or_dependency
+$(call gb_LinkTarget_add_cxxflags,$(1),$(gb_CXXFLAGS_ZCINLINE_OFF))
+ifeq ($(HAVE_DLLEXPORTINLINES),TRUE)
+$(call gb_LinkTarget_add_cxxflags,$(1),-Zc:dllexportInlines)
+endif
+
+endef
+
+gb_LinkTarget__get_plugins_var = $(call gb_LinkTarget__get_workdir_linktargetname,$(1))<>PLUGINS
+gb_LinkTarget__get_plugins = $($(call gb_LinkTarget__get_plugins_var,$(1)))
+gb_Library__get_plugins = $($(call gb_LinkTarget__get_plugins_var,$(call gb_Library_get_linktarget,$(1))))
+
+define gb_LinkTarget__add_plugin
+$(call gb_LinkTarget__get_plugins_var,$(1)) += $(2)
+
+endef
+
+# Instead of setting nodep use gb_LinkTarget__set_plugin_for_nodep
+#
+# call gb_LinkTarget__set_plugin_for,linktarget,loader,nodep
+define gb_LinkTarget__set_plugin_for
+ifeq (,$(filter $(1),$(foreach plugin,$(gb_Library_KNOWNPLUGINS),$(call gb_Library_get_linktarget,$(plugin)))))
+$$(eval $$(call gb_Output_error,Unknown plugin(s) '$(filter $(1),$(foreach plugin,$(gb_Library_KNOWNPLUGINS),$(call gb_Library_get_linktarget,$(plugin))))'. Plugins must be registered in Repository.mk or RepositoryExternal.mk))
+endif
+ifneq (,$(filter $(1),$(foreach lib,$(gb_MERGEDLIBS),$(call gb_Library_get_linktarget,$(lib)))))
+$$(eval $$(call gb_Output_error,Plugins can't be in mergelibs))
+endif
+ifeq ($(call gb_LinkTarget__is_build_tool,$(1)),$(true))
+$$(eval $$(call gb_Output_error,Plugin support for build tools not implemented))
+endif
+
+$(if $(filter $(2),$(gb_Library_KNOWNLOADERS)),,gb_Library_KNOWNLOADERS += $(2))
+$(if $(3),,$(call gb_LinkTarget_use_libraries,$(1),$(2),,$(4)))
+
+endef
+
+# call gb_LinkTarget__set_plugin_for_nodep,linktarget,loader
+gb_LinkTarget__set_plugin_for_nodep = $(call gb_LinkTarget__set_plugin_for,$(1),$(2),$(true))
+
+# call gb_LinkTarget_add_prejs,linktarget,js_file
+define gb_LinkTarget_add_prejs
+ifeq (EMSCRIPTEN,$(OS))
+$(call gb_LinkTarget_get_target,$(1)) : T_PREJS += $(2)
+$(call gb_LinkTarget_get_target,$(1)) : $(2)
+endif
+
+endef
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/Module.mk b/solenv/gbuild/Module.mk
new file mode 100644
index 000000000..bb915f503
--- /dev/null
+++ b/solenv/gbuild/Module.mk
@@ -0,0 +1,495 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+
+# Overview of dependencies and tasks of Module
+#
+# target task depends on
+# Module build the product all product targets
+# excluding tests recursive Modules
+# Module/unitcheck run unit tests all unit tests
+# recursive Module/checks
+# Module/slowcheck run all slow unit tests
+# Module/screenshot create all screenshots
+# Module/subsequentcheck run system tests all system tests
+# Module/uicheck run uitests all uitests
+# recursive Module/subsequentchecks
+# build (global) build the product top-level Module
+# unitcheck (global) run unit tests top-level Module/unitcheck
+# slowcheck (global) run slow unit tests top-level Module/slowcheck
+# screenshot (global) create all screenshots top-level Module/screenshot
+# subsequentcheck (global) run system tests top-level Module/subsequentcheck
+# perfcheck (global) run performance unit tests top-level Module/perfcheck
+# uicheck (global) run the uitests run all uitests
+
+
+# Module class
+
+gb_Module_ALLMODULES :=
+gb_Module_MODULELOCATIONS :=
+gb_Module_TARGETSTACK :=
+gb_Module_L10NTARGETSTACK :=
+gb_Module_CHECKTARGETSTACK :=
+gb_Module_SLOWCHECKTARGETSTACK :=
+gb_Module_SCREENSHOTTARGETSTACK :=
+gb_Module_SUBSEQUENTCHECKTARGETSTACK :=
+gb_Module_PERFCHECKTARGETSTACK :=
+gb_Module_UICHECKTARGETSTACK :=
+gb_Module_CLEANTARGETSTACK :=
+
+# The currently read gbuild makefile.
+#
+# gbuild classes should use this if they need to depend on their makefile
+# (e.g., to make sure a zip file is rebuilt if files are removed from it).
+# Because makefiles may include other makefiles, it is not safe to rely
+# on $(MAKEFILE_LIST).
+gb_Module_CURRENTMAKEFILE :=
+
+$(call gb_Module_get_nonl10n_target,%) :
+ $(call gb_Output_announce,$*,$(true),BIN,5)
+ $(call gb_Trace_MakeMark,$*,BIN)
+ -$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && \
+ touch $@)
+
+.PHONY : $(call gb_Module_get_clean_target,%)
+$(call gb_Module_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),MOD,5)
+ $(call gb_Output_announce_title,module $* cleared.)
+ -$(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_Module_get_target,$*) $(call gb_Module_get_nonl10n_target,$*) $(call gb_Module_get_l10n_target,$*) $(call gb_Module_get_check_target,$*) $(call gb_Module_get_slowcheck_target,$*) $(call gb_Module_get_screenshot_target,$*) $(call gb_Module_get_subsequentcheck_target,$*) $(call gb_Module_get_perfcheck_target,$*) $(call gb_Module_get_uicheck,$*))
+
+$(call gb_Module_get_l10n_target,%) :
+ $(call gb_Output_announce,$*,$(true),LOC,5)
+ $(call gb_Trace_MakeMark,$*,LOC)
+ $(call gb_Output_announce_title,module $* done.)
+ -$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && \
+ touch $@)
+
+$(call gb_Module_get_check_target,%) :
+ $(call gb_Output_announce,$*,$(true),CHK,5)
+ $(call gb_Trace_MakeMark,$*,CHK)
+ $(call gb_Output_announce_title,module $* checks done.)
+ -$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && \
+ touch $@)
+
+$(call gb_Module_get_slowcheck_target,%) :
+ $(call gb_Output_announce,$*,$(true),SLC,5)
+ $(call gb_Trace_MakeMark,$*,SLC)
+ $(call gb_Output_announce_title,module $* slowchecks done.)
+ -$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && \
+ touch $@)
+
+$(call gb_Module_get_screenshot_target,%) :
+ $(call gb_Output_announce,$*,$(true),SCR,5)
+ $(call gb_Trace_MakeMark,$*,SCR)
+ $(call gb_Output_announce_title,module $* screenshots done.)
+ -$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && \
+ touch $@)
+
+$(call gb_Module_get_subsequentcheck_target,%) :
+ $(call gb_Output_announce,$*,$(true),SCK,5)
+ $(call gb_Trace_MakeMark,$*,SCK)
+ $(call gb_Output_announce_title,module $* subsequentchecks done.)
+ -$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && \
+ touch $@)
+
+$(call gb_Module_get_perfcheck_target,%) :
+ $(call gb_Output_announce,$*,$(true),PFC,5)
+ $(call gb_Trace_MakeMark,$*,PFC)
+ $(call gb_Output_announce_title,module $* perfchecks done.)
+ -$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && \
+ touch $@)
+
+$(call gb_Module_get_uicheck_target,%) :
+ $(call gb_Output_announce,$*,$(true),UIT,5)
+ $(call gb_Trace_MakeMark,$*,UIT)
+ $(call gb_Output_announce_title,module $* uicheck done.)
+ -$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && \
+ touch $@)
+
+$(call gb_Module_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),MOD,5)
+ $(call gb_Trace_MakeMark,$*,MOD)
+ $(call gb_Output_announce_title,module $* done.)
+ -$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && \
+ touch $@)
+
+.PHONY : build build-l10n-only build-non-l10n-only unitcheck slowcheck screenshot subsequentcheck perfcheck uicheck clean check debugrun help showmodules translations
+.DEFAULT_GOAL := build
+
+ifeq ($(gb_Side),build)
+build-tools : $(gb_BUILD_TOOLS)
+ $(call gb_Output_announce,loaded tools: $(gb_BUILD_TOOLS),$(true),ALL,6)
+ $(call gb_Trace_MakeMark,$(gb_BUILD_TOOLS),ALL)
+ $(call gb_Output_announce_title,build-tools done.)
+ $(call gb_Output_announce_bell)
+endif
+
+build :
+ $(call gb_Output_announce,top level modules: $(foreach module,$(filter-out deliverlog $(WORKDIR)/bootstrap,$^),$(notdir $(module))),$(true),ALL,6)
+ $(call gb_Trace_MakeMark,top level modules: $(foreach module,$(filter-out deliverlog $(WORKDIR)/bootstrap,$^),$(notdir $(module))),ALL)
+ $(if $(gb_VERBOSE),$(call gb_Output_announce,loaded modules: $(sort $(gb_Module_ALLMODULES)),$(true),ALL,6))
+ $(call gb_Output_announce_title,build done.)
+ $(call gb_Output_announce_bell)
+
+build-l10n-only :
+ $(call gb_Output_announce,top level modules: $(foreach module,$(filter-out deliverlog $(WORKDIR)/bootstrap,$^),$(notdir $(module))),$(true),LOC,6)
+ $(call gb_Trace_MakeMark,top level modules: $(foreach module,$(filter-out deliverlog $(WORKDIR)/bootstrap,$^),$(notdir $(module))),LOC)
+ $(if $(gb_VERBOSE),$(call gb_Output_announce,loaded modules: $(sort $(gb_Module_ALLMODULES)),$(true),LOC,6))
+ $(call gb_Output_announce_title,l10n done.)
+ $(call gb_Output_announce_bell)
+
+build-non-l10n-only :
+ $(call gb_Output_announce,top level modules: $(foreach module,$(filter-out deliverlog $(WORKDIR)/bootstrap,$^),$(notdir $(module))),$(true),BIN,6)
+ $(call gb_Trace_MakeMark,top level modules: $(foreach module,$(filter-out deliverlog $(WORKDIR)/bootstrap,$^),$(notdir $(module))),BIN)
+ $(if $(gb_VERBOSE),$(call gb_Output_announce,loaded modules: $(sort $(gb_Module_ALLMODULES)),$(true),BIN,6))
+ $(call gb_Output_announce_title,non-l10n done.)
+ $(call gb_Output_announce_bell)
+
+unitcheck :
+ $(if $(gb_VERBOSE),$(call gb_Output_announce,loaded modules: $(sort $(gb_Module_ALLMODULES)),$(true),CHK,6))
+ $(call gb_Output_announce_title,all unittests checked.)
+ $(call gb_Output_announce_bell)
+
+slowcheck :
+ $(if $(gb_VERBOSE),$(call gb_Output_announce,loaded modules: $(sort $(gb_Module_ALLMODULES)),$(true),SLC,6))
+ $(call gb_Output_announce_title,all slowtests checked.)
+ $(call gb_Output_announce_bell)
+
+screenshot :
+ $(if $(gb_VERBOSE),$(call gb_Output_announce,loaded modules: $(sort $(gb_Module_ALLMODULES)),$(true),SCR,6))
+ $(call gb_Output_announce_title,all screenshots checked.)
+ $(call gb_Output_announce_bell)
+
+# removing the dependency on build for now until we can make a full build with gbuild
+#subsequentcheck : build
+subsequentcheck :
+ $(if $(gb_VERBOSE),$(call gb_Output_announce,loaded modules: $(sort $(gb_Module_ALLMODULES)),$(true),SCK,6))
+ $(call gb_Output_announce_title,all subsequent tests checked.)
+ $(call gb_Output_announce_bell)
+
+perfcheck :
+ $(if $(gb_VERBOSE),$(call gb_Output_announce,loaded modules: $(sort $(gb_Module_ALLMODULES)),$(true),PFC,6))
+ $(call gb_Output_announce_title,all perftests checked.)
+ $(call gb_Output_announce_bell)
+
+uicheck : build
+ $(if $(gb_VERBOSE),$(call gb_Output_announce,loaded modules: $(sort $(gb_Module_ALLMODULES)),$(true),UIT,6))
+ $(call gb_Output_announce_title,all uicheck checked.)
+ $(call gb_Output_announce_bell)
+
+clean :
+ $(if $(gb_VERBOSE),$(call gb_Output_announce,top level modules: $(foreach module,$^,$(notdir $(module))),$(false),ALL,6))
+ $(call gb_Output_announce,loaded modules: $(sort $(gb_Module_ALLMODULES)),$(false),ALL,6)
+ $(call gb_Output_announce_title,all cleared.)
+ $(call gb_Output_announce_bell)
+
+check : unitcheck slowcheck
+ $(call gb_Output_announce_title,all tests checked.)
+ $(call gb_Output_announce_bell)
+
+debugrun :
+ $(call gb_Module_DEBUGRUNCOMMAND)
+
+help :
+ @cat $(SRCDIR)/solenv/gbuild/gbuild.help.txt
+
+showmodules :
+ $(info $(strip $(gb_Module_ALLMODULES)))
+ @true
+
+translations : $(WORKDIR)/pot.done
+
+$(WORKDIR)/pot.done : $(foreach exec,cfgex helpex localize propex ulfex xrmex treex, \
+ $(call gb_Executable_get_target_for_build,$(exec)))
+ $(call gb_Output_announce,$(subst .pot,,$(subst $(WORKDIR)/,,$@)),$(true),POT,1)
+ $(call gb_Trace_MakeMark,$(subst .pot,,$(subst $(WORKDIR)/,,$@)),POT)
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@) && $(call gb_Helper_execute,localize) $(SRCDIR) $(dir $@)/pot \
+ && $(FIND) $(dir $@)/pot -type f -printf "%P\n" | sed -e "s/\.pot/.po/" | LC_ALL=C $(SORT) > $(dir $@)/LIST \
+ && touch $@)
+
+# enable if: no "-MODULE/" defined AND ["all" defined OR "MODULE/" defined]
+# $(1) is module name, $(2) is directory name two levels up (for externals it's 'external')
+gb_Module__symbols_enabled = \
+ $(and $(if $(filter -$(1)/,$(gb_ENABLE_SYMBOLS_FOR)),,$(true)),\
+ $(if $(filter -$(2)/,$(gb_ENABLE_SYMBOLS_FOR)),,$(true)),\
+ $(filter all $(1)/,$(gb_ENABLE_SYMBOLS_FOR)))
+# enable if: no "-MODULE/" defined AND ["all" defined OR "MODULE/" defined]
+# $(1) is module name, $(2) is directory name two levels up (for externals it's 'external')
+gb_Module__force_compile = \
+ $(and $(if $(filter -$(1)/,$(FORCE_COMPILE)),,$(true)),\
+ $(if $(filter -$(2)/,$(FORCE_COMPILE)),,$(true)),\
+ $(filter all $(1)/,$(FORCE_COMPILE)))
+
+define gb_Module_Module
+gb_Module_ALLMODULES += $(1)
+gb_Module_MODULELOCATIONS += $(1):$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
+gb_Module_TARGETSTACK := $(call gb_Module_get_target,$(1)) $(gb_Module_TARGETSTACK)
+gb_Module_L10NTARGETSTACK := $(call gb_Module_get_l10n_target,$(1)) $(gb_Module_L10NTARGETSTACK)
+gb_Module_CHECKTARGETSTACK := $(call gb_Module_get_check_target,$(1)) $(gb_Module_CHECKTARGETSTACK)
+gb_Module_SLOWCHECKTARGETSTACK := $(call gb_Module_get_slowcheck_target,$(1)) $(gb_Module_SLOWCHECKTARGETSTACK)
+gb_Module_SCREENSHOTTARGETSTACK := $(call gb_Module_get_screenshot_target,$(1)) $(gb_Module_SCREENSHOTTARGETSTACK)
+gb_Module_UICHECKTARGETSTACK := $(call gb_Module_get_uicheck_target,$(1)) $(gb_Module_UICHECKTARGETSTACK)
+gb_Module_SUBSEQUENTCHECKTARGETSTACK := $(call gb_Module_get_subsequentcheck_target,$(1)) $(gb_Module_SUBSEQUENTCHECKTARGETSTACK)
+gb_Module_PERFCHECKTARGETSTACK := $(call gb_Module_get_perfcheck_target,$(1)) $(gb_Module_PERFCHECKTARGETSTACK)
+gb_Module_CLEANTARGETSTACK := $(call gb_Module_get_clean_target,$(1)) $(gb_Module_CLEANTARGETSTACK)
+gb_Module_CURRENTMODULE_SYMBOLS_ENABLED := $(call gb_Module__symbols_enabled,$(1),$(notdir $(realpath $(dir $(realpath $(lastword $(MAKEFILE_LIST))))../)))
+gb_Module_CURRENTMODULE_FORCE_COMPILE := $(call gb_Module__force_compile,$(1),$(notdir $(realpath $(dir $(realpath $(lastword $(MAKEFILE_LIST))))../)))
+gb_Module_CURRENTMODULE_NAME := $(1)
+$(call gb_Helper_make_userfriendly_targets,$(1),Module)
+$(if $(filter-out libreoffice instsetoo_native android ios,$(1)),\
+ $(call gb_Postprocess_register_target,AllModulesButInstsetNative,Module,$(1)))
+
+$(call gb_Postprocess_get_target,AllModuleTests) : $(call gb_Module_get_check_target,$(1))
+$(call gb_Postprocess_get_target,AllModuleSlowtests) : $(call gb_Module_get_slowcheck_target,$(1))
+$(call gb_Postprocess_get_target,AllModuleScreenshots) : $(call gb_Module_get_screenshot_target,$(1))
+$(call gb_Postprocess_get_target,AllModuleUITest) : $(call gb_Module_get_uicheck_target,$(1))
+
+endef
+
+# This is called inside the included file and pushes one target on each stack.
+# This has to be called with full late evaluation ($$(eval $$(call ))) and
+# should never be inlined ($(call )) as the calls defining it might be sourced
+# before gb_Module.
+define gb_Module_register_target
+gb_Module_CURRENTTARGET := $(1)
+gb_Module_CURRENTCLEANTARGET := $(2)
+
+endef
+
+# Here we include the file (in it there will be a call to gb_Module_register_target)
+define gb_Module__read_targetfile
+gb_Module_CURRENTTARGET :=
+gb_Module_CURRENTCLEANTARGET :=
+gb_Module_CURRENTMAKEFILE := $(patsubst $(1):%,%,$(filter $(1):%,$(gb_Module_MODULELOCATIONS)))$(2).mk
+include $(patsubst $(1):%,%,$(filter $(1):%,$(gb_Module_MODULELOCATIONS)))$(2).mk
+gb_Module_CURRENTMAKEFILE :=
+ifneq ($$(words $$(gb_Module_CURRENTTARGET)) $$(words $$(gb_Module_CURRENTCLEANTARGET)),1 1)
+$$(eval $$(call gb_Output_error,No $(3) registered while reading $(patsubst $(1):%,%,$(filter $(1):%,$(gb_Module_MODULELOCATIONS)))$(2).mk!))
+endif
+
+endef
+
+define gb_Module_add_target
+$(if $(filter AllLang% Dictionary% Package_registry,$(2)),$(warning target $(2) should be a l10n target))
+$(call gb_Module__read_targetfile,$(1),$(2),target)
+
+$(call gb_Module_get_nonl10n_target,$(1)) : $$(gb_Module_CURRENTTARGET)
+$(call gb_Module_get_clean_target,$(1)) : $$(gb_Module_CURRENTCLEANTARGET)
+
+endef
+
+define gb_Module_add_l10n_target
+$(if $(filter AllLang% CustomTarget_autotextshare Dictionary% Package_registry,$(2)),,$(warning target $(2) should not be a l10n target))
+$(call gb_Module__read_targetfile,$(1),$(2),target)
+
+$(call gb_Module_get_l10n_target,$(1)) : $$(gb_Module_CURRENTTARGET)
+$(call gb_Module_get_clean_target,$(1)) : $$(gb_Module_CURRENTCLEANTARGET)
+
+endef
+
+define gb_Module_add_check_target
+$(call gb_Module__read_targetfile,$(1),$(2),check target)
+
+$(call gb_Module_get_check_target,$(1)) : $$(gb_Module_CURRENTTARGET)
+$(call gb_Module_get_clean_target,$(1)) : $$(gb_Module_CURRENTCLEANTARGET)
+
+endef
+
+define gb_Module_add_slowcheck_target
+$(call gb_Module__read_targetfile,$(1),$(2),slowcheck target)
+
+$(call gb_Module_get_slowcheck_target,$(1)) : $$(gb_Module_CURRENTTARGET)
+$(call gb_Module_get_clean_target,$(1)) : $$(gb_Module_CURRENTCLEANTARGET)
+
+endef
+
+define gb_Module_add_screenshot_target
+$(call gb_Module__read_targetfile,$(1),$(2),screenshot target)
+
+$(call gb_Module_get_screenshot_target,$(1)) : $$(gb_Module_CURRENTTARGET)
+$(call gb_Module_get_clean_target,$(1)) : $$(gb_Module_CURRENTCLEANTARGET)
+
+endef
+
+# has order dependency on AllModulesButInstsetNative to be able to run
+# subsequentcheck in the same make process on "make check"
+define gb_Module_add_subsequentcheck_target
+$(call gb_Module__read_targetfile,$(1),$(2),subsequentcheck target)
+
+$(call gb_Module_get_subsequentcheck_target,$(1)) : $$(gb_Module_CURRENTTARGET)
+$$(gb_Module_CURRENTTARGET) :| \
+ $(call gb_Postprocess_get_target,AllModulesButInstsetNative) \
+ $(call gb_Package_get_target,instsetoo_native_setup) \
+ $(call gb_Package_get_target,instsetoo_native_setup_ure)
+$(call gb_Module_get_clean_target,$(1)) : $$(gb_Module_CURRENTCLEANTARGET)
+
+endef
+
+define gb_Module_add_perfcheck_target
+$(call gb_Module__read_targetfile,$(1),$(2),perfcheck target)
+
+$(call gb_Module_get_perfcheck_target,$(1)) : $$(gb_Module_CURRENTTARGET)
+$(call gb_Module_get_clean_target,$(1)) : $$(gb_Module_CURRENTCLEANTARGET)
+
+endef
+
+define gb_Module_add_uicheck_target
+$(call gb_Module__read_targetfile,$(1),$(2),uicheck target)
+
+$(call gb_Module_get_uicheck_target,$(1)) : $$(gb_Module_CURRENTTARGET)
+$$(gb_Module_CURRENTTARGET) :| \
+ $(call gb_Postprocess_get_target,AllModulesButInstsetNative) \
+ $(call gb_Package_get_target,instsetoo_native_setup) \
+ $(call gb_Package_get_target,instsetoo_native_setup_ure)
+$(call gb_Module_get_uicheck_target,$(1)) : $$(gb_Module_CURRENTTARGET)
+$(call gb_Module_get_clean_target,$(1)) : $$(gb_Module_CURRENTCLEANTARGET)
+
+endef
+
+define gb_Module__modulefile
+$(patsubst $(1):%,%,$(filter $(1):%,$(gb_Module_MODULELOCATIONS)))/$(2)/Module_$(2).mk
+endef
+
+define gb_Module_add_moduledir
+$(if $(wildcard $(call gb_Module__modulefile,$(1),$(2))),,$(call gb_Output_error,Module does not exist: $(call gb_Module__modulefile,$(1),$(2))))
+include $(call gb_Module__modulefile,$(1),$(2))
+$(call gb_Module_get_target,$(1)) : $$(firstword $$(gb_Module_TARGETSTACK))
+$(call gb_Module_get_l10n_target,$(1)) : $$(firstword $$(gb_Module_L10NTARGETSTACK))
+$(call gb_Module_get_check_target,$(1)) : $$(firstword $$(gb_Module_CHECKTARGETSTACK))
+$(call gb_Module_get_slowcheck_target,$(1)) : $$(firstword $$(gb_Module_SLOWCHECKTARGETSTACK))
+$(call gb_Module_get_screenshot_target,$(1)) : $$(firstword $$(gb_Module_SCREENSHOTTARGETSTACK))
+$(call gb_Module_get_subsequentcheck_target,$(1)) : $$(firstword $$(gb_Module_SUBSEQUENTCHECKTARGETSTACK))
+$(call gb_Module_get_perfcheck_target,$(1)) : $$(firstword $$(gb_Module_PERFCHECKTARGETSTACK))
+$(call gb_Module_get_uicheck_target,$(1)) : $$(firstword $$(gb_Module_UICHECKTARGETSTACK))
+$(call gb_Module_get_clean_target,$(1)) : $$(firstword $$(gb_Module_CLEANTARGETSTACK))
+gb_Module_TARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_TARGETSTACK)),$$(gb_Module_TARGETSTACK))
+gb_Module_L10NTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_L10NTARGETSTACK)),$$(gb_Module_L10NTARGETSTACK))
+gb_Module_CHECKTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_CHECKTARGETSTACK)),$$(gb_Module_CHECKTARGETSTACK))
+gb_Module_SLOWCHECKTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_SLOWCHECKTARGETSTACK)),$$(gb_Module_SLOWCHECKTARGETSTACK))
+gb_Module_SCREENSHOTTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_SCREENSHOTTARGETSTACK)),$$(gb_Module_SCREENSHOTTARGETSTACK))
+gb_Module_SUBSEQUENTCHECKTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_SUBSEQUENTCHECKTARGETSTACK)),$$(gb_Module_SUBSEQUENTCHECKTARGETSTACK))
+gb_Module_PERFCHECKTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_PERFCHECKTARGETSTACK)),$$(gb_Module_PERFCHECKTARGETSTACK))
+gb_Module_UICHECKTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_UICHECKTARGETSTACK)),$$(gb_Module_UICHECKTARGETSTACK))
+gb_Module_CLEANTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_CLEANTARGETSTACK)),$$(gb_Module_CLEANTARGETSTACK))
+
+endef
+
+define gb_Module_add_targets
+$(call gb_Module_get_target,$(1)) : $(call gb_Module_get_nonl10n_target,$(1))
+$(foreach target,$(2),$(call gb_Module_add_target,$(1),$(target)))
+
+endef
+
+define gb_Module_add_l10n_targets
+$(call gb_Module_get_target,$(1)) : $(call gb_Module_get_l10n_target,$(1))
+$(foreach target,$(2),$(call gb_Module_add_l10n_target,$(1),$(target)))
+
+endef
+
+gb_Module_add_targets_for_build = $(call gb_Module_add_targets,$(1),$(2))
+
+define gb_Module_add_check_targets
+$(foreach target,$(2),$(call gb_Module_add_check_target,$(1),$(target)))
+
+endef
+
+define gb_Module_add_slowcheck_targets
+$(foreach target,$(2),$(call gb_Module_add_slowcheck_target,$(1),$(target)))
+
+endef
+
+define gb_Module_add_screenshot_targets
+$(foreach target,$(2),$(call gb_Module_add_screenshot_target,$(1),$(target)))
+
+endef
+
+define gb_Module_add_subsequentcheck_targets
+$(foreach target,$(2),$(call gb_Module_add_subsequentcheck_target,$(1),$(target)))
+
+endef
+
+define gb_Module_add_perfcheck_targets
+$(foreach target,$(2),$(call gb_Module_add_perfcheck_target,$(1),$(target)))
+
+endef
+
+define gb_Module_add_moduledirs
+$(foreach target,$(sort $(2)),$(call gb_Module_add_moduledir,$(1),$(target)))
+
+endef
+
+define gb_Module_add_uicheck_targets
+$(foreach target,$(2),$(call gb_Module_add_uicheck_target,$(1),$(target)))
+
+endef
+
+define gb_Module_make_global_targets
+ifneq ($$(gb_Module_TARGETSTACK),)
+$$(eval $$(call gb_Output_error,Corrupted module target stack!1))
+endif
+
+include $(1)
+
+build : build-non-l10n-only build-l10n-only
+build-non-l10n-only : $$(firstword $$(gb_Module_TARGETSTACK))
+build-l10n-only : $$(firstword $$(gb_Module_L10NTARGETSTACK))
+unitcheck : $$(firstword $$(gb_Module_CHECKTARGETSTACK))
+slowcheck : $$(firstword $$(gb_Module_SLOWCHECKTARGETSTACK))
+screenshot : $$(firstword $$(gb_Module_SCREENSHOTTARGETSTACK))
+ifeq ($(WINDOWS_BUILD_SIGNING),TRUE)
+screenshot : $(call gb_CustomTarget_get_workdir,postprocess/signing)/signing.done
+endif
+subsequentcheck : $$(firstword $$(gb_Module_SUBSEQUENTCHECKTARGETSTACK))
+perfcheck : $$(firstword $$(gb_Module_PERFCHECKTARGETSTACK))
+uicheck : build $$(firstword $$(gb_Module_UICHECKTARGETSTACK))
+clean : $$(firstword $$(gb_Module_CLEANTARGETSTACK))
+
+ifneq ($$(words $$(gb_Module_TARGETSTACK)),1)
+$$(eval $$(call gb_Output_error,Corrupted module target stack! $(gb_Module_TARGETSTACK)))
+endif
+
+gb_Module_TARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_TARGETSTACK)),$$(gb_Module_TARGETSTACK))
+gb_Module_L10NTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_L10NTARGETSTACK)),$$(gb_Module_L10NTARGETSTACK))
+gb_Module_CHECKTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_CHECKTARGETSTACK)),$$(gb_Module_CHECKTARGETSTACK))
+gb_Module_SLOWCHECKTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_SLOWCHECKTARGETSTACK)),$$(gb_Module_SLOWCHECKTARGETSTACK))
+gb_Module_SCREENSHOTTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_SCREENSHOTTARGETSTACK)),$$(gb_Module_SCREENSHOTTARGETSTACK))
+gb_Module_SUBSEQUENTCHECKTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_SUBSEQUENTCHECKTARGETSTACK)),$$(gb_Module_SUBSEQUENTCHECKTARGETSTACK))
+gb_Module_UICHECKTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_UICHECKTARGETSTACK)),$$(gb_Module_UICHECKTARGETSTACK))
+gb_Module_PERFCHECKTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_PERFCHECKTARGETSTACK)),$$(gb_Module_PERFCHECKTARGETSTACK))
+gb_Module_CLEANTARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_CLEANTARGETSTACK)),$$(gb_Module_CLEANTARGETSTACK))
+
+ifneq ($$(and $$(gb_Module_TARGETSTACK),$$(gb_Module_CHECKTARGETSTACK),$$(gb_Module_SLOWCHECKTARGETSTACK),$$(gb_Module_SCREENSHOTTARGETSTACK),$$(gb_Module_SUBSEQUENTCHECKTARGETSTACK),$$(gb_Module_UICHECKTARGETSTACK),$$(gb_Module_PERFCHECKTARGETSTACK),$$(gb_Module_L10NTARGETSTACK)),)
+$$(eval $$(call gb_Output_error,Corrupted module target stack!3))
+endif
+
+$$(eval $$(gb_Extensions_final_hook))
+endef
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/Output.mk b/solenv/gbuild/Output.mk
new file mode 100644
index 000000000..c4b992df4
--- /dev/null
+++ b/solenv/gbuild/Output.mk
@@ -0,0 +1,157 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# user notifications and formatting
+
+define gb_Output__format_type
+[$(word 2,$(1) build clean) $(2)]
+endef
+
+define gb_Output__format_target
+$(1)
+endef
+
+define gb_Output_error
+$(error $(1))
+endef
+
+define gb_Output_announce_title
+endef
+
+define gb_Output_announce_bell
+endef
+
+define gb_Output_info
+$(info [info $(2)] $(1))
+endef
+
+define gb_Output_warn
+$(warning $(NEWLINE)[WARN $(2)] !!!$(NEWLINE)[WARN $(2)] !!! $(1)$(NEWLINE)[WARN $(2)] !!!)
+endef
+
+gb_Output_ESCAPE := $(shell echo|awk 'BEGIN { printf "%c", 27 }' -)
+gb_Output_BELL := $(shell echo|awk 'BEGIN { printf "%c", 7 }' -)
+
+# default to color output, if interactive
+ifeq ($(origin gb_COLOR),undefined)
+ifneq ($(MAKE_TERMOUT),)
+# Cygwin mintty has issues where gb_Output_error is swallowed
+ifneq ($(OS),WNT)
+gb_COLOR=$(true)
+endif
+endif
+endif
+
+# only enable colorized output if
+# - gb_COLOR is set
+# - we have a known term
+gb_KNOWN_TERM:=Eterm aterm gnome kterm linux putty rxvt rxvt-unicode screen xterm xterm xtermc cygwin
+gb_KNOWN_TERM+=$(patsubst %,%-color,$(gb_KNOWN_TERM))
+gb_KNOWN_TERM+=$(patsubst %-color,%-256color,$(gb_KNOWN_TERM))
+gb_KNOWN_TERM+=$(patsubst %-color,%+256color,$(gb_KNOWN_TERM))
+gb_KNOWN_TERM+=$(patsubst %,screen.%,$(gb_KNOWN_TERM))
+ifneq ($(strip $(gb_COLOR)),)
+ifneq ($(filter $(TERM),$(gb_KNOWN_TERM)),)
+
+gb_Output_COLOR_RESET := $(gb_Output_ESCAPE)[0m
+gb_Output_COLOR_RESETANDESCAPE := $(gb_Output_COLOR_RESET)$(gb_Output_ESCAPE)
+
+gb_Output_COLOR_OUTBUILD_LEVEL1 := $(gb_Output_COLOR_RESETANDESCAPE)[37;40m
+gb_Output_COLOR_OUTBUILD_LEVEL2 := $(gb_Output_COLOR_RESETANDESCAPE)[37;40m
+gb_Output_COLOR_OUTBUILD_LEVEL3 := $(gb_Output_COLOR_RESETANDESCAPE)[37;40m
+gb_Output_COLOR_OUTBUILD_LEVEL4 := $(gb_Output_COLOR_RESETANDESCAPE)[37;40m
+gb_Output_COLOR_OUTBUILD_LEVEL5 := $(gb_Output_COLOR_RESETANDESCAPE)[37;1;46m
+gb_Output_COLOR_OUTBUILD_LEVEL6 := $(gb_Output_COLOR_RESETANDESCAPE)[37;1;44m
+
+gb_Output_COLOR_INBUILD_LEVEL1 := $(gb_Output_COLOR_RESETANDESCAPE)[36;40m
+gb_Output_COLOR_INBUILD_LEVEL2 := $(gb_Output_COLOR_RESETANDESCAPE)[36;1;40m
+gb_Output_COLOR_INBUILD_LEVEL3 := $(gb_Output_COLOR_RESETANDESCAPE)[32;40m
+gb_Output_COLOR_INBUILD_LEVEL4 := $(gb_Output_COLOR_RESETANDESCAPE)[32;1;40m
+gb_Output_COLOR_INBUILD_LEVEL5 := $(gb_Output_COLOR_RESETANDESCAPE)[37;1;46m
+gb_Output_COLOR_INBUILD_LEVEL6 := $(gb_Output_COLOR_RESETANDESCAPE)[37;1;44m
+
+gb_Output_COLOR_OUTCLEAN_LEVEL1 := $(gb_Output_COLOR_RESETANDESCAPE)[37;40m
+gb_Output_COLOR_OUTCLEAN_LEVEL2 := $(gb_Output_COLOR_RESETANDESCAPE)[37;40m
+gb_Output_COLOR_OUTCLEAN_LEVEL3 := $(gb_Output_COLOR_RESETANDESCAPE)[37;40m
+gb_Output_COLOR_OUTCLEAN_LEVEL4 := $(gb_Output_COLOR_RESETANDESCAPE)[37;40m
+gb_Output_COLOR_OUTCLEAN_LEVEL5 := $(gb_Output_COLOR_RESETANDESCAPE)[33;1;41m
+gb_Output_COLOR_OUTCLEAN_LEVEL6 := $(gb_Output_COLOR_RESETANDESCAPE)[37;1;41m
+
+gb_Output_COLOR_INCLEAN_LEVEL1 := $(gb_Output_COLOR_RESETANDESCAPE)[33;40m
+gb_Output_COLOR_INCLEAN_LEVEL2 := $(gb_Output_COLOR_RESETANDESCAPE)[33;1;40m
+gb_Output_COLOR_INCLEAN_LEVEL3 := $(gb_Output_COLOR_RESETANDESCAPE)[31;40m
+gb_Output_COLOR_INCLEAN_LEVEL4 := $(gb_Output_COLOR_RESETANDESCAPE)[31;1;40m
+gb_Output_COLOR_INCLEAN_LEVEL5 := $(gb_Output_COLOR_RESETANDESCAPE)[33;1;41m
+gb_Output_COLOR_INCLEAN_LEVEL6 := $(gb_Output_COLOR_RESETANDESCAPE)[37;1;41m
+
+gb_Output_COLOR_ERROR := $(gb_Output_COLOR_RESETANDESCAPE)[37;1;41m
+
+define gb_Output__format_type
+$(subst :, ,$(word 2,$(1) \
+ $(gb_Output_COLOR_OUTBUILD_LEVEL$(3))[$(gb_Output_COLOR_INBUILD_LEVEL$(3))$(subst $(WHITESPACE),:,$(2))$(gb_Output_COLOR_OUTBUILD_LEVEL$(3))] \
+ $(gb_Output_COLOR_OUTCLEAN_LEVEL$(3))[$(gb_Output_COLOR_INCLEAN_LEVEL$(3))$(subst $(WHITESPACE),:,$(2))$(gb_Output_COLOR_OUTCLEAN_LEVEL$(3))]))$(gb_Output_COLOR_RESET)
+endef
+
+define gb_Output_info
+$(info $(gb_Output_COLOR_OUTBUILD_LEVEL6)[$(gb_Output_COLOR_INBUILD_LEVEL6)info $(2)$(gb_Output_COLOR_OUTBUILD_LEVEL6)]$(gb_Output_COLOR_RESET) $(1))
+endef
+
+define gb_Output_warn
+$(warning $(NEWLINE)$(gb_Output_COLOR_OUTCLEAN_LEVEL6)[$(gb_Output_COLOR_INCLEAN_LEVEL6)WARN $(2)$(gb_Output_COLOR_OUTCLEAN_LEVEL6)]$(gb_Output_COLOR_RESET) !!!$(NEWLINE)$(gb_Output_COLOR_OUTCLEAN_LEVEL6)[$(gb_Output_COLOR_INCLEAN_LEVEL6)WARN $(2)$(gb_Output_COLOR_OUTCLEAN_LEVEL6)]$(gb_Output_COLOR_RESET) !!! $(1)$(NEWLINE)$(gb_Output_COLOR_OUTCLEAN_LEVEL6)[$(gb_Output_COLOR_INCLEAN_LEVEL6)WARN $(2)$(gb_Output_COLOR_OUTCLEAN_LEVEL6)]$(gb_Output_COLOR_RESET) !!!)
+endef
+
+define gb_Output_error
+$(error $(gb_Output_COLOR_ERROR)$(1)$(gb_Output_COLOR_RESET))
+endef
+
+endif
+endif
+
+# only enable title output if
+# - gb_TITLES is set
+# - we have a known term
+ifneq ($(strip $(gb_TITLES)),)
+ifneq ($(filter $(TERM),$(gb_KNOWN_TERM)),)
+define gb_Output_announce_title
+$(info $(gb_Output_ESCAPE)]2;gbuild: $(1)$(gb_Output_BELL)$(gb_Output_ESCAPE)[A)
+endef
+
+$(call gb_Output_announce_title,...)
+
+endif
+endif
+
+# only enable bell output if
+# - gb_BELL is set
+# - gb_TTY is true (not piping to a file)
+ifneq ($(strip $(gb_BELL)),)
+define gb_Output_announce_bell
+$(info $(gb_Output_BELL)$(gb_Output_ESCAPE)[A)
+endef
+endif
+
+define gb_Output_announce_str
+$(call gb_Output__format_type,$(2),$(3),$(4)) $(call gb_Output__format_target,$(1))
+endef
+
+define gb_Output_announce
+$(info $(call gb_Output_announce_str,$(1),$(2),$(3),$(4)))
+endef
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/Package.mk b/solenv/gbuild/Package.mk
new file mode 100644
index 000000000..9c90322cf
--- /dev/null
+++ b/solenv/gbuild/Package.mk
@@ -0,0 +1,227 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+
+# PackagePart class
+
+# a pattern rule with multiple targets is actually executed only once for each
+# match, so define only pattern rules with one target here
+# the .dir is for make 3.81, which ignores trailing /
+define gb_PackagePart__rule
+$(1)/.dir :
+ $$(if $$(wildcard $$(dir $$@)),,mkdir -p $$(dir $$@))
+$(1)/%/.dir :
+ $$(if $$(wildcard $$(dir $$@)),,mkdir -p $$(dir $$@))
+$(1)/% :
+ $$(call gb_Deliver_deliver,$$<,$$@)
+endef
+
+$(foreach destination,$(call gb_PackagePart_get_destinations),$(eval \
+ $(call gb_PackagePart__rule,$(destination))))
+
+# Deliver one file to the output dir.
+#
+# gb_PackagePart_PackagePart destfile source prep-target outdir
+define gb_PackagePart_PackagePart
+$(4)/$(1) : $(2) | $(dir $(4)/$(1)).dir
+$(2) :| $(3)
+
+$(if $(gb_Package_PRESTAGEDIR),\
+ $(if $(wildcard $(gb_Package_PRESTAGEDIR)/$(1)),\
+ $(call gb_Deliver_add_deliverable,$(4)/$(1),$(gb_Package_PRESTAGEDIR)/$(1),$(3)),\
+ $(call gb_Deliver_add_deliverable,$(4)/$(1),$(2),$(3)) \
+ ),\
+ $(call gb_Deliver_add_deliverable,$(4)/$(1),$(2),$(3)) \
+)
+
+endef
+
+
+# Package class
+
+$(dir $(call gb_Package_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_Package_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+.PHONY : $(call gb_Package_get_clean_target,%)
+$(call gb_Package_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),PKG,2)
+ RESPONSEFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),500,$(FILES)) \
+ && cat $${RESPONSEFILE} | $(if $(filter WNT,$(OS)),env -i PATH="$$PATH") xargs $(if $(filter MACOSX,$(OS_FOR_BUILD)),-n 1000) rm -fr \
+ && rm -f $${RESPONSEFILE}
+
+$(call gb_Package_get_preparation_target,%) :
+ mkdir -p $(dir $@) && touch $@
+
+# NOTE: It is possible that a file has been added to the package more
+# than once, so we must drop the duplicates, or Windows installer will
+# be unhappy.
+# TODO: this is only for convenience for impl. of gbuild classes. There
+# should be check that it does not happen in "normal" use, i.e., in
+# Package_foo makefiles.
+$(call gb_Package_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),PKG,2)
+ $(call gb_Trace_StartRange,$*,PKG)
+ $(if $(PACKAGE_DEFINED),,$(call gb_Output_error,$(RDEPENDS) depend(s) on package $* which does not exist.))
+ rm -f $@ && \
+ mv $(call gb_var2file,$@.tmp,100,$(sort $(FILES))) $@
+ $(call gb_Trace_EndRange,$*,PKG)
+
+# for other targets that want to create Packages, does not register at Module
+define gb_Package_Package_internal
+gb_Package_SOURCEDIR_$(1) := $(2)
+gb_Package_OUTDIR_$(1) := $(INSTROOT)
+$(call gb_Package_get_target,$(1)) : PACKAGE_DEFINED := $(true)
+$(call gb_Package_get_target,$(1)) : FILES :=
+$(call gb_Package_get_clean_target,$(1)) : FILES := $(call gb_Package_get_target,$(1)) $(call gb_Package_get_preparation_target,$(1))
+$(call gb_Package_get_target,$(1)) : $(call gb_Package_get_preparation_target,$(1))
+$(call gb_Package_get_target,$(1)) : $(gb_Module_CURRENTMAKEFILE)
+$(call gb_Package_get_target,$(1)) :| $(dir $(call gb_Package_get_target,$(1))).dir
+
+endef
+
+define gb_Package_Package
+$$(if $$(gb_Package_SOURCEDIR_$(1)),$$(call gb_Output_error,gb_Package__check: Package $(1) has already been defined))
+$(if $(filter postprocess% instsetoo_native%,$(1)),,\
+ $(call gb_Postprocess_register_target,AllPackages,Package,$(1)))
+ifeq (,$$(filter $(1),$$(gb_Package_REGISTERED)))
+$$(eval $$(call gb_Output_info,Currently known packages are: $(sort $(gb_Package_REGISTERED)),ALL))
+$$(eval $$(call gb_Output_error,Package $(1) must be registered in Repository.mk or RepositoryExternal.mk))
+endif
+$(call gb_Package_Package_internal,$(1),$(2))
+$$(eval $$(call gb_Module_register_target,$(call gb_Package_get_target,$(1)),$(call gb_Package_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),Package)
+
+endef
+
+# Ensure that the package is defined.
+#
+# gb_Package__check package
+define gb_Package__check
+$$(if $$(gb_Package_SOURCEDIR_$(1)),,$$(call gb_Output_error,gb_Package__check: Package $(1) has not been defined))
+
+endef
+
+# Set output dir for the package files.
+#
+# Default is $(INSTROOT).
+#
+# gb_Package_set_outdir package outdir
+define gb_Package_set_outdir
+$(call gb_Package__check,$(1))
+gb_Package_OUTDIR_$(1) := $(2)
+
+endef
+
+# Add empty directory (if it's non-empty, don't use this, use
+# gb_Package_add_file for the files in it instead!)
+define gb_Package_add_empty_directory
+$(call gb_Package__check,$(1))
+$(if $(strip $(2)),,$(call gb_Output_error,gb_Package_add_directory requires 2 arguments))
+$(call gb_Package_get_target,$(1)) :| $$(gb_Package_OUTDIR_$(1))/$(2)/.dir
+$(call gb_Package_get_target,$(1)) : FILES += $$(gb_Package_OUTDIR_$(1))/$(2)
+$(call gb_Package_get_clean_target,$(1)) : FILES += $$(gb_Package_OUTDIR_$(1))/$(2)
+
+endef
+
+# Example:
+# $(eval $(call gb_Package_add_empty_directories,foo_inc,inc/foo))
+# # -> inc/foo
+define gb_Package_add_empty_directories
+$(call gb_Package__check,$(1))
+$(foreach file,$(2),$(call gb_Package_add_empty_directory,$(1),$(file)))
+
+endef
+
+define gb_Package_add_symbolic_link
+$(call gb_Package__check,$(1))
+$(if $(strip $(3)),,$(call gb_Output_error,gb_Package_add_symbolic_link requires 3 arguments))
+$(call gb_Package_get_target,$(1)) : $$(gb_Package_OUTDIR_$(1))/$(2)
+$$(gb_Package_OUTDIR_$(1))/$(2) :| $$(dir $$(gb_Package_OUTDIR_$(1))/$(2)).dir
+ rm -f $$@ && ln -s $(3) $$@
+
+$(call gb_Package_get_target,$(1)) : FILES += $$(gb_Package_OUTDIR_$(1))/$(2)
+$(call gb_Package_get_clean_target,$(1)) : FILES += $$(gb_Package_OUTDIR_$(1))/$(2)
+
+endef
+
+define gb_Package_add_file
+$(call gb_Package__check,$(1))
+$(if $(strip $(3)),,$(call gb_Output_error,gb_Package_add_file requires 3 arguments))
+$(call gb_Package_get_target,$(1)) : $$(gb_Package_OUTDIR_$(1))/$(2)
+$(call gb_Package_get_target,$(1)) : FILES += $$(gb_Package_OUTDIR_$(1))/$(2)
+$(call gb_Package_get_clean_target,$(1)) : FILES += $$(gb_Package_OUTDIR_$(1))/$(2)
+$(call gb_PackagePart_PackagePart,$(2),$$(gb_Package_SOURCEDIR_$(1))/$(3),$(call gb_Package_get_preparation_target,$(1)),$$(gb_Package_OUTDIR_$(1)))
+
+endef
+
+# Adds several files at once.
+#
+# Files are copied directly into the specified directory.
+#
+# Example:
+# $(eval $(call gb_Package_Package,foo_inc,$(SRCDIR)/foo/inc))
+# $(eval $(call gb_Package_add_files,foo_inc,inc/foo,foo/bar/foo.hxx))
+# # -> inc/foo/foo.hxx
+define gb_Package_add_files
+$(call gb_Package__check,$(1))
+$(if $(strip $(3)),,$(if $(filter 1,$(words $(2))),,$(call gb_Output_error,gb_Package_add_files: it looks like either pkg name or dest. dir is missing)))
+$(foreach file,$(3),$(call gb_Package_add_file,$(1),$(2)/$(notdir $(file)),$(file)))
+
+endef
+
+# Adds several files at once.
+#
+# Files are copied including subdirectories.
+#
+# Example:
+# $(eval $(call gb_Package_Package,foo_inc,$(SRCDIR)/foo/inc))
+# $(eval $(call gb_Package_add_files,foo_inc,inc,foo/bar/foo.hxx))
+# # -> inc/foo/bar/foo.hxx
+define gb_Package_add_files_with_dir
+$(call gb_Package__check,$(1))
+$(if $(strip $(3)),,$(if $(filter 1,$(words $(2))),,$(call gb_Output_error,gb_Package_add_files: it looks like either pkg name or dest. dir is missing)))
+$(foreach file,$(3),$(call gb_Package_add_file,$(1),$(2)/$(file),$(file)))
+
+endef
+
+# Package files from custom target
+define gb_Package_use_custom_target
+$(call gb_Package__check,$(1))
+$(call gb_Package_get_preparation_target,$(1)) :| $(call gb_CustomTarget_get_target,$(2))
+
+endef
+
+# Package files from unpacked tarball of an external project
+define gb_Package_use_unpacked
+$(call gb_Package__check,$(1))
+$(call gb_Package_get_preparation_target,$(1)) :| $(call gb_UnpackedTarball_get_target,$(2))
+
+endef
+
+# Package files from build of an external project
+define gb_Package_use_external_project
+$(call gb_Package__check,$(1))
+$(call gb_Package_get_preparation_target,$(1)) :| $(call gb_ExternalProject_get_target,$(2))
+
+endef
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/PackageSet.mk b/solenv/gbuild/PackageSet.mk
new file mode 100644
index 000000000..e85c3ecea
--- /dev/null
+++ b/solenv/gbuild/PackageSet.mk
@@ -0,0 +1,77 @@
+# -*- 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/.
+#
+
+# class PackageSet
+
+# Allows to bundle a set of packages under one name.
+#
+# This is intended to be used by gbuild classes that want to provide a
+# filelist for installer, but for implementation reasons have to use
+# several Packages internally (e.g., because of different source dirs).
+
+$(dir $(call gb_PackageSet_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_PackageSet_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_PackageSet_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),PKS,2)
+ $(call gb_Trace_StartRange,$*,PKS)
+ cat $(sort $(FILELISTS)) > $@
+ $(call gb_Trace_EndRange,$*,PKS)
+
+.PHONY : $(call gb_PackageSet_get_clean_target,%)
+$(call gb_PackageSet_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),PKS,2)
+ rm -f $(call gb_PackageSet_get_target,$*)
+
+# Create and register a package set.
+#
+# gb_PackageSet_PackageSet set
+define gb_PackageSet_PackageSet
+$(call gb_PackageSet_PackageSet_internal,$(1))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_PackageSet_get_target,$(1)),$(call gb_PackageSet_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),PackageSet)
+
+endef
+
+# Create a package set.
+#
+# gb_PackageSet_PackageSet_internal set
+define gb_PackageSet_PackageSet_internal
+$(call gb_PackageSet_get_target,$(1)) : FILELISTS :=
+
+$(call gb_PackageSet_get_target,$(1)) :| $(dir $(call gb_PackageSet_get_target,$(1))).dir
+
+endef
+
+# Add a package to the set.
+#
+# A package can be added more than once.
+#
+# gb_PackageSet_add_package set package
+define gb_PackageSet_add_package
+$(call gb_PackageSet_get_target,$(1)) : FILELISTS += $(call gb_Package_get_target,$(2))
+
+$(call gb_PackageSet_get_target,$(1)) : $(call gb_Package_get_target,$(2))
+$(call gb_PackageSet_get_clean_target,$(1)) : $(call gb_Package_get_clean_target,$(2))
+
+endef
+
+# Add several packages to the set at once.
+#
+# gb_PackageSet_add_packages set package(s)
+define gb_PackageSet_add_packages
+$(foreach package,$(2),$(call gb_PackageSet_add_package,$(1),$(package)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/Pagein.mk b/solenv/gbuild/Pagein.mk
new file mode 100644
index 000000000..606596ce2
--- /dev/null
+++ b/solenv/gbuild/Pagein.mk
@@ -0,0 +1,61 @@
+# -*- 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/.
+#
+
+gb_Pagein__is_library = $(filter $(1),$(gb_Library_KNOWNLIBS))
+
+gb_Pagein__make_library_path = $(call gb_Library_get_runtime_filename,$(1))
+
+gb_Pagein__make_path = \
+$(if $(call gb_Pagein__is_library,$(1)),$(call gb_Pagein__make_library_path,$(1)),$(1))
+
+gb_Pagein__get_install_target = $(INSTROOT)/$(LIBO_BIN_FOLDER)/pagein-$(1)
+
+define gb_Pagein__command
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) && rm -f $(1) \
+ && touch $(1) \
+ $(foreach object,$(OBJECTS),&& echo $(call gb_Pagein__make_path,$(object)) >> $(1)))
+
+endef
+
+.PHONY : $(call gb_Pagein_get_clean_target,%)
+$(call gb_Pagein_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),PAG,5)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_Pagein__get_install_target,$*) $(call gb_Pagein_get_target,$*))
+
+$(call gb_Pagein_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),PAG,5)
+ $(call gb_Trace_StartRange,$*,PAG)
+ $(call gb_Pagein__command,$@,$*,$^)
+ $(call gb_Trace_EndRange,$*,PAG)
+
+define gb_Pagein_Pagein
+$(call gb_Pagein_get_target,$(1)) : OBJECTS :=
+$(call gb_Pagein_get_target,$(1)) : $(gb_Module_CURRENTMAKEFILE)
+$$(eval $$(call gb_Module_register_target,$(call gb_Pagein__get_install_target,$(1)),$(call gb_Pagein_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),Pagein,$(call gb_Pagein_get_target,$(1)))
+
+$(call gb_Helper_install_final, \
+ $(call gb_Pagein__get_install_target,$(1)), \
+ $(call gb_Pagein_get_target,$(1)))
+
+endef
+
+define gb_Pagein_add_object
+$(call gb_Pagein_get_target,$(1)) : OBJECTS += $(filter-out $(gb_MERGEDLIBS),$(2))
+
+endef
+
+define gb_Pagein_add_objects
+$(foreach object,$(2),$(call gb_Pagein_add_object,$(1),$(object)))
+
+endef
+
+# vim: set ts=4 sw=4 noet:
diff --git a/solenv/gbuild/Postprocess.mk b/solenv/gbuild/Postprocess.mk
new file mode 100644
index 000000000..2c1dfd2f4
--- /dev/null
+++ b/solenv/gbuild/Postprocess.mk
@@ -0,0 +1,56 @@
+# -*- 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/.
+#
+
+$(dir $(call gb_Postprocess_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_Postprocess_get_target,%) :
+ $(call gb_Output_announce,$(POSTPROCESS_INFO): $(if $(POSTPROCESS_PREFIX),$(subst $(POSTPROCESS_PREFIX),,$^),$^),$(true),ALL,6)
+ $(call gb_Trace_MakeMark,$(POSTPROCESS_INFO): $(if $(POSTPROCESS_PREFIX),$(subst $(POSTPROCESS_PREFIX),,$^),$^),ALL)
+ touch $@
+
+.PHONY : $(call gb_Postprocess_get_clean_target,%)
+$(call gb_Postprocess_get_clean_target,%) :
+ $(call gb_Output_announce,$(POSTPROCESS_INFO): $(if $(POSTPROCESS_PREFIX),$(subst $(POSTPROCESS_PREFIX),,$^),$^),$(false),ALL,6)
+ rm -f $(call gb_Postprocess_get_target,$*)
+
+define gb_Postprocess_Postprocess
+$(call gb_Postprocess_get_target,$(1)) : POSTPROCESS_INFO := $(2)
+$(call gb_Postprocess_get_target,$(1)) : POSTPROCESS_PREFIX := $(3)
+$(call gb_Postprocess_get_clean_target,$(1)) : POSTPROCESS_INFO := $(2)
+$(call gb_Postprocess_get_clean_target,$(1)) : POSTPROCESS_PREFIX := $(subst $(WORKDIR),$(WORKDIR)/Clean,$(3))
+
+$(call gb_Postprocess_get_target,$(1)) :| $(dir $(call gb_Postprocess_get_target,$(1))).dir
+
+$(call gb_Helper_make_userfriendly_targets,$(1),Postprocess)
+
+endef
+
+# gb_Postprocess_register_target category class targetname
+define gb_Postprocess_register_target
+$(call gb_Postprocess_get_target,$(1)) : $(call gb_$(2)_get_target,$(3))
+$(call gb_Postprocess_get_clean_target,$(1)) : $(call gb_$(2)_get_clean_target,$(3))
+
+endef
+
+define gb_Postprocess_make_targets
+$(call gb_Postprocess_Postprocess,AllExecutables,All executables)
+$(call gb_Postprocess_Postprocess,AllLibraries,All libraries)
+$(call gb_Postprocess_Postprocess,AllModulesButInstsetNative,All modules but instset,$(WORKDIR)/Module/)
+$(call gb_Postprocess_Postprocess,AllPackages,All packages,$(WORKDIR)/Package/)
+$(call gb_Postprocess_Postprocess,AllResources,All resources,$(WORKDIR)/AllLangRes/)
+$(call gb_Postprocess_Postprocess,AllUIConfigs,All UI configuration files,$(WORKDIR)/UIConfig/)
+$(call gb_Postprocess_Postprocess,AllModuleTests,All modules' tests,$(WORKDIR)/Module/check/)
+$(call gb_Postprocess_Postprocess,AllModuleSlowtests,All modules' slowtests,$(WORKDIR)/Module/slowcheck/)
+$(call gb_Postprocess_Postprocess,AllModuleScreenshots,All modules' screenshots,$(WORKDIR)/Module/screenshot/)
+$(call gb_Postprocess_Postprocess,AllModuleUITests,All modules' uitests,$(WORKDIR)/Module/uicheck/)
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/PrecompiledHeaders.mk b/solenv/gbuild/PrecompiledHeaders.mk
new file mode 100644
index 000000000..b6d3ecdfe
--- /dev/null
+++ b/solenv/gbuild/PrecompiledHeaders.mk
@@ -0,0 +1,184 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+
+# PrecompiledHeader class
+
+# Use different PCH file depending on whether we use debugging symbols.
+gb_PrecompiledHeader__get_debugdir = $(if $(call gb_target_symbols_enabled,$(1)),debug,nodebug)
+
+# $(call gb_PrecompiledHeader_generate_timestamp_rule,linktargetmakefilename)
+define gb_PrecompiledHeader_generate_timestamp_rule
+$(call gb_LinkTarget_get_pch_timestamp,$(1)) :
+ mkdir -p $$(dir $$@) && touch $$@
+
+endef
+
+ifneq ($(gb_ENABLE_PCH),)
+
+# IMPORTANT: Since these defines get expanded, every $ needs to be doubled to $$, except
+# for $(1)'s and things that are constant.
+# The defines are needed to get the right version of gb_PrecompiledHeader__get_debugdir.
+
+# all cxxflags to use for compilation
+gb_PrecompiledHeader_cxxflags_includes := $$(PCH_DEFS) $$(PCH_CXXFLAGS) $$(gb_PrecompiledHeader_EXCEPTIONFLAGS)
+# flags to save to the .flags file to check if they are the same as last time
+# (note: the leading space in sed is important, to remove the option and its separating space)
+gb_PrecompiledHeader_flags_for_flags_file := $$(sort $(gb_PrecompiledHeader_cxxflags_includes)) \
+ $(if $(gb_PrecompiledHeader_ignore_flags_for_flags_file),| sed 's/ $(gb_PrecompiledHeader_ignore_flags_for_flags_file)//')
+
+# $(call gb_PrecompiledHeader_generate_rules,pchtarget,linktarget,linktargetmakefilename,pchcxxfile,compiler)
+define gb_PrecompiledHeader_generate_rules
+
+$(call gb_PrecompiledHeader_get_dep_target,$(1),$(3)) :
+ $$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $$(dir $$@) && \
+ echo "$$(call gb_PrecompiledHeader_get_target,$(1),$(3)) : $$(gb_Helper_PHONY)" > $$@)
+
+# keep the flags the PCH was built with in a separate file, update the file if and only if the flags
+# change, and make the PCH depend on it => the PCH will be rebuilt on any flags change
+.PHONY: force
+$(call gb_PrecompiledHeader_get_flags_file,$(1),$(3)) : force
+ $$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $$(dir $$@) && \
+ echo $(gb_PrecompiledHeader_flags_for_flags_file) | cmp -s - $$@ \
+ || echo $(gb_PrecompiledHeader_flags_for_flags_file) > $$@)
+
+# despite this being only one .d file, need to run concat-deps on it to
+# re-write external headers from UnpackedTarball
+$(call gb_PrecompiledHeader_get_target,$(1),$(3)) :
+ test "$$(PCH_LINKTARGETMAKEFILENAME)" = "$(3)" \
+ || ( echo "Error, PCH $(1) built by $$(PCH_LINKTARGETMAKEFILENAME) instead of $(3)" >&2; exit 1)
+ rm -f $$@
+ $$(call gb_PrecompiledHeader__command,$$@,$(1),$$<,$(gb_PrecompiledHeader_cxxflags_includes),$$(INCLUDE),$(3),$(5))
+ $$(call gb_PrecompiledHeader__sum_command,$$@,$(1),$$<,$(gb_PrecompiledHeader_cxxflags_includes),$$(INCLUDE),$(3),$(5))
+ifeq ($(gb_FULLDEPS),$(true))
+ $$(call gb_Helper_abbreviate_dirs,\
+ RESPONSEFILE=$$(call gb_var2file,$$(shell $$(gb_MKTEMP)),200,$$(call gb_PrecompiledHeader_get_dep_target_tmp,$(1),$(3))) && \
+ $$(call gb_Executable_get_command,concat-deps) $$$${RESPONSEFILE} \
+ > $$(call gb_PrecompiledHeader_get_dep_target,$(1),$(3)) && \
+ rm -f $$$${RESPONSEFILE} $$(call gb_PrecompiledHeader_get_dep_target_tmp,$(1),$(3)))
+endif
+
+$(call gb_PrecompiledHeader_get_for_reuse_target,$(1),$(3)) : $(call gb_LinkTarget_get_target,$(2))
+ $$(call gb_PrecompiledHeader__create_reuse_files,$(2),$(1),$(3))
+ mkdir -p $$(dir $$@) && touch $$@
+
+.PHONY : $(call gb_PrecompiledHeader_get_clean_target,$(1))
+$(call gb_PrecompiledHeader_get_clean_target,$(1)) :
+ $$(call gb_Output_announce,$(1),$(false),PCH,1)
+ -$$(call gb_Helper_abbreviate_dirs,\
+ rm -f $$(call gb_PrecompiledHeader_get_target,$(1),$(3)) \
+ $$(call gb_PrecompiledHeader_get_target,$(1),$(3)).obj \
+ $$(call gb_PrecompiledHeader_get_target,$(1),$(3)).pdb \
+ $$(call gb_PrecompiledHeader_get_target,$(1),$(3)).sum \
+ $$(call gb_PrecompiledHeader_get_flags_file,$(1),$(3)) \
+ $$(call gb_PrecompiledHeader_get_for_reuse_target,$(1),$(3)) \
+ $$(call gb_PrecompiledHeader_get_dep_target,$(1),$(3)))
+
+endef
+
+# $(call gb_PrecompiledHeader_check_flags,linktargetmakefilename,pchcxxfile,pchfile,flags)
+# When creating a PCH, the PCH's CXXFLAGS are saved to a matching .flags file. When reusing the PCH
+# from another linktarget, use the file to check that the linktarget uses the same CXXFLAGS as the PCH.
+# This complements the check in gb_CxxObject__set_pchflags.
+define gb_PrecompiledHeader_check_flags
+$$(call gb_Helper_abbreviate_dirs,\
+ $$(if $$(strip $$(call gb_PrecompiledHeader_check_flags_internal,$$(shell cat $(4)),$(5),$(2))),false,true) || ( \
+ echo Error reusing $(2) by $(1). >&2 && \
+ echo -n " precompiled header flags : ">&2 && \
+ cat $(4) >&2 && \
+ echo " object flags : "$$(sort $(5)) >&2 && \
+ echo " reason : $$(call gb_PrecompiledHeader_check_flags_internal,$$(shell cat $(4)),$(5),$(2))" >&2 && \
+ echo Incorrect precompiled header setup or internal gbuild error. >&2 ; \
+ exit 1) \
+)
+
+endef
+
+# When trying to reuse one PCH between multiple linktargets, there is a problem that we have
+# various defines that cause mismatch in the check above, but these defines actually should not affect the PCH.
+# Specifically, there are 3 kinds:
+# - -DXXX_DLLIMPLEMENTATION - they are used only in our headers, should not affect system headers.
+# - -DSYSTEM_XXX - they are used only by our code (if at all), should not affect system headers
+# - various LO configuration defines - they again should only be used by our code and not system headers
+# Technically, different compilers handle additional defines like this:
+# - GCC
+# * It is explicitly allowed to have different macros, as long as they do not affect the PCH.
+# * With -Winvalid-pch GCC will even warn if there is a change in a macro affecting the PCH.
+# * https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html
+# - Clang
+# * I could not find an official statement on what happens if definitions are different.
+# * In practice a conflict does not seem to be detected, but the PCH and all the code in it
+# acts according to the settings it was built with. Using a PCH and adding more defines
+# seems to be functionally equivalent to creating the definitions only after the PCH inclusion.
+# * As a side-effect, macros defined on the command line not present in the PCH suddenly
+# trigger the -Wunused-macros warning. See bottom of pch/inc/clangfix.hxx .
+# - MSVC
+# * MSVC explicitly states that the definitions must be the same, but they are not checked,
+# and "unpredictable results can occur" if files depend on them.
+# * In practice the situation seems to be the same as with Clang, the PCH and the code from it
+# act according to the settings it was built with.
+# * https://docs.microsoft.com/en-us/cpp/build/creating-precompiled-header-files
+# So while this is officially tricky, in practice it seems to work to allow PCH reuse if the linktarget
+# has more defines than the PCH was built with, as long as the defines do not affect the PCH.
+gb_PrecompiledHeader_ignore_flags_system := \
+-DFASTSAX_DLLIMPLEMENTATION \
+-DSAX_DLLIMPLEMENTATION \
+-DSCQAHELPER_DLLIMPLEMENTATION \
+-DVCLPLUG_WIN_IMPLEMENTATION \
+-DVCLPLUG_GEN_IMPLEMENTATION \
+-DSYSTEM_EXPAT \
+-DSYSTEM_LIBXML \
+-DSYSTEM_ZLIB \
+-DSYSTEM_NSS \
+-DHAVE_VALGRIND_HEADERS \
+-DUSE_RANDR \
+-DUSE_XINERAMA_XORG \
+-DDISABLE_CVE_TESTS \
+-DCPPUNIT_PLUGIN_EXPORT='extern "C" SAL_DLLPUBLIC_EXPORT' \
+-DOOO_DLLIMPLEMENTATION_TEST \
+-DSK_USER_CONFIG_HEADER=% \
+-DSKIA_DLL \
+-DGLM_FORCE_CTOR_INIT \
+-DVCL_INTERNALS \
+-DZLIB_CONST \
+$(gb_CXXFLAGS_include)$(SRCDIR)/pch/inc/clangfix.hxx \
+$(gb_CXXFLAGS_no_pch_warnings) \
+$(gb_PrecompiledHeader_ignore_flags_for_flags_file) \
+
+# Probably also update pch/inc/clangfix.hxx if you extend the list.
+
+# $(call gb_PrecompiledHeader_check_flags_internal,pchfileflags,flags,pchcxxfile)
+# Check if two sets of flags are compatible, allowing reuse of the PCH. Flags are compatible if
+# - they are the same
+# - the PCH is precompiled_system and the linktarget has additional defines listed above
+define gb_PrecompiledHeader_check_flags_internal
+$(if $(filter-out $(2),$(1)),$(filter-out $(2),$(1)), \
+ $(if $(filter-out $(1),$(2)),\
+ $(if $(filter-out precompiled_system,$(notdir $(3))),$(filter-out $(1),$(2)), \
+ $(foreach flag,$(filter-out $(1),$(2)),$(filter-out $(gb_PrecompiledHeader_ignore_flags_system),$(flag))) \
+ ) \
+ ,) \
+)
+endef
+
+endif
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/PythonTest.mk b/solenv/gbuild/PythonTest.mk
new file mode 100644
index 000000000..4e81261d2
--- /dev/null
+++ b/solenv/gbuild/PythonTest.mk
@@ -0,0 +1,129 @@
+# -*- 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/.
+#
+
+# PythonTest class
+
+# (gb_PythonTest_GDBTRACE et al are defined alongside gb_CppunitTest_GDBTRACE in CppunitTest.mk)
+
+gb_PythonTest_UNITTESTFAILED ?= $(GBUILDDIR)/platform/unittest-failed-default.sh
+
+ifeq ($(SYSTEM_PYTHON),)
+gb_PythonTest_EXECUTABLE := $(gb_Python_INSTALLED_EXECUTABLE)
+gb_PythonTest_EXECUTABLE_GDB := $(gb_Python_INSTALLED_EXECUTABLE_GDB)
+gb_PythonTest_DEPS ?= $(call gb_Package_get_target,python3) $(call gb_Package_get_target,python_shell)
+else
+gb_PythonTest_EXECUTABLE := $(PYTHON_FOR_BUILD)
+gb_PythonTest_EXECUTABLE_GDB := $(PYTHON_FOR_BUILD)
+gb_PythonTest_DEPS :=
+endif
+
+gb_PythonTest_COMMAND := $(gb_PythonTest_EXECUTABLE) -m org.libreoffice.unittest
+
+.PHONY : $(call gb_PythonTest_get_clean_target,%)
+$(call gb_PythonTest_get_clean_target,%) :
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -fr $(WORKDIR)/PythonTest/$*)
+
+ifneq ($(DISABLE_PYTHON),TRUE)
+
+.PHONY : $(call gb_PythonTest_get_target,%)
+$(call gb_PythonTest_get_target,%) :\
+ $(call gb_Library_get_target,pyuno) \
+ $(if $(filter-out WNT,$(OS)),$(call gb_Library_get_target,pyuno_wrapper)) \
+ | $(gb_PythonTest_DEPS)
+ifneq ($(gb_SUPPRESS_TESTS),)
+ @true
+else
+ $(call gb_Output_announce,$*,$(true),PYT,2)
+ $(call gb_Trace_StartRange,$*,PYT)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf $(dir $(call gb_PythonTest_get_target,$*)) && \
+ mkdir -p $(dir $(call gb_PythonTest_get_target,$*))user/user/autotext && \
+ $(if $(gb_CppunitTest__interactive),, \
+ $(if $(value gb_CppunitTest_postprocess), \
+ rm -fr $@.core && mkdir $@.core && cd $@.core &&)) \
+ { \
+ $(if $(filter gdb,$(gb_PythonTest_GDBTRACE)),,$(gb_PythonTest_PRECOMMAND)) \
+ $(if $(G_SLICE),G_SLICE=$(G_SLICE)) \
+ $(if $(GLIBCXX_FORCE_NEW),GLIBCXX_FORCE_NEW=$(GLIBCXX_FORCE_NEW)) \
+ $(DEFS) \
+ TEST_LIB=$(call gb_Library_get_target,test) \
+ URE_BOOTSTRAP=vnd.sun.star.pathname:$(call gb_Helper_get_rcfile,$(INSTROOT)/$(LIBO_ETC_FOLDER)/fundamental) \
+ PYTHONPATH="$(PYPATH)" \
+ UserInstallation=$(call gb_Helper_make_url,$(dir $(call gb_PythonTest_get_target,$*))user) \
+ TestUserDir="$(call gb_Helper_make_url,$(dir $(call gb_PythonTest_get_target,$*)))" \
+ PYTHONDONTWRITEBYTECODE=1 \
+ $(gb_TEST_ENV_VARS) \
+ $(ICECREAM_RUN) $(gb_PythonTest_GDBTRACE) $(gb_CppunitTest_VALGRINDTOOL) $(gb_CppunitTest_RR) \
+ $(gb_PythonTest_COMMAND) \
+ $(if $(PYTHON_TEST_NAME),$(PYTHON_TEST_NAME),$(MODULES)) \
+ ; } \
+ $(if $(gb_CppunitTest__interactive),, \
+ > $@.log 2>&1 \
+ || ($(if $(value gb_CppunitTest_postprocess), \
+ RET=$$?; \
+ $(call gb_CppunitTest_postprocess,$(gb_PythonTest_EXECUTABLE_GDB),$@.core,$$RET) >> $@.log 2>&1;) \
+ cat $@.log; $(gb_PythonTest_UNITTESTFAILED) Python $*)))
+ $(call gb_Trace_EndRange,$*,PYT)
+endif
+
+# always use udkapi and URE services
+define gb_PythonTest_PythonTest
+$(call gb_PythonTest_get_target,$(1)) : PYPATH := $(SRCDIR)/unotest/source/python$$(gb_CLASSPATHSEP)$(INSTROOT)/$(LIBO_LIB_PYUNO_FOLDER)$(if $(filter-out $(LIBO_LIB_PYUNO_FOLDER),$(LIBO_LIB_FOLDER)),$(gb_CLASSPATHSEP)$(INSTROOT)/$(LIBO_LIB_FOLDER))
+$(call gb_PythonTest_get_target,$(1)) : MODULES :=
+
+$(eval $(call gb_Module_register_target,$(call gb_PythonTest_get_target,$(1)),$(call gb_PythonTest_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),PythonTest)
+
+endef
+
+define gb_PythonTest_set_defs
+$(call gb_PythonTest_get_target,$(1)) : DEFS := $(2)
+
+endef
+
+# put the directory on the PYTHONPATH because the "unittest" loader
+# mysteriously fails to load modules given as absolute path unless the $PWD is
+# a prefix of the absolute path, which it is not when we go into a certain
+# dir to get a core dump there
+#
+# gb_PythonTest_add_modules directory module(s)
+define gb_PythonTest_add_modules
+$(call gb_PythonTest_get_target,$(1)) : PYPATH := $$(PYPATH)$$(gb_CLASSPATHSEP)$(2)
+$(call gb_PythonTest_get_target,$(1)) : MODULES += $(3)
+
+endef
+
+define gb_PythonTest_use_customtarget
+$(call gb_PythonTest_get_target,$(1)) : $(call gb_CustomTarget_get_workdir,$(2))
+
+endef
+
+
+else # DISABLE_PYTHON
+
+.PHONY : $(call gb_PythonTest_get_target,$(1))
+$(call gb_PythonTest_get_target,%) :
+ifeq ($(gb_SUPPRESS_TESTS),)
+ $(call gb_Output_announce,$* (skipped - no PythonTest),$(true),PYT,2)
+endif
+ @true
+
+define gb_PythonTest_PythonTest
+$(eval $(call gb_Module_register_target,$(call gb_PythonTest_get_target,$(1)),$(call gb_PythonTest_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),PythonTest)
+
+endef
+
+gb_PythonTest_set_defs :=
+gb_PythonTest_add_modules :=
+gb_PythonTest_use_customtarget :=
+
+endif # DISABLE_PYTHON
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/Pyuno.mk b/solenv/gbuild/Pyuno.mk
new file mode 100644
index 000000000..3e5cb820f
--- /dev/null
+++ b/solenv/gbuild/Pyuno.mk
@@ -0,0 +1,79 @@
+# -*- 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/.
+#
+
+# class Pyuno
+#
+# Handles creation and delivery of Python UNO components.
+#
+# Provides one filelist, called Pyuno/<name>.
+
+$(dir $(call gb_Pyuno_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_Pyuno_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_Pyuno_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),PYU,3)
+ $(call gb_Trace_MakeMark,$*,PYU)
+ touch $@
+
+$(call gb_Pyuno_get_final_target,%) :
+ touch $@
+
+.PHONY : $(call gb_Pyuno_get_clean_target,%)
+$(call gb_Pyuno_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),PYU,3)
+ rm -f $(call gb_Pyuno_get_target,$*) $(call gb_Pyuno_get_final_target,$*)
+
+gb_Pyuno_get_packagename = Pyuno/$(1)
+
+# gb_Pyuno_Pyuno component
+define gb_Pyuno_Pyuno
+$(call gb_Package_Package_internal,$(call gb_Pyuno_get_packagename,$(1)),$(2))
+
+$(call gb_Pyuno_get_final_target,$(1)) : $(call gb_Pyuno_get_target,$(1))
+$(call gb_Pyuno_get_target,$(1)) : $(call gb_Package_get_target,$(call gb_Pyuno_get_packagename,$(1)))
+$(call gb_Pyuno_get_target,$(1)) :| $(dir $(call gb_Pyuno_get_target,$(1))).dir
+$(call gb_Pyuno_get_clean_target,$(1)) : $(call gb_Package_get_clean_target,$(call gb_Pyuno_get_packagename,$(1)))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_Pyuno_get_final_target,$(1)),$(call gb_Pyuno_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),Pyuno,$(call gb_Pyuno_get_final_target,$(1)))
+
+endef
+
+# gb_Pyuno_add_file component destination source
+define gb_Pyuno_add_file
+$(call gb_Package_add_file,$(call gb_Pyuno_get_packagename,$(1)),$(LIBO_LIB_PYUNO_FOLDER)/$(2),$(3))
+
+endef
+
+# gb_Pyuno_add_files component destdir source
+define gb_Pyuno_add_files
+$(foreach file,$(3),$(call gb_Pyuno_add_file,$(1),$(if $(strip $(2)),$(strip $(2))/)$(file),$(file)))
+
+endef
+
+gb_Pyuno__COMPONENTPREFIX := vnd.openoffice.pymodule:
+
+define gb_Pyuno_set_componentfile_full
+$(call gb_ComponentTarget_ComponentTarget,$(2),$(3),$(4),$(5))
+$(call gb_Pyuno_get_final_target,$(1)) : $(call gb_ComponentTarget_get_target,$(2))
+$(call gb_ComponentTarget_get_target,$(2)) : $(call gb_Pyuno_get_target,$(1))
+$(call gb_Pyuno_get_clean_target,$(1)) : $(call gb_ComponentTarget_get_clean_target,$(2))
+
+endef
+
+# Set .component file for the component.
+define gb_Pyuno_set_componentfile
+$(call gb_Pyuno_set_componentfile_full,$(1),$(2),$(gb_Pyuno__COMPONENTPREFIX),$(1),$(3))
+
+endef
+
+# vim:set shiftwidth=4 tabstop=4 noexpandtab:
diff --git a/solenv/gbuild/README b/solenv/gbuild/README
new file mode 100644
index 000000000..e99f96fa4
--- /dev/null
+++ b/solenv/gbuild/README
@@ -0,0 +1,17 @@
+
+GBuild is a set of makefile macros built on top of gmake that attempts to simplify LibreOffice development.
+
+See
+ https://wiki.documentfoundation.org/Development/Build_System
+for online build-system documentation.
+
+See
+ https://web.archive.org/web/20130911015536/http://wiki.openoffice.org/wiki/Build_Environment_Effort/Module_Migration
+for an archived overview of the new build system.
+
+See
+ ./solenv/doc/gbuild
+for a commented class/API hierarchy of gbuild written in C++ syntax. It was not
+intended for any use beyond to generate nicelooking docs with the doxygen
+doxygen documentation generator from it. It likely is quite outdated these
+days.
diff --git a/solenv/gbuild/Rdb.mk b/solenv/gbuild/Rdb.mk
new file mode 100644
index 000000000..45058888d
--- /dev/null
+++ b/solenv/gbuild/Rdb.mk
@@ -0,0 +1,75 @@
+# -*- 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/.
+#
+
+gb_Rdb__get_install_target = $(INSTROOT)/$(LIBO_ETC_FOLDER)/services/$(1).rdb
+
+define gb_Rdb__command
+$(call gb_Helper_abbreviate_dirs,\
+ RESPONSEFILE=$(call gb_var2file,$(shell $(call gb_MKTEMP)),70,\
+ <list> \
+ $(foreach component,$(COMPONENTS),\
+ <filename>$(call gb_ComponentTarget_get_target,$(component))</filename>) \
+ </list>) && \
+ mkdir -p $(dir $@) && \
+ $(call gb_ExternalExecutable_get_command,xsltproc) --nonet -o $(1) \
+ $(SRCDIR)/solenv/bin/packcomponents.xslt $$RESPONSEFILE && \
+ rm $$RESPONSEFILE)
+endef
+
+$(call gb_Rdb_get_target,%) :| $(call gb_ExternalExecutable_get_dependencies,xsltproc)
+ $(call gb_Output_announce,$*,$(true),RDB,1)
+ $(call gb_Trace_StartRange,$*,RDB)
+ $(call gb_Rdb__command,$@,$*,$?,$^)
+ $(call gb_Trace_EndRange,$*,RDB)
+
+.PHONY : $(call gb_Rdb_get_clean_target,%)
+$(call gb_Rdb_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),RDB,1)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_Rdb__get_install_target,$*) $(call gb_Rdb_get_target,$*))
+
+define gb_Rdb__Rdb_impl
+# gb_Rdb_add_component, which adds to the target-specific COMPONENTS variable, can be called (from
+# gb_ComponentTarget_ComponentTarget) before gb_Rdb__Rdb_impl is called, so using `COMPONENTS :=`
+# here could lose content; but still use `COMPONENTS ?=` here to establish COMPONENTS as target-
+# specific even in the corner case of an empty Rdb with no gb_Rdb_add_component calls, so that the
+# use of $(COMPONENTS) in gb_Rdb__command would not accidentally pick a global COMPONENTS variable:
+$(call gb_Rdb_get_target,$(1)) : COMPONENTS ?=
+$(call gb_Rdb_get_target,$(1)) : $(gb_Module_CURRENTMAKEFILE)
+$$(eval $$(call gb_Module_register_target,$(2),$(call gb_Rdb_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),Rdb,$(2))
+
+endef
+
+define gb_Rdb_Rdb
+$(call gb_Rdb__Rdb_impl,$(1),$(call gb_Rdb_get_target,$(1)))
+
+endef
+
+# FIXME this needs some layer-like thing for the special case in URE
+define gb_Rdb_Rdb_install
+$(call gb_Rdb__Rdb_impl,$(1),$(if $(2),$(INSTROOT)/$(2),$(call gb_Rdb__get_install_target,$(1))))
+$(call gb_Helper_install_final, \
+ $(if $(2),$(INSTROOT)/$(2),$(call gb_Rdb__get_install_target,$(1))), \
+ $(call gb_Rdb_get_target,$(1)))
+
+endef
+
+define gb_Rdb_add_component
+$(call gb_Rdb_get_target,$(1)) : $(call gb_ComponentTarget_get_target,$(2))
+$(call gb_Rdb_get_target,$(1)) : COMPONENTS += $(2)
+
+endef
+
+define gb_Rdb_add_components
+$(foreach component,$(2),$(call gb_Rdb_add_component,$(1),$(component)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/SdiTarget.mk b/solenv/gbuild/SdiTarget.mk
new file mode 100644
index 000000000..ed98bdbfa
--- /dev/null
+++ b/solenv/gbuild/SdiTarget.mk
@@ -0,0 +1,83 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# SdiTarget class
+gb_SdiTarget_SVIDLDEPS := $(call gb_Executable_get_runtime_dependencies,svidl)
+gb_SdiTarget_SVIDLCOMMAND := $(call gb_Executable_get_command,svidl)
+
+$(call gb_SdiTarget_get_target,%) : $(SRCDIR)/%.sdi $(gb_SdiTarget_SVIDLDEPS)
+ $(call gb_Output_announce,$*,$(true),SDI,1)
+ $(call gb_Trace_StartRange,$*,SDI)
+ $(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $@))
+ $(call gb_Helper_abbreviate_dirs,\
+ cd $(dir $<) && \
+ $(gb_SdiTarget_SVIDLCOMMAND) -quiet \
+ $(INCLUDE) \
+ -fs$@.hxx \
+ -fx$(EXPORTS) \
+ -fm$@ \
+ $(if $(gb_FULLDEPS),-fM$(call gb_SdiTarget_get_dep_target,$*)) \
+ $< \
+ && touch $@.hxx)
+ $(call gb_Trace_EndRange,$*,SDI)
+# touch the hxx file so it's newer than the target - the .hxx only occurs in
+# generated .d files, so it's not a target yet when building from scratch!
+
+# rule necessary to rebuild cxx files that include the header
+$(call gb_SdiTarget_get_target,%.hxx) : $(call gb_SdiTarget_get_target,%)
+ touch $@
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(dir $(call gb_SdiTarget_get_dep_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_SdiTarget_get_dep_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_SdiTarget_get_dep_target,%) :
+ $(if $(wildcard $@),touch $@)
+endif
+
+.PHONY : $(call gb_SdiTarget_get_clean_target,%)
+$(call gb_SdiTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),SDI,1)
+ -$(call gb_Helper_abbreviate_dirs,\
+ rm -f \
+ $(call gb_SdiTarget_get_target,$*).hxx \
+ $(call gb_SdiTarget_get_dep_target,$*) \
+ $(call gb_SdiTarget_get_target,$*))
+
+define gb_SdiTarget_SdiTarget
+$(call gb_SdiTarget_get_target,$(1)) : \
+ INCLUDE := -I$(SRCDIR)/include $(SOLARINC) -I$$(dir $(SRCDIR)/$(1))
+$(call gb_SdiTarget_get_target,$(1)) : EXPORTS := $(SRCDIR)/$(2).sdi
+ifeq ($(gb_FULLDEPS),$(true))
+-include $(call gb_SdiTarget_get_dep_target,$(1))
+$(call gb_SdiTarget_get_dep_target,$(1)) :| $(dir $(call gb_SdiTarget_get_dep_target,$(1))).dir
+endif
+$(call gb_Helper_make_userfriendly_targets,$(1),SdiTarget)
+endef
+
+define gb_SdiTarget_set_include
+$(call gb_SdiTarget_get_target,$(1)) : INCLUDE := $(2)
+
+endef
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/StaticLibrary.mk b/solenv/gbuild/StaticLibrary.mk
new file mode 100644
index 000000000..e310dc903
--- /dev/null
+++ b/solenv/gbuild/StaticLibrary.mk
@@ -0,0 +1,118 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+
+# Static Library class
+
+# defined globally in gbuild.mk
+# defined by platform
+# gb_StaticLibrary_get_filename
+# gb_StaticLibrary_PLAINEXT
+# gb_StaticLibrary_StaticLibrary_platform
+
+
+# EVIL: gb_StaticLibrary and gb_Library need the same deliver rule because they are indistinguishable on windows
+.PHONY : $(WORKDIR)/Clean/StaticLibrary/%
+$(WORKDIR)/Clean/StaticLibrary/% :
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(AUXTARGETS))
+
+define gb_StaticLibrary_StaticLibrary
+$(call gb_StaticLibrary__StaticLibrary_impl,$(1),$(call gb_StaticLibrary_get_linktarget,$(1)))
+
+endef
+
+# call gb_StaticLibrary__StaticLibrary_impl,staticlib,linktarget
+define gb_StaticLibrary__StaticLibrary_impl
+$(call gb_LinkTarget_LinkTarget,$(2),StaticLibrary_$(1),NONE)
+$(call gb_LinkTarget_set_targettype,$(2),StaticLibrary)
+$(call gb_StaticLibrary_get_clean_target,$(1)) : $(call gb_LinkTarget_get_clean_target,$(2))
+$(call gb_StaticLibrary_get_clean_target,$(1)) : AUXTARGETS :=
+$(call gb_StaticLibrary_StaticLibrary_platform,$(1),$(2))
+$$(eval $$(call gb_Module_register_target,$(call gb_StaticLibrary_get_target,$(1)),$(call gb_StaticLibrary_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),StaticLibrary)
+
+endef
+
+# forward the call to the gb_LinkTarget implementation
+# (note: because the function name is in $(1), the other args are shifted by 1)
+define gb_StaticLibrary__forward_to_Linktarget
+$(call gb_LinkTarget_$(subst gb_StaticLibrary_,,$(1)),$(call gb_StaticLibrary_get_linktarget,$(2)),$(3),$(4),StaticLibrary_$(2))
+
+endef
+
+# copy pasta for forwarding: this could be (and was) done more elegantly, but
+# these here can be found by both git grep and ctags
+gb_StaticLibrary_add_cobject = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_cobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_cxxobject = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_cxxobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_objcxxobject = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_objcxxobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_cxxclrobject = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_cxxclrobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_asmobject = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_asmobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_exception_objects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_x64_generated_exception_objects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_generated_cobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_x64_generated_cobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_generated_exception_objects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_generated_objcobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_generated_objcxxobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_generated_nasmobjects = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_cflags = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_cxxflags = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_objcflags = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_objcxxflags = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_nasmflags = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_cxxclrflags = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_defs = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_set_include = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_ldflags = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_set_ldflags = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_set_x64 = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_libs = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_set_library_path_flags = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_api = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_sdk_api = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_udk_api = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_internal_api = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_internal_bootstrap_api = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_internal_comprehensive_api = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_external = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_externals = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_custom_headers = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_package = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_packages = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_unpacked = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_external_project = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_static_libraries = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_add_sdi_headers = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_set_precompiled_header = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_reuse_precompiled_header = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_common_precompiled_header = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_set_warnings_not_errors = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_set_warnings_disabled = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_set_external_code = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_set_generated_cxx_suffix = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_use_clang = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+gb_StaticLibrary_set_clang_precompiled_header = $(call gb_StaticLibrary__forward_to_Linktarget,$(0),$(1),$(2),$(3))
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/TargetLocations.mk b/solenv/gbuild/TargetLocations.mk
new file mode 100644
index 000000000..32d7eed72
--- /dev/null
+++ b/solenv/gbuild/TargetLocations.mk
@@ -0,0 +1,487 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# outdir target pattern
+
+# these are hard-coded to URE for now since there are so few of them...
+gb_CliLibrary_get_target = $(INSTROOT)/$(LIBO_URE_LIB_FOLDER)/$(1)$(gb_CliLibrary_EXT)
+gb_CliNativeLibrary_get_target = $(INSTROOT)/$(LIBO_URE_LIB_FOLDER)/$(1)$(gb_CliNativeLibrary_EXT)
+gb_CliUnoApi_get_target = $(INSTROOT)/$(if $(filter cli_uretypes,$(1)),$(LIBO_URE_LIB_FOLDER),$(LIBO_LIB_FOLDER))/$(1)$(gb_CliUnoApi_EXT)
+gb_PackagePart_get_destinations = \
+ $(INSTDIR) \
+ $(WORKDIR)/unittest \
+
+# kind of lame but with just 3 of these why bother with registration etc.
+gb_UnoApi_get_target = $(INSTROOT)/$(if $(filter udkapi,$(1)),$(LIBO_URE_MISC_FOLDER)/types,$(LIBO_ETC_FOLDER)/types/$(1)).rdb
+gb_UnoApi_get_target_for_build = $(INSTROOT_FOR_BUILD)/$(if $(filter udkapi,$(1)),$(LIBO_URE_MISC_FOLDER_FOR_BUILD)/types,$(LIBO_ETC_FOLDER)/types/$(1)).rdb
+
+# workdir target patterns
+
+gb_AutoInstall_get_target = $(WORKDIR)/AutoInstall/$(1)
+gb_AllLangHelp_get_target = $(WORKDIR)/AllLangHelp/$(1)
+gb_AllLangHelp_get_helpfiles_target = $(WORKDIR)/AllLangHelp/$(1).helpfiles
+gb_AllLangPackage_get_target = $(WORKDIR)/AllLangPackage/$(1)
+gb_AllLangMoTarget_get_target = $(WORKDIR)/AllLangMo/$(1)
+gb_AsmObject_get_target = $(WORKDIR)/AsmObject/$(1).o
+gb_AsmObject_get_dwo_target = $(WORKDIR)/AsmObject/$(1).dwo
+gb_CObject_get_target = $(WORKDIR)/CObject/$(1).o
+gb_CObject_get_dwo_target = $(WORKDIR)/CObject/$(1).dwo
+gb_GenCObject_get_target = $(WORKDIR)/GenCObject/$(1).o
+gb_GenCObject_get_dwo_target = $(WORKDIR)/GenCObject/$(1).dwo
+gb_CliAssembly_get_target = $(WORKDIR)/CliAssembly/$(1).done
+gb_CliAssemblyTarget_get_target = $(WORKDIR)/CliAssemblyTarget/$(1).done
+gb_CliAssemblyTarget_get_assembly_target = $(WORKDIR)/CliAssemblyTarget/$(1)$(gb_CliAssemblyTarget_POLICYEXT)
+gb_CliConfigTarget_get_target = $(WORKDIR)/CliConfigTarget/$(1).config
+gb_CliNativeLibrary_get_preparation_target = $(WORKDIR)/CliNativeLibraryTarget/$(1).prepare
+gb_CompilerTest_get_target = $(WORKDIR)/CompilerTest/$(1)
+gb_ComponentTarget_get_target = $(WORKDIR)/ComponentTarget/$(1).component
+gb_ComponentTarget_get_target_for_build = $(WORKDIR_FOR_BUILD)/ComponentTarget/$(1).component
+gb_Configuration_get_preparation_target = $(WORKDIR)/Configuration/$(1).prepared
+gb_CppunitTest_get_target = $(WORKDIR)/CppunitTest/$(1).test
+gb_CustomPackage_get_target = $(WORKDIR)/CustomPackage/$(1).filelist
+gb_CustomTarget_get_repo_target = $(WORKDIR)/CustomTarget/$(2)_$(1).done
+gb_CustomTarget_get_target = $(WORKDIR)/CustomTarget/$(1).done
+gb_CustomTarget_get_workdir = $(WORKDIR)/CustomTarget/$(1)
+gb_DescriptionTranslateTarget_get_target = $(WORKDIR)/DescriptionTranslateTarget/$(1).xml
+gb_Dictionary_get_target = $(WORKDIR)/Dictionary/$(1).done
+gb_CxxObject_get_target = $(WORKDIR)/CxxObject/$(1).o
+gb_CxxObject_get_dwo_target = $(WORKDIR)/CxxObject/$(1).dwo
+gb_GenCxxObject_get_target = $(WORKDIR)/GenCxxObject/$(1).o
+gb_GenCxxObject_get_dwo_target = $(WORKDIR)/GenCxxObject/$(1).dwo
+gb_GenNasmObject_get_target = $(WORKDIR)/GenNasmObject/$(1).o
+gb_GenNasmObject_get_dwo_target = $(WORKDIR)/GenNasmObject/$(1).dwo
+gb_Executable_get_headers_target = $(WORKDIR)/Headers/Executable/$(1)
+gb_Executable_get_linktargetfile = $(call gb_LinkTarget_get_target,$(call gb_Executable_get_linktarget,$1))
+gb_Executable_get_runtime_target = $(WORKDIR_FOR_BUILD)/Executable/$(1).run
+gb_Extension_get_target = $(WORKDIR)/Extension/$(1).oxt
+gb_Extension_get_rootdir = $(WORKDIR)/Extension/$(1)/root
+gb_Extension_get_workdir = $(WORKDIR)/Extension/$(1)
+gb_ExtensionPackage_get_target = $(WORKDIR)/ExtensionPackage/$(1).filelist
+gb_ExtensionPackage_get_preparation_target = $(WORKDIR)/ExtensionPackage/$(1).prepare
+gb_ExtensionPackageSet_get_target = $(WORKDIR)/ExtensionPackage/$(1).set
+gb_ExternalPackage_get_target = $(WORKDIR)/ExternalPackage/$(1)
+gb_ExternalProject_get_statedir = $(WORKDIR)/ExternalProject/$(1)
+gb_ExternalProject_get_preparation_target = $(WORKDIR)/ExternalProject/$(1).prepare
+gb_ExternalProject_get_state_target = $(WORKDIR)/ExternalProject/$(1)/$(2)
+gb_ExternalProject_get_target = $(WORKDIR)/ExternalProject/$(1).done
+gb_ExternalProject_get_target_for_build = $(WORKDIR_FOR_BUILD)/ExternalProject/$(1).done
+gb_Gallery_get_target = $(WORKDIR)/Gallery/$(1).done
+gb_Gallery_get_workdir = $(WORKDIR)/Gallery/$(1)
+gb_GeneratedPackage_get_target = $(WORKDIR)/GeneratedPackage/$(1).filelist
+gb_GeneratedPackage_get_target_for_build = $(WORKDIR_FOR_BUILD)/GeneratedPackage/$(1).filelist
+gb_HelpIndexTarget_get_target = $(WORKDIR)/HelpIndexTarget/$(1).done
+gb_HelpJarTarget_get_target = $(WORKDIR)/HelpJarTarget/$(1).done
+gb_HelpLinkTarget_get_preparation_target = $(WORKDIR)/HelpLinkTarget/$(1).prepare
+gb_HelpLinkTarget_get_target = $(WORKDIR)/HelpLinkTarget/$(1).done
+gb_HelpTarget_get_filelist = $(WORKDIR)/HelpTarget/$(1).filelist
+gb_HelpTarget_get_linked_target = $(WORKDIR)/HelpTarget/$(1).translate
+gb_HelpTarget_get_target = $(WORKDIR)/HelpTarget/$(1).zip
+gb_HelpTarget_get_translation_target = $(call gb_HelpTarget_get_filelist,$(1))
+gb_HelpTarget_get_workdir = $(WORKDIR)/HelpTarget/$(1)
+gb_HelpTranslatePartTarget_get_target = $(WORKDIR)/HelpTranslatePartTarget/$(1)/done
+gb_HelpTranslatePartTarget_get_translated_target = $(WORKDIR)/HelpTranslatePartTarget/$(1)/$(2).xhp
+gb_HelpTranslatePartTarget_get_workdir = $(WORKDIR)/HelpTranslatePartTarget/$(1)
+gb_HelpTranslateTarget_get_target = $(WORKDIR)/HelpTranslateTarget/$(1).done
+gb_HelpTreeTarget_get_target = $(WORKDIR)/HelpTreeTarget/$(1).tree
+gb_InstallModule_get_filelist = $(call gb_InstallModuleTarget_get_filelist,$(1))
+gb_InstallModule_get_target = $(WORKDIR)/InstallModule/$(1).done
+gb_InstallModuleTarget_get_external_target = $(WORKDIR)/InstallModuleTarget/$(1).external
+gb_InstallModuleTarget_get_filelist = $(WORKDIR)/InstallModuleTarget/$(1).filelist
+gb_InstallModuleTarget_get_target = $(WORKDIR)/InstallModuleTarget/$(1).filelist
+gb_InstallScript_get_target = $(WORKDIR)/InstallScriptTarget/$(1)$(gb_InstallScript_EXT)
+gb_InternalUnoApi_get_target = $(WORKDIR)/InternalUnoApi/$(1).done
+gb_Jar_get_target = $(call gb_Jar_get_install_target,$(1))
+gb_Jar_get_classsetname = Jar/$(1)
+gb_JavaClassSet_get_classdir = $(WORKDIR)/JavaClassSet/$(1)
+gb_JavaClassSet_get_repo_target = $(WORKDIR)/JavaClassSet/$(2)/$(1).done
+gb_JavaClassSet_get_target = $(WORKDIR)/JavaClassSet/$(1)/done
+gb_JunitTest_get_classsetname = JunitTest/$(1)
+gb_JunitTest_get_target = $(WORKDIR)/JunitTest/$(1)/done
+gb_JunitTest_get_userdir = $(WORKDIR)/JunitTest/$(1)/user
+gb_PythonTest_get_target = $(WORKDIR)/PythonTest/$(1)/done
+# linktarget = class/object<>some_optional_target, like Library/libswlo.so<>/.../instdir/program/libswlo.so
+# while the target is optional, the workdir functions will always work correctly
+gb_LinkTarget__get_workdir_linktargetname = $(firstword $(subst <>, ,$(1)))
+gb_LinkTarget__get_workdir_linktargetclass = $(firstword $(subst /, ,$(call gb_LinkTarget__get_workdir_linktargetname,$(1))))
+gb_LinkTarget__get_workdir_linktargetobject = $(lastword $(subst /, ,$(call gb_LinkTarget__get_workdir_linktargetname,$(1))))
+gb_LinkTarget_get_headers_target = \
+ $(WORKDIR)/Headers/$(call gb_LinkTarget__get_workdir_linktargetname,$(1))
+gb_LinkTarget_get_objects_list = \
+ $(WORKDIR)/LinkTarget/$(call gb_LinkTarget__get_workdir_linktargetname,$(1)).objectlist
+gb_LinkTarget_get_dep_target = \
+ $(WORKDIR)/Dep/LinkTarget/$(call gb_LinkTarget__get_workdir_linktargetname,$(1)).d
+gb_LinkTarget_get_dep_libraries_target = \
+ $(WORKDIR)/Dep/LinkTarget/$(call gb_LinkTarget__get_workdir_linktargetname,$(1)).d.libraries
+gb_LinkTarget_get_dep_externals_target = \
+ $(WORKDIR)/Dep/LinkTarget/$(call gb_LinkTarget__get_workdir_linktargetname,$(1)).d.externals
+gb_LinkTarget_get_dep_statics_target = \
+ $(WORKDIR)/Dep/LinkTarget/$(call gb_LinkTarget__get_workdir_linktargetname,$(1)).d.statics
+gb_LinkTarget_get_clean_target = \
+ $(WORKDIR)/Clean/LinkTarget/$(call gb_LinkTarget__get_workdir_linktargetname,$(1))
+gb_LinkTarget_get_target = $(lastword $(subst <>, ,$(1)))
+gb_LinkTarget_get_pch_timestamp = $(WORKDIR)/PrecompiledHeader/$(call gb_PrecompiledHeader__get_debugdir,$(1))/Timestamps/$(1)
+gb_LinkTarget_get_pch_reuse_timestamp = $(WORKDIR)/PrecompiledHeader/$(call gb_PrecompiledHeader__get_debugdir,$(1))/Timestamps/$(1)_reuse
+gb_Module_get_nonl10n_target = $(WORKDIR)/Module/nonl10n/$(1)
+gb_Module_get_l10n_target = $(WORKDIR)/Module/l10n/$(1)
+gb_Module_get_check_target = $(WORKDIR)/Module/check/$(1)
+gb_Module_get_slowcheck_target = $(WORKDIR)/Module/slowcheck/$(1)
+gb_Module_get_screenshot_target = $(WORKDIR)/Module/screenshot/$(1)
+gb_Module_get_subsequentcheck_target = $(WORKDIR)/Module/subsequentcheck/$(1)
+gb_Module_get_perfcheck_target = $(WORKDIR)/Module/perfcheck/$(1)
+gb_Module_get_uicheck_target = $(WORKDIR)/Module/uicheck/$(1)
+gb_Module_get_target = $(WORKDIR)/Module/$(1)
+gb_ObjCxxObject_get_target = $(WORKDIR)/ObjCxxObject/$(1).o
+gb_ObjCxxObject_get_dwo_target = $(WORKDIR)/ObjCxxObject/$(1).dwo
+gb_ObjCObject_get_target = $(WORKDIR)/ObjCObject/$(1).o
+gb_ObjCObject_get_dwo_target = $(WORKDIR)/ObjCObject/$(1).dwo
+gb_GenObjCxxObject_get_target = $(WORKDIR)/GenObjCxxObject/$(1).o
+gb_GenObjCxxObject_get_dwo_target = $(WORKDIR)/GenObjCxxObject/$(1).dwo
+gb_GenObjCObject_get_target = $(WORKDIR)/GenObjCObject/$(1).o
+gb_GenObjCObject_get_dwo_target = $(WORKDIR)/GenObjCObject/$(1).dwo
+gb_CxxClrObject_get_target = $(WORKDIR)/CxxClrObject/$(1).o
+gb_CxxClrObject_get_dwo_target = $(WORKDIR)/CxxClrObject/$(1).dwo
+gb_GenCxxClrObject_get_target = $(WORKDIR)/GenCxxClrObject/$(1).o
+gb_GenCxxClrObject_get_dwo_target = $(WORKDIR)/GenCxxClrObject/$(1).dwo
+gb_Pagein_get_target = $(WORKDIR)/Pagein/pagein-$(1)
+gb_Package_get_preparation_target = $(WORKDIR)/Package/prepared/$(1)
+gb_Package_get_target = $(WORKDIR)/Package/$(1).filelist
+gb_Package_get_target_for_build = $(WORKDIR_FOR_BUILD)/Package/$(1).filelist
+gb_PackageSet_get_target = $(WORKDIR)/PackageSet/$(1).filelist
+gb_PackageInfo_get_target = $(WORKDIR)/PackageInfo
+gb_Postprocess_get_target = $(WORKDIR)/Postprocess/$(1)
+gb_PrecompiledHeader_get_dep_target = $(WORKDIR)/Dep/PrecompiledHeader/$(call gb_PrecompiledHeader__get_debugdir,$(2))/$(1).hxx$(gb_PrecompiledHeader_EXT).d
+gb_PrecompiledHeader_get_dep_target_tmp = $(call gb_PrecompiledHeader_get_dep_target,$(1),$(2)).tmp
+gb_PrecompiledHeader_get_flags_file = $(WORKDIR)/PrecompiledHeader/$(call gb_PrecompiledHeader__get_debugdir,$(2))/$(1).hxx$(gb_PrecompiledHeader_EXT).flags
+gb_PrecompiledHeader_get_for_reuse_target = $(WORKDIR)/PrecompiledHeader/$(call gb_PrecompiledHeader__get_debugdir,$(2))/$(1).hxx$(gb_PrecompiledHeader_EXT).reuse
+gb_PrecompiledHeader_get_target = $(WORKDIR)/PrecompiledHeader/$(call gb_PrecompiledHeader__get_debugdir,$(2))/$(1).hxx$(gb_PrecompiledHeader_EXT)
+gb_PropertiesTranslateTarget_get_target = $(WORKDIR)/PropertiesTranslateTarget/$(1).properties
+gb_Pyuno_get_final_target = $(WORKDIR)/Pyuno/$(1).final
+gb_Pyuno_get_target = $(WORKDIR)/Pyuno/$(1).done
+gb_Rdb_get_target = $(WORKDIR)/Rdb/$(1).rdb
+gb_Rdb_get_target_for_build = $(WORKDIR_FOR_BUILD)/Rdb/$(1).rdb
+gb_ResTarget_get_target = $(WORKDIR)/ResTarget/$(1).res
+gb_MoTarget_get_target = $(WORKDIR)/MoTarget/$(1).mo
+gb_ScpMergeTarget_get_target = $(WORKDIR)/ScpMergeTarget/$(1).ulf
+gb_ScpPreprocessTarget_get_target = $(WORKDIR)/ScpPreprocessTarget/$(1).pre
+gb_ScpTarget_get_external_target = $(WORKDIR)/ScpTarget/$(1).external
+gb_ScpTarget_get_target = $(WORKDIR)/ScpTarget/$(1).par
+gb_ScpTemplateTarget_get_dir = $(abspath $(WORKDIR)/ScpTemplateTarget/$(dir $(1)))
+gb_ScpTemplateTarget_get_target = $(abspath $(WORKDIR)/ScpTemplateTarget/$(dir $(1))$(subst pack,modules,$(subst module_,all,$(notdir $(1)))).inc)
+gb_SdiTarget_get_target = $(WORKDIR)/SdiTarget/$(1)
+gb_ThesaurusIndexTarget_get_target = $(WORKDIR)/ThesaurusIndexTarget/$(basename $(1)).idx
+gb_UIConfig_get_imagelist_target = $(WORKDIR)/UIConfig/$(1).ilst
+gb_UIConfig_get_a11yerrors_target = $(WORKDIR)/UIConfig/$(1).a11yerrors
+gb_UIConfig_get_target = $(WORKDIR)/UIConfig/$(1).done
+gb_UIImageListTarget_get_target = $(WORKDIR)/UIImageListTarget/$(1).ilst
+gb_UIMenubarTarget_get_target = $(WORKDIR)/UIMenubarTarget/$(1).xml
+gb_UITest_get_target = $(WORKDIR)/UITest/$(1)/done
+gb_UnoApiTarget_get_target = $(WORKDIR)/UnoApiTarget/$(1).rdb
+gb_UnoApiHeadersTarget_get_bootstrap_dir = $(WORKDIR)/UnoApiHeadersTarget/$(1)/$(call gb_UnoApiHeadersTarget_select_variant,$(1),bootstrap)
+gb_UnoApiHeadersTarget_get_comprehensive_dir = $(WORKDIR)/UnoApiHeadersTarget/$(1)/$(call gb_UnoApiHeadersTarget_select_variant,$(1),comprehensive)
+gb_UnoApiHeadersTarget_get_dir = $(WORKDIR)/UnoApiHeadersTarget/$(1)/$(call gb_UnoApiHeadersTarget_select_variant,$(1),normal)
+gb_UnoApiHeadersTarget_get_real_bootstrap_dir = $(WORKDIR)/UnoApiHeadersTarget/$(1)/bootstrap
+gb_UnoApiHeadersTarget_get_real_comprehensive_dir = $(WORKDIR)/UnoApiHeadersTarget/$(1)/comprehensive
+gb_UnoApiHeadersTarget_get_real_dir = $(WORKDIR)/UnoApiHeadersTarget/$(1)/normal
+gb_UnoApiHeadersTarget_get_real_bootstrap_target = $(WORKDIR)/UnoApiHeadersTarget/$(1)/bootstrap.done
+gb_UnoApiHeadersTarget_get_real_comprehensive_target = $(WORKDIR)/UnoApiHeadersTarget/$(1)/comprehensive.done
+gb_UnoApiHeadersTarget_get_real_target = $(WORKDIR)/UnoApiHeadersTarget/$(1)/normal.done
+gb_UnoApiHeadersTarget_get_bootstrap_target = $(WORKDIR)/UnoApiHeadersTarget/$(1)/$(call gb_UnoApiHeadersTarget_select_variant,$(1),bootstrap).done
+gb_UnoApiHeadersTarget_get_comprehensive_target = $(WORKDIR)/UnoApiHeadersTarget/$(1)/$(call gb_UnoApiHeadersTarget_select_variant,$(1),comprehensive).done
+gb_UnoApiHeadersTarget_get_target = $(WORKDIR)/UnoApiHeadersTarget/$(1)/$(call gb_UnoApiHeadersTarget_select_variant,$(1),normal).done
+gb_UnpackedTarball_get_dir = $(WORKDIR)/UnpackedTarball/$(1)
+gb_UnpackedTarball_get_pristine_dir = $(WORKDIR)/UnpackedTarball/$(1).org
+gb_UnpackedTarball_get_final_target = $(WORKDIR)/UnpackedTarball/$(1).update
+# NOTE: the .done target is hardcoded in solenv/bin/concat-deps.c !
+gb_UnpackedTarball_get_target = $(WORKDIR)/UnpackedTarball/$(1).done
+gb_UnpackedTarball_get_preparation_target = $(WORKDIR)/UnpackedTarball/$(1).prepare
+gb_UnpackedTarget_get_target = $(WORKDIR)/UnpackedTarget/$(1)
+gb_WinResTarget_get_target = $(WORKDIR)/WinResTarget/$(1)$(gb_WinResTarget_POSTFIX)
+# workdir targets: $(1) is prefix/path
+gb_Configuration_get_target = $(WORKDIR)/Configuration/$(1).done
+gb_YaccTarget_get_grammar_target = $(WORKDIR)/YaccTarget/$(1).cxx
+gb_YaccTarget_get_header_target = $(WORKDIR)/YaccTarget/$(1).hxx
+gb_YaccTarget_get_target = $(WORKDIR)/YaccTarget/$(1).done
+
+gb_LexTarget_get_scanner_target = $(WORKDIR)/LexTarget/$(1).cxx
+gb_LexTarget_get_target = $(WORKDIR)/LexTarget/$(1).done
+
+gb_XcdTarget_get_target = $(WORKDIR)/XcdTarget/$(1)
+gb_XcsTarget_get_target = $(WORKDIR)/XcsTarget$(if $(1),/)$(1)
+gb_XcuDataTarget_get_target = $(WORKDIR)/XcuDataTarget/$(1)
+gb_XcuFilterFiltersTarget_get_target = $(WORKDIR)/XcuFilterFiltersTarget/$(1)
+gb_XcuFilterInternalTarget_get_target = $(WORKDIR)/XcuFilterInternalTarget/$(1)
+gb_XcuFilterOthersTarget_get_target = $(WORKDIR)/XcuFilterOthersTarget/$(1)
+gb_XcuFilterTypesTarget_get_target = $(WORKDIR)/XcuFilterTypesTarget/$(1)
+gb_XcuLangpackTarget_get_target = $(WORKDIR)/XcuLangpackTarget/$(1)
+gb_XcuModuleTarget_get_target = $(WORKDIR)/XcuModuleTarget/$(1)
+gb_XcuMergeTarget_get_target = $(WORKDIR)/XcuMergeTarget/$(1)
+gb_XcuResTarget_get_target = $(WORKDIR)/XcuResTarget/$(1)
+gb_Zip_get_target = $(WORKDIR)/Zip/$(1).zip
+
+define gb_Library_get_exports_target
+$(WORKDIR)/LinkTarget/$(call gb_Library__get_workdir_linktargetname,$(1)).exports
+endef
+
+define gb_Library_get_versionlink_target
+$(call gb_Library_get_sdk_link_dir)/$(basename $(call gb_Library_get_filename,$(1)))
+endef
+
+define gb_Library_get_headers_target
+$(patsubst $(1):%,$(WORKDIR)/Headers/Library/%,$(filter $(1):%,$(gb_Library_FILENAMES)))
+endef
+
+define gb_StaticLibrary_get_headers_target
+$(WORKDIR)/Headers/StaticLibrary/$(call gb_StaticLibrary_get_filename,$(1))
+endef
+
+$(eval $(call gb_Helper_make_clean_targets,\
+ AutoInstall \
+ AllLangHelp \
+ AllLangPackage \
+ AllLangMoTarget \
+ CliAssembly \
+ CliAssemblyTarget \
+ CliConfigTarget \
+ CliLibrary \
+ CliNativeLibrary \
+ CliUnoApi \
+ CompilerTest \
+ ComponentTarget \
+ CustomPackage \
+ DescriptionTranslateTarget \
+ Dictionary \
+ Executable \
+ ExternalPackage \
+ Extension \
+ ExtensionPackage \
+ ExtensionPackageSet \
+ Gallery \
+ GeneratedPackage \
+ HelpTarget \
+ HelpIndexTarget \
+ HelpJarTarget \
+ HelpLinkTarget \
+ HelpTranslatePartTarget \
+ HelpTranslateTarget \
+ HelpTreeTarget \
+ InstallModule \
+ InstallModuleTarget \
+ InstallScript \
+ InternalUnoApi \
+ JavaClassSet \
+ Jar \
+ JunitTest \
+ Library \
+ Module \
+ PackagePart \
+ Package \
+ PackageSet \
+ Pagein \
+ Postprocess \
+ PrecompiledHeader \
+ PropertiesTranslateTarget \
+ Pyuno \
+ PythonTest \
+ Rdb \
+ ResTarget \
+ ScpMergeTarget \
+ ScpPreprocessTarget \
+ ScpTarget \
+ ScpTemplateTarget \
+ SdiTarget \
+ StaticLibrary \
+ ThesaurusIndexTarget \
+ CppunitTest \
+ CppunitTestFakeExecutable \
+ CustomTarget \
+ ExternalProject \
+ UIConfig \
+ UIImageListTarget \
+ UIMenubarTarget \
+ UITest \
+ UnoApi \
+ UnoApiHeadersTarget \
+ UnoApiTarget \
+ UnpackedTarball \
+ UnpackedTarget \
+ WinResTarget \
+ YaccTarget \
+ LexTarget \
+ Zip \
+ XcsTarget \
+ XcuDataTarget \
+ XcuModuleTarget \
+ XcuLangpackTarget \
+ XcuMergeTarget \
+ XcuResTarget \
+ Configuration \
+))
+
+$(eval $(call gb_Helper_make_dep_targets,\
+ CObject \
+ CxxObject \
+ ObjCObject \
+ ObjCxxObject \
+ CxxClrObject \
+ AsmObject \
+ GenCObject \
+ GenCxxObject \
+ GenObjCObject \
+ GenObjCxxObject \
+ GenNasmObject \
+ GenCxxClrObject \
+ SdiTarget \
+))
+
+# other getters
+
+define gb_Library_get_layer
+$(patsubst $(1):%,%,$(filter $(1):%,$(gb_Library_LAYER)))
+endef
+
+define gb_Executable_get_layer
+$(patsubst $(1):%,%,$(filter $(1):%,$(gb_Executable_LAYER)))
+endef
+
+define gb_Library_get_filename
+$(patsubst $(1):%,%,$(filter $(1):%,$(gb_Library_FILENAMES)))
+endef
+
+define gb_Library_get_filename_for_build
+$(patsubst $(1):%,%,$(filter $(1):%,$(gb_Library_FILENAMES_FOR_BUILD)))
+endef
+
+define gb_Executable_get_filename
+$(patsubst $(1):%,%,$(filter $(1):%,$(gb_Executable_FILENAMES)))
+endef
+
+define gb_Executable_get_filename_for_build
+$(patsubst $(1):%,%,$(filter $(1):%,$(gb_Executable_FILENAMES_FOR_BUILD)))
+endef
+
+# Get dependencies needed for running the executable
+#
+# This is not strictly necessary, but it makes the use more similar to
+# ExternalExecutable.
+#
+# gb_Executable_get_runtime_dependencies executable
+define gb_Executable_get_runtime_dependencies
+$(call gb_Executable_get_runtime_target,$(1))
+endef
+
+# Get complete command-line for running the executable
+#
+# This includes setting library path.
+#
+# gb_Executable_get_command executable
+define gb_Executable_get_command
+$(gb_Helper_set_ld_path) $(BUILDTOOLTRACE) $(2) $(call gb_Executable_get_target_for_build,$(1))
+endef
+
+define gb_Executable__get_workdir_linktargetname
+Executable/$(call gb_Executable_get_filename,$(1))
+endef
+define gb_Executable_get_target
+$(call gb_Executable__get_dir_for_exe,$(1))/$(call gb_Executable_get_filename,$(1))
+endef
+ifneq ($(CROSS_COMPILING),)
+# Can we assume this is used only for executables registered for "NONE"?
+define gb_Executable_get_target_for_build
+$(call gb_Executable__get_dir_for_exe_for_build,$(1))/$(call gb_Executable_get_filename_for_build,$(1))
+endef
+else
+gb_Executable_get_target_for_build = $(gb_Executable_get_target)
+endif # CROSS_COMPILING
+define gb_Executable_get_linktarget
+$(call gb_Executable__get_workdir_linktargetname,$(1))<>$(call gb_Executable_get_target,$(1))
+endef
+gb_Executable_get_linktarget_target = $(call gb_LinkTarget_get_target,$(call gb_Executable_get_linktarget,$(1)))
+
+gb_ExternalProject__get_workdir_linktargetname = ExternalProject/$(1)
+
+define gb_Library__get_workdir_linktargetname
+Library/$(call gb_Library_get_filename,$(1))
+endef
+define gb_Library_get_target
+$(call gb_Library_get_instdir,$(1))/$(call gb_Library_get_runtime_filename,$(1))
+endef
+ifneq ($(CROSS_COMPILING),)
+define gb_Library_get_target_for_build
+$(call gb_Library_get_instdir_for_build,$(1))/$(call gb_Library_get_runtime_filename_for_build,$(1))
+endef
+else
+gb_Library_get_target_for_build = $(gb_Library_get_target)
+endif # CROSS_COMPILING
+# this returns a tuple of both the linktargetname, and the target file
+define gb_Library_get_linktarget
+$(call gb_Library__get_workdir_linktargetname,$(1))<>$(call gb_Library_get_target,$(1))
+endef
+gb_Library_get_linktarget_target = $(call gb_LinkTarget_get_target,$(call gb_Library_get_linktarget,$(1)))
+gb_Library_get_dep_libraries_target = $(call gb_LinkTarget_get_dep_libraries_target,$(call gb_Library_get_linktarget,$(1)))
+
+define gb_StaticLibrary__get_workdir_linktargetname
+StaticLibrary/$(call gb_StaticLibrary_get_filename,$(1))
+endef
+define gb_StaticLibrary_get_target
+$(WORKDIR)/LinkTarget/$(call gb_StaticLibrary__get_workdir_linktargetname,$(1))
+endef
+# this returns a tuple of both the linktargetname, and the target file
+define gb_StaticLibrary_get_linktarget
+$(call gb_StaticLibrary__get_workdir_linktargetname,$(1))<>$(call gb_StaticLibrary_get_target,$(1))
+endef
+gb_StaticLibrary_get_linktarget_target = $(call gb_LinkTarget_get_target,$(call gb_StaticLibrary_get_linktarget,$(1)))
+
+define gb_CppunitTest__get_workdir_linktargetname
+CppunitTest/$(call gb_CppunitTest_get_filename,$(1))
+endef
+define gb_CppunitTest__get_linktarget_target
+$(WORKDIR)/LinkTarget/$(call gb_CppunitTest__get_workdir_linktargetname,$(1))
+endef
+# this returns a tuple of both the linktargetname, and the target file
+define gb_CppunitTest_get_linktarget
+$(call gb_CppunitTest__get_workdir_linktargetname,$(1))<>$(call gb_CppunitTest__get_linktarget_target,$(1))
+endef
+gb_CppunitTest_get_linktarget_target = $(call gb_LinkTarget_get_target,$(call gb_CppunitTest_get_linktarget,$(1)))
+
+define gb_CompilerTest__get_workdir_linktargetname
+CompilerTest/$(1)
+endef
+define gb_CompilerTest__get_linktarget_target
+$(WORKDIR)/LinkTarget/$(call gb_CompilerTest__get_workdir_linktargetname,$(1))
+endef
+# this returns a tuple of both the linktargetname, and the target file
+define gb_CompilerTest_get_linktarget
+$(call gb_CompilerTest__get_workdir_linktargetname,$(1))<>$(call gb_CompilerTest__get_linktarget_target,$(1))
+endef
+
+# static members declared here because they are used globally
+
+gb_StaticLibrary_WORKDIR = $(WORKDIR)/LinkTarget/StaticLibrary
+gb_Library_WORKDIR_FOR_BUILD = $(WORKDIR_FOR_BUILD)/LinkTarget/Library
+gb_Executable_BINDIR = $(WORKDIR)/LinkTarget/Executable
+gb_Executable_BINDIR_FOR_BUILD = $(WORKDIR_FOR_BUILD)/LinkTarget/Executable
+gb_Library_DLLDIR = $(WORKDIR)/LinkTarget/Library
+gb_Library_DLLDIR_FOR_BUILD = $(WORKDIR_FOR_BUILD)/LinkTarget/Library
+gb_CppunitTest_DLLDIR = $(WORKDIR)/LinkTarget/CppunitTest
+
+# static variables declared here because they are used globally
+
+gb_POLOCATION := $(SRCDIR)/translations/source
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/Tempfile.mk b/solenv/gbuild/Tempfile.mk
new file mode 100644
index 000000000..ee0593db8
--- /dev/null
+++ b/solenv/gbuild/Tempfile.mk
@@ -0,0 +1,45 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+ifneq ($(HAVE_GNUMAKE_FILE_FUNC),)
+define gb_var2file
+$(file >$(1),$(3))$(1)
+endef
+else
+# Write string to temporary file by chopping into pieces that
+# fit the commandline
+# parameters: filename, maxitems (for one write), string
+# returns: filename
+define gb_var2file
+$(strip $(1)
+$(eval gb_var2file_helpervar := $$(shell printf "%s" "" > $(1) ))\
+$(eval gb_var2file_curblock := $(firstword $(3)))\
+$(foreach item,$(wordlist 2,99999,$(3)),$(eval gb_var2file_curblock += $(item)
+ ifeq ($$(words $$(gb_var2file_curblock)),$(2))
+ gb_var2file_helpervar := $$(shell printf "%s" "$$(gb_var2file_curblock)" >> $(1) )
+ gb_var2file_curblock :=
+ endif
+ ))\
+ $(eval gb_var2file_helpervar := $(shell printf "%s\n" "$(gb_var2file_curblock)" >> $(1) )
+ gb_var2file_curblock :=
+ ))
+endef
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/TestHelpers.mk b/solenv/gbuild/TestHelpers.mk
new file mode 100644
index 000000000..2ce814ecd
--- /dev/null
+++ b/solenv/gbuild/TestHelpers.mk
@@ -0,0 +1,47 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# 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/.
+#
+
+# This makes sure that more_fonts, opensymbol and fontconfig is installed
+define gb_TestHelpers_use_more_fonts
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq (,$$(filter MORE_FONTS,$$(BUILD_TYPE)))
+ifeq (,$$(filter more_fonts,$$(gb_Module_ALLMODULES)))
+
+# the gbuildtojson / gbuild self-test runs tests "out of scope", but itself depends
+# on more fonts, so we must ignore the font tests for these tests.
+ifeq (,$$(gb_IGNORE_MORE_FONTS))
+
+# we are in single module mode -> fail test on missing fonts from filelists!
+# include Module_more_font.mk fails with strange error messages,
+# so we can't check if the more_fonts filelists are up-to-date, so just assume it.
+
+$(1): \
+ $$(foreach font,$$(gb_Package_MODULE_ooo_fonts), \
+ $$(if $$(wildcard $$(call gb_Package_get_target,$$(font))), \
+ $$(foreach file,$$(shell cat $$(call gb_Package_get_target,$$(font))), \
+ $$(if $$(wildcard $$(file)),,$$(error Missing font -> run make more_fonts extras))), \
+ $$(error Missing font filelist -> run make more_fonts extras)))
+endif
+else
+# we're in global run mode (full knowledge) -> depend directly on the delivered fonts!
+
+$(1): \
+ $$(foreach package,$$(subst ExternalPackage_,,$$(filter ExternalPackage_%,$$(call gb_Module_get_classnames,more_fonts))), \
+ $$(call gb_Package_get_files,$$(package))) \
+ $$(call gb_Package_get_files,extras_font) \
+ $$(if $$(filter Package_extras_fontconfig,$$(call gb_Module_get_classnames,extras)), \
+ $$(call gb_Package_get_files,extras_fontconfig))
+endif
+endif
+endif
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/Trace.mk b/solenv/gbuild/Trace.mk
new file mode 100644
index 000000000..8d416157d
--- /dev/null
+++ b/solenv/gbuild/Trace.mk
@@ -0,0 +1,61 @@
+# -*- 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/.
+#
+
+# Support for tracing what gbuild does.
+# Run 'make GBUILD_TRACE=/somewhere/log.json', process the file
+# using solenv/bin/finish-gbuild-trace.py, and then view it in Chromium
+# using the chrome://tracing URL:
+# - the '?' icon in the top-right is the help
+# - 'gbuild' rows represent per-parallelism (per-CPU) usage in time
+# - 'totals' rows represent sums for reach build type
+# - note that 'EXTERNAL' targets do not detect whether the external package
+# is built with parallelism or not, so the actual CPU time may be higher
+# - vertical lines represent targets that themselves do not take any time
+# to build
+# - any target can be found using the search field in the top right corner
+# (just type e.g. '[MOD]: sal' and hit the '->' button, if you cannot see
+# it pressing 'm' or 'f' can help)
+
+gb_TRACE :=
+ifneq ($(GBUILD_TRACE),)
+gb_TRACE := $(abspath $(GBUILD_TRACE))
+endif
+
+ifneq ($(gb_TRACE),)
+
+# call gb_Trace_AddMark,marktype,detail,type,extra
+# The (flock;cat) part is to minimize lock time.
+define gb_Trace__AddMark
+echo "{\"name\": \"$(3)\", \"ph\": \"$(1)\", \"pid\": 1, \"tid\": 1, \"ts\": $$(date +%s%N),\"args\":{\"message\":\"[$(3)]: $(2)\"}}," | ( flock 1; cat ) >>$(gb_TRACE)
+endef
+
+# call gb_Trace_StartRange,detail,type
+define gb_Trace_StartRange
+$(call gb_Trace__AddMark,B,$(1),$(2))
+endef
+
+# call gb_Trace_EndRange,detail,type
+define gb_Trace_EndRange
+$(call gb_Trace__AddMark,E,$(1),$(2))
+endef
+
+# call gb_Trace_MakeMark,detail,type
+define gb_Trace_MakeMark
+$(call gb_Trace__AddMark,i,$(1),$(2))
+endef
+
+ifeq ($(MAKE_RESTARTS),)
+$(shell rm -f $(gb_TRACE) 2>/dev/null)
+else
+$(shell $(call gb_Trace__AddMark,i,make restart,MAKE))
+endif
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/UIConfig.mk b/solenv/gbuild/UIConfig.mk
new file mode 100644
index 000000000..eaca4c5d8
--- /dev/null
+++ b/solenv/gbuild/UIConfig.mk
@@ -0,0 +1,358 @@
+# -*- 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/.
+#
+
+# class UIMenubarTarget
+
+# Handles platform-specific processing of menubar config files.
+
+# defined by platform:
+# gb_UIMenubarTarget_UIMenubarTarget_platform
+# gb_UIMenubarTarget__command
+
+$(dir $(call gb_UIMenubarTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_UIMenubarTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_UIMenubarTarget_get_target,%) :
+ $(call gb_UIMenubarTarget__command,$@,$*,$<)
+
+.PHONY : $(call gb_UIMenubarTarget_get_clean_target,%)
+$(call gb_UIMenubarTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$(2),$(false),UIM,1)
+ rm -f $(call gb_UIMenubarTarget_get_target,$*)
+
+# Process a menubar configuration file.
+#
+# gb_UIMenubarTarget_UIMenubarTarget target source
+define gb_UIMenubarTarget_UIMenubarTarget
+$(call gb_UIMenubarTarget_get_target,$(1)) : $(2)
+$(call gb_UIMenubarTarget_get_target,$(1)) :| $(dir $(call gb_UIMenubarTarget_get_target,$(1))).dir
+
+$(call gb_UIMenubarTarget_UIMenubarTarget_platform,$(1),$(2))
+
+endef
+
+# class UIImageListTarget
+
+# Handles creation of image lists for .ui files.
+
+gb_UIImageListTarget_COMMAND = $(call gb_ExternalExecutable_get_command,xsltproc)
+gb_UIImageListTarget_DEPS = $(call gb_ExternalExecutable_get_dependencies,xsltproc)
+gb_UIImageListTarget_XSLTFILE := $(SRCDIR)/solenv/bin/uiimagelist.xsl
+
+# NOTE: for some reason xsltproc does not produce any file if there is
+# no output, so we touch the target to make sure it exists.
+define gb_UIImageListTarget__command
+$(call gb_Helper_abbreviate_dirs,\
+ $(gb_UIImageListTarget_COMMAND) --nonet -o $@ $(gb_UIImageListTarget_XSLTFILE) $(UIFILE) && \
+ touch $@ \
+)
+endef
+
+$(dir $(call gb_UIImageListTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_UIImageListTarget_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_UIImageListTarget_get_target,%) : $(gb_UIImageListTarget_DEPS) $(gb_UIImageListTarget_XSLTFILE)
+ $(call gb_Output_announce,$*,$(true),UIL,1)
+ $(call gb_Trace_StartRange,$*,UIL)
+ $(call gb_UIImageListTarget__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,UIL)
+
+.PHONY : $(call gb_UIImageListTarget_get_clean_target,%)
+$(call gb_UIImageListTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),UIL,1)
+ rm -f $(call gb_UIImageListTarget_get_target,$*)
+
+# Extract list of images referenced in a .ui file.
+#
+# gb_UIImageListTarget_UIImageListTarget uifile
+define gb_UIImageListTarget_UIImageListTarget
+$(call gb_UIImageListTarget_get_target,$(1)) : UIFILE := $(SRCDIR)/$(1).ui
+
+$(call gb_UIImageListTarget_get_target,$(1)) : $(SRCDIR)/$(1).ui
+$(call gb_UIImageListTarget_get_target,$(1)) :| $(dir $(call gb_UIImageListTarget_get_target,$(1))).dir
+
+endef
+
+# class UIConfig
+
+# Handles UI configuration files.
+#
+# This mostly means UI description files (suffix .ui) for the new layouting
+# mechanism.
+#
+# This class provides the following filelists:
+# * UIConfig/<name> containing all nontranslatable files
+
+gb_UIConfig_INSTDIR := $(LIBO_SHARE_FOLDER)/config/soffice.cfg
+
+ifneq ($(filter LXML,$(BUILD_TYPE)),)
+gb_UIConfig_LXML_PATH := PYTHONPATH=$${PYTHONPATH:+$$PYTHONPATH:}$(call gb_UnpackedTarball_get_dir,lxml)/install ;
+gb_UIConfig_LXML_TARGET := $(call gb_ExternalProject_get_target,lxml)
+endif
+gb_UIConfig_gla11y_SCRIPT := $(SRCDIR)/bin/gla11y
+
+$(dir $(call gb_UIConfig_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_UIConfig_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_UIConfig_get_target,%) : $(call gb_UIConfig_get_imagelist_target,%) $(call gb_UIConfig_get_a11yerrors_target,%)
+ $(call gb_Output_announce,$*,$(true),UIC,2)
+ $(call gb_Trace_StartRange,$*,UIC)
+ $(call gb_Helper_abbreviate_dirs,\
+ touch $@ \
+ )
+ $(call gb_Trace_EndRange,$*,UIC)
+
+$(call gb_UIConfig_get_imagelist_target,%) :
+ $(call gb_UIConfig__command)
+
+.PHONY : $(call gb_UIConfig_get_clean_target,%)
+$(call gb_UIConfig_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),UIC,2)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_UIConfig_get_target,$*) $(call gb_UIConfig_get_imagelist_target,$*) \
+ )
+ $(call gb_Output_announce,$*,$(false),UIA,2)
+ rm -f $(call gb_UIConfig_get_a11yerrors_target,$*)
+
+gb_UIConfig_gla11y_PARAMETERS = -P $(SRCDIR)/ -f $(UI_A11YFALSE)
+
+# Disable this to see suppressed warnings
+ifeq (1,1)
+gb_UIConfig_gla11y_PARAMETERS += -s $(UI_A11YSUPPRS)
+endif
+# Enable this to regenerate suppression files
+ifeq (1,0)
+gb_UIConfig_gla11y_PARAMETERS += -g $(UI_A11YSUPPRS)
+endif
+
+# Tell gla11y about LO-specific widgets
+# These are storage, containers, or preview
+gb_UIConfig_gla11y_PARAMETERS += --widgets-suffixignored +ValueSet,HBox,VBox,ToolBox,Preview,PreviewWin,PreviewWindow,PrevWindow
+# These are buttons, thus already contain their label (but an image is not enough)
+gb_UIConfig_gla11y_PARAMETERS += --widgets-button +svtlo-ManagedMenuButton
+
+# All new warnings should be fatal except a few kinds which could be only doubtful
+gb_UIConfig_gla11y_PARAMETERS += --fatal-all --not-fatal-type duplicate-mnemonic --not-fatal-type labelled-by-and-mnemonic --not-fatal-type orphan-label
+
+define gb_UIConfig_a11yerrors__command
+$(call gb_UIConfig__gla11y_command)
+endef
+
+$(call gb_UIConfig_get_a11yerrors_target,%) : $(gb_UIConfig_LXML_TARGET) $(call gb_ExternalExecutable_get_dependencies,python) $(gb_UIConfig_gla11y_SCRIPT)
+ $(call gb_Output_announce,$*,$(true),UIA,1)
+ $(call gb_Trace_StartRange,$*,UIA)
+ $(call gb_UIConfig_a11yerrors__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,UIA)
+
+gb_UIConfig_get_packagename = UIConfig/$(1)
+gb_UIConfig_get_packagesetname = UIConfig/$(1)
+
+# Processes and delivers a set of UI configuration files.
+#
+# gb_UIConfig_UIConfig modulename
+define gb_UIConfig_UIConfig
+ifeq (,$$(filter $(1),$$(gb_UIConfig_REGISTERED)))
+$$(eval $$(call gb_Output_info,Currently known UI configs are: $(sort $(gb_UIConfig_REGISTERED)),ALL))
+$$(eval $$(call gb_Output_error,UIConfig $(1) must be registered in Repository.mk))
+endif
+$(call gb_UIConfig_get_imagelist_target,$(1)) : UI_IMAGELISTS :=
+
+$(call gb_PackageSet_PackageSet_internal,$(call gb_UIConfig_get_packagesetname,$(1)))
+$(call gb_Package_Package_internal,$(call gb_UIConfig_get_packagename,$(1)),$(SRCDIR))
+$(call gb_Package_Package_internal,$(call gb_UIConfig_get_packagename,$(1)_generated),$(WORKDIR))
+
+$(call gb_PackageSet_add_package,$(call gb_UIConfig_get_packagesetname,$(1)),$(call gb_UIConfig_get_packagename,$(1)))
+
+$(call gb_UIConfig_get_target,$(1)) :| $(dir $(call gb_UIConfig_get_target,$(1))).dir
+$(call gb_UIConfig_get_imagelist_target,$(1)) :| $(dir $(call gb_UIConfig_get_imagelist_target,$(1))).dir
+$(call gb_UIConfig_get_a11yerrors_target,$(1)) :| $(dir $(call gb_UIConfig_get_a11yerrors_target,$(1))).dir
+$(call gb_UIConfig_get_a11yerrors_target,$(1)) : UI_A11YSUPPRS := $(SRCDIR)/solenv/sanitizers/ui/$(1).suppr
+$(call gb_UIConfig_get_a11yerrors_target,$(1)) : UI_A11YFALSE := $(SRCDIR)/solenv/sanitizers/ui/$(1).false
+$(call gb_UIConfig_get_target,$(1)) : $(call gb_PackageSet_get_target,$(call gb_UIConfig_get_packagesetname,$(1)))
+$(call gb_UIConfig_get_clean_target,$(1)) : $(call gb_PackageSet_get_clean_target,$(call gb_UIConfig_get_packagesetname,$(1)))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_UIConfig_get_target,$(1)),$(call gb_UIConfig_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),UIConfig)
+$(call gb_Postprocess_register_target,AllUIConfigs,UIConfig,$(1))
+
+endef
+
+# gb_UIConfig__package_file target package type destfile srcfile
+define gb_UIConfig__package_file
+$(call gb_Package_add_file,$(2),$(gb_UIConfig_INSTDIR)/$(1)/$(3)/$(4),$(5))
+
+endef
+
+# gb_UIConfig__package_uifile target package destfile srcfile
+define gb_UIConfig__package_uifile
+$(call gb_UIConfig__package_file,$(1),$(2),ui,$(3),$(4))
+
+endef
+
+define gb_UIConfig_add_a11yerrors_uifile
+$(call gb_UIConfig_get_a11yerrors_target,$(1)) : UIFILES += $(SRCDIR)/$(2).ui
+$(call gb_UIConfig_get_a11yerrors_target,$(1)) : $(SRCDIR)/$(2).ui
+
+endef
+
+# gb_UIConfig__add_uifile target file
+define gb_UIConfig__add_uifile
+$(call gb_UIConfig__package_uifile,$(1),$(call gb_UIConfig_get_packagename,$(1)),$(notdir $(2)).ui,$(2).ui)
+$(call gb_UIImageListTarget_UIImageListTarget,$(2))
+
+$(call gb_UIConfig_get_imagelist_target,$(1)) : UI_IMAGELISTS += $(call gb_UIImageListTarget_get_target,$(2))
+$(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_add_a11yerrors_uifile,$(1),$(2))
+
+endef
+
+gb_UIConfig_ALLFILES:=
+# Adds .ui file to the package
+#
+# The file is relative to $(SRCDIR) and without extension.
+#
+# gb_UIConfig_add_uifile target uifile
+define gb_UIConfig_add_uifile
+gb_UIConfig_ALLFILES+=$(1):$(notdir $(2))
+$(call gb_UIConfig__add_uifile,$(1),$(2))
+
+endef
+
+# Adds multiple .ui files to the package
+#
+# gb_UIConfig_add_uifiles target uifile(s)
+define gb_UIConfig_add_uifiles
+$(foreach uifile,$(2),$(call gb_UIConfig_add_uifile,$(1),$(uifile)))
+
+endef
+
+# gb_UIConfig_add_uifiles target uifile(s) but only for running gla11y
+define gb_UIConfig_add_a11yerrors_uifiles
+$(foreach uifile,$(2),$(call gb_UIConfig_add_a11yerrors_uifile,$(1),$(uifile)))
+
+endef
+
+# gb_UIConfig__add_xmlfile target package-target type xmlfile
+define gb_UIConfig__add_xmlfile
+$(call gb_UIConfig__package_file,$(1),$(call gb_UIConfig_get_packagename,$(2)),$(3),$(notdir $(4)).xml,$(4).xml)
+
+endef
+
+define gb_UIConfig__add_menubarfile
+$(call gb_UIMenubarTarget_UIMenubarTarget,$(2),$(3))
+$(call gb_Package_add_file,$(call gb_UIConfig_get_packagename,$(1)_generated),$(gb_UIConfig_INSTDIR)/$(1)/menubar/$(notdir $(2)).xml,$(subst $(WORKDIR)/,,$(call gb_UIMenubarTarget_get_target,$(2))))
+$(call gb_PackageSet_add_package,$(call gb_UIConfig_get_packagesetname,$(1)),$(call gb_UIConfig_get_packagename,$(1)_generated))
+
+$(call gb_Package_get_target,$(call gb_UIConfig_get_packagename,$(1)_generated)) : $(call gb_UIMenubarTarget_get_target,$(2))
+$(call gb_Package_get_clean_target,$(call gb_UIConfig_get_packagename,$(1)_generated)) : $(call gb_UIMenubarTarget_get_clean_target,$(2))
+
+endef
+
+# Add menubar config file to the package.
+#
+# The file is relative to $(SRCDIR) and without extension.
+#
+# gb_UIConfig_add_menubarfile target file
+define gb_UIConfig_add_menubarfile
+$(call gb_UIConfig__add_menubarfile,$(1),$(gb_UIConfig_INSTDIR)/$(1)/menubar/$(notdir $(2)),$(SRCDIR)/$(2).xml)
+
+endef
+
+# Adds multiple menubar config files to the package.
+#
+# gb_UIConfig_add_menubarfiles target file(s)
+define gb_UIConfig_add_menubarfiles
+$(foreach menubarfile,$(2),$(call gb_UIConfig_add_menubarfile,$(1),$(menubarfile)))
+
+endef
+
+# Add a generated menubar config file to the package.
+#
+# The file is relative to $(WORKDIR) and without extension.
+#
+# gb_UIConfig_add_generated_menubarfile target file
+define gb_UIConfig_add_generated_menubarfile
+$(call gb_UIConfig__add_menubarfile,$(1),$(gb_UIConfig_INSTDIR)/$(1)/menubar/$(notdir $(2)),$(WORKDIR)/$(2).xml)
+
+endef
+
+# Adds multiple menubar config files to the package.
+#
+# gb_UIConfig_add_generated_menubarfiles target file(s)
+define gb_UIConfig_add_generated_menubarfiles
+$(foreach menubarfile,$(2),$(call gb_UIConfig_add_generated_menubarfile,$(1),$(menubarfile)))
+
+endef
+
+# Add statusbar config file to the package.
+#
+# The file is relative to $(SRCDIR) and without extension.
+#
+# gb_UIConfig_add_statusbarfile target file
+define gb_UIConfig_add_statusbarfile
+$(call gb_UIConfig__add_xmlfile,$(1),$(1),statusbar,$(2))
+
+endef
+
+# Adds multiple statusbar config files to the package.
+#
+# gb_UIConfig_add_statusbarfiles target file(s)
+define gb_UIConfig_add_statusbarfiles
+$(foreach statusbarfile,$(2),$(call gb_UIConfig_add_statusbarfile,$(1),$(statusbarfile)))
+
+endef
+
+# Add toolbar config file to the package.
+#
+# The file is relative to $(SRCDIR) and without extension.
+#
+# gb_UIConfig_add_toolbarfile target file
+define gb_UIConfig_add_toolbarfile
+$(call gb_UIConfig__add_xmlfile,$(1),$(1),toolbar,$(2))
+
+endef
+
+# Adds multiple toolbar config files to the package.
+#
+# gb_UIConfig_add_toolbarfiles target file(s)
+define gb_UIConfig_add_toolbarfiles
+$(foreach toolbarfile,$(2),$(call gb_UIConfig_add_toolbarfile,$(1),$(toolbarfile)))
+
+endef
+
+# Add popupmenu config file to the package.
+#
+# The file is relative to $(SRCDIR) and without extension.
+#
+# gb_UIConfig_add_popupmenufile target file
+define gb_UIConfig_add_popupmenufile
+$(call gb_UIConfig__add_xmlfile,$(1),$(1),popupmenu,$(2))
+
+endef
+
+# Adds multiple popupmenu config files to the package.
+#
+# gb_UIConfig_add_popupmenufiles target file(s)
+define gb_UIConfig_add_popupmenufiles
+$(foreach popupmenufile,$(2),$(call gb_UIConfig_add_popupmenufile,$(1),$(popupmenufile)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/UITest.mk b/solenv/gbuild/UITest.mk
new file mode 100644
index 000000000..0a0893923
--- /dev/null
+++ b/solenv/gbuild/UITest.mk
@@ -0,0 +1,157 @@
+# -*- 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/.
+#
+
+# UITest class
+
+gb_UITest_UNITTESTFAILED ?= $(GBUILDDIR)/uitest-failed-default.sh
+
+ifeq ($(SYSTEM_PYTHON),)
+gb_UITest_EXECUTABLE := $(gb_Python_INSTALLED_EXECUTABLE)
+gb_UITest_DEPS ?= $(call gb_Package_get_target,python3)
+else
+gb_UITest_EXECUTABLE := $(PYTHON_FOR_BUILD)
+gb_UITest_DEPS :=
+endif
+
+# UITests are much more likely to generate core files for the soffice than for
+# the python executable, but solenv/bin/gdb-core-bt.sh is often unable to
+# determine the executable that generated a core file, so make it fall back to
+# the soffice executable rather than to gb_UITest_EXECUTABLE:
+gb_UITest_EXECUTABLE_GDB := $(call gb_Executable_get_target,soffice_bin)
+
+ifneq ($(strip $(UITESTTRACE)),)
+gb_UITest_GDBTRACE := --gdb
+gb_UITest__interactive := $(true)
+endif
+
+ifneq ($(gb_UITest_DEBUGRUN),)
+gb_UITest_SOFFICEARG:=connect:pipe,name=$(USER)
+gb_UITest__interactive := $(true)
+else
+gb_UITest_SOFFICEARG:=path:$(INSTROOT)/$(LIBO_BIN_FOLDER)/soffice
+endif
+
+gb_UITest_COMMAND = $(ICECREAM_RUN) $(gb_CppunitTest_RR) $(gb_UITest_EXECUTABLE) $(SRCDIR)/uitest/test_main.py
+
+gb_TEST_ENV_VARS += LIBO_LANG=C
+
+.PHONY : $(call gb_UITest_get_clean_target,%)
+$(call gb_UITest_get_clean_target,%) :
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $@ $@.log)
+
+ifneq ($(DISABLE_PYTHON),TRUE)
+
+# qadevOOo/qa/registrymodifications.xcu is copied to user profile directory to ensure en_US locale;
+# this might be overwritten later when gb_UITest_use_config is set
+.PHONY : $(call gb_UITest_get_target,%)
+$(call gb_UITest_get_target,%) :| $(gb_UITest_DEPS)
+ifneq ($(gb_SUPPRESS_TESTS),)
+ @true
+else
+ $(call gb_Output_announce,$*,$(true),UIT,2)
+ $(call gb_Trace_StartRange,$*,UIT)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf $(dir $(call gb_UITest_get_target,$*)) && \
+ mkdir -p $(dir $(call gb_UITest_get_target,$*))/user/user && \
+ cp $(SRCDIR)/qadevOOo/qa/registrymodifications.xcu $(dir $(call gb_UITest_get_target,$*))/user/user/ && \
+ $(if $(gb_UITest__interactive),, \
+ rm -fr $@.core && mkdir -p $(dir $(call gb_UITest_get_target,$*))user/ && mkdir $@.core && cd $@.core && ) \
+ $(if $(gb_UITest_use_config), \
+ cp $(gb_UITest_use_config) $(dir $(call gb_UITest_get_target,$*))user/. && ) \
+ ($(gb_UITest_PRECOMMAND) \
+ $(if $(G_SLICE),G_SLICE=$(G_SLICE)) \
+ $(if $(GLIBCXX_FORCE_NEW),GLIBCXX_FORCE_NEW=$(GLIBCXX_FORCE_NEW)) \
+ $(DEFS) \
+ $(if $(filter WNT,$(OS)),SAL_LOG_FILE="$(dir $(call gb_UITest_get_target,$*))/soffice.out.log") \
+ TEST_LIB=$(call gb_Library_get_target,test) \
+ URE_BOOTSTRAP=vnd.sun.star.pathname:$(call gb_Helper_get_rcfile,$(INSTROOT)/$(LIBO_ETC_FOLDER)/fundamental) \
+ PYTHONPATH="$(PYPATH)" \
+ TestUserDir="$(call gb_Helper_make_url,$(dir $(call gb_UITest_get_target,$*)))" \
+ PYTHONDONTWRITEBYTECODE=0 \
+ $(if $(ENABLE_WERROR),PYTHONWARNINGS=error) \
+ $(if $(filter WNT,$(OS)),TZ=) \
+ $(gb_TEST_ENV_VARS) \
+ $(gb_UITest_COMMAND) \
+ --soffice="$(gb_UITest_SOFFICEARG)" \
+ --userdir=$(call gb_Helper_make_url,$(dir $(call gb_UITest_get_target,$*))user) \
+ --dir=$(strip $(MODULES)) \
+ $(gb_UITest_GDBTRACE) \
+ $(if $(gb_UITest__interactive),, \
+ > $@.log 2>&1 \
+ || ($(if $(value gb_CppunitTest_postprocess), \
+ RET=$$?; \
+ $(call gb_CppunitTest_postprocess,$(gb_UITest_EXECUTABLE_GDB),$@.core,$$RET) >> $@.log 2>&1;) \
+ $(if $(filter WNT,$(OS)), \
+ printf '%s: <<<\n' $(dir $(call gb_UITest_get_target,$*))/soffice.out.log; \
+ cat $(dir $(call gb_UITest_get_target,$*))/soffice.out.log; \
+ printf ' >>>\n\n';) \
+ cat $@.log; $(gb_UITest_UNITTESTFAILED) UI $*))))
+ $(call gb_Trace_EndRange,$*,UIT)
+endif
+
+# always use udkapi and URE services
+define gb_UITest_UITest
+$(call gb_UITest_get_target,$(1)) : PYPATH := $(SRCDIR)/uitest$$(gb_CLASSPATHSEP)$(SRCDIR)/unotest/source/python$$(gb_CLASSPATHSEP)$(INSTROOT)/$(LIBO_LIB_PYUNO_FOLDER)$(if $(filter-out $(LIBO_LIB_PYUNO_FOLDER),$(LIBO_LIB_FOLDER)),$(gb_CLASSPATHSEP)$(INSTROOT)/$(LIBO_LIB_FOLDER))
+$(call gb_UITest_get_target,$(1)) : MODULES :=
+
+$(eval $(call gb_TestHelpers_use_more_fonts,$(call gb_UITest_get_target,$(1))))
+$(eval $(call gb_Module_register_target,$(call gb_UITest_get_target,$(1)),$(call gb_UITest_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),UITest)
+
+endef
+
+define gb_UITest_set_defs
+$(call gb_UITest_get_target,$(1)) : DEFS := $(2)
+
+endef
+
+# put the directory on the PYTHONPATH because the "unittest" loader
+# mysteriously fails to load modules given as absolute path unless the $PWD is
+# a prefix of the absolute path, which it is not when we go into a certain
+# dir to get a core dump there
+#
+# gb_UITest_add_modules directory module(s)
+define gb_UITest_add_modules
+$(call gb_UITest_get_target,$(1)) : PYPATH := $$(PYPATH)$$(gb_CLASSPATHSEP)$(strip $(2))/$(strip $(3))
+$(call gb_UITest_get_target,$(1)) : MODULES += $(strip $(2))/$(strip $(3))
+
+endef
+
+define gb_UITest_use_customtarget
+$(call gb_UITest_get_target,$(1)) : $(call gb_CustomTarget_get_workdir,$(2))
+
+endef
+
+define gb_UITest_use_configuration
+$(call gb_UITest_get_target,$(1)) : gb_UITest_use_config := $(2)
+endef
+
+
+else # DISABLE_PYTHON
+
+.PHONY : $(call gb_UITest_get_target,$(1))
+$(call gb_UITest_get_target,%) :
+ifeq ($(gb_SUPPRESS_TESTS),)
+ $(call gb_Output_announce,$* (skipped - no UITest),$(true),PYT,2)
+endif
+ @true
+
+define gb_UITest_UITest
+$(eval $(call gb_Module_register_target,$(call gb_UITest_get_target,$(1)),$(call gb_UITest_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),UITest)
+
+endef
+
+gb_UITest_set_defs :=
+gb_UITest_add_modules :=
+gb_UITest_use_customtarget :=
+
+endif # DISABLE_PYTHON
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/UnoApi.mk b/solenv/gbuild/UnoApi.mk
new file mode 100644
index 000000000..d99195d21
--- /dev/null
+++ b/solenv/gbuild/UnoApi.mk
@@ -0,0 +1,104 @@
+# -*- 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/.
+#
+
+gb_UnoApi_ENABLE_INSTALL := $(and $(filter host,$(gb_Side)),$(filter ODK,$(BUILD_TYPE)))
+
+.PHONY : $(call gb_UnoApi_get_clean_target,%)
+$(call gb_UnoApi_get_clean_target,%) :
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_UnoApi_get_target,$*))
+
+# call gb_UnoApi_UnoApi,api
+define gb_UnoApi_UnoApi
+$(call gb_UnoApiTarget_UnoApiTarget,$(1),$(1))
+$(call gb_UnoApiHeadersTarget_UnoApiHeadersTarget,$(1))
+ifneq ($(gb_UnoApi_ENABLE_INSTALL),)
+$(call gb_Package_Package_internal,$(1)_idl,$(SRCDIR))
+$(call gb_Package_set_outdir,$(1)_idl,$(INSTDIR))
+endif
+
+$(call gb_UnoApi_get_target,$(1)) :| $(dir $(call gb_UnoApi_get_target,$(1))).dir
+$(call gb_UnoApi_get_target,$(1)) : $(call gb_UnoApiTarget_get_target,$(1))
+$(call gb_UnoApi_get_target,$(1)) :| $(call gb_UnoApiHeadersTarget_get_target,$(1))
+$(call gb_UnoApi_get_clean_target,$(1)) : $(call gb_UnoApiTarget_get_clean_target,$(1))
+$(call gb_UnoApi_get_clean_target,$(1)) : $(call gb_UnoApiHeadersTarget_get_clean_target,$(1))
+
+$(call gb_Deliver_add_deliverable,$(call gb_UnoApi_get_target,$(1)),$(call gb_UnoApiTarget_get_target,$(1)),$(1))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_UnoApi_get_target,$(1)),$(call gb_UnoApi_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),UnoApi)
+
+endef
+
+ifneq ($(gb_UnoApi_ENABLE_INSTALL),)
+
+# Create a package of IDL files for putting into SDK.
+#
+# gb_UnoApi_package_idlfiles api
+define gb_UnoApi_package_idlfiles
+$(call gb_UnoApi_get_target,$(1)) :| $(call gb_Package_get_target,$(1)_idl)
+$(call gb_UnoApi_get_clean_target,$(1)) : $(call gb_Package_get_clean_target,$(1)_idl)
+
+endef
+
+define gb_UnoApi__add_idlfile
+$(call gb_Package_add_file,$(1)_idl,$(patsubst $(1)/%,$(SDKDIRNAME)/idl/%,$(2).idl),$(2).idl)
+
+endef
+
+else # !gb_UnoApi_ENABLE_INSTALL
+
+gb_UnoApi_package_idlfiles :=
+gb_UnoApi__add_idlfile :=
+
+endif
+
+# For enum types, plain struct types, polymorphic struct type templates,
+# exception types, interface types, typedefs, and constant groups:
+define gb_UnoApi_add_idlfiles
+$(call gb_UnoApiTarget_add_idlfiles,$(1),$(2),$(3))
+$(call gb_UnoApiHeadersTarget_add_headerfiles,$(1),$(2),$(addsuffix .hpp,$(3)))
+$(call gb_UnoApiHeadersTarget_add_headerfiles,$(1),$(2),$(addsuffix .hdl,$(3)))
+$(foreach idl,$(3),$(call gb_UnoApi__add_idlfile,$(1),$(gb_UnoApiTarget_REG_$(1))/$(2)/$(idl)))
+
+endef
+
+# For single-interface--based services and interface-based singletons:
+define gb_UnoApi_add_idlfiles_nohdl
+$(call gb_UnoApiTarget_add_idlfiles,$(1),$(2),$(3))
+$(call gb_UnoApiHeadersTarget_add_headerfiles,$(1),$(2),$(addsuffix .hpp,$(3)))
+$(foreach idl,$(3),$(call gb_UnoApi__add_idlfile,$(1),$(gb_UnoApiTarget_REG_$(1))/$(2)/$(idl)))
+
+endef
+
+# For accumulation-based services and service-based singletons:
+define gb_UnoApi_add_idlfiles_noheader
+$(call gb_UnoApiTarget_add_idlfiles,$(1),$(2),$(3))
+$(foreach idl,$(3),$(call gb_UnoApi__add_idlfile,$(1),$(gb_UnoApiTarget_REG_$(1))/$(2)/$(idl)))
+
+endef
+
+define gb_UnoApi__use_api
+$(call gb_UnoApiTarget_use_api,$(1),$(2))
+$(call gb_UnoApiHeadersTarget_use_api,$(1),$(2))
+$(call gb_UnoApi_get_target,$(1)) :| $(call gb_UnoApi_get_target,$(2))
+
+endef
+
+define gb_UnoApi_use_api
+$(foreach rdb,$(2),$(call gb_UnoApi__use_api,$(1),$(rdb)))
+
+endef
+
+define gb_UnoApi_set_reference_rdbfile
+$(call gb_UnoApiTarget_set_reference_rdbfile,$(1),$(2))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/UnoApiTarget.mk b/solenv/gbuild/UnoApiTarget.mk
new file mode 100644
index 000000000..563ab82a2
--- /dev/null
+++ b/solenv/gbuild/UnoApiTarget.mk
@@ -0,0 +1,250 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# UnoApiTarget
+
+gb_UnoApiTarget_UNOIDLWRITEDEPS := $(call gb_Executable_get_runtime_dependencies,unoidl-write)
+gb_UnoApiTarget_UNOIDLWRITECOMMAND := $(call gb_Executable_get_command,unoidl-write)
+
+gb_UnoApiTarget_UNOIDLCHECKDEPS := $(call gb_Executable_get_runtime_dependencies,unoidl-check)
+gb_UnoApiTarget_UNOIDLCHECKCOMMAND := $(call gb_Executable_get_command,unoidl-check)
+
+define gb_UnoApiTarget__command
+mkdir -p $(dir $(1)) \
+$(if $(UNOAPI_ENTITIES), \
+ && RESPONSEFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),500,$(UNOAPI_ENTITIES))) \
+&& $(gb_UnoApiTarget_UNOIDLWRITECOMMAND) \
+ $(foreach rdb,$(UNOAPI_DEPRDBS),$(call gb_UnoApiTarget_get_target,$(rdb))) \
+ $(SRCDIR)/$(gb_UnoApiTarget_REG_$(2)) $(if $(UNOAPI_ENTITIES),@$${RESPONSEFILE}) $(1) \
+$(if $(UNOAPI_ENTITIES),&& rm -f $${RESPONSEFILE}) \
+$(if $(UNOAPI_REFERENCE), \
+ $(call gb_Output_announce,$(2),$(true),DBc,3) \
+ && $(gb_UnoApiTarget_UNOIDLCHECKCOMMAND) $(UNOAPI_REFERENCE) -- \
+ $(foreach rdb,$(UNOAPI_DEPRDBS),$(call gb_UnoApiTarget_get_target,$(rdb))) \
+ $(1))
+endef
+
+$(call gb_UnoApiTarget_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),UNO,4)
+ $(call gb_Trace_StartRange,$*,UNO)
+ $(call gb_UnoApiTarget__command,$@,$*)
+ $(call gb_Trace_EndRange,$*,UNO)
+
+.PHONY : $(call gb_UnoApiTarget_get_clean_target,%)
+$(call gb_UnoApiTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),UNO,4)
+ -$(call gb_Helper_abbreviate_dirs,\
+ rm -rf $(call gb_UnoApiTarget_get_target,$*))
+
+define gb_UnoApiTarget_UnoApiTarget
+gb_UnoApiTarget_REG_$(1) := $(2)
+$(call gb_UnoApiTarget_get_target,$(1)) : UNOAPI_ENTITIES :=
+$(call gb_UnoApiTarget_get_target,$(1)) : UNOAPI_REFERENCE :=
+$(call gb_UnoApiTarget_get_target,$(1)) : UNOAPI_DEPRDBS :=
+$(call gb_UnoApiTarget_get_target,$(1)) : $(gb_UnoApiTarget_UNOIDLWRITEDEPS)
+$(call gb_UnoApiTarget_get_target,$(1)) : $(SRCDIR)/$(2) # may be dir, though
+
+endef
+
+define gb_UnoApiTarget_add_idlfile
+$(call gb_UnoApiTarget_get_target,$(1)) : UNOAPI_ENTITIES += $(subst /,.,$(2))$(if $(2),.)$(3)
+$(call gb_UnoApiTarget_get_target,$(1)) : $(SRCDIR)/$(gb_UnoApiTarget_REG_$(1))/$(2)/$(3).idl
+
+endef
+
+define gb_UnoApiTarget_add_idlfiles
+$(foreach idl,$(3),$(call gb_UnoApiTarget_add_idlfile,$(1),$(2),$(idl)))
+
+endef
+
+define gb_UnoApiTarget_set_reference_rdbfile
+$(call gb_UnoApiTarget_get_target,$(1)) : UNOAPI_REFERENCE := $(2)
+$(call gb_UnoApiTarget_get_target,$(1)) : $(2)
+$(call gb_UnoApiTarget_get_target,$(1)) : $(gb_UnoApiTarget_UNOIDLCHECKDEPS)
+
+endef
+
+define gb_UnoApiTarget_use_api
+$(call gb_UnoApiTarget_get_target,$(1)) : UNOAPI_DEPRDBS += $(2)
+$(call gb_UnoApiTarget_get_target,$(1)) : $(call gb_UnoApiTarget_get_target,$(2))
+
+endef
+
+# UnoApiHeadersTarget
+
+# defined by platform
+# gb_UnoApiHeadersTarget_select_variant
+
+# Allow to redefine header variant.
+#
+# On iOS we use static linking because dynamic loading of own code
+# isn't allowed by the iOS App Store rules, and we want our code to be
+# eventually distributable there as part of apps.
+#
+# To avoid problems that this causes together with the lovely
+# intentional breaking of the One Definition Rule, for iOS we always
+# generate comprehensive headers for certain type RDBS. (The ODR
+# breakage doesn't harm, by accident or careful design, on platforms
+# where shared libraries are used.) To avoid generating the same headers
+# more than once, we are silently "redirecting" the target to point to
+# comprehensive headers instead.
+#
+# Example:
+# If gb_UnoApiHeadersTarget_select_variant is defined as
+#
+# ifeq ($(DISABLE_DYNLOADING),TRUE)
+# gb_UnoApiHeadersTarget_select_variant = $(if $(filter udkapi,$(1)),comprehensive,$(2))
+# else
+# gb_UnoApiHeadersTarget_select_variant = $(2)
+# endif
+#
+# then, for the DISABLE_DYNLOADING case, whenever a makefile uses
+# $(call gb_UnoApiHeadersTarget_get_target,udkapi) or $(call
+# gb_UnoApiHeadersTarget_get_dir,udkapi), it will get target or dir for
+# comprehensive headers instead.
+#
+# We are experimenting with static linking on Android, too. There for
+# technical reasons to get around silly limitations in the OS, sigh.
+#
+# gb_UnoApiHeadersTarget_select_variant api default-variant
+ifeq ($(origin gb_UnoApiHeadersTarget_select_variant),undefined)
+$(eval $(call gb_Output_error,gb_UnoApiHeadersTarget_select_variant must be defined by platform))
+endif
+
+gb_UnoApiHeadersTarget_CPPUMAKERDEPS := $(call gb_Executable_get_runtime_dependencies,cppumaker)
+gb_UnoApiHeadersTarget_CPPUMAKERCOMMAND := $(call gb_Executable_get_command,cppumaker)
+
+define gb_UnoApiHeadersTarget__command
+ $(gb_UnoApiHeadersTarget_CPPUMAKERCOMMAND) \
+ -Gc $(4) -O$(3) $(call gb_UnoApiTarget_get_target,$(2)) \
+ $(UNOAPI_DEPS) && \
+ touch $(1)
+
+endef
+
+$(call gb_UnoApiHeadersTarget_get_real_bootstrap_target,%) : \
+ $(gb_UnoApiHeadersTarget_CPPUMAKERDEPS)
+ $(call gb_Output_announce,$*,$(true),HPB,3) \
+ $(call gb_Trace_StartRange,$*,HPB)
+ $(call gb_UnoApiHeadersTarget__command,$@,$*,$(call gb_UnoApiHeadersTarget_get_bootstrap_dir,$*))
+ $(call gb_Trace_EndRange,$*,HPB)
+
+$(call gb_UnoApiHeadersTarget_get_real_comprehensive_target,%) : \
+ $(gb_UnoApiHeadersTarget_CPPUMAKERDEPS)
+ $(call gb_Output_announce,$*,$(true),HPC,3)
+ $(call gb_Trace_StartRange,$*,HPC)
+ $(call gb_UnoApiHeadersTarget__command,$@,$*,$(call gb_UnoApiHeadersTarget_get_comprehensive_dir,$*),-C)
+ $(call gb_Trace_EndRange,$*,HPC)
+
+$(call gb_UnoApiHeadersTarget_get_real_target,%) : \
+ $(gb_UnoApiHeadersTarget_CPPUMAKERDEPS)
+ $(call gb_Output_announce,$*,$(true),HPP,3) \
+ $(call gb_Trace_StartRange,$*,HPP)
+ $(call gb_UnoApiHeadersTarget__command,$@,$*,$(call gb_UnoApiHeadersTarget_get_dir,$*),-L)
+ $(call gb_Trace_EndRange,$*,HPP)
+
+.PHONY : $(call gb_UnoApiHeadersTarget_get_clean_target,%)
+$(call gb_UnoApiHeadersTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),HPP,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf \
+ $(call gb_UnoApiHeadersTarget_get_real_dir,$*) \
+ $(call gb_UnoApiHeadersTarget_get_real_bootstrap_dir,$*) \
+ $(call gb_UnoApiHeadersTarget_get_real_comprehensive_dir,$*) \
+ $(call gb_UnoApiHeadersTarget_get_real_target,$*) \
+ $(call gb_UnoApiHeadersTarget_get_real_bootstrap_target,$*)) \
+ $(call gb_UnoApiHeadersTarget_get_real_comprehensive_target,$*)
+
+define gb_UnoApiHeadersTarget_UnoApiHeadersTarget
+$(call gb_UnoApiHeadersTarget_get_target,$(1)) : $(call gb_UnoApiTarget_get_target,$(1))
+$(call gb_UnoApiHeadersTarget_get_bootstrap_target,$(1)) : $(call gb_UnoApiTarget_get_target,$(1))
+$(call gb_UnoApiHeadersTarget_get_comprehensive_target,$(1)) : $(call gb_UnoApiTarget_get_target,$(1))
+$(call gb_UnoApiHeadersTarget_get_clean_target,$(1)) : $(call gb_UnoApiTarget_get_clean_target,$(1))
+
+$(call gb_UnoApiHeadersTarget_get_target,$(1)) : UNOAPI_DEPS :=
+$(call gb_UnoApiHeadersTarget_get_bootstrap_target,$(1)) : UNOAPI_DEPS :=
+$(call gb_UnoApiHeadersTarget_get_comprehensive_target,$(1)) : UNOAPI_DEPS :=
+
+# need dummy recipes so that header files are delivered in Package_inc;
+# otherwise make will consider the header to be up-to-date because it was
+# actually built by the recipe for gb_UnoApiHeadersTarget_get_target
+$(call gb_UnoApiHeadersTarget_get_real_dir,$(1))/%.hdl : \
+ $(call gb_Executable_get_target_for_build,cppumaker) \
+ | $(call gb_UnoApiHeadersTarget_get_real_target,$(1))
+ touch $$@
+
+$(call gb_UnoApiHeadersTarget_get_real_dir,$(1))/%.hpp : \
+ $(call gb_Executable_get_target_for_build,cppumaker) \
+ | $(call gb_UnoApiHeadersTarget_get_real_target,$(1))
+ touch $$@
+
+$(call gb_UnoApiHeadersTarget_get_real_bootstrap_dir,$(1))/%.hdl : \
+ $(call gb_Executable_get_target_for_build,cppumaker) \
+ | $(call gb_UnoApiHeadersTarget_get_real_bootstrap_target,$(1))
+ touch $$@
+
+$(call gb_UnoApiHeadersTarget_get_real_bootstrap_dir,$(1))/%.hpp : \
+ $(call gb_Executable_get_target_for_build,cppumaker) \
+ | $(call gb_UnoApiHeadersTarget_get_real_bootstrap_target,$(1))
+ touch $$@
+
+$(call gb_UnoApiHeadersTarget_get_real_comprehensive_dir,$(1))/%.hdl : \
+ $(call gb_Executable_get_target_for_build,cppumaker) \
+ | $(call gb_UnoApiHeadersTarget_get_real_comprehensive_target,$(1))
+ touch $$@
+
+$(call gb_UnoApiHeadersTarget_get_real_comprehensive_dir,$(1))/%.hpp : \
+ $(call gb_Executable_get_target_for_build,cppumaker) \
+ | $(call gb_UnoApiHeadersTarget_get_real_comprehensive_target,$(1))
+ touch $$@
+
+endef
+
+# ensure that idl change triggers the dummy rule to rebuild the headers
+# call gb_UnoApiHeadersTarget_add_headerfile,unoapi,headerfile
+define gb_UnoApiHeadersTarget_add_headerfile
+$(call gb_UnoApiHeadersTarget_get_dir,$(1))/$(2) : \
+ $(SRCDIR)/$(basename $(gb_UnoApiTarget_REG_$(1))/$(2)).idl
+
+endef
+
+# call gb_UnoApiHeadersTarget_add_headerfiles,unoapi,directory,headerfilenames
+define gb_UnoApiHeadersTarget_add_headerfiles
+$(foreach hdr,$(3),$(call gb_UnoApiHeadersTarget_add_headerfile,$(1),$(2)/$(hdr)))
+endef
+
+define gb_UnoApiHeadersTarget__use_api_for_target
+$(call gb_UnoApiHeadersTarget_get_$(3),$(1)) : $(call gb_UnoApiTarget_get_target,$(2))
+$(call gb_UnoApiHeadersTarget_get_$(3),$(1)) : UNOAPI_DEPS += -X$(call gb_UnoApiTarget_get_target,$(2))
+
+endef
+
+define gb_UnoApiHeadersTarget__use_api
+$(call gb_UnoApiHeadersTarget__use_api_for_target,$(1),$(2),target)
+$(call gb_UnoApiHeadersTarget__use_api_for_target,$(1),$(2),bootstrap_target)
+$(call gb_UnoApiHeadersTarget__use_api_for_target,$(1),$(2),comprehensive_target)
+
+endef
+
+define gb_UnoApiHeadersTarget_use_api
+$(foreach rdb,$(2),$(call gb_UnoApiHeadersTarget__use_api,$(1),$(rdb)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/UnpackedTarball.mk b/solenv/gbuild/UnpackedTarball.mk
new file mode 100644
index 000000000..fb574f6a9
--- /dev/null
+++ b/solenv/gbuild/UnpackedTarball.mk
@@ -0,0 +1,455 @@
+# -*- 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/.
+#
+
+# UnpackedTarget class
+
+# Handles unpacking of a tarball
+
+# platform
+# gb_UnpackedTarget_TARFILE_LOCATION
+# NOTE: only for commands; targets should use TARFILE_LOCATION directly
+
+# Location of internal copies of config.{guess,sub}.
+gb_UnpackedTarball_CONFIGDIR := $(GBUILDDIR)
+
+define gb_UnpackedTarget__command_untar
+$(GNUTAR) \
+ -x \
+ $(3) \
+ -C $(UNPACKED_DIR) \
+ $(STRIP_COMPONENTS)=$(UNPACKED_STRIP_COMPONENTS) \
+ -f $(UNPACKED_TARBALL)
+endef
+
+define gb_UnpackedTarget__command_unzip
+unzip \
+ -qq \
+ -d $(UNPACKED_DIR) $(UNPACKED_TARBALL) \
+$(if $(filter-out 0,$(UNPACKED_STRIP_COMPONENTS)),\
+ && UNZIP_DIR=`ls $(UNPACKED_DIR)` \
+ && mv $(UNPACKED_DIR)/$$UNZIP_DIR/* $(UNPACKED_DIR) \
+ && rm -rf $(UNPACKED_DIR)/$$UNZIP_DIR \
+)
+endef
+
+define gb_UnpackedTarget__command
+$(call gb_Output_announce,$(notdir $(2)),$(true),UPK,1)
+ $(call gb_Trace_StartRange,$(notdir $(2)),UPK)
+$(call gb_Helper_abbreviate_dirs,\
+ $(if $(wildcard $(UNPACKED_DIR)),rm -rf $(UNPACKED_DIR) &&) \
+ mkdir -p $(UNPACKED_DIR) && \
+ $(call gb_UnpackedTarget__command_$(1),$(2),$(3),$(4)) && \
+ touch $(2) \
+)
+ $(call gb_Trace_EndRange,$(notdir $(2)),UPK)
+endef
+
+$(dir $(call gb_UnpackedTarget_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_UnpackedTarget_get_target,%).tar.bz2 :
+ $(call gb_UnpackedTarget__command,untar,$@,$*,-j)
+
+$(call gb_UnpackedTarget_get_target,%).tar.xz :
+ $(call gb_UnpackedTarget__command,untar,$@,$*,-J)
+
+$(call gb_UnpackedTarget_get_target,%).tar.gz :
+ $(call gb_UnpackedTarget__command,untar,$@,$*,-z)
+
+$(call gb_UnpackedTarget_get_target,%).tgz :
+ $(call gb_UnpackedTarget__command,untar,$@,$*,-z)
+
+$(call gb_UnpackedTarget_get_target,%).zip :
+ $(call gb_UnpackedTarget__command,unzip,$@,$*)
+
+$(call gb_UnpackedTarget_get_target,%).oxt :
+ $(call gb_UnpackedTarget__command,unzip,$@,$*)
+
+.PHONY : $(call gb_UnpackedTarget_get_clean_target,%)
+$(call gb_UnpackedTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),UPK,1)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_UnpackedTarget_get_target,$*) \
+ )
+
+# gb_UnpackedTarget_UnpackedTarget target outdir strip-components?
+define gb_UnpackedTarget_UnpackedTarget
+$(call gb_UnpackedTarget_get_target,$(1)) : UNPACKED_DIR := $(2)
+$(call gb_UnpackedTarget_get_target,$(1)) : UNPACKED_TARBALL := $(gb_UnpackedTarget_TARFILE_LOCATION)/$(1)
+$(call gb_UnpackedTarget_get_target,$(1)) : UNPACKED_STRIP_COMPONENTS := $(if $(strip $(3)),$(strip $(3)),1)
+
+$(call gb_UnpackedTarget_get_target,$(1)) : $(TARFILE_LOCATION)/$(1)
+$(call gb_UnpackedTarget_get_target,$(1)) :| $(dir $(call gb_UnpackedTarget_get_target,$(1))).dir
+
+endef
+
+# UnpackedTarball class
+
+# Handles unpacking and patching of an external project
+#
+# The unpacked dir is recreated every time one of the patches, copied
+# files or the makefile changes.
+
+# This is what dmake patches use. Once all external modules are
+# converted, it is better to be changed to 1.
+gb_UnpackedTarball_PATCHLEVEL_DEFAULT := 2
+
+gb_UnpackedTarball_CONVERTTODOS = \
+ $(gb_AWK) 'sub("$$","\r")' $(1) > $(1).TEMP && mv $(1).TEMP $(1)
+gb_UnpackedTarball_CONVERTTOUNIX = \
+ tr -d '\r' < $(1) > $(1).TEMP && mv $(1).TEMP $(1)
+
+define gb_UnpackedTarball__copy_files_impl
+$(if $(1),\
+ && cp $(firstword $(1)) $(firstword $(2)) \
+ $(call gb_UnpackedTarball__copy_files_impl,$(wordlist 2,$(words $(1)),$(1)),$(wordlist 2,$(words $(2)),$(2))) \
+)
+endef
+
+# Drop leading &&
+define gb_UnpackedTarball__copy_files_fix
+$(wordlist 2,$(words $(1)),$(1))
+endef
+
+define gb_UnpackedTarball__copy_files
+$(call gb_UnpackedTarball__copy_files_fix,$(call gb_UnpackedTarball__copy_files_impl,$(1),$(2)))
+endef
+
+define gb_UnpackedTarball__command
+$(call gb_Helper_abbreviate_dirs,\
+ ( \
+ cd $(3) \
+ $(if $(UNPACKED_IS_BIN_TARBALL),,&& \
+ $(if $(UNPACKED_PRE_ACTION),\
+ $(UNPACKED_PRE_ACTION) && \
+ ) \
+ $(if $(UNPACKED_FILES),\
+ mkdir -p $(sort $(dir $(UNPACKED_DESTFILES))) && \
+ $(call gb_UnpackedTarball__copy_files,$(UNPACKED_FILES),$(UNPACKED_DESTFILES)) && \
+ ) \
+ $(foreach file,$(UNPACKED_FIX_EOL),$(call gb_UnpackedTarball_CONVERTTOUNIX,$(file)) && ) \
+ $(if $(UNPACKED_PATCHES),\
+ for p in $(UNPACKED_PATCHES); do \
+ pl=$(UNPACKED_PATCHLEVEL); \
+ s=$${p##*.}; case "$$s" in [0-9]$(CLOSE_PAREN) pl="$$s"; ;; esac ; \
+ $(GNUPATCH) $(UNPACKED_PATCHFLAGS) -f -s "-p$$pl" --fuzz=0 < "$$p"; \
+ if test "$$?" -ne 0; then echo "Patch FAILED: $$p"; exit 1; fi;\
+ done && \
+ ) \
+ $(foreach file,$(UNPACKED_FIX_EOL),$(call gb_UnpackedTarball_CONVERTTODOS,$(file)) && ) \
+ $(foreach confdir,$(UNPACKED_CONFIG_DIRS),\
+ cp -f $(SRCDIR)/config.guess $(SRCDIR)/config.sub $(confdir) && \
+ ) \
+ $(if $(UNPACKED_POST_ACTION),\
+ $(UNPACKED_POST_ACTION) && \
+ ) \
+ $(if $(gb_KEEP_PRISTINE), \
+ rm -fr $(call gb_UnpackedTarball_get_pristine_dir,$(2)) && \
+ cp -r $(call gb_UnpackedTarball_get_dir,$(2)) $(call gb_UnpackedTarball_get_pristine_dir,$(2)) && \
+ ) \
+ touch $(1) \
+ )\
+ ) || \
+ ( \
+ touch $(call gb_UnpackedTarball_get_preparation_target,$(2)) && \
+ exit 1 \
+ )
+)
+endef
+
+$(dir $(call gb_UnpackedTarball_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(call gb_UnpackedTarball_get_preparation_target,%) :
+ touch $@
+
+$(call gb_UnpackedTarball_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),PAT,2)
+ $(call gb_Trace_StartRange,$*,PAT)
+ $(call gb_UnpackedTarball__command,$@,$*,$(call gb_UnpackedTarball_get_dir,$*))
+ $(call gb_Trace_EndRange,$*,PAT)
+
+$(call gb_UnpackedTarball_get_final_target,%) :
+ touch $@
+
+.PHONY : $(call gb_UnpackedTarball_get_clean_target,%)
+$(call gb_UnpackedTarball_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),PAT,2)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -rf \
+ $(call gb_UnpackedTarball_get_final_target,$*) \
+ $(call gb_UnpackedTarball_get_target,$*) \
+ $(call gb_UnpackedTarball_get_preparation_target,$*) \
+ $(call gb_UnpackedTarball_get_dir,$*) \
+ $(call gb_UnpackedTarball_get_pristine_dir,$*) \
+ )
+
+# Initialize unpacked tarball
+define gb_UnpackedTarball_UnpackedTarball_internal
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_DESTFILES :=
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_FILES :=
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_FIX_EOL :=
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_PATCHES :=
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_PATCHLEVEL := $(gb_UnpackedTarball_PATCHLEVEL_DEFAULT)
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_PATCHFLAGS :=
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_POST_ACTION :=
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_PRE_ACTION :=
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_CONFIG_DIRS :=
+
+$(call gb_UnpackedTarball_get_preparation_target,$(1)) : $(gb_Module_CURRENTMAKEFILE)
+$(call gb_UnpackedTarball_get_preparation_target,$(1)) :| $(dir $(call gb_UnpackedTarball_get_target,$(1))).dir
+$(call gb_UnpackedTarball_get_target,$(1)) : $(call gb_UnpackedTarball_get_preparation_target,$(1))
+$(call gb_UnpackedTarball_get_target,$(1)) :| $(dir $(call gb_UnpackedTarball_get_target,$(1))).dir
+$(call gb_UnpackedTarball_get_final_target,$(1)) : $(call gb_UnpackedTarball_get_target,$(1))
+
+private gb_UnpackedTarball_PATTERN_RULES_$(1) :=
+
+endef
+
+# Define a new unpacked tarball
+define gb_UnpackedTarball_UnpackedTarball
+$(call gb_UnpackedTarball_UnpackedTarball_internal,$(1))
+
+$$(eval $$(call gb_Module_register_target,$(call gb_UnpackedTarball_get_final_target,$(1)),$(call gb_UnpackedTarball_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),UnpackedTarball,$(call gb_UnpackedTarball_get_final_target,$(1)))
+
+endef
+
+# Convert line ending from dos to unix style for selected files
+#
+# This is done before applying patches, because patches expect unix
+# style line ending, and the files are converted back after that. The
+# files are relative to the unpacked path.
+#
+# gb_UnpackedTarball_fix_end_of_line unpacked file(s)
+define gb_UnpackedTarball_fix_end_of_line
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_FIX_EOL += $(addprefix $(call gb_UnpackedTarball_get_dir,$(1))/,$(2))
+
+endef
+
+
+# Internal version of set_tarball, mostly to avoid repeated invocation of $(shell
+define gb_UnpackedTarball_set_tarball_internal
+$(call gb_UnpackedTarget_UnpackedTarget,$(2),$(call gb_UnpackedTarball_get_dir,$(1)),$(3),$(4))
+$(call gb_UnpackedTarball_get_target,$(1)) : $(call gb_UnpackedTarget_get_target,$(2))
+$(call gb_UnpackedTarball_get_clean_target,$(1)) : $(call gb_UnpackedTarget_get_clean_target,$(2))
+$(call gb_UnpackedTarget_get_target,$(2)) : $(call gb_UnpackedTarball_get_preparation_target,$(1))
+$(if $(findstring in,$(5)),
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_IS_BIN_TARBALL := YES
+$(call gb_ExternalProject_get_state_target,$(1),%) : UNPACKED_IS_BIN_TARBALL := YES)
+$(if $(findstring out,$(5)),$(call gb_Module_get_target,$(4)) : $(TARFILE_LOCATION)/$(6)
+$(TARFILE_LOCATION)/$(6) : $(call gb_Module_get_nonl10n_target,$(4))
+ $$(call gb_Output_announce,$(6),$(true),PKB,3)
+ $$(call gb_Trace_StartRange,$(6),PKB)
+ if test ! -f "$$@" ; then cd $(call gb_UnpackedTarball_get_dir,) && $(GNUTAR) -czf "$$@" $(1)/ || $(GNUTAR) -czf "$$@" $(1)/ ; else touch "$$@" ; fi
+ $$(call gb_Trace_EndRange,$(6),PKB)
+)
+
+endef
+
+# Set tarball name
+#
+# gb_UnpackedTarball_set_tarball unpacked tarball-name
+define gb_UnpackedTarball_set_tarball
+$(if $(USE_LIBRARY_BIN_TAR),
+$(if $(4),
+$(if $(shell "$(SRCDIR)/solenv/bin/bin_library_info.sh" -l "$(gb_UnpackedTarget_TARFILE_LOCATION)" -o "$(4)" -b "$(BUILDDIR)" -s "$(SRCDIR)" -t "$(2)" -m verify -p "$(OS)_$(CPUNAME)"),
+$(call gb_UnpackedTarball_set_tarball_internal,$(1),$(shell "$(SRCDIR)/solenv/bin/bin_library_info.sh" -l "$(gb_UnpackedTarget_TARFILE_LOCATION)" -o "$(4)" -b "$(BUILDDIR)" -s "$(SRCDIR)" -t "$(2)" -m verify -p "$(OS)_$(CPUNAME)"),$(3),$(4),in),\
+$(call gb_UnpackedTarball_set_tarball_internal,$(1),$(2),$(3),$(4),out,$(shell "$(SRCDIR)/solenv/bin/bin_library_info.sh" -l "$(gb_UnpackedTarget_TARFILE_LOCATION)" -o "$(4)" -b "$(BUILDDIR)" -s "$(SRCDIR)" -t "$(2)" -m name -p "$(OS)_$(CPUNAME)")))
+,
+$(call gb_UnpackedTarball_set_tarball_internal,$(1),$(2),$(3),$(4),)
+)
+,
+$(call gb_UnpackedTarball_set_tarball_internal,$(1),$(2),$(3),$(4),)
+)
+
+endef
+
+# Set patch level to be used for all patches
+#
+# The default value is 3 to be able to work with current dmake patches.
+#
+# gb_UnpackedTarball_set_patchlevel unpacked level
+define gb_UnpackedTarball_set_patchlevel
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_PATCHLEVEL := $(2)
+
+endef
+
+# Add patch flags to be passed to patch for all patches cf. fdo#66826
+#
+# gb_UnpackedTarball_set_patchlevel unpacked level
+define gb_UnpackedTarball_set_patchflags
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_PATCHFLAGS := $(2)
+
+endef
+
+# Add a patch to be applied on the unpacked files
+#
+# gb_UnpackedTarball_add_patch unpacked patch
+define gb_UnpackedTarball_add_patch
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_PATCHES += $(SRCDIR)/$(2)
+$(call gb_UnpackedTarball_get_preparation_target,$(1)) : $(SRCDIR)/$(2)
+
+endef
+
+# Add several patches at once
+#
+# gb_UnpackedTarball_add_patches unpacked patch(es)
+define gb_UnpackedTarball_add_patches
+$(foreach patch,$(2),$(call gb_UnpackedTarball_add_patch,$(1),$(patch)))
+
+endef
+
+# Add a file from source dir to the unpacked dir
+#
+# This function should not be used for overwriting existing files--use a
+# patch for that purpose.
+#
+# gb_UnpackedTarball_add_file unpacked destfile file
+define gb_UnpackedTarball_add_file
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_FILES += $(SRCDIR)/$(3)
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_DESTFILES += $(call gb_UnpackedTarball_get_dir,$(1))/$(2)
+$(call gb_UnpackedTarball_get_preparation_target,$(1)) : $(SRCDIR)/$(3)
+
+endef
+
+# Add several files(s) from source dir to the unpacked dir
+#
+# The files are added into the specified subdir.
+#
+# gb_UnpackedTarball_add_files unpacked subdir file(s)
+define gb_UnpackedTarball_add_files
+$(foreach file,$(3),$(call gb_UnpackedTarball_add_file,$(1),$(2)/$(notdir $(file)),$(file)))
+
+endef
+
+# Set arbitrary shell command to be run during unpack
+#
+# The command is run at the very beginning, in freshly unpacked tarball.
+# The command is run in the unpacked directory. If more than one command
+# is used, care should be taken that the whole command fails if either
+# of the sub-commands fails.
+#
+# gb_UnpackedTarball_set_pre_action unpacked shell-command
+define gb_UnpackedTarball_set_pre_action
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_PRE_ACTION := $(strip $(2))
+
+endef
+
+# Set arbitrary shell command to be run during unpack
+#
+# The command is run at the very end: after patching, C++ extension
+# mangling and copying additional files in. The command is run in the
+# unpacked directory. If more than one command is used, care should be
+# taken that the whole command fails if either of the sub-commands
+# fails.
+#
+# NOTE: This is a bit hackish, but it is the easiest way to move files
+# around or delete files (typically because the file causes build
+# problems in the original location, c.f. clucene). This is doable by
+# using -E with patch (we use GNU patch anyway), but it would mean an
+# additional patch to maintain...
+#
+# gb_UnpackedTarball_set_post_action unpacked shell-command
+define gb_UnpackedTarball_set_post_action
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_POST_ACTION := $(strip $(2))
+
+endef
+
+define gb_UnpackedTarbal__make_pattern_rule
+$(call gb_UnpackedTarball_get_dir,$(1))/%$(2) :
+ $$(if $$(wildcard $$@),,$$(call gb_Output_error,file $$@ does not exist in the tarball))
+ $$(if $$(UNPACKED_MODE),chmod $$(UNPACKED_MODE) $$@ &&) \
+ touch $$@
+
+$(eval gb_UnpackedTarball_PATTERN_RULES_$(1) += $(2))
+
+endef
+
+define gb_UnpackedTarbal__ensure_pattern_rule
+$(if $(filter $(2),$(gb_UnpackedTarball_PATTERN_RULES_$(1))),,$(call gb_UnpackedTarbal__make_pattern_rule,$(1),$(2)))
+
+endef
+
+define gb_UnpackedTarbal__make_file_rule
+$(call gb_UnpackedTarball_get_dir,$(1))/$(2) :
+ $$(if $$(wildcard $$@),,$$(call gb_Output_error,file $$@ does not exist in the tarball))
+ $$(if $$(UNPACKED_MODE),chmod $$(UNPACKED_MODE) $$@ &&) \
+ touch $$@
+
+endef
+
+# Mark a source file to be used outside of this module
+#
+# This results in the timestamp of the file being updated, so a possible
+# change is recognized properly by other files depending on it. The
+# update is run after possible post action.
+#
+# See description of class ExternalPackage for more information.
+#
+# gb_UnpackedTarball_mark_output_file unpacked file
+define gb_UnpackedTarball_mark_output_file
+$(call gb_UnpackedTarball_get_final_target,$(1)) : $(call gb_UnpackedTarball_get_dir,$(1))/$(2)
+$(call gb_UnpackedTarball_get_dir,$(1))/$(2) : $(call gb_UnpackedTarball_get_target,$(1))
+$(call gb_UnpackedTarball_get_dir,$(1))/$(2) : UNPACKED_MODE := 644
+$(if $(suffix $(2)),\
+ $(call gb_UnpackedTarbal__ensure_pattern_rule,$(1),$(suffix $(2))),\
+ $(call gb_UnpackedTarbal__make_file_rule,$(1),$(2)) \
+)
+
+endef
+
+# Mark several source files to be used outside of this module
+#
+# gb_UnpackedTarball_mark_output_files unpacked file(s)
+define gb_UnpackedTarball_mark_output_files
+$(foreach file,$(2),$(call gb_UnpackedTarball_mark_output_file,$(1),$(file)))
+
+endef
+
+# Replace project's config.{guess,sub} files by internal copies
+#
+# This is useful if the project's config files are outdated and don't
+# allow build on some new arch. The internal copies are located at
+# gb_UnpackedTarball_CONFIGDIR.
+#
+# If the configs are placed somewhere else than in the top-level dir of
+# the project, pass the (relative) dir as second argument. (It can even
+# be a list of dirs, if the project contains multiple subprojects, each
+# with its own configure.)
+#
+# gb_UnpackedTarball_update_autoconf_configs unpacked dirs(s)?
+define gb_UnpackedTarball_update_autoconf_configs
+$(call gb_UnpackedTarball_get_target,$(1)) : UNPACKED_CONFIG_DIRS += $(if $(strip $(2)),$(2),.)
+
+endef
+
+# force the rebuild of an external target
+# this only works when running as partial build.
+#
+%.rebuild :
+ if [ -f $(call gb_UnpackedTarball_get_target,$*) ] ; then \
+ touch $(call gb_UnpackedTarball_get_target,$*) ; \
+ $(MAKE) ;\
+ fi
+
+%.genpatch :
+ if [ -d $(call gb_UnpackedTarball_get_dir,$*) -a -d $(call gb_UnpackedTarball_get_pristine_dir,$*) ] ; then \
+ ( \
+ patch_file=$$(pwd)/$*.new.patch.1; \
+ cd $(call gb_UnpackedTarball_get_dir,) ; \
+ diff -ur $*.org $* > $$patch_file; \
+ echo "Patch $$patch_file generated" ; \
+ ); \
+ else \
+ echo "Error: No pristine tarball available for $*" 1>&2 ; \
+ fi
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/WinResTarget.mk b/solenv/gbuild/WinResTarget.mk
new file mode 100644
index 000000000..7cc98adc5
--- /dev/null
+++ b/solenv/gbuild/WinResTarget.mk
@@ -0,0 +1,123 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# WinResTarget class
+
+gb_WinResTarget_DEFAULTDEFS := $(gb_RCDEFS)
+
+define gb_WinResTarget_WinResTarget
+$(call gb_WinResTarget_WinResTarget_init,$(1))
+$$(eval $$(call gb_Module_register_target,$(call gb_WinResTarget_get_target,$(1)),$(call gb_WinResTarget_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),WinResTarget)
+
+endef
+
+define gb_WinResTarget_WinResTarget_init
+$(call gb_WinResTarget_get_target,$(1)) : DEFS := $(gb_WinResTarget_DEFAULTDEFS)
+$(call gb_WinResTarget_get_target,$(1)) : FLAGS := $(gb_RCFLAGS)
+$(call gb_WinResTarget_get_target,$(1)) : INCLUDE := -I$(SRCDIR)/include $(subst -isystem,-I,$(SOLARINC)) -I$(BUILDDIR)/config_$(gb_Side)
+$(call gb_WinResTarget_get_clean_target,$(1)) : RCFILE :=
+$(call gb_WinResTarget_get_target,$(1)) : RCFILE :=
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_WinResTarget_get_dep_target,$(1)) : DEFS := $$(gb_WinResTarget_DEFAULTDEFS)
+$(call gb_WinResTarget_get_dep_target,$(1)) : FLAGS := $$(gb_RCFLAGS)
+$(call gb_WinResTarget_get_dep_target,$(1)) : INCLUDE := $$(gb_WinResTarget_INCLUDE) -I$(BUILDDIR)/config_$(gb_Side)
+$(call gb_WinResTarget_get_dep_target,$(1)) : RCFILE :=
+
+-include $(call gb_WinResTarget_get_dep_target,$(1))
+endif
+
+endef
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_WinResTarget_get_dep_target,%) : $(gb_WinResTarget__command_target)
+ $(call gb_WinResTarget__command_dep,$@,$*,$(call gb_WinResTarget_get_target,$*))
+endif
+
+
+$(call gb_WinResTarget_get_target,%) :
+ $(call gb_WinResTarget__command,$@,$*,$<)
+
+$(call gb_WinResTarget_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),RC ,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ rm -f $(call gb_WinResTarget_get_target,$*) \
+ $(call gb_WinResTarget_get_dep_target,$*))
+
+define gb_WinResTarget_add_defs
+$(call gb_WinResTarget_get_target,$(1)) : DEFS += $(2)
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_WinResTarget_get_dep_target,$(1)) : DEFS += $(2)
+endif
+
+endef
+
+define gb_WinResTarget__add_include
+$(call gb_WinResTarget_get_target,$(1)) : INCLUDE += -I$(2)
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_WinResTarget_get_dep_target,$(1)) : INCLUDE += -I$(2)
+endif
+
+endef
+
+define gb_WinResTarget_set_include
+$(call gb_WinResTarget_get_target,$(1)) : INCLUDE := $(2)
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_WinResTarget_get_dep_target,$(1)) : INCLUDE := $(2)
+endif
+
+endef
+
+define gb_WinResTarget_set_rcfile
+$(call gb_WinResTarget_get_clean_target,$(1)) : RCFILE := $(SRCDIR)/$(strip $(2)).rc
+$(call gb_WinResTarget_get_target,$(1)) : RCFILE := $(SRCDIR)/$(strip $(2)).rc
+$(call gb_WinResTarget_get_target,$(1)) : $(SRCDIR)/$(strip $(2)).rc
+
+ifeq ($(gb_FULLDEPS),$(true))
+$(call gb_WinResTarget_get_dep_target,$(1)) : RCFILE := $(SRCDIR)/$(strip $(2)).rc
+endif
+
+endef
+
+define gb_WinResTarget_add_dependency
+$(call gb_WinResTarget_get_target,$(1)) : $(SRCDIR)/$(strip $(2))
+
+endef
+
+define gb_WinResTarget_add_dependencies
+$(foreach dep,$(2),$(call gb_WinResTarget_add_dependency,$(1),$(dep)))
+
+endef
+
+define gb_WinResTarget__use_custom_headers
+$(call gb_WinResTarget_get_target,$(1)) : $(call gb_CustomTarget_get_target,$(2))
+$(call gb_WinResTarget__add_include,$(1),$(call gb_CustomTarget_get_workdir,$(2)))
+
+endef
+
+define gb_WinResTarget_use_custom_headers
+$(foreach customtarget,$(2),$(call gb_WinResTarget__use_custom_headers,$(1),$(customtarget)))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/Zip.mk b/solenv/gbuild/Zip.mk
new file mode 100644
index 000000000..b2debba77
--- /dev/null
+++ b/solenv/gbuild/Zip.mk
@@ -0,0 +1,154 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# Zip class
+
+gb_Zip__get_preparation_target = $(WORKDIR)/Zip/$(1).prepare
+
+gb_Zip_ZIPCOMMAND := zip $(if $(findstring s,$(MAKEFLAGS)),-q)
+
+# remove zip file in workdir and outdir
+$(call gb_Zip_get_clean_target,%) :
+ $(call gb_Output_announce,$*,$(false),ZIP,3)
+ $(call gb_Helper_abbreviate_dirs,\
+ $(if $(CLEAR_LOCATION),rm -rf $(gb_Package_Location_$*) &&) \
+ $(if $(INSTALL_NAME),rm -f $(INSTALL_NAME) &&) \
+ rm -f $(call gb_Zip_get_target,$*) && \
+ rm -f $(call gb_Zip__get_preparation_target,$*))
+
+$(dir $(call gb_Zip_get_target,%)).dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+$(dir $(call gb_Zip_get_target,%))%/.dir :
+ $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
+
+# rule to create zip package in workdir
+# --filesync makes sure that all files in the zip package will be removed that no longer are in $(FILES)
+# if there are no files, zip fails; copy empty zip file to target in that case
+$(call gb_Zip_get_target,%) :
+ $(call gb_Output_announce,$*,$(true),ZIP,3)
+ $(call gb_Trace_StartRange,$*,ZIP)
+ $(call gb_Helper_abbreviate_dirs,\
+ $(if $(FILES),\
+ RESPONSEFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),500,\
+ $(FILES)) && \
+ cd $(LOCATION) && \
+ cat $${RESPONSEFILE} | tr "[:space:]" "\n" | \
+ $(gb_Zip_ZIPCOMMAND) -@rX --filesync --must-match \
+ $(call gb_Zip_get_target,$*) && \
+ rm -f $${RESPONSEFILE} && \
+ touch $@\
+ , cp $(SRCDIR)/solenv/gbuild/empty.zip $@)\
+ $(if $(INSTALL_NAME),&& cp $(call gb_Zip_get_target,$*) $(INSTALL_NAME)) \
+ )
+ $(call gb_Trace_EndRange,$*,ZIP)
+
+# the preparation target is here to ensure proper ordering of actions in cases
+# when we want to, e.g., create a zip from files created by a custom target
+$(call gb_Zip__get_preparation_target,%) :
+ touch $@
+
+# clear file list, set location (zipping uses relative paths)
+# register target and clean target
+# add deliverable
+# add dependency for outdir target to workdir target (pattern rule for delivery is in Package.mk)
+# the zip package target requires that all added files have a common root directory (package location)
+# names of added files are relative to it; the zip will store them with their complete relative path name
+# the location can't be stored in a scoped variable as it is needed in the add_file macro (see rule above)
+define gb_Zip_Zip_internal_nodeliver
+$(call gb_Zip_get_target,$(1)) : FILES :=
+$(call gb_Zip_get_target,$(1)) : INSTALL_NAME :=
+$(call gb_Zip_get_target,$(1)) : LOCATION := $(2)
+$(call gb_Zip_get_target,$(1)) :| $(dir $(call gb_Zip_get_target,$(1))).dir
+$(call gb_Zip__get_preparation_target,$(1)) :| $(dir $(call gb_Zip__get_preparation_target,$(1))).dir
+$(call gb_Zip_get_clean_target,$(1)) : CLEAR_LOCATION :=
+$(call gb_Zip_get_clean_target,$(1)) : INSTALL_NAME :=
+$(eval gb_Package_Location_$(1) := $(2))
+
+endef
+
+define gb_Zip_Zip_internal
+$(call gb_Zip_Zip_internal_nodeliver,$(1),$(2))
+
+endef
+
+# depend on makefile to enforce a rebuild if files are removed from the zip
+define gb_Zip_Zip
+$(call gb_Zip_Zip_internal,$(1),$(2))
+$(call gb_Zip_get_target,$(1)) : $(gb_Module_CURRENTMAKEFILE)
+
+$(eval $(call gb_Module_register_target,$(call gb_Zip_get_target,$(1)),$(call gb_Zip_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),Zip,$(call gb_Zip_get_target,$(1)))
+
+endef
+
+# adding a file creates a dependency to it
+# the full path name of the file needs access to the package location
+# as scoped variables only exist in rules, we use a postfixed name to refer to the location
+#
+# if package location is in $(WORKDIR) we can specify third parameter and copy file from different place
+# then we need also remove the location on make clean
+define gb_Zip_add_file
+$(call gb_Zip_get_target,$(1)) : FILES += $(2)
+$(call gb_Zip_get_target,$(1)) : $(gb_Package_Location_$(1))/$(2)
+$(gb_Package_Location_$(1))/$(2) :| $(call gb_Zip__get_preparation_target,$(1))
+ifneq ($(3),)
+$(call gb_Zip_get_clean_target,$(1)) : CLEAR_LOCATION := TRUE
+$(gb_Package_Location_$(1))/$(2) : $(3)
+ mkdir -p $$(dir $$@)
+ cp -f $$< $$@
+
+endif
+
+endef
+
+# add additional dependency that must exist before the archive can be created
+define gb_Zip_add_dependency
+$(call gb_Zip__get_preparation_target,$(1)) :| $(2)
+
+endef
+
+define gb_Zip_add_files
+$(foreach file,$(2),$(call gb_Zip_add_file,$(1),$(file)))
+endef
+
+define gb_Zip_add_dependencies
+$(foreach dependency,$(2),$(call gb_Zip_add_dependency,$(1),$(dependency)))
+
+endef
+
+define gb_Zip_add_commandoptions
+$(call gb_Zip_get_target,$(1)) : gb_Zip_ZIPCOMMAND += $(2)
+
+endef
+
+define gb_Zip_set_install_name
+$(call gb_Zip_get_target,$(1)) : INSTALL_NAME := $(2)
+$(call gb_Zip_get_target,$(1)) :| $(dir $(2)).dir
+$(call gb_Zip_get_clean_target,$(1)) : INSTALL_NAME := $(2)
+
+endef
+
+define gb_Zip_use_unpacked
+$(call gb_Zip__get_preparation_target,$(1)) \
+ :| $(call gb_UnpackedTarball_get_final_target,$(2))
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/empty.zip b/solenv/gbuild/empty.zip
new file mode 100644
index 000000000..15cb0ecb3
--- /dev/null
+++ b/solenv/gbuild/empty.zip
Binary files differ
diff --git a/solenv/gbuild/extensions/post_Counters.mk b/solenv/gbuild/extensions/post_Counters.mk
new file mode 100644
index 000000000..8773844a5
--- /dev/null
+++ b/solenv/gbuild/extensions/post_Counters.mk
@@ -0,0 +1,22 @@
+# -*- 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/.
+#
+
+ifneq ($(filter countoutdated,$(MAKECMDGOALS)),)
+
+gb_Output_announce=
+
+ifneq ($(strip $(filter-out countoutdated,$(MAKECMDGOALS))),)
+countoutdated: $(filter-out countoutdated,$(MAKECMDGOALS))
+else
+countoutdated: $(.DEFAULT_GOAL)
+endif
+
+endif
+
+# vim: set noet ts=4 sw=4:
diff --git a/solenv/gbuild/extensions/post_Fuzzers.mk b/solenv/gbuild/extensions/post_Fuzzers.mk
new file mode 100644
index 000000000..e26e65935
--- /dev/null
+++ b/solenv/gbuild/extensions/post_Fuzzers.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/.
+#
+
+# chain-link all fuzzer binaries
+$(foreach fuzzer,$(gb_Fuzzers_KNOWN), \
+ $(eval gb_Fuzzers_KNOWN = $(filter-out $(fuzzer),$(gb_Fuzzers_KNOWN))) \
+ $(if $(firstword $(gb_Fuzzers_KNOWN)), \
+ $(eval $(call gb_Executable_get_linktarget_target,$(firstword $(gb_Fuzzers_KNOWN))) : \
+ $(call gb_Executable_get_linktarget_target,$(fuzzer)))))
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/extensions/post_GbuildToJson.mk b/solenv/gbuild/extensions/post_GbuildToJson.mk
new file mode 100644
index 000000000..f1707a488
--- /dev/null
+++ b/solenv/gbuild/extensions/post_GbuildToJson.mk
@@ -0,0 +1,202 @@
+# -*- 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/.
+#
+
+
+# Outstanding work:
+#
+# fill files names in:
+# --ASMOBJECTS
+# --GENCOBJECTS
+# --YACCOBJECTS
+# --LEXOBJECTS
+# --JAVAOBJECTS
+# --PYTHONOBJECTS
+#
+# Add black listed modules a json files (--DENYLIST)
+#
+# Reduce number of denylisted modules
+
+ifneq ($(filter gbuildtojson,$(MAKECMDGOALS)),)
+
+# possibly recurse to ensure gbuildtojson was build before running the modded make
+gb_GbuildToJson_prep := $(shell $(MAKE) -f $(SRCDIR)/solenv/Makefile Executable_gbuildtojson)
+gb_FULLDEPS:=
+
+gbuildtojson:
+ @true
+
+
+gb_GbuildToJson_PHONY := $(WORKDIR)/GBUILDTOJSONPHONY
+.PHONY : $(gb_GbuildToJson_PHONY)
+$(gb_GbuildToJson_PHONY):
+ @true
+
+
+
+define gb_LinkTarget__command
+mkdir -p $(WORKDIR)/GbuildToJson/$(dir $(2))
+mkdir -p $(WORKDIR)/LinkTarget/$(dir $(2))
+$(if $(GBUILDTOJSON_LD_LIBRARY_PATH),LD_LIBRARY_PATH=$(GBUILDTOJSON_LD_LIBRARY_PATH)) \
+$(call gb_Executable_get_command,gbuildtojson) \
+--makefile=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(T_MAKEFILE)) \
+--linktarget=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(2)) \
+--ilibtarget=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(ILIBTARGET)) \
+--cxxobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(CXXOBJECTS)) \
+--yaccobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(YACCOBJECTS)) \
+--objcobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(OBJCOBJECTS)) \
+--objcxxobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(OBJCXXOBJECTS)) \
+--cxxclrobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(CXXCLROBJECTS)) \
+--asmobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(ASMOBJECTS)) \
+--lexobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(LEXOBJECTS)) \
+--gencobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(GENCOBJECTS)) \
+--gencxxobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(GENCXXOBJECTS)) \
+--gencxxclrobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(GENCXXCLROBJECTS)) \
+--cobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(COBJECTS)) \
+--javaobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(JAVAOBJECTS)) \
+--pythonobjects=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(PYTHONOBJECTS)) \
+--cflags=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(T_CFLAGS)) \
+--cflagsappend=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(T_CFLAGS_APPEND)) \
+--cxxflags=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(T_CXXFLAGS)) \
+--cxxflagsappend=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(T_CXXFLAGS_APPEND)) \
+--objcflags=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(T_OBJCFLAGS)) \
+--objcflagsappend=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(T_OBJCFLAGS_APPEND)) \
+--objcxxflags=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(T_OBJCXXFLAGS)) \
+--objcxxflagsappend=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(T_OBJCXXFLAGS_APPEND)) \
+--cxxclrflags=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(T_CXXCLRFLAGS)) \
+--cxxclrflagsappend=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(T_CXXCLRFLAGS_APPEND)) \
+--defs=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(DEFS)) \
+--include=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(INCLUDE)) \
+--linked_libs=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(LINKED_LIBS)) \
+--linked_static_libs=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(LINKED_STATIC_LIBS)) \
+> $(WORKDIR)/GbuildToJson/$(2)
+endef
+
+define gb_Postprocess_register_target
+gbuildtojson : $(call gb_LinkTarget_get_target,$(call gb_$(2)_get_linktarget,$(3)))
+
+$(call gb_LinkTarget_get_target,$(call gb_$(2)_get_linktarget,$(3))): $(gb_Helper_MISCDUMMY) $(gb_GbuildToJson_PHONY)
+$(call gb_LinkTarget_get_target,$(call gb_$(2)_get_linktarget,$(3))): T_MAKEFILE := $(lastword $(MAKEFILE_LIST))
+endef
+
+define gb_CppunitTest_register_target
+gbuildtojson : $(call gb_LinkTarget_get_target,$(2))
+
+$(call gb_LinkTarget_get_target,$(2)): $(gb_Helper_MISCDUMMY) $(gb_GbuildToJson_PHONY)
+$(call gb_LinkTarget_get_target,$(2)): T_MAKEFILE := $(lastword $(MAKEFILE_LIST))
+endef
+
+gb_LinkTarget_use_static_libraries =
+gb_UnoApiHeadersTarget_get_target = $(gb_Helper_MISCDUMMY)
+gb_UnpackedTarball_get_final_target = $(gb_Helper_MISCDUMMY)
+gb_LinkTarget__get_headers_check =
+define gb_LinkTarget_add_cobject
+$(call gb_LinkTarget_get_target,$(1)) : COBJECTS += $(2)
+
+endef
+define gb_LinkTarget_add_cxxobject_internal
+$(call gb_LinkTarget_get_target,$(1)) : CXXOBJECTS += $(2)
+
+endef
+define gb_LinkTarget_add_generated_c_object
+$(call gb_LinkTarget_get_target,$(1)) : GENCOBJECTS += $(2)
+
+endef
+define gb_LinkTarget_add_generated_cxx_object_internal
+$(call gb_LinkTarget_get_target,$(1)) : GENCXXOBJECTS += $(2)
+
+endef
+define gb_LinkTarget_add_generated_cxxclrobject
+$(call gb_LinkTarget_get_target,$(1)) : GENCXXCLROBJECTS += $(2)
+
+endef
+define gb_LinkTarget_add_objcobject
+$(call gb_LinkTarget_get_target,$(1)) : OBJCOBJECTS += $(2)
+
+endef
+define gb_LinkTarget_add_objcxxobject
+$(call gb_LinkTarget_get_target,$(1)) : OBJCXXOBJECTS += $(2)
+
+endef
+define gb_LinkTarget_add_cxxclrobject
+$(call gb_LinkTarget_get_target,$(1)) : CXXCLROBJECTS += $(2)
+
+endef
+define gb_LinkTarget_add_scanners
+$(call gb_LinkTarget_get_target,$(1)) : LEXOBJECTS += $(2)
+
+endef
+define gb_LinkTarget_add_grammars
+$(call gb_LinkTarget_get_target,$(1)) : YACCOBJECTS += $(2)
+
+endef
+gb_LinkTarget_use_package =
+gb_LinkTarget_use_generated_package =
+gb_LinkTarget_add_sdi_headers =
+gb_LinkTarget_use_external_project =
+gb_LinkTarget__check_srcdir_paths =
+gb_LinkTarget__command_objectlist = @true
+gb_WinResTarget_WinResTarget_init =
+gb_WinResTarget_set_rcfile =
+gb_WinResTarget_add_defs =
+gb_LinkTarget_set_nativeres =
+gb_LinkTarget_add_nativeres =
+gb_Library_set_componentfile =
+gb_Library_add_componentimpl =
+
+#$(call gb_Library_get_exports_target,%):
+$(WORKDIR)/LinkTarget/Library/%.exports:
+ @true
+
+define gb_LinkTarget__use_custom_headers
+$(call gb_LinkTarget__add_include,$(1),$(call gb_CustomTarget_get_workdir,$(2)))
+
+endef
+
+
+define gb_Module__add_target_impl
+$(call gb_Module__read_targetfile,$(1),$(2),target)
+
+$(call gb_Module_get_nonl10n_target,$(1)) : $(3)
+
+endef
+
+define gb_Module__add_check_target_impl
+$(call gb_Module__read_targetfile,$(1),$(2),check target)
+
+$(call gb_Module_get_check_target,$(1)) : $(3)
+
+endef
+
+define gb_Module_add_target
+$(if $(filter Library_% Executable_%,$(2)),$(call gb_Module__add_target_impl,$(1),$(2),$$(gb_Module_CURRENTTARGET)))
+endef
+
+define gb_Module_add_check_target
+$(if $(filter CppunitTest_% Library_%,$(2)),$(call gb_Module__add_check_target_impl,$(1),$(2),$$(gb_Module_CURRENTTARGET)))
+endef
+
+gb_Module_add_l10n_target =
+
+gb_GbuildToJson_DENYLISTEDMODULES := cli_ure jurt external
+
+define gb_Module__add_moduledir_impl
+include $(patsubst $(1):%,%,$(filter $(1):%,$(gb_Module_MODULELOCATIONS)))/$(2)/Module_$(notdir $(2)).mk
+$(call gb_Module_get_target,$(1)) : $$(firstword $$(gb_Module_TARGETSTACK))
+gb_Module_TARGETSTACK := $$(wordlist 2,$$(words $$(gb_Module_TARGETSTACK)),$$(gb_Module_TARGETSTACK))
+
+endef
+
+define gb_Module_add_moduledir
+$(if $(filter $(gb_GbuildToJson_DENYLISTEDMODULES),$(2)),,$(call gb_Module__add_moduledir_impl,$(1),$(2)))
+
+endef
+
+endif
+
+# vim: set noet ts=4 sw=4:
diff --git a/solenv/gbuild/extensions/post_PackageInfo.mk b/solenv/gbuild/extensions/post_PackageInfo.mk
new file mode 100644
index 000000000..331eeb89e
--- /dev/null
+++ b/solenv/gbuild/extensions/post_PackageInfo.mk
@@ -0,0 +1,116 @@
+# -*- 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/.
+#
+
+gb_PackageInfo_InstallModules := \
+ base \
+ calc \
+ graphicsfilter \
+ tde \
+ impress \
+ onlineupdate \
+ gnome \
+ kde \
+ math \
+ ooo \
+ writer \
+ ure \
+ activexbinarytable \
+ ooobinarytable \
+ winexplorerextbinarytable \
+
+define gb_PackageInfo_emit_binaries_command
+@touch $(foreach suf,executables libraries files,$(gb_PackageInfo_get_target)/$(1).$(suf))
+@$(foreach executable,$(gb_Executable_MODULE_$(1)),echo "$(patsubst $(INSTDIR)/%,%,$(call gb_Executable_get_target,$(executable)))" >> $(gb_PackageInfo_get_target)/$(1).executables &&) true
+@$(foreach library,$(gb_SdkLinkLibrary_MODULE_$(1)),echo "sdk/lib/$(call gb_Library_get_linktarget,$(library))" >> $(gb_PackageInfo_get_target)/$(1).sdklinklibraries &&) true
+@$(foreach library,$(gb_Library_MODULE_$(1)),echo "$(patsubst $(INSTDIR)/%,%,$(call gb_Library_get_target,$(library)))" >> $(gb_PackageInfo_get_target)/$(1).libraries &&) true
+@$(foreach jar,$(gb_Jar_MODULE_$(1)),echo "$(patsubst $(INSTDIR)/%,%,$(call gb_Jar_get_target,$(jar)))" >> $(gb_PackageInfo_get_target)/$(1).jars &&) true
+@$(foreach pkg,$(gb_Package_MODULE_$(1)),echo "$(call gb_Package_get_target,$(pkg))" >> $(gb_PackageInfo_get_target)/$(1).packages &&) true
+@echo "$(foreach suf,executables libraries files,$(gb_PackageInfo_get_target)/$(1).$(suf)) \\" >> $(WORKDIR)/Dep/packageinfo.d
+
+endef
+
+define gb_PackageInfo_emit_help_for_one_target
+$(foreach suf,cfg db ht idxl/_0.cfs idxl/segments_3 idxl/segments.gen jar key tree,$(if $(wildcard $(INSTDIR)/help/$(1).$(suf)),echo "help/$(1).$(suf)" >> $(2) && )) true
+
+endef
+
+define gb_PackageInfo_emit_help_for_one_lang
+@touch $(foreach suf,executables libraries files,$(gb_PackageInfo_get_target)/help-$(1).$(suf))
+$(foreach target,$(gb_AllLangHelp_ALLTARGETS),$(call gb_PackageInfo_emit_help_for_one_target,$(1)/$(target),$(gb_PackageInfo_get_target)/help-$(1).files))
+$(foreach suf,html css,$(foreach file,$(wildcard $(INSTDIR)/help/$(1)/*.$(suf)),echo "$(patsubst $(INSTDIR)/%,%,$(file))" >> $(gb_PackageInfo_get_target)/help-$(1).files && )) true
+@echo " $(foreach suf,executables libraries files,$(gb_PackageInfo_get_target)/help-$(1).$(suf)) \\" >> $(WORKDIR)/Dep/packageinfo.d
+
+endef
+
+#getting the package files post-hoc with wildcard is not good and should be done better
+define gb_PackageInfo_emit_l10n_for_one_alllangpackage
+@$(foreach file,$(shell ls $(INSTDIR)/$(1)/$(2)),echo "$(1)/$(2)/$(file)" >> $(gb_PackageInfo_get_target)/l10n-$(2).files &&) true
+
+endef
+
+define gb_PackageInfo_emit_l10n_for_one_mo
+@echo "$(patsubst $(INSTDIR)/%,%,$(call gb_MoTarget_get_install_target,$(shell $(SRCDIR)/solenv/bin/localestr $(2))/LC_MESSAGES/$(1)))" >> $(gb_PackageInfo_get_target)/l10n-$(2).files
+
+endef
+
+define gb_PackageInfo_emit_l10n_for_one_configfile
+echo "$(LIBO_SHARE_FOLDER)/registry/$(2)$(1).xcd" >> $(gb_PackageInfo_get_target)/l10n-$(1).files
+
+endef
+
+define gb_PackageInfo_emit_l10n_for_one_lang
+@touch $(foreach suf,executables libraries files,$(gb_PackageInfo_get_target)/l10n-$(1).$(suf))
+$(if $(filter-out qtz en-US,$(1)),$(foreach packagedir,$(patsubst %/,%,$(gb_AllLangPackage_ALLDIRS)),$(call gb_PackageInfo_emit_l10n_for_one_alllangpackage,$(packagedir),$(1))))
+$(if $(filter $(gb_AllLangMoTarget_LANGS),$(1)),$(foreach target,$(gb_AllLangMoTarget_REGISTERED),$(call gb_PackageInfo_emit_l10n_for_one_mo,$(target),$(1))))
+$(if $(filter $(gb_Configuration_LANGS),$(1)),$(foreach configfile,Langpack- res/fcfg_langpack_ res/registry_,$(call gb_PackageInfo_emit_l10n_for_one_configfile,$(1),$(configfile))))
+$(if $(filter $(gb_CJK_LANGS),$(1)),$(foreach configfile,cjk_,$(call gb_PackageInfo_emit_l10n_for_one_configfile,$(1),$(configfile))))
+$(if $(filter $(gb_CTL_LANGS),$(1)),$(foreach configfile,ctl_,$(call gb_PackageInfo_emit_l10n_for_one_configfile,$(1),$(configfile))))
+$(if $(filter $(gb_CTLSEQCHECK_LANGS),$(1)),$(foreach configfile,ctlseqcheck_,$(call gb_PackageInfo_emit_l10n_for_one_configfile,$(1),$(configfile))))
+@echo "$(foreach suf,executables libraries files,$(gb_PackageInfo_get_target)/l10n-$(1).$(suf)) \\" >> $(WORKDIR)/Dep/packageinfo.d
+
+endef
+
+-include $(WORKDIR)/Dep/packageinfo.d
+$(foreach filelist,files executables libraries,$(gb_PackageInfo_get_target)/%.$(filelist)):
+ @rm -rf $(gb_PackageInfo_get_target) $(WORKDIR)/Dep/packageinfo.d && mkdir $(gb_PackageInfo_get_target)
+ $(foreach installmodule,$(gb_PackageInfo_InstallModules),$(call gb_PackageInfo_emit_binaries_command,$(installmodule)))
+ $(foreach helplang,$(gb_HELP_LANGS),$(call gb_PackageInfo_emit_help_for_one_lang,$(helplang)))
+ $(foreach l10nlang,$(if $(strip $(gb_WITH_LANG)),$(gb_WITH_LANG),en-US),$(call gb_PackageInfo_emit_l10n_for_one_lang,$(l10nlang)))
+ @echo "$(gb_PackageInfo_get_target)/packageinfo_all : $(filter-out $(WORKDIR)/Dep/%,$(MAKEFILE_LIST))" >> $(WORKDIR)/Dep/packageinfo.d
+ @touch $(gb_PackageInfo_get_target)/packageinfo_all
+
+$(gb_PackageInfo_get_target)/packageinfo_all:
+ $(MAKE) -f $(firstword $(MAKEFILE_LIST)) $(gb_PackageInfo_get_target)/$(firstword $(gb_PackageInfo_InstallModules)).files
+
+.PHONY : packageinfo
+packageinfo: $(gb_PackageInfo_get_target)/packageinfo_all
+
+install-package-%: $(gb_PackageInfo_get_target)/packageinfo_all
+ for executable in `cat $(gb_PackageInfo_get_target)/$*.executables`; \
+ do \
+ install -D $(INSTDIR)/$${executable} $(INSTALLDIR)/$${executable} ;\
+ done
+ for library in `cat $(gb_PackageInfo_get_target)/$*.sdklinklibraries`; \
+ do \
+ install -D -m644 $(INSTDIR)/$${library} $(INSTALLDIR)/$${library}; \
+ done
+ for library in `cat $(gb_PackageInfo_get_target)/$*.libraries`; \
+ do \
+ install -D -m644 $(INSTDIR)/$${library} $(INSTALLDIR)/$${library}; \
+ done
+ for jar in `cat $(gb_PackageInfo_get_target)/$*.jars`; \
+ do \
+ install -D -m644 $(INSTDIR)/$${jar} $(INSTALLDIR)/$${jar}; \
+ done
+ for file in `cat $(gb_PackageInfo_get_target)/$*.files`; \
+ do \
+ install -D -m644 $(INSTDIR)/$${file} $(INSTALLDIR)/$${file}; \
+ done
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/extensions/post_SpeedUpTargets.mk b/solenv/gbuild/extensions/post_SpeedUpTargets.mk
new file mode 100644
index 000000000..3db6355ab
--- /dev/null
+++ b/solenv/gbuild/extensions/post_SpeedUpTargets.mk
@@ -0,0 +1,88 @@
+# -*- 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/.
+#
+
+ifneq ($(CROSS_COMPILING),)
+gb_Module_add_targets_for_build :=
+gb_Module_SKIPTARGETS := check slowcheck screenshot subsequentcheck uicheck
+endif
+
+ifeq ($(gb_Side),build)
+gb_Module_SKIPTARGETS := check slowcheck screenshot subsequentcheck uicheck
+endif
+
+ifeq ($(MAKECMDGOALS),build)
+gb_Module_SKIPTARGETS := check slowcheck screenshot subsequentcheck uicheck
+endif
+
+ifeq (,$(filter perfcheck,$(MAKECMDGOALS)))
+gb_Module_SKIPTARGETS += perfcheck
+else
+gb_Module_SKIPTARGETS += check slowcheck screenshot subsequentcheck uicheck
+endif
+
+ifneq ($(strip $(MAKECMDGOALS)),)
+# speed up depending on the target
+gb_SpeedUpTargets_LEVEL_4 := debugrun help translations install-package-% packageinfo
+gb_SpeedUpTargets_LEVEL_3 := showmodules $(gb_SpeedUpTargets_LEVEL_4)
+gb_SpeedUpTargets_LEVEL_2 := $(gb_SpeedUpTargets_LEVEL_3)
+gb_SpeedUpTargets_LEVEL_1 := clean showdeliverables $(gb_PackageInfo_get_target)/% $(gb_SpeedUpTargets_LEVEL_2)
+
+ifeq (T,$(if $(filter-out $(gb_SpeedUpTargets_LEVEL_1),$(MAKECMDGOALS)),,T))
+gb_FULLDEPS :=
+
+ifeq (T,$(if $(filter-out $(gb_SpeedUpTargets_LEVEL_2),$(MAKECMDGOALS)),,T))
+gb_Module_SKIPTARGETS += check slowcheck screenshot subsequentcheck uicheck
+
+ifeq (T,$(if $(filter-out $(gb_SpeedUpTargets_LEVEL_3),$(MAKECMDGOALS)),,T))
+gb_Module_SKIPTARGETS += build
+
+ifeq (T,$(if $(filter-out $(gb_SpeedUpTargets_LEVEL_4),$(MAKECMDGOALS)),,T))
+gb_Module_SKIPTARGETS += module
+
+endif
+endif
+endif
+endif
+
+endif
+
+
+ifneq (,$(filter build,$(gb_Module_SKIPTARGETS)))
+gb_Module_add_target =
+endif
+
+ifneq (,$(filter check,$(gb_Module_SKIPTARGETS)))
+gb_Module_add_check_target =
+endif
+
+ifneq (,$(filter slowcheck,$(gb_Module_SKIPTARGETS)))
+gb_Module_add_slowcheck_target =
+endif
+
+ifneq (,$(filter screenshot,$(gb_Module_SKIPTARGETS)))
+gb_Module_add_screenshot_target =
+endif
+
+ifneq (,$(filter subsequentcheck,$(gb_Module_SKIPTARGETS)))
+gb_Module_add_subsequentcheck_target =
+endif
+
+ifneq (,$(filter perfcheck,$(gb_Module_SKIPTARGETS)))
+gb_Module_add_perfcheck_target =
+endif
+
+ifneq (,$(filter uicheck,$(gb_Module_SKIPTARGETS)))
+gb_Module_add_uicheck_target =
+endif
+
+ifneq (,$(filter module,$(gb_Module_SKIPTARGETS)))
+gb_Module_add_moduledir =
+endif
+
+# vim:set shiftwidth=4 softtabstop=4 noexpandtab:
diff --git a/solenv/gbuild/extensions/pre_BuildTools.mk b/solenv/gbuild/extensions/pre_BuildTools.mk
new file mode 100644
index 000000000..0a83545cf
--- /dev/null
+++ b/solenv/gbuild/extensions/pre_BuildTools.mk
@@ -0,0 +1,54 @@
+# -*- 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/.
+#
+
+# Tools we need to build for cross-compiling
+ifeq ($(gb_Side),build)
+
+gb_BUILD_TOOLS_executables = \
+ bestreversemap \
+ cfgex \
+ climaker \
+ cpp \
+ cppumaker \
+ gencoll_rule \
+ genconv_dict \
+ gendict \
+ $(if $(WITH_GALLERY_BUILD),gengal) \
+ genindex_data \
+ helpex \
+ idxdict \
+ javamaker \
+ $(call gb_CondExeLockfile,lockfile) \
+ makedepend \
+ propex \
+ saxparser \
+ svidl \
+ treex \
+ ulfex \
+ unoidl-check \
+ unoidl-write \
+ xrmex \
+ $(call gb_Helper_optional,HELPTOOLS, \
+ HelpIndexer \
+ HelpLinker \
+ ) \
+ $(if $(filter WNT,$(OS)),$(call gb_Helper_optional,DESKTOP,lngconvex)) \
+
+gb_BUILD_TOOLS_executables_extern = \
+ python \
+ xsltproc \
+
+gb_BUILD_TOOLS = \
+ $(foreach executable,$(gb_BUILD_TOOLS_executables),$(call gb_Executable_get_runtime_dependencies,$(executable))) \
+ $(foreach executable,$(gb_BUILD_TOOLS_executables_extern),$(call gb_ExternalExecutable_get_dependencies,$(executable))) \
+ $(INSTROOT)/$(LIBO_URE_ETC_FOLDER)/$(call gb_Helper_get_rcfile,uno) \
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/extensions/pre_Counters.mk b/solenv/gbuild/extensions/pre_Counters.mk
new file mode 100644
index 000000000..eaec75069
--- /dev/null
+++ b/solenv/gbuild/extensions/pre_Counters.mk
@@ -0,0 +1,31 @@
+# -*- 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/.
+#
+
+gb_CountersOutdated_COUNTER_ALL:=
+gb_CountersOutdated_COUNTER_TYPES:=
+
+.PHONY: countoutdated
+countoutdated:
+ $(info total outdated files: $(words $(gb_CountersOutdated_COUNTER_ALL)))
+ $(info types of outdated files: $(gb_CountersOutdated_TYPES))
+ $(foreach type,$(gb_CountersOutdated_TYPES),$(info $(type): $(words $(gb_CountersOutdated_COUNTER_$(type)))))
+ @true
+
+ifneq ($(filter countoutdated,$(MAKECMDGOALS)),)
+
+$(WORKDIR)/%:
+ $(eval gb_CountersOutdated_COUNTER_ALL+= x)
+ $(eval gb_CountersOutdated__TYPE=$(firstword $(subst /, ,$*)))
+ $(if $(filter undefined,$(origin gb_CountersOutdated_COUNTER_$(gb_CountersOutdated__TYPE))),$(eval gb_CountersOutdated_COUNTER_$(gb_CountersOutdated__TYPE):=) $(eval gb_CountersOutdated_TYPES+=$(gb_CountersOutdated__TYPE)))
+ $(eval gb_CountersOutdated_COUNTER_$(gb_CountersOutdated__TYPE)+= x)
+ @true
+
+endif
+
+# vim: set noet ts=4 sw=4:
diff --git a/solenv/gbuild/extensions/pre_MergedLibsList.mk b/solenv/gbuild/extensions/pre_MergedLibsList.mk
new file mode 100644
index 000000000..b2402ec0c
--- /dev/null
+++ b/solenv/gbuild/extensions/pre_MergedLibsList.mk
@@ -0,0 +1,122 @@
+# -*- 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/.
+#
+
+# we link all object files from these libraries into one, merged library
+gb_MERGE_LIBRARY_LIST := \
+ avmedia \
+ $(if $(filter WNT,$(OS)),avmediawin) \
+ $(call gb_Helper_optional,SCRIPTING, \
+ basctl \
+ basprov \
+ ) \
+ basegfx \
+ canvasfactory \
+ canvastools \
+ comphelper \
+ configmgr \
+ cppcanvas \
+ $(call gb_Helper_optional,BREAKPAD,crashreport) \
+ ctl \
+ dbtools \
+ deployment \
+ deploymentmisc \
+ $(if $(filter-out MACOSX WNT,$(OS)),desktopbe1) \
+ $(if $(filter WNT,$(OS)),directx9canvas) \
+ drawinglayercore \
+ drawinglayer \
+ editeng \
+ emfio \
+ $(if $(filter WNT,$(OS)),emser) \
+ evtatt \
+ filterconfig \
+ for \
+ forui \
+ fps_office \
+ frm \
+ fsstorage \
+ fwk \
+ $(if $(filter WNT,$(OS)),gdipluscanvas) \
+ guesslang \
+ $(call gb_Helper_optional,DESKTOP,helplinker) \
+ hyphen \
+ i18nsearch \
+ i18npool \
+ i18nutil \
+ lng \
+ lnth \
+ localebe1 \
+ msfilter \
+ mtfrenderer \
+ numbertext \
+ odfflatxml \
+ offacc \
+ $(if $(ENABLE_OPENGL_CANVAS),oglcanvas) \
+ $(if $(filter OPENCL,$(BUILD_TYPE)),opencl) \
+ package2 \
+ passwordcontainer \
+ sax \
+ sb \
+ simplecanvas \
+ sfx \
+ sofficeapp \
+ sot \
+ spell \
+ $(if $(or $(DISABLE_GUI),$(ENABLE_WASM_STRIP_SPLASH)),,spl) \
+ srtrs1 \
+ $(call gb_Helper_optional,SCRIPTING,stringresource) \
+ svgio \
+ svl \
+ svt \
+ svx \
+ svxcore \
+ syssh \
+ textfd \
+ tk \
+ tl \
+ ucb1 \
+ ucbhelper \
+ ucpexpand1 \
+ ucpext \
+ ucphier1 \
+ ucpimage \
+ ucpfile1 \
+ ucptdoc1 \
+ unordf \
+ unoxml \
+ updatefeed \
+ utl \
+ uui \
+ vbaevents \
+ vbahelper \
+ vcl \
+ vclcanvas \
+ xmlfa \
+ xmlfd \
+ xmlscript \
+ xo \
+ xof \
+ xsltdlg \
+ xsltfilter \
+ xstor \
+
+
+# allow module-deps.pl to color based on this.
+ifneq ($(ENABLE_PRINT_DEPS),)
+
+$(info MergeLibContents: $(gb_MERGE_LIBRARY_LIST))
+
+endif
+
+ifneq ($(MERGELIBS),)
+
+gb_MERGEDLIBS := $(gb_MERGE_LIBRARY_LIST)
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/gbuild.help.txt b/solenv/gbuild/gbuild.help.txt
new file mode 100644
index 000000000..acd16ed2e
--- /dev/null
+++ b/solenv/gbuild/gbuild.help.txt
@@ -0,0 +1,159 @@
+NAME
+ gbuild - GNU make based build system for LibreOffice
+
+SYNOPSIS
+ make [ -f makefile ] [ options ] [ variable=value ... ] [ targets ] ...
+
+IMPORTANT OPTIONS
+ -s Silent operation; do not print the commands as they are executed.
+
+ -n Print the commands that would be executed, but do not execute them.
+ -k Continue as much as possible after an error.
+
+ -j Specifies the number of jobs (commands) to run simultaneously.
+ -l Specifies that no new jobs (commands) should be started if there are
+ others jobs running and the load average is at least load.
+
+ -t Touch files (mark them up to date without really changing them)
+ instead of running their commands.
+ -W Pretend that the target file has just been modified.
+ -o Do not remake the file file even if it is older than its
+ dependencies, and do not remake anything on account of changes in file.
+
+ -p Print the data base (rules and variable values) that results from
+ reading the makefiles.
+ --debug=b debug make run, see GNU make man page for details
+
+ (descriptions from GNU make man page)
+
+AVAILABLE TARGETS
+ build build product (default goal)
+ clean remove all generated files
+ debugrun starts the INSTDIR instance and allows tests to
+ be run against it. You can provide additional
+ arguments to soffice.bin using the gb_DBGARGS
+ variable.
+
+ check run unit tests and if in toplevel subsequentcheck
+ unitcheck run unit tests
+ slowcheck run slow unit tests
+ screenshot create all screenshots
+ subsequentcheck run system tests (requires full installation)
+ perfcheck run performance/callgrind unit tests
+ uicheck run UI tests
+
+ You can set gb_SUPPRESS_TESTS to just build but not run the tests.
+
+ build-l10n-only builds translation files for the build products
+ build-non-l10n-only builds the product without the localization files
+ translations extract .pot files to workdir/pot
+
+ packageinfo generates package information for distros
+ dump-deps-png creates dependency diagrams in PNG format
+ NOTE: needs graphviz to work
+ showmodules shows all registered modules
+
+ <module> an alias for <module>.build
+ <module>.<toplevel target> runs the toplevel target for the named
+ module. Per default, all pre-requisite are excluded!
+ <module>.allbuild as build + including all the pre-requisite modules
+ <module>.allcheck as check + including all the pre-requisite modules
+ <module>.buildall an alias for <module>.allbuild
+ <module>.checkall an alias for <module>.allcheck
+ <module>.showdeliverables show the targets delivered to INSTDIR and
+ their source
+
+ cmd execute the command contained in the variable cmd=""
+ in a shell with config_host.mk or config_build.mk
+ environment set. (see gb_SIDE)
+
+ <target> build gbuild target (such as Library_vbaswobj or
+ CppunitTest_sw_macros_test)
+ <target>.clean clean gbuild target
+ <class>_<target> for all targets and for the following classes:
+ o AllLangMoTarget
+ o AllLangZip
+ o CliLibrary
+ o CliNativeLibrary
+ o CliUnoApi
+ o ComponentTarget
+ o Configuration
+ o CppunitTest
+ o CustomTarget
+ o Dictionary
+ o Executable
+ o Extension
+ o ExternalPackage
+ o ExternalProject
+ o Gallery
+ o Helper
+ o InstallModule
+ o InstallScript
+ o InternalUnoApi
+ o Jar
+ o JunitTest
+ o Library
+ o Package
+ o Pagein
+ o PythonTest
+ o Pyuno
+ o Rdb
+ o StaticLibrary
+ o UI
+ o UnoApi
+ o UnpackedTarball
+ o WinResTarget
+ o Zip
+
+INTERACTIVE VARIABLES:
+ BUILDTOOLTRACE Run all commands that invoke built tools in strace,
+ valgrind or a debugger:
+ BUILDTOOLTRACE='$(DEVENV) /debugexe' PARALLELISM=1 make
+ DEBUG / debug If not empty, build as with --enable-debug.
+ ENABLE_SYMBOLS / enable_symbols
+ If not empty, build as with --enable-symbols.
+ DBGLEVEL / dbglevel
+ If not empty, force the debug level to the specified value. The
+ debug level is passed to the source code through OSL_DEBUG_LEVEL
+ macro.
+ 0 = no debug (as with --disable-debug)
+ 1 = debugging information + no optimizations (as with --enable-debug)
+ (Note that levels higher than 2 are used only by obsolete debugging
+ features. Use SAL_INFO/SAL_WARN with a specific area for extra debug
+ output in new code.)
+ 2 = debugging information + no optimizations + extra
+ debug output. OSL_TRACE starts being active on this
+ level.
+ 3... = debugging information + no optimizations + extra
+ debug output (usually extremely verbose). Levels
+ > 2 are not used very much.
+ PARALLELISM If not empty, pass argument on as the -j switch
+ to recursive make invocations. Useful to
+ lower/increase build parallelism individually.
+ verbose=t Verbose mode: display all commands
+ LEXFLAGS Append flags for LEX scanner generator invocation.
+ YACCFLAGS Append flags for YACC parser generator invocation.
+ CPPFLAGS Append preprocessor flags for C/C++/ObjC/ObjC++ compilation.
+ CFLAGS Override compiler flags for plain C compilation.
+ ENVCFLAGS Append compiler flags for plain C compilation.
+ CXXFLAGS Override compiler flags for C++ compilation.
+ Note: this overrides default optimization and debug
+ flags; to append flags without overriding, use:
+ CXXFLAGS='$(call gb_LinkTarget__get_debugflags,$(1)) -Wfoo'
+ ENVCFLAGSCXX Append compiler flags for C++ compilation.
+ OBJCFLAGS Override compiler flags for Objective C compilation.
+ OBJCXXFLAGS Override compiler flags for Objective C++ compilation.
+ LDFLAGS Override linker flags.
+ gb_FULLDEPS Generate and use dependencies (on by default, handle with care).
+ gb_COLOR Use ASCII color output.
+ gb_TITLES Show progress in terminal title.
+ gb_Side Either "host" or "build" (default to "host").
+ determine if config_host.mk or config_build.mk is used to
+ set the build environment.
+ gb_DBGARGS Append these arguments to GDBs "set args" command for
+ debugrun. Double quotes will be automatically escaped.
+ gb_SUPPRESS_TESTS Do not run tests (but still build them, when requested
+ by the given targets).
+ GCC_COLORS Colorize gcc diagnostics output. See
+ https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Message-Formatting-Options.html
+ for details & syntax. Or export that setting in your .bash_profile.
diff --git a/solenv/gbuild/gbuild.mk b/solenv/gbuild/gbuild.mk
new file mode 100644
index 000000000..075c029b0
--- /dev/null
+++ b/solenv/gbuild/gbuild.mk
@@ -0,0 +1,406 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+GBUILDDIR:=$(SRCDIR)/solenv/gbuild
+
+# vars needed from the env/calling makefile
+
+# DEBUG
+# JAVA_HOME
+# LIBXML_CFLAGS
+# OS
+# SOLARINC
+# UPD
+
+# PTHREAD_CFLAGS (Linux)
+# SYSTEM_ICU (Linux)
+# SYSTEM_LIBJPEG (Linux)
+# SYSTEM_LIBXML (Linux)
+
+.DELETE_ON_ERROR:
+
+# do not use built-in rules
+# DO NOT TOUCH THIS LINE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING
+# REMOVING THIS MAKES e.g. MODULE SW ALONE SLOWER BY SOME 300%
+# FOR TAIL_BUILD THE IMPACT IS HUGE!
+# (unless you are doing make -r, which we should explicitly NOT require from
+# users)
+MAKEFLAGS += r
+.SUFFIXES:
+
+true := T
+false :=
+gb_not = $(if $(1),$(false),$(true))
+
+define NEWLINE
+
+
+endef
+
+define WHITESPACE
+
+endef
+
+COMMA :=,
+
+OPEN_PAREN :=(
+CLOSE_PAREN :=)
+
+gb_SPACE:=$(gb_SPACE) $(gb_SPACE)
+
+gb_VERBOSE := $(verbose)
+
+include $(GBUILDDIR)/Helper.mk
+
+include $(GBUILDDIR)/Conditions.mk
+
+include $(SRCDIR)/solenv/inc/langlist.mk
+
+# optional extensions that should never be essential
+ifneq ($(wildcard $(GBUILDDIR)/extensions/pre_*.mk),)
+include $(wildcard $(GBUILDDIR)/extensions/pre_*.mk)
+endif
+
+include $(GBUILDDIR)/Output.mk
+
+gb_TIMELOG := 0
+ifneq ($(strip $(TIMELOG)$(timelog)),)
+gb_TIMELOG := 1
+endif
+
+ifneq ($(ENABLE_DBGUTIL),)
+gb_ENABLE_DBGUTIL := $(true)
+else
+gb_ENABLE_DBGUTIL := $(false)
+endif
+
+gb_ENABLE_SYMBOLS_FOR := $(ENABLE_SYMBOLS_FOR)
+
+# ENABLE_SYMBOLS (presumably from the command line)
+ifneq ($(strip $(ENABLE_SYMBOLS)),)
+gb_ENABLE_SYMBOLS_FOR := $(ENABLE_SYMBOLS)
+endif
+ifneq ($(strip $(enable_symbols)),)
+gb_ENABLE_SYMBOLS_FOR := $(enable_symbols)
+endif
+
+# note: ENABLE_BREAKPAD turns on symbols
+ifneq ($(strip $(ENABLE_BREAKPAD)),)
+gb_ENABLE_SYMBOLS_FOR := all
+endif
+
+gb_DEBUGLEVEL := 0
+ifneq ($(strip $(DEBUG)),)
+gb_DEBUGLEVEL := 1
+# make DEBUG=true should force -g
+ifeq ($(origin DEBUG),command line)
+gb_ENABLE_SYMBOLS_FOR := all
+endif
+endif
+ifneq ($(strip $(debug)),)
+gb_DEBUGLEVEL := 1
+ifeq ($(origin debug),command line)
+gb_ENABLE_SYMBOLS_FOR := all
+endif
+endif
+ifeq ($(gb_ENABLE_DBGUTIL),$(true))
+gb_DEBUGLEVEL := 1
+endif
+
+ifneq ($(strip $(DBGLEVEL)),)
+gb_DEBUGLEVEL := $(strip $(DBGLEVEL))
+ifeq ($(origin DBGLEVEL),command line)
+gb_ENABLE_SYMBOLS_FOR := all
+endif
+endif
+ifneq ($(strip $(dbglevel)),)
+gb_DEBUGLEVEL := $(strip $(dbglevel))
+ifeq ($(origin dbglevel),command line)
+gb_ENABLE_SYMBOLS_FOR := all
+endif
+endif
+
+# handle special cases
+ifeq ($(gb_ENABLE_SYMBOLS_FOR),1)
+gb_ENABLE_SYMBOLS_FOR := all
+endif
+ifeq ($(gb_ENABLE_SYMBOLS_FOR),0)
+gb_ENABLE_SYMBOLS_FOR :=
+endif
+ifeq ($(gb_ENABLE_SYMBOLS_FOR),yes)
+gb_ENABLE_SYMBOLS_FOR := all
+endif
+ifeq ($(gb_ENABLE_SYMBOLS_FOR),no)
+gb_ENABLE_SYMBOLS_FOR :=
+endif
+
+# Detect whether symbols should be enabled for the given gbuild target.
+# enable if: no "-TARGET" defined AND [module is enabled OR "TARGET" defined]
+gb_target_symbols_enabled = \
+ $(and $(if $(filter -$(1),$(ENABLE_SYMBOLS_FOR)),,$(true)),\
+ $(or $(gb_Module_CURRENTMODULE_SYMBOLS_ENABLED),\
+ $(filter $(1),$(ENABLE_SYMBOLS_FOR))))
+
+ifeq ($(BLOCK_PCH),)
+gb_ENABLE_PCH := $(ENABLE_PCH)
+else
+# Setting BLOCK_PCH effectively disables PCH, but the extra object file will be still linked in.
+# This is useful for rebuilding only some files with PCH disabled, e.g. to check #include's,
+# disabling the whole ENABLE_PCH would lead to unresolved symbols at link time.
+gb_ENABLE_PCH :=
+endif
+
+ifneq ($(nodep)$(ENABLE_PRINT_DEPS),)
+gb_FULLDEPS := $(false)
+else
+gb_FULLDEPS := $(true)
+endif
+
+ifneq ($(strip $(patches)$(PATCHES)),)
+gb_KEEP_PRISTINE := $(true)
+else
+gb_KEEP_PRISTINE := $(false)
+endif
+
+ifeq ($(findstring s,$(MAKEFLAGS)),)
+gb_QUIET_EXTERNAL := $(false)
+else
+gb_QUIET_EXTERNAL := $(true)
+endif
+
+# save user-supplied flags for latter use
+ifneq ($(strip $(ENVCFLAGS)),)
+gb__ENV_CFLAGS := $(ENVCFLAGS)
+endif
+ifneq ($(strip $(ENVCFLAGSCXX)),)
+gb__ENV_CXXFLAGS := $(ENVCFLAGSCXX)
+endif
+
+include $(GBUILDDIR)/ExternalExecutable.mk
+include $(GBUILDDIR)/TargetLocations.mk
+include $(GBUILDDIR)/Tempfile.mk
+
+$(eval $(call gb_Helper_init_registries))
+include $(SRCDIR)/Repository.mk
+include $(SRCDIR)/RepositoryExternal.mk
+$(eval $(call gb_Helper_collect_knownlibs))
+
+gb_Library_DLLPOSTFIX := lo
+gb_RUN_CONFIGURE :=
+
+gb_CONFIGURE_PLATFORMS := --build=$(BUILD_PLATFORM) --host=$(HOST_PLATFORM)
+
+# Include platform/cpu/compiler specific config/definitions
+
+include $(GBUILDDIR)/platform/$(OS)_$(CPUNAME)_$(COM).mk
+
+# this is optional
+include $(SRCDIR)/RepositoryFixes.mk
+
+# after platform; at least currently python depends on variable set in platform
+$(eval $(call gb_ExternalExecutable_collect_registrations))
+
+# add user-supplied flags
+ifneq ($(strip gb__ENV_CFLAGS),)
+gb_LinkTarget_CFLAGS += $(gb__ENV_CFLAGS)
+endif
+ifneq ($(strip gb__ENV_CXXFLAGS),)
+gb_LinkTarget_CXXFLAGS += $(gb__ENV_CXXFLAGS)
+endif
+
+gb_CPUDEFS += -D$(CPUNAME)
+
+gb_GLOBALDEFS := \
+ -D_REENTRANT \
+ -DOSL_DEBUG_LEVEL=$(gb_DEBUGLEVEL) \
+ $(gb_OSDEFS) \
+ $(gb_COMPILERDEFS) \
+ $(gb_CPUDEFS) \
+
+ifeq ($(gb_ENABLE_DBGUTIL),$(true))
+gb_GLOBALDEFS += -DDBG_UTIL
+
+ifneq ($(COM)-$(MSVC_USE_DEBUG_RUNTIME),MSC-)
+gb_GLOBALDEFS += -D_DEBUG
+endif
+endif
+
+ifeq ($(gb_TIMELOG),1)
+gb_GLOBALDEFS += -DTIMELOG \
+
+endif
+
+ifeq ($(strip $(ASSERT_ALWAYS_ABORT)),FALSE)
+gb_GLOBALDEFS += -DNDEBUG \
+
+endif
+
+ifeq ($(ENABLE_SAL_LOG),TRUE)
+gb_GLOBALDEFS += -DSAL_LOG_INFO \
+ -DSAL_LOG_WARN \
+
+endif
+
+ifneq ($(gb_DEBUGLEVEL),0)
+ifneq ($(gb_DEBUGLEVEL),1) # 2 or more
+gb_GLOBALDEFS += -DDEBUG \
+
+endif
+endif
+
+gb_GLOBALDEFS += \
+ $(call gb_Helper_define_if_set,\
+ DISABLE_DYNLOADING \
+ )
+
+gb_GLOBALDEFS := $(sort $(gb_GLOBALDEFS))
+
+# Common environment variables passed into all gb_*Test classes:
+# * Cap the number of threads unittests use:
+gb_TEST_ENV_VARS := MAX_CONCURRENCY=4
+# * Disable searching for certificates by default:
+#
+# see xmlsecurity/source/xmlsec/nss/nssinitializer.cxx for use
+#
+# a) If MOZILLA_CERTIFICATE_FOLDER is empty then LibreOffice autodetects
+# the user's mozilla-descended application profile. To disable that we
+# use a non-empty string here.
+#
+# b) Using dbm: appears to nss as equivalent to an empty path so the
+# initial NSS_InitReadWrite will fail. In response to that failure
+# LibreOffice will create a temp fallback cert database which is removed
+# on process exit
+gb_TEST_ENV_VARS += MOZILLA_CERTIFICATE_FOLDER=dbm:
+# Avoid hanging if the cups daemon requests a password:
+gb_TEST_ENV_VARS += SAL_DISABLE_SYNCHRONOUS_PRINTER_DETECTION=1
+ifeq (,$(SAL_USE_VCLPLUGIN))
+gb_TEST_ENV_VARS += SAL_USE_VCLPLUGIN=svp
+endif
+
+# This is used to detect whether LibreOffice is being built (as opposed to building
+# 3rd-party code). Used for tag deprecation for API we want to
+# ensure is not used at all externally while we clean
+# out our internal usage, for code in sal/ that should be used only internally, etc.
+gb_DEFS_INTERNAL := \
+ -DLIBO_INTERNAL_ONLY \
+
+include $(GBUILDDIR)/Deliver.mk
+
+$(eval $(call gb_Deliver_init))
+
+include $(GBUILDDIR)/Trace.mk
+
+# We are using a set of scopes that we might as well call classes.
+
+# TODO: to what extent is the following still true?
+# It is important to include them in the right order as that is
+# -- at least in part -- defining precedence. This is not an issue in the
+# WORKDIR as there are no naming collisions there, but INSTDIR is a mess
+# and precedence is important there. This is also platform dependent.
+#
+# This is less of an issue with GNU Make versions > 3.82 which matches for
+# shortest stem instead of first match. However, upon introduction this version
+# is not available everywhere by default.
+
+include $(foreach class, \
+ ComponentTarget \
+ Postprocess \
+ AllLangMoTarget \
+ WinResTarget \
+ LinkTarget \
+ Library \
+ StaticLibrary \
+ Executable \
+ SdiTarget \
+ Package \
+ ExternalPackage \
+ CustomTarget \
+ ExternalProject \
+ Gallery \
+ Pagein \
+ PrecompiledHeaders \
+ Pyuno \
+ PythonTest \
+ UITest \
+ Rdb \
+ CppunitTest \
+ Jar \
+ JavaClassSet \
+ JunitTest \
+ Module \
+ UIConfig \
+ UnoApiTarget \
+ UnoApi \
+ UnpackedTarball \
+ InternalUnoApi \
+ CliAssembly \
+ CliLibrary \
+ CliNativeLibrary \
+ CliUnoApi \
+ Zip \
+ AllLangPackage \
+ Configuration \
+ HelpTarget \
+ AllLangHelp \
+ Extension \
+ ExtensionPackage \
+ Dictionary \
+ InstallModuleTarget \
+ InstallModule \
+ InstallScript \
+ AutoInstall \
+ PackageSet \
+ GeneratedPackage \
+ CompilerTest \
+,$(GBUILDDIR)/$(class).mk)
+
+$(eval $(call gb_Helper_process_executable_registrations))
+$(eval $(call gb_Postprocess_make_targets))
+
+# optional extensions that should never be essential
+ifneq ($(wildcard $(GBUILDDIR)/extensions/post_*.mk),)
+include $(wildcard $(GBUILDDIR)/extensions/post_*.mk)
+endif
+
+define gb_Extensions_final_hook
+ifneq ($(wildcard $(GBUILDDIR)/extensions/final_*.mk),)
+include $(wildcard $(GBUILDDIR)/extensions/final_*.mk)
+endif
+
+endef
+
+# Setup for ccache.
+ifneq ($(gb_ENABLE_PCH),)
+# CCACHE_SLOPPINESS should contain pch_defines,time_macros for PCHs.
+gb_CCACHE_SLOPPINESS :=
+ifeq ($(shell test -z "$$CCACHE_SLOPPINESS" && echo 1),1)
+gb_CCACHE_SLOPPINESS := CCACHE_SLOPPINESS=pch_defines,time_macros
+else
+ifeq ($(shell echo "$$CCACHE_SLOPPINESS" | grep -q pch_defines | grep -q time_macros && echo 1),1)
+gb_CCACHE_SLOPPINESS := CCACHE_SLOPPINESS=$CCACHE_SLOPPINESS:pch_defines,time_macros
+endif
+endif
+gb_COMPILER_SETUP += $(gb_CCACHE_SLOPPINESS)
+endif
+
+ifneq ($(CCACHE_DEPEND_MODE),)
+gb_COMPILER_SETUP += CCACHE_DEPEND=1
+endif
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/gen-autoinstall.py b/solenv/gbuild/gen-autoinstall.py
new file mode 100644
index 000000000..d55ab51d3
--- /dev/null
+++ b/solenv/gbuild/gen-autoinstall.py
@@ -0,0 +1,98 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# 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/.
+#
+
+# generate AutoInstall files from gbuild data for further scp2 processing
+
+import sys
+
+module = sys.argv[1]
+scp2componentcondition = sys.argv[2]
+scp2libtemplate = sys.argv[3]
+scp2exetemplate = sys.argv[4]
+scp2jartemplate = sys.argv[5]
+scp2pkgtemplate = sys.argv[6]
+# use 'with open(file) as f:' to avoid 'ResourceWarning: unclosed file'
+with open(sys.argv[7]) as f:
+ sdklibs = f.readline().split()
+with open(sys.argv[8]) as f:
+ libs = f.readline().split()
+with open(sys.argv[9]) as f:
+ exes = f.readline().split()
+with open(sys.argv[10]) as f:
+ jars = f.readline().split()
+with open(sys.argv[11]) as f:
+ pkgs = f.readline().split()
+
+if len(scp2componentcondition) > 0:
+ scp2componentcondition = "," + scp2componentcondition
+
+def escape(string):
+ return string.replace(".", "_").replace("-", "_").replace("/", "_")
+
+def to_tuple(l):
+ ret = []
+ i = 0
+ while i < len(l):
+ ret.append((l[i], l[i+1]))
+ i += 2
+ return ret
+
+def to_triple(l):
+ ret = []
+ i = 0
+ while i < len(l):
+ ret.append((l[i], l[i+1], l[i+2]))
+ i += 3
+ return ret
+
+print("/* autogenerated installs for group " + module + " */")
+print("#define auto_" + module + "_ALL \\")
+
+autosdklibs = [("auto_" + module + "_link_" + escape(lib),link,target) for (lib,link,target) in to_triple(sdklibs)]
+autolibs = [("auto_" + module + "_lib_" + escape(lib),libfile) for (lib,libfile) in to_tuple(libs)]
+autoexes = [("auto_" + module + "_exe_" + escape(exe),exefile) for (exe,exefile) in to_tuple(exes)]
+autojars = [("auto_" + module + "_jar_" + escape(jar),jar + ".jar") for jar in jars]
+autopkgs = [("auto_" + module + "_pkg_" + escape(pkg),pkg + ".filelist") for pkg in pkgs]
+
+allgids = [gid for (gid,_,_) in autosdklibs] + \
+ [gid for (gid,_) in autolibs] + \
+ [gid for (gid,_) in autoexes] + \
+ [gid for (gid,_) in autojars] + \
+ [gid for (gid,_) in autopkgs]
+
+print(", \\\n".join([" " + gid for gid in allgids]))
+
+for (gid, link, target) in autosdklibs:
+ print("SDK_LIBRARY_LINK(" + gid + "," + link + "," + target + ")")
+
+scp2libtemplates = set([ "URE_PRIVATE_LIB", "LIBO_LIB_FILE", "LIBO_LIB_FILE_BINARYTABLE", "LIBO_LIB_FILE_COMPONENTCONDITION", "SHLXTHDL_LIB_FILE", "SHLXTHDL_X64_LIB_FILE_COMPONENTCONDITION" ])
+for (gid, libfile) in autolibs:
+ if not(scp2libtemplate in scp2libtemplates):
+ raise Exception("invalid scp2libtemplate \"" + scp2libtemplate + "\"")
+ print(scp2libtemplate + "(" + gid + "," + libfile + scp2componentcondition + ")")
+
+scp2exetemplates = set([ "URE_EXECUTABLE", "LIBO_EXECUTABLE", "LIBO_EXECUTABLE_COMPONENTCONDITION", "SDK_EXECUTABLE" ])
+for (gid, exefile) in autoexes:
+ if not(scp2exetemplate in scp2exetemplates):
+ raise Exception("invalid scp2exetemplate \"" + scp2exetemplate + "\"")
+ print(scp2exetemplate + "(" + gid + "," + exefile + scp2componentcondition + ")")
+
+scp2jartemplates = set([ "URE_JAR_FILE", "LIBO_JAR_FILE" ])
+for (gid, jarfile) in autojars:
+ if not(scp2jartemplate in scp2jartemplates):
+ raise Exception("invalid scp2jartemplate \"" + scp2jartemplate + "\"")
+ print(scp2jartemplate + "(" + gid + "," + jarfile + scp2componentcondition + ")")
+
+scp2pkgtemplates = set([ "PACKAGE_FILELIST", "PACKAGE_FILELIST_COMPONENTCONDITION","PACKAGE_FILELIST_FONT", "SDK_PACKAGE_FILELIST" ])
+for (gid, pkgfilelist) in autopkgs:
+ if not(scp2pkgtemplate in scp2pkgtemplates):
+ raise Exception("invalid scp2pkgtemplate \"" + scp2pkgtemplate + "\"")
+ print(scp2pkgtemplate + "(" + gid + "," + pkgfilelist + scp2componentcondition + ")")
+
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/solenv/gbuild/partial_build.mk b/solenv/gbuild/partial_build.mk
new file mode 100644
index 000000000..5819667b2
--- /dev/null
+++ b/solenv/gbuild/partial_build.mk
@@ -0,0 +1,46 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+ifeq ($(gb_Side),)
+gb_Side:=host
+endif
+
+ifeq (,$(BUILDDIR))
+gb_partial_build__makefile_dir=$(dir $(abspath $(firstword $(MAKEFILE_LIST))))
+BUILDDIR := $(if $(wildcard $(gb_partial_build__makefile_dir)../Module_external.mk), \
+ $(gb_partial_build__makefile_dir)../.., \
+ $(gb_partial_build__makefile_dir)..)
+endif
+
+include $(BUILDDIR)/config_$(gb_Side).mk
+
+gb_PARTIAL_BUILD := T
+include $(SRCDIR)/solenv/gbuild/gbuild.mk
+
+$(eval $(call gb_Module_make_global_targets,$(wildcard $(module_directory)Module*.mk)))
+
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+$(if $(gb_LinkTarget__Lock),$(shell rm -f $(gb_LinkTarget__Lock)))
+ifeq ($(ENABLE_CUSTOMTARGET_COMPONENTS),TRUE)
+include $(SRCDIR)/solenv/gbuild/static.mk
+$(if $(filter a,$(gb_DEBUG_STATIC)),$(error Abort after static.mk))
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/ANDROID_AARCH64_GCC.mk b/solenv/gbuild/platform/ANDROID_AARCH64_GCC.mk
new file mode 100644
index 000000000..0fab5ede8
--- /dev/null
+++ b/solenv/gbuild/platform/ANDROID_AARCH64_GCC.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/.
+#
+
+# please make generic modifications to unxgcc.mk or android.mk
+gb_CPUDEFS += -DARM32
+gb_COMPILEROPTFLAGS := -Os
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+include $(GBUILDDIR)/platform/android.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/ANDROID_ARM_GCC.mk b/solenv/gbuild/platform/ANDROID_ARM_GCC.mk
new file mode 100644
index 000000000..0fab5ede8
--- /dev/null
+++ b/solenv/gbuild/platform/ANDROID_ARM_GCC.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/.
+#
+
+# please make generic modifications to unxgcc.mk or android.mk
+gb_CPUDEFS += -DARM32
+gb_COMPILEROPTFLAGS := -Os
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+include $(GBUILDDIR)/platform/android.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/ANDROID_INTEL_GCC.mk b/solenv/gbuild/platform/ANDROID_INTEL_GCC.mk
new file mode 100644
index 000000000..597366a7f
--- /dev/null
+++ b/solenv/gbuild/platform/ANDROID_INTEL_GCC.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/.
+#
+
+# please make generic modifications to unxgcc.mk or android.mk
+gb_CPUDEFS += -DX86
+gb_COMPILEROPTFLAGS := -Os
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+include $(GBUILDDIR)/platform/android.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/ANDROID_X86_64_GCC.mk b/solenv/gbuild/platform/ANDROID_X86_64_GCC.mk
new file mode 100644
index 000000000..bb57e8ae0
--- /dev/null
+++ b/solenv/gbuild/platform/ANDROID_X86_64_GCC.mk
@@ -0,0 +1,15 @@
+# -*- 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/.
+#
+
+# please make generic modifications to unxgcc.mk or android.mk
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+include $(GBUILDDIR)/platform/android.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/DRAGONFLY_INTEL_GCC.mk b/solenv/gbuild/platform/DRAGONFLY_INTEL_GCC.mk
new file mode 100644
index 000000000..00ccf8a03
--- /dev/null
+++ b/solenv/gbuild/platform/DRAGONFLY_INTEL_GCC.mk
@@ -0,0 +1,18 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk
+
+gb_CPUDEFS := -DX86
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+gb_CppunitTest_CPPTESTPRECOMMAND := LD_LIBRARY_PATH=$(WORKDIR)/UnpackedTarball/cppunit/src/cppunit/.libs:/usr/pkg/lib
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/DRAGONFLY_X86_64_GCC.mk b/solenv/gbuild/platform/DRAGONFLY_X86_64_GCC.mk
new file mode 100644
index 000000000..71b53d522
--- /dev/null
+++ b/solenv/gbuild/platform/DRAGONFLY_X86_64_GCC.mk
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+gb_CppunitTest_CPPTESTPRECOMMAND := LD_LIBRARY_PATH=$(WORKDIR)/UnpackedTarball/cppunit/src/cppunit/.libs:/usr/pkg/lib
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/DeclareDPIAware.manifest b/solenv/gbuild/platform/DeclareDPIAware.manifest
new file mode 100644
index 000000000..bb0123062
--- /dev/null
+++ b/solenv/gbuild/platform/DeclareDPIAware.manifest
@@ -0,0 +1,7 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
+ <asmv3:application>
+ <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
+ <dpiAware>true</dpiAware>
+ </asmv3:windowsSettings>
+ </asmv3:application>
+</assembly>
diff --git a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
new file mode 100644
index 000000000..61424f72c
--- /dev/null
+++ b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
@@ -0,0 +1,95 @@
+# -*- 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/.
+#
+
+gb_UnoApiHeadersTarget_select_variant = $(if $(filter udkapi,$(1)),comprehensive,$(2))
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+# don't sort; later can override previous settings!
+gb_EMSCRIPTEN_PRE_JS_FILES = \
+ $(SRCDIR)/static/emscripten/environment.js \
+ $(call gb_CustomTarget_get_workdir,static/emscripten_fs_image)/soffice.data.js.link \
+
+gb_RUN_CONFIGURE := $(SRCDIR)/solenv/bin/run-configure
+# avoid -s SAFE_HEAP=1 - c.f. gh#8584 this breaks source maps
+gb_EMSCRIPTEN_CPPFLAGS := -pthread -s USE_PTHREADS=1
+gb_EMSCRIPTEN_LDFLAGS := $(gb_EMSCRIPTEN_CPPFLAGS)
+
+# Initial memory size and worker thread pool
+gb_EMSCRIPTEN_LDFLAGS += -s TOTAL_MEMORY=1GB -s PTHREAD_POOL_SIZE=4
+
+# To keep the link time (and memory) down, prevent all rewriting options from wasm-emscripten-finalize
+# See emscripten.py, finalize_wasm, modify_wasm = True
+# So we need WASM_BIGINT=1 and ASSERTIONS=1 (2 implies STACK_OVERFLOW_CHECK)
+gb_EMSCRIPTEN_LDFLAGS += --bind -s FORCE_FILESYSTEM=1 -s WASM_BIGINT=1 -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s FETCH=1 -s ASSERTIONS=1 -s EXIT_RUNTIME=0 -s EXPORTED_RUNTIME_METHODS=["UTF16ToString","stringToUTF16","printErr"]
+gb_EMSCRIPTEN_QTDEFS := -DQT_NO_LINKED_LIST -DQT_NO_JAVA_STYLE_ITERATORS -DQT_NO_EXCEPTIONS -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB
+
+gb_Executable_EXT := .html
+ifeq ($(ENABLE_WASM_EXCEPTIONS),TRUE)
+gb_EMSCRIPTEN_EXCEPT = -fwasm-exceptions -s SUPPORT_LONGJMP=wasm
+gb_EMSCRIPTEN_CPPFLAGS += -s SUPPORT_LONGJMP=wasm
+else
+gb_EMSCRIPTEN_EXCEPT = -s DISABLE_EXCEPTION_CATCHING=0
+endif
+
+gb_CXXFLAGS += $(gb_EMSCRIPTEN_CPPFLAGS)
+gb_LinkTarget_EXCEPTIONFLAGS += $(gb_EMSCRIPTEN_EXCEPT)
+gb_LinkTarget_CFLAGS += $(gb_EMSCRIPTEN_CPPFLAGS) $(gb_EMSCRIPTEN_QTDEFS)
+gb_LinkTarget_CXXFLAGS += $(gb_EMSCRIPTEN_CPPFLAGS) $(gb_EMSCRIPTEN_QTDEFS) $(gb_EMSCRIPTEN_EXCEPT)
+gb_LinkTarget_LDFLAGS += $(gb_EMSCRIPTEN_LDFLAGS) $(gb_EMSCRIPTEN_CPPFLAGS) $(gb_EMSCRIPTEN_EXCEPT)
+
+# Linker and compiler optimize + debug flags are handled in LinkTarget.mk
+gb_LINKEROPTFLAGS :=
+gb_LINKERSTRIPDEBUGFLAGS :=
+# This maps to g3, no source maps, but DWARF with current emscripten!
+# https://developer.chrome.com/blog/wasm-debugging-2020/
+gb_DEBUGINFO_FLAGS = -g
+#gb_DEBUGINFO_FLAGS = -gsource-map --source-map-base=file://$(WORKDIR)/LinkTarget/Executable
+
+ifeq ($(HAVE_EXTERNAL_DWARF),TRUE)
+gb_DEBUGINFO_FLAGS += -gseparate-dwarf
+endif
+
+# We need at least code elimination, otherwise linking OOMs even with 64GB.
+# So we "fake" -Og support to mean -O1 for Emscripten and always enable it for debug in configure.
+gb_COMPILERDEBUGOPTFLAGS := -O1
+gb_COMPILERNOOPTFLAGS := -O1 -fstrict-aliasing -fstrict-overflow
+
+# cleanup addition JS and wasm files for binaries
+define gb_Executable_Executable_platform
+$(call gb_LinkTarget_add_auxtargets,$(2),\
+ $(patsubst %.lib,%.wasm,$(3)) \
+ $(patsubst %.lib,%.js,$(3)) \
+ $(patsubst %.lib,%.worker.js,$(3)) \
+)
+
+$(foreach pre_js,$(gb_EMSCRIPTEN_PRE_JS_FILES),$(call gb_Executable_add_prejs,$(1),$(pre_js)))
+
+endef
+
+define gb_CppunitTest_CppunitTest_platform
+$(call gb_LinkTarget_add_auxtargets,$(2),\
+ $(patsubst %.lib,%.wasm,$(3)) \
+ $(patsubst %.lib,%.js,$(3)) \
+ $(patsubst %.lib,%.worker.js,$(3)) \
+)
+
+$(foreach pre_js,$(gb_EMSCRIPTEN_PRE_JS_FILES),$(call gb_CppunitTest_add_prejs,$(1),$(pre_js)))
+
+endef
+
+gb_SUPPRESS_TESTS := $(true)
+
+define gb_Library_get_rpath
+endef
+
+define gb_Executable_get_rpath
+endef
+
+# vim: set noet sw=4 ts=4
diff --git a/solenv/gbuild/platform/FREEBSD_AARCH64_GCC.mk b/solenv/gbuild/platform/FREEBSD_AARCH64_GCC.mk
new file mode 100644
index 000000000..6199f17b3
--- /dev/null
+++ b/solenv/gbuild/platform/FREEBSD_AARCH64_GCC.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/.
+#
+
+#please make generic modifications to unxgcc.mk
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/FREEBSD_INTEL_GCC.mk b/solenv/gbuild/platform/FREEBSD_INTEL_GCC.mk
new file mode 100644
index 000000000..5582d2dc8
--- /dev/null
+++ b/solenv/gbuild/platform/FREEBSD_INTEL_GCC.mk
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk
+
+gb_CPUDEFS := -DX86
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/FREEBSD_POWERPC64_GCC.mk b/solenv/gbuild/platform/FREEBSD_POWERPC64_GCC.mk
new file mode 100644
index 000000000..93fdf8126
--- /dev/null
+++ b/solenv/gbuild/platform/FREEBSD_POWERPC64_GCC.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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+gb_CPUDEFS += -DPPC -DPOWERPC64
+gb_COMPILERDEFAULTOPTFLAGS := -O2
+gb_CXXFLAGS += -mminimal-toc
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/FREEBSD_POWERPC_GCC.mk b/solenv/gbuild/platform/FREEBSD_POWERPC_GCC.mk
new file mode 100644
index 000000000..48c29b6f1
--- /dev/null
+++ b/solenv/gbuild/platform/FREEBSD_POWERPC_GCC.mk
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+gb_CPUDEFS += -DPPC -DPOWERPC
+gb_COMPILERDEFAULTOPTFLAGS := -O2
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/FREEBSD_X86_64_GCC.mk b/solenv/gbuild/platform/FREEBSD_X86_64_GCC.mk
new file mode 100644
index 000000000..6199f17b3
--- /dev/null
+++ b/solenv/gbuild/platform/FREEBSD_X86_64_GCC.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/.
+#
+
+#please make generic modifications to unxgcc.mk
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/HAIKU_INTEL_GCC.mk b/solenv/gbuild/platform/HAIKU_INTEL_GCC.mk
new file mode 100644
index 000000000..5582d2dc8
--- /dev/null
+++ b/solenv/gbuild/platform/HAIKU_INTEL_GCC.mk
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk
+
+gb_CPUDEFS := -DX86
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/HAIKU_X86_64_GCC.mk b/solenv/gbuild/platform/HAIKU_X86_64_GCC.mk
new file mode 100644
index 000000000..6199f17b3
--- /dev/null
+++ b/solenv/gbuild/platform/HAIKU_X86_64_GCC.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/.
+#
+
+#please make generic modifications to unxgcc.mk
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_AARCH64_GCC.mk b/solenv/gbuild/platform/LINUX_AARCH64_GCC.mk
new file mode 100644
index 000000000..431485a7c
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_AARCH64_GCC.mk
@@ -0,0 +1,12 @@
+# -*- 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/.
+#
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_ARM_GCC.mk b/solenv/gbuild/platform/LINUX_ARM_GCC.mk
new file mode 100644
index 000000000..cccf5772b
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_ARM_GCC.mk
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+gb_CPUDEFS += -DARM32
+gb_COMPILEROPTFLAGS := -Os
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_AXP_GCC.mk b/solenv/gbuild/platform/LINUX_AXP_GCC.mk
new file mode 100644
index 000000000..b0d41078f
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_AXP_GCC.mk
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+gb_COMPILEROPTFLAGS := -Os
+gb_LinkTarget_LDFLAGS += -Wl,--no-relax
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_GODSON64_GCC.mk b/solenv/gbuild/platform/LINUX_GODSON64_GCC.mk
new file mode 100644
index 000000000..4a0a619e4
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_GODSON64_GCC.mk
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+gb_CPUDEFS += -DMIPS64
+gb_COMPILEROPTFLAGS := -Os
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_GODSON_GCC.mk b/solenv/gbuild/platform/LINUX_GODSON_GCC.mk
new file mode 100644
index 000000000..976aaedf9
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_GODSON_GCC.mk
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+gb_CPUDEFS += -DMIPS
+gb_COMPILEROPTFLAGS := -Os
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_HPPA_GCC.mk b/solenv/gbuild/platform/LINUX_HPPA_GCC.mk
new file mode 100644
index 000000000..c1a1ceeee
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_HPPA_GCC.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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_IA64_GCC.mk b/solenv/gbuild/platform/LINUX_IA64_GCC.mk
new file mode 100644
index 000000000..c1a1ceeee
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_IA64_GCC.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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_INTEL_GCC.mk b/solenv/gbuild/platform/LINUX_INTEL_GCC.mk
new file mode 100644
index 000000000..146e95cf9
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_INTEL_GCC.mk
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+gb_CPUDEFS := -DX86
+gb_COMPILEROPTFLAGS := -Os
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_M68K_GCC.mk b/solenv/gbuild/platform/LINUX_M68K_GCC.mk
new file mode 100644
index 000000000..9e007101d
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_M68K_GCC.mk
@@ -0,0 +1,15 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+gb_COMPILEROPTFLAGS := -Os
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_POWERPC64_GCC.mk b/solenv/gbuild/platform/LINUX_POWERPC64_GCC.mk
new file mode 100644
index 000000000..1880b3bad
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_POWERPC64_GCC.mk
@@ -0,0 +1,15 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+gb_CPUDEFS += -DPPC
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_POWERPC_GCC.mk b/solenv/gbuild/platform/LINUX_POWERPC_GCC.mk
new file mode 100644
index 000000000..1880b3bad
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_POWERPC_GCC.mk
@@ -0,0 +1,15 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+gb_CPUDEFS += -DPPC
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_S390X_GCC.mk b/solenv/gbuild/platform/LINUX_S390X_GCC.mk
new file mode 100644
index 000000000..c1a1ceeee
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_S390X_GCC.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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_S390_GCC.mk b/solenv/gbuild/platform/LINUX_S390_GCC.mk
new file mode 100644
index 000000000..c1a1ceeee
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_S390_GCC.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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_SPARC64_GCC.mk b/solenv/gbuild/platform/LINUX_SPARC64_GCC.mk
new file mode 100644
index 000000000..9e007101d
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_SPARC64_GCC.mk
@@ -0,0 +1,15 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+gb_COMPILEROPTFLAGS := -Os
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_SPARC_GCC.mk b/solenv/gbuild/platform/LINUX_SPARC_GCC.mk
new file mode 100644
index 000000000..9e007101d
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_SPARC_GCC.mk
@@ -0,0 +1,15 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+gb_COMPILEROPTFLAGS := -Os
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/LINUX_X86_64_GCC.mk b/solenv/gbuild/platform/LINUX_X86_64_GCC.mk
new file mode 100644
index 000000000..c1a1ceeee
--- /dev/null
+++ b/solenv/gbuild/platform/LINUX_X86_64_GCC.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/.
+#
+
+#please make generic modifications to unxgcc.mk or linux.mk
+
+include $(GBUILDDIR)/platform/linux.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/MACOSX_AARCH64_GCC.mk b/solenv/gbuild/platform/MACOSX_AARCH64_GCC.mk
new file mode 100644
index 000000000..d8845ccbb
--- /dev/null
+++ b/solenv/gbuild/platform/MACOSX_AARCH64_GCC.mk
@@ -0,0 +1,13 @@
+# -*- 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/.
+#
+#*************************************************************************
+
+include $(GBUILDDIR)/platform/macosx.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/MACOSX_X86_64_GCC.mk b/solenv/gbuild/platform/MACOSX_X86_64_GCC.mk
new file mode 100644
index 000000000..d8845ccbb
--- /dev/null
+++ b/solenv/gbuild/platform/MACOSX_X86_64_GCC.mk
@@ -0,0 +1,13 @@
+# -*- 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/.
+#
+#*************************************************************************
+
+include $(GBUILDDIR)/platform/macosx.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/NETBSD_INTEL_GCC.mk b/solenv/gbuild/platform/NETBSD_INTEL_GCC.mk
new file mode 100644
index 000000000..feb527ba9
--- /dev/null
+++ b/solenv/gbuild/platform/NETBSD_INTEL_GCC.mk
@@ -0,0 +1,21 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk
+
+gb_CPUDEFS := -DX86
+gb_COMPILEROPTFLAGS := -O -g
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+NB_ADD_LIBPATH := /usr/pkg/lib:/usr/X11R7/lib
+
+gb_CppunitTest_CPPTESTPRECOMMAND := LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}$(WORKDIR)/UnpackedTarball/cppunit/src/cppunit/.libs:$(NB_ADD_LIBPATH)
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/NETBSD_X86_64_GCC.mk b/solenv/gbuild/platform/NETBSD_X86_64_GCC.mk
new file mode 100644
index 000000000..fbbf7b428
--- /dev/null
+++ b/solenv/gbuild/platform/NETBSD_X86_64_GCC.mk
@@ -0,0 +1,20 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk
+
+gb_COMPILEROPTFLAGS := -O -g
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+NB_ADD_LIBPATH := /usr/pkg/lib:/usr/X11R7/lib
+
+gb_CppunitTest_CPPTESTPRECOMMAND := LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}$(WORKDIR)/UnpackedTarball/cppunit/src/cppunit/.libs:$(NB_ADD_LIBPATH)
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/OPENBSD_INTEL_GCC.mk b/solenv/gbuild/platform/OPENBSD_INTEL_GCC.mk
new file mode 100644
index 000000000..50d803d29
--- /dev/null
+++ b/solenv/gbuild/platform/OPENBSD_INTEL_GCC.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/.
+#
+
+#please make generic modifications to unxgcc.mk
+
+gb_CPUDEFS := -DX86
+gb_STDLIBS := $(PTHREAD_LIBS)
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/OPENBSD_X86_64_GCC.mk b/solenv/gbuild/platform/OPENBSD_X86_64_GCC.mk
new file mode 100644
index 000000000..15908054d
--- /dev/null
+++ b/solenv/gbuild/platform/OPENBSD_X86_64_GCC.mk
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+
+#please make generic modifications to unxgcc.mk
+
+gb_STDLIBS := $(PTHREAD_LIBS)
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/SOLARIS_INTEL_GCC.mk b/solenv/gbuild/platform/SOLARIS_INTEL_GCC.mk
new file mode 100644
index 000000000..7f31c8a8a
--- /dev/null
+++ b/solenv/gbuild/platform/SOLARIS_INTEL_GCC.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/.
+#
+#*************************************************************************
+
+include $(GBUILDDIR)/platform/solaris.mk
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/SOLARIS_SPARC_GCC.mk b/solenv/gbuild/platform/SOLARIS_SPARC_GCC.mk
new file mode 100644
index 000000000..25b383489
--- /dev/null
+++ b/solenv/gbuild/platform/SOLARIS_SPARC_GCC.mk
@@ -0,0 +1,16 @@
+# -*- 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/.
+#
+#*************************************************************************
+
+gb_CPUDEFS := -D__sparcv8plus
+
+include $(GBUILDDIR)/platform/solaris.mk
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/WNT_AARCH64_MSC.mk b/solenv/gbuild/platform/WNT_AARCH64_MSC.mk
new file mode 100644
index 000000000..c9cf93138
--- /dev/null
+++ b/solenv/gbuild/platform/WNT_AARCH64_MSC.mk
@@ -0,0 +1,26 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+gb_CPUDEFS := -D_ARM64_=1
+
+include $(GBUILDDIR)/platform/com_MSC_defs.mk
+
+include $(GBUILDDIR)/platform/com_MSC_class.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/WNT_INTEL_MSC.mk b/solenv/gbuild/platform/WNT_INTEL_MSC.mk
new file mode 100644
index 000000000..690a7083a
--- /dev/null
+++ b/solenv/gbuild/platform/WNT_INTEL_MSC.mk
@@ -0,0 +1,26 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+gb_CPUDEFS := -D_X86_=1
+
+include $(GBUILDDIR)/platform/com_MSC_defs.mk
+
+include $(GBUILDDIR)/platform/com_MSC_class.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/WNT_X86_64_MSC.mk b/solenv/gbuild/platform/WNT_X86_64_MSC.mk
new file mode 100644
index 000000000..18eae3e74
--- /dev/null
+++ b/solenv/gbuild/platform/WNT_X86_64_MSC.mk
@@ -0,0 +1,26 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+gb_CPUDEFS := -D_AMD64_=1
+
+include $(GBUILDDIR)/platform/com_MSC_defs.mk
+
+include $(GBUILDDIR)/platform/com_MSC_class.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/android.mk b/solenv/gbuild/platform/android.mk
new file mode 100644
index 000000000..fde207ecc
--- /dev/null
+++ b/solenv/gbuild/platform/android.mk
@@ -0,0 +1,129 @@
+# -*- 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/.
+#
+
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+
+gb_STDLIBS := -static-libstdc++
+
+endif
+
+# No unit testing can be run
+gb_CppunitTest_CPPTESTPRECOMMAND := :
+
+# Re-define this from unxgcc.mk with some small but important
+# changes. Just temporarily done this way, shm_get promised to
+# eventually enable this to be done this in some more elegant and less
+# redundant fashion.
+
+gb_LinkTarget_LDFLAGS += \
+ -Wl,-z,defs \
+ -Wl,--as-needed \
+ -Wl,--no-add-needed
+
+define gb_LinkTarget__command_dynamiclink
+$(call gb_Helper_abbreviate_dirs,\
+ $(if $(CXXOBJECTS)$(GENCXXOBJECTS)$(EXTRAOBJECTLISTS),$(gb_CXX),$(gb_CC)) \
+ -shared \
+ $(if $(filter Library CppunitTest,$(TARGETTYPE)),$(gb_Library_TARGETTYPEFLAGS)) \
+ $(subst \d,$$,$(RPATH)) \
+ $(T_USE_LD) $(T_LDFLAGS) \
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_target,$(object))) \
+ $(foreach extraobjectlist,$(EXTRAOBJECTLISTS),`cat $(extraobjectlist)`) \
+ -Wl$(COMMA)--start-group $(foreach lib,$(LINKED_STATIC_LIBS),$(call gb_StaticLibrary_get_target,$(lib))) -Wl$(COMMA)--end-group \
+ $(T_LIBS) \
+ $(patsubst lib%.a,-l%,$(patsubst lib%.so,-l%,$(foreach lib,$(LINKED_LIBS),$(call gb_Library_get_filename,$(lib))))) \
+ -o $(1))
+endef
+
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+
+# Library class
+
+gb_Library_DEFS :=
+gb_Library_SYSPRE := lib
+gb_Library_UNOVERPRE := $(gb_Library_SYSPRE)uno_
+gb_Library_PLAINEXT := .a
+gb_Library_DLLEXT := .a
+gb_Library_RTEXT := gcc3$(gb_Library_PLAINEXT)
+
+gb_Library_OOOEXT := $(gb_Library_DLLPOSTFIX)$(gb_Library_PLAINEXT)
+gb_Library_UNOEXT := .uno$(gb_Library_PLAINEXT)
+
+endif
+
+# Prefix UNO library filenames with "lib"
+gb_Library_FILENAMES := \
+ $(foreach lib,$(gb_Library_OOOLIBS),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_OOOEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_NONE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_URE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OOO),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PRIVATELIBS_URE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_OOOEXT)) \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_RTEXT)) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):$(gb_Library_UNOVERPRE)$(lib)$(gb_Library_PLAINEXT)) \
+
+
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+
+gb_Library_FILENAMES += \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OXT),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_EXTENSIONLIBS),$(lib):$(lib)$(gb_Library_UNOEXT)) \
+
+gb_Library_LAYER := \
+ $(foreach lib,$(gb_Library_OOOLIBS),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_URE),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OOO),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OXT),$(lib):OXT) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_NONE),$(lib):NONE) \
+ $(foreach lib,$(gb_Library_PRIVATELIBS_URE),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_EXTENSIONLIBS),$(lib):OXT) \
+
+define gb_Library_Library_platform
+$(call gb_LinkTarget_get_target,$(2)) : LAYER := $(call gb_Library_get_layer,$(1))
+
+endef
+
+# CppunitTest class
+
+gb_CppunitTest_get_filename = libtest_$(1).a
+
+# No use for Cppunit targets now for Android (which would be just
+# static archives), they are just a waste of disk space.
+define gb_LinkTarget__command
+$(call gb_Output_announce,$(2),$(true),LNK,4)
+ $(call gb_Trace_StartRange,$(2),LNK)
+$(if $(filter CppunitTest,$(TARGETTYPE)), \
+ touch $(1), \
+ $(call gb_LinkTarget__command_staticlink,$(1)))
+ $(call gb_Trace_EndRange,$(2),LNK)
+endef
+
+endif
+
+# No DT_RPATH or DT_RUNPATH support in the Bionic dynamic linker so
+# don't bother generating such.
+
+define gb_Library_get_rpath
+endef
+
+define gb_Executable_get_rpath
+endef
+
+gb_LinkTarget_LDFLAGS := $(subst -Wl$(COMMA)-rpath-link$(COMMA)$(SYSBASE)/lib:$(SYSBASE)/usr/lib,,$(gb_LinkTarget_LDFLAGS))
+
+gb_Library__set_soversion_script_platform =
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/com_GCC_class.mk b/solenv/gbuild/platform/com_GCC_class.mk
new file mode 100644
index 000000000..d34464030
--- /dev/null
+++ b/solenv/gbuild/platform/com_GCC_class.mk
@@ -0,0 +1,255 @@
+# -*- 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/.
+#
+
+ifeq ($(gb_FULLDEPS),$(true))
+ifneq (,$(CCACHE_HARDLINK))
+# cannot move hardlink over itself, so create dep file directly, even if that
+# might leave a broken file behind in case the build is interrupted forcefully
+define gb_cxx_dep_generation_options
+-MMD -MT $(1) -MP -MF $(2)
+endef
+define gb_cxx_dep_copy
+endef
+else
+define gb_cxx_dep_generation_options
+-MMD -MT $(1) -MP -MF $(2)_
+endef
+define gb_cxx_dep_copy
+&& mv $(1)_ $(1)
+endef
+endif
+else
+define gb_cxx_dep_generation_options
+endef
+define gb_cxx_dep_copy
+endef
+endif
+
+# AsmObject class
+
+gb_AsmObject_get_source = $(1)/$(2).s
+
+# $(call gb_AsmObject__command,object,relative-source,source,dep-file)
+define gb_AsmObject__command
+$(call gb_Output_announce,$(2),$(true),ASM,3)
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) $(dir $(4)) && cd $(SRCDIR) && \
+ $(gb_CC) \
+ -x assembler-with-cpp \
+ $(T_LTOFLAGS) \
+ $(gb_AFLAGS) \
+ $(if $(HAVE_ASM_END_BRANCH_INS_SUPPORT),-DEND_BRANCH_INS_SUPPORT) \
+ -c $(3) \
+ -o $(1)) \
+ $(INCLUDE) && \
+ echo "$(1) : $(3)" > $(4)
+endef
+
+# CObject class
+
+# $(call gb_CObject__compiler,source,compiler)
+define gb_CObject__compiler
+ $(if $(filter %.c %.m,$(1)), \
+ $(if $(2), $(2), $(gb_CC)), \
+ $(if $(2), $(2), $(gb_CXX)))
+endef
+
+# When gb_LinkTarget_use_clang is used, filter out GCC flags that Clang doesn't know.
+# $(call gb_CObject__filter_out_clang_cflags,cflags)
+define gb_CObject__filter_out_clang_cflags
+ $(filter-out $(gb_FilterOutClangCFLAGS),$(1))
+endef
+
+# $(call gb_CObject__command_pattern,object,flags,source,dep-file,compiler-plugins,compiler)
+define gb_CObject__command_pattern
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) $(dir $(4)) && cd $(SRCDIR) && \
+ $(gb_COMPILER_SETUP) \
+ $(if $(5),$(gb_COMPILER_PLUGINS_SETUP)) \
+ $(call gb_CObject__compiler,$(3),$(6)) \
+ $(DEFS) \
+ $(T_LTOFLAGS) \
+ $(if $(VISIBILITY),,$(gb_VISIBILITY_FLAGS)) \
+ $(if $(WARNINGS_NOT_ERRORS),$(if $(ENABLE_WERROR),$(if $(PLUGIN_WARNINGS_AS_ERRORS),$(gb_COMPILER_PLUGINS_WARNINGS_AS_ERRORS))),$(gb_CFLAGS_WERROR)) \
+ $(if $(5),$(gb_COMPILER_PLUGINS)) \
+ $(if $(COMPILER_TEST),-fsyntax-only -ferror-limit=0 -Xclang -verify) \
+ $(if $(6), $(call gb_CObject__filter_out_clang_cflags,$(2)),$(2)) \
+ $(if $(WARNINGS_DISABLED),$(gb_CXXFLAGS_DISABLE_WARNINGS)) \
+ $(if $(EXTERNAL_CODE),$(gb_CXXFLAGS_Wundef),$(gb_DEFS_INTERNAL)) \
+ -c $(3) \
+ -o $(1) \
+ $(if $(COMPILER_TEST),,$(call gb_cxx_dep_generation_options,$(1),$(4))) \
+ $(INCLUDE) \
+ $(PCHFLAGS) \
+ $(if $(COMPILER_TEST),,$(call gb_cxx_dep_copy,$(4))) \
+ )
+endef
+
+# PrecompiledHeader class
+
+ifeq ($(COM_IS_CLANG),TRUE)
+gb_PrecompiledHeader_get_enableflags = -include-pch $(call gb_PrecompiledHeader_get_target,$(1),$(2))
+gb_PrecompiledHeader_EXT := .pch
+# Workaround: Apple Clang version 12.0.5 sometimes tries to compile instead of generating PCH
+# when used just with -c c++-header, so help it by being explicit.
+gb_PrecompiledHeader_emit_pch := -Xclang -emit-pch
+else
+gb_PrecompiledHeader_get_enableflags = \
+-include $(dir $(call gb_PrecompiledHeader_get_target,$(1),$(2)))$(notdir $(subst .gch,,$(call gb_PrecompiledHeader_get_target,$(1),$(2))))
+gb_PrecompiledHeader_EXT := .gch
+gb_PrecompiledHeader_emit_pch :=
+endif
+
+gb_PrecompiledHeader_extra_pch_cxxflags += $(PCH_INSTANTIATE_TEMPLATES)
+
+# Clang supports building extra object file where it puts code that would be shared by all users of the PCH.
+# Unlike with MSVC it is built as a separate step. The relevant options are used only when generating the PCH
+# and when creating the PCH's object file, normal compilations using the PCH do not need extra options.
+gb_PrecompiledHeader_pch_with_obj += $(BUILDING_PCH_WITH_OBJ)
+gb_PrecompiledHeader_extra_pch_cxxflags += $(BUILDING_PCH_WITH_OBJ)
+ifneq ($(BUILDING_PCH_WITH_OBJ),)
+# If using Clang's PCH extra object, we may need to strip unused sections, otherwise inline and template functions
+# emitted in that object may in some cases cause unresolved references to private symbols in other libraries.
+gb_LinkTarget_LDFLAGS += $(LD_GC_SECTIONS)
+gb_PrecompiledHeader_pch_with_obj += -ffunction-sections -fdata-sections
+# Enable generating more shared code and debuginfo in the PCH object file.
+gb_PrecompiledHeader_extra_pch_cxxflags += $(PCH_DEBUGINFO)
+ifeq ($(ENABLE_OPTIMIZED),)
+# -fmodules-codegen appears to be worth it only if not optimizing, otherwise optimizing all the functions emitted
+# in the PCH object file may take way too long, especially given that many of those may get thrown away
+gb_PrecompiledHeader_extra_pch_cxxflags += $(PCH_CODEGEN)
+endif
+endif
+
+# This is for MSVC's object file built directly as a side-effect of building the PCH.
+gb_PrecompiledHeader_get_objectfile =
+
+# $(call gb_PrecompiledHeader__command,pchfile,pchtarget,source,cxxflags,includes,linktargetmakefilename,compiler)
+define gb_PrecompiledHeader__command
+$(call gb_Output_announce,$(2),$(true),PCH,1)
+ $(call gb_Trace_StartRange,$(2),PCH)
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) $(dir $(call gb_PrecompiledHeader_get_dep_target,$(2),$(6))) && \
+ cd $(BUILDDIR)/ && \
+ CCACHE_DISABLE=1 $(gb_COMPILER_SETUP) \
+ $(if $(7),$(7),$(gb_CXX)) \
+ -x c++-header $(gb_PrecompiledHeader_emit_pch) \
+ $(if $(7), $(call gb_CObject__filter_out_clang_cflags,$(4)),$(4)) \
+ $(if $(WARNINGS_DISABLED),$(gb_CXXFLAGS_DISABLE_WARNINGS)) \
+ $(gb_COMPILERDEPFLAGS) \
+ $(if $(VISIBILITY),,$(gb_VISIBILITY_FLAGS)) \
+ $(if $(EXTERNAL_CODE),$(gb_CXXFLAGS_Wundef),$(gb_DEFS_INTERNAL)) \
+ $(gb_NO_PCH_TIMESTAMP) \
+ $(gb_PrecompiledHeader_extra_pch_cxxflags) \
+ $(5) \
+ $(call gb_cxx_dep_generation_options,$(1),$(call gb_PrecompiledHeader_get_dep_target_tmp,$(2),$(6))) \
+ -c $(patsubst %.cxx,%.hxx,$(3)) \
+ -o$(1) \
+ $(call gb_cxx_dep_copy,$(call gb_PrecompiledHeader_get_dep_target_tmp,$(2),$(6))) \
+ )
+ $(call gb_Trace_EndRange,$(2),PCH)
+endef
+
+ifeq ($(COM_IS_CLANG),TRUE)
+# Clang has -fno-pch-timestamp, just checksum the file for CCACHE_PCH_EXTSUM
+# $(call gb_PrecompiledHeader__sum_command,pchfile,pchtarget,source,cxxflags,includes,linktargetmakefilename,compiler)
+define gb_PrecompiledHeader__sum_command
+ $(SHA256SUM) $(1) >$(1).sum
+endef
+else
+# GCC does not generate the same .gch for the same input, so checksum the (preprocessed) input
+# $(call gb_PrecompiledHeader__sum_command,pchfile,pchtarget,source,cxxflags,includes,linktargetmakefilename,compiler)
+define gb_PrecompiledHeader__sum_command
+$(call gb_Helper_abbreviate_dirs,\
+ CCACHE_DISABLE=1 $(gb_COMPILER_SETUP) \
+ $(if $(7),$(7),$(gb_CXX)) \
+ -x c++-header \
+ $(4) \
+ $(if $(WARNINGS_DISABLED),$(gb_CXXFLAGS_DISABLE_WARNINGS)) \
+ $(gb_COMPILERDEPFLAGS) \
+ $(if $(VISIBILITY),,$(gb_VISIBILITY_FLAGS)) \
+ $(if $(EXTERNAL_CODE),$(gb_CXXFLAGS_Wundef),$(gb_DEFS_INTERNAL)) \
+ $(gb_NO_PCH_TIMESTAMP) \
+ $(5) \
+ -E $(patsubst %.cxx,%.hxx,$(3)) \
+ -o- \
+ | $(SHA256SUM) >$(1).sum \
+ )
+endef
+endif
+
+# not needed
+gb_PrecompiledHeader__create_reuse_files =
+gb_PrecompiledHeader__copy_reuse_files =
+
+# YaccTarget class
+
+define gb_YaccTarget__command
+$(call gb_Output_announce,$(2),$(true),YAC,3)
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(3)) && \
+ $(BISON) $(T_YACCFLAGS) -v --defines=$(4) -o $(5) $(1) && touch $(3) )
+
+endef
+
+# CppunitTest class
+
+ifeq ($(strip $(DEBUGCPPUNIT)),TRUE)
+ifeq ($(strip $(CPPUNITTRACE)),)
+CPPUNITTRACE := gdb --args
+endif
+ifeq ($(filter gdb,$(CPPUNITTRACE)),)
+$(error For DEBUGCPPUNIT=TRUE, CPPUNITTRACE must be a command that runs gdb)
+endif
+gb_CppunitTest_DEBUGCPPUNIT := -nx --batch --command=$(SRCDIR)/solenv/bin/gdbtrycatchtrace-stdout
+endif
+
+# ExternalProject class
+
+gb_ExternalProject_use_autoconf :=
+gb_ExternalProject_use_nmake :=
+
+# StaticLibrary class
+
+gb_StaticLibrary_get_filename = lib$(1).a
+gb_StaticLibrary_PLAINEXT := .a
+gb_StaticLibrary_StaticLibrary_platform :=
+
+gb_LinkTarget_get_linksearchpath_for_layer = \
+ -L$(WORKDIR)/LinkTarget/StaticLibrary \
+ -L$(call gb_Library_get_sdk_link_dir) \
+ $(foreach layer,\
+ $(subst +, ,$(patsubst $(1):%.,%,\
+ $(filter $(1):%.,$(gb_LinkTarget_LAYER_LINKPATHS)))),\
+ $(patsubst $(layer):%,-L%,\
+ $(filter $(layer):%,$(gb_Library_LAYER_DIRS))))
+
+
+gb_ICU_PRECOMMAND := $(call gb_Helper_extend_ld_path,$(WORKDIR_FOR_BUILD)/UnpackedTarball/icu/source/lib)
+
+# UIConfig class
+
+# macOS sort(1) cannot read a response file
+define gb_UIConfig__command
+$(call gb_Helper_abbreviate_dirs,\
+ $(SORT) -u $(UI_IMAGELISTS) /dev/null > $@ \
+)
+
+endef
+
+define gb_UIConfig__gla11y_command
+$(call gb_Helper_abbreviate_dirs,\
+ $(gb_UIConfig_LXML_PATH) $(if $(SYSTEM_LIBXML)$(SYSTEM_LIBXSLT),,$(gb_Helper_set_ld_path)) \
+ $(call gb_ExternalExecutable_get_command,python) \
+ $(gb_UIConfig_gla11y_SCRIPT) $(gb_UIConfig_gla11y_PARAMETERS) -o $@ $(UIFILES)
+)
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/com_GCC_defs.mk b/solenv/gbuild/platform/com_GCC_defs.mk
new file mode 100644
index 000000000..bdf1684eb
--- /dev/null
+++ b/solenv/gbuild/platform/com_GCC_defs.mk
@@ -0,0 +1,335 @@
+# -*- 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/.
+#
+
+gb_AWK := awk
+
+gb_CLASSPATHSEP := :
+gb_LICENSE := LICENSE
+gb_README = README_$(1)
+
+# use CC/CXX if they are nondefaults
+ifneq ($(origin CC),default)
+gb_CC := $(CC)
+gb_GCCP := $(CC)
+else
+gb_CC := gcc
+gb_GCCP := gcc
+endif
+
+ifneq ($(origin CXX),default)
+gb_CXX := $(CXX)
+else
+gb_CXX := g++
+endif
+
+ifneq ($(origin AR),default)
+gb_AR := $(AR)
+else
+gb_AR := $(shell $(CC) -print-prog-name=ar)
+endif
+
+# shell setup (env.vars) for the compiler
+gb_COMPILER_SETUP :=
+
+ifeq ($(strip $(gb_COMPILEROPTFLAGS)),)
+gb_COMPILEROPTFLAGS := -O2
+endif
+
+gb_AFLAGS := $(AFLAGS)
+
+gb_COMPILERDEFS := \
+ -DBOOST_ERROR_CODE_HEADER_ONLY \
+ -DBOOST_SYSTEM_NO_DEPRECATED \
+ -DCPPU_ENV=$(CPPU_ENV) \
+ $(if $(filter EMSCRIPTEN,$(OS)),-U_FORTIFY_SOURCE) \
+
+# enable debug STL
+ifeq ($(gb_ENABLE_DBGUTIL),$(true))
+ifneq ($(HAVE_LIBSTDCPP),)
+gb_COMPILERDEFS_STDLIB_DEBUG = -D_GLIBCXX_DEBUG
+else
+ifneq ($(LIBCPP_DEBUG),)
+gb_COMPILERDEFS_STDLIB_DEBUG = $(LIBCPP_DEBUG)
+endif
+endif
+gb_COMPILERDEFS += $(gb_COMPILERDEFS_STDLIB_DEBUG)
+endif
+
+gb_CFLAGS_COMMON := \
+ -Wall \
+ -Wendif-labels \
+ -Wextra \
+ -Wstrict-prototypes \
+ -Wundef \
+ -Wunreachable-code \
+ $(if $(or $(and $(COM_IS_CLANG),$(or $(findstring icecc,$(CC)),$(findstring icecc,$(CCACHE_PREFIX)))),$(findstring sccache,$(CC))),,-Wunused-macros) \
+ $(if $(COM_IS_CLANG),-Wembedded-directive) \
+ -finput-charset=UTF-8 \
+ -fmessage-length=0 \
+ -fno-common \
+ -pipe \
+ $(if $(filter EMSCRIPTEN,$(OS)),-fno-stack-protector,-fstack-protector-strong) \
+
+gb_CXXFLAGS_COMMON := \
+ -Wall \
+ -Wno-missing-braces \
+ -Wnon-virtual-dtor \
+ -Wendif-labels \
+ -Wextra \
+ -Wundef \
+ -Wunreachable-code \
+ -Wshadow \
+ $(if $(or $(and $(COM_IS_CLANG),$(or $(findstring icecc,$(CXX)),$(findstring icecc,$(CCACHE_PREFIX)))),$(findstring sccache,$(CXX))),,-Wunused-macros) \
+ $(if $(COM_IS_CLANG),-Wembedded-directive) \
+ -finput-charset=UTF-8 \
+ -fmessage-length=0 \
+ -fno-common \
+ -pipe \
+ $(if $(filter EMSCRIPTEN,$(OS)),-fno-stack-protector,-fstack-protector-strong) \
+
+ifeq ($(HAVE_WDEPRECATED_COPY_DTOR),TRUE)
+gb_CXXFLAGS_COMMON += -Wdeprecated-copy-dtor
+endif
+
+gb_CXXFLAGS_DISABLE_WARNINGS = -w
+
+ifeq ($(HAVE_BROKEN_GCC_WMAYBE_UNINITIALIZED),TRUE)
+gb_CXXFLAGS_COMMON += -Wno-maybe-uninitialized
+endif
+
+ifeq ($(HAVE_BROKEN_GCC_WSTRINGOP_OVERFLOW),TRUE)
+gb_CXXFLAGS_COMMON += -Wno-stringop-overflow
+endif
+
+gb_CXXFLAGS_Wundef = -Wno-undef
+
+gb_CXXFLAGS_include := -include$(gb_SPACE)
+
+ifeq ($(strip $(gb_GCOV)),YES)
+gb_CFLAGS_COMMON += -fprofile-arcs -ftest-coverage
+gb_CXXFLAGS_COMMON += -fprofile-arcs -ftest-coverage
+gb_LinkTarget_LDFLAGS += -fprofile-arcs -lgcov
+gb_COMPILEROPTFLAGS := -O0
+endif
+
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+gb_CFLAGS_COMMON += -ffunction-sections -fdata-sections
+gb_CXXFLAGS_COMMON += -ffunction-sections -fdata-sections
+ifneq ($(OS),EMSCRIPTEN)
+gb_LinkTarget_LDFLAGS += -Wl,--gc-sections
+endif
+endif
+
+ifeq ($(COM_IS_CLANG),TRUE)
+gb_CXXFLAGS_COMMON += \
+ -Wimplicit-fallthrough \
+ -Wunused-exception-parameter \
+ -Wrange-loop-analysis
+else
+gb_CFLAGS_COMMON += \
+ -Wduplicated-cond \
+ -Wlogical-op \
+ -Wshift-overflow=2
+gb_CXXFLAGS_COMMON += \
+ -Wduplicated-cond \
+ -Wlogical-op \
+ -Wshift-overflow=2 \
+ -Wunused-const-variable=1
+endif
+
+# GCC 8 -Wcast-function-type (included in -Wextra) unhelpfully even warns on reinterpret_cast
+# between incompatible function types:
+ifeq ($(shell expr '$(GCC_VERSION)' '>=' 800),1)
+gb_CXXFLAGS_COMMON += \
+ -Wno-cast-function-type
+endif
+
+# If CC or CXX already include -fvisibility=hidden, don't duplicate it
+ifeq (,$(filter -fvisibility=hidden,$(CC)))
+gb_VISIBILITY_FLAGS := -fvisibility=hidden
+endif
+gb_VISIBILITY_FLAGS_CXX := -fvisibility-inlines-hidden
+gb_CXXFLAGS_COMMON += $(gb_VISIBILITY_FLAGS_CXX)
+
+gb_LinkTarget_LDFLAGS += $(if $(filter EMSCRIPTEN,$(OS)),-fno-stack-protector,-fstack-protector-strong)
+
+ifneq ($(gb_ENABLE_PCH),)
+ifeq ($(COM_IS_CLANG),TRUE)
+# Clang by default includes in the PCH timestamps of the files it was
+# generated from, which would make the PCH be a "new" file for ccache
+# even if the file has not actually changed. Disabling the timestamp
+# prevents this at the cost of risking using an outdated PCH (which
+# should be unlikely, given that gbuild has dependencies set up
+# for our includes and system includes are unlikely to change).
+gb_NO_PCH_TIMESTAMP := -Xclang -fno-pch-timestamp
+else
+gb_CFLAGS_COMMON += -fpch-preprocess -Winvalid-pch
+gb_CXXFLAGS_COMMON += -fpch-preprocess -Winvalid-pch
+gb_NO_PCH_TIMESTAMP :=
+endif
+endif
+
+gb_CFLAGS_WERROR = $(if $(ENABLE_WERROR),-Werror)
+
+# This is the default in non-C++11 mode
+ifeq ($(COM_IS_CLANG),TRUE)
+gb_CXX03FLAGS := -std=gnu++98 -Werror=c++11-extensions -Wno-c++11-long-long \
+ -Wno-deprecated-declarations
+else
+gb_CXX03FLAGS := -std=gnu++98 -Wno-long-long \
+ -Wno-variadic-macros -Wno-non-virtual-dtor -Wno-deprecated-declarations
+endif
+
+# On Windows MSVC only supports C90 so force gnu89 (especially in clang) to
+# to catch potential gnu89/C90 incompatibilities locally.
+gb_CFLAGS_COMMON += -std=gnu89
+
+ifeq ($(ENABLE_LTO),TRUE)
+ifeq ($(COM_IS_CLANG),TRUE)
+gb_LTOFLAGS := -flto=thin
+ifeq (,$(index,iOS MACOSX,$(OS)))
+gb_LTOPLUGINFLAGS := --plugin $(if $(LD_PLUGIN),$(LD_PLUGIN),LLVMgold.so)
+endif
+else
+# use parallelism based on make's job handling
+gb_LTOFLAGS := -flto=jobserver -fuse-linker-plugin -O2
+# clang does not support -flto=<number>
+gb_CLANG_LTOFLAGS := -flto=thin
+endif
+endif
+
+gb_LinkTarget_EXCEPTIONFLAGS := \
+ -DEXCEPTIONS_ON \
+ -fexceptions
+
+ifeq ($(gb_ENABLE_DBGUTIL),$(false))
+# Clang doesn't have this option
+ifeq ($(HAVE_GCC_FNO_ENFORCE_EH_SPECS),TRUE)
+gb_LinkTarget_EXCEPTIONFLAGS += \
+ -fno-enforce-eh-specs
+gb_FilterOutClangCFLAGS += -fno-enforce-eh-specs
+endif
+endif
+
+gb_PrecompiledHeader_EXCEPTIONFLAGS := $(gb_LinkTarget_EXCEPTIONFLAGS)
+
+# We turn on and off this one depending on whether icecream and/or ccache are used,
+# and changing cxxflags cause PCH rebuilds, so e.g. a plain temporary 'CCACHE_DISABLE=1'
+# would cause a rebuild. Ignore the flag there, it's irrelevant for PCH use anyway.
+gb_PrecompiledHeader_ignore_flags_for_flags_file := -Wunused-macros
+
+# optimization level
+gb_COMPILERNOOPTFLAGS := -O0 -fstrict-aliasing -fstrict-overflow
+gb_COMPILERDEBUGOPTFLAGS := -Og
+
+ifeq ($(OS),ANDROID)
+gb_DEBUGINFO_FLAGS=-glldb
+# Clang does not know -ggdb2 or some other options
+else ifeq ($(HAVE_GCC_GGDB2),TRUE)
+gb_DEBUGINFO_FLAGS=-ggdb2
+else
+gb_DEBUGINFO_FLAGS=-g2
+endif
+gb_LINKER_DEBUGINFO_FLAGS=
+
+ifeq ($(HAVE_EXTERNAL_DWARF),TRUE)
+gb_DEBUGINFO_FLAGS+=-gsplit-dwarf
+# GCC 11 defaults to -gdwarf-5, which GDB 10 doesn't support in split debug info
+ifeq ($(COM_IS_CLANG),)
+gb_DEBUGINFO_FLAGS+=-gdwarf-4
+endif
+endif
+
+ifeq ($(HAVE_CLANG_DEBUG_INFO_KIND_CONSTRUCTOR),TRUE)
+gb_DEBUGINFO_FLAGS+=-Xclang -debug-info-kind=constructor
+endif
+
+ifeq ($(ENABLE_GDB_INDEX),TRUE)
+gb_LINKER_DEBUGINFO_FLAGS += -Wl,--gdb-index
+gb_DEBUGINFO_FLAGS += -ggnu-pubnames
+endif
+
+gb_LinkTarget_INCLUDE :=\
+ $(SOLARINC) \
+ -I$(BUILDDIR)/config_$(gb_Side) \
+
+ifeq ($(COM_IS_CLANG),TRUE)
+gb_COMPILER_TEST_FLAGS := -Xclang -plugin-arg-loplugin -Xclang --unit-test-mode
+ifeq ($(COMPILER_PLUGIN_TOOL),)
+gb_COMPILER_PLUGINS := -Xclang -load -Xclang $(BUILDDIR)/compilerplugins/clang/plugin.so -Xclang -add-plugin -Xclang loplugin
+ifneq ($(COMPILER_PLUGIN_WARNINGS_ONLY),)
+gb_COMPILER_PLUGINS += -Xclang -plugin-arg-loplugin -Xclang \
+ --warnings-only='$(COMPILER_PLUGIN_WARNINGS_ONLY)'
+endif
+else
+gb_COMPILER_PLUGINS := -Xclang -load -Xclang $(BUILDDIR)/compilerplugins/clang/plugin.so -Xclang -plugin -Xclang loplugin $(foreach plugin,$(COMPILER_PLUGIN_TOOL), -Xclang -plugin-arg-loplugin -Xclang $(plugin))
+ifneq ($(UPDATE_FILES),)
+gb_COMPILER_PLUGINS += -Xclang -plugin-arg-loplugin -Xclang --scope=$(UPDATE_FILES)
+endif
+endif
+ifeq ($(COMPILER_PLUGINS_DEBUG),TRUE)
+gb_COMPILER_PLUGINS += -Xclang -plugin-arg-loplugin -Xclang --debug
+endif
+# set CCACHE_CPP2=1 to prevent clang generating spurious warnings
+gb_COMPILER_SETUP += CCACHE_CPP2=1
+gb_COMPILER_PLUGINS_SETUP := ICECC_EXTRAFILES=$(SRCDIR)/include/sal/log-areas.dox CCACHE_EXTRAFILES=$(SRCDIR)/include/sal/log-areas.dox SCCACHE_EXTRAFILES=$(SRCDIR)/include/sal/log-areas.dox
+gb_COMPILER_PLUGINS_WARNINGS_AS_ERRORS := \
+ -Xclang -plugin-arg-loplugin -Xclang --warnings-as-errors
+else
+# Set CCACHE_CPP2 to prevent GCC -Werror=implicit-fallthrough= when ccache strips comments from C
+# code (which still needs /*fallthrough*/-style comments to silence that warning):
+ifeq ($(ENABLE_WERROR),TRUE)
+gb_COMPILER_SETUP += CCACHE_CPP2=1
+endif
+gb_COMPILER_TEST_FLAGS :=
+gb_COMPILER_PLUGINS :=
+gb_COMPILER_PLUGINS_SETUP :=
+gb_COMPILER_PLUGINS_WARNINGS_AS_ERRORS :=
+endif
+
+# Executable class
+
+gb_Executable_EXT_for_build :=
+
+# Helper class
+
+ifeq ($(OS_FOR_BUILD),MACOSX)
+gb_Helper_LIBRARY_PATH_VAR := DYLD_LIBRARY_PATH
+else ifeq ($(OS_FOR_BUILD),AIX)
+gb_Helper_LIBRARY_PATH_VAR := LIBPATH
+else ifeq ($(OS_FOR_BUILD),WNT)
+# In theory possible if cross-compiling to some Unix from Windows,
+# in practice strongly discouraged to even try that
+gb_Helper_LIBRARY_PATH_VAR := PATH
+else ifeq ($(OS_FOR_BUILD),HAIKU)
+gb_Helper_LIBRARY_PATH_VAR := LIBRARY_PATH
+else
+gb_Helper_LIBRARY_PATH_VAR := LD_LIBRARY_PATH
+endif
+
+gb_Helper_set_ld_path := $(gb_Helper_LIBRARY_PATH_VAR)=$${$(gb_Helper_LIBRARY_PATH_VAR):+$$$(gb_Helper_LIBRARY_PATH_VAR):}"$(INSTROOT_FOR_BUILD)/$(LIBO_URE_LIB_FOLDER_FOR_BUILD):$(INSTROOT_FOR_BUILD)/$(LIBO_LIB_FOLDER_FOR_BUILD)"
+
+# $(1): list of : separated directory pathnames to append to the ld path
+define gb_Helper_extend_ld_path
+$(gb_Helper_set_ld_path):$(1)
+endef
+
+# Convert path to file URL.
+define gb_Helper_make_url
+file://$(strip $(1))
+endef
+
+gb_Helper_get_rcfile = $(1)rc
+
+ifneq ($(gb_ENABLE_PCH),)
+# Enable use of .sum files for PCHs.
+gb_COMPILER_SETUP += CCACHE_PCH_EXTSUM=1
+endif
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/com_MSC_class.mk b/solenv/gbuild/platform/com_MSC_class.mk
new file mode 100644
index 000000000..06d21ecd4
--- /dev/null
+++ b/solenv/gbuild/platform/com_MSC_class.mk
@@ -0,0 +1,742 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# Convert path to file URL.
+define gb_Helper_make_url
+file:///$(strip $(1))
+endef
+
+# YaccTarget class
+
+define gb_YaccTarget__command
+$(call gb_Output_announce,$(2),$(true),YAC,3)
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(3)) && \
+ $(BISON) $(T_YACCFLAGS) --defines=$(4) -o $(5) $(1) && touch $(3) )
+
+endef
+
+# CObject class
+
+# $(call gb_CObject__compiler,flags,source,compiler)
+define gb_CObject__compiler
+ $(if $(filter YES,$(LIBRARY_X64)), $(CXX_X64_BINARY), \
+ $(if $(filter YES,$(PE_X86)), $(CXX_X86_BINARY), \
+ $(if $(filter %.c,$(2)), \
+ $(if $(3), $(3), $(gb_CC)), \
+ $(if $(filter -clr,$(1)), \
+ $(MSVC_CXX) -I$(SRCDIR)/solenv/clang-cl, \
+ $(if $(3), $(3), $(gb_CXX))))))
+endef
+
+# Avoid annoying warning D9025 about overriding command-line arguments.
+gb_Helper_remove_overridden_flags = \
+ $(filter-out -W4 -w -arch:SSE -arch:SSE2 -arch:AVX -arch:AVX2 -Od -O2 -Zc:inline -Zc:inline- \
+ -Zc:dllexportInlines -Zc:dllexportInlines- -EHs -EHa -DNOMINMAX -UNOMINMAX -D_X86_=1 -U_X86_ \
+ -D_AMD64_=1 -U_AMD64_,$(1)) \
+ $(lastword $(filter -W4 -w,$(1))) \
+ $(lastword $(filter -Od -O2,$(1))) \
+ $(lastword $(filter -arch:SSE -arch:SSE2 -arch:AVX -arch:AVX2,$(1))) \
+ $(lastword $(filter -EHs -EHa,$(1))) \
+ $(lastword $(filter -DNOMINMAX -UNOMINMAX,$(1))) \
+ $(lastword $(filter -D_X86_=1 -U_X86_,$(1))) \
+ $(lastword $(filter -D_AMD64_=1 -U_AMD64_,$(1))) \
+ $(lastword $(filter -Zc:inline -Zc:inline-,$(1))) \
+ $(lastword $(filter -Zc:dllexportInlines -Zc:dllexportInlines-,$(1)))
+
+# $(call gb_CObject__command_pattern,object,flags,source,dep-file,compiler-plugins,compiler)
+define gb_CObject__command_pattern
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) $(dir $(4)) && \
+ unset INCLUDE && \
+ $(if $(and $(gb_COMPILERDEPFLAGS),$(T_USE_CLANG)), export SHOWINCLUDES_PREFIX="${LO_CLANG_SHOWINCLUDES_PREFIX}" &&) \
+ $(gb_COMPILER_SETUP) \
+ $(call gb_CObject__compiler,$(2),$(3),$(6)) \
+ $(call gb_Helper_remove_overridden_flags, \
+ $(DEFS) \
+ $(if $(filter YES,$(LIBRARY_X64)), ,$(gb_LTOFLAGS)) \
+ $(2) $(if $(WARNINGS_DISABLED),$(gb_CXXFLAGS_DISABLE_WARNINGS)) \
+ $(if $(EXTERNAL_CODE), \
+ $(if $(filter -clr,$(2)),,$(if $(COM_IS_CLANG),-Wno-undef)), \
+ $(gb_DEFS_INTERNAL)) \
+ $(if $(WARNINGS_NOT_ERRORS),$(if $(ENABLE_WERROR),$(if $(PLUGIN_WARNINGS_AS_ERRORS),$(gb_COMPILER_PLUGINS_WARNINGS_AS_ERRORS))),$(gb_CFLAGS_WERROR)) \
+ $(if $(filter -clr,$(2)),,$(if $(5),$(gb_COMPILER_PLUGINS))) \
+ $(if $(COMPILER_TEST),-fsyntax-only -ferror-limit=0 -Xclang -verify) \
+ $(PCHFLAGS) \
+ $(if $(COMPILER_TEST),,$(gb_COMPILERDEPFLAGS)) \
+ $(if $(filter YES,$(LIBRARY_X64)), -U_X86_ -D_AMD64_,) \
+ $(if $(filter YES,$(PE_X86)), -D_X86_ -U_AMD64_,)) \
+ $(INCLUDE) \
+ -Fd$(PDBFILE) \
+ -c $(3) \
+ -Fo$(1)) \
+ $(if $(COMPILER_TEST),,$(call gb_create_deps,$(4),$(1),$(3)))
+endef
+
+# PrecompiledHeader class
+
+gb_PrecompiledHeader_get_enableflags = \
+ -Yu$(SRCDIR)/$(3).hxx \
+ -FI$(SRCDIR)/$(3).hxx \
+ -Fp$(call gb_PrecompiledHeader_get_target,$(1),$(2)) \
+ $(gb_PCHWARNINGS)
+
+gb_PrecompiledHeader_EXT := .pch
+
+# MSVC PCH needs extra .obj created during the creation of the PCH file
+gb_PrecompiledHeader_get_objectfile = $(1).obj
+
+# $(call gb_PrecompiledHeader__command,pchfile,pchtarget,source,cxxflags,includes,linktargetmakefilename,compiler)
+define gb_PrecompiledHeader__command
+$(call gb_Output_announce,$(2),$(true),PCH,1)
+ $(call gb_Trace_StartRange,$(2),PCH)
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) $(dir $(call gb_PrecompiledHeader_get_dep_target,$(2),$(6))) && \
+ unset INCLUDE && \
+ $(if $(and $(gb_COMPILERDEPFLAGS),$(T_USE_CLANG)), export SHOWINCLUDES_PREFIX="${LO_CLANG_SHOWINCLUDES_PREFIX}" &&) \
+ CCACHE_DISABLE=1 $(gb_COMPILER_SETUP) \
+ $(call gb_CObject__compiler,$(4),$(3),$(7)) \
+ $(call gb_Helper_remove_overridden_flags, \
+ $(4) $(if $(WARNINGS_DISABLED),$(gb_CXXFLAGS_DISABLE_WARNINGS))) \
+ -Fd$(PDBFILE) \
+ $(if $(EXTERNAL_CODE),$(if $(COM_IS_CLANG),-Wno-undef),$(gb_DEFS_INTERNAL)) \
+ $(if $(filter YES,$(LIBRARY_X64)), ,$(gb_LTOFLAGS)) \
+ $(gb_COMPILERDEPFLAGS) \
+ $(gb_NO_PCH_TIMESTAMP) \
+ $(5) \
+ -c $(3) \
+ -Yc$(notdir $(patsubst %.cxx,%.hxx,$(3))) -I$(dir $(patsubst %.cxx,%.hxx,$(3))) -Fp$(1) -Fo$(1).obj) \
+ $(call gb_create_deps,$(call gb_PrecompiledHeader_get_dep_target_tmp,$(2),$(6)),$(1),$(3))
+ $(call gb_Trace_EndRange,$(2),PCH)
+endef
+
+ifeq ($(COM_IS_CLANG),TRUE)
+# Clang has -fno-pch-timestamp, just checksum the file for CCACHE_PCH_EXTSUM
+# $(call gb_PrecompiledHeader__sum_command,pchfile,pchtarget,source,cxxflags,includes,linktargetmakefilename,compiler)
+define gb_PrecompiledHeader__sum_command
+ $(SHA256SUM) $(1) >$(1).sum
+endef
+else
+# MSVC does not generate the same .pch for the same input, so checksum the (preprocessed) input
+# $(call gb_PrecompiledHeader__sum_command,pchfile,pchtarget,source,cxxflags,includes,linktargetmakefilename,compiler)
+define gb_PrecompiledHeader__sum_command
+$(call gb_Helper_abbreviate_dirs,\
+ unset INCLUDE && \
+ CCACHE_DISABLE=1 $(gb_COMPILER_SETUP) \
+ $(call gb_CObject__compiler,$(4),$(3),$(7)) \
+ $(call gb_Helper_remove_overridden_flags, \
+ $(4)$(if $(WARNINGS_DISABLED),$(gb_CXXFLAGS_DISABLE_WARNINGS))) \
+ $(if $(EXTERNAL_CODE),$(if $(COM_IS_CLANG),-Wno-undef),$(gb_DEFS_INTERNAL)) \
+ $(gb_LTOFLAGS) \
+ $(5) \
+ -E $(3) \
+ 2>&1 | $(SHA256SUM) >$(1).sum \
+ )
+endef
+endif
+
+# When building a PCH, MSVC also creates a .pdb file with debug info. So for reuse
+# add the .pdb to the PCH's files and then use the .pdb also for linktargets that reuse the PCH.
+# call gb_PrecompiledHeader__create_reuse_files,linktarget,pchtarget,linktargetmakefilename
+define gb_PrecompiledHeader__create_reuse_files
+rm -f $(call gb_PrecompiledHeader_get_target,$(2),$(3)).pdb; \
+if test -f $(call gb_LinkTarget_get_pdbfile_in,$(1)); then \
+ cp $(call gb_LinkTarget_get_pdbfile_in,$(1)) $(call gb_PrecompiledHeader_get_target,$(2),$(3)).pdb; \
+fi
+endef
+
+# call gb_PrecompiledHeader__copy_reuse_files,linktarget,pchtarget,linktargetmakefilename
+define gb_PrecompiledHeader__copy_reuse_files
+rm -f $(call gb_LinkTarget_get_pdbfile_in,$(1)); \
+if test -f $(call gb_PrecompiledHeader_get_target,$(2),$(3)).pdb; then \
+ cp $(call gb_PrecompiledHeader_get_target,$(2),$(3)).pdb $(call gb_LinkTarget_get_pdbfile_in,$(1)); \
+fi
+endef
+
+# AsmObject class
+ifeq ($(CPUNAME),AARCH64)
+gb_AsmObject_get_source = $(1)/$(2).S
+
+# Code needs a preprocessor step .S -> .asm -> .o
+define gb_AsmObject__command
+$(call gb_Output_announce,$(2),$(true),ASM,3)
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) $(dir $(4)) && \
+ "$(CC)" -nologo -EP -D_M_ARM64 $(SOLARINC) $(3) > $(subst .o,.asm,$(1)) && \
+ "$(ML_EXE)" $(gb_AFLAGS) -g -errorReport:prompt -o $(1) $(subst .o,.asm,$(1)), \
+ ) && \
+ echo "$(1) : $(3)" > $(4)
+endef
+
+else # !AARCH64
+gb_AsmObject_get_source = $(1)/$(2).asm
+
+define gb_AsmObject__command
+$(call gb_Output_announce,$(2),$(true),ASM,3)
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) $(dir $(4)) && \
+ "$(ML_EXE)" \
+ $(if $(filter X86_64,$(CPUNAME)),, /safeseh) \
+ /c /Cp $(gb_AFLAGS) -D$(COM) /Fo$(1) $(3)) && \
+ echo "$(1) : $(3)" > $(4)
+endef
+
+endif
+
+# LinkTarget class
+
+gb_LinkTarget_CFLAGS := $(gb_CFLAGS)
+gb_LinkTarget_CXXFLAGS := $(gb_CXXFLAGS)
+gb_LinkTarget_CXXCLRFLAGS := $(gb_CXXCLRFLAGS)
+
+gb_LinkTarget_INCLUDE :=\
+ $(SOLARINC) \
+ $(foreach inc,$(subst ;, ,$(JDKINC)),-I$(inc)) \
+ -I$(BUILDDIR)/config_$(gb_Side) \
+
+# We must name the .pdb like libname.pdb, not libname.\(dll\|exe\|pyd\).pdb,
+# otherwise WinDbg does not find it.
+define gb_LinkTarget__get_pdb_filename
+$(patsubst %.dll,%.pdb,$(patsubst %.exe,%.pdb,$(patsubst %.bin,%.bin.pdb,$(patsubst %.pyd,%.pdb,$(1)))))
+endef
+
+gb_LinkTarget_get_pdbfile_in = \
+ $(WORKDIR)/LinkTarget/$(call gb_LinkTarget__get_workdir_linktargetname,$(1)).objects.pdb
+
+gb_LinkTarget_get_pdbfile_out = \
+ $(call gb_LinkTarget__get_pdb_filename,$(WORKDIR)/LinkTarget/$(call gb_LinkTarget__get_workdir_linktargetname,$(1)))
+
+gb_LinkTarget_get_ilkfile = \
+ $(WORKDIR)/LinkTarget/$(call gb_LinkTarget__get_workdir_linktargetname,$(1)).ilk
+
+gb_LinkTarget_get_manifestfile = \
+ $(WORKDIR)/LinkTarget/$(call gb_LinkTarget__get_workdir_linktargetname,$(1)).manifest
+
+gb_LinkTarget_get_linksearchpath_for_layer = \
+ -LIBPATH:$(WORKDIR)/LinkTarget/StaticLibrary \
+ -LIBPATH:$(INSTDIR)/$(SDKDIRNAME)/lib \
+ $(if $(filter OXT,$(1)),\
+ -LIBPATH:$(WORKDIR)/LinkTarget/ExtensionLibrary, \
+ -LIBPATH:$(WORKDIR)/LinkTarget/Library)
+
+# avoid fatal error LNK1170 for Library_merged
+define gb_LinkTarget_MergedResponseFile
+cat $${RESPONSEFILE} | sed 's/ /\n/g' | grep -v '^$$' > $${RESPONSEFILE}.1 && \
+mv $${RESPONSEFILE}.1 $${RESPONSEFILE} &&
+endef
+
+gb_MSC_SUBSYSTEM_VERSION=$(COMMA)$(if $(filter AARCH64,$(CPUNAME)),6.02,6.01)
+
+# the sort on the libraries is used to filter out duplicates to keep commandline
+# length in check - otherwise the dupes easily hit the limit when linking mergedlib
+define gb_LinkTarget__command
+$(call gb_Output_announce,$(2),$(true),LNK,4)
+ $(call gb_Trace_StartRange,$(2),LNK)
+$(call gb_Helper_abbreviate_dirs,\
+ rm -f $(1) && \
+ RESPONSEFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),100, \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_target,$(object))) \
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_target,$(object))) \
+ $(foreach object,$(CXXCLROBJECTS),$(call gb_CxxClrObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXCLROBJECTS),$(call gb_GenCxxClrObject_get_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_target,$(object))) \
+ $(foreach extraobjectlist,$(EXTRAOBJECTLISTS),$(shell cat $(extraobjectlist))) \
+ $(PCHOBJS) $(NATIVERES)) && \
+ $(if $(filter $(call gb_Library__get_workdir_linktargetname,merged),$(2)),$(call gb_LinkTarget_MergedResponseFile)) \
+ unset INCLUDE && \
+ $(gb_LINK) \
+ $(if $(filter Library CppunitTest,$(TARGETTYPE)),$(gb_Library_TARGETTYPEFLAGS)) \
+ $(if $(filter StaticLibrary,$(TARGETTYPE)),-LIB) \
+ $(if $(filter Executable,$(TARGETTYPE)),$(gb_Executable_TARGETTYPEFLAGS)) \
+ $(if $(T_SYMBOLS),$(if $(filter Executable Library CppunitTest,$(TARGETTYPE)),$(gb_Windows_PE_TARGETTYPEFLAGS_DEBUGINFO)),) \
+ $(if $(filter YES,$(TARGETGUI)), -SUBSYSTEM:WINDOWS$(gb_MSC_SUBSYSTEM_VERSION), -SUBSYSTEM:CONSOLE$(gb_MSC_SUBSYSTEM_VERSION)) \
+ $(if $(filter YES,$(LIBRARY_X64)), -MACHINE:X64) \
+ $(if $(filter YES,$(PE_X86)), -MACHINE:X86) \
+ $(if $(filter YES,$(LIBRARY_X64)), \
+ -LIBPATH:$(COMPATH)/lib/x64 \
+ -LIBPATH:$(WINDOWS_SDK_HOME)/lib/x64 \
+ -LIBPATH:$(UCRTSDKDIR)lib/$(UCRTVERSION)/ucrt/x64 \
+ $(if $(filter 80 81 10,$(WINDOWS_SDK_VERSION)),-LIBPATH:$(WINDOWS_SDK_HOME)/lib/$(WINDOWS_SDK_LIB_SUBDIR)/um/x64)) \
+ $(if $(filter YES,$(PE_X86)), \
+ -LIBPATH:$(COMPATH)/lib/x86 \
+ -LIBPATH:$(WINDOWS_SDK_HOME)/lib/x86 \
+ -LIBPATH:$(UCRTSDKDIR)lib/$(UCRTVERSION)/ucrt/x86 \
+ $(if $(filter 80 81 10,$(WINDOWS_SDK_VERSION)),-LIBPATH:$(WINDOWS_SDK_HOME)/lib/$(WINDOWS_SDK_LIB_SUBDIR)/um/x86)) \
+ $(T_USE_LD) $(T_LDFLAGS) \
+ $(if $(filter Library CppunitTest Executable,$(TARGETTYPE)),/NATVIS:$(SRCDIR)/solenv/vs/LibreOffice.natvis) \
+ @$${RESPONSEFILE} \
+ $(foreach lib,$(sort $(LINKED_LIBS)),$(call gb_Library_get_ilibfilename,$(lib))) \
+ $(foreach lib,$(sort $(LINKED_STATIC_LIBS)),$(call gb_StaticLibrary_get_filename,$(lib))) \
+ $(if $(filter-out StaticLibrary,$(TARGETTYPE)),\
+ $(sort $(T_LIBS)) user32.lib \
+ -manifestfile:$(WORKDIR)/LinkTarget/$(2).manifest \
+ -pdb:$(call gb_LinkTarget__get_pdb_filename,$(WORKDIR)/LinkTarget/$(2))) \
+ $(if $(ILIBTARGET),-out:$(1) -implib:$(ILIBTARGET),-out:$(1)) \
+ | LC_ALL=C $(GBUILDDIR)/platform/filter-creatingLibrary.awk; RC=$${PIPESTATUS[0]}; rm $${RESPONSEFILE} \
+ $(if $(filter Library,$(TARGETTYPE)),; if [ ! -f $(ILIBTARGET) ]; then rm -f $(1); exit 42; fi) \
+ $(if $(filter Library,$(TARGETTYPE)),&& if [ -f $(WORKDIR)/LinkTarget/$(2).manifest ]; then mt.exe $(MTFLAGS) -nologo -manifest $(WORKDIR)/LinkTarget/$(2).manifest $(SRCDIR)/solenv/gbuild/platform/win_compatibility.manifest -outputresource:$(1)\;2 && touch -r $(1) $(WORKDIR)/LinkTarget/$(2).manifest $(ILIBTARGET); fi) \
+ $(if $(filter Executable,$(TARGETTYPE)),&& if [ -f $(WORKDIR)/LinkTarget/$(2).manifest ]; then mt.exe $(MTFLAGS) -nologo -manifest $(WORKDIR)/LinkTarget/$(2).manifest $(SRCDIR)/solenv/gbuild/platform/win_compatibility.manifest -outputresource:$(1)\;1 && touch -r $(1) $(WORKDIR)/LinkTarget/$(2).manifest; fi) \
+ $(if $(filter Executable,$(TARGETTYPE)),&& mt.exe $(MTFLAGS) -nologo -manifest $(SRCDIR)/solenv/gbuild/platform/DeclareDPIAware.manifest -updateresource:$(1)\;1 ) \
+ $(if $(filter Library,$(TARGETTYPE)),&& \
+ echo $(notdir $(1)) > $(WORKDIR)/LinkTarget/$(2).exports.tmp && \
+ $(gb_DUMPBIN) \
+ -exports $(ILIBTARGET) \
+ >> $(WORKDIR)/LinkTarget/$(2).exports.tmp && \
+ $(call gb_Helper_replace_if_different_and_touch,$(WORKDIR)/LinkTarget/$(2).exports.tmp,$(WORKDIR)/LinkTarget/$(2).exports,$(1))) \
+ ; \
+ $(call gb_Trace_EndRange,$(2),LNK) $(if $(gb_TRACE),;) \
+ exit $$RC)
+endef
+
+define gb_MSVCRT_subst
+$(if $(MSVC_USE_DEBUG_RUNTIME),$(subst msvcrt,msvcrtd,$(subst msvcprt,msvcprtd,$(subst libcmt,libcmtd,$(subst libvcruntime,libvcruntimed,$(subst libucrt,libucrtd,$(subst libcpmt,libcpmtd,$(subst msvcmrt,msvcmrtd,$(1)))))))),$(1))
+endef
+
+define gb_LinkTarget_use_system_win32_libs
+$(call gb_LinkTarget_add_libs,$(1),$(foreach lib,$(2),$(call gb_MSVCRT_subst,$(lib)).lib))
+$(if $(call gb_LinkTarget__is_merged,$(1)),\
+ $(call gb_LinkTarget_add_libs,$(call gb_Library_get_linktarget,merged),$(foreach lib,$(2),$(call gb_MSVCRT_subst,$(lib)).lib)))
+endef
+
+# Flags common for PE executables (EXEs and DLLs).
+# Enable incremental only when debugging to speed up relinking.
+gb_Windows_PE_TARGETTYPEFLAGS := \
+ -release \
+ -opt:noref \
+ $(if $(filter 0,$(gb_DEBUGLEVEL)), -incremental:no) \
+ $(if $(filter NO,$(LIBRARY_X64)), -safeseh) \
+ -nxcompat \
+ -dynamicbase \
+ -manifest
+
+# link.exe in -LIB mode doesn't understand -debug, use it only for EXEs and DLLs
+ifeq ($(gb_ENABLE_DBGUTIL),$(true))
+# fastlink is faster but pdb files reference .obj files
+gb_Windows_PE_TARGETTYPEFLAGS_DEBUGINFO := -debug:fastlink
+else
+gb_Windows_PE_TARGETTYPEFLAGS_DEBUGINFO := -debug
+endif
+
+ifeq ($(ENABLE_LTO),TRUE)
+gb_Windows_PE_TARGETTYPEFLAGS += -LTCG
+endif
+
+# Library class
+
+
+gb_Library_DEFS := -D_DLL
+gb_Library_TARGETTYPEFLAGS := \
+ -DLL \
+ $(gb_Windows_PE_TARGETTYPEFLAGS)
+
+gb_Library_get_rpath :=
+
+gb_Library_SYSPRE := i
+gb_Library_PLAINEXT := .lib
+gb_Library_PLAINEXT_FOR_BUILD := .lib
+
+gb_Library_LAYER := \
+ $(foreach lib,$(gb_Library_OOOLIBS),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_NONE),$(lib):NONE) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_URE),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OOO),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OXT),$(lib):OXT) \
+ $(foreach lib,$(gb_Library_PRIVATELIBS_URE),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_EXTENSIONLIBS),$(lib):OXT) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_SHLXTHDL),$(lib):SHLXTHDL) \
+
+gb_Library_ILIBFILENAMES :=\
+ $(foreach lib,$(gb_Library_KNOWNLIBS),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+
+gb_Library_DLLEXT := .dll
+gb_Library_UDK_MAJORVER := 3
+gb_Library_RTEXT := MSC$(gb_Library_DLLEXT)
+gb_Library_OOOEXT := $(gb_Library_DLLPOSTFIX)$(gb_Library_DLLEXT)
+gb_Library_UNOEXT := .uno$(gb_Library_DLLEXT)
+gb_Library_UNOVEREXT := $(gb_Library_UDK_MAJORVER)$(gb_Library_DLLEXT)
+gb_Library_RTVEREXT := $(gb_Library_UDK_MAJORVER)$(gb_Library_RTEXT)
+
+gb_Library_FILENAMES :=\
+ $(foreach lib,$(gb_Library_OOOLIBS),$(lib):$(lib)$(gb_Library_OOOEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_NONE),$(lib):$(lib)$(gb_Library_DLLEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_URE),$(lib):$(lib)$(gb_Library_DLLEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OOO),$(lib):$(lib)$(gb_Library_DLLEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OXT),$(lib):$(lib)$(gb_Library_DLLEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_SHLXTHDL),$(lib):$(lib)$(gb_Library_DLLEXT)) \
+ $(foreach lib,$(gb_Library_PRIVATELIBS_URE),$(lib):$(lib)$(gb_Library_OOOEXT)) \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):$(lib)$(gb_Library_RTVEREXT)) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):$(lib)$(gb_Library_UNOVEREXT)) \
+ $(foreach lib,$(gb_Library_EXTENSIONLIBS),$(lib):$(lib)$(gb_Library_UNOEXT)) \
+
+# An assembly is a special kind of library for CLI
+define gb_Library_Assembly
+$(call gb_Library_Library,$(1))
+$(call gb_Library_get_linktarget_target,$(1)) : NATIVERES :=
+
+endef
+
+define gb_Library_Library_platform
+$(call gb_LinkTarget_set_ilibtarget,$(2),$(3))
+
+$(call gb_LinkTarget_add_auxtargets,$(2),\
+ $(patsubst %.lib,%.exp,$(3)) \
+ $(call gb_LinkTarget_get_manifestfile,$(2)) \
+ $(call gb_LinkTarget_get_pdbfile_in,$(2)) \
+ $(call gb_LinkTarget_get_pdbfile_out,$(2)) \
+ $(call gb_LinkTarget_get_ilkfile,$(2)) \
+)
+
+$(call gb_Library_add_default_nativeres,$(1),$(1)/default)
+
+$(call gb_LinkTarget_get_target,$(2)) \
+$(call gb_LinkTarget_get_headers_target,$(2)) : PDBFILE = $(call gb_LinkTarget_get_pdbfile_in,$(2))
+
+endef
+
+define gb_Library_add_default_nativeres
+$(call gb_WinResTarget_WinResTarget_init,$(2))
+$(call gb_WinResTarget_set_rcfile,$(2),include/default)
+$(call gb_WinResTarget_add_defs,$(2),\
+ -DVERVARIANT="$(LIBO_VERSION_PATCH)" \
+ -DRES_APP_VENDOR="$(OOO_VENDOR)" \
+ -DORG_NAME="$(call gb_Library_get_filename,$(1))"\
+ -DINTERNAL_NAME="$(subst $(gb_Library_DLLEXT),,$(call gb_Library_get_filename,$(1)))" \
+ -DADDITIONAL_VERINFO1="" \
+ -DADDITIONAL_VERINFO2="" \
+ -DADDITIONAL_VERINFO3="" \
+)
+$(call gb_Library_add_nativeres,$(1),$(2))
+$(call gb_Library_get_clean_target,$(1)) : $(call gb_WinResTarget_get_clean_target,$(2))
+
+endef
+
+define gb_Executable_add_default_nativeres
+$(call gb_WinResTarget_WinResTarget_init,$(1)/default)
+$(call gb_WinResTarget_set_rcfile,$(1)/default,include/default)
+$(call gb_WinResTarget_add_defs,$(1)/default,\
+ -DVERVARIANT="$(LIBO_VERSION_PATCH)" \
+ -DRES_APP_VENDOR="$(OOO_VENDOR)" \
+ -DORG_NAME="$(call gb_Executable_get_filename,$(1))"\
+ -DINTERNAL_NAME="$(subst $(gb_Executable_EXT),,$(call gb_Executable_get_filename,$(1)))" \
+ -DADDITIONAL_VERINFO1="$(if $(2),VALUE \"FileDescription\"$(COMMA) \"$(2)\\0\")" \
+ -DADDITIONAL_VERINFO2="" \
+ -DADDITIONAL_VERINFO3="" \
+)
+$(call gb_Executable_add_nativeres,$(1),$(1)/default)
+$(call gb_Executable_get_clean_target,$(1)) : $(call gb_WinResTarget_get_clean_target,$(1)/default)
+
+endef
+
+define gb_LinkTarget_add_nativeres
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_WinResTarget_get_target,$(2))
+$(call gb_LinkTarget_get_target,$(1)) : NATIVERES += $(call gb_WinResTarget_get_target,$(2))
+
+endef
+
+define gb_LinkTarget_set_nativeres
+$(call gb_LinkTarget_get_target,$(1)) : $(call gb_WinResTarget_get_target,$(2))
+$(call gb_LinkTarget_get_target,$(1)) : NATIVERES := $(call gb_WinResTarget_get_target,$(2))
+
+endef
+
+define gb_Library_get_ilibfilename
+$(patsubst $(1):%,%,$(filter $(1):%,$(gb_Library_ILIBFILENAMES)))
+endef
+
+gb_Library_get_sdk_link_dir = $(INSTDIR)/$(SDKDIRNAME)/lib
+
+gb_Library_get_sdk_link_lib = $(gb_Library_get_ilib_target)
+
+# StaticLibrary class
+
+gb_StaticLibrary_get_filename = $(1).lib
+gb_StaticLibrary_PLAINEXT := .lib
+
+define gb_StaticLibrary_StaticLibrary_platform
+$(call gb_LinkTarget_get_target,$(2)) \
+$(call gb_LinkTarget_get_headers_target,$(2)) : PDBFILE = $(call gb_LinkTarget_get_pdbfile_in,$(2))
+
+$(call gb_LinkTarget_add_auxtargets,$(2),\
+ $(call gb_LinkTarget_get_pdbfile_in,$(2)) \
+)
+
+endef
+
+# Executable class
+
+gb_Executable_EXT := .exe
+gb_Executable_EXT_for_build := .exe
+gb_Executable_TARGETTYPEFLAGS := $(gb_Windows_PE_TARGETTYPEFLAGS)
+
+gb_Executable_get_rpath :=
+
+# surprisingly some executables have exports so link.exe creates import lib
+define gb_Executable_Executable_platform
+$(call gb_LinkTarget_set_ilibtarget,$(2),$(3))
+
+$(call gb_LinkTarget_add_auxtargets,$(2),\
+ $(patsubst %.lib,%.exp,$(3)) \
+ $(call gb_LinkTarget_get_pdbfile_out,$(2)) \
+ $(call gb_LinkTarget_get_pdbfile_in,$(2)) \
+ $(call gb_LinkTarget_get_manifestfile,$(2)) \
+)
+
+$(call gb_LinkTarget_get_target,$(2)) \
+$(call gb_LinkTarget_get_headers_target,$(2)) : PDBFILE := $(call gb_LinkTarget_get_pdbfile_in,$(2))
+
+endef
+
+# CppunitTest class
+
+gb_CppunitTest_UNITTESTFAILED := $(GBUILDDIR)/platform/unittest-failed-WNT.sh
+gb_CppunitTest_PYTHONDEPS := $(call gb_Package_get_target,python3)
+gb_CppunitTest_DEFS := -D_DLL
+gb_CppunitTest_CPPTESTPRECOMMAND := $(call gb_Helper_prepend_ld_path,$(shell cygpath -u $(gb_Library_DLLDIR)):$(shell cygpath -u $(WORKDIR)/UnpackedTarball/cppunit/src/cppunit/$(if $(MSVC_USE_DEBUG_RUNTIME),DebugDll,ReleaseDll)))
+gb_CppunitTest_get_filename = test_$(1).dll
+gb_CppunitTest_get_ilibfilename = itest_$(1).lib
+
+define gb_CppunitTest_CppunitTest_platform
+$(call gb_LinkTarget_set_ilibtarget,$(2),$(3))
+
+$(call gb_LinkTarget_add_auxtargets,$(2),\
+ $(patsubst %.lib,%.exp,$(3)) \
+ $(3) \
+ $(call gb_LinkTarget_get_manifestfile,$(2)) \
+ $(call gb_LinkTarget_get_pdbfile_out,$(2)) \
+ $(call gb_LinkTarget_get_pdbfile_in,$(2)) \
+ $(call gb_LinkTarget_get_ilkfile,$(2)) \
+)
+
+$(call gb_LinkTarget_get_target,$(2)) \
+$(call gb_LinkTarget_get_headers_target,$(2)) : PDBFILE = $(call gb_LinkTarget_get_pdbfile_in,$(2))
+
+endef
+
+# JunitTest class
+
+ifneq ($(OOO_TEST_SOFFICE),)
+gb_JunitTest_SOFFICEARG:=$(OOO_TEST_SOFFICE)
+else
+ifneq ($(gb_JunitTest_DEBUGRUN),)
+gb_JunitTest_SOFFICEARG:=connect:pipe,name=$(USER)
+else
+gb_JunitTest_SOFFICEARG:=path:$(INSTROOT)/$(LIBO_BIN_FOLDER)/soffice
+endif
+endif
+
+
+define gb_JunitTest_JunitTest_platform
+$(call gb_JunitTest_get_target,$(1)) : DEFS := \
+ -Dorg.openoffice.test.arg.soffice="$(gb_JunitTest_SOFFICEARG)" \
+ -Dorg.openoffice.test.arg.env=PATH="$$$$PATH" \
+ -Dorg.openoffice.test.arg.user=$(call gb_Helper_make_url,$(call gb_JunitTest_get_userdir,$(1)))
+ -Dorg.openoffice.test.arg.workdir=$(call gb_JunitTest_get_userdir,$(1)) \
+
+endef
+
+
+define gb_Module_DEBUGRUNCOMMAND
+printf "\nAttach the debugger to soffice.bin\n\n"
+OFFICESCRIPT=`mktemp` && \
+printf "$(INSTROOT)/$(LIBO_BIN_FOLDER)/soffice.exe" > $${OFFICESCRIPT} && \
+printf " --norestore --nologo '--accept=pipe,name=$(USER);urp;'\n" >> $${OFFICESCRIPT} && \
+$(SHELL) $${OFFICESCRIPT} && \
+rm $${OFFICESCRIPT}
+endef
+
+
+
+
+# PythonTest class
+
+gb_PythonTest_PRECOMMAND := $(gb_CppunitTest_CPPTESTPRECOMMAND)
+gb_PythonTest_DEPS = $(call gb_Package_get_target,python3) $(call gb_Executable_get_target,python)
+
+ifeq ($(strip $(CPPUNITTRACE)),TRUE)
+override CPPUNITTRACE := '$(DEVENV)' /debugexe
+endif
+
+# WinResTarget class
+
+gb_WinResTarget_POSTFIX :=.res
+
+define gb_WinResTarget__command
+$(call gb_Output_announce,$(2),$(true),RC ,1)
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) && \
+ $(gb_RC) \
+ $(DEFS) $(FLAGS) \
+ $(INCLUDE) \
+ -Fo$(1) \
+ $(RCFILE) )
+endef
+
+$(eval $(call gb_Helper_make_dep_targets,\
+ WinResTarget \
+))
+
+ifeq ($(gb_FULLDEPS),$(true))
+# FIXME this is used before TargetLocations is read?
+gb_WinResTarget__command_target = $(WORKDIR_FOR_BUILD)/LinkTarget/Executable/makedepend.exe
+define gb_WinResTarget__command_dep
+$(call gb_Output_announce,RC:$(2),$(true),DEP,1)
+ $(call gb_Trace_StartRange,RC:$(2),DEP)
+$(call gb_Helper_abbreviate_dirs,\
+ mkdir -p $(dir $(1)) && \
+ $(call gb_Executable_get_target_for_build,makedepend) \
+ $(INCLUDE) \
+ $(DEFS) \
+ $(RCFILE) \
+ -o .res \
+ -p $(dir $(3)) \
+ -f $(1))
+ $(call gb_Trace_EndRange,RC:$(2),DEP)
+endef
+else
+gb_WinResTarget__command_target =
+gb_WinResTarget__command_dep =
+endif
+
+# InstallModuleTarget class
+
+define gb_InstallModuleTarget_InstallModuleTarget_platform
+$(call gb_InstallModuleTarget_add_defs,$(1),\
+ $(gb_CPUDEFS) \
+ $(gb_OSDEFS) \
+ -DCOMID=MSC \
+)
+
+endef
+
+# ExternalProject class
+
+# Use the gcc wrappers for an autoconf based project
+#
+# gb_ExternalProject_register_targets project state_target
+define gb_ExternalProject_use_autoconf
+$(call gb_ExternalProject_get_preparation_target,$(1)) : $(call gb_Executable_get_runtime_dependencies,gcc-wrapper) \
+ $(call gb_Executable_get_runtime_dependencies,g++-wrapper)
+$(call gb_ExternalProject_get_state_target,$(1),$(2)): WRAPPERS := $(gb_AUTOCONF_WRAPPERS)
+endef
+
+# Set INCLUDE and LIB variables and unset MAKE/MAKEFLAGS when using nmake
+#
+# gb_ExternalProject_use_nmake project state_target
+define gb_ExternalProject_use_nmake
+$(call gb_ExternalProject_get_state_target,$(1),$(2)): NMAKE := $(gb_NMAKE_VARS)
+endef
+
+# if ccache is enabled, then split it and use lastword as REAL_FOO
+# /opt/lo/bin/ccache /cygdrive/c/PROGRA~2/MICROS~2.0/VC/bin/cl.exe
+
+gb_AUTOCONF_WRAPPERS = \
+ REAL_CC="$(shell cygpath -w $(filter-out -%,$(CC)))" \
+ REAL_CC_FLAGS="$(filter -%,$(CC))" \
+ CC="$(call gb_Executable_get_target_for_build,gcc-wrapper)" \
+ REAL_CXX="$(shell cygpath -w $(filter-out -%,$(CXX)))" \
+ REAL_CXX_FLAGS="$(filter -%,$(CXX))" \
+ CXX="$(call gb_Executable_get_target_for_build,g++-wrapper)" \
+ LD="$(shell cygpath -w $(COMPATH)/bin/link.exe) -nologo"
+
+gb_ExternalProject_INCLUDE := \
+ $(subst -I,,$(subst $(WHITESPACE),;,$(SOLARINC)))
+
+gb_NMAKE_VARS = \
+ CC="$(shell cygpath -w $(filter-out -%,$(CC))) $(filter -%,$(CC))" \
+ INCLUDE="$(gb_ExternalProject_INCLUDE)" \
+ LIB="$(ILIB)" \
+ MAKEFLAGS= \
+ MAKE=
+
+# InstallScript class
+
+gb_InstallScript_EXT := .inf
+
+# CliAssemblyTarget class
+
+gb_CliAssemblyTarget_POLICYEXT := $(gb_Library_DLLEXT)
+gb_CliAssemblyTarget_get_dll = $(call gb_Library__get_dir_for_layer,NONE)/$(1)$(gb_CliAssemblyTarget_POLICYEXT)
+
+# Extension class
+
+gb_Extension_LICENSEFILE_DEFAULT := $(INSTROOT)/license.txt
+
+# UnpackedTarget class
+
+gb_UnpackedTarget_TARFILE_LOCATION := $(shell cygpath -u $(TARFILE_LOCATION))
+
+# UnoApiHeadersTarget class
+
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+gb_UnoApiHeadersTarget_select_variant = $(if $(filter udkapi,$(1)),comprehensive,$(2))
+else
+gb_UnoApiHeadersTarget_select_variant = $(2)
+endif
+
+# UIConfig class
+
+# use responsefile because cui has too many files for command line
+define gb_UIConfig__command
+$(call gb_Helper_abbreviate_dirs,\
+ RESPONSEFILE=$(call gb_var2file,$(shell $(gb_MKTEMP)),100,$(if $(UI_IMAGELISTS),$(strip $(UI_IMAGELISTS)),/dev/null)) \
+ && tr " " "\000" < $$RESPONSEFILE | tr -d "\r\n" > $$RESPONSEFILE.0 \
+ && $(SORT) -u --files0-from=$$RESPONSEFILE.0 > $@ \
+ && rm $$RESPONSEFILE $$RESPONSEFILE.0 \
+)
+
+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 gb_var2file,$(shell $(gb_MKTEMP)),100,$(UIFILES)) && \
+ $(gb_UIConfig_LXML_PATH) $(if $(SYSTEM_LIBXML)$(SYSTEM_LIBXSLT),,$(gb_Helper_set_ld_path)) \
+ $(call gb_ExternalExecutable_get_command,python) \
+ $(gb_UIConfig_gla11y_SCRIPT) $(gb_UIConfig_gla11y_PARAMETERS) -o $@ -L $$FILES && \
+ rm $$FILES
+)
+
+endef
+
+# UIMenubarTarget class
+
+define gb_UIMenubarTarget__command
+$(call gb_Output_announce,$(2),$(true),UIM,1)
+$(call gb_Trace_StartRange,$(2),UIM)
+cp $(3) $(1)
+$(call gb_Trace_EndRange,$(2),UIM)
+
+endef
+
+gb_UIMenubarTarget_UIMenubarTarget_platform :=
+
+# Python
+gb_Python_HOME := $(INSTDIR_FOR_BUILD)/program/python-core-$(PYTHON_VERSION)
+gb_Python_PRECOMMAND := PATH="$(shell cygpath -w $(INSTDIR_FOR_BUILD)/program)" PYTHONHOME="$(gb_Python_HOME)" PYTHONPATH="$${PYPATH:+$$PYPATH:}$(gb_Python_HOME)/lib;$(gb_Python_HOME)/lib/lib-dynload:$(INSTDIR_FOR_BUILD)/program"
+gb_Python_INSTALLED_EXECUTABLE := $(INSTROOT_FOR_BUILD)/$(LIBO_BIN_FOLDER)/python.exe
+
+gb_ICU_PRECOMMAND := PATH="$(shell cygpath -w $(WORKDIR_FOR_BUILD)/UnpackedTarball/icu/source/lib)"
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/com_MSC_defs.mk b/solenv/gbuild/platform/com_MSC_defs.mk
new file mode 100644
index 000000000..364c0011f
--- /dev/null
+++ b/solenv/gbuild/platform/com_MSC_defs.mk
@@ -0,0 +1,352 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# set tmpdir to some mixed case path, suitable for native tools
+gb_TMPDIR:=$(if $(TMPDIR),$(shell cygpath -m $(TMPDIR)),$(shell cygpath -m /tmp))
+
+# please make generic Windows modifications to windows.mk
+include $(GBUILDDIR)/platform/windows.mk
+
+gb_CC := cl
+gb_CXX := cl
+gb_LINK := link
+gb_DUMPBIN := dumpbin
+gb_AWK := awk
+gb_CLASSPATHSEP := ;
+gb_RC := rc
+
+# use CC/CXX if they are nondefaults
+ifneq ($(origin CC),default)
+gb_CC := $(CC)
+gb_GCCP := $(CC)
+endif
+ifneq ($(origin CXX),default)
+gb_CXX := $(CXX)
+endif
+
+# _SCL_SECURE_NO_WARNINGS avoids deprecation warnings for STL algorithms
+# like std::copy, std::transform (when MSVC_USE_DEBUG_RUNTIME is enabled)
+
+gb_COMPILERDEFS := \
+ -DBOOST_ERROR_CODE_HEADER_ONLY \
+ -DBOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE \
+ -DBOOST_SYSTEM_NO_DEPRECATED \
+ -D_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING \
+ -D_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING \
+ -D_SILENCE_CXX17_RESULT_OF_DEPRECATION_WARNING \
+ -D_CRT_NON_CONFORMING_SWPRINTFS \
+ -D_CRT_NONSTDC_NO_DEPRECATE \
+ -D_CRT_SECURE_NO_DEPRECATE \
+ -D_SCL_SECURE_NO_WARNINGS \
+ -D_MT \
+ -D_DLL \
+ -DCPPU_ENV=$(CPPU_ENV) \
+
+ifeq ($(CPUNAME),INTEL)
+gb_COMPILERDEFS += \
+ -DBOOST_MEM_FN_ENABLE_CDECL \
+
+endif
+
+gb_RCDEFS := \
+ $(gb_WIN_VERSION_DEFS) \
+
+gb_RCFLAGS :=
+
+gb_AFLAGS := $(AFLAGS)
+
+# Do we really need to disable this many warnings? It seems to me that
+# many of these warnings are for constructs that we have been actively
+# cleaning away from the code, to avoid warnings when building with
+# gcc or Clang and -Wall -Werror.
+
+# C4127: conditional expression is constant
+
+# C4201: nonstandard extension used : nameless struct/union
+
+# C4244: nonstandard extension used : formal parameter 'identifier'
+# was previously defined as a type
+
+# C4250: 'class1' : inherits 'class2::member' via dominance
+
+# C4251: 'identifier' : class 'type' needs to have dll-interface to be
+# used by clients of class 'type2'
+
+# C4267: conversion from 'size_t' to 'type', possible loss of data
+
+# C4275: non-DLL-interface classkey 'identifier' used as base for
+# DLL-interface classkey 'identifier'
+
+# C4505: 'function' : unreferenced local function has been removed
+
+# C4611: interaction between 'function' and C++ object destruction is
+# non-portable
+
+# C4702: unreachable code
+
+# C4706: assignment within conditional expression
+
+gb_CFLAGS := \
+ -utf-8 \
+ -Gd \
+ -GR \
+ -Gs \
+ -GS \
+ $(if $(MSVC_USE_DEBUG_RUNTIME),-MDd,-MD) \
+ -nologo \
+ -W4 \
+ -wd4244 \
+ -wd4505 \
+ -bigobj \
+
+gb_CXXFLAGS_DISABLE_WARNINGS = -w
+
+ifneq ($(COM_IS_CLANG),TRUE)
+
+# clang-cl doesn't support -Wv:18 for now
+gb_CFLAGS += \
+ -Wv:18 \
+
+endif
+
+gb_CXXFLAGS := \
+ -utf-8 \
+ $(CXXFLAGS_CXX11) \
+ -Gd \
+ -GR \
+ -Gs \
+ -GS \
+ -Gy \
+ $(if $(MSVC_USE_DEBUG_RUNTIME),-MDd,-MD) \
+ -nologo \
+ -W4 \
+ -wd4127 \
+ -wd4201 \
+ -wd4244 \
+ -wd4250 \
+ -wd4251 \
+ -wd4267 \
+ -wd4275 \
+ -wd4505 \
+ -wd4611 \
+ -wd4706 \
+ -bigobj \
+
+ifneq ($(COM_IS_CLANG),TRUE)
+gb_CXXFLAGS += -Zc:inline
+gb_CXXFLAGS_ZCINLINE_OFF := -Zc:inline-
+endif
+
+ifeq ($(CPUNAME),INTEL)
+
+gb_CXXFLAGS += \
+ -Zm500 \
+
+gb_CFLAGS += \
+ -Zm500 \
+
+endif
+
+ifeq ($(HAVE_DLLEXPORTINLINES),TRUE)
+gb_CXXFLAGS += -Zc:dllexportInlines-
+endif
+
+gb_CXXFLAGS_include := -FI
+ifeq ($(COM_IS_CLANG),TRUE)
+gb_CXXFLAGS_no_pch_warnings := -Wno-clang-cl-pch
+endif
+
+ifneq ($(COM_IS_CLANG),TRUE)
+
+# clang-cl doesn't support -Wv:18 for now
+# Work around MSVC 2017 C4702 compiler bug with release builds
+# http://document-foundation-mail-archive.969070.n3.nabble.com/Windows-32-bit-build-failure-unreachable-code-tp4243848.html
+# http://document-foundation-mail-archive.969070.n3.nabble.com/64-bit-Windows-build-failure-after-MSVC-Update-tp4246816.html
+gb_CXXFLAGS += \
+ -Wv:18 \
+ $(if $(filter 0,$(gb_DEBUGLEVEL)),-wd4702) \
+
+endif
+
+# rc.exe does not support -nologo in 6.1.6723.1 that is in the Windows SDK 6.0A
+gb_RCFLAGS += -nologo
+
+# C4005: 'identifier' : macro redefinition
+
+gb_PCHWARNINGS = \
+ -we4650 \
+ -we4651 \
+ -we4652 \
+ -we4653 \
+ -we4005 \
+
+gb_STDLIBS := \
+ advapi32.lib \
+
+gb_CFLAGS_WERROR = $(if $(ENABLE_WERROR),-WX)
+
+# there does not seem to be a way to force C++03 with MSVC, nor with clang-cl against MSVC system
+# headers
+gb_CXX03FLAGS :=
+
+gb_LinkTarget_EXCEPTIONFLAGS := \
+ -DEXCEPTIONS_ON \
+ -EHs \
+
+gb_PrecompiledHeader_EXCEPTIONFLAGS := $(gb_LinkTarget_EXCEPTIONFLAGS)
+
+ifneq ($(gb_ENABLE_PCH),)
+ifeq ($(COM_IS_CLANG),TRUE)
+# the same as in com_GCC_defs.mk
+gb_NO_PCH_TIMESTAMP := -Xclang -fno-pch-timestamp
+endif
+endif
+
+gb_LinkTarget_LDFLAGS := \
+ $(if $(findstring s,$(filter-out --%,$(MAKEFLAGS))),-nologo,) \
+ $(patsubst %,-LIBPATH:%,$(filter-out .,$(subst ;, ,$(subst \,/,$(ILIB))))) \
+
+# Prevent warning spamming
+# Happens because of the way we link our unit tests with our libraries.
+# LNK4049: locally defined symbol
+gb_LinkTarget_LDFLAGS += \
+ /ignore:4217 /ignore:4049
+
+
+ifeq ($(ENABLE_Z7_DEBUG),)
+gb_DEBUGINFO_FLAGS := \
+ -FS \
+ -Zi \
+
+else
+# ccache does not work with -Zi
+gb_DEBUGINFO_FLAGS := \
+ -Z7 \
+
+endif
+
+# See gb_Windows_PE_TARGETTYPEFLAGS_DEBUGINFO
+gb_LINKER_DEBUGINFO_FLAGS :=
+
+gb_COMPILEROPTFLAGS := -O2 -Oy-
+gb_COMPILERNOOPTFLAGS := -Od
+gb_COMPILERDEBUGOPTFLAGS :=
+
+ifeq ($(gb_FULLDEPS),$(true))
+gb_COMPILERDEPFLAGS := -showIncludes
+define gb_create_deps
+| LC_ALL=C $(GBUILDDIR)/platform/filter-showIncludes.awk -vdepfile=$(1) -vobjectfile=$(2) -vsourcefile=$(3); exit $${PIPESTATUS[0]}
+endef
+else
+gb_COMPILERDEPFLAGS :=
+define gb_create_deps
+| LC_ALL=C $(GBUILDDIR)/platform/filter-sourceName.awk; exit $${PIPESTATUS[0]}
+endef
+endif
+
+gb_LTOFLAGS := $(if $(filter TRUE,$(ENABLE_LTO)),-GL)
+
+# When compiling for CLR, disable "warning C4339: use of undefined type detected
+# in CLR meta-data - use of this type may lead to a runtime exception":
+gb_CXXCLRFLAGS := \
+ $(if $(COM_IS_CLANG), \
+ $(patsubst -std=%,-std:c++17 -Zc:__cplusplus,$(gb_CXXFLAGS)), \
+ $(gb_CXXFLAGS)) \
+ $(gb_LinkTarget_EXCEPTIONFLAGS) \
+ -AI $(INSTDIR)/$(LIBO_URE_LIB_FOLDER) \
+ -EHa \
+ -clr \
+ -wd4339 \
+ -Wv:18 \
+ -wd4267 \
+ -Zc:twoPhase- \
+
+ifeq ($(COM_IS_CLANG),TRUE)
+
+gb_CFLAGS += \
+ -Wendif-labels \
+ -Wshadow \
+ -Wstrict-prototypes \
+ -Wundef \
+ -Wunused-macros \
+
+gb_CXXFLAGS += \
+ -Wendif-labels \
+ -Wimplicit-fallthrough \
+ -Wno-missing-braces \
+ -Wnon-virtual-dtor \
+ -Woverloaded-virtual \
+ -Wshadow \
+ -Wundef \
+ -Wunused-macros \
+
+endif
+
+ifeq ($(COM_IS_CLANG),TRUE)
+gb_COMPILER_TEST_FLAGS := -Xclang -plugin-arg-loplugin -Xclang --unit-test-mode
+ifeq ($(COMPILER_PLUGIN_TOOL),)
+gb_COMPILER_PLUGINS := -Xclang -load -Xclang $(BUILDDIR)/compilerplugins/clang/plugin.dll -Xclang -add-plugin -Xclang loplugin
+ifneq ($(COMPILER_PLUGIN_WARNINGS_ONLY),)
+gb_COMPILER_PLUGINS += -Xclang -plugin-arg-loplugin -Xclang \
+ --warnings-only='$(COMPILER_PLUGIN_WARNINGS_ONLY)'
+endif
+else
+gb_COMPILER_PLUGINS := -Xclang -load -Xclang $(BUILDDIR)/compilerplugins/clang/plugin.dll -Xclang -plugin -Xclang loplugin $(foreach plugin,$(COMPILER_PLUGIN_TOOL), -Xclang -plugin-arg-loplugin -Xclang $(plugin))
+ifneq ($(UPDATE_FILES),)
+gb_COMPILER_PLUGINS += -Xclang -plugin-arg-loplugin -Xclang --scope=$(UPDATE_FILES)
+endif
+endif
+ifeq ($(COMPILER_PLUGINS_DEBUG),TRUE)
+gb_COMPILER_PLUGINS += -Xclang -plugin-arg-loplugin -Xclang --debug
+endif
+gb_COMPILER_PLUGINS_WARNINGS_AS_ERRORS := \
+ -Xclang -plugin-arg-loplugin -Xclang --warnings-as-errors
+else
+gb_COMPILER_TEST_FLAGS :=
+gb_COMPILER_PLUGINS :=
+gb_COMPILER_PLUGINS_WARNINGS_AS_ERRORS :=
+endif
+
+# Helper class
+
+gb_Helper_set_ld_path := PATH="$(shell cygpath -u $(INSTDIR_FOR_BUILD)/$(LIBO_URE_LIB_FOLDER)):$(shell cygpath -u $(INSTDIR_FOR_BUILD)/$(LIBO_BIN_FOLDER)):$$PATH"
+
+define gb_Helper_prepend_ld_path
+PATH="$(shell cygpath -u $(INSTDIR_FOR_BUILD)/$(LIBO_URE_LIB_FOLDER)):$(shell cygpath -u $(INSTDIR_FOR_BUILD)/$(LIBO_BIN_FOLDER)):$(1):$$PATH"
+endef
+
+# $(1): one directory pathname to append to the ld path
+define gb_Helper_extend_ld_path
+$(gb_Helper_set_ld_path)':$(shell cygpath -u $(1))'
+endef
+
+# common macros to build GPG related libraries
+# we explicitly have to replace cygwin with mingw32 for the host, but the build must stay cygwin, or cmd.exe processes will be spawned
+gb_WIN_GPG_WINDRES_target := $(if $(filter INTEL,$(CPUNAME)),pe-i386,pe-x86-64)
+gb_WIN_GPG_platform_switches := --build=$(BUILD_PLATFORM) --host=$(subst cygwin,mingw32,$(HOST_PLATFORM))
+gb_WIN_GPG_cross_setup_exports = export REAL_BUILD_CC="$(filter-out -%,$(CC_FOR_BUILD))" REAL_BUILD_CC_FLAGS="$(filter -%,$(CC_FOR_BUILD))" \
+ && export CC_FOR_BUILD="$(call gb_Executable_get_target_for_build,gcc-wrapper) --wrapper-env-prefix=REAL_BUILD_ $(SOLARINC) -L$(subst ;, -L,$(ILIB_FOR_BUILD))" \
+ && export RC='windres -O COFF --target=$(gb_WIN_GPG_WINDRES_target) --preprocessor=$(call gb_Executable_get_target_for_build,cpp) --preprocessor-arg=-+ -DRC_INVOKED -DWINAPI_FAMILY=0 $(SOLARINC)'
+
+ifneq ($(gb_ENABLE_PCH),)
+# Enable use of .sum files for PCHs.
+gb_COMPILER_SETUP += CCACHE_PCH_EXTSUM=1
+endif
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/filter-creatingLibrary.awk b/solenv/gbuild/platform/filter-creatingLibrary.awk
new file mode 100755
index 000000000..231609feb
--- /dev/null
+++ b/solenv/gbuild/platform/filter-creatingLibrary.awk
@@ -0,0 +1,46 @@
+#!/usr/bin/gawk -f
+# -*- 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/.
+#
+
+# Filter out the "Creating library" message printed by link.exe,
+# as there is no way to disable it.
+
+BEGIN {
+ creatinglibrary_prefix = ENVIRON["CREATINGLIBRARY_PREFIX"];
+ generatingcode_message = ENVIRON["GENERATINGCODE_MESSAGE"];
+ finishedgeneratingcode_message = ENVIRON["FINISHEDGENERATINGCODE_MESSAGE"];
+ if (!creatinglibrary_prefix) {
+ creatinglibrary_prefix = "\\.lib.*\\.exp"
+ }
+ if (!generatingcode_message) {
+ generatingcode_message = "Generating code"
+ }
+ if (!finishedgeneratingcode_message) {
+ finishedgeneratingcode_message = "Finished generating code"
+ }
+ firstline = 1
+}
+
+{
+ if (firstline && match($0, creatinglibrary_prefix)) {
+ # ignore
+ } else if (match($0, generatingcode_message)) {
+ # ignore
+ } else if (match($0, finishedgeneratingcode_message)) {
+ # ignore
+ } else {
+ # because MSVC stupidly prints errors on stdout, it's
+ # necessary to forward everything that isn't matched by the pattern
+ # so users get to see them.
+ print $0 > "/dev/stderr"
+ }
+ firstline = 0
+}
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/filter-showIncludes.awk b/solenv/gbuild/platform/filter-showIncludes.awk
new file mode 100755
index 000000000..9f5cabd10
--- /dev/null
+++ b/solenv/gbuild/platform/filter-showIncludes.awk
@@ -0,0 +1,99 @@
+#!/usr/bin/gawk -f
+# -*- 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/.
+#
+
+# Create dependency information from the output of cl.exe's showInclude. It
+# needs additional information - the output name to which to write, objfile
+# that depends on the includes, and the original file name.
+# For best results all arguments should be absolute paths.
+#
+# It also consolidates the file names to a canonical form, and filters out
+# duplicates.
+#
+# based on filter-showInclude.pl by Jan Holesovsky <kendy@suse.cz>
+
+BEGIN {
+ if (!depfile || !objectfile || !sourcefile) {
+ print "usage: filter-showIncludes.awk -vdepfile=depfile.d " \
+ "-vobjectfile=objfile.o -vsourcefile=source.cxx" > "/dev/stderr"
+ exit 1
+ }
+ tempfile = depfile ".tmp"
+ print objectfile " : \\\n " sourcefile " \\" > tempfile
+
+ showincludes_prefix = ENVIRON["SHOWINCLUDES_PREFIX"];
+ if (!showincludes_prefix) {
+ showincludes_prefix = "Note: including file:"
+ }
+
+ # to match especially drive letters in allowlist case insensitive
+ IGNORECASE = 1
+ allowlist = \
+ "^(" ENVIRON["SRCDIR"] "|" ENVIRON["BUILDDIR"] ")"
+ firstline = 1
+}
+
+{
+ sub(/\r$/, "")
+ sub(/^ */, "")
+ if (index($0, showincludes_prefix) == 1) {
+ $0 = substr($0, length(showincludes_prefix) + 1)
+ sub(/^ */, "")
+
+ # The output from MSVC may contain a carriage return character at the
+ # end of filenames, in which case the translation unit will depend on a
+ # non-existing header, resulting in constant rebuild of all files,
+ # prevent that.
+ sub(/ /, "")
+
+ gsub(/\\/, "/")
+ gsub(/ /, "\\ ")
+ if ($0 ~ allowlist) { # filter out system headers
+ if (!($0 in incfiles)) {
+ incfiles[$0]
+ print " " $0 " \\" > tempfile
+ }
+ }
+ } else {
+ # because MSVC stupidly prints errors on stdout, it's
+ # necessary to forward everything that isn't matched by the pattern
+ # so users get to see them.
+ if (firstline) { # ignore the line that just prints name of sourcefile
+ firstline = 0
+ } else {
+ print $0 > "/dev/stderr"
+ }
+ }
+}
+
+END {
+ if (!tempfile) {
+ exit 1
+ }
+ print "" > tempfile
+
+ # fdo#40099 if header.h does not exist, it will simply be considered out of
+ # date and any targets that use it as a prerequisite will be updated,
+ # which avoid misery when the header is deliberately deleted and removed
+ # as an include
+ # see http://www.makelinux.net/make3/make3-CHP-8-SECT-3
+ for (file in incfiles) {
+ print file " :\n" > tempfile
+ }
+
+ close(tempfile)
+ movecmd = "mv " tempfile " " depfile
+ ret = system(movecmd)
+ if (ret) {
+ print "ERROR: " movecmd " FAILED with status " ret > "/dev/stderr"
+ exit ret
+ }
+}
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/filter-sourceName.awk b/solenv/gbuild/platform/filter-sourceName.awk
new file mode 100755
index 000000000..d55e2707d
--- /dev/null
+++ b/solenv/gbuild/platform/filter-sourceName.awk
@@ -0,0 +1,32 @@
+#!/usr/bin/gawk -f
+# -*- 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/.
+#
+
+# Filter out the "sourcefile.cxx" message printed by cl.exe,
+# as there is no way to disable it. This file is used
+# in place of filter-showIncludes.awk (which does the same)
+# when --disable-dependency-tracking is used.
+
+BEGIN {
+ firstline = 1
+}
+
+{
+ if (firstline) {
+ # ignore
+ } else {
+ # because MSVC stupidly prints errors on stdout, it's
+ # necessary to forward everything that isn't matched by the pattern
+ # so users get to see them.
+ print $0 > "/dev/stderr"
+ }
+ firstline = 0
+}
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/iOS.mk b/solenv/gbuild/platform/iOS.mk
new file mode 100644
index 000000000..15f1ce4ef
--- /dev/null
+++ b/solenv/gbuild/platform/iOS.mk
@@ -0,0 +1,269 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+ifeq ($(CC),)
+$(error You must set CC in the environment. See README.cross for example.)
+endif
+ifeq ($(CXX),)
+$(error You must set CXX in the environment. See README.cross for example.)
+endif
+
+gb_COMPILEROPTFLAGS := -O2
+
+include $(GBUILDDIR)/platform/com_GCC_defs.mk
+
+# Use standard lldb debugger
+gb_DEBUGINFO_FLAGS=-g
+gb_LINKER_DEBUGINFO_FLAGS=
+
+# Darwin mktemp -t expects a prefix, not a pattern
+gb_MKTEMP := /usr/bin/mktemp -t gbuild.
+
+gb_OSDEFS := \
+ -DIOS \
+ -D_PTHREADS \
+ -DUNIX \
+ -DUNX \
+ -D_REENTRANT \
+ -DNO_PTHREAD_PRIORITY \
+ $(LFS_CFLAGS) \
+
+gb_CFLAGS := \
+ $(gb_CFLAGS_COMMON) \
+ -Wshadow \
+ -fno-strict-aliasing \
+
+gb_CXXFLAGS := \
+ $(gb_CXXFLAGS_COMMON) \
+ -Wno-ctor-dtor-privacy \
+ -fno-strict-aliasing \
+ -fsigned-char \
+ $(CXXFLAGS_CXX11) \
+
+# These are to get the compiler to switch to Objective-C++ or Objective-C mode
+gb_OBJCXXFLAGS := -x objective-c++
+gb_OBJCFLAGS := -x objective-c
+
+gb_COMPILERDEFS += \
+ -DBOOST_DETAIL_NO_CONTAINER_FWD
+
+# LinkTarget class
+
+gb_LinkTarget_CFLAGS := $(gb_CFLAGS)
+gb_LinkTarget_CXXFLAGS := $(gb_CXXFLAGS)
+gb_LinkTarget_OBJCXXFLAGS := $(gb_CXXFLAGS) $(gb_OBJCXXFLAGS)
+gb_LinkTarget_OBJCFLAGS := $(gb_CFLAGS) $(gb_OBJCFLAGS)
+
+define gb_LinkTarget__get_liblinkflags
+$(patsubst lib%.a,-l%,$(foreach lib,$(1),$(call gb_Library_get_filename,$(lib))))
+endef
+
+define gb_LinkTarget__get_layer
+$(if $(filter Executable,$(1)),\
+ $$(call gb_Executable_get_layer,$(2)),\
+ $$(call gb_Library_get_layer,$(2)))
+endef
+
+# To not export anything: -Wl$(COMMA)-exported_symbols_list$(COMMA)/dev/null
+# But for some reason that slows down ld significantly.
+
+define gb_LinkTarget__command_dynamiclink
+ $(if $(filter Library CppunitTest,$(TARGETTYPE)),@echo No dynamic libraries should be built for iOS && exit 1, \
+ $(if $(CXXOBJECTS)$(OBJCXXOBJECTS)$(GENCXXOBJECTS)$(EXTRAOBJECTLISTS),$(gb_CXX),$(gb_CC)) \
+ $(gb_Executable_TARGETTYPEFLAGS) \
+ $(subst \d,$$,$(RPATH)) \
+ $(T_USE_LD) $(T_LDFLAGS) \
+ -dead_strip \
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_target,$(object))) \
+ $(foreach object,$(OBJCOBJECTS),$(call gb_ObjCObject_get_target,$(object))) \
+ $(foreach object,$(OBJCXXOBJECTS),$(call gb_ObjCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_target,$(object))) \
+ $(foreach extraobjectlist,$(EXTRAOBJECTLISTS),`cat $(extraobjectlist)`) \
+ $(foreach lib,$(LINKED_STATIC_LIBS),$(call gb_StaticLibrary_get_target,$(lib))) \
+ $(call gb_LinkTarget__get_liblinkflags,$(LINKED_LIBS)) \
+ $(shell $(SRCDIR)/bin/lo-all-static-libs) \
+ $(T_LIBS) \
+ -o $(1))
+endef
+
+# parameters: 1-linktarget 2-cobjects 3-cxxobjects
+define gb_LinkTarget__command_staticlink
+$(call gb_Helper_abbreviate_dirs,\
+ rm -f $(1) && \
+ $(gb_AR) -rsu $(1) \
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_target,$(object))) \
+ $(foreach object,$(OBJCOBJECTS),$(call gb_ObjCObject_get_target,$(object))) \
+ $(foreach object,$(OBJCXXOBJECTS),$(call gb_ObjCxxObject_get_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_target,$(object))) \
+ $(foreach extraobjectlist,$(EXTRAOBJECTLISTS),@$(extraobjectlist)) \
+ $(if $(findstring s,$(MAKEFLAGS)),2> /dev/null))
+endef
+
+define gb_LinkTarget__command
+$(call gb_Output_announce,$(2),$(true),LNK,4)
+ $(call gb_Trace_StartRange,$(2),LNK)
+$(if $(filter Executable,$(TARGETTYPE)),$(call gb_LinkTarget__command_dynamiclink,$(1),$(2)))
+$(if $(filter CppunitTest Library StaticLibrary,$(TARGETTYPE)),$(call gb_LinkTarget__command_staticlink,$(1)))
+ $(call gb_Trace_EndRange,$(2),LNK)
+endef
+
+define gb_LinkTarget_use_system_darwin_frameworks
+$(call gb_LinkTarget_add_libs,$(1),$(foreach fw,$(2),-framework $(fw)))
+$(if $(call gb_LinkTarget__is_merged,$(1)),\
+ $(call gb_LinkTarget_add_libs,$(call gb_Library_get_linktarget,merged),$(foreach fw,$(2),-framework $(fw))))
+endef
+
+
+# Library class
+
+gb_Library_DEFS :=
+gb_Library_SYSPRE := lib
+gb_Library_UNOVERPRE := $(gb_Library_SYSPRE)uno_
+gb_Library_PLAINEXT := .a
+gb_Library_PLAINEXT_FOR_BUILD := .dylib
+gb_Library_DLLEXT := .a
+gb_Library_RTEXT := gcc3$(gb_Library_PLAINEXT)
+
+gb_Library_OOOEXT := $(gb_Library_DLLPOSTFIX)$(gb_Library_PLAINEXT)
+gb_Library_UNOEXT := .uno$(gb_Library_PLAINEXT)
+
+gb_Library_FILENAMES := \
+ $(foreach lib,$(gb_Library_OOOLIBS),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_OOOEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_NONE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_URE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OOO),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OXT),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PRIVATELIBS_URE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_OOOEXT)) \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_RTEXT)) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):$(gb_Library_UNOVERPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_EXTENSIONLIBS),$(lib):$(lib)$(gb_Library_UNOEXT)) \
+
+
+gb_Library_LAYER := \
+ $(foreach lib,$(gb_Library_OOOLIBS),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_URE),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OOO),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OXT),$(lib):OXT) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_NONE),$(lib):NONE) \
+ $(foreach lib,$(gb_Library_PRIVATELIBS_URE),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_EXTENSIONLIBS),$(lib):OXT) \
+
+define gb_Library_Library_platform
+$(call gb_LinkTarget_get_target,$(2)) : LAYER := $(call gb_Library_get_layer,$(1))
+
+endef
+
+gb_Library__set_soversion_script_platform =
+
+gb_Library_get_sdk_link_dir = $(WORKDIR)/LinkTarget/Library
+
+# Executable class
+
+gb_Executable_EXT :=
+gb_Executable_TARGETTYPEFLAGS :=
+
+gb_Executable_LAYER := \
+ $(foreach exe,$(gb_Executable_UREBIN),$(exe):UREBIN) \
+ $(foreach exe,$(gb_Executable_SDK),$(exe):SDKBIN) \
+ $(foreach exe,$(gb_Executable_OOO),$(exe):OOO) \
+ $(foreach exe,$(gb_Executable_NONE),$(exe):NONE) \
+
+
+define gb_Executable_Executable_platform
+$(call gb_LinkTarget_get_target,$(2)) : LAYER := $(call gb_Executable_get_layer,$(1))
+
+endef
+
+
+# CppunitTest class
+
+gb_CppunitTest_CPPTESTPRECOMMAND := :
+gb_CppunitTest_get_filename = libtest_(1).a
+gb_CppunitTest_get_ilibfilename = $(gb_CppunitTest_get_filename)
+
+define gb_CppunitTest_CppunitTest_platform
+$(call gb_LinkTarget_get_target,$(2)) : LAYER := NONE
+
+endef
+
+# InstallModuleTarget class
+
+define gb_InstallModuleTarget_InstallModuleTarget_platform
+$(call gb_InstallModuleTarget_add_defs,$(1),\
+ $(gb_CPUDEFS) \
+ $(gb_OSDEFS) \
+ -DCOMID=gcc3 \
+ -D_gcc3 \
+)
+
+endef
+
+# InstallScript class
+
+gb_InstallScript_EXT := .ins
+
+# CliAssemblyTarget class
+
+gb_CliAssemblyTarget_POLICYEXT :=
+gb_CliAssemblyTarget_get_dll :=
+
+# Extension class
+
+gb_Extension_LICENSEFILE_DEFAULT := $(INSTROOT)/LICENSE
+
+# UnpackedTarget class
+
+gb_UnpackedTarget_TARFILE_LOCATION := $(TARFILE_LOCATION)
+
+# UnoApiHeadersTarget class
+
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+gb_UnoApiHeadersTarget_select_variant = $(if $(filter udkapi,$(1)),comprehensive,$(2))
+else
+gb_UnoApiHeadersTarget_select_variant = $(2)
+endif
+
+# UIMenubarTarget class
+
+define gb_UIMenubarTarget__command
+$(call gb_Output_announce,$(2),$(true),UIM,1)
+$(call gb_Trace_StartRange,$(2),UIM)
+cp $(3) $(1)
+$(call gb_Trace_EndRange,$(2),UIM)
+
+endef
+
+gb_UIMenubarTarget_UIMenubarTarget_platform :=
+
+# Python
+gb_PYTHON_PRECOMMAND :=
+
+include $(GBUILDDIR)/platform/com_GCC_class.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/iOS_AARCH64_GCC.mk b/solenv/gbuild/platform/iOS_AARCH64_GCC.mk
new file mode 100644
index 000000000..0d03fa027
--- /dev/null
+++ b/solenv/gbuild/platform/iOS_AARCH64_GCC.mk
@@ -0,0 +1,22 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+gb_CPUDEFS := -DARM64
+
+include $(GBUILDDIR)/platform/iOS.mk
diff --git a/solenv/gbuild/platform/iOS_X86_64_GCC.mk b/solenv/gbuild/platform/iOS_X86_64_GCC.mk
new file mode 100644
index 000000000..008f54f2e
--- /dev/null
+++ b/solenv/gbuild/platform/iOS_X86_64_GCC.mk
@@ -0,0 +1,22 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+gb_CPUDEFS := -DX86_64
+
+include $(GBUILDDIR)/platform/iOS.mk
diff --git a/solenv/gbuild/platform/linux.mk b/solenv/gbuild/platform/linux.mk
new file mode 100644
index 000000000..8fc7d38e3
--- /dev/null
+++ b/solenv/gbuild/platform/linux.mk
@@ -0,0 +1,24 @@
+# -*- 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/.
+#
+
+gb__LinkTarget_LDFLAGS_zdefs := -Wl,-z,defs
+ifeq ($(COM_IS_CLANG),TRUE)
+ifneq ($(filter -fsanitize=%,$(CC) $(LDFLAGS)),)
+gb__LinkTarget_LDFLAGS_zdefs :=
+endif
+endif
+gb_LinkTarget_LDFLAGS += $(gb__LinkTarget_LDFLAGS_zdefs)
+
+include $(GBUILDDIR)/platform/unxgcc.mk
+
+ifneq ($(ATOMIC_LIB),)
+gb_STDLIBS_CXX := $(ATOMIC_LIB)
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/macosx.mk b/solenv/gbuild/platform/macosx.mk
new file mode 100644
index 000000000..5c072cba4
--- /dev/null
+++ b/solenv/gbuild/platform/macosx.mk
@@ -0,0 +1,381 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+gb_SDKDIR := $(MACOSX_SDK_PATH)
+
+include $(GBUILDDIR)/platform/com_GCC_defs.mk
+
+# Darwin mktemp -t expects a prefix, not a pattern
+gb_MKTEMP ?= /usr/bin/mktemp -t gbuild
+
+gb_OSDEFS := \
+ -D$(OS) \
+ -D_PTHREADS \
+ -DUNIX \
+ -DUNX \
+ -D_REENTRANT \
+ -DNO_PTHREAD_PRIORITY \
+ -DMAC_OS_X_VERSION_MIN_REQUIRED=$(MAC_OS_X_VERSION_MIN_REQUIRED) \
+ -DMAC_OS_X_VERSION_MAX_ALLOWED=$(MAC_OS_X_VERSION_MIN_REQUIRED) \
+ $(LFS_CFLAGS) \
+
+
+gb_CFLAGS := \
+ $(gb_CFLAGS_COMMON) \
+ -fPIC \
+ -fno-strict-aliasing \
+ -Wshadow
+
+gb_CXXFLAGS := \
+ $(gb_CXXFLAGS_COMMON) \
+ -fPIC \
+ -Woverloaded-virtual \
+ -Wshadow \
+ -Wno-ctor-dtor-privacy \
+ -fno-strict-aliasing \
+ -fsigned-char \
+ $(CXXFLAGS_CXX11)
+
+ #-fsigned-char \ might be removed?
+
+# these are to get g++ to switch to Objective-C++ mode
+# (see toolkit module for a case where it is necessary to do it this way)
+gb_OBJCXXFLAGS := -x objective-c++ -fobjc-exceptions
+
+gb_OBJCFLAGS := -x objective-c -fobjc-exceptions
+
+# LinkTarget class
+
+define gb_LinkTarget__get_rpath_for_layer
+$(patsubst $(1):%,%,$(filter $(1):%,$(gb_LinkTarget__RPATHS)))
+endef
+
+gb_LinkTarget__RPATHS := \
+ URELIB:@__________________________________________________URELIB/ \
+ UREBIN: \
+ OOO:@__________________________________________________OOO/ \
+ SDKBIN: \
+ OXT: \
+ NONE:@__________________________________________________NONE/ \
+
+# $(call gb_LinkTarget__get_installname,libfilename,layerprefix)
+define gb_LinkTarget__get_installname
+$(if $(2),-install_name '$(2)$(1)')
+endef
+
+gb_LinkTarget_CFLAGS := $(gb_CFLAGS)
+gb_LinkTarget_CXXFLAGS := $(gb_CXXFLAGS)
+gb_LinkTarget_OBJCXXFLAGS := $(gb_CXXFLAGS) $(gb_OBJCXXFLAGS)
+gb_LinkTarget_OBJCFLAGS := $(gb_CFLAGS) $(gb_OBJCFLAGS)
+
+define gb_LinkTarget__get_layer
+$(if $(filter Executable,$(1)),\
+ $$(call gb_Executable_get_layer,$(2)),\
+ $$(call gb_Library_get_layer,$(2)))
+endef
+
+# We cannot sign executables early since Mojave/Catalina would treat them as
+# restricted binary and ignore any DYLD_LIBRARY_PATH setting - So all
+# signing is handled by the solenv/bin/macosx-codesign-app-bundle script.
+# And the soffice executable needs to be signed last in
+# macosx-codesign-app-bundle, as codesign would fail complaining that other
+# parts of the app have not yet been signed:
+
+define gb_LinkTarget__command_dynamiclink
+$(call gb_Helper_abbreviate_dirs,\
+ FILELIST=$(call gb_var2file,$(shell $(gb_MKTEMP)),100, \
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_target,$(object))) \
+ $(foreach object,$(OBJCOBJECTS),$(call gb_ObjCObject_get_target,$(object))) \
+ $(foreach object,$(OBJCXXOBJECTS),$(call gb_ObjCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_target,$(object))) \
+ $(foreach object,$(GENOBJCOBJECTS),$(call gb_GenObjCObject_get_target,$(object))) \
+ $(foreach object,$(GENOBJCXXOBJECTS),$(call gb_GenObjCxxObject_get_target,$(object))) \
+ $(foreach extraobjectlist,$(EXTRAOBJECTLISTS),$(shell cat $(extraobjectlist)))) && \
+ cat $${FILELIST} | tr "[:space:]" "\n" | grep -v '^$$' > $${FILELIST}.1 && \
+ mv $${FILELIST}.1 $${FILELIST} && \
+ $(if $(CXXOBJECTS)$(OBJCXXOBJECTS)$(GENCXXOBJECTS)$(EXTRAOBJECTLISTS),$(gb_CXX),$(gb_CC)) \
+ $(if $(filter Executable,$(TARGETTYPE)),$(gb_Executable_TARGETTYPEFLAGS)) \
+ $(if $(filter Bundle,$(TARGETTYPE)),$(gb_Bundle_TARGETTYPEFLAGS)) \
+ $(if $(filter Library CppunitTest,$(TARGETTYPE)),$(gb_Library_TARGETTYPEFLAGS)) \
+ $(subst \d,$$,$(RPATH)) \
+ $(T_USE_LD) $(T_LDFLAGS) \
+ $(patsubst lib%.dylib,-l%,$(patsubst %.$(gb_Library_UDK_MAJORVER),%,$(foreach lib,$(LINKED_LIBS),$(call gb_Library_get_filename,$(lib))))) \
+ -Wl$(COMMA)-filelist$(COMMA)$${FILELIST} \
+ $(T_LIBS) \
+ $(foreach lib,$(LINKED_STATIC_LIBS),$(call gb_StaticLibrary_get_target,$(lib))) \
+ -o $(1) && \
+ rm -f $${FILELIST} && \
+ $(if $(SOVERSIONSCRIPT),ln -sf $(1) $(ILIBTARGET),:) && \
+ $(if $(filter Executable,$(TARGETTYPE)), \
+ $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl app $(LAYER) $(1) &&) \
+ $(if $(filter Library Bundle CppunitTest,$(TARGETTYPE)),\
+ $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl $(LAYER) $(1) &&) \
+ $(if $(filter Library,$(TARGETTYPE)),\
+ otool -l $(1) | grep -A 5 LC_ID_DYLIB \
+ > $(WORKDIR)/LinkTarget/$(2).exports.tmp && \
+ $(NM) -g -P $(1) | cut -d' ' -f1-2 | grep -v U$$ \
+ >> $(WORKDIR)/LinkTarget/$(2).exports.tmp && \
+ $(call gb_Helper_replace_if_different_and_touch,$(WORKDIR)/LinkTarget/$(2).exports.tmp, \
+ $(WORKDIR)/LinkTarget/$(2).exports,$(1)) &&) \
+ :)
+endef
+
+# parameters: 1-linktarget 2-cobjects 3-cxxobjects
+define gb_LinkTarget__command_staticlink
+$(call gb_Helper_abbreviate_dirs,\
+ rm -f $(1) && \
+ $(gb_AR) -rsu $(1) \
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_target,$(object))) \
+ $(foreach object,$(OBJCOBJECTS),$(call gb_ObjCObject_get_target,$(object))) \
+ $(foreach object,$(OBJCXXOBJECTS),$(call gb_ObjCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_target,$(object))) \
+ $(foreach object,$(GENOBJCOBJECTS),$(call gb_GenObjCObject_get_target,$(object))) \
+ $(foreach object,$(GENOBJCXXOBJECTS),$(call gb_GenObjCxxObject_get_target,$(object))) \
+ $(foreach extraobjectlist,$(EXTRAOBJECTLISTS),$(shell cat $(extraobjectlist))) \
+ $(if $(findstring s,$(MAKEFLAGS)),2> /dev/null))
+endef
+
+define gb_LinkTarget__command
+$(call gb_Output_announce,$(2),$(true),LNK,4)
+ $(call gb_Trace_StartRange,$(2),LNK)
+$(if $(filter Library Bundle CppunitTest Executable,$(TARGETTYPE)),$(call gb_LinkTarget__command_dynamiclink,$(1),$(2)))
+$(if $(filter StaticLibrary,$(TARGETTYPE)),$(call gb_LinkTarget__command_staticlink,$(1)))
+ $(call gb_Trace_EndRange,$(2),LNK)
+endef
+
+define gb_LinkTarget_use_system_darwin_frameworks
+$(call gb_LinkTarget_add_libs,$(1),$(foreach fw,$(2),-framework $(fw)))
+$(if $(call gb_LinkTarget__is_merged,$(1)),\
+ $(call gb_LinkTarget_add_libs,$(call gb_Library_get_linktarget,merged),$(foreach fw,$(2),-framework $(fw))))
+endef
+
+
+# Library class
+
+gb_Library_DEFS :=
+gb_Library_TARGETTYPEFLAGS := -dynamiclib -single_module
+gb_Bundle_TARGETTYPEFLAGS := -bundle
+gb_Library_UDK_MAJORVER := 3
+gb_Library_SYSPRE := lib
+gb_Library_UNOVERPRE := $(gb_Library_SYSPRE)uno_
+gb_Library_PLAINEXT := .dylib
+gb_Library_PLAINEXT_FOR_BUILD := .dylib
+gb_Library_DLLEXT := .dylib
+gb_Library_RTEXT := gcc3$(gb_Library_PLAINEXT)
+
+gb_Library_OOOEXT := $(gb_Library_DLLPOSTFIX)$(gb_Library_PLAINEXT)
+gb_Library_UNOEXT := .uno$(gb_Library_PLAINEXT)
+
+gb_Library_FILENAMES := \
+ $(foreach lib,$(gb_Library_OOOLIBS),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_OOOEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_NONE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_URE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OOO),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OXT),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PRIVATELIBS_URE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_OOOEXT)) \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_RTEXT).$(gb_Library_UDK_MAJORVER)) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):$(gb_Library_UNOVERPRE)$(lib)$(gb_Library_PLAINEXT).$(gb_Library_UDK_MAJORVER)) \
+ $(foreach lib,$(gb_Library_EXTENSIONLIBS),$(lib):$(lib)$(gb_Library_UNOEXT)) \
+
+
+gb_Library_LAYER := \
+ $(foreach lib,$(gb_Library_OOOLIBS),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_URE),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OOO),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OXT),$(lib):OXT) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_NONE),$(lib):NONE) \
+ $(foreach lib,$(gb_Library_PRIVATELIBS_URE),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_EXTENSIONLIBS),$(lib):OXT) \
+
+define gb_Library_get_rpath
+$(call gb_LinkTarget__get_installname,$(call gb_Library_get_filename,$(1)),$(call gb_LinkTarget__get_rpath_for_layer,$(call gb_Library_get_layer,$(1))))
+endef
+
+define gb_Library_Library_platform
+$(call gb_LinkTarget_get_target,$(2)) : RPATH := $(call gb_Library_get_rpath,$(1))
+$(call gb_LinkTarget_get_target,$(2)) : LAYER := $(call gb_Library_get_layer,$(1))
+
+endef
+
+gb_Library__set_soversion_script_platform = $(gb_Library__set_soversion_script)
+
+gb_Library_get_sdk_link_dir = $(WORKDIR)/LinkTarget/Library
+
+gb_Library_get_sdk_link_lib = $(gb_Library_get_versionlink_target)
+
+# bundle is a special kind of library that exists only on Darwin/OSX
+# set the TARGETTYPE to Bundle, and clear install_name(RPATH)
+define gb_Library_Bundle
+$(call gb_Library_Library,$(1))
+$(call gb_LinkTarget_set_targettype,$(call gb_Library_get_linktarget,$(1)),Bundle)
+$(call gb_Library_get_linktarget_target,$(1)) : RPATH :=
+endef
+
+# Executable class
+
+gb_Executable_EXT :=
+gb_Executable_TARGETTYPEFLAGS := -bind_at_load
+
+gb_Executable_LAYER := \
+ $(foreach exe,$(gb_Executable_UREBIN),$(exe):UREBIN) \
+ $(foreach exe,$(gb_Executable_SDK),$(exe):SDKBIN) \
+ $(foreach exe,$(gb_Executable_OOO),$(exe):OOO) \
+ $(foreach exe,$(gb_Executable_NONE),$(exe):NONE) \
+
+
+gb_Executable_get_rpath :=
+
+define gb_Executable_Executable_platform
+$(call gb_LinkTarget_get_target,$(2)) : RPATH :=
+$(call gb_LinkTarget_get_target,$(2)) : LAYER := $(call gb_Executable_get_layer,$(1))
+
+endef
+
+
+# CppunitTest class
+
+gb_CppunitTest_UNITTESTFAILED := $(GBUILDDIR)/platform/unittest-failed-MACOSX.sh
+gb_CppunitTest_PYTHONDEPS := $(call gb_Library_get_target,pyuno_wrapper) $(if $(SYSTEM_PYTHON),,$(call gb_GeneratedPackage_get_target,python3))
+gb_CppunitTest_CPPTESTPRECOMMAND := \
+ $(call gb_Helper_extend_ld_path,$(gb_Library_DLLDIR):$(WORKDIR)/UnpackedTarball/cppunit/src/cppunit/.libs)
+gb_CppunitTest_get_filename = libtest_$(1).dylib
+gb_CppunitTest_get_ilibfilename = $(gb_CppunitTest_get_filename)
+gb_CppunitTest_malloc_check := -o "env MallocScribble=1" -o "env MallocPreScribble=1"
+
+define gb_CppunitTest_CppunitTest_platform
+$(call gb_LinkTarget_get_target,$(2)) : RPATH :=
+$(call gb_LinkTarget_get_target,$(2)) : LAYER := NONE
+
+endef
+
+# JunitTest class
+
+ifneq ($(OOO_TEST_SOFFICE),)
+gb_JunitTest_SOFFICEARG:=$(OOO_TEST_SOFFICE)
+else
+ifneq ($(gb_JunitTest_DEBUGRUN),)
+gb_JunitTest_SOFFICEARG:=connect:pipe,name=$(USER)
+else
+gb_JunitTest_SOFFICEARG:=path:$(INSTROOT)/$(LIBO_BIN_FOLDER)/soffice
+endif
+endif
+
+define gb_JunitTest_JunitTest_platform
+$(call gb_JunitTest_get_target,$(1)) : DEFS := \
+ -Dorg.openoffice.test.arg.soffice="$(gb_JunitTest_SOFFICEARG)" \
+ -Dorg.openoffice.test.arg.env=DYLD_LIBRARY_PATH"$$$${DYLD_LIBRARY_PATH+=$$$$DYLD_LIBRARY_PATH}" \
+ -Dorg.openoffice.test.arg.user=$(call gb_Helper_make_url,$(call gb_JunitTest_get_userdir,$(1))) \
+ -Dorg.openoffice.test.arg.workdir=$(call gb_JunitTest_get_userdir,$(1)) \
+
+endef
+
+# PythonTest class
+
+gb_PythonTest_UNITTESTFAILED := $(GBUILDDIR)/platform/unittest-failed-MACOSX.sh
+gb_PythonTest_DEPS := $(call gb_GeneratedPackage_get_target,python3) $(call gb_Package_get_target,python_shell)
+gb_PythonTest_PRECOMMAND := $(gb_Helper_LIBRARY_PATH_VAR)=$${$(gb_Helper_LIBRARY_PATH_VAR):+$$$(gb_Helper_LIBRARY_PATH_VAR):}$(INSTROOT)/$(LIBO_URE_LIB_FOLDER)
+ifneq ($(LIBO_LIB_FOLDER),$(LIBO_URE_LIB_FOLDER))
+gb_PythonTest_PRECOMMAND := $(gb_PythonTest_PRECOMMAND):$(INSTROOT)/$(LIBO_LIB_FOLDER)
+endif
+gb_PythonTest_PRECOMMAND := $(gb_PythonTest_PRECOMMAND):$(WORKDIR)/UnpackedTarball/cppunit/src/cppunit/.libs
+
+# UITest class
+
+gb_UITest_DEPS := $(call gb_GeneratedPackage_get_target,python3)
+
+# Module class
+
+define gb_Module_DEBUGRUNCOMMAND
+lldb -f $(INSTROOT)/$(LIBO_BIN_FOLDER)/soffice -- --norestore --nologo \
+ '"--accept=pipe,name=$(USER)\;urp"'
+endef
+
+# InstallModuleTarget class
+
+define gb_InstallModuleTarget_InstallModuleTarget_platform
+$(call gb_InstallModuleTarget_add_defs,$(1),\
+ $(gb_CPUDEFS) \
+ $(gb_OSDEFS) \
+ -DCOMID=gcc3 \
+ -D_gcc3 \
+)
+
+endef
+
+# InstallScript class
+
+gb_InstallScript_EXT := .ins
+
+# CliAssemblyTarget class
+
+gb_CliAssemblyTarget_POLICYEXT :=
+gb_CliAssemblyTarget_get_dll :=
+
+# Extension class
+
+gb_Extension_LICENSEFILE_DEFAULT := $(INSTROOT)/Resources/LICENSE
+
+# UnpackedTarget class
+
+gb_UnpackedTarget_TARFILE_LOCATION := $(TARFILE_LOCATION)
+
+# UnoApiHeadersTarget class
+
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+gb_UnoApiHeadersTarget_select_variant = $(if $(filter udkapi,$(1)),comprehensive,$(2))
+else
+gb_UnoApiHeadersTarget_select_variant = $(2)
+endif
+
+# UIMenubarTarget class
+
+define gb_UIMenubarTarget__command
+$(call gb_Output_announce,$(2),$(true),UIM,1)
+$(call gb_Trace_StartRange,$(2),UIM)
+$(call gb_ExternalExecutable_get_command,xsltproc) --nonet -o $(1) $(UI_MENUBAR_XSLT) $(3)
+$(call gb_Trace_EndRange,$(2),UIM)
+
+endef
+
+define gb_UIMenubarTarget_UIMenubarTarget_platform
+$(call gb_UIMenubarTarget_get_target,$(1)) : UI_MENUBAR_XSLT := $(SRCDIR)/solenv/bin/macosx_menubar_modification.xsl
+$(call gb_UIMenubarTarget_get_target,$(1)) : $(SRCDIR)/solenv/bin/macosx_menubar_modification.xsl
+$(call gb_UIMenubarTarget_get_target,$(1)) :| $(call gb_ExternalExecutable_get_dependencies,xsltproc)
+
+endef
+
+# Python
+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)
+
+include $(GBUILDDIR)/platform/com_GCC_class.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/solaris.mk b/solenv/gbuild/platform/solaris.mk
new file mode 100644
index 000000000..9d18cd913
--- /dev/null
+++ b/solenv/gbuild/platform/solaris.mk
@@ -0,0 +1,357 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+include $(GBUILDDIR)/platform/com_GCC_defs.mk
+
+gb_MKTEMP := mktemp -t gbuild.XXXXXX
+
+ifneq ($(origin AR),default)
+gb_AR := $(AR)
+endif
+
+# do not define SOLARIS - use #ifdef __sun instead
+# -D$(OS) \
+
+gb_OSDEFS := \
+ -DSYSV \
+ -DSUN \
+ -DSUN4 \
+ -D_REENTRANT \
+ -D_POSIX_PTHREAD_SEMANTICS \
+ -D_PTHREADS \
+ -DUNIX \
+ -DUNX \
+ $(PTHREAD_CFLAGS) \
+ $(LFS_CFLAGS) \
+
+gb_CFLAGS := \
+ $(gb_CFLAGS_COMMON) \
+ -fPIC \
+ -Wshadow \
+
+gb_CXXFLAGS := \
+ $(gb_CXXFLAGS_COMMON) \
+ -fPIC \
+ -Wshadow \
+ -Woverloaded-virtual \
+ $(CXXFLAGS_CXX11) \
+
+ifneq ($(strip $(SYSBASE)),)
+gb_CXXFLAGS += --sysroot=$(SYSBASE)
+gb_CFLAGS += --sysroot=$(SYSBASE)
+gb_LinkTarget_LDFLAGS += \
+ -Wl,--sysroot=$(SYSBASE)
+endif
+
+gb_LinkTarget_LDFLAGS += \
+ -L$(SYSBASE)/lib \
+ -L$(SYSBASE)/usr/lib \
+ -Wl,-B,direct \
+ -Wl,-z,defs \
+ -Wl,-z,combreloc \
+
+ifeq ($(HAVE_LD_HASH_STYLE),TRUE)
+gb_LinkTarget_LDFLAGS += \
+ -Wl,--hash-style=$(WITH_LINKER_HASH_STYLE) \
+
+endif
+
+ifneq ($(HAVE_LD_BSYMBOLIC_FUNCTIONS),)
+gb_LinkTarget_LDFLAGS += -Wl,-Bsymbolic-functions
+endif
+
+# sun ld doesn't understand -O1 optimize flag
+gb_LINKEROPTFLAGS :=
+gb_LINKERSTRIPDEBUGFLAGS := -Wl,-zredlocsym -Wl,-znoldynsym
+
+# LinkTarget class
+
+define gb_LinkTarget__get_rpath_for_layer
+$(patsubst $(1):%,%,$(filter $(1):%,$(gb_LinkTarget__RPATHS)))
+endef
+
+gb_LinkTarget__RPATHS := \
+ URELIB:\dORIGIN \
+ UREBIN:\dORIGIN \
+ OOO:\dORIGIN \
+ SDKBIN:\dORIGIN/../../program \
+ OXT: \
+ NONE:\dORIGIN/../Library \
+
+gb_LinkTarget_CFLAGS := $(gb_CFLAGS) $(gb_CFLAGS_WERROR)
+gb_LinkTarget_CXXFLAGS := $(gb_CXXFLAGS) $(gb_CFLAGS_WERROR)
+
+# note that `cat $(extraobjectlist)` is needed to build with older gcc versions, e.g. 4.1.2 on SLED10
+# we want to use @$(extraobjectlist) in the long run
+# link with C compiler if there are no C++ files (pyuno_wrapper depends on this)
+define gb_LinkTarget__command_dynamiclink
+$(call gb_Helper_abbreviate_dirs,\
+ $(if $(CXXOBJECTS)$(GENCXXOBJECTS)$(EXTRAOBJECTLISTS),$(gb_CXX),$(gb_CC)) \
+ $(if $(filter Library CppunitTest,$(TARGETTYPE)),$(gb_Library_TARGETTYPEFLAGS)) \
+ $(T_LTOFLAGS) \
+ $(if $(SOVERSIONSCRIPT),-Wl$(COMMA)-soname=$(notdir $(1)) \
+ ) \
+ $(subst \d,$$,$(RPATH)) \
+ $(T_USE_LD) $(T_LDFLAGS) \
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_target,$(object))) \
+ $(foreach extraobjectlist,$(EXTRAOBJECTLISTS),`cat $(extraobjectlist)`) \
+ -Wl$(COMMA)--start-group \
+ $(foreach lib,$(LINKED_STATIC_LIBS),\
+ $(call gb_StaticLibrary_get_target,$(lib))) \
+ $(T_LIBS) \
+ -Wl$(COMMA)--end-group \
+ -Wl$(COMMA)-zrecord \
+ $(patsubst lib%.a,-l%,$(patsubst lib%.so,-l%,$(patsubst %.$(gb_Library_UDK_MAJORVER),%,$(foreach lib,$(LINKED_LIBS),$(call gb_Library_get_filename,$(lib)))))) \
+ -o $(1) \
+ $(if $(SOVERSIONSCRIPT),&& ln -sf ../../program/$(notdir $(1)) $(ILIBTARGET)))
+ $(if $(filter Library,$(TARGETTYPE)), $(call gb_Helper_abbreviate_dirs,\
+ $(READELF) -d $(1) | grep SONAME > $(WORKDIR)/LinkTarget/$(2).exports.tmp; \
+ $(NM) --dynamic --extern-only --defined-only --format=posix $(1) \
+ | cut -d' ' -f1-2 \
+ >> $(WORKDIR)/LinkTarget/$(2).exports.tmp && \
+ $(call gb_Helper_replace_if_different_and_touch,$(WORKDIR)/LinkTarget/$(2).exports.tmp, \
+ $(WORKDIR)/LinkTarget/$(2).exports,$(1))))
+endef
+
+define gb_LinkTarget__command_staticlink
+$(call gb_Helper_abbreviate_dirs,\
+ rm -f $(1) && \
+ $(gb_AR) $(gb_LTOPLUGINFLAGS) -rsu $(1) \
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_target,$(object))) \
+ $(foreach extraobjectlist,$(EXTRAOBJECTLISTS),@$(extraobjectlist)) \
+ $(if $(findstring s,$(MAKEFLAGS)),2> /dev/null))
+endef
+
+define gb_LinkTarget__command
+$(call gb_Output_announce,$(2),$(true),LNK,4)
+ $(call gb_Trace_StartRange,$(2),LNK)
+$(if $(filter Library CppunitTest Executable,$(TARGETTYPE)),$(call gb_LinkTarget__command_dynamiclink,$(1),$(2)))
+$(if $(filter StaticLibrary,$(TARGETTYPE)),$(call gb_LinkTarget__command_staticlink,$(1)))
+ $(call gb_Trace_EndRange,$(2),LNK)
+endef
+
+
+# Library class
+
+gb_Library_DEFS :=
+gb_Library_TARGETTYPEFLAGS := -shared -Wl,-M/usr/lib/ld/map.noexstk -mimpure-text
+gb_Library_UDK_MAJORVER := 3
+gb_Library_SYSPRE := lib
+gb_Library_UNOVERPRE := $(gb_Library_SYSPRE)uno_
+gb_Library_PLAINEXT := .so
+gb_Library_DLLEXT := .so
+gb_Library_RTEXT := gcc3$(gb_Library_PLAINEXT)
+
+gb_Library_OOOEXT := $(gb_Library_DLLPOSTFIX)$(gb_Library_PLAINEXT)
+gb_Library_UNOEXT := .uno$(gb_Library_PLAINEXT)
+
+gb_STDLIBS := \
+ -lm \
+ -lnsl \
+ -lsocket \
+
+gb_Library_FILENAMES := \
+ $(foreach lib,$(gb_Library_OOOLIBS),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_OOOEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_NONE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_URE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OOO),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OXT),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PRIVATELIBS_URE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_OOOEXT)) \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_RTEXT).$(gb_Library_UDK_MAJORVER)) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):$(gb_Library_UNOVERPRE)$(lib)$(gb_Library_PLAINEXT).$(gb_Library_UDK_MAJORVER)) \
+ $(foreach lib,$(gb_Library_EXTENSIONLIBS),$(lib):$(lib)$(gb_Library_UNOEXT)) \
+
+
+gb_Library_LAYER := \
+ $(foreach lib,$(gb_Library_OOOLIBS),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_URE),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OOO),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OXT),$(lib):OXT) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_NONE),$(lib):NONE) \
+ $(foreach lib,$(gb_Library_PRIVATELIBS_URE),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_EXTENSIONLIBS),$(lib):OXT) \
+
+define gb_Library__get_rpath
+$(if $(1),$(strip -Wl,-z,origin '-Wl,-rpath,$(1)' -L$(INSTDIR)/program))
+endef
+
+define gb_Library_get_rpath
+$(call gb_Library__get_rpath,$(call gb_LinkTarget__get_rpath_for_layer,$(call gb_Library_get_layer,$(1))))
+endef
+
+define gb_Library_Library_platform
+$(call gb_LinkTarget_get_target,$(2)) : RPATH := $(call gb_Library_get_rpath,$(1))
+
+endef
+
+gb_Library__set_soversion_script_platform = $(gb_Library__set_soversion_script)
+
+gb_Library_get_sdk_link_dir = $(INSTDIR)/$(SDKDIRNAME)/lib
+
+gb_Library_get_sdk_link_lib = $(gb_Library_get_versionlink_target)
+
+# Executable class
+
+gb_Executable_EXT :=
+
+gb_Executable_LAYER := \
+ $(foreach exe,$(gb_Executable_UREBIN),$(exe):UREBIN) \
+ $(foreach exe,$(gb_Executable_SDK),$(exe):SDKBIN) \
+ $(foreach exe,$(gb_Executable_OOO),$(exe):OOO) \
+ $(foreach exe,$(gb_Executable_NONE),$(exe):NONE) \
+
+
+define gb_Executable__get_rpath
+$(strip -Wl,-z,origin $(if $(1),'-Wl$(COMMA)-rpath$(COMMA)$(1)') -L$(INSTDIR)/program)
+endef
+
+define gb_Executable_get_rpath
+$(call gb_Executable__get_rpath,$(call gb_LinkTarget__get_rpath_for_layer,$(call gb_Executable_get_layer,$(1))))
+endef
+
+define gb_Executable_Executable_platform
+$(call gb_LinkTarget_get_target,$(2)) : RPATH := $(call gb_Executable_get_rpath,$(1))
+
+endef
+
+
+# CppunitTest class
+
+gb_CppunitTest_CPPTESTPRECOMMAND := \
+ $(call gb_Helper_extend_ld_path,$(WORKDIR)/UnpackedTarball/cppunit/src/cppunit/.libs)
+gb_CppunitTest_get_filename = libtest_$(1).so
+gb_CppunitTest_get_ilibfilename = $(gb_CppunitTest_get_filename)
+
+define gb_CppunitTest_CppunitTest_platform
+$(call gb_LinkTarget_get_target,$(2)) : RPATH := $(call gb_Library__get_rpath,$(call gb_LinkTarget__get_rpath_for_layer,NONE))
+
+endef
+
+define gb_CppunitTest_postprocess
+$(SRCDIR)/solenv/bin/gdb-core-bt.sh $(1) $(2) $(3)
+endef
+
+# JunitTest class
+
+ifneq ($(OOO_TEST_SOFFICE),)
+gb_JunitTest_SOFFICEARG:=$(OOO_TEST_SOFFICE)
+else
+ifneq ($(gb_JunitTest_DEBUGRUN),)
+gb_JunitTest_SOFFICEARG:=connect:pipe,name=$(USER)
+else
+gb_JunitTest_SOFFICEARG:=path:$(INSTROOT)/$(LIBO_BIN_FOLDER)/soffice
+endif
+endif
+
+define gb_JunitTest_JunitTest_platform
+$(call gb_JunitTest_get_target,$(1)) : DEFS := \
+ -Dorg.openoffice.test.arg.env=$(gb_Helper_LIBRARY_PATH_VAR)"$$$${$(gb_Helper_LIBRARY_PATH_VAR)+=$$$$$(gb_Helper_LIBRARY_PATH_VAR)}" \
+ -Dorg.openoffice.test.arg.user=$(call gb_Helper_make_url,$(call gb_JunitTest_get_userdir,$(1))) \
+ -Dorg.openoffice.test.arg.workdir=$(call gb_JunitTest_get_userdir,$(1)) \
+ -Dorg.openoffice.test.arg.postprocesscommand=$(SRCDIR)/solenv/bin/gdb-core-bt.sh \
+ -Dorg.openoffice.test.arg.soffice="$(gb_JunitTest_SOFFICEARG)" \
+
+endef
+
+# PythonTest class
+
+gb_PythonTest_PRECOMMAND := $(gb_CppunitTest_CPPTESTPRECOMMAND)
+
+# Module class
+
+define gb_Module_DEBUGRUNCOMMAND
+OFFICESCRIPT=`mktemp` && \
+printf ". $(INSTROOT)/program/ooenv\\n" > $${OFFICESCRIPT} && \
+printf "gdb --tui $(INSTROOT)/$(LIBO_BIN_FOLDER)/soffice.bin" >> $${OFFICESCRIPT} && \
+printf " -ex \"set args --norestore --nologo '--accept=pipe,name=$(USER);urp;' \"" >> $${OFFICESCRIPT} && \
+printf " -ex \"r\"\\n" >> $${OFFICESCRIPT} && \
+$(SHELL) $${OFFICESCRIPT} && \
+rm $${OFFICESCRIPT}
+endef
+
+# InstallModuleTarget class
+
+define gb_InstallModuleTarget_InstallModuleTarget_platform
+$(call gb_InstallModuleTarget_add_defs,$(1),\
+ $(gb_CPUDEFS) \
+ $(gb_OSDEFS) \
+ -DCOMID=gcc3 \
+ -D_gcc3 \
+)
+
+endef
+
+# InstallScript class
+
+gb_InstallScript_EXT := .ins
+
+# CliAssemblyTarget class
+
+gb_CliAssemblyTarget_POLICYEXT :=
+gb_CliAssemblyTarget_get_dll :=
+
+# Extension class
+
+gb_Extension_LICENSEFILE_DEFAULT := $(INSTROOT)/LICENSE
+
+# UnpackedTarget class
+
+gb_UnpackedTarget_TARFILE_LOCATION := $(TARFILE_LOCATION)
+
+# UnoApiHeadersTarget class
+
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+gb_UnoApiHeadersTarget_select_variant = $(if $(filter udkapi,$(1)),comprehensive,$(2))
+else
+gb_UnoApiHeadersTarget_select_variant = $(2)
+endif
+
+# UIMenubarTarget class
+
+define gb_UIMenubarTarget__command
+$(call gb_Output_announce,$(2),$(true),UIM,1)
+$(call gb_Trace_StartRange,$(2),UIM)
+cp $(3) $(1)
+$(call gb_Trace_EndRange,$(2),UIM)
+
+endef
+
+gb_UIMenubarTarget_UIMenubarTarget_platform :=
+
+# Python
+gb_Python_PRECOMMAND := 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
+
+include $(GBUILDDIR)/platform/com_GCC_class.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/unittest-failed-MACOSX.sh b/solenv/gbuild/platform/unittest-failed-MACOSX.sh
new file mode 100755
index 000000000..049da92b4
--- /dev/null
+++ b/solenv/gbuild/platform/unittest-failed-MACOSX.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+# -*- Mode: sh; 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+cat << EOF
+
+Error: a unit test failed, please do one of:
+make $1Test_$2 CPPUNITTRACE="lldb --" # for interactive debugging on macOS
+make $1Test_$2 VALGRIND=memcheck # for memory checking
+
+You can limit the execution to just one particular test by:
+
+EOF
+
+case $1 in
+ Python)
+ cat << EOF
+make $1Test_$2 PYTHON_TEST_NAME="testXYZ" ...above mentioned params...
+
+EOF
+ ;;
+ *)
+ cat << EOF
+make $1Test_$2 CPPUNIT_TEST_NAME="testXYZ" ...above mentioned params...
+
+EOF
+ ;;
+esac
+
+exit 1
+
+# vim: set et sw=4:
diff --git a/solenv/gbuild/platform/unittest-failed-WNT.sh b/solenv/gbuild/platform/unittest-failed-WNT.sh
new file mode 100755
index 000000000..5ace1f0d1
--- /dev/null
+++ b/solenv/gbuild/platform/unittest-failed-WNT.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+# -*- Mode: sh; 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+cat << EOF
+
+Error: a unit test failed, please do one of:
+make $1Test_$2 CPPUNITTRACE=TRUE # which is a shortcut for the following line
+make $1Test_$2 CPPUNITTRACE="'$DEVENV' /debugexe" # for interactive debugging in Visual Studio
+make $1Test_$2 CPPUNITTRACE="drmemory -free_max_frames 20" # for memory checking (install Dr.Memory first, and put it to your PATH)
+
+You can limit the execution to just one particular test by:
+
+EOF
+
+case $1 in
+ Python)
+ cat << EOF
+make $1Test_$2 PYTHON_TEST_NAME="testXYZ" ...above mentioned params...
+
+EOF
+ ;;
+ *)
+ cat << EOF
+make $1Test_$2 CPPUNIT_TEST_NAME="testXYZ" ...above mentioned params...
+
+EOF
+ ;;
+esac
+
+exit 1
+
+# vim: set et sw=4:
diff --git a/solenv/gbuild/platform/unittest-failed-default.sh b/solenv/gbuild/platform/unittest-failed-default.sh
new file mode 100755
index 000000000..1e742fd7f
--- /dev/null
+++ b/solenv/gbuild/platform/unittest-failed-default.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+# -*- Mode: sh; 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+cat << EOF
+
+Error: a unit test failed, please do one of:
+
+make $1Test_$2 CPPUNITTRACE="gdb --args"
+ # for interactive debugging on Linux
+make $1Test_$2 VALGRIND=memcheck
+ # for memory checking
+make $1Test_$2 DEBUGCPPUNIT=TRUE
+ # for exception catching
+
+You can limit the execution to just one particular test by:
+
+EOF
+
+case $1 in
+ Python)
+ cat << EOF
+make PYTHON_TEST_NAME="testXYZ" ...above mentioned params...
+
+EOF
+ ;;
+ *)
+ cat << EOF
+make CPPUNIT_TEST_NAME="testXYZ" ...above mentioned params...
+
+EOF
+ ;;
+esac
+
+exit 1
+
+# vim: set et sw=4:
diff --git a/solenv/gbuild/platform/unxgcc.mk b/solenv/gbuild/platform/unxgcc.mk
new file mode 100644
index 000000000..94fd8a019
--- /dev/null
+++ b/solenv/gbuild/platform/unxgcc.mk
@@ -0,0 +1,427 @@
+# -*- 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# to block heavy exception handling that try to acquire the solarmutex
+export LO_LEAN_EXCEPTION=1
+
+include $(GBUILDDIR)/platform/com_GCC_defs.mk
+
+gb_MKTEMP := mktemp -t gbuild.XXXXXX
+
+ifneq ($(origin AR),default)
+gb_AR := $(AR)
+endif
+
+gb_OSDEFS := \
+ -D$(OS) \
+ -D_PTHREADS \
+ -DUNIX \
+ -DUNX \
+ $(PTHREAD_CFLAGS) \
+ $(LFS_CFLAGS) \
+
+gb_CFLAGS := \
+ $(gb_CFLAGS_COMMON) \
+ -fPIC \
+ -Wshadow \
+
+# At least libstdc++ needs -pthread when including various C++ headers like <thread>, see
+# <https://gcc.gnu.org/onlinedocs/gcc-8.3.0/libstdc++/manual/manual/using.html
+# #manual.intro.using.flags>:
+ifneq ($(HAVE_LIBSTDCPP),)
+gb_CXX_LINKFLAGS := -pthread
+endif
+# libc++ needs it too
+ifneq ($(HAVE_LIBCPP),)
+gb_CXX_LINKFLAGS := -pthread
+endif
+
+gb_CXXFLAGS := \
+ $(gb_CXXFLAGS_COMMON) \
+ -fPIC \
+ -Wshadow \
+ -Woverloaded-virtual \
+ $(CXXFLAGS_CXX11) \
+ $(gb_CXX_LINKFLAGS) \
+
+
+ifneq ($(strip $(SYSBASE)),)
+gb_CXXFLAGS += --sysroot=$(SYSBASE)
+gb_CFLAGS += --sysroot=$(SYSBASE)
+gb_LinkTarget_LDFLAGS += \
+ -Wl,--sysroot=$(SYSBASE)
+endif
+
+ifeq (,$(DISABLE_DYNLOADING))
+gb_LinkTarget_LDFLAGS += \
+ -Wl,-rpath-link,$(SYSBASE)/lib:$(SYSBASE)/usr/lib \
+ -Wl,-z,combreloc \
+
+endif
+
+ifeq ($(HAVE_LD_HASH_STYLE),TRUE)
+gb_LinkTarget_LDFLAGS += \
+ -Wl,--hash-style=$(WITH_LINKER_HASH_STYLE) \
+
+endif
+
+ifneq ($(HAVE_LD_BSYMBOLIC_FUNCTIONS),)
+gb_LinkTarget_LDFLAGS += -Wl,-Bsymbolic-functions
+endif
+
+gb_LINKEROPTFLAGS := -Wl,-O1
+gb_LINKERSTRIPDEBUGFLAGS := -Wl,-S
+
+# LinkTarget class
+
+define gb_LinkTarget__get_rpath_for_layer
+$(patsubst $(1):%,%,$(filter $(1):%,$(gb_LinkTarget__RPATHS)))
+endef
+
+gb_LinkTarget__RPATHS := \
+ URELIB:\dORIGIN \
+ UREBIN:\dORIGIN \
+ OOO:\dORIGIN \
+ SDKBIN:\dORIGIN/../../program \
+ OXT: \
+ NONE:\dORIGIN/../Library \
+
+gb_LinkTarget_CFLAGS := $(gb_CFLAGS)
+gb_LinkTarget_CXXFLAGS := $(gb_CXXFLAGS)
+
+gb_LinkTarget__cmd_lockfile = $(if $(LOCKFILE),$(LOCKFILE),$(call gb_Executable_get_command,lockfile))
+gb_LinkTarget__Lock := $(WORKDIR)/LinkTarget/link.lock
+
+# No newline or space before endef!
+define gb_LinkTarget__WantLock
+$(if $(strip $(and \
+ $(call gb_CondExeLockfile,$(true)), \
+ $(filter-out Executable/lockfile,$(1)), \
+ $(if $(filter FUZZERS,$(BUILD_TYPE)),,$(DISABLE_DYNLOADING)), \
+ $(filter CppunitTest Executable,$(TARGETTYPE)) \
+ )),$(true))
+endef
+
+# In theory would need to track, if any of the linked objects is C++ code, so for the static build we assume yes :-(
+gb_LinkTarget__NeedsCxxLinker = $(if $(CXXOBJECTS)$(GENCXXOBJECTS)$(EXTRAOBJECTLISTS)$(filter-out XTRUE,X$(ENABLE_RUNTIME_OPTIMIZATIONS)$(DISABLE_DYNLOADING)),$(true))
+
+# note that `cat $(extraobjectlist)` is needed to build with older gcc versions, e.g. 4.1.2 on SLED10
+# we want to use @$(extraobjectlist) in the long run
+# link with C compiler if there are no C++ files (pyuno_wrapper depends on this)
+# But always link with C++ compiler e.g. under -fsanitize=undefined, as sal uses
+# __ubsan_handle_dynamic_type_cache_miss_abort and __ubsan_vptr_type_cache from
+# libclang_rt.ubsan_cxx-x86_64.a, and oosplash links against sal but itself only
+# contains .c sources:
+define gb_LinkTarget__command_dynamiclink
+$(if $(call gb_LinkTarget__WantLock,$2), \
+ echo "$(call gb_Output_announce_str,$(2): wait for lock at $$(date -u),$(true),LNK,5)" ; \
+ $(gb_LinkTarget__cmd_lockfile) -r -1 $(gb_LinkTarget__Lock) ; \
+ echo "$(call gb_Output_announce_str,$(2): got link lock at $$(date -u),$(true),LNK,5)" ; \
+)
++$(call gb_Helper_abbreviate_dirs,\
+ $(if $(call gb_LinkTarget__NeedsCxxLinker),$(or $(T_CXX),$(gb_CXX)) $(gb_CXX_LINKFLAGS),$(or $(T_CC),$(gb_CC))) \
+ $(if $(filter Library CppunitTest,$(TARGETTYPE)),$(gb_Library_TARGETTYPEFLAGS)) \
+ $(T_LTOFLAGS) \
+ $(if $(SOVERSIONSCRIPT),-Wl$(COMMA)--soname=$(notdir $(1)) \
+ -Wl$(COMMA)--version-script=$(SOVERSIONSCRIPT)) \
+ $(subst \d,$$,$(RPATH)) \
+ $(T_USE_LD) $(T_LDFLAGS) $(foreach pre_js,$(T_PREJS), --pre-js $(pre_js)) \
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_target,$(object))) \
+ $(foreach extraobjectlist,$(EXTRAOBJECTLISTS),`cat $(extraobjectlist)`) \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)), \
+ -Wl$(COMMA)--start-group \
+ $(patsubst lib%.a,-l%,$(patsubst lib%.so,-l%,$(patsubst %.$(gb_Library_UDK_MAJORVER),%,$(foreach lib,$(LINKED_LIBS),$(call gb_Library_get_filename,$(lib)))))) \
+ $(foreach lib,$(LINKED_STATIC_LIBS),$(call gb_StaticLibrary_get_target,$(lib))) \
+ $(patsubst $(gb_LinkTarget__syslib),%,$(T_LIBS)) \
+ $(if $(call gb_LinkTarget__NeedsCxxLinker),$(T_STDLIBS_CXX)) \
+ -Wl$(COMMA)--end-group \
+ , \
+ -Wl$(COMMA)--start-group \
+ $(foreach lib,$(LINKED_STATIC_LIBS),$(call gb_StaticLibrary_get_target,$(lib))) \
+ $(T_LIBS) \
+ $(if $(call gb_LinkTarget__NeedsCxxLinker),$(T_STDLIBS_CXX)) \
+ -Wl$(COMMA)--end-group \
+ -Wl$(COMMA)--no-as-needed \
+ $(patsubst lib%.a,-l%,$(patsubst lib%.so,-l%,$(patsubst %.$(gb_Library_UDK_MAJORVER),%,$(foreach lib,$(LINKED_LIBS),$(call gb_Library_get_filename,$(lib)))))) \
+ ) \
+ -o $(1) \
+ $(if $(SOVERSIONSCRIPT),&& ln -sf ../../program/$(notdir $(1)) $(ILIBTARGET)) \
+ $(if $(call gb_LinkTarget__WantLock,$(2)),; RC=$$? ; rm -f $(gb_LinkTarget__Lock); if test $$RC -ne 0; then exit $$RC; fi))
+
+$(if $(filter Library,$(TARGETTYPE)), $(call gb_Helper_abbreviate_dirs,\
+ $(READELF) -d $(1) | grep SONAME > $(WORKDIR)/LinkTarget/$(2).exports.tmp; \
+ $(NM) $(gb_LTOPLUGINFLAGS) --dynamic --extern-only --defined-only --format=posix $(1) \
+ | cut -d' ' -f1-2 >> $(WORKDIR)/LinkTarget/$(2).exports.tmp && \
+ $(call gb_Helper_replace_if_different_and_touch,$(WORKDIR)/LinkTarget/$(2).exports.tmp, \
+ $(WORKDIR)/LinkTarget/$(2).exports,$(1))))
+$(if $(and $(filter CppunitTest Executable,$(TARGETTYPE)),$(filter EMSCRIPTEN,$(OS)),$(filter TRUE,$(ENABLE_QT5))), \
+ cp $(QT5_PLATFORMS_SRCDIR)/qtlogo.svg $(QT5_PLATFORMS_SRCDIR)/qtloader.js $(dir $(1)) ; \
+ sed -e 's/@APPNAME@/$(subst $(gb_Executable_EXT),,$(notdir $(1)))/' $(QT5_PLATFORMS_SRCDIR)/wasm_shell.html > $(dir $(1))qt_$(notdir $(1)) ; \
+ ln -sf $(call gb_CustomTarget_get_workdir,static/emscripten_fs_image)/soffice.data $(dir $(1))/soffice.data ; \
+ ln -sf $(call gb_CustomTarget_get_workdir,static/emscripten_fs_image)/soffice.data.js.metadata $(dir $(1))/soffice.data.js.metadata ; \
+)
+endef
+
+define gb_LinkTarget__command_staticlink
+$(call gb_Helper_abbreviate_dirs,\
+ rm -f $(1) && \
+ $(gb_AR) $(gb_LTOPLUGINFLAGS) -rsu $(1) \
+ $(foreach object,$(COBJECTS),$(call gb_CObject_get_target,$(object))) \
+ $(foreach object,$(CXXOBJECTS),$(call gb_CxxObject_get_target,$(object))) \
+ $(foreach object,$(ASMOBJECTS),$(call gb_AsmObject_get_target,$(object))) \
+ $(foreach object,$(GENCOBJECTS),$(call gb_GenCObject_get_target,$(object))) \
+ $(foreach object,$(GENCXXOBJECTS),$(call gb_GenCxxObject_get_target,$(object))) \
+ $(foreach object,$(GENNASMOBJECTS),$(call gb_GenNasmObject_get_target,$(object))) \
+ $(foreach extraobjectlist,$(EXTRAOBJECTLISTS),@$(extraobjectlist)) \
+ $(if $(findstring s,$(MAKEFLAGS)),2> /dev/null))
+endef
+
+define gb_LinkTarget__command
+$(call gb_Output_announce,$(2),$(true),LNK,4)
+ $(call gb_Trace_StartRange,$(2),LNK)
+$(if $(filter CppunitTest Executable,$(TARGETTYPE)),$(call gb_LinkTarget__command_dynamiclink,$(1),$(2)))
+$(if $(filter Library,$(TARGETTYPE)),$(if $(filter TRUE,$(DISABLE_DYNLOADING)),$(call gb_LinkTarget__command_staticlink,$(1)),$(call gb_LinkTarget__command_dynamiclink,$(1),$(2))))
+$(if $(filter StaticLibrary,$(TARGETTYPE)),$(call gb_LinkTarget__command_staticlink,$(1)))
+ $(call gb_Trace_EndRange,$(2),LNK)
+endef
+
+
+# Library class
+
+gb_Library_DEFS :=
+gb_Library_SYSPRE := lib
+gb_Library_UNOVERPRE := $(gb_Library_SYSPRE)uno_
+
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+
+gb_Library_PLAINEXT := .a
+gb_Library_PLAINEXT_FOR_BUILD := .so
+gb_Library_DLLEXT := .a
+
+else
+
+gb_Library_TARGETTYPEFLAGS := -shared -Wl,-z,noexecstack
+gb_Library_UDK_MAJORVER := 3
+gb_Library_PLAINEXT := .so
+gb_Library_PLAINEXT_FOR_BUILD := .so
+gb_Library_DLLEXT := .so
+
+endif
+
+gb_Library_RTEXT := gcc3$(gb_Library_PLAINEXT)
+
+gb_Library_OOOEXT := $(gb_Library_DLLPOSTFIX)$(gb_Library_PLAINEXT)
+gb_Library_UNOEXT := .uno$(gb_Library_PLAINEXT)
+
+gb_Library_FILENAMES := \
+ $(foreach lib,$(gb_Library_OOOLIBS),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_OOOEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_NONE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_URE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OOO),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OXT),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_PLAINEXT)) \
+ $(foreach lib,$(gb_Library_PRIVATELIBS_URE),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_OOOEXT)) \
+ $(foreach lib,$(gb_Library_EXTENSIONLIBS),$(lib):$(lib)$(gb_Library_UNOEXT)) \
+
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+
+gb_Library_FILENAMES += \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_RTEXT)) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):$(gb_Library_UNOVERPRE)$(lib)$(gb_Library_PLAINEXT)) \
+
+else
+
+gb_Library_FILENAMES += \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):$(gb_Library_SYSPRE)$(lib)$(gb_Library_RTEXT).$(gb_Library_UDK_MAJORVER)) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):$(gb_Library_UNOVERPRE)$(lib)$(gb_Library_PLAINEXT).$(gb_Library_UDK_MAJORVER)) \
+
+endif
+
+gb_Library_LAYER := \
+ $(foreach lib,$(gb_Library_OOOLIBS),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_URE),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OOO),$(lib):OOO) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_OXT),$(lib):OXT) \
+ $(foreach lib,$(gb_Library_PLAINLIBS_NONE),$(lib):NONE) \
+ $(foreach lib,$(gb_Library_PRIVATELIBS_URE),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_RTVERLIBS),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_UNOVERLIBS),$(lib):URELIB) \
+ $(foreach lib,$(gb_Library_EXTENSIONLIBS),$(lib):OXT) \
+
+define gb_Library__get_rpath
+$(if $(1),$(strip -Wl,-z,origin '-Wl,-rpath,$(1)' -Wl,-rpath-link,$(INSTDIR)/program))
+endef
+
+define gb_Library_get_rpath
+$(call gb_Library__get_rpath,$(call gb_LinkTarget__get_rpath_for_layer,$(call gb_Library_get_layer,$(1))))
+endef
+
+define gb_Library_Library_platform
+$(call gb_LinkTarget_get_target,$(2)) : RPATH := $(call gb_Library_get_rpath,$(1))
+
+endef
+
+gb_Library__set_soversion_script_platform = $(gb_Library__set_soversion_script)
+
+gb_Library_get_sdk_link_dir = $(INSTDIR)/$(SDKDIRNAME)/lib
+
+gb_Library_get_sdk_link_lib = $(gb_Library_get_versionlink_target)
+
+# Executable class
+
+gb_Executable_EXT :=
+
+gb_Executable_LAYER := \
+ $(foreach exe,$(gb_Executable_UREBIN),$(exe):UREBIN) \
+ $(foreach exe,$(gb_Executable_SDK),$(exe):SDKBIN) \
+ $(foreach exe,$(gb_Executable_OOO),$(exe):OOO) \
+ $(foreach exe,$(gb_Executable_NONE),$(exe):NONE) \
+
+
+define gb_Executable__get_rpath
+$(strip -Wl,-z,origin $(if $(1),'-Wl$(COMMA)-rpath$(COMMA)$(1)') -Wl,-rpath-link,$(INSTDIR)/program)
+endef
+
+define gb_Executable_get_rpath
+$(call gb_Executable__get_rpath,$(call gb_LinkTarget__get_rpath_for_layer,$(call gb_Executable_get_layer,$(1))))
+endef
+
+define gb_Executable_Executable_platform
+$(call gb_LinkTarget_get_target,$(2)) : RPATH := $(call gb_Executable_get_rpath,$(1))
+
+endef
+
+
+# CppunitTest class
+
+gb_CppunitTest_CPPTESTPRECOMMAND := \
+ $(call gb_Helper_extend_ld_path,$(WORKDIR)/UnpackedTarball/cppunit/src/cppunit/.libs)
+gb_CppunitTest_get_filename = libtest_$(1).so
+gb_CppunitTest_get_ilibfilename = $(gb_CppunitTest_get_filename)
+gb_CppunitTest_malloc_check := -ex 'set environment MALLOC_CHECK_=2; set environment MALLOC_PERTURB_=153'
+
+define gb_CppunitTest_CppunitTest_platform
+$(call gb_LinkTarget_get_target,$(2)) : RPATH := $(call gb_Library__get_rpath,$(call gb_LinkTarget__get_rpath_for_layer,NONE))
+
+endef
+
+define gb_CppunitTest_postprocess
+$(SRCDIR)/solenv/bin/gdb-core-bt.sh $(1) $(2) $(3)
+endef
+
+# JunitTest class
+
+ifneq ($(OOO_TEST_SOFFICE),)
+gb_JunitTest_SOFFICEARG:=$(OOO_TEST_SOFFICE)
+else
+ifneq ($(gb_JunitTest_DEBUGRUN),)
+gb_JunitTest_SOFFICEARG:=connect:pipe,name=$(USER)
+else
+gb_JunitTest_SOFFICEARG:=path:$(INSTROOT)/$(LIBO_BIN_FOLDER)/soffice
+endif
+endif
+
+define gb_JunitTest_JunitTest_platform
+$(call gb_JunitTest_get_target,$(1)) : DEFS := \
+ -Dorg.openoffice.test.arg.env=$(gb_Helper_LIBRARY_PATH_VAR)"$$$${$(gb_Helper_LIBRARY_PATH_VAR)+=$$$$$(gb_Helper_LIBRARY_PATH_VAR)}" \
+ -Dorg.openoffice.test.arg.user=$(call gb_Helper_make_url,$(call gb_JunitTest_get_userdir,$(1))) \
+ -Dorg.openoffice.test.arg.workdir=$(call gb_JunitTest_get_userdir,$(1)) \
+ -Dorg.openoffice.test.arg.postprocesscommand=$(SRCDIR)/solenv/bin/gdb-core-bt.sh \
+ -Dorg.openoffice.test.arg.soffice="$(gb_JunitTest_SOFFICEARG)" \
+
+endef
+
+# PythonTest class
+
+gb_PythonTest_PRECOMMAND := $(gb_CppunitTest_CPPTESTPRECOMMAND)
+
+# Module class
+
+define gb_Module_DEBUGRUNCOMMAND
+OFFICESCRIPT=`mktemp` && \
+printf 'if [ -e $(INSTROOT)/program/ooenv ]; then . $(INSTROOT)/program/ooenv; fi\n' > $${OFFICESCRIPT} && \
+printf "PYTHONWARNINGS=default gdb $(INSTROOT)/$(LIBO_BIN_FOLDER)/soffice.bin" >> $${OFFICESCRIPT} && \
+printf " -ex \"set args --norestore --nologo '--accept=pipe,name=$(USER);urp;' %s\"" \
+ "$(subst ","\\\"",$(value gb_DBGARGS))" >> $${OFFICESCRIPT} && \
+$(SHELL) $${OFFICESCRIPT} && \
+rm $${OFFICESCRIPT}
+endef
+
+# InstallModuleTarget class
+
+define gb_InstallModuleTarget_InstallModuleTarget_platform
+$(call gb_InstallModuleTarget_add_defs,$(1),\
+ $(gb_CPUDEFS) \
+ $(gb_OSDEFS) \
+ -DCOMID=gcc3 \
+ -D_gcc3 \
+)
+
+endef
+
+# InstallScript class
+
+gb_InstallScript_EXT := .ins
+
+# CliAssemblyTarget class
+
+gb_CliAssemblyTarget_POLICYEXT :=
+gb_CliAssemblyTarget_get_dll :=
+
+# Extension class
+
+gb_Extension_LICENSEFILE_DEFAULT := $(INSTROOT)/LICENSE
+
+# UnpackedTarget class
+
+gb_UnpackedTarget_TARFILE_LOCATION := $(TARFILE_LOCATION)
+
+# UnoApiHeadersTarget class
+
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+gb_UnoApiHeadersTarget_select_variant = $(if $(filter udkapi,$(1)),comprehensive,$(2))
+else
+gb_UnoApiHeadersTarget_select_variant = $(2)
+endif
+
+# UIMenubarTarget class
+
+define gb_UIMenubarTarget__command
+$(call gb_Output_announce,$(2),$(true),UIM,1)
+$(call gb_Trace_StartRange,$(2),UIM)
+cp $(3) $(1)
+$(call gb_Trace_EndRange,$(2),UIM)
+
+endef
+
+gb_UIMenubarTarget_UIMenubarTarget_platform :=
+
+# Python
+gb_Python_PRECOMMAND := 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
+
+include $(GBUILDDIR)/platform/com_GCC_class.mk
+
+# vim: set noet sw=4:
diff --git a/solenv/gbuild/platform/win_compatibility.manifest b/solenv/gbuild/platform/win_compatibility.manifest
new file mode 100644
index 000000000..709f6f3c7
--- /dev/null
+++ b/solenv/gbuild/platform/win_compatibility.manifest
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <!-- Windows 10 -->
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+ <!-- Windows 8.1 -->
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+ <!-- Windows 8 -->
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+ <!-- Windows 7 -->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ </application>
+ </compatibility>
+</assembly>
diff --git a/solenv/gbuild/platform/windows.mk b/solenv/gbuild/platform/windows.mk
new file mode 100644
index 000000000..57f906ad1
--- /dev/null
+++ b/solenv/gbuild/platform/windows.mk
@@ -0,0 +1,60 @@
+# -*- 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/.
+#
+
+# to block heavy exception handling that try to acquire the solarmutex
+export LO_LEAN_EXCEPTION=1
+
+gb_LICENSE := license.txt
+gb_README = readme_$(1).txt
+
+gb_Helper_get_rcfile = $(1).ini
+
+gb_Helper_LIBRARY_PATH_VAR := PATH
+
+gb_MKTEMP := mktemp --tmpdir=$(gb_TMPDIR) gbuild.XXXXXX
+
+# define _WIN32_WINNT and WINVER will be derived from it in sdkddkver.h
+# current baseline is Windows 7 (NT 6.1)
+# for _WIN32_IE, if _WIN32_WINNT >= 0x0600 the derived value from
+# sdkddkver.h is sufficient
+gb_WIN_VERSION_DEFS := \
+ -D_WIN32_WINNT=0x0601 \
+ -DWIN32 \
+ -DWNT \
+
+gb_OSDEFS := \
+ $(gb_WIN_VERSION_DEFS) \
+ -DNOMINMAX \
+ $(LFS_CFLAGS) \
+
+gb_Executable_LAYER := \
+ $(foreach exe,$(gb_Executable_UREBIN),$(exe):UREBIN) \
+ $(foreach exe,$(gb_Executable_SDK),$(exe):SDKBIN) \
+ $(foreach exe,$(gb_Executable_OOO),$(exe):OOO) \
+ $(foreach exe,$(gb_Executable_NONE),$(exe):NONE) \
+
+# empty to avoid --warn-undefined-functions
+gb_Library__set_soversion_script_platform =
+
+# default platform and configuration values used by msbuild
+gb_MSBUILD_CONFIG := $(if $(MSVC_USE_DEBUG_RUNTIME),Debug,Release)
+gb_MSBUILD_PLATFORM := $(strip \
+ $(if $(filter INTEL,$(CPUNAME)),Win32) \
+ $(if $(filter X86_64,$(CPUNAME)),x64) \
+ $(if $(filter AARCH64,$(CPUNAME)),ARM64) \
+ )
+gb_MSBUILD_CONFIG_AND_PLATFORM := \
+ /p:Configuration=$(gb_MSBUILD_CONFIG) \
+ /p:Platform=$(gb_MSBUILD_PLATFORM)
+
+gb_CONFIGURE_PLATFORMS := \
+ $(if $(and $(filter i686-pc-cygwin,$(HOST_PLATFORM)),$(filter x86_64-pc-cygwin,$(BUILD_PLATFORM))), \
+ --build=$(HOST_PLATFORM),--build=$(BUILD_PLATFORM)) --host=$(HOST_PLATFORM)
+
+# vim:set noexpandtab:
diff --git a/solenv/gbuild/static.mk b/solenv/gbuild/static.mk
new file mode 100644
index 000000000..faa9a73db
--- /dev/null
+++ b/solenv/gbuild/static.mk
@@ -0,0 +1,247 @@
+# -*- 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/.
+#
+
+# "spezialgelagerter Sonderfall" :-(
+#
+# *******************************************
+# Use gb_DEBUG_STATIC=t to dump various debug info for the static build preparation!
+# Use gb_DEBUG_STATIC=a to abort / error after the dump
+# *******************************************
+#
+# "Generic" comment from the author:
+# My thought was: the dependency info is already there. Can't be too hard to use it for
+# correct static linkage... well it took more than two weeks to hopefully identify all
+# problems / edge cases. Now I can appreciate the usage bin/lo-all-static-libs even more.
+#
+# This code moved a few times to the various gbuild / make phases: Makefile / module
+# setup (in use_(libraries|externals)), post parsing (like now), make "dependency" tree
+# processing. It currently looks like this is the only working option.
+#
+# For static linking, we must collect all depending libraries, externals and statics to
+# be available at link time. And Libraries and externals can use each other. This could
+# be done "in-line", while make processes the dependency tree and would have the correct
+# order, so no separate tree-walking would be needed.
+# It can't be done while reading / processing the modules, as this happens in no order, so
+# depending modules will be missing.
+#
+# Then there is the (gbuild new) concept of plugin libraries. These depend on some loader
+# libraries, like vcl and vclplug_* or gie. For a shared library build, these plugins are
+# just dlopen'ed, but for a static build, any linked binary must also link the plugins, which
+# turns plugins + loaders into a dependency cycle. The implemented solution is to just add
+# plugins to executables, if these depend on a loader library. This results in the additional
+# rule: nothing non-plugin is allowed to depend on a plugins (see gb_Library_set_plugin_for).
+#
+# And we can't add these dependencies while make is already processing the Executables,
+# because these contain additional eval'ed targets, which we can't create in make recipes.
+# This is especially true for externals (see gb_LinkTarget__use_* in RepositoryExternal.mk).
+# We also can't add all plugins to all executables, as we have multiple helper
+# binaries, which are needed early and don't depend on plugins.
+#
+# So the only option left seems to be to walk the dependency tree ourself and expand all
+# the libraries and externals and then add the plugins to the executables. Statics are
+# handled after that, since these won't need extra dependencies not already known.
+# It's a bit fragile in theory, as you can add "gbuild-undetectable" dependencies to any
+# target in the modules, which would need some manual adjustment, but currently that
+# doesn't seem to happen in any breaking way and it works to link multiple Executable
+# with large and small expanded dependency lists.
+#
+# Then there is the special static "components" library, which simply depends on all build
+# components. In theory these could be limited per-module (Writer, Calc, etc.), but currently
+# this is not implemented and instead solenv/bin/native-code.py is used, so actually
+# everything is build and "cleaned up" at link time, which is especially expensive for WASM.
+# That library is currently just used for Emscripten, but could be used generally for
+# static builds.
+#
+# There is already a lot of $(info ...) protected by the already mentioned $(gb_DEBUG_STATIC).
+
+ifeq ($(gb_FULLDEPS),$(true))
+ifeq (,$(gb_PARTIAL_BUILD))
+
+$(foreach lib,$(gb_Library_KNOWNLIBS),$(if $(call gb_Library__get_component,$(lib)), \
+ $(eval $(call gb_Library_use_libraries,components,$(lib)))))
+
+define gb_LinkTarget__add_x_template
+
+# call gb_LinkTarget__add_$(1),linktarget,objects
+define gb_LinkTarget__add_$(1)
+$$(foreach item,$$(2),$$(if $$(filter $$(item),GBUILD_TOUCHED $$(call gb_LinkTarget__get_all_$(1),$$(1))),,
+ $$(if $(gb_DEBUG_STATIC),$$(info $$(call gb_LinkTarget__get_all_$(1)_var,$$(call gb_LinkTarget__get_workdir_linktargetname,$$(1))) += $$(item)))
+ $$(eval $$(call gb_LinkTarget__get_all_$(1)_var,$$(call gb_LinkTarget__get_workdir_linktargetname,$$(1))) += $$(item))
+))
+endef
+
+endef # gb_LinkTarget__add_x_template
+
+ifneq (,$(gb_DEBUG_STATIC))
+$(info $(call gb_LinkTarget__add_x_template,libraries))
+$(info $(call gb_LinkTarget__add_x_template,externals))
+$(info $(call gb_LinkTarget__add_x_template,statics))
+endif
+$(eval $(call gb_LinkTarget__add_x_template,libraries))
+$(eval $(call gb_LinkTarget__add_x_template,externals))
+$(eval $(call gb_LinkTarget__add_x_template,statics))
+
+# call gb_LinkTarget__add_linktargets,linktarget,class,func,objects
+define gb_LinkTarget__add_linktargets
+$(call gb_LinkTarget__add_$(3),$(1),$(4))
+$(foreach item,$(foreach mapped,$(4),$(call gb_$(2)__get_workdir_linktargetname,$(mapped))),
+ $(call gb_LinkTarget__add_libraries,$(1),$(call gb_LinkTarget__get_all_libraries,$(item)))
+ $(call gb_LinkTarget__add_externals,$(1),$(call gb_LinkTarget__get_all_externals,$(item)))
+ $(call gb_LinkTarget__add_statics,$(1),$(call gb_LinkTarget__get_all_statics,$(item)))
+)
+endef
+
+# contains the list of all touched workdir_linktargetname(s)
+gb_LinkTarget__ALL_TOUCHED =
+
+define gb_LinkTarget__add_touch
+$(eval $(call gb_LinkTarget__get_all_libraries_var,$(call gb_LinkTarget__get_workdir_linktargetname,$(1))) += GBUILD_TOUCHED)
+$(eval $(call gb_LinkTarget__get_all_externals_var,$(call gb_LinkTarget__get_workdir_linktargetname,$(1))) += GBUILD_TOUCHED)
+$(eval $(call gb_LinkTarget__get_all_statics_var,$(call gb_LinkTarget__get_workdir_linktargetname,$(1))) += GBUILD_TOUCHED)
+gb_LinkTarget__ALL_TOUCHED += $(1)
+
+endef
+
+define gb_LinkTarget__remove_touch
+$(call gb_LinkTarget__get_all_libraries_var,$(1)) := $(filter-out GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_libraries,$(1)))
+$(call gb_LinkTarget__get_all_externals_var,$(1)) := $(filter-out GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_externals,$(1)))
+$(call gb_LinkTarget__get_all_statics_var,$(1)) := $(filter-out GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_statics,$(1)))
+
+endef
+
+# call gb_LinkTarget__fill_all_deps.linktargetname
+define gb_LinkTarget__fill_all_deps
+$(if $(filter GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_lo_libraries,$(1))),,
+
+ # LO has quite a few dependency loops, so touch first to break them
+ $(call gb_LinkTarget__add_touch,$(1))
+
+ # Add lo libraries
+ $(foreach item,$(filter-out GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_lo_libraries,$(1))),
+ $(call gb_LinkTarget__fill_all_deps,$(call gb_Library_get_linktarget,$(item)))
+ $(call gb_LinkTarget__add_libraries,$(1),$(call gb_Library__get_all_libraries,$(item)))
+ $(call gb_LinkTarget__add_externals,$(1),$(call gb_Library__get_all_externals,$(item)))
+ $(call gb_LinkTarget__add_statics,$(1),$(call gb_Library__get_all_statics,$(item)))
+ )
+
+ # Add (win32) system libraries
+ $(call gb_LinkTarget__add_libraries,$(1),$(call gb_LinkTarget__get_all_sys_libraries,$(1)))
+
+ # Add externals
+ $(foreach item,$(filter-out GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_externals,$(1))),
+ $(call gb_LinkTarget__fill_all_deps,$(call gb_ExternalProject__get_workdir_linktargetname,$(item)))
+ $(call gb_LinkTarget__add_libraries,$(1),$(call gb_ExternalProject__get_all_libraries,$(item)))
+ $(call gb_LinkTarget__add_externals,$(1),$(call gb_ExternalProject__get_all_externals,$(item)))
+ $(call gb_LinkTarget__add_statics,$(1),$(call gb_ExternalProject__get_all_statics,$(item)))
+ )
+
+ # Add statics
+ $(foreach item,$(filter-out GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_statics,$(1))),
+ $(call gb_LinkTarget__fill_all_deps,$(call gb_StaticLibrary_get_linktarget,$(item)))
+ $(call gb_LinkTarget__add_libraries,$(1),$(call gb_StaticLibrary__get_all_libraries,$(item)))
+ $(call gb_LinkTarget__add_externals,$(1),$(call gb_StaticLibrary__get_all_externals,$(item)))
+ $(call gb_LinkTarget__add_statics,$(1),$(call gb_StaticLibrary__get_all_statics,$(item)))
+ )
+
+ $(if $(gb_DEBUG_STATIC),
+ $(info gb_LinkTarget__fill_all_deps libraries for $(call gb_LinkTarget__get_workdir_linktargetname,$(1)) out: $(call gb_LinkTarget__get_all_libraries,$(1)))
+ $(info gb_LinkTarget__fill_all_deps externals for $(call gb_LinkTarget__get_workdir_linktargetname,$(1)) out: $(call gb_LinkTarget__get_all_externals,$(1)))
+ $(info gb_LinkTarget__fill_all_deps statics for $(call gb_LinkTarget__get_workdir_linktargetname,$(1)) out: $(call gb_LinkTarget__get_all_statics,$(1)))
+ )
+)
+
+endef
+
+
+# call gb_LinkTarget__expand_executable,linktarget
+define gb_LinkTarget__expand_executable
+$(call gb_LinkTarget__fill_all_deps,$(1))
+
+# 1. Check if cppuhelper loader for components is requested and add the needed plugin dependences
+# This is a *HACK*, so we don't have to recursively check loader libraries
+# 2. Find any other loader libraries and add the needed plugin dependences
+$(if $(filter cppuhelper,$(filter $(gb_Library_KNOWNLOADERS),$(call gb_LinkTarget__get_all_libraries,$(1)))),
+ $(call gb_LinkTarget__add_linktargets,$(1),Library,libraries,$(call gb_Library__get_plugins,cppuhelper)))
+$(foreach loader,$(filter $(filter-out cppuhelper,$(gb_Library_KNOWNLOADERS)),$(call gb_LinkTarget__get_all_libraries,$(1))),
+ $(call gb_LinkTarget__add_linktargets,$(1),Library,libraries,$(call gb_Library__get_plugins,$(loader))))
+
+$(if $(filter-out GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_libraries,$(1))),
+ $(eval $(call gb_LinkTarget_use_libraries,$(1),$(filter-out GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_libraries,$(1))))))
+
+$(if $(filter-out GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_externals,$(1))),
+ $(eval $(call gb_LinkTarget_use_externals,$(1),$(filter-out GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_externals,$(1))))))
+
+$(if $(filter-out GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_statics,$(1))),
+ $(eval $(call gb_LinkTarget_use_static_libraries,$(1),$(filter-out GBUILD_TOUCHED,$(call gb_LinkTarget__get_all_statics,$(1))))))
+
+# Some fixes for the _use_external_project(s) mess
+$(if $(filter icui18n icuuc,$(call gb_LinkTarget__get_all_externals,$(1))),
+ $(call gb_LinkTarget_use_externals,$(1),icudata))
+$(if $(filter orcus-parser,$(call gb_LinkTarget__get_all_externals,$(1))),
+ $(call gb_LinkTarget_use_static_libraries,$(1),boost_filesystem))
+
+$(if $(gb_DEBUG_STATIC),
+ $(info gb_LinkTarget__expand_executable libraries for $(call gb_LinkTarget__get_workdir_linktargetname,$(1)): $(call gb_LinkTarget__get_all_libraries,$(1)))
+ $(info gb_LinkTarget__expand_executable externals for $(call gb_LinkTarget__get_workdir_linktargetname,$(1)): $(call gb_LinkTarget__get_all_externals,$(1)))
+ $(info gb_LinkTarget__expand_executable statics for $(call gb_LinkTarget__get_workdir_linktargetname,$(1)): $(call gb_LinkTarget__get_all_statics,$(1)))
+)
+
+endef
+
+$(foreach lib,$(gb_Library_KNOWNLIBS), \
+ $(eval $(call gb_LinkTarget__fill_all_deps,$(call gb_Library_get_linktarget,$(lib)))))
+$(foreach exec,$(gb_Executable_KNOWN), \
+ $(eval $(call gb_LinkTarget__expand_executable,$(call gb_Executable_get_linktarget,$(exec)))))
+$(foreach workdir_linktargetname,$(gb_LinkTarget__ALL_TOUCHED), \
+ $(eval $(call gb_LinkTarget__remove_touch,$(workdir_linktargetname))))
+
+else # gb_PARTIAL_BUILD
+
+# call gb_LinkTarget__expand_executable_template,class
+define gb_LinkTarget__expand_executable_template
+
+gb_$(1)__get_dep_libraries_target = $$(call gb_LinkTarget_get_dep_libraries_target,$$(call gb_$(1)__get_workdir_linktargetname,$$(1)))
+gb_$(1)__get_dep_externals_target = $$(call gb_LinkTarget_get_dep_externals_target,$$(call gb_$(1)__get_workdir_linktargetname,$$(1)))
+gb_$(1)__get_dep_statics_target = $$(call gb_LinkTarget_get_dep_statics_target,$$(call gb_$(1)__get_workdir_linktargetname,$$(1)))
+
+# call gb_$(1)__has_any_dependencies,item
+define gb_$(1)__has_any_dependencies
+$$(if $$(strip $$(filter-out GBUILD_TOUCHED,
+ $$(call gb_$(1)__get_all_libraries,$$(1))
+ $$(call gb_$(1)__get_all_externals,$$(1))
+ $$(call gb_$(1)__get_all_statics,$$(1)))),$$(1))
+
+endef
+
+# call gb_$(1)__expand_deps,item
+define gb_$(1)__expand_deps
+$$(if $$(call gb_$(1)__has_any_dependencies,$$(1)),
+ $$(if $$(shell cat $$(call gb_$(1)__get_dep_libraries_target,$$(1)) 2>/dev/null),
+ $$(eval $$(call gb_$(1)_use_libraries,$$(1),$$(shell cat $$(call gb_$(1)__get_dep_libraries_target,$$(1))))))
+ $$(if $$(shell cat $$(call gb_$(1)__get_dep_externals_target,$$(1)) 2>/dev/null),
+ $$(eval $$(call gb_$(1)_use_externals,$$(1),$$(shell cat $$(call gb_$(1)__get_dep_externals_target,$$(1))))))
+ $$(if $$(shell cat $$(call gb_$(1)__get_dep_statics_target,$$(1)) 2>/dev/null), \
+ $$(eval $$(call gb_$(1)_use_static_libraries,$$(1),$$(shell cat $$(call gb_$(1)__get_dep_statics_target,$$(1))))))
+)
+
+endef
+
+endef # gb_LinkTarget__expand_executable_template
+
+ifneq (,$(gb_DEBUG_STATIC))
+$(info $(call gb_LinkTarget__expand_executable_template,Executable))
+endif
+$(eval $(call gb_LinkTarget__expand_executable_template,Executable))
+
+$(foreach exec,$(gb_Executable_KNOWN),$(eval $(call gb_Executable__expand_deps,$(exec))))
+
+endif # gb_PARTIAL_BUILD
+endif # gb_FULLDEPS
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/uitest-failed-default.sh b/solenv/gbuild/uitest-failed-default.sh
new file mode 100755
index 000000000..44d229379
--- /dev/null
+++ b/solenv/gbuild/uitest-failed-default.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+# -*- Mode: sh; 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/.
+#
+cat << EOF
+
+Error: a unit test failed:
+
+To rerun just this failed test without all others, use:
+ make UITest_$2
+
+Or to run just a specific test case method, use:
+ make UITest_$2 UITEST_TEST_NAME="Module.ClassName.methodName"
+where
+ Module - the name of the python file (without the .py extension)
+ Class - is the name in the "class Class" declaration
+
+Or to do interactive debugging, run two shells with:
+ LANG=C SAL_USE_VCLPLUGIN=gen make debugrun
+ make gb_UITest_DEBUGRUN=T UITest_$2
+
+The SAL_USE_VCLPLUGIN part is unnecessary if you are running on a kde desktop.
+(The default gtk3 backend has issues with some uitests).
+
+Failing that, put a
+ time.sleep(60)
+in the beginning of the method in the .py file,
+and attach gdb to the running soffice process.
+
+EOF
+
+# In theory, we could add this text, but it really doesn't work very well.
+#
+# Or to do interactive debugging, run two shells with:
+# make debugrun
+# make gb_UITest_DEBUGRUN=T UITest_$2
+
+exit 1
+
+# vim: set et sw=4:
diff --git a/solenv/gbuildtojson/gbuildtojson.cxx b/solenv/gbuildtojson/gbuildtojson.cxx
new file mode 100644
index 000000000..4d60ac787
--- /dev/null
+++ b/solenv/gbuildtojson/gbuildtojson.cxx
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+* 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/.
+*/
+
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+#include <list>
+#include <map>
+#include <sstream>
+#include <string>
+#include <stdio.h>
+
+int main(int argc, char** argv)
+{
+ const std::string optsintro("--");
+ std::map<std::string, std::string> vartofile;
+ for(int i=1; i < argc; ++i)
+ {
+ const std::string arg(argv[i]);
+ if(arg.substr(0,2) != optsintro)
+ {
+ std::cerr << "Only option args starting with -- allowed." << std::endl;
+ return 1;
+ }
+ const size_t eqpos = arg.find("=", 2);
+ if(eqpos == std::string::npos)
+ {
+ std::cerr << "Only option args assigning with = allowed." << std::endl;
+ return 2;
+ }
+ const std::string argname(arg.substr(2, eqpos-2));
+ vartofile[argname] = arg.substr(eqpos+1, std::string::npos);
+ }
+ std::cout << "{";
+ bool first(true);
+ for(const auto& varandfile : vartofile)
+ {
+ if(first)
+ first =false;
+ else
+ std::cout << "," << std::endl;
+ std::string varupper(varandfile.first);
+ for(auto& c : varupper)
+ if(c != '_')
+ c = c-32;
+ std::ifstream filestream(varandfile.second.c_str());
+ std::stringstream contents;
+ contents << filestream.rdbuf();
+ filestream.close();
+ (void)remove(varandfile.second.c_str());
+ std::string escapedcontents;
+ for(const auto& c : contents.str())
+ {
+ if(c=='\\')
+ escapedcontents += "\\\\";
+ else if(c=='"')
+ escapedcontents += "\\\"";
+ else if(c=='\n')
+ continue;
+ else
+ escapedcontents += c;
+ }
+ std::cout << "\"" << varupper << "\": \"" << escapedcontents << "\"";
+ }
+ std::cout << "}" << std::endl;
+ return 0;
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */