Use Erlang.mk's native Elixir support for CLI

This avoids using Mix while compiling which simplifies
a number of things and let us do further build improvements
later on.

Elixir is only enabled from within rabbitmq_cli currently.

Eunit is disabled since there are only Elixir tests.

Dialyzer will force-enable Elixir in order to process
Elixir-compiled beam files.

This commit also includes a few changes that are
related:

 * The Erlang distribution will now be started for parallel-ct

 * Many unnecessary PROJECT_MOD lines have been removed

 * `eunit_formatters` has been removed, it provides little value

 * The new `maybe_flock` Erlang.mk function is used where possible

 * Build test deps when testing rabbitmq_cli (Mix won't do it anymore)

 * rabbitmq_ct_helpers now use the early plugins to have Dialyzer
   properly set up

(cherry picked from commit c5d150a7ef)
This commit is contained in:
Loïc Hoguin 2024-12-12 12:08:06 +01:00 committed by Mergify
parent 2ea40e05b3
commit f101e8a212
36 changed files with 1091 additions and 4111 deletions

106
Makefile
View File

@ -31,10 +31,6 @@ DISABLE_DISTCLEAN = 1
ifeq ($(filter-out xref,$(MAKECMDGOALS)),)
XREF_SCOPE = app deps
# We add all the applications that are in non-standard paths
# so they are included in the analyses as well.
XREF_EXTRA_APP_DIRS = $(filter-out deps/rabbitmq_cli/_build/dev/lib/rabbit_common/,$(wildcard deps/rabbitmq_cli/_build/dev/lib/*/)) deps/rabbitmq_prelaunch/
# For Elixir protocols the right fix is to include the consolidated/
# folders in addition to ebin/. However this creates conflicts because
# some modules are duplicated. So instead we ignore warnings from
@ -49,10 +45,6 @@ XREF_IGNORE = [ \
xref: ERL_LIBS := $(ERL_LIBS):$(CURDIR)/apps:$(CURDIR)/deps:$(dir $(shell elixir --eval ':io.format "~s~n", [:code.lib_dir :elixir ]'))
endif
ifneq ($(wildcard deps/.hex/cache.erl),)
deps:: restore-hex-cache-ets-file
endif
include rabbitmq-components.mk
# Set PROJECT_VERSION, calculated in rabbitmq-components.mk,
@ -84,54 +76,6 @@ ifdef PLUGINS
RABBITMQ_ENABLED_PLUGINS ?= $(call comma_list,$(PLUGINS))
endif
# --------------------------------------------------------------------
# Mix Hex cache management.
# --------------------------------------------------------------------
# We restore the initial Hex cache.ets file from an Erlang term created
# at the time the source archive was prepared.
#
# See the `$(SOURCE_DIST)` recipe for the reason behind this step.
restore-hex-cache-ets-file: deps/.hex/cache.ets
deps/.hex/cache.ets: deps/.hex/cache.erl
$(gen_verbose) $(call erlang,$(call restore_hex_cache_from_erl_term,$<,$@))
define restore_hex_cache_from_erl_term
In = "$(1)",
Out = "$(2)",
{ok, [Props, Entries]} = file:consult(In),
Name = proplists:get_value(name, Props),
Type = proplists:get_value(type, Props),
Access = proplists:get_value(protection, Props),
NamedTable = proplists:get_bool(named_table, Props),
Keypos = proplists:get_value(keypos, Props),
Heir = proplists:get_value(heir, Props),
ReadConc = proplists:get_bool(read_concurrency, Props),
WriteConc = proplists:get_bool(write_concurrency, Props),
Compressed = proplists:get_bool(compressed, Props),
Options0 = [
Type,
Access,
{keypos, Keypos},
{heir, Heir},
{read_concurrency, ReadConc},
{write_concurrency, WriteConc}],
Options1 = case NamedTable of
true -> [named_table | Options0];
false -> Options0
end,
Options2 = case Compressed of
true -> [compressed | Options0];
false -> Options0
end,
Tab = ets:new(Name, Options2),
[true = ets:insert(Tab, Entry) || Entry <- Entries],
ok = ets:tab2file(Tab, Out),
init:stop().
endef
# --------------------------------------------------------------------
# Distribution - common variables and generic functions.
# --------------------------------------------------------------------
@ -263,14 +207,6 @@ $(1): $(ERLANG_MK_RECURSIVE_DEPS_LIST)
sed -E -i.bak "s|^[[:blank:]]*include[[:blank:]]+\.\./.*erlang.mk$$$$|include ../../erlang.mk|" \
$$@/deps/$$$$(basename $$$$dep)/Makefile && \
rm $$@/deps/$$$$(basename $$$$dep)/Makefile.bak; \
mix_exs=$$@/deps/$$$$(basename $$$$dep)/mix.exs; \
if test -f $$$$mix_exs; then \
(cd $$$$(dirname "$$$$mix_exs") && \
(test -d $$@/deps/.hex || env DEPS_DIR=$$@/deps MIX_HOME=$$@/deps/.mix HEX_HOME=$$@/deps/.hex MIX_ENV=prod FILL_HEX_CACHE=yes mix local.hex --force) && \
env DEPS_DIR=$$@/deps MIX_HOME=$$@/deps/.mix HEX_HOME=$$@/deps/.hex MIX_ENV=prod FILL_HEX_CACHE=yes mix deps.get --only prod && \
cp $(CURDIR)/mk/rabbitmq-mix.mk . && \
rm -rf _build deps); \
fi; \
if test -f "$$$$dep/license_info"; then \
cp "$$$$dep/license_info" "$$@/deps/licensing/license_info_$$$$(basename $$$$dep)"; \
cat "$$$$dep/license_info" >> $$@/LICENSE; \
@ -295,7 +231,6 @@ $(1): $(ERLANG_MK_RECURSIVE_DEPS_LIST)
done
$${verbose} echo "PLUGINS := $(PLUGINS)" > $$@/plugins.mk
$${verbose} sort -r < "$$@.git-times.txt" | head -n 1 > "$$@.git-time.txt"
$${verbose} $$(call erlang,$$(call dump_hex_cache_to_erl_term,$$(call core_native_path,$$@),$$(call core_native_path,$$@.git-time.txt)))
$${verbose} find $$@ -print0 | xargs -0 touch -t "$$$$(cat $$@.git-time.txt)"
$${verbose} rm "$$@.git-times.txt" "$$@.git-time.txt"
@ -337,47 +272,6 @@ clean-$(1):
clean:: clean-$(1)
endef
# Mix Hex component requires a cache file, otherwise it refuses to build
# offline... That cache is an ETS table with all the applications we
# depend on, plus some versioning informations and checksums. There
# are two problems with that: the table contains a date (`last_update`
# field) and `ets:tab2file()` produces a different file each time it's
# called.
#
# To make our source archive reproducible, we fix the time of the
# `last_update` field to the last Git commit and dump the content of the
# table as an Erlang term to a text file.
#
# The ETS file must be recreated before compiling RabbitMQ. See the
# `restore-hex-cache-ets-file` Make target.
define dump_hex_cache_to_erl_term
In = "$(1)/deps/.hex/cache.ets",
Out = "$(1)/deps/.hex/cache.erl",
{ok, DateStr} = file:read_file("$(2)"),
{match, Date} = re:run(DateStr,
"^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})\.([0-9]{2})",
[{capture, all_but_first, list}]),
[Year, Month, Day, Hour, Min, Sec] = [erlang:list_to_integer(V) || V <- Date],
{ok, Tab} = ets:file2tab(In),
true = ets:insert(Tab, {last_update, {{Year, Month, Day}, {Hour, Min, Sec}}}),
Props = [
Prop
|| {Key, _} = Prop <- ets:info(Tab),
Key =:= name orelse
Key =:= type orelse
Key =:= protection orelse
Key =:= named_table orelse
Key =:= keypos orelse
Key =:= heir orelse
Key =:= read_concurrency orelse
Key =:= write_concurrency orelse
Key =:= compressed],
Entries = ets:tab2list(Tab),
ok = file:write_file(Out, io_lib:format("~w.~n~w.~n", [Props, Entries])),
ok = file:delete(In),
init:stop().
endef
# --------------------------------------------------------------------
# Distribution - public targets
# --------------------------------------------------------------------

View File

@ -1,6 +1,5 @@
PROJECT = amqp10_client
PROJECT_DESCRIPTION = AMQP 1.0 client
PROJECT_MOD = amqp10_client_app
define PROJECT_APP_EXTRA_KEYS
%% Hex.pm package informations.

View File

@ -1,6 +1,5 @@
PROJECT = oauth2_client
PROJECT_DESCRIPTION = OAuth2 client from the RabbitMQ Project
PROJECT_MOD = oauth2_client_app
BUILD_DEPS = rabbit
DEPS = rabbit_common jose
@ -12,5 +11,8 @@ PLT_APPS = rabbit
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk
# Required to properly autopatch jose.
ELIXIR = system
include rabbitmq-components.mk
include erlang.mk

View File

@ -328,6 +328,7 @@ tpl_parallel_ct_test_spec_set_$1 = $$(call tpl_parallel_ct_test_spec,$(PARALLEL_
parallel-ct-set-$(1): test-build
$(verbose) mkdir -p $(CT_LOGS_DIR)
$(verbose) $$(call core_render,tpl_parallel_ct_test_spec_set_$(1),ct.set-$(1).spec)
$$(eval ERL := erl -noinput -boot no_dot_erlang)
$$(call erlang,$$(call ct_master.erl,ct.set-$(1).spec),-sname parallel_ct_$(PROJECT)@localhost -hidden -kernel net_ticktime 5)
endef
@ -337,6 +338,7 @@ $(foreach set,1 2 3 4,$(eval $(call parallel_ct_set_target,$(set))))
parallel-ct: test-build
$(verbose) mkdir -p $(CT_LOGS_DIR)
$(eval ERL := erl -noinput -boot no_dot_erlang)
$(call erlang,$(call ct_master.erl,ct.test.spec),-sname parallel_ct_$(PROJECT)@localhost -hidden -kernel net_ticktime 5)
# --------------------------------------------------------------------

View File

@ -1880,6 +1880,7 @@ determine_persist_to(Msg,
%% via the direct client), we make a guess based on the number of
%% headers.
%% @todo We can probably simplify this.
{MetaSize, _BodySize} = mc:size(Msg),
case BodySize >= IndexMaxSize of
true -> msg_store;

View File

@ -12,7 +12,7 @@ ifneq ($(filter rabbitmq_cli,$(BUILD_DEPS) $(DEPS)),)
# Add the CLI ebin directory to the code path for the compiler: plugin
# CLI extensions may access behaviour modules defined in this directory.
RMQ_ERLC_OPTS += -pa $(DEPS_DIR)/rabbitmq_cli/_build/dev/lib/rabbitmqctl/ebin
RMQ_ERLC_OPTS += -pa $(DEPS_DIR)/rabbitmq_cli/ebin
endif
RMQ_ERLC_OPTS += +deterministic

View File

@ -3,7 +3,6 @@
DIST_DIR ?= $(CURDIR)/plugins
CLI_SCRIPTS_DIR ?= $(CURDIR)/sbin
CLI_ESCRIPTS_DIR ?= $(CURDIR)/escript
MIX = echo y | mix
# Set $(DIST_AS_EZS) to a non-empty value to enable the packaging of
# plugins as .ez archives.
@ -81,17 +80,13 @@ endef
# Real entry point: it tests the existence of an .app file to determine
# if it is an Erlang application (and therefore if it should be provided
# as an .ez plugin archive) and calls do_ez_target_erlangmk. If instead
# it finds a Mix configuration file, it is skipped, as the only elixir
# applications in the directory are used by rabbitmq_cli and compiled
# with it.
# as an .ez plugin archive) and calls do_ez_target_erlangmk.
#
# $(call ez_target,path_to_app)
define ez_target
dist_$(1)_appdir = $(2)
dist_$(1)_appfile = $$(dist_$(1)_appdir)/ebin/$(1).app
dist_$(1)_mixfile = $$(dist_$(1)_appdir)/mix.exs
$$(if $$(shell test -f $$(dist_$(1)_appfile) && echo OK), \
$$(eval $$(call do_ez_target_erlangmk,$(1),$$(call get_app_version,$$(dist_$(1)_appfile)),$$(dist_$(1)_appdir))))
@ -117,9 +112,8 @@ endif
endif
# The actual recipe to create the .ez plugin archive. Some variables
# are defined in the do_ez_target_erlangmk and do_ez_target_mix macros
# above. All .ez archives are also listed in this do_ez_target_erlangmk
# and do_ez_target_mix macros.
# are defined in the do_ez_target_erlangmk macro
# above. All .ez archives are also listed in this macro.
RSYNC ?= rsync
RSYNC_V_0 =
@ -200,7 +194,7 @@ test-dist:: $(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST) test-build
$(MAYBE_APPS_LIST)"; \
fi
DIST_EZS = $(ERLANGMK_DIST_EZS) $(MIX_DIST_EZS)
DIST_EZS = $(ERLANGMK_DIST_EZS)
do-dist:: $(DIST_EZS)
$(verbose) unwanted='$(filter-out $(DIST_EZS) $(EXTRA_DIST_EZS), \
@ -223,43 +217,21 @@ endif
install-cli: install-cli-scripts install-cli-escripts
@:
install-cli-scripts:
install-cli-scripts: | $(CLI_SCRIPTS_DIR)
$(gen_verbose) \
set -e; \
test -d "$(DEPS_DIR)/rabbit/scripts"; \
if command -v flock >/dev/null; then \
flock $(CLI_SCRIPTS_LOCK) \
sh -e -c 'mkdir -p "$(CLI_SCRIPTS_DIR)" && \
cp -a $(DEPS_DIR)/rabbit/scripts/* $(CLI_SCRIPTS_DIR)/'; \
elif command -v lockf >/dev/null; then \
lockf $(CLI_SCRIPTS_LOCK) \
sh -e -c 'mkdir -p "$(CLI_SCRIPTS_DIR)" && \
cp -a $(DEPS_DIR)/rabbit/scripts/* $(CLI_SCRIPTS_DIR)/'; \
else \
mkdir -p "$(CLI_SCRIPTS_DIR)" && \
cp -a $(DEPS_DIR)/rabbit/scripts/* $(CLI_SCRIPTS_DIR)/; \
fi
$(call maybe_flock,$(CLI_SCRIPTS_LOCK), \
cp -a $(DEPS_DIR)/rabbit/scripts/* $(CLI_SCRIPTS_DIR)/)
install-cli-escripts:
$(gen_verbose) \
if command -v flock >/dev/null; then \
flock $(CLI_ESCRIPTS_LOCK) \
sh -c 'mkdir -p "$(CLI_ESCRIPTS_DIR)" && \
install-cli-escripts: | $(CLI_ESCRIPTS_DIR)
$(gen_verbose) $(call maybe_flock,$(CLI_ESCRIPTS_LOCK), \
$(MAKE) -C "$(DEPS_DIR)/rabbitmq_cli" install \
PREFIX="$(abspath $(CLI_ESCRIPTS_DIR))" \
DESTDIR='; \
elif command -v lockf >/dev/null; then \
lockf $(CLI_ESCRIPTS_LOCK) \
sh -c 'mkdir -p "$(CLI_ESCRIPTS_DIR)" && \
$(MAKE) -C "$(DEPS_DIR)/rabbitmq_cli" install \
PREFIX="$(abspath $(CLI_ESCRIPTS_DIR))" \
DESTDIR='; \
else \
mkdir -p "$(CLI_ESCRIPTS_DIR)" && \
$(MAKE) -C "$(DEPS_DIR)/rabbitmq_cli" install \
PREFIX="$(abspath $(CLI_ESCRIPTS_DIR))" \
DESTDIR= ; \
fi
DESTDIR= IS_DEP=1)
$(CLI_SCRIPTS_DIR) $(CLI_ESCRIPTS_DIR):
$(verbose) mkdir -p $@
clean-dist::
$(gen_verbose) rm -rf \

View File

@ -4,7 +4,8 @@
DIALYZER_OPTS ?= -Werror_handling -Wunmatched_returns -Wunknown
dialyze: ERL_LIBS = $(APPS_DIR):$(DEPS_DIR):$(DEPS_DIR)/rabbitmq_cli/_build/dev/lib:$(dir $(shell elixir --eval ':io.format "~s~n", [:code.lib_dir :elixir ]'))
dialyze: ELIXIR_LIBS = $(dir $(shell readlink -f `which elixir`))/../lib
dialyze: ERL_LIBS = $(APPS_DIR):$(DEPS_DIR):$(ELIXIR_LIBS)
# --------------------------------------------------------------------
# Common Test flags.

View File

@ -19,7 +19,7 @@ endef
DEPS = rabbit_common rabbit
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers
PLT_APPS += rabbitmqctl
PLT_APPS += rabbitmq_cli
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk

View File

@ -10,7 +10,7 @@ BUILD_DEPS = rabbit_common rabbitmq_cli
DEPS = rabbit cowlib jose base64url oauth2_client
TEST_DEPS = cowboy rabbitmq_web_dispatch rabbitmq_ct_helpers rabbitmq_ct_client_helpers amqp_client rabbitmq_web_mqtt emqtt rabbitmq_amqp_client
PLT_APPS += rabbitmqctl
PLT_APPS += rabbitmq_cli
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk
@ -19,5 +19,8 @@ dep_base64url = hex 1.0.1
dep_emqtt = git https://github.com/emqx/emqtt.git 1.11.0
# Required to properly autopatch jose.
ELIXIR = system
include ../../rabbitmq-components.mk
include ../../erlang.mk

View File

@ -1,6 +1,5 @@
PROJECT = rabbitmq_aws
PROJECT_DESCRIPTION = A minimalistic AWS API interface used by rabbitmq-autocluster (3.6.x) and other RabbitMQ plugins
PROJECT_MOD = rabbitmq_aws_app
PROJECT_REGISTERED = rabbitmq_aws
define PROJECT_ENV

View File

@ -1,7 +1,21 @@
PROJECT = rabbitmq_cli
PROJECT = rabbitmqctl
define PROJECT_ENV
[{scopes, #{
rabbitmqctl => ctl,
'rabbitmq-diagnostics' => diagnostics,
'rabbitmq-plugins' => plugins,
'rabbitmq-queues' => queues,
'rabbitmq-streams' => streams,
'rabbitmq-upgrade' => upgrade,
'vmware-rabbitmq' => vmware
}}]
endef
BUILD_DEPS = rabbit_common
DEPS = csv json stdout_formatter
LOCAL_DEPS = elixir
TEST_DEPS = amqp amqp_client temp x509 rabbit
dep_amqp = hex 3.3.0
@ -16,6 +30,11 @@ DEP_PLUGINS = rabbit_common/mk/rabbitmq-build.mk
VERBOSE_TEST ?= true
MAX_CASES ?= 1
# Force enable Elixir in this project since
# this is an Elixir application.
ELIXIR = system
# We are still using Mix for testing.
MIX_TEST_OPTS ?= ""
MIX_TEST = ERL_COMPILER_OPTIONS=deterministic MIX_ENV=test mix do compile --warnings-as-errors, test --max-cases=$(MAX_CASES) --warnings-as-errors
@ -27,34 +46,37 @@ ifeq ($(VERBOSE_TEST),true)
MIX_TEST := $(MIX_TEST) --trace
endif
EUNIT = disable
export MAKE
ESCRIPT_NAME = Elixir.RabbitMQCtl
ESCRIPT_FILE = escript/rabbitmqctl
.DEFAULT_GOAL = $(ESCRIPT_FILE)
escript::
$(verbose) mkdir -p escript/
include ../../rabbitmq-components.mk
include ../../erlang.mk
# rabbitmq-mix.mk is generated during the creation of the RabbitMQ
# source archive. It sets some environment variables to allow
# rabbitmq_cli to build offline, using the bundled sources only.
-include rabbitmq-mix.mk
$(ESCRIPT_FILE): $(EX_FILES)
$(verbose) $(MAKE) escript
ESCRIPT_EMU_ARGS += -hidden
escript-zip::
$(verbose) $(ESCRIPT_ZIP) $(ESCRIPT_ZIP_FILE) $(ELIXIR_LIBS)/*
ACTUAL_ESCRIPTS = escript/rabbitmqctl
LINKED_ESCRIPTS = escript/rabbitmq-plugins \
escript/rabbitmq-diagnostics \
escript/rabbitmq-queues \
escript/rabbitmq-streams \
escript/vmware-rabbitmq \
escript/rabbitmq-upgrade
ESCRIPTS = $(ACTUAL_ESCRIPTS) $(LINKED_ESCRIPTS)
escript/rabbitmq-diagnostics \
escript/rabbitmq-queues \
escript/rabbitmq-streams \
escript/vmware-rabbitmq \
escript/rabbitmq-upgrade
# Record the build and link dependency: the target files are linked to
# their first dependency.
rabbitmq-plugins = escript/rabbitmqctl
rabbitmq-diagnostics = escript/rabbitmqctl
rabbitmq-queues = escript/rabbitmqctl
rabbitmq-streams = escript/rabbitmqctl
rabbitmq-upgrade = escript/rabbitmqctl
vmware-rabbitmq = escript/rabbitmqctl
escript/rabbitmq-plugins escript/rabbitmq-diagnostics escript/rabbitmq-queues escript/rabbitmq-streams escript/rabbitmq-upgrade escript/vmware-rabbitmq: escript/rabbitmqctl
escript:: $(LINKED_ESCRIPTS)
# We use hardlinks or symlinks in the `escript` directory and
# install's PREFIX when a single escript can have several names (eg.
@ -76,17 +98,9 @@ else
link_escript = ln -f "$(dir $(2))$(notdir $(1))" "$(2)"
endif
app:: $(ESCRIPTS)
@:
rabbitmqctl_srcs := mix.exs \
$(call core_find,config/,*.exs) \
$(call core_find,lib/,*.ex)
# Elixir dependencies are fetched and compiled as part of the alias
# `mix make_all`. We do not fetch and build them in `make deps` because
# mix(1) startup time is quite high. Thus we prefer to run it once, even
# though it kind of breaks the Erlang.mk model.
# Erlang.mk will fetch dependencies as it now has native Elixir support.
# However we are still using Mix for tests and this means Mix will fetch
# test dependencies.
#
# We write `y` on mix stdin because it asks approval to install Hex if
# it's missing. Another way to do it is to use `mix local.hex` but it
@ -100,24 +114,15 @@ rabbitmqctl_srcs := mix.exs \
# we do to create the source archive, and we must do the same here,
# otherwise mix(1) complains about missing dependencies (the non-prod
# ones).
$(ACTUAL_ESCRIPTS): $(rabbitmqctl_srcs)
$(gen_verbose) if test -d ../.hex; then \
echo y | ERL_COMPILER_OPTIONS=deterministic mix make_all_in_src_archive; \
else \
echo y | ERL_COMPILER_OPTIONS=deterministic mix make_all; \
fi
$(LINKED_ESCRIPTS):
$(LINKED_ESCRIPTS): $(ESCRIPT_FILE)
$(verbose) rm -f "$@"
$(gen_verbose) $(call link_escript,$<,$@)
rel:: $(ESCRIPTS)
@:
tests:: $(ESCRIPTS)
tests:: escript test-deps
$(verbose) $(MAKE) -C ../../ install-cli
$(verbose) $(MAKE) -C ../../ start-background-broker \
PLUGINS="rabbit rabbitmq_federation rabbitmq_stomp rabbitmq_stream_management amqp_client" \
PLUGINS="rabbitmq_federation rabbitmq_stomp rabbitmq_stream_management amqp_client" \
$(if $(filter khepri,$(RABBITMQ_METADATA_STORE)),,RABBITMQ_FEATURE_FLAGS="-khepri_db")
$(gen_verbose) $(MIX_TEST) \
$(if $(RABBITMQ_METADATA_STORE),--exclude $(filter-out $(RABBITMQ_METADATA_STORE),khepri mnesia),) \
@ -128,26 +133,26 @@ tests:: $(ESCRIPTS)
.PHONY: test
test:: $(ESCRIPTS)
test:: escript test-deps
ifdef TEST_FILE
$(gen_verbose) $(MIX_TEST) $(TEST_FILE)
else
$(verbose) echo "TEST_FILE must be set, e.g. TEST_FILE=./test/ctl" 1>&2; false
endif
dialyzer:: $(ESCRIPTS)
dialyzer:: escript
MIX_ENV=test mix dialyzer
.PHONY: install
install: $(ESCRIPTS)
install: $(ESCRIPT_FILE)
ifdef PREFIX
$(gen_verbose) mkdir -p "$(DESTDIR)$(PREFIX)"
$(verbose) $(foreach script,$(ACTUAL_ESCRIPTS), \
cmp -s "$(script)" "$(DESTDIR)$(PREFIX)/$(notdir $(script))" || \
cp "$(script)" "$(DESTDIR)$(PREFIX)/$(notdir $(script))";)
$(verbose) \
cmp -s "$(ESCRIPT_FILE)" "$(DESTDIR)$(PREFIX)/$(notdir $(ESCRIPT_FILE))" || \
cp "$(ESCRIPT_FILE)" "$(DESTDIR)$(PREFIX)/$(notdir $(ESCRIPT_FILE))"
$(verbose) $(foreach script,$(LINKED_ESCRIPTS), \
$(call link_escript,$($(notdir $(script))),$(DESTDIR)$(PREFIX)/$(notdir $(script)));)
$(call link_escript,$(ESCRIPT_FILE),$(DESTDIR)$(PREFIX)/$(notdir $(script)));)
else
$(verbose) echo "You must specify a PREFIX" 1>&2; false
endif
@ -155,7 +160,7 @@ endif
clean:: clean-mix
clean-mix:
$(gen_verbose) rm -f $(ESCRIPTS)
$(gen_verbose) rm -f $(ESCRIPT_FILE) $(LINKED_ESCRIPTS)
$(verbose) echo y | mix clean
format:

View File

@ -96,7 +96,7 @@ end
# Elixir 1.15 compiler optimizations require that we explicitly
# add the csv code path
true = Code.append_path(Path.join(["_build", Atom.to_string(Mix.env()), "lib", "csv", "ebin"]))
true = Code.append_path(Path.join(["..", "csv", "ebin"]))
defimpl CSV.Encode, for: PID do
def encode(pid, env \\ []) do

View File

@ -25,7 +25,18 @@ defmodule RabbitMQCtl do
@type command_result() :: {:error, ExitCodes.exit_code(), term()} | term()
@spec main(list()) :: no_return()
def main(["--auto-complete" | []]) do
def main(cmd0) do
{:ok, _} = :application.ensure_all_started(:elixir)
cmd = Enum.map(cmd0, &List.to_string/1)
System.argv(cmd)
:application.set_env(:logger, :level, :warning, [{:persistent, true}])
:application.set_env(:logger, :console, [{:device, :standard_error}], [{:persistent, true}])
{:ok, _} = :application.ensure_all_started(:rabbitmqctl)
Kernel.CLI.run(fn _ -> RabbitMQCtl.main1(cmd) end)
end
@spec main1(list()) :: no_return()
def main1(["--auto-complete" | []]) do
# silence Erlang/OTP's standard library warnings, it's acceptable for CLI tools,
# see rabbitmq/rabbitmq-server#8912
_ = :logger.set_primary_config(:level, :error)
@ -33,7 +44,7 @@ defmodule RabbitMQCtl do
handle_shutdown(:ok)
end
def main(unparsed_command) do
def main1(unparsed_command) do
# silence Erlang/OTP's standard library warnings, it's acceptable for CLI tools,
# see rabbitmq/rabbitmq-server#8912
_ = :logger.set_primary_config(:level, :error)

View File

@ -20,8 +20,8 @@ defmodule RabbitMQCtl.MixfileBase do
path: "escript/rabbitmqctl"
],
prune_code_paths: false,
elixirc_options: [ignore_module_conflict: true],
deps: deps(Mix.env()),
aliases: aliases(),
xref: [
exclude: [
CSV,
@ -142,6 +142,7 @@ defmodule RabbitMQCtl.MixfileBase do
fake_cmd = "true"
is_bazel = System.get_env("IS_BAZEL") != nil
# Note that normal deps will be fetched by Erlang.mk on build.
[
{
:json,
@ -196,29 +197,4 @@ defmodule RabbitMQCtl.MixfileBase do
[]
end
end
defp aliases do
[
make_deps: [
"deps.get",
"deps.compile"
],
make_app: [
"compile",
"escript.build"
],
make_all: [
"deps.get",
"deps.compile",
"compile",
"escript.build"
],
make_all_in_src_archive: [
"deps.get --only prod",
"deps.compile",
"compile",
"escript.build"
]
]
end
end

View File

@ -499,7 +499,7 @@ defmodule TestHelper do
end
def error_check(cmd_line, code) do
assert catch_exit(RabbitMQCtl.main(cmd_line)) == {:shutdown, code}
assert catch_exit(RabbitMQCtl.main1(cmd_line)) == {:shutdown, code}
end
def with_channel(vhost, fun) do

View File

@ -8,7 +8,7 @@ endef
DEPS = rabbit_common rabbit khepri khepri_mnesia_migration
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers amqp_client rabbitmq_amqp_client
PLT_APPS += mnesia rabbitmqctl
PLT_APPS += mnesia rabbitmq_cli
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk

View File

@ -16,8 +16,7 @@ XREF_IGNORE = [ \
dep_inet_tcp_proxy = git https://github.com/rabbitmq/inet_tcp_proxy master
# As this is a helper application we don't need other plugins;
# however we can run a test broker in the test suites.
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk
include ../../rabbitmq-components.mk

View File

@ -342,7 +342,7 @@ maybe_rabbit_srcdir(Config) ->
ensure_application_srcdir(Config, App, Module) ->
ensure_application_srcdir(Config, App, erlang, Module).
ensure_application_srcdir(Config, App, Lang, Module) ->
ensure_application_srcdir(Config, App, _Lang, Module) ->
AppS = atom_to_list(App),
Key = list_to_atom(AppS ++ "_srcdir"),
SecondaryKey = list_to_atom("secondary_" ++ AppS ++ "_srcdir"),
@ -351,18 +351,10 @@ ensure_application_srcdir(Config, App, Lang, Module) ->
case code:which(Module) of
non_existing ->
filename:join(?config(erlang_mk_depsdir, Config), AppS);
P when Lang =:= erlang ->
P ->
%% P is $SRCDIR/ebin/$MODULE.beam.
filename:dirname(
filename:dirname(P));
P when Lang =:= elixir ->
%% P is $SRCDIR/_build/$MIX_ENV/lib/$APP/ebin/$MODULE.beam.
filename:dirname(
filename:dirname(
filename:dirname(
filename:dirname(
filename:dirname(
filename:dirname(P))))))
filename:dirname(P))
end;
P ->
P
@ -500,9 +492,8 @@ new_script_location(Config, Script) ->
ensure_rabbitmqctl_app(Config) ->
SrcDir = ?config(rabbitmq_cli_srcdir, Config),
MixEnv = os:getenv("MIX_ENV", "dev"),
EbinDir = filename:join(
[SrcDir, "_build", MixEnv, "lib", "rabbitmqctl", "ebin"]),
[SrcDir, "ebin"]),
case filelib:is_file(filename:join(EbinDir, "rabbitmqctl.app")) of
true ->
true = code:add_path(EbinDir),
@ -513,11 +504,11 @@ ensure_rabbitmqctl_app(Config) ->
Config;
{error, _} ->
{skip, "Access to rabbitmq_cli ebin dir. required, " ++
"please build rabbitmq_cli and set MIX_ENV"}
"please build rabbitmq_cli"}
end;
false ->
{skip, "Access to rabbitmq_cli ebin dir. required, " ++
"please build rabbitmq_cli and set MIX_ENV"}
"please build rabbitmq_cli"}
end.
load_rabbitmqctl_app(Config) ->

View File

@ -16,7 +16,7 @@ endef
DEPS = rabbit_common rabbit amqp_client
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers
PLT_APPS += rabbitmqctl
PLT_APPS += rabbitmq_cli
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk

View File

@ -7,7 +7,7 @@ define PROJECT_APP_EXTRA_KEYS
endef
DEPS = rabbit_common rabbit rabbitmq_federation rabbitmq_prometheus
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers eunit_formatters
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk

View File

@ -21,7 +21,7 @@ DEPS = rabbit_common rabbit rabbitmq_web_dispatch
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers
LOCAL_DEPS += xmerl ranch ssl crypto public_key
PLT_APPS += rabbitmqctl
PLT_APPS += rabbitmq_cli
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk

View File

@ -45,7 +45,7 @@ LOCAL_DEPS = ssl
DEPS = ranch rabbit amqp10_common
TEST_DEPS = cowlib emqtt ct_helper rabbitmq_ct_helpers rabbitmq_ct_client_helpers rabbitmq_management amqp_client rabbitmq_consistent_hash_exchange rabbitmq_amqp_client rabbitmq_stomp rabbitmq_stream rabbitmq_federation
PLT_APPS += rabbitmqctl elixir
PLT_APPS += rabbitmq_cli elixir
dep_ct_helper = git https://github.com/extend/ct_helper.git master
dep_emqtt = git https://github.com/emqx/emqtt.git 1.11.0
@ -144,6 +144,7 @@ tpl_parallel_ct_test_spec_set_$1 = $$(call tpl_parallel_ct_test_spec,$(PARALLEL_
parallel-ct-set-$(1): test-build
$(verbose) mkdir -p $(CT_LOGS_DIR)
$(verbose) $$(call core_render,tpl_parallel_ct_test_spec_set_$(1),ct.set-$(1).spec)
$$(eval ERL := erl -noinput -boot no_dot_erlang)
$$(call erlang,$$(call ct_master.erl,ct.set-$(1).spec),-sname parallel_ct_$(PROJECT)@localhost -hidden -kernel net_ticktime 5)
endef

View File

@ -1,6 +1,5 @@
PROJECT = rabbitmq_peer_discovery_consul
PROJECT_DESCRIPTION = Consult-based RabbitMQ peer discovery backend
PROJECT_MOD = rabbitmq_peer_discovery_consul_app
DEPS = rabbit_common rabbitmq_peer_discovery_common rabbit
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers ct_helper meck

View File

@ -1,6 +1,5 @@
PROJECT = rabbitmq_peer_discovery_etcd
PROJECT_DESCRIPTION = etcd-based RabbitMQ peer discovery backend
PROJECT_MOD = rabbitmq_peer_discovery_etcd_app
DEPS = rabbit_common rabbitmq_peer_discovery_common rabbit eetcd gun
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers ct_helper meck

View File

@ -1,6 +1,5 @@
PROJECT = rabbitmq_peer_discovery_k8s
PROJECT_DESCRIPTION = Kubernetes-based RabbitMQ peer discovery backend
PROJECT_MOD = rabbitmq_peer_discovery_k8s_app
DEPS = rabbit_common rabbitmq_peer_discovery_common rabbit
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers meck

View File

@ -11,9 +11,7 @@ PROJECT_DESCRIPTION = Prometheus metrics for RabbitMQ
PROJECT_MOD := rabbit_prometheus_app
DEPS = accept cowboy rabbit rabbitmq_management_agent prometheus rabbitmq_web_dispatch
BUILD_DEPS = amqp_client rabbit_common rabbitmq_management
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers eunit_formatters rabbitmq_stream
EUNIT_OPTS = no_tty, {report, {eunit_progress, [colored, profile]}}
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers rabbitmq_stream
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk

View File

@ -25,7 +25,7 @@ LOCAL_DEPS = crypto
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers rabbitmq_amqp1_0 meck
PLT_APPS += rabbitmqctl
PLT_APPS += rabbitmq_cli
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk elvis_mk

View File

@ -7,7 +7,7 @@ define PROJECT_APP_EXTRA_KEYS
endef
DEPS = rabbit_common rabbit rabbitmq_shovel rabbitmq_prometheus
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers eunit_formatters
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk

View File

@ -33,7 +33,7 @@ endef
DEPS = ranch rabbit_common rabbit amqp_client
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers
PLT_APPS += rabbitmqctl elixir
PLT_APPS += rabbitmq_cli elixir
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk

View File

@ -25,7 +25,7 @@ LOCAL_DEPS = ssl
DEPS = rabbit rabbitmq_stream_common osiris ranch
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers amqp_client amqp10_client
PLT_APPS += rabbitmqctl elixir
PLT_APPS += rabbitmq_cli elixir
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk

View File

@ -1,6 +1,5 @@
PROJECT = rabbitmq_stream_management
PROJECT_DESCRIPTION = RabbitMQ Stream Management
PROJECT_MOD = rabbit_stream_management
define PROJECT_ENV
[

View File

@ -21,7 +21,7 @@ LOCAL_DEPS = ssl
DEPS = rabbit cowboy rabbitmq_mqtt
TEST_DEPS = emqtt rabbitmq_ct_helpers rabbitmq_ct_client_helpers rabbitmq_management rabbitmq_stomp rabbitmq_consistent_hash_exchange
PLT_APPS += rabbitmqctl elixir cowlib
PLT_APPS += rabbitmq_cli elixir cowlib
# FIXME: Add Ranch as a BUILD_DEPS to be sure the correct version is picked.
# See rabbitmq-components.mk.

4784
erlang.mk vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +0,0 @@
# This file is copied to rabbitmq_cli (and possibly other Elixir-based
# components) when the RabbitMQ source archive is created, to allow
# those Elixir applications to build even with no access to Hex.pm,
# using the bundled sources only.
HEX_OFFLINE := 1
# mix(1) centralizes its data in `$MIX_HOME`. When unset, it defaults
# to something under `$XDG_DATA_HOME`/`$XDG_CONFIG_HOME` or `$HOME`
# depending on the Elixir version.
#
# We store those data for offline build in `$(DEPS_DIR)`.
override MIX_HOME := $(DEPS_DIR)/.mix
# In addition to `$MIX_HOME`, we still have to set `$HEX_HOME` which is used to
# find `~/.hex` where the Hex.pm cache and packages are stored.
override HEX_HOME := $(DEPS_DIR)/.hex
export HEX_OFFLINE MIX_HOME HEX_HOME

View File

@ -44,11 +44,8 @@ dist:
# Umbrella. Those manpages are copied to www.rabbitmq.com
#
# We explicitely set $HOME as a Make variable below because some package
# builders do that, as part of cleaning the build environment. It
# exercises our hack to convince mix(1) to work offline because that
# hack depends on `$HOME`. A Make variable on the command line takes
# precedence over variables declared in Makefiles, so our hack needs
# to consider this. We do the same with the Freedesktop.org-specified
# builders do that, as part of cleaning the build environment.
# We do the same with the Freedesktop.org-specified
# variables ($XDG_*_HOME).
$(MAKE) -C $(SOURCE_DIR) \
HOME="$(HOME)" \