Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Native elixir #1020

Draft
wants to merge 38 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
fe9837b
Implement 'hex' for erlang.mk
artman41 May 12, 2023
530f669
Get modules from Elixir compiler
essen Dec 3, 2024
823207d
Resolve recompile issues, merge app_file, and delete a bunch
essen Dec 5, 2024
bdee475
More
essen Dec 5, 2024
7340500
Obvious fixes
essen Dec 6, 2024
60ed0f7
Restore optional usage of Elixir as dep
essen Dec 6, 2024
da5f16e
More cleanup
essen Dec 6, 2024
41a9b86
Missed one
essen Dec 6, 2024
9df18e4
Don't need this I think
essen Dec 6, 2024
544e712
Make Elixir autopatch -j compatible
essen Dec 9, 2024
330ad83
Fix autopatch
essen Dec 9, 2024
e8ceee4
Debug
essen Dec 9, 2024
524511e
Debug
essen Dec 9, 2024
5bc07e5
Debug
essen Dec 9, 2024
f21d95f
Debug
essen Dec 9, 2024
71e23fa
Debug
essen Dec 9, 2024
c5b753a
Debug
essen Dec 9, 2024
3933501
Debug
essen Dec 9, 2024
60fbc0f
Debug
essen Dec 9, 2024
560e8a8
Debug end?
essen Dec 9, 2024
08aba48
Fix the failing LEGACY=1 test
essen Dec 9, 2024
ca7a777
Rework tests
essen Dec 10, 2024
91636d9
Install libsodium in CI when needed
essen Dec 10, 2024
84e4044
Debug
essen Dec 10, 2024
56360f7
Debug
essen Dec 10, 2024
81934da
Fix more concurrency issues?
essen Dec 10, 2024
1c281a6
Try again
essen Dec 10, 2024
95e6cdf
Put it back
essen Dec 10, 2024
09cee52
Move things around
essen Dec 10, 2024
8df75ed
Rework Mix autopatch and fix another concurrency issue
essen Dec 11, 2024
12f1987
Don't handle elixir specially if it's the only dep
essen Dec 11, 2024
bfa73c4
Resolve ELIXIR_LIBS only once - it's slow
essen Dec 12, 2024
6be6f4d
Don't FULL=1 when building escripts
essen Dec 12, 2024
cd0efb9
Fix escript again
essen Dec 12, 2024
8d4112f
More improvements including better escript building
essen Dec 13, 2024
91e552d
Probably good changes
essen Dec 13, 2024
ef04797
More improvements and fixes
essen Dec 16, 2024
fa90971
Fix default PROJECT_MOD
essen Dec 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ jobs:
matrix:
erlang:
- '27'
elixir:
- '1.17'
os:
# - macos-latest
- ubuntu-latest
Expand All @@ -31,6 +33,7 @@ jobs:
- core-compat
# Trick GH runners into picking this slower job early.
- ACME=1 c=core-deps
- core-elixir
- core-makedep
- core-misc
- core-plugins
Expand Down Expand Up @@ -78,6 +81,7 @@ jobs:
uses: erlef/setup-beam@v1
with:
otp-version: ${{ matrix.erlang }}
elixir-version: ${{ matrix.elixir }}
version-type: loose

- name: Setup MSYS2 (Windows)
Expand All @@ -94,6 +98,10 @@ jobs:
gnu-netcat
diffutils

- name: Install libsodium (Linux, Elixir)
if: matrix.os == 'ubuntu-latest' && matrix.suite == 'core-elixir'
run: sudo apt-get -y install libsodium-dev

- name: Run tests (Linux)
if: matrix.os == 'ubuntu-latest'
run: make check c=${{ matrix.suite }} -j4 -k ${{ matrix.extra }}
Expand Down Expand Up @@ -143,7 +151,7 @@ jobs:
uses: erlef/setup-beam@v1
with:
otp-version: ${{ matrix.erlang }}
elixir-version: 1.17
elixir-version: '1.17'
version-type: loose

- name: Setup MSYS2 (Windows)
Expand Down
1 change: 1 addition & 0 deletions build.config
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ core/deps
# Core modules, continued.
core/beam-cache
core/erlc
core/elixir
core/docs
core/rel
core/test
Expand Down
2 changes: 1 addition & 1 deletion core/core.mk
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ PROJECT ?= $(notdir $(CURDIR))
PROJECT := $(strip $(PROJECT))

PROJECT_VERSION ?= rolling
PROJECT_MOD ?= $(PROJECT)_app
PROJECT_MOD ?=
PROJECT_ENV ?= []

# Verbosity.
Expand Down
4 changes: 1 addition & 3 deletions core/deps-tools.mk
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ endif
ifeq ($(IS_APP)$(IS_DEP),)
$(verbose) sort < $(ERLANG_MK_RECURSIVE_TMP_LIST) | \
uniq > $(ERLANG_MK_RECURSIVE_TMP_LIST).sorted
$(verbose) cmp -s $(ERLANG_MK_RECURSIVE_TMP_LIST).sorted $@ \
|| mv $(ERLANG_MK_RECURSIVE_TMP_LIST).sorted $@
$(verbose) rm -f $(ERLANG_MK_RECURSIVE_TMP_LIST).sorted
$(verbose) mv $(ERLANG_MK_RECURSIVE_TMP_LIST).sorted $@
$(verbose) rm $(ERLANG_MK_RECURSIVE_TMP_LIST)
endif
endif # ifneq ($(SKIP_DEPS),)
Expand Down
154 changes: 105 additions & 49 deletions core/deps.mk
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ dep_name = $(call query_name,$(1))
# Application directories.

LOCAL_DEPS_DIRS = $(foreach a,$(LOCAL_DEPS),$(if $(wildcard $(APPS_DIR)/$a),$(APPS_DIR)/$a))
# Elixir is handled specially as it must be built before all other deps
# when Mix autopatching is necessary.
ALL_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(foreach dep,$(filter-out $(IGNORE_DEPS),$(BUILD_DEPS) $(DEPS)),$(call query_name,$(dep))))

# When we are calling an app directly we don't want to include it here
Expand Down Expand Up @@ -210,9 +212,11 @@ endif
ifneq ($(SKIP_DEPS),)
deps::
else
deps:: $(ALL_DEPS_DIRS) apps clean-tmp-deps.log | $(ERLANG_MK_TMP)
ifneq ($(ALL_DEPS_DIRS),)
$(verbose) set -e; for dep in $(ALL_DEPS_DIRS); do \
ALL_DEPS_DIRS_TO_BUILD = $(if $(filter-out $(DEPS_DIR)/elixir,$(ALL_DEPS_DIRS)),$(filter-out $(DEPS_DIR)/elixir,$(ALL_DEPS_DIRS)),$(ALL_DEPS_DIRS))

deps:: $(ALL_DEPS_DIRS_TO_BUILD) apps clean-tmp-deps.log | $(ERLANG_MK_TMP)
ifneq ($(ALL_DEPS_DIRS_TO_BUILD),)
$(verbose) set -e; for dep in $(ALL_DEPS_DIRS_TO_BUILD); do \
if grep -qs ^$$dep$$ $(ERLANG_MK_TMP)/deps.log; then \
:; \
else \
Expand All @@ -236,34 +240,41 @@ endif

# Deps related targets.

# @todo rename GNUmakefile and makefile into Makefile first, if they exist
# While Makefile file could be GNUmakefile or makefile,
# in practice only Makefile is needed so far.
define dep_autopatch
autopatch_verbose_0 = @echo " PATCH " $(subst autopatch-,,$@) "(method: $(AUTOPATCH_METHOD))";
autopatch_verbose_2 = set -x;
autopatch_verbose = $(autopatch_verbose_$(V))

define dep_autopatch_detect
if [ -f $(DEPS_DIR)/$1/erlang.mk ]; then \
rm -rf $(DEPS_DIR)/$1/ebin/; \
$(call erlang,$(call dep_autopatch_appsrc.erl,$1)); \
$(call dep_autopatch_erlang_mk,$1); \
echo erlang.mk; \
elif [ -f $(DEPS_DIR)/$1/mix.exs -a -d $(DEPS_DIR)/$1/lib ]; then \
echo mix; \
elif [ -f $(DEPS_DIR)/$1/Makefile ]; then \
if [ -f $(DEPS_DIR)/$1/rebar.lock ]; then \
$(call dep_autopatch2,$1); \
elif [ 0 != `grep -c "include ../\w*\.mk" $(DEPS_DIR)/$1/Makefile` ]; then \
$(call dep_autopatch2,$1); \
elif [ 0 != `grep -ci "^[^#].*rebar" $(DEPS_DIR)/$1/Makefile` ]; then \
$(call dep_autopatch2,$1); \
elif [ -n "`find $(DEPS_DIR)/$1/ -type f -name \*.mk -not -name erlang.mk -exec grep -i "^[^#].*rebar" '{}' \;`" ]; then \
$(call dep_autopatch2,$1); \
fi \
else \
if [ ! -d $(DEPS_DIR)/$1/src/ ]; then \
$(call dep_autopatch_noop,$1); \
echo rebar3; \
elif [ 0 != \`grep -c "include ../\w*\.mk" $(DEPS_DIR)/$1/Makefile\` ]; then \
echo rebar3; \
elif [ 0 != \`grep -ci "^[^#].*rebar" $(DEPS_DIR)/$1/Makefile\` ]; then \
echo rebar3; \
elif [ -n "\`find $(DEPS_DIR)/$1/ -type f -name \*.mk -not -name erlang.mk -exec grep -i "^[^#].*rebar" '{}' \;\`" ]; then \
echo rebar3; \
else \
$(call dep_autopatch2,$1); \
echo noop; \
fi \
elif [ ! -d $(DEPS_DIR)/$1/src/ ]; then \
echo noop; \
else \
echo rebar3; \
fi
endef

define dep_autopatch2
define dep_autopatch_for_erlang.mk
rm -rf $(DEPS_DIR)/$1/ebin/; \
$(call erlang,$(call dep_autopatch_appsrc.erl,$1)); \
$(call dep_autopatch_erlang_mk,$1)
endef

define dep_autopatch_for_rebar3
! test -f $(DEPS_DIR)/$1/ebin/$1.app || \
mv -n $(DEPS_DIR)/$1/ebin/$1.app $(DEPS_DIR)/$1/src/$1.app.src; \
rm -f $(DEPS_DIR)/$1/ebin/$1.app; \
Expand All @@ -279,8 +290,22 @@ define dep_autopatch2
fi
endef

define dep_autopatch_noop
printf "noop:\n" > $(DEPS_DIR)/$1/Makefile
define dep_autopatch_for_mix
$(call dep_autopatch_mix,$1)
endef

define dep_autopatch_for_noop
test -f $(DEPS_DIR)/$1/Makefile || printf "noop:\n" > $(DEPS_DIR)/$1/Makefile
endef

define maybe_flock
if command -v flock >/dev/null; then \
flock $1 sh -c "$2"; \
elif command -v lockf >/dev/null; then \
lockf $1 sh -c "$2"; \
else \
$2; \
fi
endef

# Replace "include erlang.mk" with a line that will load the parent Erlang.mk
Expand All @@ -307,13 +332,7 @@ endef

# We use flock/lockf when available to avoid concurrency issues.
define dep_autopatch_fetch_rebar
if command -v flock >/dev/null; then \
flock $(ERLANG_MK_TMP)/rebar.lock sh -c "$(call dep_autopatch_fetch_rebar2)"; \
elif command -v lockf >/dev/null; then \
lockf $(ERLANG_MK_TMP)/rebar.lock sh -c "$(call dep_autopatch_fetch_rebar2)"; \
else \
$(call dep_autopatch_fetch_rebar2); \
fi
$(call maybe_flock,$(ERLANG_MK_TMP)/rebar.lock,$(call dep_autopatch_fetch_rebar2))
endef

define dep_autopatch_fetch_rebar2
Expand Down Expand Up @@ -397,7 +416,6 @@ define dep_autopatch_rebar.erl
GetHexVsn2 = fun(N, NP) ->
case file:consult("$(call core_native_path,$(DEPS_DIR)/$1/rebar.lock)") of
{ok, Lock} ->
io:format("~p~n", [Lock]),
LockPkgs = case lists:keyfind("1.2.0", 1, Lock) of
{_, LP} ->
LP;
Expand All @@ -411,10 +429,8 @@ define dep_autopatch_rebar.erl
end,
if
is_list(LockPkgs) ->
io:format("~p~n", [LockPkgs]),
case lists:keyfind(atom_to_binary(N, latin1), 1, LockPkgs) of
{_, {pkg, _, Vsn}, _} ->
io:format("~p~n", [Vsn]),
{N, {hex, NP, binary_to_list(Vsn)}};
_ ->
false
Expand Down Expand Up @@ -806,6 +822,37 @@ define hex_get_tarball.erl
end
endef

# Unfortunately this currently requires Elixir.
define hex_version_resolver.erl
HexVersionResolve = fun(Name, Req) ->
application:ensure_all_started(ssl),
application:ensure_all_started(inets),
Config = $(hex_config.erl),
case hex_repo:get_package(Config, atom_to_binary(Name)) of
{ok, {200, _RespHeaders, Package}} ->
#{releases := List} = Package,
{value, #{version := Version}} = lists:search(fun(#{version := Vsn}) ->
M = list_to_atom("Elixir.Version"),
F = list_to_atom("match?"),
M:F(Vsn, Req)
end, List),
{ok, Version};
{ok, {Status, _, Errors}} ->
{error, Status, Errors}
end
end,
HexVersionResolveAndPrint = fun(Name, Req) ->
case HexVersionResolve(Name, Req) of
{ok, Version} ->
io:format("~s", [Version]),
halt(0);
{error, Status, Errors} ->
io:format("Error ~b: ~0p~n", [Status, Errors]),
halt(77)
end
end
endef

ifeq ($(CACHE_DEPS),1)

# Hex only has a package version. No need to look in the Erlang.mk packages.
Expand Down Expand Up @@ -835,7 +882,7 @@ define dep_fetch_fail
endef

define dep_target
$(DEPS_DIR)/$(call query_name,$1): | $(if $(filter hex,$(call query_fetch_method,$1)),hex-core) $(ERLANG_MK_TMP)
$(DEPS_DIR)/$(call query_name,$1): $(if $(filter elixir,$(BUILD_DEPS) $(DEPS)),$(if $(filter-out elixir,$1),$(DEPS_DIR)/elixir/ebin/dep_built)) $(if $(filter hex,$(call query_fetch_method,$1)),$(if $(wildcard $(DEPS_DIR)/$(call query_name,$1)),,$(DEPS_DIR)/hex_core/ebin/dep_built)) | $(ERLANG_MK_TMP)
$(eval DEP_NAME := $(call query_name,$1))
$(eval DEP_STR := $(if $(filter $1,$(DEP_NAME)),$1,"$1 ($(DEP_NAME))"))
$(verbose) if test -d $(APPS_DIR)/$(DEP_NAME); then \
Expand All @@ -854,30 +901,39 @@ $(DEPS_DIR)/$(call query_name,$1): | $(if $(filter hex,$(call query_fetch_method
cd $(DEPS_DIR)/$(DEP_NAME) && ./configure; \
fi
ifeq ($(filter $1,$(NO_AUTOPATCH)),)
$(verbose) $$(MAKE) --no-print-directory autopatch-$(DEP_NAME)
$(verbose) $$(MAKE) --no-print-directory autopatch-$(DEP_NAME) AUTOPATCH_METHOD=`$(call dep_autopatch_detect,$1)`
endif

.PHONY: autopatch-$(call query_name,$1)

ifeq ($1,elixir)
autopatch-elixir::
ln -s lib/elixir/ebin $(DEPS_DIR)/elixir/
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$(verbose)

else
autopatch-$(call query_name,$1)::
$(verbose) if [ "$1" = "elixir" -a "$(ELIXIR_PATCH)" ]; then \
ln -s lib/elixir/ebin $(DEPS_DIR)/elixir/; \
else \
$$(call dep_autopatch,$(call query_name,$1)) \
fi
$$(autopatch_verbose) $$(call dep_autopatch_for_$(AUTOPATCH_METHOD),$(call query_name,$1))
endif
endef

# We automatically depend on hex_core when the project isn't already.
$(if $(filter hex_core,$(DEPS) $(BUILD_DEPS) $(DOC_DEPS) $(REL_DEPS) $(TEST_DEPS)),,\
$(eval $(call dep_target,hex_core)))

.PHONY: hex-core

hex-core: $(DEPS_DIR)/hex_core
$(verbose) if [ ! -e $(DEPS_DIR)/hex_core/ebin/dep_built ]; then \
$(MAKE) -C $(DEPS_DIR)/hex_core IS_DEP=1; \
touch $(DEPS_DIR)/hex_core/ebin/dep_built; \
fi
$(DEPS_DIR)/hex_core/ebin/dep_built: | $(ERLANG_MK_TMP)
$(verbose) $(call maybe_flock,$(ERLANG_MK_TMP)/hex_core.lock,\
if [ ! -e $(DEPS_DIR)/hex_core/ebin/dep_built ]; then \
$(MAKE) $(DEPS_DIR)/hex_core; \
$(MAKE) -C $(DEPS_DIR)/hex_core IS_DEP=1; \
touch $(DEPS_DIR)/hex_core/ebin/dep_built; \
fi)

$(DEPS_DIR)/elixir/ebin/dep_built: | $(ERLANG_MK_TMP)
$(verbose) $(call maybe_flock,$(ERLANG_MK_TMP)/elixir.lock,\
if [ ! -e $(DEPS_DIR)/elixir/ebin/dep_built ]; then \
$(MAKE) $(DEPS_DIR)/elixir; \
$(MAKE) -C $(DEPS_DIR)/elixir; \
touch $(DEPS_DIR)/elixir/ebin/dep_built; \
fi)

$(foreach dep,$(BUILD_DEPS) $(DEPS),$(eval $(call dep_target,$(dep))))

Expand Down
Loading
Loading