diff options
Diffstat (limited to 'lib/sasl/src/systools_make.erl')
-rw-r--r-- | lib/sasl/src/systools_make.erl | 420 |
1 files changed, 301 insertions, 119 deletions
diff --git a/lib/sasl/src/systools_make.erl b/lib/sasl/src/systools_make.erl index 7f400f5cce..61e660e918 100644 --- a/lib/sasl/src/systools_make.erl +++ b/lib/sasl/src/systools_make.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. +%% Copyright Ericsson AB 1996-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -31,6 +31,8 @@ -export([read_application/4]). +-export([make_hybrid_boot/5]). + -import(lists, [filter/2, keysort/2, keysearch/3, map/2, reverse/1, append/1, foldl/3, member/2, foreach/2]). @@ -56,6 +58,7 @@ %% {variables,[{Name,AbsString}]} %% {machine, jam | beam | vee} %% exref | {exref, [AppName]} +%% no_warn_sasl %%----------------------------------------------------------------- make_script(RelName) when is_list(RelName) -> @@ -86,7 +89,8 @@ make_script(RelName, Output, Flags) when is_list(RelName), Path = make_set(Path1 ++ code:get_path()), ModTestP = {member(src_tests, Flags),xref_p(Flags)}, case get_release(RelName, Path, ModTestP, machine(Flags)) of - {ok, Release, Appls, Warnings} -> + {ok, Release, Appls, Warnings0} -> + Warnings = wsasl(Flags, Warnings0), case systools_lib:werror(Flags, Warnings) of true -> return(ok,Warnings,Flags); @@ -110,7 +114,13 @@ make_script(RelName, _Output, Flags) when is_list(Flags) -> make_script(RelName, _Output, Flags) -> badarg(Flags,[RelName, Flags]). -%% Inlined. + +wsasl(Options, Warnings) -> + case lists:member(no_warn_sasl,Options) of + true -> lists:delete({warning,missing_sasl},Warnings); + false -> Warnings + end. + badarg(BadArg, Args) -> erlang:error({badarg,BadArg}, Args). @@ -162,6 +172,118 @@ return({error,Mod,Error},_,Flags) -> error end. + +%%----------------------------------------------------------------- +%% Make hybrid boot file for upgrading emulator. The resulting boot +%% file is a combination of the two input files, where kernel, stdlib +%% and sasl versions are taken from the second file (the boot file of +%% the new release), and all other application versions from the first +%% file (the boot file of the old release). +%% +%% The most important thing that can fail here is that the input boot +%% files do not contain all three base applications - kernel, stdlib +%% and sasl. +%% +%% TmpVsn = string(), +%% Paths = {KernelPath,StdlibPath,SaslPath} +%% Returns {ok,Boot} | {error,Reason} +%% Boot1 = Boot2 = Boot = binary() +%% Reason = {app_not_found,App} | {app_not_replaced,App} +%% App = kernel | stdlib | sasl +make_hybrid_boot(TmpVsn, Boot1, Boot2, Paths, Args) -> + catch do_make_hybrid_boot(TmpVsn, Boot1, Boot2, Paths, Args). +do_make_hybrid_boot(TmpVsn, Boot1, Boot2, Paths, Args) -> + {script,{_RelName1,_RelVsn1},Script1} = binary_to_term(Boot1), + {script,{RelName2,_RelVsn2},Script2} = binary_to_term(Boot2), + MatchPaths = get_regexp_path(Paths), + NewScript1 = replace_paths(Script1,MatchPaths), + {Kernel,Stdlib,Sasl} = get_apps(Script2,undefined,undefined,undefined), + NewScript2 = replace_apps(NewScript1,Kernel,Stdlib,Sasl), + NewScript3 = add_apply_upgrade(NewScript2,Args), + Boot = term_to_binary({script,{RelName2,TmpVsn},NewScript3}), + {ok,Boot}. + +%% For each app, compile a regexp that can be used for finding its path +get_regexp_path({KernelPath,StdlibPath,SaslPath}) -> + {ok,KernelMP} = re:compile("kernel-[0-9\.]+",[unicode]), + {ok,StdlibMP} = re:compile("stdlib-[0-9\.]+",[unicode]), + {ok,SaslMP} = re:compile("sasl-[0-9\.]+",[unicode]), + [{KernelMP,KernelPath},{StdlibMP,StdlibPath},{SaslMP,SaslPath}]. + +%% For each path in the script, check if it matches any of the MPs +%% found above, and if so replace it with the correct new path. +replace_paths([{path,Path}|Script],MatchPaths) -> + [{path,replace_path(Path,MatchPaths)}|replace_paths(Script,MatchPaths)]; +replace_paths([Stuff|Script],MatchPaths) -> + [Stuff|replace_paths(Script,MatchPaths)]; +replace_paths([],_) -> + []. + +replace_path([Path|Paths],MatchPaths) -> + [do_replace_path(Path,MatchPaths)|replace_path(Paths,MatchPaths)]; +replace_path([],_) -> + []. + +do_replace_path(Path,[{MP,ReplacePath}|MatchPaths]) -> + case re:run(Path,MP,[{capture,none}]) of + nomatch -> do_replace_path(Path,MatchPaths); + match -> ReplacePath + end; +do_replace_path(Path,[]) -> + Path. + +%% Return the entries for loading the three base applications +get_apps([{kernelProcess,application_controller, + {application_controller,start,[{application,kernel,_}]}}=Kernel| + Script],_,Stdlib,Sasl) -> + get_apps(Script,Kernel,Stdlib,Sasl); +get_apps([{apply,{application,load,[{application,stdlib,_}]}}=Stdlib|Script], + Kernel,_,Sasl) -> + get_apps(Script,Kernel,Stdlib,Sasl); +get_apps([{apply,{application,load,[{application,sasl,_}]}}=Sasl|_Script], + Kernel,Stdlib,_) -> + {Kernel,Stdlib,Sasl}; +get_apps([_|Script],Kernel,Stdlib,Sasl) -> + get_apps(Script,Kernel,Stdlib,Sasl); +get_apps([],undefined,_,_) -> + throw({error,{app_not_found,kernel}}); +get_apps([],_,undefined,_) -> + throw({error,{app_not_found,stdlib}}); +get_apps([],_,_,undefined) -> + throw({error,{app_not_found,sasl}}). + + +%% Replace the entries for loading the base applications +replace_apps([{kernelProcess,application_controller, + {application_controller,start,[{application,kernel,_}]}}| + Script],Kernel,Stdlib,Sasl) -> + [Kernel|replace_apps(Script,undefined,Stdlib,Sasl)]; +replace_apps([{apply,{application,load,[{application,stdlib,_}]}}|Script], + Kernel,Stdlib,Sasl) -> + [Stdlib|replace_apps(Script,Kernel,undefined,Sasl)]; +replace_apps([{apply,{application,load,[{application,sasl,_}]}}|Script], + _Kernel,_Stdlib,Sasl) -> + [Sasl|Script]; +replace_apps([Stuff|Script],Kernel,Stdlib,Sasl) -> + [Stuff|replace_apps(Script,Kernel,Stdlib,Sasl)]; +replace_apps([],undefined,undefined,_) -> + throw({error,{app_not_replaced,sasl}}); +replace_apps([],undefined,_,_) -> + throw({error,{app_not_replaced,stdlib}}); +replace_apps([],_,_,_) -> + throw({error,{app_not_replaced,kernel}}). + + +%% Finally add an apply of release_handler:new_emulator_upgrade - which will +%% complete the execution of the upgrade script (relup). +add_apply_upgrade(Script,Args) -> + [{progress, started} | RevScript] = lists:reverse(Script), + lists:reverse([{progress,started}, + {apply,{release_handler,new_emulator_upgrade,Args}} | + RevScript]). + + + %%----------------------------------------------------------------- %% Create a release package from a release file. %% Options is a list of {path, Path} | silent | @@ -250,13 +372,13 @@ get_release(File, Path, ModTestP, Machine) -> end. get_release1(File, Path, ModTestP, Machine) -> - {ok, Release} = read_release(File, Path), + {ok, Release, Warnings1} = read_release(File, Path), {ok, Appls0} = collect_applications(Release, Path), {ok, Appls1} = check_applications(Appls0), - {ok, Appls2} = sort_included_applications(Appls1, Release), % OTP-4121 - {ok, Warnings} = check_modules(Appls2, Path, ModTestP, Machine), + {ok, Appls2} = sort_used_and_incl_appls(Appls1, Release), % OTP-4121, OTP-9984 + {ok, Warnings2} = check_modules(Appls2, Path, ModTestP, Machine), {ok, Appls} = sort_appls(Appls2), - {ok, Release, Appls, Warnings}. + {ok, Release, Appls, Warnings1 ++ Warnings2}. %%______________________________________________________________________ %% read_release(File, Path) -> {ok, #release} | throw({error, What}) @@ -271,11 +393,12 @@ read_release(File, Path) -> check_rel(Release) -> case catch check_rel1(Release) of - {ok, {Name,Vsn,Evsn,Appl,Incl}} -> + {ok, {Name,Vsn,Evsn,Appl,Incl}, Ws} -> {ok, #release{name=Name, vsn=Vsn, erts_vsn=Evsn, applications=Appl, - incl_apps=Incl}}; + incl_apps=Incl}, + Ws}; {error, Error} -> throw({error,?MODULE,Error}); Error -> @@ -286,8 +409,8 @@ check_rel1({release,{Name,Vsn},{erts,EVsn},Appl}) when is_list(Appl) -> check_name(Name), check_vsn(Vsn), check_evsn(EVsn), - {Appls,Incls} = check_appl(Appl), - {ok, {Name,Vsn,EVsn,Appls,Incls}}; + {{Appls,Incls},Ws} = check_appl(Appl), + {ok, {Name,Vsn,EVsn,Appls,Incls},Ws}; check_rel1(_) -> {error, badly_formatted_release}. @@ -340,25 +463,35 @@ check_appl(Appl) -> end, Appl) of [] -> - mandatory_applications(Appl), - split_app_incl(Appl); + {ApplsNoIncls,Incls} = split_app_incl(Appl), + {ok,Ws} = mandatory_applications(ApplsNoIncls,undefined, + undefined,undefined), + {{ApplsNoIncls,Incls},Ws}; Illegal -> throw({error, {illegal_applications,Illegal}}) end. -mandatory_applications(Appl) -> - AppNames = map(fun(AppT) -> element(1, AppT) end, - Appl), - Mand = mandatory_applications(), - case filter(fun(X) -> member(X, AppNames) end, Mand) of - Mand -> - ok; - _ -> - throw({error, {missing_mandatory_app, Mand}}) - end. - -mandatory_applications() -> - [kernel, stdlib]. +mandatory_applications([{kernel,_,Type}|Apps],undefined,Stdlib,Sasl) -> + mandatory_applications(Apps,Type,Stdlib,Sasl); +mandatory_applications([{stdlib,_,Type}|Apps],Kernel,undefined,Sasl) -> + mandatory_applications(Apps,Kernel,Type,Sasl); +mandatory_applications([{sasl,_,Type}|Apps],Kernel,Stdlib,undefined) -> + mandatory_applications(Apps,Kernel,Stdlib,Type); +mandatory_applications([_|Apps],Kernel,Stdlib,Sasl) -> + mandatory_applications(Apps,Kernel,Stdlib,Sasl); +mandatory_applications([],Type,_,_) when Type=/=permanent -> + error_mandatory_application(kernel,Type); +mandatory_applications([],_,Type,_) when Type=/=permanent -> + error_mandatory_application(stdlib,Type); +mandatory_applications([],_,_,undefined) -> + {ok, [{warning,missing_sasl}]}; +mandatory_applications([],_,_,_) -> + {ok,[]}. + +error_mandatory_application(App,undefined) -> + throw({error, {missing_mandatory_app, App}}); +error_mandatory_application(App,Type) -> + throw({error, {mandatory_app, App, Type}}). split_app_incl(Appl) -> split_app_incl(Appl, [], []). @@ -709,34 +842,45 @@ undefined_applications(Appls) -> filter(fun(X) -> not member(X, Defined) end, Uses). %%______________________________________________________________________ -%% sort_included_applications(Applications, Release) -> Applications +%% sort_used_and_incl_appls(Applications, Release) -> Applications %% Applications = [{{Name,Vsn},#application}] %% Release = #release{} %% -%% Check that included applications are given in the same order as in -%% the release resource file (.rel). Otherwise load instructions in -%% the boot script, and consequently release upgrade instructions in -%% relup, may end up in the wrong order. +%% OTP-4121, OTP-9984 +%% Check that used and included applications are given in the same +%% order as in the release resource file (.rel). Otherwise load and +%% start instructions in the boot script, and consequently release +%% upgrade instructions in relup, may end up in the wrong order. -sort_included_applications(Applications, Release) when is_tuple(Release) -> +sort_used_and_incl_appls(Applications, Release) when is_tuple(Release) -> {ok, - sort_included_applications(Applications, Release#release.applications)}; - -sort_included_applications([{Tuple,Appl}|Appls], OrderedAppls) -> - case Appl#application.includes of - Incls when length(Incls)>1 -> - IndexedIncls = find_pos(Incls, OrderedAppls), - SortedIndexedIncls = lists:keysort(1, IndexedIncls), - Incls2 = lists:map(fun({_Index,Name}) -> Name end, - SortedIndexedIncls), - Appl2 = Appl#application{includes=Incls2}, - [{Tuple,Appl2}|sort_included_applications(Appls, OrderedAppls)]; - _Incls -> - [{Tuple,Appl}|sort_included_applications(Appls, OrderedAppls)] - end; -sort_included_applications([], _OrderedAppls) -> + sort_used_and_incl_appls(Applications, Release#release.applications)}; + +sort_used_and_incl_appls([{Tuple,Appl}|Appls], OrderedAppls) -> + Incls2 = + case Appl#application.includes of + Incls when length(Incls)>1 -> + sort_appl_list(Incls, OrderedAppls); + Incls -> + Incls + end, + Uses2 = + case Appl#application.uses of + Uses when length(Uses)>1 -> + sort_appl_list(Uses, OrderedAppls); + Uses -> + Uses + end, + Appl2 = Appl#application{includes=Incls2, uses=Uses2}, + [{Tuple,Appl2}|sort_used_and_incl_appls(Appls, OrderedAppls)]; +sort_used_and_incl_appls([], _OrderedAppls) -> []. +sort_appl_list(List, Order) -> + IndexedList = find_pos(List, Order), + SortedIndexedList = lists:keysort(1, IndexedList), + lists:map(fun({_Index,Name}) -> Name end, SortedIndexedList). + find_pos([Name|Incs], OrderedAppls) -> [find_pos(1, Name, OrderedAppls)|find_pos(Incs, OrderedAppls)]; find_pos([], _OrderedAppls) -> @@ -1120,7 +1264,8 @@ sort_appls(Appls) -> {ok, sort_appls(Appls, [], [], [])}. sort_appls([{N, A}|T], Missing, Circular, Visited) -> {Name,_Vsn} = N, - {Uses, T1, NotFnd1} = find_all(Name, A#application.uses, T, Visited, [], []), + {Uses, T1, NotFnd1} = find_all(Name, lists:reverse(A#application.uses), + T, Visited, [], []), {Incs, T2, NotFnd2} = find_all(Name, lists:reverse(A#application.includes), T1, Visited, [], []), Missing1 = NotFnd1 ++ NotFnd2 ++ Missing, @@ -1323,15 +1468,18 @@ pack_app(#application{name=Name,vsn=V,id=Id,description=D,modules=M, {applications, App}, {included_applications, Incs}, {env, Env}, - {start_phases, SF}, {maxT, MaxT}, {maxP, MaxP} | - behave(Mod)]}. - + behave([{start_phases,SF},{mod,Mod}])]}. + +behave([{mod,[]}|T]) -> + behave(T); +behave([{start_phases,undefined}|T]) -> + behave(T); +behave([H|T]) -> + [H|behave(T)]; behave([]) -> - []; -behave(Mod) -> - [{mod, Mod}]. + []. %%______________________________________________________________________ %% mandatory modules; this modules must be loaded before processes @@ -1510,8 +1658,19 @@ add_system_files(Tar, RelName, Release, Path1) -> SVsn = Release#release.vsn, RelName0 = filename:basename(RelName), + RelVsnDir = filename:join("releases", SVsn), + + %% OTP-9746: store rel file in releases/<vsn> + %% Adding rel file to + %% 1) releases directory - so it can be easily extracted + %% separately (see release_handler:unpack_release) + %% 2) releases/<vsn> - so the file must not be explicitly moved + %% after unpack. add_to_tar(Tar, RelName ++ ".rel", filename:join("releases", RelName0 ++ ".rel")), + add_to_tar(Tar, RelName ++ ".rel", + filename:join(RelVsnDir, RelName0 ++ ".rel")), + %% OTP-6226 Look for the system files not only in cwd %% -- @@ -1527,26 +1686,27 @@ add_system_files(Tar, RelName, Release, Path1) -> [RelDir, "."|Path1] end, - ToDir = filename:join("releases", SVsn), case lookup_file(RelName0 ++ ".boot", Path) of false -> throw({error, {tar_error,{add, RelName0++".boot",enoent}}}); Boot -> - add_to_tar(Tar, Boot, filename:join(ToDir, "start.boot")) + add_to_tar(Tar, Boot, filename:join(RelVsnDir, "start.boot")) end, case lookup_file("relup", Path) of false -> ignore; Relup -> - add_to_tar(Tar, Relup, filename:join(ToDir, "relup")) + check_relup(Relup), + add_to_tar(Tar, Relup, filename:join(RelVsnDir, "relup")) end, case lookup_file("sys.config", Path) of false -> ignore; Sys -> - add_to_tar(Tar, Sys, filename:join(ToDir, "sys.config")) + check_sys_config(Sys), + add_to_tar(Tar, Sys, filename:join(RelVsnDir, "sys.config")) end, ok. @@ -1562,6 +1722,44 @@ lookup_file(Name, [Dir|Path]) -> lookup_file(_Name, []) -> false. +%% Check that relup can be parsed and has expected format +check_relup(File) -> + case file:consult(File) of + {ok,[{Vsn,UpFrom,DownTo}]} when is_list(Vsn), is_integer(hd(Vsn)), + is_list(UpFrom), is_list(DownTo) -> + ok; + {ok,_} -> + throw({error,{tar_error,{add,"relup",[invalid_format]}}}); + Other -> + throw({error,{tar_error,{add,"relup",[Other]}}}) + end. + +%% Check that sys.config can be parsed and has expected format +check_sys_config(File) -> + case file:consult(File) of + {ok,[SysConfig]} -> + case lists:all(fun({App,KeyVals}) when is_atom(App), + is_list(KeyVals)-> + true; + (OtherConfig) when is_list(OtherConfig), + is_integer(hd(OtherConfig)) -> + true; + (_) -> + false + end, + SysConfig) of + true -> + ok; + false -> + throw({error,{tar_error, + {add,"sys.config",[invalid_format]}}}) + end; + {ok,_} -> + throw({error,{tar_error,{add,"sys.config",[invalid_format]}}}); + Other -> + throw({error,{tar_error,{add,"sys.config",[Other]}}}) + end. + %%______________________________________________________________________ %% Add either a application located under a variable dir or all other %% applications to a tar file. @@ -1850,90 +2048,67 @@ get_flag(_,_) -> false. %% Check Options for make_script check_args_script(Args) -> - cas(Args, - {undef, undef, undef, undef, undef, undef, undef, undef, - undef, []}). + cas(Args, []). -cas([], {_Path,_Sil,_Loc,_Test,_Var,_Mach,_Xref,_XrefApps,_Werror, X}) -> +cas([], X) -> X; %%% path --------------------------------------------------------------- -cas([{path, P} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_list(P) -> +cas([{path, P} | Args], X) when is_list(P) -> case check_path(P) of ok -> - cas(Args, {P, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X}); + cas(Args, X); error -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X++[{path,P}]}) + cas(Args, X++[{path,P}]) end; %%% silent ------------------------------------------------------------- -cas([silent | Args], {Path, _Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, silent, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X}); +cas([silent | Args], X) -> + cas(Args, X); %%% local -------------------------------------------------------------- -cas([local | Args], {Path, Sil, _Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, Sil, local, Test, Var, Mach, Xref, XrefApps, - Werror, X}); +cas([local | Args], X) -> + cas(Args, X); %%% src_tests ------------------------------------------------------- -cas([src_tests | Args], {Path, Sil, Loc, _Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, - {Path, Sil, Loc, src_tests, Var, Mach, Xref, Werror, XrefApps,X}); +cas([src_tests | Args], X) -> + cas(Args, X); %%% variables ---------------------------------------------------------- -cas([{variables, V} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_list(V) -> +cas([{variables, V} | Args], X) when is_list(V) -> case check_vars(V) of ok -> - cas(Args, - {Path, Sil, Loc, Test, V, Mach, Xref, XrefApps, Werror, X}); + cas(Args, X); error -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X++[{variables, V}]}) + cas(Args, X++[{variables, V}]) end; %%% machine ------------------------------------------------------------ -cas([{machine, M} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_atom(M) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, X}); +cas([{machine, M} | Args], X) when is_atom(M) -> + cas(Args, X); %%% exref -------------------------------------------------------------- -cas([exref | Args], {Path, Sil, Loc, Test, Var, Mach, _Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, exref, XrefApps, Werror, X}); +cas([exref | Args], X) -> + cas(Args, X); %%% exref Apps --------------------------------------------------------- -cas([{exref, Apps} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_list(Apps) -> +cas([{exref, Apps} | Args], X) when is_list(Apps) -> case check_apps(Apps) of ok -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, - Xref, Apps, Werror, X}); + cas(Args, X); error -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, - Xref, XrefApps, Werror, X++[{exref, Apps}]}) + cas(Args, X++[{exref, Apps}]) end; %%% outdir Dir --------------------------------------------------------- -cas([{outdir, Dir} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_list(Dir) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, X}); +cas([{outdir, Dir} | Args], X) when is_list(Dir) -> + cas(Args, X); %%% otp_build (secret, not documented) --------------------------------- -cas([otp_build | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, X}); +cas([otp_build | Args], X) -> + cas(Args, X); +%%% warnings_as_errors ------------------------------------------------- +cas([warnings_as_errors | Args], X) -> + cas(Args, X); +%%% no_warn_sasl ------------------------------------------------------- +cas([no_warn_sasl | Args], X) -> + cas(Args, X); %%% no_module_tests (kept for backwards compatibility, but ignored) ---- -cas([no_module_tests | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, X}); -%%% warnings_as_errors (kept for backwards compatibility, but ignored) ---- -cas([warnings_as_errors | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, _Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - warnings_as_errors, X}); +cas([no_module_tests | Args], X) -> + cas(Args, X); %%% ERROR -------------------------------------------------------------- -cas([Y | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, - X++[Y]}). +cas([Y | Args], X) -> + cas(Args, X++[Y]). @@ -2072,9 +2247,12 @@ format_error({missing_parameter,Par}) -> format_error({illegal_applications,Names}) -> io_lib:format("Illegal applications in the release file: ~p~n", [Names]); -format_error({missing_mandatory_app,Names}) -> - io_lib:format("Mandatory applications (~p) must be specified in the release file~n", - [Names]); +format_error({missing_mandatory_app,Name}) -> + io_lib:format("Mandatory application ~p must be specified in the release file~n", + [Name]); +format_error({mandatory_app,Name,Type}) -> + io_lib:format("Mandatory application ~p must be of type 'permanent' in the release file. Is '~p'.~n", + [Name,Type]); format_error({duplicate_register,Dups}) -> io_lib:format("Duplicated register names: ~n~s", [map(fun({{Reg,App1,_,_},{Reg,App2,_,_}}) -> @@ -2198,5 +2376,9 @@ form_warn(Prefix, {exref_undef, Undef}) -> [Prefix,M,F,A]) end, map(F, Undef); +form_warn(Prefix, missing_sasl) -> + io_lib:format("~s: Missing application sasl. " + "Can not upgrade with this release~n", + [Prefix]); form_warn(Prefix, What) -> io_lib:format("~s ~p~n", [Prefix,What]). |