| ################################################################################ |
| # rebar package infrastructure for Erlang packages |
| # |
| # This file implements an infrastructure that eases development of |
| # package .mk files for rebar packages. It should be used for all |
| # packages that use rebar as their build system. |
| # |
| # In terms of implementation, this rebar infrastructure requires the |
| # .mk file to only specify metadata information about the package: |
| # name, version, download URL, etc. |
| # |
| # We still allow the package .mk file to override what the different |
| # steps are doing, if needed. For example, if <PKG>_BUILD_CMDS is |
| # already defined, it is used as the list of commands to perform to |
| # build the package, instead of the default rebar behaviour. The |
| # package can also define some post operation hooks. |
| # |
| ################################################################################ |
| |
| # Directories to store rebar dependencies in. |
| # |
| # These directories actually only contain symbolic links to Erlang |
| # applications in either $(HOST_DIR) or $(STAGING_DIR). One needs |
| # them to avoid rebar complaining about missing dependencies, as this |
| # infrastructure tells rebar to NOT download dependencies during |
| # the build stage. |
| # |
| REBAR_HOST_DEPS_DIR = $(HOST_DIR)/share/rebar/deps |
| REBAR_TARGET_DEPS_DIR = $(STAGING_DIR)/usr/share/rebar/deps |
| |
| # Tell rebar where to find the dependencies |
| # |
| REBAR_HOST_DEPS_ENV = \ |
| ERL_COMPILER_OPTIONS='{i, "$(REBAR_HOST_DEPS_DIR)"}' \ |
| ERL_EI_LIBDIR=$(HOST_DIR)/lib/erlang/lib/erl_interface-$(call erlang_ei_vsn,$(HOST_DIR))/lib |
| REBAR_TARGET_DEPS_ENV = \ |
| ERL_COMPILER_OPTIONS='{i, "$(REBAR_TARGET_DEPS_DIR)"}' \ |
| ERL_EI_LIBDIR=$(STAGING_DIR)/usr/lib/erlang/lib/erl_interface-$(call erlang_ei_vsn,$(STAGING_DIR)/usr)/lib |
| |
| ################################################################################ |
| # Helper functions |
| ################################################################################ |
| |
| # Install an Erlang application from $(@D). |
| # |
| # i.e., define a recipe that installs the "bin ebin priv $(2)" directories |
| # from $(@D) to $(1)/$($(PKG)_ERLANG_LIBDIR). |
| # |
| # argument 1 should typically be $(HOST_DIR), $(TARGET_DIR), |
| # or $(STAGING_DIR). |
| # argument 2 is typically empty when installing in $(TARGET_DIR) and |
| # "include" when installing in $(HOST_DIR) or |
| # $(STAGING_DIR). |
| # |
| # Note: calling this function must be done with $$(call ...) because it |
| # expands package-related variables. |
| # |
| define install-erlang-directories |
| $(INSTALL) -d $(1)/$($(PKG)_ERLANG_LIBDIR) |
| for dir in bin ebin priv $(2); do \ |
| if test -d $(@D)/$$dir; then \ |
| cp -r $(@D)/$$dir $(1)/$($(PKG)_ERLANG_LIBDIR); \ |
| fi; \ |
| done |
| endef |
| |
| # Setup a symbolic link in rebar's deps_dir to the actual location |
| # where an Erlang application is installed. |
| # |
| # i.e., define a recipe that creates a symbolic link |
| # from $($(PKG)_REBAR_DEPS_DIR)/$($(PKG)_ERLANG_APP) |
| # to $(1)$($(PKG)_ERLANG_LIBDIR). |
| # |
| # For target packages for example, one uses this to setup symbolic |
| # links from $(STAGING_DIR)/usr/share/rebar/deps/<erlang-app> to |
| # $(STAGING_DIR)/usr/lib/erlang/lib/<erlang-app>-<version>. This |
| # infrastructure points rebar at the former in order to tell rebar to |
| # NOT download dependencies during the build stage, and instead use |
| # the already available dependencies. |
| # |
| # Therefore, |
| # argument 1 is $(HOST_DIR) (for host packages) or |
| # $(STAGING_DIR) (for target packages). |
| # |
| # argument 2 is HOST (for host packages) or |
| # TARGET (for target packages). |
| # |
| # Note: calling this function must be done with $$(call ...) because it |
| # expands package-related variables. |
| # |
| define install-rebar-deps |
| $(INSTALL) -d $(REBAR_$(2)_DEPS_DIR) |
| ln -f -s $(1)/$($(PKG)_ERLANG_LIBDIR) \ |
| $(REBAR_$(2)_DEPS_DIR)/$($(PKG)_ERLANG_APP) |
| endef |
| |
| # Remove the "deps" statement from a rebar.config file |
| define remove-rebar-config-dependencies |
| $(SED) '/^{deps.*}\.$$/d' -e '/^{deps/,/}\.$$/d' \ |
| $($(PKG)_DIR)/rebar.config |
| endef |
| |
| |
| ################################################################################ |
| # inner-rebar-package -- defines how the configuration, compilation |
| # and installation of a rebar package should be done, implements a few |
| # hooks to tune the build process according to rebar specifities, and |
| # calls the generic package infrastructure to generate the necessary |
| # make targets. |
| # |
| # argument 1 is the lowercase package name |
| # argument 2 is the uppercase package name, including a HOST_ prefix |
| # for host packages |
| # argument 3 is the uppercase package name, without the HOST_ prefix |
| # for host packages |
| # argument 4 is the type (target or host) |
| # |
| ################################################################################ |
| |
| define inner-rebar-package |
| |
| # Extract just the raw package name, lowercase without the leading |
| # erlang- or host- prefix, as this is used by rebar to find the |
| # dependencies a package specifies. |
| # |
| $(2)_ERLANG_APP = $(subst -,_,$(patsubst erlang-%,%,$(patsubst host-%,%,$(1)))) |
| |
| # Path where to store the package's libs, relative to either $(HOST_DIR) |
| # for host packages, or $(STAGING_DIR)/usr for target packages. |
| # |
| $(2)_ERLANG_LIBDIR = \ |
| lib/erlang/lib/$$($$(PKG)_ERLANG_APP)-$$($$(PKG)_VERSION) |
| |
| # If a host package, inherit <pkg>_USE_BUNDLED_REBAR from the target |
| # package, if not explicitly defined. Otherwise, default to NO. |
| ifndef $(2)_USE_BUNDLED_REBAR |
| ifdef $(3)_USE_BUNDLED_REBAR |
| $(2)_USE_BUNDLED_REBAR = $$($(3)_USE_BUNDLED_REBAR) |
| else |
| $(2)_USE_BUNDLED_REBAR ?= NO |
| endif |
| endif |
| |
| # If a host package, inherit <pkg>_USE_AUTOCONF from the target |
| # package, if not explicitly defined. Otherwise, default to NO. |
| ifndef $(2)_USE_AUTOCONF |
| ifdef $(3)_USE_AUTOCONF |
| $(2)_USE_AUTOCONF = $$($(3)_USE_AUTOCONF) |
| else |
| $(2)_USE_AUTOCONF ?= NO |
| endif |
| endif |
| |
| # Define the build and install commands |
| # |
| ifeq ($(4),target) |
| |
| # Target packages need the erlang interpreter on the target |
| $(2)_DEPENDENCIES += erlang |
| |
| # Used only if the package uses autotools underneath; otherwise, ignored |
| $(2)_CONF_ENV += $$(REBAR_TARGET_DEPS_ENV) |
| |
| ifndef $(2)_BUILD_CMDS |
| define $(2)_BUILD_CMDS |
| (cd $$(@D); \ |
| CC="$$(TARGET_CC)" \ |
| CXX="$$(TARGET_CXX)" \ |
| CFLAGS="$$(TARGET_CFLAGS)" \ |
| CXXFLAGS="$$(TARGET_CXXFLAGS)" \ |
| LDFLAGS="$$(TARGET_LDFLAGS)" \ |
| $$(REBAR_TARGET_DEPS_ENV) \ |
| $$(TARGET_MAKE_ENV) \ |
| $$($$(PKG)_REBAR_ENV) $$($$(PKG)_REBAR) deps_dir=$$(REBAR_TARGET_DEPS_DIR) compile \ |
| ) |
| endef |
| endif |
| |
| # We need to double-$ the 'call' because it wants to expand |
| # package-related variables |
| ifndef $(2)_INSTALL_STAGING_CMDS |
| define $(2)_INSTALL_STAGING_CMDS |
| $$(call install-erlang-directories,$$(STAGING_DIR)/usr,include) |
| $$(call install-rebar-deps,$$(STAGING_DIR)/usr,TARGET) |
| endef |
| endif |
| |
| # We need to double-$ the 'call' because it wants to expand |
| # package-related variables |
| ifndef $(2)_INSTALL_TARGET_CMDS |
| define $(2)_INSTALL_TARGET_CMDS |
| $$(call install-erlang-directories,$$(TARGET_DIR)/usr) |
| endef |
| endif |
| |
| else # !target |
| |
| # Host packages need the erlang interpreter on the host |
| $(2)_DEPENDENCIES += host-erlang |
| |
| # Used only if the package uses autotools underneath; otherwise, ignored |
| $(2)_CONF_ENV += $$(REBAR_HOST_DEPS_ENV) |
| |
| ifndef $(2)_BUILD_CMDS |
| define $(2)_BUILD_CMDS |
| (cd $$(@D); \ |
| CC="$$(HOSTCC)" \ |
| CFLAGS="$$(HOST_CFLAGS)" \ |
| LDFLAGS="$$(HOST_LDFLAGS)" \ |
| $$(REBAR_HOST_DEPS_ENV) \ |
| $$(HOST_MAKE_ENV) \ |
| $$($$(PKG)_REBAR_ENV) $$($$(PKG)_REBAR) deps_dir=$$(REBAR_HOST_DEPS_DIR) compile \ |
| ) |
| endef |
| endif |
| |
| # We need to double-$ the 'call' because it wants to expand |
| # package-related variables |
| ifndef $(2)_INSTALL_CMDS |
| define $(2)_INSTALL_CMDS |
| $$(call install-erlang-directories,$$(HOST_DIR),include) |
| $$(call install-rebar-deps,$$(HOST_DIR),HOST) |
| endef |
| endif |
| |
| endif # !target |
| |
| # Whether to use the generic rebar or the package's bundled rebar |
| # |
| ifeq ($$($(2)_USE_BUNDLED_REBAR),YES) |
| $(2)_REBAR = ./rebar |
| else |
| $(2)_REBAR = rebar |
| $(2)_DEPENDENCIES += host-erlang-rebar |
| endif |
| |
| $(2)_KEEP_DEPENDENCIES ?= NO |
| |
| # Remove dependencies listed in rebar.config unless the package says |
| # otherwise |
| ifeq ($$($(2)_KEEP_DEPENDENCIES),NO) |
| $(2)_POST_PATCH_HOOKS += remove-rebar-config-dependencies |
| endif |
| |
| # The package sub-infra to use |
| # |
| ifeq ($$($(2)_USE_AUTOCONF),YES) |
| $(call inner-autotools-package,$(1),$(2),$(3),$(4)) |
| else |
| $(call inner-generic-package,$(1),$(2),$(3),$(4)) |
| endif |
| |
| endef # inner-rebar-package |
| |
| rebar-package = $(call inner-rebar-package,$(pkgname),$(call UPPERCASE,$(pkgname)),$(call UPPERCASE,$(pkgname)),target) |
| host-rebar-package = $(call inner-rebar-package,host-$(pkgname),$(call UPPERCASE,host-$(pkgname)),$(call UPPERCASE,$(pkgname)),host) |