1 # -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 # "spezialgelagerter Sonderfall" :-(
12 # *******************************************
13 # Use gb_DEBUG_STATIC=t to dump various debug info for the static build preparation!
14 # Use gb_DEBUG_STATIC=a to abort / error after the dump
15 # *******************************************
17 # "Generic" comment from the author:
18 # My thought was: the dependency info is already there. Can't be too hard to use it for
19 # correct static linkage... well it took more than two weeks to hopefully identify all
20 # problems / edge cases. Now I can appreciate the usage bin/lo-all-static-libs even more.
22 # This code moved a few times to the various gbuild / make phases: Makefile / module
23 # setup (in use_(libraries|externals)), post parsing (like now), make "dependency" tree
24 # processing. It currently looks like this is the only working option.
26 # For static linking, we must collect all depending libraries, externals and statics to
27 # be available at link time. And Libraries and externals can use each other. This could
28 # be done "in-line", while make processes the dependency tree and would have the correct
29 # order, so no separate tree-walking would be needed.
30 # It can't be done while reading / processing the modules, as this happens in no order, so
31 # depending modules will be missing.
33 # Then there is the (gbuild new) concept of plugin libraries. These depend on some loader
34 # libraries, like vcl and vclplug_* or gie. For a shared library build, these plugins are
35 # just dlopen'ed, but for a static build, any linked binary must also link the plugins, which
36 # turns plugins + loaders into a dependency cycle. The implemented solution is to just add
37 # plugins to executables, if these depend on a loader library. This results in the additional
38 # rule: nothing non-plugin is allowed to depend on a plugins (see gb_Library_set_plugin_for).
40 # And we can't add these dependencies while make is already processing the Executables,
41 # because these contain additional eval'ed targets, which we can't create in make recipes.
42 # This is especially true for externals (see gb_LinkTarget__use_* in RepositoryExternal.mk).
43 # We also can't add all plugins to all executables, as we have multiple helper
44 # binaries, which are needed early and don't depend on plugins.
46 # So the only option left seems to be to walk the dependency tree ourself and expand all
47 # the libraries and externals and then add the plugins to the executables. Statics are
48 # handled after that, since these won't need extra dependencies not already known.
49 # It's a bit fragile in theory, as you can add "gbuild-undetectable" dependencies to any
50 # target in the modules, which would need some manual adjustment, but currently that
51 # doesn't seem to happen in any breaking way and it works to link multiple Executable
52 # with large and small expanded dependency lists.
54 # Then there is the special static "components" library, which simply depends on all built
55 # components. In theory these could be limited per-module (Writer, Calc, etc.), but currently
56 # this is not implemented and instead solenv/bin/native-code.py is used, so actually
57 # everything is build and "cleaned up" at link time, which is especially expensive for WASM.
58 # That library is currently just used for Emscripten, but could be used generally for
61 # There is already a lot of $(info ...) protected by the already mentioned $(gb_DEBUG_STATIC).
63 ifeq ($(gb_FULLDEPS
),$(true
))
64 ifeq (,$(gb_PARTIAL_BUILD
))
66 $(foreach lib
,$(gb_Library_KNOWNLIBS
),$(if
$(call gb_Library__get_component
,$(lib
)), \
67 $(eval
$(call gb_Library_use_libraries
,components
,$(lib
)))))
69 define gb_LinkTarget__add_x_template
71 # call gb_LinkTarget__add_$(1),linktarget,objects
72 define gb_LinkTarget__add_
$(1)
73 $$(foreach item
,$$(2),$$(if
$$(filter $$(item
),GBUILD_TOUCHED
$$(call gb_LinkTarget__get_all_
$(1),$$(1))),,
74 $$(if
$(gb_DEBUG_STATIC
),$$(info $$(call gb_LinkTarget__get_all_
$(1)_var
,$$(call gb_LinkTarget__get_workdir_linktargetname
,$$(1))) += $$(item
)))
75 $$(eval
$$(call gb_LinkTarget__get_all_
$(1)_var
,$$(call gb_LinkTarget__get_workdir_linktargetname
,$$(1))) += $$(item
))
79 endef # gb_LinkTarget__add_x_template
81 ifneq (,$(gb_DEBUG_STATIC
))
82 $(info $(call gb_LinkTarget__add_x_template
,libraries
))
83 $(info $(call gb_LinkTarget__add_x_template
,externals
))
84 $(info $(call gb_LinkTarget__add_x_template
,statics
))
86 $(eval
$(call gb_LinkTarget__add_x_template
,libraries
))
87 $(eval
$(call gb_LinkTarget__add_x_template
,externals
))
88 $(eval
$(call gb_LinkTarget__add_x_template
,statics
))
90 # call gb_LinkTarget__add_linktargets,linktarget,class,func,objects
91 define gb_LinkTarget__add_linktargets
92 $(call gb_LinkTarget__add_
$(3),$(1),$(4))
93 $(foreach item
,$(foreach mapped
,$(4),$(call gb_
$(2)__get_workdir_linktargetname
,$(mapped
))),
94 $(call gb_LinkTarget__add_libraries
,$(1),$(call gb_LinkTarget__get_all_libraries
,$(item
)))
95 $(call gb_LinkTarget__add_externals
,$(1),$(call gb_LinkTarget__get_all_externals
,$(item
)))
96 $(call gb_LinkTarget__add_statics
,$(1),$(call gb_LinkTarget__get_all_statics
,$(item
)))
100 # contains the list of all touched workdir_linktargetname(s)
101 gb_LinkTarget__ALL_TOUCHED
=
103 define gb_LinkTarget__add_touch
104 $(eval
$(call gb_LinkTarget__get_all_libraries_var
,$(call gb_LinkTarget__get_workdir_linktargetname
,$(1))) += GBUILD_TOUCHED
)
105 $(eval
$(call gb_LinkTarget__get_all_externals_var
,$(call gb_LinkTarget__get_workdir_linktargetname
,$(1))) += GBUILD_TOUCHED
)
106 $(eval
$(call gb_LinkTarget__get_all_statics_var
,$(call gb_LinkTarget__get_workdir_linktargetname
,$(1))) += GBUILD_TOUCHED
)
107 gb_LinkTarget__ALL_TOUCHED
+= $(1)
111 define gb_LinkTarget__remove_touch
112 $(call gb_LinkTarget__get_all_libraries_var
,$(1)) := $(filter-out GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_libraries
,$(1)))
113 $(call gb_LinkTarget__get_all_externals_var
,$(1)) := $(filter-out GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_externals
,$(1)))
114 $(call gb_LinkTarget__get_all_statics_var
,$(1)) := $(filter-out GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_statics
,$(1)))
118 # call gb_LinkTarget__fill_all_deps.linktargetname
119 define gb_LinkTarget__fill_all_deps
120 $(if
$(filter GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_lo_libraries
,$(1))),,
122 # LO has quite a few dependency loops, so touch first to break them
123 $(call gb_LinkTarget__add_touch
,$(1))
126 $(foreach item
,$(filter-out GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_lo_libraries
,$(1))),
127 $(call gb_LinkTarget__fill_all_deps
,$(call gb_Library_get_linktarget
,$(item
)))
128 $(call gb_LinkTarget__add_libraries
,$(1),$(call gb_Library__get_all_libraries
,$(item
)))
129 $(call gb_LinkTarget__add_externals
,$(1),$(call gb_Library__get_all_externals
,$(item
)))
130 $(call gb_LinkTarget__add_statics
,$(1),$(call gb_Library__get_all_statics
,$(item
)))
133 # Add (win32) system libraries
134 $(call gb_LinkTarget__add_libraries
,$(1),$(call gb_LinkTarget__get_all_sys_libraries
,$(1)))
137 $(foreach item
,$(filter-out GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_externals
,$(1))),
138 $(call gb_LinkTarget__fill_all_deps
,$(call gb_ExternalProject__get_workdir_linktargetname
,$(item
)))
139 $(call gb_LinkTarget__add_libraries
,$(1),$(call gb_ExternalProject__get_all_libraries
,$(item
)))
140 $(call gb_LinkTarget__add_externals
,$(1),$(call gb_ExternalProject__get_all_externals
,$(item
)))
141 $(call gb_LinkTarget__add_statics
,$(1),$(call gb_ExternalProject__get_all_statics
,$(item
)))
145 $(foreach item
,$(filter-out GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_statics
,$(1))),
146 $(call gb_LinkTarget__fill_all_deps
,$(call gb_StaticLibrary_get_linktarget
,$(item
)))
147 $(call gb_LinkTarget__add_libraries
,$(1),$(call gb_StaticLibrary__get_all_libraries
,$(item
)))
148 $(call gb_LinkTarget__add_externals
,$(1),$(call gb_StaticLibrary__get_all_externals
,$(item
)))
149 $(call gb_LinkTarget__add_statics
,$(1),$(call gb_StaticLibrary__get_all_statics
,$(item
)))
152 $(if
$(gb_DEBUG_STATIC
),
153 $(info gb_LinkTarget__fill_all_deps libraries for
$(call gb_LinkTarget__get_workdir_linktargetname
,$(1)) out
: $(call gb_LinkTarget__get_all_libraries
,$(1)))
154 $(info gb_LinkTarget__fill_all_deps externals for
$(call gb_LinkTarget__get_workdir_linktargetname
,$(1)) out
: $(call gb_LinkTarget__get_all_externals
,$(1)))
155 $(info gb_LinkTarget__fill_all_deps statics for
$(call gb_LinkTarget__get_workdir_linktargetname
,$(1)) out
: $(call gb_LinkTarget__get_all_statics
,$(1)))
162 # call gb_LinkTarget__expand_executable,linktarget
163 define gb_LinkTarget__expand_executable
164 $(call gb_LinkTarget__fill_all_deps
,$(1))
166 # 1. Check if cppuhelper loader for components is requested and add the needed plugin dependences
167 # This is a *HACK*, so we don't have to recursively check loader libraries
168 # 2. Find any other loader libraries and add the needed plugin dependences
169 $(if
$(filter cppuhelper
,$(filter $(gb_Library_KNOWNLOADERS
),$(call gb_LinkTarget__get_all_libraries
,$(1)))),
170 $(call gb_LinkTarget__add_linktargets
,$(1),Library
,libraries
,$(call gb_Library__get_plugins
,cppuhelper
)))
171 $(foreach loader
,$(filter $(filter-out cppuhelper
,$(gb_Library_KNOWNLOADERS
)),$(call gb_LinkTarget__get_all_libraries
,$(1))),
172 $(call gb_LinkTarget__add_linktargets
,$(1),Library
,libraries
,$(call gb_Library__get_plugins
,$(loader
))))
174 $(if
$(filter-out GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_libraries
,$(1))),
175 $(eval
$(call gb_LinkTarget_use_libraries
,$(1),$(filter-out GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_libraries
,$(1))))))
177 $(if
$(filter-out GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_externals
,$(1))),
178 $(eval
$(call gb_LinkTarget_use_externals
,$(1),$(filter-out GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_externals
,$(1))))))
180 $(if
$(filter-out GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_statics
,$(1))),
181 $(eval
$(call gb_LinkTarget_use_static_libraries
,$(1),$(filter-out GBUILD_TOUCHED
,$(call gb_LinkTarget__get_all_statics
,$(1))))))
183 # Some fixes for the _use_external_project(s) mess
184 $(if
$(filter icui18n icuuc
,$(call gb_LinkTarget__get_all_externals
,$(1))),
185 $(call gb_LinkTarget_use_externals
,$(1),icudata
))
186 $(if
$(filter orcus-parser
,$(call gb_LinkTarget__get_all_externals
,$(1))),
187 $(call gb_LinkTarget_use_static_libraries
,$(1),boost_filesystem boost_iostreams
))
189 $(if
$(gb_DEBUG_STATIC
),
190 $(info gb_LinkTarget__expand_executable libraries for
$(call gb_LinkTarget__get_workdir_linktargetname
,$(1)): $(call gb_LinkTarget__get_all_libraries
,$(1)))
191 $(info gb_LinkTarget__expand_executable externals for
$(call gb_LinkTarget__get_workdir_linktargetname
,$(1)): $(call gb_LinkTarget__get_all_externals
,$(1)))
192 $(info gb_LinkTarget__expand_executable statics for
$(call gb_LinkTarget__get_workdir_linktargetname
,$(1)): $(call gb_LinkTarget__get_all_statics
,$(1)))
197 $(foreach lib
,$(gb_Library_KNOWNLIBS
), \
198 $(eval
$(call gb_LinkTarget__fill_all_deps
,$(call gb_Library_get_linktarget
,$(lib
)))))
199 $(foreach exec
,$(gb_Executable_KNOWN
), \
200 $(eval
$(call gb_LinkTarget__expand_executable
,$(call gb_Executable_get_linktarget
,$(exec
)))))
201 $(foreach workdir_linktargetname
,$(gb_LinkTarget__ALL_TOUCHED
), \
202 $(eval
$(call gb_LinkTarget__remove_touch
,$(workdir_linktargetname
))))
204 else # gb_PARTIAL_BUILD
206 # call gb_LinkTarget__expand_executable_template,class
207 define gb_LinkTarget__expand_executable_template
209 gb_
$(1)__get_dep_libraries_target
= $$(call gb_LinkTarget_get_dep_libraries_target
,$$(call gb_
$(1)__get_workdir_linktargetname
,$$(1)))
210 gb_
$(1)__get_dep_externals_target
= $$(call gb_LinkTarget_get_dep_externals_target
,$$(call gb_
$(1)__get_workdir_linktargetname
,$$(1)))
211 gb_
$(1)__get_dep_statics_target
= $$(call gb_LinkTarget_get_dep_statics_target
,$$(call gb_
$(1)__get_workdir_linktargetname
,$$(1)))
213 # call gb_$(1)__has_any_dependencies,item
214 define gb_
$(1)__has_any_dependencies
215 $$(if
$$(strip $$(filter-out GBUILD_TOUCHED
,
216 $$(call gb_
$(1)__get_all_libraries
,$$(1))
217 $$(call gb_
$(1)__get_all_externals
,$$(1))
218 $$(call gb_
$(1)__get_all_statics
,$$(1)))),$$(1))
222 # call gb_$(1)__expand_deps,item
223 define gb_
$(1)__expand_deps
224 $$(if
$$(call gb_
$(1)__has_any_dependencies
,$$(1)),
225 $$(if
$$(shell cat
$$(call gb_
$(1)__get_dep_libraries_target
,$$(1)) 2>/dev
/null
),
226 $$(eval
$$(call gb_
$(1)_use_libraries
,$$(1),$$(shell cat
$$(call gb_
$(1)__get_dep_libraries_target
,$$(1))))))
227 $$(if
$$(shell cat
$$(call gb_
$(1)__get_dep_externals_target
,$$(1)) 2>/dev
/null
),
228 $$(eval
$$(call gb_
$(1)_use_externals
,$$(1),$$(shell cat
$$(call gb_
$(1)__get_dep_externals_target
,$$(1))))))
229 $$(if
$$(shell cat
$$(call gb_
$(1)__get_dep_statics_target
,$$(1)) 2>/dev
/null
), \
230 $$(eval
$$(call gb_
$(1)_use_static_libraries
,$$(1),$$(shell cat
$$(call gb_
$(1)__get_dep_statics_target
,$$(1))))))
235 endef # gb_LinkTarget__expand_executable_template
237 ifneq (,$(gb_DEBUG_STATIC
))
238 $(info $(call gb_LinkTarget__expand_executable_template
,Executable
))
240 $(eval
$(call gb_LinkTarget__expand_executable_template
,Executable
))
242 $(foreach exec
,$(gb_Executable_KNOWN
),$(eval
$(call gb_Executable__expand_deps
,$(exec
))))
244 endif # gb_PARTIAL_BUILD
247 # vim: set noet sw=4 ts=4: