Johan Oudinet | 781b494 | 2015-01-12 10:32:06 +0100 | [diff] [blame] | 1 | ################################################################################ |
| 2 | # rebar package infrastructure for Erlang packages |
| 3 | # |
| 4 | # This file implements an infrastructure that eases development of |
| 5 | # package .mk files for rebar packages. It should be used for all |
| 6 | # packages that use rebar as their build system. |
| 7 | # |
| 8 | # In terms of implementation, this rebar infrastructure requires the |
| 9 | # .mk file to only specify metadata information about the package: |
| 10 | # name, version, download URL, etc. |
| 11 | # |
| 12 | # We still allow the package .mk file to override what the different |
| 13 | # steps are doing, if needed. For example, if <PKG>_BUILD_CMDS is |
| 14 | # already defined, it is used as the list of commands to perform to |
| 15 | # build the package, instead of the default rebar behaviour. The |
| 16 | # package can also define some post operation hooks. |
| 17 | # |
| 18 | ################################################################################ |
| 19 | |
| 20 | # Directories to store rebar dependencies in. |
| 21 | # |
| 22 | # These directories actually only contain symbolic links to Erlang |
| 23 | # applications in either $(HOST_DIR) or $(STAGING_DIR). One needs |
| 24 | # them to avoid rebar complaining about missing dependencies, as this |
| 25 | # infrastructure tells rebar to NOT download dependencies during |
| 26 | # the build stage. |
| 27 | # |
| 28 | REBAR_HOST_DEPS_DIR = $(HOST_DIR)/usr/share/rebar/deps |
| 29 | REBAR_TARGET_DEPS_DIR = $(STAGING_DIR)/usr/share/rebar/deps |
| 30 | |
| 31 | # Tell rebar where to find the dependencies |
| 32 | # |
| 33 | REBAR_HOST_DEPS_ENV = \ |
| 34 | ERL_COMPILER_OPTIONS='{i, "$(REBAR_HOST_DEPS_DIR)"}' \ |
| 35 | ERL_EI_LIBDIR=$(HOST_DIR)/usr/lib/erlang/lib/erl_interface-$(ERLANG_EI_VSN)/lib |
| 36 | REBAR_TARGET_DEPS_ENV = \ |
| 37 | ERL_COMPILER_OPTIONS='{i, "$(REBAR_TARGET_DEPS_DIR)"}' \ |
| 38 | ERL_EI_LIBDIR=$(STAGING_DIR)/usr/lib/erlang/lib/erl_interface-$(ERLANG_EI_VSN)/lib |
| 39 | |
| 40 | ################################################################################ |
| 41 | # Helper functions |
| 42 | ################################################################################ |
| 43 | |
| 44 | # Install an Erlang application from $(@D). |
| 45 | # |
Frank Hunleth | 7af66e5 | 2015-02-16 12:00:29 -0500 | [diff] [blame] | 46 | # i.e., define a recipe that installs the "bin ebin priv $(2)" directories |
Johan Oudinet | 781b494 | 2015-01-12 10:32:06 +0100 | [diff] [blame] | 47 | # from $(@D) to $(1)$($(PKG)_ERLANG_LIBDIR). |
| 48 | # |
| 49 | # argument 1 should typically be $(HOST_DIR), $(TARGET_DIR), |
| 50 | # or $(STAGING_DIR). |
| 51 | # argument 2 is typically empty when installing in $(TARGET_DIR) and |
| 52 | # "include" when installing in $(HOST_DIR) or |
| 53 | # $(STAGING_DIR). |
| 54 | # |
| 55 | # Note: calling this function must be done with $$(call ...) because it |
| 56 | # expands package-related variables. |
| 57 | # |
| 58 | define install-erlang-directories |
| 59 | $(INSTALL) -d $(1)/$($(PKG)_ERLANG_LIBDIR) |
Frank Hunleth | 7af66e5 | 2015-02-16 12:00:29 -0500 | [diff] [blame] | 60 | for dir in bin ebin priv $(2); do \ |
Johan Oudinet | 781b494 | 2015-01-12 10:32:06 +0100 | [diff] [blame] | 61 | if test -d $(@D)/$$dir; then \ |
| 62 | cp -r $(@D)/$$dir $(1)$($(PKG)_ERLANG_LIBDIR); \ |
| 63 | fi; \ |
| 64 | done |
| 65 | endef |
| 66 | |
| 67 | # Setup a symbolic link in rebar's deps_dir to the actual location |
| 68 | # where an Erlang application is installed. |
| 69 | # |
| 70 | # i.e., define a recipe that creates a symbolic link |
| 71 | # from $($(PKG)_REBAR_DEPS_DIR)/$($(PKG)_ERLANG_APP) |
| 72 | # to $(1)$($(PKG)_ERLANG_LIBDIR). |
| 73 | # |
| 74 | # For target packages for example, one uses this to setup symbolic |
| 75 | # links from $(STAGING_DIR)/usr/share/rebar/deps/<erlang-app> to |
| 76 | # $(STAGING_DIR)/usr/lib/erlang/lib/<erlang-app>-<version>. This |
Frank Hunleth | 235879b | 2015-02-16 12:00:30 -0500 | [diff] [blame] | 77 | # infrastructure points rebar at the former in order to tell rebar to |
Johan Oudinet | 781b494 | 2015-01-12 10:32:06 +0100 | [diff] [blame] | 78 | # NOT download dependencies during the build stage, and instead use |
| 79 | # the already available dependencies. |
| 80 | # |
| 81 | # Therefore, |
| 82 | # argument 1 is $(HOST_DIR) (for host packages) or |
| 83 | # $(STAGING_DIR) (for target packages). |
| 84 | # |
| 85 | # argument 2 is HOST (for host packages) or |
| 86 | # TARGET (for target packages). |
| 87 | # |
| 88 | # Note: calling this function must be done with $$(call ...) because it |
| 89 | # expands package-related variables. |
| 90 | # |
| 91 | define install-rebar-deps |
| 92 | $(INSTALL) -d $(REBAR_$(2)_DEPS_DIR) |
| 93 | ln -f -s $(1)/$($(PKG)_ERLANG_LIBDIR) \ |
| 94 | $(REBAR_$(2)_DEPS_DIR)/$($(PKG)_ERLANG_APP) |
| 95 | endef |
| 96 | |
| 97 | ################################################################################ |
| 98 | # inner-rebar-package -- defines how the configuration, compilation |
| 99 | # and installation of a rebar package should be done, implements a few |
| 100 | # hooks to tune the build process according to rebar specifities, and |
| 101 | # calls the generic package infrastructure to generate the necessary |
| 102 | # make targets. |
| 103 | # |
| 104 | # argument 1 is the lowercase package name |
| 105 | # argument 2 is the uppercase package name, including a HOST_ prefix |
| 106 | # for host packages |
| 107 | # argument 3 is the uppercase package name, without the HOST_ prefix |
| 108 | # for host packages |
| 109 | # argument 4 is the type (target or host) |
| 110 | # |
| 111 | ################################################################################ |
| 112 | |
| 113 | define inner-rebar-package |
| 114 | |
| 115 | # Extract just the raw package name, lowercase without the leading |
| 116 | # erlang- or host- prefix, as this is used by rebar to find the |
| 117 | # dependencies a package specifies. |
| 118 | # |
| 119 | $(2)_ERLANG_APP = $(subst -,_,$(patsubst erlang-%,%,$(patsubst host-%,%,$(1)))) |
| 120 | |
| 121 | # Path where to store the package's libs, relative to either $(HOST_DIR) |
| 122 | # for host packages, or $(STAGING_DIR) for target packages. |
| 123 | # |
| 124 | $(2)_ERLANG_LIBDIR = \ |
| 125 | /usr/lib/erlang/lib/$$($$(PKG)_ERLANG_APP)-$$($$(PKG)_VERSION) |
| 126 | |
| 127 | # If a host package, inherit <pkg>_USE_BUNDLED_REBAR from the target |
| 128 | # package, if not explicitly defined. Otherwise, default to NO. |
| 129 | ifndef $(2)_USE_BUNDLED_REBAR |
| 130 | ifdef $(3)_USE_BUNDLED_REBAR |
| 131 | $(2)_USE_BUNDLED_REBAR = $$($(3)_USE_BUNDLED_REBAR) |
| 132 | else |
| 133 | $(2)_USE_BUNDLED_REBAR ?= NO |
| 134 | endif |
| 135 | endif |
| 136 | |
| 137 | # If a host package, inherit <pkg>_USE_AUTOCONF from the target |
| 138 | # package, if not explicitly defined. Otherwise, default to NO. |
| 139 | ifndef $(2)_USE_AUTOCONF |
| 140 | ifdef $(3)_USE_AUTOCONF |
| 141 | $(2)_USE_AUTOCONF = $$($(3)_USE_AUTOCONF) |
| 142 | else |
| 143 | $(2)_USE_AUTOCONF ?= NO |
| 144 | endif |
| 145 | endif |
| 146 | |
| 147 | # Define the build and install commands |
| 148 | # |
| 149 | ifeq ($(4),target) |
| 150 | |
| 151 | # Target packages need the erlang interpreter on the target |
| 152 | $(2)_DEPENDENCIES += erlang |
| 153 | |
| 154 | # Used only if the package uses autotools underneath; otherwise, ignored |
| 155 | $(2)_CONF_ENV += $$(REBAR_TARGET_DEPS_ENV) |
| 156 | |
| 157 | ifndef $(2)_BUILD_CMDS |
| 158 | define $(2)_BUILD_CMDS |
| 159 | (cd $$(@D); \ |
| 160 | CC="$$(TARGET_CC)" \ |
Frank Hunleth | 6be72cd | 2016-02-02 14:57:28 -0500 | [diff] [blame] | 161 | CXX="$$(TARGET_CXX)" \ |
Johan Oudinet | 781b494 | 2015-01-12 10:32:06 +0100 | [diff] [blame] | 162 | CFLAGS="$$(TARGET_CFLAGS)" \ |
Frank Hunleth | 6be72cd | 2016-02-02 14:57:28 -0500 | [diff] [blame] | 163 | CXXFLAGS="$$(TARGET_CXXFLAGS)" \ |
Johan Oudinet | 781b494 | 2015-01-12 10:32:06 +0100 | [diff] [blame] | 164 | LDFLAGS="$$(TARGET_LDFLAGS)" \ |
| 165 | $$(REBAR_TARGET_DEPS_ENV) \ |
| 166 | $$(TARGET_MAKE_ENV) \ |
| 167 | $$($$(PKG)_REBAR_ENV) $$($$(PKG)_REBAR) deps_dir=$$(REBAR_TARGET_DEPS_DIR) compile \ |
| 168 | ) |
| 169 | endef |
| 170 | endif |
| 171 | |
| 172 | # We need to double-$ the 'call' because it wants to expand |
| 173 | # package-related variables |
| 174 | ifndef $(2)_INSTALL_STAGING_CMDS |
| 175 | define $(2)_INSTALL_STAGING_CMDS |
| 176 | $$(call install-erlang-directories,$$(STAGING_DIR),include) |
| 177 | $$(call install-rebar-deps,$$(STAGING_DIR),TARGET) |
| 178 | endef |
| 179 | endif |
| 180 | |
| 181 | # We need to double-$ the 'call' because it wants to expand |
| 182 | # package-related variables |
| 183 | ifndef $(2)_INSTALL_TARGET_CMDS |
| 184 | define $(2)_INSTALL_TARGET_CMDS |
| 185 | $$(call install-erlang-directories,$$(TARGET_DIR)) |
| 186 | endef |
| 187 | endif |
| 188 | |
| 189 | else # !target |
| 190 | |
Johan Oudinet | 781b494 | 2015-01-12 10:32:06 +0100 | [diff] [blame] | 191 | # Host packages need the erlang interpreter on the host |
| 192 | $(2)_DEPENDENCIES += host-erlang |
| 193 | |
| 194 | # Used only if the package uses autotools underneath; otherwise, ignored |
| 195 | $(2)_CONF_ENV += $$(REBAR_HOST_DEPS_ENV) |
| 196 | |
| 197 | ifndef $(2)_BUILD_CMDS |
| 198 | define $(2)_BUILD_CMDS |
| 199 | (cd $$(@D); \ |
Frank Hunleth | a02045c | 2015-02-16 12:00:28 -0500 | [diff] [blame] | 200 | CC="$$(HOSTCC)" \ |
Johan Oudinet | 781b494 | 2015-01-12 10:32:06 +0100 | [diff] [blame] | 201 | CFLAGS="$$(HOST_CFLAGS)" \ |
| 202 | LDFLAGS="$$(HOST_LDFLAGS)" \ |
| 203 | $$(REBAR_HOST_DEPS_ENV) \ |
| 204 | $$(HOST_MAKE_ENV) \ |
| 205 | $$($$(PKG)_REBAR_ENV) $$($$(PKG)_REBAR) deps_dir=$$(REBAR_HOST_DEPS_DIR) compile \ |
| 206 | ) |
| 207 | endef |
| 208 | endif |
| 209 | |
| 210 | # We need to double-$ the 'call' because it wants to expand |
| 211 | # package-related variables |
| 212 | ifndef $(2)_INSTALL_CMDS |
| 213 | define $(2)_INSTALL_CMDS |
| 214 | $$(call install-erlang-directories,$$(HOST_DIR),include) |
| 215 | $$(call install-rebar-deps,$$(HOST_DIR),HOST) |
| 216 | endef |
| 217 | endif |
| 218 | |
| 219 | endif # !target |
| 220 | |
| 221 | # Whether to use the generic rebar or the package's bundled rebar |
| 222 | # |
| 223 | ifeq ($$($(2)_USE_BUNDLED_REBAR),YES) |
| 224 | $(2)_REBAR = ./rebar |
| 225 | else |
| 226 | $(2)_REBAR = rebar |
| 227 | $(2)_DEPENDENCIES += host-erlang-rebar |
| 228 | endif |
| 229 | |
| 230 | # The package sub-infra to use |
| 231 | # |
| 232 | ifeq ($$($(2)_USE_AUTOCONF),YES) |
| 233 | $(call inner-autotools-package,$(1),$(2),$(3),$(4)) |
| 234 | else |
| 235 | $(call inner-generic-package,$(1),$(2),$(3),$(4)) |
| 236 | endif |
| 237 | |
| 238 | endef # inner-rebar-package |
| 239 | |
| 240 | rebar-package = $(call inner-rebar-package,$(pkgname),$(call UPPERCASE,$(pkgname)),$(call UPPERCASE,$(pkgname)),target) |
| 241 | host-rebar-package = $(call inner-rebar-package,host-$(pkgname),$(call UPPERCASE,host-$(pkgname)),$(call UPPERCASE,$(pkgname)),host) |