summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rebar.config.sample6
-rw-r--r--src/rebar_config.erl25
-rw-r--r--src/rebar_core.erl78
-rw-r--r--src/rebar_port_compiler.erl376
4 files changed, 268 insertions, 217 deletions
diff --git a/rebar.config.sample b/rebar.config.sample
index 9be1373..ebcaff9 100644
--- a/rebar.config.sample
+++ b/rebar.config.sample
@@ -37,14 +37,16 @@
%% Port compilation environment variables. See rebar_port_compiler.erl for
%% more info. Default is `[]'
-{port_env, []}.
+{port_env, [{"CFLAGS", "$CFLAGS -Ifoo"},
+ {"freebsd", "LDFLAGS", "$LDFLAGS -lfoo"}]}.
%% port_specs
%% List of filenames or wildcards to be compiled. May also contain a tuple
%% consisting of a regular expression to be applied against the system
%% architecture as a filter.
{port_specs, [{"priv/so_name.so", ["c_src/*.c"]},
- {"linux", "priv/hello_linux", ["c_src/hello_linux.c"]]}.
+ {"linux", "priv/hello_linux", ["c_src/hello_linux.c"]},
+ {"linux", "priv/hello_linux", ["c_src/*.c"], [{env, []}]}}.
%% == LFE Compiler ==
diff --git a/src/rebar_config.erl b/src/rebar_config.erl
index 31788b1..e9915ea 100644
--- a/src/rebar_config.erl
+++ b/src/rebar_config.erl
@@ -31,12 +31,17 @@
get_all/2,
set/3,
set_global/2, get_global/2,
- is_verbose/0, get_jobs/0]).
+ is_verbose/0, get_jobs/0,
+ set_env/3, get_env/2]).
-include("rebar.hrl").
-record(config, { dir :: file:filename(),
- opts :: list() }).
+ opts = [] :: list(),
+ envs = [] :: list({module(), env()}) }).
+
+-type env() :: [env_var()].
+-type env_var() :: {string(), string()}.
%% Types that can be used from other modules -- alphabetically ordered.
-export_type([config/0]).
@@ -53,8 +58,7 @@ base_config(#config{opts=Opts0}) ->
new(Opts0, ConfName).
new() ->
- #config { dir = rebar_utils:get_cwd(),
- opts = [] }.
+ #config{dir = rebar_utils:get_cwd()}.
new(ConfigFile) when is_list(ConfigFile) ->
case consult_file(ConfigFile) of
@@ -88,7 +92,7 @@ new(Opts0, ConfName) ->
?ABORT("Failed to load ~s: ~p\n", [ConfigFile, Other])
end,
- #config { dir = Dir, opts = Opts }.
+ #config{dir = Dir, opts = Opts}.
get(Config, Key, Default) ->
proplists:get_value(Key, Config#config.opts, Default).
@@ -143,6 +147,17 @@ consult_file(File) ->
end
end.
+set_env(Config, Mod, Env) ->
+ OldEnvs = Config#config.envs,
+ NewEnvs = case lists:keymember(Mod, 1, OldEnvs) of
+ true -> lists:keyreplace(Mod, 1, OldEnvs, {Mod, Env});
+ false -> [{Mod,Env}|OldEnvs]
+ end,
+ Config#config{envs=NewEnvs}.
+
+get_env(Config, Mod) ->
+ proplists:get_value(Mod, Config#config.envs, []).
+
%% ===================================================================
%% Internal functions
%% ===================================================================
diff --git a/src/rebar_core.erl b/src/rebar_core.erl
index 0f098af..484b446 100644
--- a/src/rebar_core.erl
+++ b/src/rebar_core.erl
@@ -168,7 +168,7 @@ maybe_process_dir0(AppFile, ModuleSet, Config, CurrentCodePath,
CurrentCodePath, ModuleSet)
end.
-process_dir0(Dir, Command, DirSet, Config, CurrentCodePath,
+process_dir0(Dir, Command, DirSet, Config0, CurrentCodePath,
{DirModules, ModuleSetFile}) ->
%% Get the list of modules for "any dir". This is a catch-all list
%% of modules that are processed in addition to modules associated
@@ -180,21 +180,21 @@ process_dir0(Dir, Command, DirSet, Config, CurrentCodePath,
%% Invoke 'preprocess' on the modules -- this yields a list of other
%% directories that should be processed _before_ the current one.
- Predirs = acc_modules(Modules, preprocess, Config, ModuleSetFile),
+ Predirs = acc_modules(Modules, preprocess, Config0, ModuleSetFile),
SubdirAssoc = remember_cwd_subdir(Dir, Predirs),
%% Get the list of plug-in modules from rebar.config. These
%% modules may participate in preprocess and postprocess.
- {ok, PluginModules} = plugin_modules(Config, SubdirAssoc),
+ {ok, PluginModules} = plugin_modules(Config0, SubdirAssoc),
PluginPredirs = acc_modules(PluginModules, preprocess,
- Config, ModuleSetFile),
+ Config0, ModuleSetFile),
AllPredirs = Predirs ++ PluginPredirs,
?DEBUG("Predirs: ~p\n", [AllPredirs]),
- DirSet2 = process_each(AllPredirs, Command, Config,
+ DirSet2 = process_each(AllPredirs, Command, Config0,
ModuleSetFile, DirSet),
%% Make sure the CWD is reset properly; processing the dirs may have
@@ -202,25 +202,31 @@ process_dir0(Dir, Command, DirSet, Config, CurrentCodePath,
ok = file:set_cwd(Dir),
%% Check that this directory is not on the skip list
- case is_skip_dir(Dir) of
- true ->
- %% Do not execute the command on the directory, as some
- %% module has requested a skip on it.
- ?INFO("Skipping ~s in ~s\n", [Command, Dir]);
+ Config = case is_skip_dir(Dir) of
+ true ->
+ %% Do not execute the command on the directory, as some
+ %% module has requested a skip on it.
+ ?INFO("Skipping ~s in ~s\n", [Command, Dir]),
+ Config0;
- false ->
- %% Execute any before_command plugins on this directory
- execute_pre(Command, PluginModules,
- Config, ModuleSetFile),
+ false ->
+ %% Check for and get command specific environments
+ {Config1, Env} = setup_envs(Config0, Modules),
- %% Execute the current command on this directory
- execute(Command, Modules ++ PluginModules,
- Config, ModuleSetFile),
+ %% Execute any before_command plugins on this directory
+ execute_pre(Command, PluginModules,
+ Config1, ModuleSetFile, Env),
- %% Execute any after_command plugins on this directory
- execute_post(Command, PluginModules,
- Config, ModuleSetFile)
- end,
+ %% Execute the current command on this directory
+ execute(Command, Modules ++ PluginModules,
+ Config1, ModuleSetFile, Env),
+
+ %% Execute any after_command plugins on this directory
+ execute_post(Command, PluginModules,
+ Config1, ModuleSetFile, Env),
+
+ Config1
+ end,
%% Mark the current directory as processed
DirSet3 = sets:add_element(Dir, DirSet2),
@@ -311,22 +317,22 @@ is_dir_type(rel_dir, Dir) ->
is_dir_type(_, _) ->
false.
-execute_pre(Command, Modules, Config, ModuleFile) ->
+execute_pre(Command, Modules, Config, ModuleFile, Env) ->
execute_plugin_hook("pre_", Command, Modules,
- Config, ModuleFile).
+ Config, ModuleFile, Env).
-execute_post(Command, Modules, Config, ModuleFile) ->
+execute_post(Command, Modules, Config, ModuleFile, Env) ->
execute_plugin_hook("post_", Command, Modules,
- Config, ModuleFile).
+ Config, ModuleFile, Env).
-execute_plugin_hook(Hook, Command, Modules, Config, ModuleFile) ->
+execute_plugin_hook(Hook, Command, Modules, Config, ModuleFile, Env) ->
HookFunction = list_to_atom(Hook ++ atom_to_list(Command)),
- execute(HookFunction, Modules, Config, ModuleFile).
+ execute(HookFunction, Modules, Config, ModuleFile, Env).
%%
%% Execute a command across all applicable modules
%%
-execute(Command, Modules, Config, ModuleFile) ->
+execute(Command, Modules, Config, ModuleFile, Env) ->
case select_modules(Modules, Command, []) of
[] ->
Cmd = atom_to_list(Command),
@@ -346,9 +352,6 @@ execute(Command, Modules, Config, ModuleFile) ->
increment_operations(),
- %% Check for and get command specific environments
- Env = setup_envs(Config, Modules),
-
%% Run the available modules
apply_hooks(pre_hooks, Config, Command, Env),
case catch(run_modules(TargetModules, Command,
@@ -443,9 +446,16 @@ apply_hook({Env, {Command, Hook}}) ->
rebar_utils:sh(Hook, [{env, Env}, {abort_on_error, Msg}]).
setup_envs(Config, Modules) ->
- lists:flatten([M:setup_env(Config) ||
- M <- Modules,
- erlang:function_exported(M, setup_env, 1)]).
+ lists:foldl(fun(M, {C,E}=T) ->
+ case erlang:function_exported(M, setup_env, 1) of
+ true ->
+ Env = M:setup_env(C),
+ C1 = rebar_config:set_env(C, M, Env),
+ {C1, E++Env};
+ false ->
+ T
+ end
+ end, {Config, []}, Modules).
acc_modules(Modules, Command, Config, File) ->
acc_modules(select_modules(Modules, Command, []),
diff --git a/src/rebar_port_compiler.erl b/src/rebar_port_compiler.erl
index efd5cf3..612ae26 100644
--- a/src/rebar_port_compiler.erl
+++ b/src/rebar_port_compiler.erl
@@ -39,8 +39,9 @@
%% Supported configuration variables:
%%
%% * port_specs - Erlang list of tuples of the forms
-%% {arch_regex(), "priv/foo.so", ["c_src/foo.c"]}
-%% {"priv/foo", ["c_src/foo.c"]}
+%% {ArchRegex, TargetFile, Sources, Options}
+%% {ArchRegex, TargetFile, Sources}
+%% {TargetFile, Sources}
%%
%% * port_env - Erlang list of key/value pairs which will control
%% the environment when running the compiler and linker.
@@ -85,43 +86,55 @@
%% "$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(), ...] | [],
+ 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"),
- SourceFiles = get_sources(Config),
+ %% 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
- case SourceFiles of
- [] ->
- ok;
- _ ->
- Env = setup_env(Config),
+ _ -> % have old/new specs
+
+ SharedEnv = rebar_config:get_env(Config, ?MODULE),
%% Compile each of the sources
- {NewBins, ExistingBins} = compile_each(SourceFiles, Config, Env,
- [], []),
+ NewBins = compile_sources(OldSources, Specs, SharedEnv),
- %% Construct the target filename and make sure that the
- %% target directory exists
- Specs = port_specs(Config, AppFile, NewBins ++ ExistingBins),
+ %% Make sure that the target directories exist
?INFO("Using specs ~p\n", [Specs]),
- lists:foreach(fun({_, Target,_}) ->
- ok = filelib:ensure_dir(Target);
- ({Target, _}) ->
+ lists:foreach(fun(#spec{target=Target}) ->
ok = filelib:ensure_dir(Target)
end, Specs),
%% Only relink if necessary, given the Target
%% and list of new binaries
lists:foreach(
- fun({Target, Bins}) ->
+ fun(#spec{target=Target, objects=Bins, opts=Opts}) ->
AllBins = [sets:from_list(Bins),
sets:from_list(NewBins)],
Intersection = sets:intersection(AllBins),
case needs_link(Target, sets:to_list(Intersection)) of
true ->
LinkTemplate = select_link_template(Target),
+ Env = proplists:get_value(env, Opts, SharedEnv),
Cmd = expand_command(LinkTemplate, Env,
string:join(Bins, " "),
Target),
@@ -134,113 +147,83 @@ compile(Config, AppFile) ->
end.
clean(Config, AppFile) ->
- %% Build a list of sources so as to derive all the bins we generated
- Sources = get_sources(Config),
- rebar_file_utils:delete_each([source_to_bin(S) || S <- Sources]),
-
- %% Delete the target file
- ExtractTarget = fun({_, Target, _}) ->
- Target;
- ({Target, _}) ->
- Target
- end,
- rebar_file_utils:delete_each([ExtractTarget(S)
- || S <- port_specs(Config, AppFile,
- expand_objects(Sources))]).
+ %% 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
+
+ lists:foreach(fun(#spec{target=Target, objects=Objects}) ->
+ rebar_file_utils:delete_each([Target]),
+ rebar_file_utils:delete_each(Objects)
+ end, Specs)
+ end.
setup_env(Config) ->
+ setup_env(Config, []).
+
+%% ===================================================================
+%% Internal functions
+%% ===================================================================
+
+setup_env(Config, ExtraEnv) ->
%% Extract environment values from the config (if specified) and
%% merge with the default for this operating system. This enables
%% max flexibility for users.
DefaultEnv = filter_env(default_env(), []),
- PortEnv = port_env(Config),
- OverrideEnv = global_defines() ++ filter_env(PortEnv, []),
+ PortEnv = filter_env(port_env(Config), []),
+ OverrideEnv = global_defines() ++ PortEnv ++ filter_env(ExtraEnv, []),
RawEnv = apply_defaults(os_env(), DefaultEnv) ++ OverrideEnv,
expand_vars_loop(merge_each_var(RawEnv, [])).
-%% ===================================================================
-%% Internal functions
-%% ===================================================================
-
global_defines() ->
Defines = rebar_config:get_global(defines, []),
Flags = string:join(["-D" ++ D || D <- Defines], " "),
[{"ERL_CFLAGS", "$ERL_CFLAGS " ++ Flags}].
-get_sources(Config) ->
- case rebar_config:get_list(Config, port_specs, []) of
- [] ->
- %% TODO: DEPRECATED: remove
- expand_sources(rebar_config:get_list(Config, port_sources,
- ["c_src/*.c"]), []);
- PortSpecs ->
- expand_port_specs(PortSpecs)
- end.
-
-expand_port_specs(Specs) ->
- lists:flatmap(fun({_, Target, FileSpecs}) ->
- expand_file_specs(Target, FileSpecs);
- ({Target, FileSpecs}) ->
- expand_file_specs(Target, FileSpecs)
- end, filter_port_specs(Specs)).
-
-expand_file_specs(Target, FileSpecs) ->
- Sources = lists:flatmap(fun filelib:wildcard/1, FileSpecs),
- [{Target, Src} || Src <- Sources].
+replace_extension(File, NewExt) ->
+ OldExt = filename:extension(File),
+ replace_extension(File, OldExt, NewExt).
-filter_port_specs(Specs) ->
- lists:filter(fun({ArchRegex, _, _}) ->
- rebar_utils:is_arch(ArchRegex);
- ({_, _}) ->
- true
- end, Specs).
+replace_extension(File, OldExt, NewExt) ->
+ filename:rootname(File, OldExt) ++ NewExt.
+%%
+%% == compile and link ==
+%%
-%% TODO: DEPRECATED: remove
-expand_sources([], Acc) ->
- Acc;
-expand_sources([{ArchRegex, Spec} | Rest], Acc) ->
- case rebar_utils:is_arch(ArchRegex) of
- true ->
- Acc2 = expand_sources(Spec, Acc),
- expand_sources(Rest, Acc2);
- false ->
- expand_sources(Rest, Acc)
- end;
-expand_sources([Spec | Rest], Acc) ->
- Acc2 = filelib:wildcard(Spec) ++ Acc,
- expand_sources(Rest, Acc2).
-
-expand_objects(Sources) ->
- [expand_object(".o", Src) || Src <- Sources].
-
-expand_object(Ext, {_Target, Source}) ->
- expand_object(Ext, Source);
-expand_object(Ext, Source) ->
- filename:join(filename:dirname(Source), filename:basename(Source) ++ Ext).
-
-compile_each([], _Config, _Env, NewBins, ExistingBins) ->
- {lists:reverse(NewBins), lists:reverse(ExistingBins)};
-compile_each([RawSource | Rest], Config, Env, NewBins, ExistingBins) ->
- %% TODO: DEPRECATED: remove
- {Type, Source} = source_type(RawSource),
+compile_sources([], Specs, SharedEnv) -> % port_spec
+ 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([], _Type, _Env, NewBins) ->
+ lists:reverse(NewBins);
+compile_each([Source | Rest], Type, Env, NewBins) ->
Ext = filename:extension(Source),
- Bin = filename:rootname(Source, Ext) ++ ".o",
+ Bin = replace_extension(Source, Ext, ".o"),
case needs_compile(Source, Bin) of
true ->
?CONSOLE("Compiling ~s\n", [Source]),
Template = select_compile_template(Type, compiler(Ext)),
rebar_utils:sh(expand_command(Template, Env, Source, Bin),
[{env, Env}]),
- compile_each(Rest, Config, Env, [Bin | NewBins], ExistingBins);
+ compile_each(Rest, Type, Env, [Bin | NewBins]);
false ->
?INFO("Skipping ~s\n", [Source]),
- compile_each(Rest, Config, Env, NewBins, [Bin | ExistingBins])
+ compile_each(Rest, Type, Env, NewBins)
end.
-source_type({Target, Source}) -> {target_type(Target), Source};
-source_type(Source) -> {drv, Source}.
-
needs_compile(Source, Bin) ->
%% TODO: Generate depends using gcc -MM so we can also
%% check for include changes
@@ -259,6 +242,127 @@ needs_link(SoName, NewBins) ->
MaxLastMod >= Other
end.
+%%
+%% == port_specs ==
+%%
+
+get_specs(Config, AppFile) ->
+ case rebar_config:get(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) ->
+ Filtered = filter_port_specs(PortSpecs),
+ OsType = os:type(),
+ {[], [get_port_spec(Config, OsType, Spec) || Spec <- Filtered]}.
+
+filter_port_specs(Specs) ->
+ [S || S <- Specs, filter_port_spec(S)].
+
+filter_port_spec({ArchRegex, _, _, _}) ->
+ rebar_utils:is_arch(ArchRegex);
+filter_port_spec({ArchRegex, _, _}) ->
+ rebar_utils:is_arch(ArchRegex);
+filter_port_spec({_, _}) ->
+ true.
+
+get_port_spec(Config, OsType, {Target, Sources}) ->
+ get_port_spec(Config, OsType, {undefined, 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}) ->
+ SourceFiles = port_sources(Sources),
+ ObjectFiles = port_objects(SourceFiles),
+ #spec{type=target_type(Target),
+ target=maybe_switch_extension(OsType, Target),
+ sources=SourceFiles,
+ objects=ObjectFiles,
+ opts=port_opts(Config, Opts)}.
+
+port_sources(Sources) ->
+ lists:flatmap(fun filelib:wildcard/1, Sources).
+
+port_objects(SourceFiles) ->
+ [replace_extension(O, ".o") || O <- SourceFiles].
+
+port_opts(Config, Opts) ->
+ [port_opt(Config, O) || O <- Opts].
+
+port_opt(Config, {env, Env}) ->
+ {env, setup_env(Config, Env)};
+port_opt(_Config, Opt) ->
+ Opt.
+
+maybe_switch_extension({win32, nt}, Target) ->
+ switch_to_dll_or_exe(Target);
+maybe_switch_extension(_OsType, Target) ->
+ Target.
+
+switch_to_dll_or_exe(Target) ->
+ case filename:extension(Target) of
+ ".so" -> filename:rootname(Target, ".so") ++ ".dll";
+ [] -> Target ++ ".exe";
+ Other -> Other
+ 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(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(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_list(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 ==
+%%
%%
%% Choose a compiler variable, based on a provided extension
@@ -365,7 +469,6 @@ expand_keys_in_value([Key | Rest], Value, Vars) ->
end,
expand_keys_in_value(Rest, NewValue, Vars).
-
expand_command(TmplName, Env, InFiles, OutFile) ->
Cmd0 = proplists:get_value(TmplName, Env),
Cmd1 = rebar_utils:expand_env_variable(Cmd0, "PORT_IN_FILES", InFiles),
@@ -426,7 +529,6 @@ filter_env([{ArchRegex, Key, Value} | Rest], Acc) ->
filter_env([{Key, Value} | Rest], Acc) ->
filter_env(Rest, [{Key, Value} | Acc]).
-
erts_dir() ->
lists:concat([code:root_dir(), "/erts-", erlang:system_info(version)]).
@@ -520,81 +622,3 @@ default_env() ->
{"darwin11.*-32", "CXXFLAGS", "-m32 $CXXFLAGS"},
{"darwin11.*-32", "LDFLAGS", "-arch i386 $LDFLAGS"}
].
-
-source_to_bin({_Target, Source}) ->
- source_to_bin(Source);
-source_to_bin(Source) ->
- Ext = filename:extension(Source),
- filename:rootname(Source, Ext) ++ ".o".
-
-port_specs(Config, AppFile, Bins) ->
- Specs = make_port_specs(Config, AppFile, Bins),
- case os:type() of
- {win32, nt} ->
- [switch_to_dll_or_exe(Spec) || Spec <- Specs];
- _ ->
- Specs
- end.
-
-switch_to_dll_or_exe(Orig = {Name, Spec}) ->
- case filename:extension(Name) of
- ".so" ->
- {filename:rootname(Name, ".so") ++ ".dll", Spec};
- [] ->
- {Name ++ ".exe", Spec};
- _ ->
- %% Not a .so; leave it
- Orig
- end.
-
-make_port_specs(Config, AppFile, Bins) ->
- case rebar_config:get(Config, port_specs, undefined) of
- undefined ->
- %% TODO: DEPRECATED: remove
- make_so_specs(Config, AppFile, Bins);
- PortSpecs ->
- %% filter based on ArchRegex
- Specs0 = lists:filter(fun({ArchRegex, _Target, _Sources}) ->
- rebar_utils:is_arch(ArchRegex);
- (_) ->
- true
- end, PortSpecs),
- %% TODO: DEPRECATED: remove support for non-port_specs syntax
-
-
- %% drop ArchRegex from specs
- lists:map(fun({_, Target, RawSources}) ->
- {Target, sources_to_bins(RawSources)};
- ({Target, RawSources}) ->
- {Target, sources_to_bins(RawSources)}
- end, Specs0)
- end.
-
-sources_to_bins(RawSources) ->
- Sources = lists:flatmap(fun filelib:wildcard/1, RawSources),
- lists:map(fun source_to_bin/1, Sources).
-
-%% DEPRECATED
-make_so_specs(Config, AppFile, Bins) ->
- case rebar_config:get(Config, so_specs, undefined) of
- undefined ->
- %% 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(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),
- filename:join(Dir,
- lists:concat([AppName, "_drv.so"]));
-
- AName ->
- %% Old form is available -- use it
- filename:join(Dir, AName)
- end,
- [{SoName, Bins}];
-
- SoSpecs ->
- SoSpecs
- end.