|
|
@ -29,10 +29,6 @@ |
|
|
|
-export([compile/2, |
|
|
|
clean/2]). |
|
|
|
|
|
|
|
%% for internal use only |
|
|
|
-export([test_compile/3, |
|
|
|
info/2]). |
|
|
|
|
|
|
|
-include("rebar.hrl"). |
|
|
|
-include_lib("stdlib/include/erl_compile.hrl"). |
|
|
|
|
|
|
@ -128,159 +124,10 @@ clean(Config, AppDir) -> |
|
|
|
lists:foreach(fun(Dir) -> delete_dir(Dir, dirs(Dir)) end, dirs(filename:join(AppDir, "ebin"))), |
|
|
|
ok. |
|
|
|
|
|
|
|
%% =================================================================== |
|
|
|
%% .erl Compilation API (externally used by only eunit and qc) |
|
|
|
%% =================================================================== |
|
|
|
|
|
|
|
test_compile(Config, Cmd, OutDir) -> |
|
|
|
%% Obtain all the test modules for inclusion in the compile stage. |
|
|
|
TestErls = rebar_utils:find_files(filename:absname("test"), ?RE_PREFIX".*\\.erl\$"), |
|
|
|
|
|
|
|
ErlOpts = rebar_utils:erl_opts(Config), |
|
|
|
{Config1, ErlOpts1} = test_compile_config_and_opts(Config, ErlOpts, Cmd), |
|
|
|
|
|
|
|
%% Copy source files to eunit dir for cover in case they are not directly |
|
|
|
%% in src but in a subdirectory of src. Cover only looks in cwd and ../src |
|
|
|
%% for source files. Also copy files from src_dirs. |
|
|
|
SrcDirs = rebar_dir:src_dirs(proplists:append_values(src_dirs, ErlOpts1)), |
|
|
|
SrcErls = lists:foldl( |
|
|
|
fun(Dir, Acc) -> |
|
|
|
Files = rebar_utils:find_files( |
|
|
|
filename:absname(Dir), ?RE_PREFIX".*\\.erl\$"), |
|
|
|
lists:append(Acc, Files) |
|
|
|
end, [], SrcDirs), |
|
|
|
|
|
|
|
%% If it is not the first time rebar eunit or rebar qc is executed, |
|
|
|
%% there will be source files already present in Dir. Since some |
|
|
|
%% SCMs (like Perforce) set the source files as being read only (unless |
|
|
|
%% they are checked out), we need to be sure that the files already |
|
|
|
%% present in Dir are writable before doing the copy. This is done |
|
|
|
%% here by removing any file that was already present before calling |
|
|
|
%% rebar_file_utils:cp_r. |
|
|
|
|
|
|
|
%% Get the full path to a file that was previously copied in OutDir |
|
|
|
ToCleanUp = fun(F, Acc) -> |
|
|
|
F2 = filename:basename(F), |
|
|
|
F3 = filename:join([OutDir, F2]), |
|
|
|
case filelib:is_regular(F3) of |
|
|
|
true -> [F3|Acc]; |
|
|
|
false -> Acc |
|
|
|
end |
|
|
|
end, |
|
|
|
|
|
|
|
ok = rebar_file_utils:delete_each(lists:foldl(ToCleanUp, [], TestErls)), |
|
|
|
ok = rebar_file_utils:delete_each(lists:foldl(ToCleanUp, [], SrcErls)), |
|
|
|
|
|
|
|
ok = rebar_file_utils:cp_r(SrcErls ++ TestErls, OutDir), |
|
|
|
|
|
|
|
%% Compile erlang code to OutDir, using a tweaked config |
|
|
|
%% with appropriate defines for eunit, and include all the test modules |
|
|
|
%% as well. |
|
|
|
ok = doterl_compile(Config1, OutDir, TestErls, ErlOpts1), |
|
|
|
|
|
|
|
{ok, SrcErls}. |
|
|
|
|
|
|
|
%% =================================================================== |
|
|
|
%% Internal functions |
|
|
|
%% =================================================================== |
|
|
|
|
|
|
|
info(help, compile) -> |
|
|
|
info_help("Build *.erl, *.yrl, *.xrl, and *.mib sources"); |
|
|
|
info(help, clean) -> |
|
|
|
info_help("Delete *.erl, *.yrl, *.xrl, and *.mib build results"). |
|
|
|
|
|
|
|
info_help(Description) -> |
|
|
|
?CONSOLE( |
|
|
|
"~s.~n" |
|
|
|
"~n" |
|
|
|
"Valid rebar.config options:~n" |
|
|
|
" ~p~n" |
|
|
|
" ~p~n" |
|
|
|
" ~p~n" |
|
|
|
" ~p~n" |
|
|
|
" ~p~n" |
|
|
|
" ~p~n" |
|
|
|
" ~p~n" |
|
|
|
" ~p~n", |
|
|
|
[ |
|
|
|
Description, |
|
|
|
{erl_opts, [no_debug_info, |
|
|
|
{i, "myinclude"}, |
|
|
|
{src_dirs, ["src", "src2", "src3"]}, |
|
|
|
{platform_define, |
|
|
|
"(linux|solaris|freebsd|darwin)", 'HAVE_SENDFILE'}, |
|
|
|
{platform_define, "(linux|freebsd)", 'BACKLOG', 128}, |
|
|
|
{platform_define, "R13", 'old_inets'}]}, |
|
|
|
{erl_first_files, ["src/mymib1.erl", "src/mymib2.erl"]}, |
|
|
|
{mib_opts, []}, |
|
|
|
{mib_first_files, []}, |
|
|
|
{xrl_opts, []}, |
|
|
|
{xrl_first_files, []}, |
|
|
|
{yrl_opts, []}, |
|
|
|
{yrl_first_files, []} |
|
|
|
]). |
|
|
|
|
|
|
|
test_compile_config_and_opts(Config, ErlOpts, Cmd) -> |
|
|
|
{Config1, TriqOpts} = triq_opts(Config), |
|
|
|
{Config2, PropErOpts} = proper_opts(Config1), |
|
|
|
{Config3, EqcOpts} = eqc_opts(Config2), |
|
|
|
|
|
|
|
%% NOTE: For consistency, all *_first_files lists should be |
|
|
|
%% retrieved via rebar_state:get. Right now |
|
|
|
%% erl_first_files, eunit_first_files, and qc_first_files use |
|
|
|
%% rebar_state:get_list and are inherited, but xrl_first_files |
|
|
|
%% and yrl_first_files use rebar_state:get. Inheritance of |
|
|
|
%% *_first_files is questionable as the file would need to exist |
|
|
|
%% in all project directories for it to work. |
|
|
|
OptsAtom = list_to_atom(Cmd ++ "_compile_opts"), |
|
|
|
TestOpts = rebar_state:get(Config3, OptsAtom, []), |
|
|
|
Opts0 = [{d, 'TEST'}] ++ |
|
|
|
ErlOpts ++ TestOpts ++ TriqOpts ++ PropErOpts ++ EqcOpts, |
|
|
|
Opts = [O || O <- Opts0, O =/= no_debug_info], |
|
|
|
Config4 = rebar_state:set(Config3, erl_opts, Opts), |
|
|
|
|
|
|
|
FirstFilesAtom = list_to_atom(Cmd ++ "_first_files"), |
|
|
|
FirstErls = rebar_state:get(Config4, FirstFilesAtom, []), |
|
|
|
Config5 = rebar_state:set(Config4, erl_first_files, FirstErls), |
|
|
|
{Config5, Opts}. |
|
|
|
|
|
|
|
triq_opts(Config) -> |
|
|
|
{NewConfig, IsAvail} = is_lib_avail(Config, is_triq_avail, triq, |
|
|
|
"triq.hrl", "Triq"), |
|
|
|
Opts = define_if('TRIQ', IsAvail), |
|
|
|
{NewConfig, Opts}. |
|
|
|
|
|
|
|
proper_opts(Config) -> |
|
|
|
{NewConfig, IsAvail} = is_lib_avail(Config, is_proper_avail, proper, |
|
|
|
"proper.hrl", "PropEr"), |
|
|
|
Opts = define_if('PROPER', IsAvail), |
|
|
|
{NewConfig, Opts}. |
|
|
|
|
|
|
|
eqc_opts(Config) -> |
|
|
|
{NewConfig, IsAvail} = is_lib_avail(Config, is_eqc_avail, eqc, |
|
|
|
"eqc.hrl", "QuickCheck"), |
|
|
|
Opts = define_if('EQC', IsAvail), |
|
|
|
{NewConfig, Opts}. |
|
|
|
|
|
|
|
define_if(Def, true) -> [{d, Def}]; |
|
|
|
define_if(_Def, false) -> []. |
|
|
|
|
|
|
|
is_lib_avail(Config, DictKey, Mod, Hrl, Name) -> |
|
|
|
case rebar_state:get(Config, DictKey, undefined) of |
|
|
|
undefined -> |
|
|
|
IsAvail = case code:lib_dir(Mod, include) of |
|
|
|
{error, bad_name} -> |
|
|
|
false; |
|
|
|
Dir -> |
|
|
|
filelib:is_regular(filename:join(Dir, Hrl)) |
|
|
|
end, |
|
|
|
NewConfig = rebar_state:set(Config, DictKey, IsAvail), |
|
|
|
?DEBUG("~s availability: ~p\n", [Name, IsAvail]), |
|
|
|
{NewConfig, IsAvail}; |
|
|
|
IsAvail -> |
|
|
|
{Config, IsAvail} |
|
|
|
end. |
|
|
|
|
|
|
|
-spec doterl_compile(rebar_state:t(), file:filename()) -> ok. |
|
|
|
doterl_compile(State, Dir) -> |
|
|
|
ErlOpts = rebar_utils:erl_opts(State), |
|
|
|