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