summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFred Hebert <mononcqc@ferd.ca>2017-11-05 22:24:58 -0500
committerFred Hebert <mononcqc@ferd.ca>2017-11-20 14:56:06 -0500
commitbf7ec3866f1819619286cc875fa88e1dc8bb9cfc (patch)
treec4c1275a3ce82eb13829eb8cfa4d7b0e4d6d0102 /src
parent26d30a95fa8ecba5d40a4627a7b436f58b53cb0e (diff)
Make debug_info rules clear
Current rebar3 uses debug_info rules where debug_info is added by default, and no_debug_info prevents the default from being added, and removes any explicit debug_info, if any. The problem is that if 'no_debug_info' is anywhere in the config for a run, it cannot be removed even with other profiles. additionally, no_debug_info ignores special tuples like {debug_info, {Mod, Data}} and {debug_info_key, Key}, which can be used to add debug info and encrypt it (in lieu of plain debug_info) respectively. This patch makes it so that the following rules are in place: - the last option seen takes priority, allowing profile overrides by the ordering rules the compiler expects - the overriden options shall be explicitly deleted to avoid confusing the compiler - any option related to debug info seen last cancels any no_debug_info that preceded it - any no_debug_info option seen last cancels all of the other debug_info options - if debug_info is seen last, it cancels out {debug_info_key, Key} - if {debug_info_key, Key} is seen last, it cancels out debug_info - All other options are left untouched in that context (defines can still be expanded and so on) This should allow proper profile rules to be followed. Note that erl_opt profile merging puts precedence on the *last* element of a list, to match the compiler.
Diffstat (limited to 'src')
-rw-r--r--src/rebar_opts.erl40
1 files changed, 34 insertions, 6 deletions
diff --git a/src/rebar_opts.erl b/src/rebar_opts.erl
index b7156b2..1a927ba 100644
--- a/src/rebar_opts.erl
+++ b/src/rebar_opts.erl
@@ -35,12 +35,40 @@ erl_opts(Opts) ->
Defines = [{d, list_to_atom(D)} ||
D <- ?MODULE:get(Opts, defines, [])],
AllOpts = Defines ++ RawErlOpts,
- case proplists:is_defined(no_debug_info, AllOpts) of
- true ->
- [O || O <- AllOpts, O =/= no_debug_info];
- false ->
- [debug_info|AllOpts]
- end.
+ lists:reverse(filter_debug_info(lists:reverse(AllOpts))).
+
+filter_debug_info([]) ->
+ %% Default == ON
+ [debug_info];
+filter_debug_info([debug_info|_] = L) ->
+ %% drop no_debug_info and {debug_info_key, _} since those would
+ %% conflict with a plain debug_info
+ [debug_info |
+ lists:filter(fun(K) ->
+ K =/= no_debug_info andalso K =/= debug_info andalso
+ not (is_tuple(K) andalso element(1,K) =:= debug_info_key)
+ end, L)];
+filter_debug_info([{debug_info, _} = H | T]) ->
+ %% custom debug_info field; keep and filter the rest except
+ %% without no_debug_info. Still have to filter for regular or crypto
+ %% debug_info.
+ [H | filter_debug_info(lists:filter(fun(K) -> K =/= no_debug_info end, T))];
+filter_debug_info([{debug_info_key, _}=H | T]) ->
+ %% Drop no_debug_info and regular debug_info
+ [H | lists:filter(fun(K) ->
+ K =/= no_debug_info andalso K =/= debug_info andalso
+ not (is_tuple(K) andalso element(1,K) =:= debug_info_key)
+ end, T)];
+filter_debug_info([no_debug_info|T]) ->
+ %% Drop all debug info
+ lists:filter(fun(debug_info) -> false
+ ; ({debug_info, _}) -> false
+ ; ({debug_info_key, _}) -> false
+ ; (no_debug_info) -> false
+ ; (_Other) -> true
+ end, T);
+filter_debug_info([H|T]) ->
+ [H|filter_debug_info(T)].
apply_overrides(Opts, Name, Overrides) ->
%% Inefficient. We want the order we get here though.