xref: /OK3568_Linux_fs/buildroot/package/pkg-rebar.mk (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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#
28REBAR_HOST_DEPS_DIR = $(HOST_DIR)/share/rebar/deps
29REBAR_TARGET_DEPS_DIR = $(STAGING_DIR)/usr/share/rebar/deps
30
31# Tell rebar where to find the dependencies
32#
33REBAR_HOST_DEPS_ENV = \
34	ERL_COMPILER_OPTIONS='{i, "$(REBAR_HOST_DEPS_DIR)"}' \
35	ERL_EI_LIBDIR=$(HOST_DIR)/lib/erlang/lib/erl_interface-$(ERLANG_EI_VSN)/lib
36REBAR_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#
46# i.e., define a recipe that installs the "bin ebin priv $(2)" directories
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#
58define install-erlang-directories
59	$(INSTALL) -d $(1)/$($(PKG)_ERLANG_LIBDIR)
60	for dir in bin ebin priv $(2); do                               \
61		if test -d $(@D)/$$dir; then                            \
62			cp -r $(@D)/$$dir $(1)/$($(PKG)_ERLANG_LIBDIR); \
63		fi;                                                     \
64	done
65endef
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
77# infrastructure points rebar at the former in order to tell rebar to
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#
91define 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)
95endef
96
97# Remove the "deps" statement from a rebar.config file
98define remove-rebar-config-dependencies
99	$(SED) '/^{deps.*}\.$$/d' -e '/^{deps/,/}\.$$/d' \
100		$($(PKG)_DIR)/rebar.config
101endef
102
103
104################################################################################
105# inner-rebar-package -- defines how the configuration, compilation
106# and installation of a rebar package should be done, implements a few
107# hooks to tune the build process according to rebar specifities, and
108# calls the generic package infrastructure to generate the necessary
109# make targets.
110#
111#  argument 1 is the lowercase package name
112#  argument 2 is the uppercase package name, including a HOST_ prefix
113#             for host packages
114#  argument 3 is the uppercase package name, without the HOST_ prefix
115#             for host packages
116#  argument 4 is the type (target or host)
117#
118################################################################################
119
120define inner-rebar-package
121
122# Extract just the raw package name, lowercase without the leading
123# erlang- or host- prefix, as this is used by rebar to find the
124# dependencies a package specifies.
125#
126$(2)_ERLANG_APP = $(subst -,_,$(patsubst erlang-%,%,$(patsubst host-%,%,$(1))))
127
128# Path where to store the package's libs, relative to either $(HOST_DIR)
129# for host packages, or $(STAGING_DIR)/usr for target packages.
130#
131$(2)_ERLANG_LIBDIR = \
132	lib/erlang/lib/$$($$(PKG)_ERLANG_APP)-$$($$(PKG)_VERSION)
133
134# If a host package, inherit <pkg>_USE_BUNDLED_REBAR from the target
135# package, if not explicitly defined. Otherwise, default to NO.
136ifndef $(2)_USE_BUNDLED_REBAR
137 ifdef $(3)_USE_BUNDLED_REBAR
138  $(2)_USE_BUNDLED_REBAR = $$($(3)_USE_BUNDLED_REBAR)
139 else
140  $(2)_USE_BUNDLED_REBAR ?= NO
141 endif
142endif
143
144# If a host package, inherit <pkg>_USE_AUTOCONF from the target
145# package, if not explicitly defined. Otherwise, default to NO.
146ifndef $(2)_USE_AUTOCONF
147 ifdef $(3)_USE_AUTOCONF
148  $(2)_USE_AUTOCONF = $$($(3)_USE_AUTOCONF)
149 else
150  $(2)_USE_AUTOCONF ?= NO
151 endif
152endif
153
154# Define the build and install commands
155#
156ifeq ($(4),target)
157
158# Target packages need the erlang interpreter on the target
159$(2)_DEPENDENCIES += erlang
160
161# Used only if the package uses autotools underneath; otherwise, ignored
162$(2)_CONF_ENV += $$(REBAR_TARGET_DEPS_ENV)
163
164ifndef $(2)_BUILD_CMDS
165define $(2)_BUILD_CMDS
166	(cd $$(@D); \
167		CC="$$(TARGET_CC)" \
168		CXX="$$(TARGET_CXX)" \
169		CFLAGS="$$(TARGET_CFLAGS)" \
170		CXXFLAGS="$$(TARGET_CXXFLAGS)" \
171		LDFLAGS="$$(TARGET_LDFLAGS)" \
172		$$(REBAR_TARGET_DEPS_ENV) \
173		$$(TARGET_MAKE_ENV) \
174		$$($$(PKG)_REBAR_ENV) $$($$(PKG)_REBAR) deps_dir=$$(REBAR_TARGET_DEPS_DIR) compile \
175	)
176endef
177endif
178
179# We need to double-$ the 'call' because it wants to expand
180# package-related variables
181ifndef $(2)_INSTALL_STAGING_CMDS
182define $(2)_INSTALL_STAGING_CMDS
183	$$(call install-erlang-directories,$$(STAGING_DIR)/usr,include)
184	$$(call install-rebar-deps,$$(STAGING_DIR)/usr,TARGET)
185endef
186endif
187
188# We need to double-$ the 'call' because it wants to expand
189# package-related variables
190ifndef $(2)_INSTALL_TARGET_CMDS
191define $(2)_INSTALL_TARGET_CMDS
192	$$(call install-erlang-directories,$$(TARGET_DIR)/usr)
193endef
194endif
195
196else # !target
197
198# Host packages need the erlang interpreter on the host
199$(2)_DEPENDENCIES += host-erlang
200
201# Used only if the package uses autotools underneath; otherwise, ignored
202$(2)_CONF_ENV += $$(REBAR_HOST_DEPS_ENV)
203
204ifndef $(2)_BUILD_CMDS
205define $(2)_BUILD_CMDS
206	(cd $$(@D); \
207		CC="$$(HOSTCC)" \
208		CFLAGS="$$(HOST_CFLAGS)" \
209		LDFLAGS="$$(HOST_LDFLAGS)" \
210		$$(REBAR_HOST_DEPS_ENV) \
211		$$(HOST_MAKE_ENV) \
212		$$($$(PKG)_REBAR_ENV) $$($$(PKG)_REBAR) deps_dir=$$(REBAR_HOST_DEPS_DIR) compile \
213	)
214endef
215endif
216
217# We need to double-$ the 'call' because it wants to expand
218# package-related variables
219ifndef $(2)_INSTALL_CMDS
220define $(2)_INSTALL_CMDS
221	$$(call install-erlang-directories,$$(HOST_DIR),include)
222	$$(call install-rebar-deps,$$(HOST_DIR),HOST)
223endef
224endif
225
226endif # !target
227
228# Whether to use the generic rebar or the package's bundled rebar
229#
230ifeq ($$($(2)_USE_BUNDLED_REBAR),YES)
231$(2)_REBAR = ./rebar
232else
233$(2)_REBAR = rebar
234$(2)_DEPENDENCIES += host-erlang-rebar
235endif
236
237$(2)_KEEP_DEPENDENCIES ?= NO
238
239# Remove dependencies listed in rebar.config unless the package says
240# otherwise
241ifeq ($$($(2)_KEEP_DEPENDENCIES),NO)
242$(2)_POST_PATCH_HOOKS += remove-rebar-config-dependencies
243endif
244
245# The package sub-infra to use
246#
247ifeq ($$($(2)_USE_AUTOCONF),YES)
248$(call inner-autotools-package,$(1),$(2),$(3),$(4))
249else
250$(call inner-generic-package,$(1),$(2),$(3),$(4))
251endif
252
253endef # inner-rebar-package
254
255rebar-package = $(call inner-rebar-package,$(pkgname),$(call UPPERCASE,$(pkgname)),$(call UPPERCASE,$(pkgname)),target)
256host-rebar-package = $(call inner-rebar-package,host-$(pkgname),$(call UPPERCASE,host-$(pkgname)),$(call UPPERCASE,$(pkgname)),host)
257