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

Expand env vars #38

Merged
8 commits merged into from
Mar 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,19 @@ BELOW HERE BE DRAGONS
%% {ArchRegex, TargetFile, Sources}
%% {TargetFile, Sources}
%%
%% Note that if you want to use any of the rebar3 variables
%% below you must MUST use a ${}-style to get the expansion
%% to work. e.g. to expand REBAR_DEPS_DIR, do something like:
%%
%% {port_specs, [{"priv/nif.so",
%% ["c_src/nif.c",
%% "${REBAR_DEPS_DIR}/foo/bar.c"]}]}.
%%
%% This is a _very_ good way to be able to use your code both
%% as a top level app and a dependency.
%%
%% CAVEAT! Not using {} is broken for the moment.
%%
%% * port_env - Erlang list of key/value pairs which will control
%% the environment when running the compiler and linker.
%% Variables set in the surrounding system shell are taken
Expand Down
4 changes: 2 additions & 2 deletions src/pc_compilation.erl
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ compile_and_link(State, Specs) ->
true ->
LinkLang = pc_port_specs:link_lang(Spec),
LinkTemplate = select_link_template(LinkLang, Target),
Env = pc_port_specs:environment(Spec),
Env = pc_port_specs:create_env(State, Spec),
Cmd = expand_command(LinkTemplate, Env,
pc_util:strjoin(Bins, " "),
Target),
Expand Down Expand Up @@ -97,7 +97,7 @@ compile_sources(Config, Specs) ->
fun(Spec, Acc) ->
Sources = pc_port_specs:sources(Spec),
Type = pc_port_specs:type(Spec),
Env = pc_port_specs:environment(Spec),
Env = pc_port_specs:create_env(Config, Spec),
compile_each(Config, Sources, Type, Env, Acc)
end, {[], []}, Specs),
%% Rewrite clang compile commands database file only if something
Expand Down
38 changes: 35 additions & 3 deletions src/pc_port_specs.erl
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@

-export([
construct/1,
create_env/2,
%% spec accessors
environment/1,
opts/1,
objects/1,
sources/1,
target/1,
Expand Down Expand Up @@ -66,9 +68,14 @@ construct(State) ->
{ok, [S || S <- Specs, S#spec.sources /= []]}
end.

create_env(State, Spec) ->
pc_port_specs:environment(Spec) ++
try_and_create_env(State).

%% == Spec Accessors ==

environment(#spec{opts = Opts}) -> proplists:get_value(env, Opts).
opts(#spec{opts = Opts}) -> Opts.
objects(#spec{objects = Objects}) -> Objects.
sources(#spec{sources = Sources}) -> Sources.
target(#spec{target = Target}) -> Target.
Expand All @@ -79,6 +86,13 @@ link_lang(#spec{link_lang = LinkLang}) -> LinkLang.
%%% Internal Functions
%%%===================================================================

try_and_create_env(State) ->
_ = code:ensure_loaded(rebar_env),
case erlang:function_exported(rebar_env, create_env, 1) of
false -> [];
true -> rebar_env:create_env(State)
end.

port_spec_from_legacy(Config) ->
%% Get the target from the so_name variable
Target = case rebar_state:get(Config, so_name, undefined) of
Expand Down Expand Up @@ -133,13 +147,15 @@ get_port_spec(Config, OsType, {Target, Sources}) ->
get_port_spec(Config, OsType, {Arch, Target, Sources}) ->
get_port_spec(Config, OsType, {Arch, Target, Sources, []});
get_port_spec(Config, OsType, {_Arch, Target, Sources, Opts}) ->
Env = try_and_create_env(Config),
SourceFiles =
lists:flatmap(
fun(Source) ->
Source1 = rebar_utils:escape_chars(
filename:join(rebar_state:dir(Config), Source)),
Source1 = expand_env(Source, Env),
Source2 = rebar_utils:escape_chars(
filename:join(rebar_state:dir(Config), Source1)),
case filelib:wildcard(Source1) of
[] -> [Source1];
[] -> [Source2];
FileList -> FileList
end
end, Sources),
Expand All @@ -162,6 +178,22 @@ get_port_spec(Config, OsType, {_Arch, Target, Sources, Opts}) ->
objects = ObjectFiles,
opts = [port_opt(Config, O) || O <- fill_in_defaults(Opts)]}.

expand_env(Source, Env) ->
case rebar_string:chr(Source, $$) of
0 ->
%% No variables to expand. Also hides undef on older rebar3.
Source;
_ ->
lists:foldl(
fun({Key, Value}, Acc) ->
%% TODO: the expand_env_variable/3 only expands
%% variables delimited by whitespace and inside
%% ${}. Either fix or add a new function to
%% rebar3 or make a new function here in pc.
rebar_utils:expand_env_variable(Acc, Key, Value)
end, Source, Env)
end.

coerce_extension({win32, nt}, Target) ->
switch_to_dll_or_exe(Target);
coerce_extension(_OsType, Target) ->
Expand Down