Makefile 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. ifeq ($(DEBUG),1)
  2. DEBUG_INFO = $(info $1)
  3. else
  4. DEBUG_INFO = @:
  5. endif
  6. REBAR = $(CURDIR)/rebar3
  7. BUILD = $(CURDIR)/build
  8. SCRIPTS = $(CURDIR)/scripts
  9. include env.sh
  10. # Dashboard version
  11. # from https://github.com/emqx/emqx-dashboard5
  12. export EMQX_DASHBOARD_VERSION ?= v1.10.3
  13. export EMQX_EE_DASHBOARD_VERSION ?= e1.8.4-beta.1
  14. export EMQX_RELUP ?= true
  15. export EMQX_REL_FORM ?= tgz
  16. -include default-profile.mk
  17. PROFILE ?= emqx
  18. REL_PROFILES := emqx emqx-enterprise
  19. PKG_PROFILES := emqx-pkg emqx-enterprise-pkg
  20. PROFILES := $(REL_PROFILES) $(PKG_PROFILES) default
  21. CT_NODE_NAME ?= 'test@127.0.0.1'
  22. CT_READABLE ?= true
  23. CT_COVER_EXPORT_PREFIX ?= $(PROFILE)
  24. export REBAR_GIT_CLONE_OPTIONS += --depth=1
  25. ELIXIR_COMMON_DEPS := ensure-hex ensure-mix-rebar3 ensure-mix-rebar
  26. .PHONY: default
  27. default: $(REBAR) $(PROFILE)
  28. .prepare:
  29. @$(SCRIPTS)/git-hooks-init.sh # this is no longer needed since 5.0 but we keep it anyway
  30. @$(SCRIPTS)/prepare-build-deps.sh
  31. @touch .prepare
  32. .PHONY: all
  33. all: $(REBAR) $(PROFILES)
  34. .PHONY: ensure-rebar3
  35. ensure-rebar3:
  36. @$(SCRIPTS)/ensure-rebar3.sh
  37. $(REBAR): .prepare ensure-rebar3
  38. .PHONY: ensure-hex
  39. ensure-hex:
  40. # @mix local.hex --if-missing --force
  41. @mix local.hex 2.0.6 --if-missing --force
  42. .PHONY: ensure-mix-rebar3
  43. ensure-mix-rebar3: $(REBAR)
  44. @mix local.rebar rebar3 $(CURDIR)/rebar3 --if-missing --force
  45. .PHONY: ensure-mix-rebar
  46. ensure-mix-rebar: $(REBAR)
  47. @mix local.rebar --if-missing --force
  48. .PHONY: elixir-common-deps
  49. elixir-common-deps: $(ELIXIR_COMMON_DEPS)
  50. .PHONY: mix-deps-get
  51. mix-deps-get: elixir-common-deps
  52. @mix deps.get
  53. .PHONY: eunit
  54. eunit: $(REBAR) merge-config
  55. @$(REBAR) eunit --name eunit@127.0.0.1 -c -v --cover_export_name $(CT_COVER_EXPORT_PREFIX)-eunit
  56. .PHONY: proper
  57. proper: $(REBAR)
  58. @$(REBAR) proper -d test/props -c
  59. .PHONY: test-compile
  60. test-compile: $(REBAR) merge-config
  61. $(REBAR) as test compile
  62. .PHONY: $(REL_PROFILES:%=%-compile)
  63. $(REL_PROFILES:%=%-compile): $(REBAR) merge-config
  64. $(REBAR) as $(@:%-compile=%) compile
  65. .PHONY: ct
  66. ct: $(REBAR) merge-config
  67. @env ERL_FLAGS="-kernel prevent_overlapping_partitions false" $(REBAR) ct --name $(CT_NODE_NAME) -c -v --cover_export_name $(CT_COVER_EXPORT_PREFIX)-ct
  68. ## only check bpapi for enterprise profile because it's a super-set.
  69. .PHONY: static_checks
  70. static_checks:
  71. @$(REBAR) as check do xref, dialyzer
  72. @if [ "$${PROFILE}" = 'emqx-enterprise' ]; then $(REBAR) ct --suite apps/emqx/test/emqx_static_checks --readable $(CT_READABLE); fi
  73. ./scripts/check-i18n-style.sh
  74. ./scripts/check_missing_reboot_apps.exs
  75. # Allow user-set CASES environment variable
  76. ifneq ($(CASES),)
  77. CASES_ARG := --case $(CASES)
  78. endif
  79. # Allow user-set GROUPS environment variable
  80. ifneq ($(GROUPS),)
  81. GROUPS_ARG := --group $(GROUPS)
  82. endif
  83. ifeq ($(ENABLE_COVER_COMPILE),1)
  84. cover_args = --cover --cover_export_name $(CT_COVER_EXPORT_PREFIX)-$(subst /,-,$1)
  85. else
  86. cover_args =
  87. endif
  88. ## example:
  89. ## env SUITES=apps/appname/test/test_SUITE.erl CASES=t_foo make apps/appname-ct
  90. define gen-app-ct-target
  91. $1-ct: $(REBAR) merge-config clean-test-cluster-config
  92. $(eval SUITES := $(shell $(SCRIPTS)/find-suites.sh $1))
  93. ifneq ($(SUITES),)
  94. env ERL_FLAGS="-kernel prevent_overlapping_partitions false" $(REBAR) ct -v \
  95. --readable=$(CT_READABLE) \
  96. --name $(CT_NODE_NAME) \
  97. $(call cover_args,$1) \
  98. --suite $(SUITES) \
  99. $(GROUPS_ARG) \
  100. $(CASES_ARG)
  101. else
  102. @echo 'No suites found for $1'
  103. endif
  104. endef
  105. ifneq ($(filter %-ct,$(MAKECMDGOALS)),)
  106. app_to_test := $(patsubst %-ct,%,$(filter %-ct,$(MAKECMDGOALS)))
  107. $(call DEBUG_INFO,app_to_test $(app_to_test))
  108. $(eval $(call gen-app-ct-target,$(app_to_test)))
  109. endif
  110. ## apps/name-prop targets
  111. define gen-app-prop-target
  112. $1-prop:
  113. $(REBAR) proper -d test/props -v -m $(shell $(SCRIPTS)/find-props.sh $1)
  114. endef
  115. ifneq ($(filter %-prop,$(MAKECMDGOALS)),)
  116. app_to_test := $(patsubst %-prop,%,$(filter %-prop,$(MAKECMDGOALS)))
  117. $(call DEBUG_INFO,app_to_test $(app_to_test))
  118. $(eval $(call gen-app-prop-target,$(app_to_test)))
  119. endif
  120. .PHONY: ct-suite
  121. ct-suite: $(REBAR) merge-config clean-test-cluster-config
  122. ifneq ($(TESTCASE),)
  123. ifneq ($(GROUP),)
  124. $(REBAR) ct -v --readable=$(CT_READABLE) --name $(CT_NODE_NAME) --suite $(SUITE) --case $(TESTCASE) --group $(GROUP)
  125. else
  126. $(REBAR) ct -v --readable=$(CT_READABLE) --name $(CT_NODE_NAME) --suite $(SUITE) --case $(TESTCASE)
  127. endif
  128. else ifneq ($(GROUP),)
  129. $(REBAR) ct -v --readable=$(CT_READABLE) --name $(CT_NODE_NAME) --suite $(SUITE) --group $(GROUP)
  130. else
  131. $(REBAR) ct -v --readable=$(CT_READABLE) --name $(CT_NODE_NAME) --suite $(SUITE)
  132. endif
  133. .PHONY: cover
  134. cover: $(REBAR)
  135. @ENABLE_COVER_COMPILE=1 $(REBAR) as test cover
  136. .PHONY: coveralls
  137. coveralls: $(REBAR)
  138. @ENABLE_COVER_COMPILE=1 $(REBAR) as test coveralls send
  139. COMMON_DEPS := $(REBAR)
  140. .PHONY: $(REL_PROFILES)
  141. $(REL_PROFILES:%=%): $(COMMON_DEPS)
  142. @$(BUILD) $(@) rel
  143. .PHONY: compile $(PROFILES:%=compile-%)
  144. compile: $(PROFILES:%=compile-%)
  145. $(PROFILES:%=compile-%):
  146. @$(BUILD) $(@:compile-%=%) apps
  147. .PHONY: $(PROFILES:%=compile-%-elixir)
  148. $(PROFILES:%=compile-%-elixir):
  149. @env IS_ELIXIR=yes $(BUILD) $(@:compile-%-elixir=%) apps
  150. ## Not calling rebar3 clean because
  151. ## 1. rebar3 clean relies on rebar3, meaning it reads config, fetches dependencies etc.
  152. ## 2. it's slow
  153. ## NOTE: this does not force rebar3 to fetch new version dependencies
  154. ## make clean-all to delete all fetched dependencies for a fresh start-over
  155. .PHONY: clean $(PROFILES:%=clean-%)
  156. clean: $(PROFILES:%=clean-%)
  157. $(PROFILES:%=clean-%):
  158. @if [ -d _build/$(@:clean-%=%) ]; then \
  159. rm -f rebar.lock; \
  160. rm -rf _build/$(@:clean-%=%)/rel; \
  161. find _build/$(@:clean-%=%) -name '*.beam' -o -name '*.so' -o -name '*.app' -o -name '*.appup' -o -name '*.o' -o -name '*.d' -type f | xargs rm -f; \
  162. find _build/$(@:clean-%=%) -type l -delete; \
  163. fi
  164. .PHONY: clean-all
  165. clean-all:
  166. @rm -f rebar.lock
  167. @rm -rf deps
  168. @rm -rf _build
  169. @rm -f emqx_dialyzer_*_plt
  170. .PHONY: deps-all
  171. deps-all: $(REBAR) $(PROFILES:%=deps-%)
  172. @make clean # ensure clean at the end
  173. ## deps-<profile> is used in CI scripts to download deps and the
  174. ## share downloads between CI steps and/or copied into containers
  175. ## which may not have the right credentials
  176. .PHONY: $(PROFILES:%=deps-%)
  177. $(PROFILES:%=deps-%): $(COMMON_DEPS)
  178. @$(SCRIPTS)/pre-compile.sh $(@:deps-%=%)
  179. @$(REBAR) as $(@:deps-%=%) get-deps
  180. @rm -f rebar.lock
  181. .PHONY: xref
  182. xref: $(REBAR)
  183. @$(REBAR) as check xref
  184. .PHONY: dialyzer
  185. dialyzer: $(REBAR)
  186. @$(REBAR) as check dialyzer
  187. ## rel target is to create release package without relup
  188. .PHONY: $(REL_PROFILES:%=%-rel) $(PKG_PROFILES:%=%-rel)
  189. $(REL_PROFILES:%=%-rel) $(PKG_PROFILES:%=%-rel): $(COMMON_DEPS)
  190. @$(BUILD) $(subst -rel,,$(@)) rel
  191. ## download relup base packages
  192. .PHONY: $(REL_PROFILES:%=%-relup-downloads)
  193. define download-relup-packages
  194. $1-relup-downloads:
  195. @if [ "$${EMQX_RELUP}" = "true" ]; then $(SCRIPTS)/relup-build/download-base-packages.sh $1; fi
  196. endef
  197. ALL_ZIPS = $(REL_PROFILES)
  198. $(foreach zt,$(ALL_ZIPS),$(eval $(call download-relup-packages,$(zt))))
  199. ## relup target is to create relup instructions
  200. .PHONY: $(REL_PROFILES:%=%-relup)
  201. define gen-relup-target
  202. $1-relup: $(COMMON_DEPS)
  203. @$(BUILD) $1 relup
  204. endef
  205. ALL_TGZS = $(REL_PROFILES)
  206. $(foreach zt,$(ALL_TGZS),$(eval $(call gen-relup-target,$(zt))))
  207. ## tgz target is to create a release package .tar.gz with relup
  208. .PHONY: $(REL_PROFILES:%=%-tgz)
  209. define gen-tgz-target
  210. $1-tgz: $(COMMON_DEPS)
  211. @$(BUILD) $1 tgz
  212. endef
  213. ALL_TGZS = $(REL_PROFILES)
  214. $(foreach zt,$(ALL_TGZS),$(eval $(call gen-tgz-target,$(zt))))
  215. ## A pkg target depend on a regular release
  216. .PHONY: $(PKG_PROFILES)
  217. define gen-pkg-target
  218. $1: $(COMMON_DEPS)
  219. @$(BUILD) $1 pkg
  220. endef
  221. $(foreach pt,$(PKG_PROFILES),$(eval $(call gen-pkg-target,$(pt))))
  222. .PHONY: run
  223. run: compile-$(PROFILE) quickrun
  224. .PHONY: quickrun
  225. quickrun:
  226. ./dev -p $(PROFILE)
  227. ## Take the currently set PROFILE
  228. docker:
  229. @$(BUILD) $(PROFILE) docker
  230. ## docker target is to create docker instructions
  231. .PHONY: $(REL_PROFILES:%=%-docker) $(REL_PROFILES:%=%-elixir-docker)
  232. define gen-docker-target
  233. $1-docker: $(COMMON_DEPS)
  234. @$(BUILD) $1 docker
  235. endef
  236. ALL_DOCKERS = $(REL_PROFILES) $(REL_PROFILES:%=%-elixir)
  237. $(foreach zt,$(ALL_DOCKERS),$(eval $(call gen-docker-target,$(zt))))
  238. .PHONY:
  239. merge-config:
  240. @$(SCRIPTS)/merge-config.escript
  241. ## elixir target is to create release packages using Elixir's Mix
  242. .PHONY: $(REL_PROFILES:%=%-elixir) $(PKG_PROFILES:%=%-elixir)
  243. $(REL_PROFILES:%=%-elixir) $(PKG_PROFILES:%=%-elixir): $(COMMON_DEPS)
  244. @env IS_ELIXIR=yes $(BUILD) $(subst -elixir,,$(@)) elixir
  245. .PHONY: $(REL_PROFILES:%=%-elixir-pkg)
  246. define gen-elixir-pkg-target
  247. # the Elixir places the tar in a different path than Rebar3
  248. $1-elixir-pkg: $(COMMON_DEPS)
  249. @env TAR_PKG_DIR=_build/$1-pkg \
  250. IS_ELIXIR=yes \
  251. $(BUILD) $1-pkg pkg
  252. endef
  253. $(foreach pt,$(REL_PROFILES),$(eval $(call gen-elixir-pkg-target,$(pt))))
  254. .PHONY: $(REL_PROFILES:%=%-elixir-tgz)
  255. define gen-elixir-tgz-target
  256. $1-elixir-tgz: $(COMMON_DEPS)
  257. @env IS_ELIXIR=yes $(BUILD) $1 tgz
  258. endef
  259. ALL_ELIXIR_TGZS = $(REL_PROFILES)
  260. $(foreach tt,$(ALL_ELIXIR_TGZS),$(eval $(call gen-elixir-tgz-target,$(tt))))
  261. .PHONY: fmt
  262. fmt: $(REBAR)
  263. @find . \( -name '*.app.src' -o \
  264. -name '*.erl' -o \
  265. -name '*.hrl' -o \
  266. -name 'rebar.config' -o \
  267. -name '*.eterm' -o \
  268. -name '*.escript' \) \
  269. -not -path '*/_build/*' \
  270. -not -path '*/deps/*' \
  271. -not -path '*/_checkouts/*' \
  272. -type f \
  273. | xargs $(SCRIPTS)/erlfmt -w
  274. @$(SCRIPTS)/erlfmt -w 'apps/emqx/rebar.config.script'
  275. @$(SCRIPTS)/erlfmt -w 'elvis.config'
  276. @$(SCRIPTS)/erlfmt -w 'bin/nodetool'
  277. @mix format
  278. .PHONY: fmt-diff
  279. fmt-diff:
  280. @env ERLFMT_WRITE=true ./scripts/git-hook-pre-commit.sh
  281. .PHONY: clean-test-cluster-config
  282. clean-test-cluster-config:
  283. @rm -f apps/emqx_conf/data/configs/cluster.hocon || true
  284. .PHONY: spellcheck
  285. spellcheck:
  286. ./scripts/spellcheck/spellcheck.sh _build/docgen/$(PROFILE)/schema-en.json
  287. .PHONY: nothing
  288. nothing:
  289. @: