summaryrefslogtreecommitdiff
path: root/solenv/gbuild/ExternalExecutable.mk
blob: 0982dd9b8e7f1ec4befb41c5ef6dff4578885f8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# -*- 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) \
	$(2) \
	$(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.
#
# $2 is an optional part (like "xargs") to place between the setting of shell variables and the
# command proper.
#
# gb_ExternalExecutable_get_command executable
define gb_ExternalExecutable_get_command
$(strip $(call gb_ExternalExecutable__get_command,$(1),$(2)))
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: