summaryrefslogtreecommitdiff
path: root/src/rebar_port_compiler.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rebar_port_compiler.erl')
-rw-r--r--src/rebar_port_compiler.erl55
1 files changed, 40 insertions, 15 deletions
diff --git a/src/rebar_port_compiler.erl b/src/rebar_port_compiler.erl
index 272c151..61dbef9 100644
--- a/src/rebar_port_compiler.erl
+++ b/src/rebar_port_compiler.erl
@@ -62,6 +62,14 @@
%% 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
+%% ERL_EI_LIBDIR - ei library directory
+%% CXX_TEMPLATE - C++ command template
+%% CC_TEMPLATE - C command template
+%% LINK_TEMPLATE - Linker command template
+%% PORT_IN_FILES - contains a space separated list of input
+%% file(s), (used in command template)
+%% PORT_OUT_FILE - contains the output filename (used in
+%% command template)
%%
%% Note that if you wish to extend (vs. replace) these variables,
%% you MUST include a shell-style reference in your definition.
@@ -117,10 +125,10 @@ compile(Config, AppFile) ->
Intersection = sets:intersection(AllBins),
case needs_link(SoName, sets:to_list(Intersection)) of
true ->
- rebar_utils:sh(
- ?FMT("$CC ~s $LDFLAGS $DRV_LDFLAGS -o ~s",
- [string:join(Bins, " "), SoName]),
- [{env, Env}]);
+ Cmd = expand_command("LINK_TEMPLATE", Env,
+ string:join(Bins, " "),
+ SoName),
+ rebar_utils:sh(Cmd, [{env, Env}]);
false ->
?INFO("Skipping relink of ~s\n", [SoName]),
ok
@@ -182,12 +190,13 @@ compile_each([Source | Rest], Config, Env, NewBins, ExistingBins) ->
?CONSOLE("Compiling ~s\n", [Source]),
case compiler(Ext) of
"$CC" ->
- rebar_utils:sh(?FMT("$CC -c $CFLAGS $DRV_CFLAGS ~s -o ~s",
- [Source, Bin]), [{env, Env}]);
+ rebar_utils:sh(expand_command("CC_TEMPLATE", Env,
+ Source, Bin),
+ [{env, Env}]);
"$CXX" ->
- rebar_utils:sh(
- ?FMT("$CXX -c $CXXFLAGS $DRV_CFLAGS ~s -o ~s",
- [Source, Bin]), [{env, Env}])
+ rebar_utils:sh(expand_command("CXX_TEMPLATE", Env,
+ Source, Bin),
+ [{env, Env}])
end,
compile_each(Rest, Config, Env, [Bin | NewBins], ExistingBins);
@@ -302,6 +311,12 @@ expand_vars(Key, Value, Vars) ->
end,
[], Vars).
+expand_command(TmplName, Env, InFiles, OutFile) ->
+ Cmd0 = proplists:get_value(TmplName, Env),
+ Cmd1 = expand_env_variable(Cmd0, "PORT_IN_FILES", InFiles),
+ Cmd2 = expand_env_variable(Cmd1, "PORT_OUT_FILE", OutFile),
+ re:replace(Cmd2, "\\\$\\w+|\\\${\\w+}", "", [global, {return, list}]).
+
%%
%% Given a string, determine if it is expandable
%%
@@ -314,11 +329,14 @@ is_expandable(InStr) ->
%%
%% Given env. variable FOO we want to expand all references to
%% it in InStr. References can have two forms: $FOO and ${FOO}
+%% The end of form $FOO is delimited with whitespace or eol
%%
expand_env_variable(InStr, VarName, VarValue) ->
- R1 = re:replace(InStr, "\\\$" ++ VarName, VarValue),
- re:replace(R1, "\\\${" ++ VarName ++ "}", VarValue, [{return, list}]).
-
+ R1 = re:replace(InStr, "\\\$" ++ VarName ++ "\\s", VarValue ++ " ",
+ [global]),
+ R2 = re:replace(R1, "\\\$" ++ VarName ++ "\$", VarValue),
+ re:replace(R2, "\\\${" ++ VarName ++ "}", VarValue,
+ [global, {return, list}]).
%%
%% Filter a list of env vars such that only those which match the provided
@@ -343,19 +361,26 @@ erts_dir() ->
os_env() ->
Os = [list_to_tuple(re:split(S, "=", [{return, list}, {parts, 2}])) ||
S <- os:getenv()],
- lists:keydelete([],1,Os). %% Remove Windows current disk and path
+ %% Drop variables without a name (win32)
+ [{K, V} || {K, V} <- Os, K =/= []].
default_env() ->
[
+ {"CXX_TEMPLATE",
+ "$CXX -c $CXXFLAGS $DRV_CFLAGS $PORT_IN_FILES -o $PORT_OUT_FILE"},
+ {"CC_TEMPLATE",
+ "$CC -c $CFLAGS $DRV_CFLAGS $PORT_IN_FILES -o $PORT_OUT_FILE"},
+ {"LINK_TEMPLATE",
+ "$CC $PORT_IN_FILES $LDFLAGS $DRV_LDFLAGS -o $PORT_OUT_FILE"},
{"CC", "cc"},
{"CXX", "c++"},
{"ERL_CFLAGS", lists:concat([" -I", code:lib_dir(erl_interface, include),
" -I", filename:join(erts_dir(), "include"),
" "])},
- {"ERL_LDFLAGS", lists:concat([" -L", code:lib_dir(erl_interface, lib),
- " -lerl_interface -lei"])},
+ {"ERL_LDFLAGS", " -L$ERL_EI_LIBDIR -lerl_interface -lei"},
{"DRV_CFLAGS", "-g -Wall -fPIC $ERL_CFLAGS"},
{"DRV_LDFLAGS", "-shared $ERL_LDFLAGS"},
+ {"ERL_EI_LIBDIR", code:lib_dir(erl_interface, lib)},
{"darwin", "DRV_LDFLAGS",
"-bundle -flat_namespace -undefined suppress $ERL_LDFLAGS"},
{"ERLANG_ARCH", rebar_utils:wordsize()},