# -*- 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: