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
|
%% * 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
|
%% * port_envs - Erlang list of key/value pairs which will control the environment when
|
||||||
%% running the compiler and linker. By default, the following variables
|
%% running the compiler and linker. By default, the following variables
|
||||||
%% are defined:
|
%% are defined:
|
||||||
|
@ -92,19 +95,21 @@ compile(Config, AppFile) ->
|
||||||
{NewBins, ExistingBins} = compile_each(Sources, Config, Env, [], []),
|
{NewBins, ExistingBins} = compile_each(Sources, Config, Env, [], []),
|
||||||
|
|
||||||
%% Construct the driver name and make sure priv/ exists
|
%% Construct the driver name and make sure priv/ exists
|
||||||
SoName = so_name(Config, AppFile),
|
SoSpecs = so_specs(Config, AppFile, NewBins ++ ExistingBins),
|
||||||
ok = filelib:ensure_dir(SoName),
|
?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
|
%% Only relink if necessary, given the SoName and list of new binaries
|
||||||
case needs_link(SoName, NewBins) of
|
lists:foreach(fun({SoName,Bins}) ->
|
||||||
true ->
|
case needs_link(SoName, sets:to_list(sets:intersection([sets:from_list(Bins),sets:from_list(NewBins)]))) of
|
||||||
AllBins = string:join(NewBins ++ ExistingBins, " "),
|
true ->
|
||||||
rebar_utils:sh_failfast(?FMT("$CC ~s $LDFLAGS $DRV_LDFLAGS -o ~s",
|
rebar_utils:sh_failfast(?FMT("$CC ~s $LDFLAGS $DRV_LDFLAGS -o ~s",
|
||||||
[AllBins, SoName]), Env);
|
[string:join(Bins, " "), SoName]), Env);
|
||||||
false ->
|
false ->
|
||||||
?INFO("Skipping relink of ~s\n", [SoName]),
|
?INFO("Skipping relink of ~s\n", [SoName]),
|
||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
|
end, SoSpecs)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
clean(Config, AppFile) ->
|
clean(Config, AppFile) ->
|
||||||
|
@ -113,7 +118,7 @@ clean(Config, AppFile) ->
|
||||||
rebar_file_utils:delete_each([source_to_bin(S) || S <- Sources]),
|
rebar_file_utils:delete_each([source_to_bin(S) || S <- Sources]),
|
||||||
|
|
||||||
%% Delete the .so file
|
%% 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 the cleanup script, if it exists
|
||||||
run_cleanup_hook(Config).
|
run_cleanup_hook(Config).
|
||||||
|
@ -130,6 +135,11 @@ expand_sources([], Acc) ->
|
||||||
expand_sources([Spec | Rest], Acc) ->
|
expand_sources([Spec | Rest], Acc) ->
|
||||||
Acc2 = filelib:wildcard(Spec) ++ Acc,
|
Acc2 = filelib:wildcard(Spec) ++ Acc,
|
||||||
expand_sources(Rest, Acc2).
|
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) ->
|
run_precompile_hook(Config, Env) ->
|
||||||
case rebar_config:get(Config, port_pre_script, undefined) of
|
case rebar_config:get(Config, port_pre_script, undefined) of
|
||||||
|
@ -319,21 +329,19 @@ source_to_bin(Source) ->
|
||||||
Ext = filename:extension(Source),
|
Ext = filename:extension(Source),
|
||||||
filename:rootname(Source, Ext) ++ ".o".
|
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
|
%% 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 ->
|
undefined ->
|
||||||
%% Get the app name, which we'll use to
|
%% Get the app name, which we'll use to
|
||||||
%% generate the linked port driver name
|
%% generate the linked port driver name
|
||||||
case rebar_app_utils:load_app_file(AppFile) of
|
case rebar_app_utils:load_app_file(AppFile) of
|
||||||
{ok, AppName, _} ->
|
{ok, AppName, _} ->
|
||||||
lists:concat([AppName, "_drv.so"]);
|
SoName = ?FMT("priv/~s", [lists:concat([AppName, "_drv.so"])]),
|
||||||
|
[{SoName, Bins}];
|
||||||
error ->
|
error ->
|
||||||
?FAIL
|
?FAIL
|
||||||
end;
|
end;
|
||||||
Soname ->
|
SoSpecs -> SoSpecs
|
||||||
Soname
|
end.
|
||||||
end,
|
|
||||||
|
|
||||||
%% Construct the driver name
|
|
||||||
?FMT("priv/~s", [PortName]).
|
|
||||||
|
|
Loading…
Reference in a new issue