From 8eb1fc8308a99410d4ccb9e3ce1b767c7615ac26 Mon Sep 17 00:00:00 2001 From: Juhani Rankimies Date: Sat, 30 Apr 2011 23:47:15 +0300 Subject: [PATCH] Make port compilation template configurable - Port compiler no longer requires bash on windows. - It's possible to use compilers whose command lines don't fit into the default template --- src/rebar_port_compiler.erl | 55 +++++++++++++++++++++++++++---------- 1 file 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()},