mirror of
https://github.com/correl/rebar.git
synced 2024-12-18 03:00:17 +00:00
add new configuration option so_specs which allows multiple drivers to be built in the same project.
This commit is contained in:
parent
87bca27644
commit
c3fe43a0ba
1 changed files with 26 additions and 18 deletions
|
@ -39,6 +39,9 @@
|
|||
%%
|
||||
%% * port_sources - Erlang list of files and/or wildcard strings to be compiled
|
||||
%%
|
||||
%% * so_specs - Erlang list of tuples of the form {"priv/so_name.so", ["c_src/object_file_name.o"]} useful for
|
||||
%% building multiple *.so files.
|
||||
%%
|
||||
%% * port_envs - Erlang list of key/value pairs which will control the environment when
|
||||
%% running the compiler and linker. By default, the following variables
|
||||
%% are defined:
|
||||
|
@ -92,19 +95,21 @@ compile(Config, AppFile) ->
|
|||
{NewBins, ExistingBins} = compile_each(Sources, Config, Env, [], []),
|
||||
|
||||
%% Construct the driver name and make sure priv/ exists
|
||||
SoName = so_name(Config, AppFile),
|
||||
ok = filelib:ensure_dir(SoName),
|
||||
SoSpecs = so_specs(Config, AppFile, NewBins ++ ExistingBins),
|
||||
?INFO("Using specs ~p\n", [SoSpecs]),
|
||||
lists:foreach(fun({SoName,_}) -> ok = filelib:ensure_dir(SoName) end, SoSpecs),
|
||||
|
||||
%% Only relink if necessary, given the SoName and list of new binaries
|
||||
case needs_link(SoName, NewBins) of
|
||||
true ->
|
||||
AllBins = string:join(NewBins ++ ExistingBins, " "),
|
||||
lists:foreach(fun({SoName,Bins}) ->
|
||||
case needs_link(SoName, sets:to_list(sets:intersection([sets:from_list(Bins),sets:from_list(NewBins)]))) of
|
||||
true ->
|
||||
rebar_utils:sh_failfast(?FMT("$CC ~s $LDFLAGS $DRV_LDFLAGS -o ~s",
|
||||
[AllBins, SoName]), Env);
|
||||
false ->
|
||||
[string:join(Bins, " "), SoName]), Env);
|
||||
false ->
|
||||
?INFO("Skipping relink of ~s\n", [SoName]),
|
||||
ok
|
||||
end
|
||||
end
|
||||
end, SoSpecs)
|
||||
end.
|
||||
|
||||
clean(Config, AppFile) ->
|
||||
|
@ -113,7 +118,7 @@ clean(Config, AppFile) ->
|
|||
rebar_file_utils:delete_each([source_to_bin(S) || S <- Sources]),
|
||||
|
||||
%% Delete the .so file
|
||||
rebar_file_utils:delete_each([so_name(Config, AppFile)]),
|
||||
rebar_file_utils:delete_each(lists:map(fun({SoName,_}) -> SoName end, so_specs(Config, AppFile, expand_objects(Sources)))),
|
||||
|
||||
%% Run the cleanup script, if it exists
|
||||
run_cleanup_hook(Config).
|
||||
|
@ -131,6 +136,11 @@ expand_sources([Spec | Rest], Acc) ->
|
|||
Acc2 = filelib:wildcard(Spec) ++ Acc,
|
||||
expand_sources(Rest, Acc2).
|
||||
|
||||
expand_objects(Sources) ->
|
||||
lists:map(fun(File) ->
|
||||
filename:join([filename:dirname(File),filename:basename(File) ++ ".o"])
|
||||
end, Sources).
|
||||
|
||||
run_precompile_hook(Config, Env) ->
|
||||
case rebar_config:get(Config, port_pre_script, undefined) of
|
||||
undefined ->
|
||||
|
@ -319,21 +329,19 @@ source_to_bin(Source) ->
|
|||
Ext = filename:extension(Source),
|
||||
filename:rootname(Source, Ext) ++ ".o".
|
||||
|
||||
so_name(Config, AppFile) ->
|
||||
so_specs(Config, AppFile, Bins) ->
|
||||
%% Check config to see if a custom so_name has been specified
|
||||
PortName = case rebar_config:get(Config, so_name, undefined) of
|
||||
?INFO("config ~p\n", [Config]),
|
||||
case rebar_config:get(Config, so_specs, undefined) of
|
||||
undefined ->
|
||||
%% Get the app name, which we'll use to
|
||||
%% generate the linked port driver name
|
||||
case rebar_app_utils:load_app_file(AppFile) of
|
||||
{ok, AppName, _} ->
|
||||
lists:concat([AppName, "_drv.so"]);
|
||||
SoName = ?FMT("priv/~s", [lists:concat([AppName, "_drv.so"])]),
|
||||
[{SoName, Bins}];
|
||||
error ->
|
||||
?FAIL
|
||||
end;
|
||||
Soname ->
|
||||
Soname
|
||||
end,
|
||||
|
||||
%% Construct the driver name
|
||||
?FMT("priv/~s", [PortName]).
|
||||
SoSpecs -> SoSpecs
|
||||
end.
|
||||
|
|
Loading…
Reference in a new issue