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.erl228
1 files changed, 70 insertions, 158 deletions
diff --git a/src/rebar_port_compiler.erl b/src/rebar_port_compiler.erl
index 22acff6..91b2cac 100644
--- a/src/rebar_port_compiler.erl
+++ b/src/rebar_port_compiler.erl
@@ -86,37 +86,21 @@
%% "$CFLAGS -X86Options"}]}
%%
-%% TODO: reconsider keeping both sources and objects once
-%% support for deprecated options has been remove.
-%% remove [] as valid value for sources, objects, and opts
-%% when removing deprecated options.
-record(spec, {type::'drv' | 'exe',
target::file:filename(),
- sources = [] :: [file:filename(), ...] | [],
- objects = [] :: [file:filename(), ...] | [],
+ sources = [] :: [file:filename(), ...],
+ objects = [] :: [file:filename(), ...],
opts = [] ::list() | []}).
-compile(Config, AppFile) ->
- rebar_utils:deprecated(port_sources, port_specs, Config, "soon"),
- rebar_utils:deprecated(so_name, port_specs, Config, "soon"),
- rebar_utils:deprecated(so_specs, port_specs, Config, "soon"),
-
- %% TODO: remove SpecType and OldSources make get_specs/2
- %% return list(#spec{}) when removing deprecated options
- {SpecType, {OldSources, Specs}} = get_specs(Config, AppFile),
-
- case {SpecType, OldSources, Specs} of
- {old, [], _} ->
- ok; % old specs empty
- {new, [], []} ->
- ok; % port_specs empty
-
- _ -> % have old/new specs
-
+compile(Config, _AppFile) ->
+ case get_specs(Config) of
+ [] ->
+ ok;
+ Specs ->
SharedEnv = rebar_config:get_env(Config, ?MODULE),
%% Compile each of the sources
- NewBins = compile_sources(OldSources, Specs, SharedEnv),
+ NewBins = compile_sources(Config, Specs, SharedEnv),
%% Make sure that the target directories exist
?INFO("Using specs ~p\n", [Specs]),
@@ -146,24 +130,17 @@ compile(Config, AppFile) ->
end, Specs)
end.
-clean(Config, AppFile) ->
- %% TODO: remove SpecType and OldSources make get_specs/2
- %% return list(#spec{}) when removing deprecated options
- {SpecType, {OldSources, Specs}} = get_specs(Config, AppFile),
-
- case {SpecType, OldSources, Specs} of
- {old, [], _} ->
- ok; % old specs empty
- {new, [], []} ->
- ok; % port_specs empty
-
- _ -> % have old/new specs
-
+clean(Config, _AppFile) ->
+ case get_specs(Config) of
+ [] ->
+ ok;
+ Specs ->
lists:foreach(fun(#spec{target=Target, objects=Objects}) ->
rebar_file_utils:delete_each([Target]),
rebar_file_utils:delete_each(Objects)
end, Specs)
- end.
+ end,
+ ok.
setup_env(Config) ->
setup_env(Config, []).
@@ -177,15 +154,17 @@ setup_env(Config, ExtraEnv) ->
%% merge with the default for this operating system. This enables
%% max flexibility for users.
DefaultEnv = filter_env(default_env(), []),
- PortEnv = filter_env(port_env(Config), []),
- OverrideEnv = global_defines() ++ PortEnv ++ filter_env(ExtraEnv, []),
+ RawPortEnv = rebar_config:get_list(Config, port_env, []),
+ PortEnv = filter_env(RawPortEnv, []),
+ Defines = get_defines(Config),
+ OverrideEnv = Defines ++ PortEnv ++ filter_env(ExtraEnv, []),
RawEnv = apply_defaults(os_env(), DefaultEnv) ++ OverrideEnv,
expand_vars_loop(merge_each_var(RawEnv, [])).
-global_defines() ->
- Defines = rebar_config:get_global(defines, []),
- Flags = string:join(["-D" ++ D || D <- Defines], " "),
- [{"ERL_CFLAGS", "$ERL_CFLAGS " ++ Flags}].
+get_defines(Config) ->
+ RawDefines = rebar_config:get_xconf(Config, defines, []),
+ Defines = string:join(["-D" ++ D || D <- RawDefines], " "),
+ [{"ERL_CFLAGS", "$ERL_CFLAGS " ++ Defines}].
replace_extension(File, NewExt) ->
OldExt = filename:extension(File),
@@ -198,18 +177,16 @@ replace_extension(File, OldExt, NewExt) ->
%% == compile and link ==
%%
-compile_sources([], Specs, SharedEnv) -> % port_spec
+compile_sources(Config, Specs, SharedEnv) ->
lists:foldl(
fun(#spec{sources=Sources, type=Type, opts=Opts}, NewBins) ->
Env = proplists:get_value(env, Opts, SharedEnv),
- compile_each(Sources, Type, Env, NewBins)
- end, [], Specs);
-compile_sources(OldSources, _Specs, SharedEnv) -> % deprecated
- compile_each(OldSources, drv, SharedEnv, []).
+ compile_each(Config, Sources, Type, Env, NewBins)
+ end, [], Specs).
-compile_each([], _Type, _Env, NewBins) ->
+compile_each(_Config, [], _Type, _Env, NewBins) ->
lists:reverse(NewBins);
-compile_each([Source | Rest], Type, Env, NewBins) ->
+compile_each(Config, [Source | Rest], Type, Env, NewBins) ->
Ext = filename:extension(Source),
Bin = replace_extension(Source, Ext, ".o"),
case needs_compile(Source, Bin) of
@@ -217,22 +194,27 @@ compile_each([Source | Rest], Type, Env, NewBins) ->
Template = select_compile_template(Type, compiler(Ext)),
Cmd = expand_command(Template, Env, Source, Bin),
ShOpts = [{env, Env}, return_on_error, {use_stdout, false}],
- exec_compiler(Source, Cmd, ShOpts),
- compile_each(Rest, Type, Env, [Bin | NewBins]);
+ exec_compiler(Config, Source, Cmd, ShOpts),
+ compile_each(Config, Rest, Type, Env, [Bin | NewBins]);
false ->
?INFO("Skipping ~s\n", [Source]),
- compile_each(Rest, Type, Env, NewBins)
+ compile_each(Config, Rest, Type, Env, NewBins)
end.
-exec_compiler(Source, Cmd, ShOpts) ->
+exec_compiler(Config, Source, Cmd, ShOpts) ->
case rebar_utils:sh(Cmd, ShOpts) of
{error, {_RC, RawError}} ->
- AbsSource = filename:absname(Source),
+ AbsSource = case rebar_utils:processing_base_dir(Config) of
+ true ->
+ Source;
+ false ->
+ filename:absname(Source)
+ end,
?CONSOLE("Compiling ~s\n", [AbsSource]),
Error = re:replace(RawError, Source, AbsSource,
[{return, list}, global]),
?CONSOLE("~s", [Error]),
- ?ABORT;
+ ?FAIL;
{ok, Output} ->
?CONSOLE("Compiling ~s\n", [Source]),
?CONSOLE("~s", [Output])
@@ -260,19 +242,11 @@ needs_link(SoName, NewBins) ->
%% == port_specs ==
%%
-get_specs(Config, AppFile) ->
- case rebar_config:get_local(Config, port_specs, undefined) of
- undefined ->
- %% TODO: DEPRECATED: remove support for non-port_specs syntax
- {old, old_get_specs(Config, AppFile)};
- PortSpecs ->
- {new, get_port_specs(Config, PortSpecs)}
- end.
-
-get_port_specs(Config, PortSpecs) ->
+get_specs(Config) ->
+ PortSpecs = rebar_config:get_local(Config, port_specs, []),
Filtered = filter_port_specs(PortSpecs),
OsType = os:type(),
- {[], [get_port_spec(Config, OsType, Spec) || Spec <- Filtered]}.
+ [get_port_spec(Config, OsType, Spec) || Spec <- Filtered].
filter_port_specs(Specs) ->
[S || S <- Specs, filter_port_spec(S)].
@@ -323,58 +297,6 @@ switch_to_dll_or_exe(Target) ->
_Other -> Target
end.
-%% TODO: DEPRECATED: remove support for non-port_specs syntax [old_*()]
-old_get_specs(Config, AppFile) ->
- OsType = os:type(),
- SourceFiles = old_get_sources(Config),
- Specs =
- case rebar_config:get_local(Config, so_specs, undefined) of
- undefined ->
- Objects = port_objects(SourceFiles),
- %% New form of so_specs is not provided. See if the old form
- %% of {so_name} is available instead
- Dir = "priv",
- SoName =
- case rebar_config:get_local(Config, so_name, undefined) of
- undefined ->
- %% Ok, neither old nor new form is
- %% available. Use the app name and
- %% generate a sensible default.
- AppName = rebar_app_utils:app_name(AppFile),
- DrvName = ?FMT("~s_drv.so", [AppName]),
- filename:join([Dir, DrvName]);
- AName ->
- %% Old form is available -- use it
- filename:join(Dir, AName)
- end,
- [old_get_so_spec({SoName, Objects}, OsType)];
- SoSpecs ->
- [old_get_so_spec(S, OsType) || S <- SoSpecs]
- end,
- {SourceFiles, Specs}.
-
-old_get_sources(Config) ->
- RawSources = rebar_config:get_local(Config, port_sources,
- ["c_src/*.c"]),
- FilteredSources = old_filter_port_sources(RawSources),
- old_expand_sources(FilteredSources).
-
-old_filter_port_sources(PortSources) ->
- [S || S <- PortSources, old_is_arch_port_sources(S)].
-
-old_is_arch_port_sources({Arch, _Sources}) -> rebar_utils:is_arch(Arch);
-old_is_arch_port_sources(_Sources) -> true.
-
-old_expand_sources(Sources) ->
- lists:flatmap(fun filelib:wildcard/1, Sources).
-
-old_get_so_spec({Target, Objects}, OsType) ->
- #spec{type=drv,
- target=maybe_switch_extension(OsType, Target),
- sources=[],
- objects=Objects,
- opts=[]}.
-
%%
%% == port_env ==
%%
@@ -498,35 +420,6 @@ is_expandable(InStr) ->
nomatch -> false
end.
-port_env(Config) ->
- %% TODO: remove support for deprecated port_envs option
- PortEnv = rebar_utils:get_deprecated_list(Config, port_envs, port_env,
- [], "soon"),
- %% TODO: remove migration of deprecated port_env DRV_-/EXE_-less vars
- %% when the deprecation grace period ends
- WarnAndConvertVar = fun(Var) ->
- New = "DRV_" ++ Var,
- rebar_utils:deprecated(Var, New, "soon"),
- New
- end,
- ConvertVar = fun(Var="CXX_TEMPLATE") -> WarnAndConvertVar(Var);
- (Var="CC_TEMPLATE") -> WarnAndConvertVar(Var);
- (Var="LINK_TEMPLATE") -> WarnAndConvertVar(Var);
- (Var) -> Var
- end,
- %% Also warn about references to deprecated vars? omitted for
- %% performance reasons.
- ReplaceVars = fun(Val) ->
- re:replace(Val, "\\$(CXX|CC|LINK)(_TEMPLATE)",
- "DRV_\\1\\2", [{return,list}, global])
- end,
- Convert = fun({ArchRegex, Var, Val}) ->
- {ArchRegex, ConvertVar(Var), ReplaceVars(Val)};
- ({Var, Val}) ->
- {ConvertVar(Var), ReplaceVars(Val)}
- end,
- [Convert(EnvVar) || EnvVar <- PortEnv].
-
%%
%% Filter a list of env vars such that only those which match the provided
%% architecture regex (or do not have a regex) are returned.
@@ -626,13 +519,32 @@ default_env() ->
{"darwin9.*-64$", "CXXFLAGS", "-m64 $CXXFLAGS"},
{"darwin9.*-64$", "LDFLAGS", "-arch x86_64 $LDFLAGS"},
- %% OS X Snow Leopard flags for 32-bit
- {"darwin10.*-32", "CFLAGS", "-m32 $CFLAGS"},
- {"darwin10.*-32", "CXXFLAGS", "-m32 $CXXFLAGS"},
- {"darwin10.*-32", "LDFLAGS", "-arch i386 $LDFLAGS"},
-
- %% OS X Lion flags for 32-bit
- {"darwin11.*-32", "CFLAGS", "-m32 $CFLAGS"},
- {"darwin11.*-32", "CXXFLAGS", "-m32 $CXXFLAGS"},
- {"darwin11.*-32", "LDFLAGS", "-arch i386 $LDFLAGS"}
+ %% OS X Snow Leopard, Lion, and Mountain Lion flags for 32-bit
+ {"darwin1[0-2].*-32", "CFLAGS", "-m32 $CFLAGS"},
+ {"darwin1[0-2].*-32", "CXXFLAGS", "-m32 $CXXFLAGS"},
+ {"darwin1[0-2].*-32", "LDFLAGS", "-arch i386 $LDFLAGS"},
+
+ %% Windows specific flags
+ %% add MS Visual C++ support to rebar on Windows
+ {"win32", "CC", "cl.exe"},
+ {"win32", "CXX", "cl.exe"},
+ {"win32", "LINKER", "link.exe"},
+ {"win32", "DRV_CXX_TEMPLATE",
+ %% DRV_* and EXE_* Templates are identical
+ "$CXX /c $CXXFLAGS $DRV_CFLAGS $PORT_IN_FILES /Fo$PORT_OUT_FILE"},
+ {"win32", "DRV_CC_TEMPLATE",
+ "$CC /c $CFLAGS $DRV_CFLAGS $PORT_IN_FILES /Fo$PORT_OUT_FILE"},
+ {"win32", "DRV_LINK_TEMPLATE",
+ "$LINKER $PORT_IN_FILES $LDFLAGS $DRV_LDFLAGS /OUT:$PORT_OUT_FILE"},
+ %% DRV_* and EXE_* Templates are identical
+ {"win32", "EXE_CXX_TEMPLATE",
+ "$CXX /c $CXXFLAGS $EXE_CFLAGS $PORT_IN_FILES /Fo$PORT_OUT_FILE"},
+ {"win32", "EXE_CC_TEMPLATE",
+ "$CC /c $CFLAGS $EXE_CFLAGS $PORT_IN_FILES /Fo$PORT_OUT_FILE"},
+ {"win32", "EXE_LINK_TEMPLATE",
+ "$LINKER $PORT_IN_FILES $LDFLAGS $EXE_LDFLAGS /OUT:$PORT_OUT_FILE"},
+ %% ERL_CFLAGS are ok as -I even though strictly it should be /I
+ {"win32", "ERL_LDFLAGS", " /LIBPATH:$ERL_EI_LIBDIR erl_interface.lib ei.lib"},
+ {"win32", "DRV_CFLAGS", "/Zi /Wall $ERL_CFLAGS"},
+ {"win32", "DRV_LDFLAGS", "/DLL $ERL_LDFLAGS"}
].