Avoid potential negative array index access to cached text.
[LibreOffice.git] / solenv / gbuild / ExternalProject.mk
blob5227e6c13bec69370d1a8a7bae850b053131848f
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 # class ExternalProject
12 # Handles build of an external project
14 # Build of an external typically uses three gbuild classes:
15 # ExternalProject, ExternalPackage or Package, and UnpackedTarball. The
16 # first step is to prepare sources using UnpackedTarball. The tarball is
17 # passed to an ExternalProject, which handles the build proper and the
18 # results are delivered by an ExternalPackage (or Package, again;
19 # Package is sufficient if no files--e.g., headers--from the unpacked
20 # tarball need to be delivered.)
22 # An ExternalProject always uses one UnpackedTarball with the same name.
23 # The dependency structure ensures that any change on a dependency
24 # of the ExternalProject will cause the UnpackedTarball to be unpacked
25 # again, so the ExternalProject always does a clean build and is not at
26 # the mercy of the external's build system's dubious incremental builds.
28 # ExternalProject target
29 # => ExternalProject state target(s) (these actually build stuff)
30 # => UnpackedTarball target (unpack the tarball)
31 # => UnpackedTarball prepare target
32 # => ExternalProject prepare target
33 # => stuff the external depends upon
35 # ExternalProject has no gbuild abstraction for actually building the
36 # external code, so it is necessary to define rule(s) and recipe(s) to
37 # handle it. It does not matter if there are several rules handling
38 # separate phases of the build (e.g., configure, build, install) or if
39 # the whole build is handled by one rule.
41 # ExternalProject uses two directories during the build: state dir
42 # serves to keep file targets that mark state of the build progress
43 # (e.g., "configure done", "build done") and the targets are accessible
44 # via gb_ExternalProject_get_state_target. It is highly advised to
45 # register them using gb_ExternalProject_register_targets. The second
46 # directory is work dir, accessible only from recipes via variable
47 # $(EXTERNAL_WORKDIR).
49 $(dir $(call gb_ExternalProject_get_statedir,%))%/.dir :
50 $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
52 $(dir $(call gb_ExternalProject_get_target,%)).dir :
53 $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
55 $(call gb_ExternalProject_get_preparation_target,%) :
56 touch $@
58 $(call gb_ExternalProject_get_target,%) :
59 $(call gb_Output_announce,$*,$(true),PRJ,3)
60 $(call gb_Trace_MakeMark,$*,PRJ)
61 touch $@
63 .PHONY : $(call gb_ExternalProject_get_clean_target,%)
64 $(call gb_ExternalProject_get_clean_target,%) :
65 $(call gb_Output_announce,$*,$(false),PRJ,3)
66 $(call gb_Helper_abbreviate_dirs,\
67 rm -rf \
68 $(call gb_ExternalProject_get_target,$*) \
69 $(call gb_ExternalProject_get_statedir,$*) \
72 # Define a new external project, using an unpacked tarball of the same name
74 # gb_ExternalProject_ExternalProject project
75 define gb_ExternalProject_ExternalProject
76 $(call gb_ExternalProject_get_target,$(1)) : EXTERNAL_WORKDIR := $(call gb_UnpackedTarball_get_dir,$(1))
78 $(call gb_ExternalProject_get_preparation_target,$(1)) : $(gb_Module_CURRENTMAKEFILE)
79 $(call gb_ExternalProject_get_preparation_target,$(1)) :| $(dir $(call gb_ExternalProject_get_target,$(1))).dir
80 $(call gb_UnpackedTarball_get_preparation_target,$(1)) : $(call gb_ExternalProject_get_preparation_target,$(1))
81 $(call gb_ExternalProject_get_clean_target,$(1)) : $(call gb_UnpackedTarball_get_clean_target,$(1))
82 $(call gb_ExternalProject_get_target,$(1)) : $(call gb_UnpackedTarball_get_target,$(1))
83 $(call gb_ExternalProject_get_target,$(1)) :| $(dir $(call gb_ExternalProject_get_target,$(1))).dir
85 $$(eval $$(call gb_Module_register_target,$(call gb_ExternalProject_get_target,$(1)),$(call gb_ExternalProject_get_clean_target,$(1))))
86 $(call gb_Helper_make_userfriendly_targets,$(1),ExternalProject)
88 endef
90 # Depend on an unpacked tarball
92 # This is needed to express dependencies on header-only projects, which
93 # do not have any ExternalProject.
95 # gb_ExternalProject_use_unpacked project unpacked
96 define gb_ExternalProject_use_unpacked
97 $(call gb_ExternalProject_get_preparation_target,$(1)) : $(call gb_UnpackedTarball_get_target,$(2))
99 endef
101 # Register a target in state directory
103 # This function defines proper dependencies for the target to ensure
104 # that:
105 # * the main target is updated if this target is updated
106 # * this target is updated if the unpacked tarball has changed.
108 # gb_ExternalProject_register_target project target
109 define gb_ExternalProject_register_target
110 $(call gb_ExternalProject_get_target,$(1)) : $(call gb_ExternalProject_get_state_target,$(1),$(2))
111 $(call gb_ExternalProject_get_state_target,$(1),$(2)) : $(call gb_UnpackedTarball_get_target,$(1))
112 $(call gb_ExternalProject_get_state_target,$(1),$(2)) :| $(dir $(call gb_ExternalProject_get_state_target,$(1),$(2))).dir
114 endef
116 # Register several targets at once
118 # gb_ExternalProject_register_targets project target(s)
119 define gb_ExternalProject_register_targets
120 $(foreach target,$(2),$(call gb_ExternalProject_register_target,$(1),$(target)))
122 endef
124 # Make an external Project depend on another ExternalProject
125 define gb_ExternalProject_use_external_project
126 $(call gb_ExternalProject_get_preparation_target,$(1)) : $(call gb_ExternalProject_get_target,$(2))
128 endef
130 # call gb_ExternalProject_use_external_projects,project,projects
131 define gb_ExternalProject_use_external_projects
132 $(foreach ext,$(2),$(call gb_ExternalProject_use_external_project,$(1),$(ext)))
133 endef
135 # Make an ExternalProject depend on an external
137 # this forwards to functions that must be defined in RepositoryExternal.mk.
138 # $(eval $(call gb_ExternalProject_use_external,library,external))
139 define gb_ExternalProject_use_external
140 $(if $(filter undefined,$(origin gb_ExternalProject__use_$(2))),\
141 $(error gb_ExternalProject_use_external: unknown external: $(2)),\
142 $(call gb_ExternalProject__use_$(2),$(1)))
143 endef
145 define gb_ExternalProject_use_externals
146 $(foreach external,$(2),$(call gb_ExternalProject_use_external,$(1),$(external)))
147 endef
149 # Make an external project depend on a package
151 # This is most useful for depending on output files created by another
152 # ExternalProject.
154 # gb_ExternalProject_use_package external package
155 define gb_ExternalProject_use_package
156 $(call gb_ExternalProject_get_preparation_target,$(1)) : $(call gb_Package_get_target,$(2))
158 endef
160 # Make an external project depend on several packages at once
162 # gb_ExternalProject_use_packages external package(s)
163 define gb_ExternalProject_use_packages
164 $(foreach package,$(2),$(call gb_ExternalProject_use_package,$(1),$(package)))
166 endef
168 # Make an external project depend on a StaticLibrary
170 # Realistically there are some externals that do not have a usable build
171 # system, and other externals that do may depend on those.
173 # gb_ExternalProject_use_static_libraries external staticlibraries
174 define gb_ExternalProject_use_static_libraries
175 $(call gb_ExternalProject_get_preparation_target,$(1)) : \
176 $(foreach lib,$(2),$(call gb_StaticLibrary_get_target,$(lib)))
178 endef
180 # Make an external project depend on a Library
182 # Realistically there are some externals that do not have a usable build
183 # system, and other externals that do may depend on those.
185 # gb_ExternalProject_use_libraries external libraries
186 define gb_ExternalProject_use_libraries
187 ifneq (,$$(filter-out $(gb_Library_KNOWNLIBS) $(gb_LinkTarget__syslib),$(2)))
188 $$(eval $$(call gb_Output_info,currently known libraries are: $(sort $(gb_Library_KNOWNLIBS)),ALL))
189 $$(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))
190 endif
191 ifneq (,$$(filter $$(gb_MERGEDLIBS),$(2)))
192 $$(eval $$(call gb_Output_error,Cannot link against library/libraries $$(filter $$(gb_MERGEDLIBS),$(2)) because they are merged.))
193 endif
195 $(call gb_ExternalProject_get_preparation_target,$(1)) : \
196 $(foreach lib,$(2),$(call gb_Library_get_target,$(lib)))
198 endef
200 # Make an external project depend on a Jar file
202 # gb_ExternalProject_use_jars external jars
203 define gb_ExternalProject_use_jars
204 $(call gb_ExternalProject_get_preparation_target,$(1)) : \
205 $(foreach jar,$(2),$(call gb_Jar_get_target,$(jar)))
207 endef
209 # Returns flags to include in CFLAGS/CXXFLAGS to enable optimizations and/or debugging.
210 # gb_ExternalProject_get_build_flags project
211 gb_ExternalProject_get_build_flags = $(call gb_LinkTarget__get_debugflags,ExternalProject_$(1))
213 # Returns flags to include in LDFLAGS to enable optimizations and/or debugging.
214 # gb_ExternalProject_get_link_flags project
215 gb_ExternalProject_get_link_flags = $(LDFLAGS) $(USE_LD) $(call gb_LinkTarget__get_debugldflags,ExternalProject_$(1))
217 # Run a target command
219 # This provides a wrapper that changes to the right directory,
220 # touches the 'target' if successful and also provides
221 # the ability to hide the output if there is no failure
222 # gb_ExternalProject_run,run_target,command,optional_extra_sub_directory,optional_log_filename)
223 # default log_filename is <run_target>.log
226 define gb_ExternalProject_run
227 $(if $(findstring YES,$(UNPACKED_IS_BIN_TARBALL)),\
228 touch $@,
229 $(call gb_Helper_print_on_error,cd $(EXTERNAL_WORKDIR)/$(3) && \
230 unset Platform && \
231 $(if $(WRAPPERS),export $(WRAPPERS) &&) \
232 $(if $(NMAKE),export $(NMAKE) &&) \
233 $(if $(gb_COMPILER_SETUP),export $(gb_COMPILER_SETUP) &&) \
234 $(2) && touch $@,$(EXTERNAL_WORKDIR)/$(if $(3),$(3)/,)$(if $(4),$(4),$(1).log))
236 endef
238 # vim: set noet sw=4 ts=4: