-
Notifications
You must be signed in to change notification settings - Fork 35
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
erlang.mk bug #50
Comments
Perhaps switching to rebar3 (or even Elixir's |
Found a verbosity switch: ╰─➤ V=2 make escript-zip
erlang.mk:30: Please upgrade to GNU Make 4 or later: https://erlang.mk/guide/installation.html
set -x; rm -f /home/username/tools/Gradualizer/.erlang.mk/deps.log
+ rm -f /home/username/tools/Gradualizer/.erlang.mk/deps.log
set -x; rm -f /home/username/tools/Gradualizer/.erlang.mk/apps.log
+ rm -f /home/username/tools/Gradualizer/.erlang.mk/apps.log
set -x; mkdir -p /home/username/tools/Gradualizer/.erlang.mk
+ mkdir -p /home/username/tools/Gradualizer/.erlang.mk
set -x; set -e; for dep in ; do \
mkdir -p $dep/ebin; \
done
+ set -e
set -x; set -e; for dep in ; do \
if grep -qs ^$dep$ /home/username/tools/Gradualizer/.erlang.mk/apps.log; then \
:; \
else \
echo $dep >> /home/username/tools/Gradualizer/.erlang.mk/apps.log; \
make -C $dep IS_APP=1; \
fi \
done
+ set -e
set -x; mkdir -p /home/username/tools/Gradualizer/.erlang.mk
+ mkdir -p /home/username/tools/Gradualizer/.erlang.mk
set -x; set -e; for dep in ; do \
if grep -qs ^$dep$ /home/username/tools/Gradualizer/.erlang.mk/deps.log; then \
:; \
else \
echo $dep >> /home/username/tools/Gradualizer/.erlang.mk/deps.log; \
if [ -f $dep/GNUmakefile ] || [ -f $dep/makefile ] || [ -f $dep/Makefile ]; then \
make -C $dep IS_DEP=1; \
else \
echo "Error: No Makefile to build dependency $dep." >&2; \
exit 2; \
fi \
fi \
done
+ set -e
set -x; erl +A0 -noinput -boot start_clean -pz /home/username/tools/Gradualizer/.erlang.mk/rebar/ebin -eval " E = ets:new(makedep, [bag]), G = digraph:new([acyclic]), ErlFiles = lists:usort(string:tokens(\"src/absform.erl src/constraints.erl src/gradualizer.erl src/gradualizer_cli.erl src/gradualizer_db.erl src/gradualizer_file_utils.erl src/gradualizer_lib.erl src/rebar_prv_gradualizer.erl src/ty.erl src/typechecker.erl src/typelib.erl \", \" \")), DepsDir = \"/home/username/tools/Gradualizer/deps\", AppsDir = \"/home/username/tools/Gradualizer/apps\", DepsDirsSrc = \"\", DepsDirsInc = \"\", AppsDirsSrc = \"\", AppsDirsInc = \"\", DepsDirs = lists:usort(string:tokens(DepsDirsSrc++DepsDirsInc, \" \")), AppsDirs = lists:usort(string:tokens(AppsDirsSrc++AppsDirsInc, \" \")), Modules = [{list_to_atom(filename:basename(F, \".erl\")), F} || F <- ErlFiles], Add = fun (Mod, Dep) -> case lists:keyfind(Dep, 1, Modules) of false -> ok; {_, DepFile} -> {_, ModFile} = lists:keyfind(Mod, 1, Modules), ets:insert(E, {ModFile, DepFile}), digraph:add_vertex(G, Mod), digraph:add_vertex(G, Dep), digraph:add_edge(G, Mod, Dep) end end, AddHd = fun (F, Mod, DepFile) -> case file:open(DepFile, [read]) of {error, enoent} -> ok; {ok, Fd} -> {_, ModFile} = lists:keyfind(Mod, 1, Modules), case ets:match(E, {ModFile, DepFile}) of [] -> ets:insert(E, {ModFile, DepFile}), F(F, Fd, Mod,0); _ -> ok end end end, SearchHrl = fun F(_Hrl, []) -> {error,enoent}; F(Hrl, [Dir|Dirs]) -> HrlF = filename:join([Dir,Hrl]), case filelib:is_file(HrlF) of true -> {ok, HrlF}; false -> F(Hrl,Dirs) end end, Attr = fun (_F, Mod, behavior, Dep) -> Add(Mod, Dep); (_F, Mod, behaviour, Dep) -> Add(Mod, Dep); (_F, Mod, compile, {parse_transform, Dep}) -> Add(Mod, Dep); (_F, Mod, compile, Opts) when is_list(Opts) -> case proplists:get_value(parse_transform, Opts) of undefined -> ok; Dep -> Add(Mod, Dep) end; (F, Mod, include, Hrl) -> case SearchHrl(Hrl, [\"src\", \"include\",AppsDir,DepsDir]++AppsDirs++DepsDirs) of {ok, FoundHrl} -> AddHd(F, Mod, FoundHrl); {error, _} -> false end; (F, Mod, include_lib, Hrl) -> case SearchHrl(Hrl, [\"src\", \"include\",AppsDir,DepsDir]++AppsDirs++DepsDirs) of {ok, FoundHrl} -> AddHd(F, Mod, FoundHrl); {error, _} -> false end; (F, Mod, import, {Imp, _}) -> IsFile = case lists:keyfind(Imp, 1, Modules) of false -> false; {_, FilePath} -> filelib:is_file(FilePath) end, case IsFile of false -> ok; true -> Add(Mod, Imp) end; (_, _, _, _) -> ok end, MakeDepend = fun (F, Fd, Mod, StartLocation) -> {ok, Filename} = file:pid2name(Fd), case io:parse_erl_form(Fd, undefined, StartLocation) of {ok, AbsData, EndLocation} -> case AbsData of {attribute, _, Key, Value} -> Attr(F, Mod, Key, Value), F(F, Fd, Mod, EndLocation); _ -> F(F, Fd, Mod, EndLocation) end; {eof, _ } -> file:close(Fd); {error, ErrorDescription } -> file:close(Fd); {error, ErrorInfo, ErrorLocation} -> F(F, Fd, Mod, ErrorLocation) end, ok end, [begin Mod = list_to_atom(filename:basename(F, \".erl\")), {ok, Fd} = file:open(F, [read]), MakeDepend(MakeDepend, Fd, Mod,0) end || F <- ErlFiles], Depend = sofs:to_external(sofs:relation_to_family(sofs:relation(ets:tab2list(E)))), CompileFirst = [X || X <- lists:reverse(digraph_utils:topsort(G)), [] =/= digraph:in_neighbours(G, X)], TargetPath = fun(Target) -> case lists:keyfind(Target, 1, Modules) of false -> \"\"; {_, DepFile} -> DirSubname = tl(string:tokens(filename:dirname(DepFile), \"/\")), string:join(DirSubname ++ [atom_to_list(Target)], \"/\") end end, ok = file:write_file(\"gradualizer.d\", [ [[F, \"::\", [[\" \", D] || D <- Deps], \"; @touch \$@\n\"] || {F, Deps} <- Depend], \"\nCOMPILE_FIRST +=\", [[\" \", TargetPath(CF)] || CF <- CompileFirst], \"\n\" ]), halt()" -- erlang.mk
+ erl +A0 -noinput -boot start_clean -pz /home/username/tools/Gradualizer/.erlang.mk/rebar/ebin -eval ' E = ets:new(makedep, [bag]), G = digraph:new([acyclic]), ErlFiles = lists:usort(string:tokens("src/absform.erl src/constraints.erl src/gradualizer.erl src/gradualizer_cli.erl src/gradualizer_db.erl src/gradualizer_file_utils.erl src/gradualizer_lib.erl src/rebar_prv_gradualizer.erl src/ty.erl src/typechecker.erl src/typelib.erl ", " ")), DepsDir = "/home/username/tools/Gradualizer/deps", AppsDir = "/home/username/tools/Gradualizer/apps", DepsDirsSrc = "", DepsDirsInc = "", AppsDirsSrc = "", AppsDirsInc = "", DepsDirs = lists:usort(string:tokens(DepsDirsSrc++DepsDirsInc, " ")), AppsDirs = lists:usort(string:tokens(AppsDirsSrc++AppsDirsInc, " ")),Modules = [{list_to_atom(filename:basename(F, ".erl")), F} || F <- ErlFiles], Add = fun (Mod, Dep) -> case lists:keyfind(Dep, 1, Modules) of false -> ok; {_, DepFile} -> {_, ModFile} = lists:keyfind(Mod, 1, Modules), ets:insert(E, {ModFile, DepFile}), digraph:add_vertex(G, Mod), digraph:add_vertex(G, Dep), digraph:add_edge(G, Mod, Dep) end end, AddHd = fun (F, Mod, DepFile) -> case file:open(DepFile, [read]) of {error, enoent} -> ok; {ok, Fd} -> {_, ModFile} = lists:keyfind(Mod, 1, Modules), case ets:match(E, {ModFile, DepFile}) of [] -> ets:insert(E, {ModFile, DepFile}), F(F, Fd, Mod,0); _ -> ok end end end, SearchHrl = fun F(_Hrl, []) -> {error,enoent}; F(Hrl, [Dir|Dirs]) -> HrlF = filename:join([Dir,Hrl]), case filelib:is_file(HrlF) of true -> {ok, HrlF}; false -> F(Hrl,Dirs) end end, Attr = fun (_F, Mod, behavior, Dep) -> Add(Mod, Dep); (_F, Mod, behaviour, Dep) -> Add(Mod, Dep); (_F, Mod, compile, {parse_transform, Dep}) -> Add(Mod, Dep); (_F, Mod, compile, Opts) when is_list(Opts) -> case proplists:get_value(parse_transform, Opts) of undefined -> ok; Dep -> Add(Mod, Dep) end; (F, Mod, include, Hrl) -> case SearchHrl(Hrl, ["src", "include",AppsDir,DepsDir]++AppsDirs++DepsDirs) of {ok, FoundHrl} -> AddHd(F, Mod, FoundHrl); {error, _} -> false end; (F, Mod, include_lib, Hrl) -> case SearchHrl(Hrl, ["src", "include",AppsDir,DepsDir]++AppsDirs++DepsDirs) of {ok, FoundHrl} -> AddHd(F, Mod, FoundHrl); {error, _} -> false end; (F, Mod, import, {Imp, _}) -> IsFile = case lists:keyfind(Imp, 1, Modules) of false -> false; {_, FilePath} -> filelib:is_file(FilePath) end, case IsFile of false -> ok; true -> Add(Mod, Imp) end; (_, _, _, _) -> ok end, MakeDepend = fun (F, Fd, Mod, StartLocation) -> {ok, Filename} = file:pid2name(Fd), case io:parse_erl_form(Fd, undefined, StartLocation) of {ok, AbsData, EndLocation} -> case AbsData of {attribute, _, Key, Value} -> Attr(F, Mod, Key, Value), F(F, Fd, Mod, EndLocation); _ -> F(F, Fd, Mod, EndLocation) end; {eof, _ } -> file:close(Fd); {error, ErrorDescription } -> file:close(Fd); {error, ErrorInfo, ErrorLocation} -> F(F, Fd, Mod, ErrorLocation) end, ok end, [beginMod = list_to_atom(filename:basename(F, ".erl")), {ok, Fd} = file:open(F, [read]), MakeDepend(MakeDepend, Fd, Mod,0) end || F <- ErlFiles], Depend = sofs:to_external(sofs:relation_to_family(sofs:relation(ets:tab2list(E)))), CompileFirst = [X || X <- lists:reverse(digraph_utils:topsort(G)), [] =/= digraph:in_neighbours(G, X)], TargetPath = fun(Target) -> case lists:keyfind(Target, 1, Modules) of false -> ""; {_, DepFile} -> DirSubname = tl(string:tokens(filename:dirname(DepFile), "/")), string:join(DirSubname ++ [atom_to_list(Target)], "/") end end, ok = file:write_file("gradualizer.d", [ [[F, "::", [[" ", D] || D <- Deps], "; @touch $@\n"] || {F, Deps} <- Depend], "\nCOMPILE_FIRST +=", [[" ", TargetPath(CF)] || CF <- CompileFirst], "\n" ]), halt()' -- erlang.mk
set -x; make --no-print-directory app-build
+ make --no-print-directory app-build
erlang.mk:30: Please upgrade to GNU Make 4 or later: https://erlang.mk/guide/installation.html
set -x; mkdir -p ebin/
+ mkdir -p ebin/
set -x; erlc -v +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard -o ebin/ -pa ebin/ -I include/ src/absform.erl src/constraints.erl src/gradualizer.erl src/gradualizer_cli.erl src/gradualizer_db.erl src/gradualizer_file_utils.erl src/gradualizer_lib.erl src/rebar_prv_gradualizer.erl src/ty.erl src/typechecker.erl src/typelib.erl
+ erlc -v +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard -o ebin/ -pa ebin/ -I include/ src/absform.erl src/constraints.erl src/gradualizer.erl src/gradualizer_cli.erl src/gradualizer_db.erl src/gradualizer_file_utils.erl src/gradualizer_lib.erl src/rebar_prv_gradualizer.erl src/ty.erl src/typechecker.erl src/typelib.erl
src/ty.erl:6: Warning: export_all flag enabled - all functions will be exported
src/typechecker.erl:23: Warning: export_all flag enabled - all functions will be exported
set -x; if [ -z "$(grep -e '^[^%]*{\s*modules\s*,' src/gradualizer.app.src)" ]; then \
echo "Empty modules entry not found in gradualizer.app.src. Please consult the erlang.mk README for instructions." >&2; \
exit 1; \
fi
++ grep -e '^[^%]*{\s*modules\s*,' src/gradualizer.app.src
+ '[' -z ' {modules, []}' ']'
set -x; cat src/gradualizer.app.src \
| sed "s/{[[:space:]]*modules[[:space:]]*,[[:space:]]*\[\]}/{modules, \['absform','constraints','gradualizer','gradualizer_cli','gradualizer_db','gradualizer_file_utils','gradualizer_lib','rebar_prv_gradualizer','ty','typechecker','typelib'\]}/" \
| sed "s/{id,[[:space:]]*\"git\"}/{id, \"\"}/" \
> ebin/gradualizer.app
+ cat src/gradualizer.app.src
+ sed 's/{id,[[:space:]]*"git"}/{id, ""}/'
+ sed 's/{[[:space:]]*modules[[:space:]]*,[[:space:]]*\[\]}/{modules, \['\''absform'\'','\''constraints'\'','\''gradualizer'\'','\''gradualizer_cli'\'','\''gradualizer_db'\'','\''gradualizer_file_utils'\'','\''gradualizer_lib'\'','\''rebar_prv_gradualizer'\'','\''ty'\'','\''typechecker'\'','\''typelib'\''\]}/'
set -x; :
+ :
set -x; mkdir -p ./ ./ ./ ./ ./
+ mkdir -p ./ ./ ./ ./ ./
set -x; rm -f /home/username/tools/Gradualizer/.erlang.mk/escript.zip
+ rm -f /home/username/tools/Gradualizer/.erlang.mk/escript.zip
set -x; cd .. && 7z a -tzip -mx=9 -mtc=off /home/username/tools/Gradualizer/.erlang.mk/escript.zip gradualizer/ebin/*
+ cd ..
+ 7z a -tzip -mx=9 -mtc=off /home/username/tools/Gradualizer/.erlang.mk/escript.zip 'gradualizer/ebin/*'
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,2 CPUs Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz (306F2),ASM,AES-NI)
Scanning the drive:
WARNING: No more files
gradualizer
0 files, 0 bytes
Creating archive: /home/username/tools/Gradualizer/.erlang.mk/escript.zip
Items to compress: 0
Files read from disk: 0
Archive size: 22 bytes (1 KiB)
Scan WARNINGS for files and folders:
gradualizer : No more files
----------------
Scan WARNINGS: 1
make: *** [escript-zip] Error 1 |
Been following the makefile at: And I ran across something interesting. It is going UP out of the directory, then trying to pack PROJECT = gradualizer However, this git repository is named Now, renaming the directory as ╰─➤ make escript
erlang.mk:30: Please upgrade to GNU Make 4 or later: https://erlang.mk/guide/installation.html
erlang.mk:30: Please upgrade to GNU Make 4 or later: https://erlang.mk/guide/installation.html
GEN escript-zip
GEN escript
╰─➤ ls -lah g*
-rwxrwxr-x. 1 username username 144K Oct 11 11:44 gradualizer
-rw-rw-r--. 1 username username 67 Oct 11 11:41 gradualizer.d
╰─➤ ./gradualizer
Usage: gradualizer [options] [PATH...]
A type checker for Erlang/Elixir
PATH Files or directories to type check
-h, --help display this help and exit
-pa, --path-add Add the specified directory to the beginning of
the code path; see erl -pa [string]
--print-file prefix error printouts with the file name the
error is from
--no-print-file inverse of --print-file
- the default behaviour
--stop-on-first-error stop type checking at the first error
--no-stop-on-first-error inverse of --stop-on-first-error
- the default behaviour So it compiled and seems to work. So immediately that means that the erlang.mk file at https://github.com/josefs/Gradualizer/blob/master/erlang.mk is broken because it absolutely should not ever be stepping outside of the repository directory, but a greater question is how does it work for anyone else with a default clone when the repository name is |
erlang.mk:30: Please upgrade to GNU Make 4 or later
@OvermindDL1 I got it to work by changing the name of the directory too. I agree that it's a strange way of doing it. Deciding on a build system is often controversial. What we have now seems to work decently so I don't think people are too keen of changing unless there is a real benefit. |
@gomoripeti, I'd like to hear your take on this. |
Yeah I don't really care what's used as long as it works. Although that |
Actually I don't think this repo could be used like that anyway as Well, a rebar3 or a mix version of the build system would be just a couple of lines as it stands (unlike the rather huge erlang.mk file...), it's fairly simple to compile as-is. |
I would prefer the use of rebar3 in this project, definitely not mix since that creates an unnecessary dependency to Elixir. It should be trivial to use rebar3 for this. Using rebar3 would also get reid of the dependency to 7z that came up when I tried to 'make escript'. |
hello all, I also hit this problem, and renaming the parent dir was the ultimate solution. Strangely enough if I used Anyway I just introduced erlang.mk because the project already used custom make rules, and I've never used erlang.mk before, so it was a good chance to try - rather subjective choice. So I have no objection in converting to rebar3. (To be fair you can look at the |
It sounds like we have a consensus to start to use rebar3 and I don't have any objection to that. Is anyone willing to submit a PR? |
The problem concerns only when used as a dependency for another project, right? It should definitely be possible to use this repo as a dependency for projects using rebar3. Do we even need a rebar config file to make it work? I guess it works already, but if not, we should add a small rebar config file. Has anyone tried? It would be nice however if the Makefile would work as well, when used as a dependency for projects using the erlang.mk dependency way (i.e. download the dependency and run make inside). If possible, it would be nice to not require a dependency to rebar in this case. A simple rule just running erlc would be enough for this. Regardless of build system, how about renaming the repo to lowercase gradualizer? It doesn't hurt that the repo has the same name as the application. When not used as a dependency, I don't mind using rebar, but I think the make file works fine as it is for this. |
No, it happens when you try to build it straight from a fresh git clone into the default named directory on any filesystem that is case-sensitive. Using something like rebar3 'would' make it significantly easier to distribute this via packaging systems like hex as well as using it as a dependency to integrate it into build tools, but that's just a bonus around the overall issue.
As I recall you can include a rebar thunk/wrapper file to just download-and-run, but in general if someone is doing some BEAM language work (erlang/elixir/lfe/alpaca/whatever) then they probably have rebar anyway (and considering windows as well they more likely have rebar3 than make regardless).
This would be an immediate fix and I'm all for it, regardless the erlang.mk file is bugged anyway, but that would at least make clone-and-compile work.
It still prevents windows users from compiling it. Multi-platform is important. |
Actually as Gradualizer has no dependencies it should already work perfectly with rebar3 too (without a rebar.config). So if you are on windows and you don't have
Also this is why Gradualizer works perfectly as a rebar3 dependency/plugin. But I am absolutely not against converting to rebar3 "officially", this mostly consists of updating the README (and removing the huge erlang.mk file) One con of erlang.mk is that I dont think it supports creating a hex package. |
It doesn't? That seems odd considering how well hex dependencies are used in the BEAM world across a variety of languages now. Rebar3 has native support so that would be a definite boon. |
Attempting to run
make escript
on RedHat linux (which is locked tomake
versionGNU Make 3.82
with no alternatives on the main installs), and runningmake escript
gives this:╰─➤ make escript erlang.mk:30: Please upgrade to GNU Make 4 or later: https://erlang.mk/guide/installation.html erlang.mk:30: Please upgrade to GNU Make 4 or later: https://erlang.mk/guide/installation.html GEN escript-zip WARNING: No more files gradualizer make: *** [escript-zip] Error 1
And the supplied link is useless as it says nothing about how to workaround the issue on modern RedHat installs (which regulate what can and cannot be installed).
The text was updated successfully, but these errors were encountered: