mirror of
https://github.com/correl/rebar.git
synced 2024-11-14 19:19:30 +00:00
Overhaul env expansion so that rebar fully expands env refs prior to invoking the shell script. Also now using DRV_* env vars for compilation/linking of files found in c_src; this frees up "normal" CFLAGS/LDFLAGS for usage in sub build scripts.
This commit is contained in:
parent
51133313a6
commit
1f6d861aba
3 changed files with 86 additions and 25 deletions
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
-define(FAIL, throw({error, failed})).
|
-define(FAIL, throw({error, failed})).
|
||||||
|
|
||||||
-define(ABORT(Str, Args), ?ERROR(Str, Args), init:stop(1)).
|
-define(ABORT(Str, Args), rebar_utils:abort(Str, Args)).
|
||||||
|
|
||||||
-define(CONSOLE(Str, Args), io:format(Str, Args)).
|
-define(CONSOLE(Str, Args), io:format(Str, Args)).
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,10 @@
|
||||||
%% CFLAGS - C compiler
|
%% CFLAGS - C compiler
|
||||||
%% CXXFLAGS - C++ compiler
|
%% CXXFLAGS - C++ compiler
|
||||||
%% LDFLAGS - Link flags
|
%% LDFLAGS - Link flags
|
||||||
%% DRIVER_CFLAGS - default -I paths for erts and ei
|
%% ERL_CFLAGS - default -I paths for erts and ei
|
||||||
%% DRIVER_LDFLAGS - default -L and -lerl_interface -lei
|
%% ERL_LDFLAGS - default -L and -lerl_interface -lei
|
||||||
|
%% DRV_CFLAGS - flags that will be used for compiling the driver
|
||||||
|
%% DRV_LDFLAGS - flags that will be used for linking the driver
|
||||||
%%
|
%%
|
||||||
%% Note that if you wish to extend (vs. replace) these variables, you MUST
|
%% Note that if you wish to extend (vs. replace) these variables, you MUST
|
||||||
%% include a shell-style reference in your definition. E.g. to extend CFLAGS,
|
%% include a shell-style reference in your definition. E.g. to extend CFLAGS,
|
||||||
|
@ -80,7 +82,7 @@ compile(Config, AppFile) ->
|
||||||
%% default for this operating system. This enables max flexibility for users.
|
%% default for this operating system. This enables max flexibility for users.
|
||||||
DefaultEnvs = filter_envs(default_env(), []),
|
DefaultEnvs = filter_envs(default_env(), []),
|
||||||
OverrideEnvs = filter_envs(rebar_config:get_list(Config, port_envs, []), []),
|
OverrideEnvs = filter_envs(rebar_config:get_list(Config, port_envs, []), []),
|
||||||
Env = merge_envs(OverrideEnvs, DefaultEnvs),
|
Env = expand_vars_loop(merge_each_var(os_env() ++ DefaultEnvs ++ OverrideEnvs, [])),
|
||||||
|
|
||||||
%% One or more files are available for building. Run the pre-compile hook, if
|
%% One or more files are available for building. Run the pre-compile hook, if
|
||||||
%% necessary.
|
%% necessary.
|
||||||
|
@ -97,7 +99,8 @@ compile(Config, AppFile) ->
|
||||||
case needs_link(SoName, NewBins) of
|
case needs_link(SoName, NewBins) of
|
||||||
true ->
|
true ->
|
||||||
AllBins = string:join(NewBins ++ ExistingBins, " "),
|
AllBins = string:join(NewBins ++ ExistingBins, " "),
|
||||||
rebar_utils:sh_failfast(?FMT("$CC ~s $LDFLAGS $DRIVER_LDFLAGS -o ~s", [AllBins, SoName]), Env);
|
rebar_utils:sh_failfast(?FMT("$CC ~s $LDFLAGS $DRV_LDFLAGS -o ~s",
|
||||||
|
[AllBins, SoName]), Env);
|
||||||
false ->
|
false ->
|
||||||
?INFO("Skipping relink of ~s\n", [SoName]),
|
?INFO("Skipping relink of ~s\n", [SoName]),
|
||||||
ok
|
ok
|
||||||
|
@ -162,9 +165,11 @@ compile_each([Source | Rest], Config, Env, NewBins, ExistingBins) ->
|
||||||
?CONSOLE("Compiling ~s\n", [Source]),
|
?CONSOLE("Compiling ~s\n", [Source]),
|
||||||
case compiler(Ext) of
|
case compiler(Ext) of
|
||||||
"$CC" ->
|
"$CC" ->
|
||||||
rebar_utils:sh_failfast(?FMT("$CC -c $CFLAGS $DRIVER_CFLAGS ~s -o ~s", [Source, Bin]), Env);
|
rebar_utils:sh_failfast(?FMT("$CC -c $CFLAGS $DRV_CFLAGS ~s -o ~s",
|
||||||
|
[Source, Bin]), Env);
|
||||||
"$CXX" ->
|
"$CXX" ->
|
||||||
rebar_utils:sh_failfast(?FMT("$CXX -c $CXXFLAGS $DRIVER_CFLAGS ~s -o ~s", [Source, Bin]), Env)
|
rebar_utils:sh_failfast(?FMT("$CXX -c $CXXFLAGS $DRV_CFLAGS ~s -o ~s",
|
||||||
|
[Source, Bin]), Env)
|
||||||
end,
|
end,
|
||||||
compile_each(Rest, Config, Env, [Bin | NewBins], ExistingBins);
|
compile_each(Rest, Config, Env, [Bin | NewBins], ExistingBins);
|
||||||
|
|
||||||
|
@ -192,13 +197,6 @@ needs_link(SoName, NewBins) ->
|
||||||
MaxLastMod >= Other
|
MaxLastMod >= Other
|
||||||
end.
|
end.
|
||||||
|
|
||||||
merge_envs(OverrideEnvs, DefaultEnvs) ->
|
|
||||||
orddict:merge(fun(Key, Override, Default) ->
|
|
||||||
expand_env_variable(Override, Key, Default)
|
|
||||||
end,
|
|
||||||
orddict:from_list(OverrideEnvs),
|
|
||||||
orddict:from_list(DefaultEnvs)).
|
|
||||||
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
%% Choose a compiler variable, based on a provided extension
|
%% Choose a compiler variable, based on a provided extension
|
||||||
|
@ -213,6 +211,62 @@ compiler(".C") -> "$CXX";
|
||||||
compiler(_) -> "$CC".
|
compiler(_) -> "$CC".
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Given a list of {Key, Value} environment variables, where Key may be defined
|
||||||
|
%% multiple times, walk the list and expand each self-reference so that we
|
||||||
|
%% end with a list of each variable singly-defined.
|
||||||
|
%%
|
||||||
|
merge_each_var([], Vars) ->
|
||||||
|
Vars;
|
||||||
|
merge_each_var([{Key, Value} | Rest], Vars) ->
|
||||||
|
case orddict:find(Key, Vars) of
|
||||||
|
error ->
|
||||||
|
%% Nothing yet defined for this key/value. Expand any self-references
|
||||||
|
%% as blank.
|
||||||
|
Evalue = expand_env_variable(Value, Key, "");
|
||||||
|
{ok, Value0} ->
|
||||||
|
%% Use previous definition in expansion
|
||||||
|
Evalue = expand_env_variable(Value, Key, Value0)
|
||||||
|
end,
|
||||||
|
merge_each_var(Rest, orddict:store(Key, Evalue, Vars)).
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Give a unique list of {Key, Value} environment variables, expand each one
|
||||||
|
%% for every other key until no further expansions are possible.
|
||||||
|
%%
|
||||||
|
expand_vars_loop(Vars) ->
|
||||||
|
expand_vars_loop(Vars, 10).
|
||||||
|
|
||||||
|
expand_vars_loop(Vars0, 0) ->
|
||||||
|
?ABORT("Max. expansion reached for ENV vars!\n", []);
|
||||||
|
expand_vars_loop(Vars0, Count) ->
|
||||||
|
Vars = lists:foldl(fun({Key, Value}, Acc) ->
|
||||||
|
expand_vars(Key, Value, Acc)
|
||||||
|
end,
|
||||||
|
Vars0, Vars0),
|
||||||
|
case orddict:from_list(Vars) of
|
||||||
|
Vars0 ->
|
||||||
|
Vars0;
|
||||||
|
Vars ->
|
||||||
|
expand_vars_loop(Vars, Count-1)
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Expand all OTHER references to a given K/V pair
|
||||||
|
%%
|
||||||
|
expand_vars(Key, Value, Vars) ->
|
||||||
|
lists:foldl(fun({AKey, AValue}, Acc) ->
|
||||||
|
case AKey of
|
||||||
|
Key ->
|
||||||
|
NewValue = AValue;
|
||||||
|
_ ->
|
||||||
|
NewValue = expand_env_variable(AValue, Key, Value)
|
||||||
|
end,
|
||||||
|
[{AKey, NewValue} | Acc]
|
||||||
|
end,
|
||||||
|
[], Vars).
|
||||||
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
%% Given env. variable FOO we want to expand all references to
|
%% Given env. variable FOO we want to expand all references to
|
||||||
%% it in InStr. References can have two forms: $FOO and ${FOO}
|
%% it in InStr. References can have two forms: $FOO and ${FOO}
|
||||||
|
@ -242,18 +296,20 @@ filter_envs([{Key, Value} | Rest], Acc) ->
|
||||||
erts_dir() ->
|
erts_dir() ->
|
||||||
lists:concat([code:root_dir(), "/erts-", erlang:system_info(version)]).
|
lists:concat([code:root_dir(), "/erts-", erlang:system_info(version)]).
|
||||||
|
|
||||||
|
os_env() ->
|
||||||
|
[list_to_tuple(re:split(S, "=", [{return, list}])) || S <- os:getenv()].
|
||||||
|
|
||||||
default_env() ->
|
default_env() ->
|
||||||
[{"CC", "gcc"},
|
[{"CC", "gcc"},
|
||||||
{"CXX", "g++"},
|
{"CXX", "g++"},
|
||||||
{"CFLAGS", "-g -Wall -fPIC"},
|
{"ERL_CFLAGS", lists:concat([" -I", code:lib_dir(erl_interface, include),
|
||||||
{"CXXFLAGS", "-g -Wall -fPIC"},
|
" -I", filename:join(erts_dir(), include),
|
||||||
{"LDFLAGS", "-shared"},
|
" "])},
|
||||||
{"darwin", "LDFLAGS", "-bundle -flat_namespace -undefined suppress"},
|
{"ERL_LDFLAGS", lists:concat([" -L", code:lib_dir(erl_interface, lib),
|
||||||
{"DRIVER_CFLAGS", lists:concat([" -I", code:lib_dir(erl_interface, include),
|
" -lerl_interface -lei"])},
|
||||||
" -I", filename:join(erts_dir(), include),
|
{"DRV_CFLAGS", "-g -Wall -fPIC $ERL_CFLAGS"},
|
||||||
" "])},
|
{"DRV_LDFLAGS", "-shared $ERL_LDFLAGS"},
|
||||||
{"DRIVER_LDFLAGS", lists:concat([" -L", code:lib_dir(erl_interface, lib),
|
{"darwin", "DRV_LDFLAGS", "-bundle -flat_namespace -undefined suppress $ERL_LDFLAGS"},
|
||||||
" -lerl_interface -lei"])},
|
|
||||||
{"ERLANG_ARCH", integer_to_list(8 * erlang:system_info(wordsize))},
|
{"ERLANG_ARCH", integer_to_list(8 * erlang:system_info(wordsize))},
|
||||||
{"ERLANG_TARGET", rebar_utils:get_arch()}].
|
{"ERLANG_TARGET", rebar_utils:get_arch()}].
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
find_files/2,
|
find_files/2,
|
||||||
now_str/0,
|
now_str/0,
|
||||||
ensure_dir/1,
|
ensure_dir/1,
|
||||||
beam_to_mod/2, beams/1]).
|
beam_to_mod/2, beams/1,
|
||||||
|
abort/2]).
|
||||||
|
|
||||||
-include("rebar.hrl").
|
-include("rebar.hrl").
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ find_files(Dir, Regex) ->
|
||||||
|
|
||||||
now_str() ->
|
now_str() ->
|
||||||
{{Year, Month, Day}, {Hour, Minute, Second}} = calendar:local_time(),
|
{{Year, Month, Day}, {Hour, Minute, Second}} = calendar:local_time(),
|
||||||
lists:flatten(io_lib:format("~4b/~2..0b/~2..0b ~2..0b:~2..0b:~2..0b",
|
lists:flatten(io_lib:format("~4b/~2..0b/~2..0b ~2..0b:~2..0b:~2..0b",
|
||||||
[Year, Month, Day, Hour, Minute, Second])).
|
[Year, Month, Day, Hour, Minute, Second])).
|
||||||
|
|
||||||
%% TODO: Review why filelib:ensure_dir/1 sometimes returns {error, eexist}.
|
%% TODO: Review why filelib:ensure_dir/1 sometimes returns {error, eexist}.
|
||||||
|
@ -113,6 +114,10 @@ ensure_dir(Path) ->
|
||||||
Error
|
Error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
abort(String, Args) ->
|
||||||
|
?ERROR(String, Args),
|
||||||
|
halt(1).
|
||||||
|
|
||||||
%% ====================================================================
|
%% ====================================================================
|
||||||
%% Internal functions
|
%% Internal functions
|
||||||
%% ====================================================================
|
%% ====================================================================
|
||||||
|
|
Loading…
Reference in a new issue