diff --git a/Makefile b/Makefile index 785458601..9316fede1 100644 --- a/Makefile +++ b/Makefile @@ -159,6 +159,10 @@ compile: $(PROFILES:%=compile-%) $(PROFILES:%=compile-%): @$(BUILD) $(@:compile-%=%) apps +.PHONY: $(PROFILES:%=compile-%-elixir) +$(PROFILES:%=compile-%-elixir): + @env IS_ELIXIR=yes $(BUILD) $(@:compile-%-elixir=%) apps + ## Not calling rebar3 clean because ## 1. rebar3 clean relies on rebar3, meaning it reads config, fetches dependencies etc. ## 2. it's slow diff --git a/build b/build index 7fd171402..0115cbb63 100755 --- a/build +++ b/build @@ -145,6 +145,16 @@ just_compile() { make_docs } +just_compile_elixir() { + ./scripts/pre-compile.sh "$PROFILE" + rm -f rebar.lock + # shellcheck disable=SC1010 + env MIX_ENV="$PROFILE" mix do local.hex --if-missing --force, \ + local.rebar rebar3 "${PWD}/rebar3" --if-missing --force, \ + deps.get + env MIX_ENV="$PROFILE" mix compile +} + make_rel() { local release_or_tar="${1}" just_compile @@ -395,7 +405,11 @@ log "building artifact=$ARTIFACT for profile=$PROFILE" case "$ARTIFACT" in apps) - just_compile + if [ "${IS_ELIXIR:-}" = "yes" ]; then + just_compile_elixir + else + just_compile + fi ;; doc|docs) make_docs diff --git a/dev b/dev index 5087cc30f..6a20c4a2d 100755 --- a/dev +++ b/dev @@ -2,6 +2,10 @@ set -euo pipefail +if [ -n "${DEBUG:-}" ]; then + set -x +fi + UNAME="$(uname -s)" PROJ_ROOT="$(git rev-parse --show-toplevel)" @@ -123,6 +127,14 @@ case "${PROFILE}" in ee|emqx-enterprise) PROFILE='emqx-enterprise' ;; + ce-ex|emqx-elixir) + export IS_ELIXIR=yes + PROFILE='emqx' + ;; + ee-ex|emqx-enterprise-elixir) + export IS_ELIXIR=yes + PROFILE='emqx-enterprise' + ;; *) echo "Unknown profile $PROFILE" exit 1 @@ -131,10 +143,10 @@ esac export PROFILE case "${PROFILE}" in - emqx) + emqx|emqx-elixir) export SCHEMA_MOD='emqx_conf_schema' ;; - emqx-enterprise) + emqx-enterprise|emqx-enterprise-elixir) export SCHEMA_MOD='emqx_enterprise_schema' ;; esac @@ -177,6 +189,17 @@ prepare_erl_libs() { erl_libs="${app}" fi done + if [ "${IS_ELIXIR:-}" = "yes" ]; then + local elixir_libs_root_dir + elixir_libs_root_dir=$(realpath "$(elixir -e ':code.lib_dir(:elixir) |> IO.puts()')"/..) + for app in "${elixir_libs_root_dir}"/*; do + if [ -n "$erl_libs" ]; then + erl_libs="${erl_libs}${sep}${app}" + else + erl_libs="${app}" + fi + done + fi export ERL_LIBS="$erl_libs" } @@ -342,21 +365,45 @@ boot() { append_args_file APPS="$(apps_to_load)" - BOOT_SEQUENCE=" - Apps=[${APPS}], - ok=lists:foreach(fun application:load/1, Apps), - io:format(user, \"~nLoaded: ~p~n\", [Apps]), - {ok, _} = application:ensure_all_started(emqx_machine). - " + if [ "${IS_ELIXIR:-}" = "yes" ]; then + BOOT_SEQUENCE=' + apps = System.get_env("APPS") |> String.split(",") |> Enum.map(&String.to_atom/1) + Enum.each(apps, &Application.load/1) + IO.inspect(apps, label: :loaded, limit: :infinity) + {:ok, _} = Application.ensure_all_started(:emqx_machine) + ' + if [ -n "${EPMD_ARGS:-}" ]; then + EPMD_ARGS_ELIXIR="--erl $EPMD_ARGS" + else + EPMD_ARGS_ELIXIR="" + fi - # shellcheck disable=SC2086 - erl -name "$EMQX_NODE_NAME" \ - $EPMD_ARGS \ - -proto_dist ekka \ - -args_file "$ARGS_FILE" \ - -config "$CONF_FILE" \ - -s emqx_restricted_shell set_prompt_func \ - -eval "$BOOT_SEQUENCE" + # shellcheck disable=SC2086 + env APPS="$APPS" iex \ + --name "$EMQX_NODE_NAME" \ + $EPMD_ARGS_ELIXIR \ + --erl '-user Elixir.IEx.CLI' \ + --erl '-proto_dist ekka' \ + --vm-args "$ARGS_FILE" \ + --erl-config "$CONF_FILE" \ + -e "$BOOT_SEQUENCE" + else + BOOT_SEQUENCE=" + Apps=[${APPS}], + ok=lists:foreach(fun application:load/1, Apps), + io:format(user, \"~nLoaded: ~p~n\", [Apps]), + {ok, _} = application:ensure_all_started(emqx_machine). + " + + # shellcheck disable=SC2086 + erl -name "$EMQX_NODE_NAME" \ + $EPMD_ARGS \ + -proto_dist ekka \ + -args_file "$ARGS_FILE" \ + -config "$CONF_FILE" \ + -s emqx_restricted_shell set_prompt_func \ + -eval "$BOOT_SEQUENCE" + fi } # Generate a random id