aboutsummaryrefslogtreecommitdiffstats
path: root/lib/reltool/src
diff options
context:
space:
mode:
authorSiri Hansen <[email protected]>2012-02-16 14:58:57 +0100
committerSiri Hansen <[email protected]>2012-03-19 09:48:54 +0100
commita5240467ac0b5428063360fc4a3d67ab9ffa1413 (patch)
tree38acda36f4e798399b5ce6223de7cbd48798b9ea /lib/reltool/src
parent0bc47607cad0c9ad475a7c0a8e7aa5633d00ceb5 (diff)
downloadotp-a5240467ac0b5428063360fc4a3d67ab9ffa1413.tar.gz
otp-a5240467ac0b5428063360fc4a3d67ab9ffa1413.tar.bz2
otp-a5240467ac0b5428063360fc4a3d67ab9ffa1413.zip
[reltool] Link together escript with inlined application
OTP-9968 Make sure that inlined applications in an escript is included/excluded as the escript itself, and forbid explicit configuration of the inlined application.
Diffstat (limited to 'lib/reltool/src')
-rw-r--r--lib/reltool/src/reltool.hrl3
-rw-r--r--lib/reltool/src/reltool_mod_win.erl6
-rw-r--r--lib/reltool/src/reltool_server.erl113
-rw-r--r--lib/reltool/src/reltool_target.erl8
4 files changed, 84 insertions, 46 deletions
diff --git a/lib/reltool/src/reltool.hrl b/lib/reltool/src/reltool.hrl
index 8e80c80e10..0a90c42ce2 100644
--- a/lib/reltool/src/reltool.hrl
+++ b/lib/reltool/src/reltool.hrl
@@ -45,6 +45,7 @@
-type profile() :: development | embedded | standalone.
-type relocatable() :: boolean().
-type escript_file() :: file().
+-type escript_app_name() :: app_name().
-type mod_name() :: atom().
-type app_name() :: atom().
-type app_vsn() :: string(). % e.g. "4.7"
@@ -170,7 +171,7 @@
-record(app,
{ %% Static info
name :: app_name(),
- is_escript :: boolean(),
+ is_escript :: boolean() | {inlined, escript_app_name()},
use_selected_vsn :: boolean() | undefined,
active_dir :: dir(),
sorted_dirs :: [dir()],
diff --git a/lib/reltool/src/reltool_mod_win.erl b/lib/reltool/src/reltool_mod_win.erl
index e1c2fa5100..8cf175547b 100644
--- a/lib/reltool/src/reltool_mod_win.erl
+++ b/lib/reltool/src/reltool_mod_win.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-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
@@ -314,8 +314,8 @@ do_create_code_page(#state{xref_pid = Xref, mod = M} = S, PageName) ->
{ok, App} = reltool_server:get_app(Xref, M#mod.app_name),
ErlBin =
case App#app.is_escript of
- true -> find_escript_bin(App, M);
- false -> find_regular_bin(App, M)
+ false -> find_regular_bin(App, M);
+ _ -> find_escript_bin(App, M)
end,
load_code(Editor, ErlBin),
diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl
index da15d91581..f5abaf0957 100644
--- a/lib/reltool/src/reltool_server.erl
+++ b/lib/reltool/src/reltool_server.erl
@@ -467,20 +467,30 @@ loop(#state{common = C, sys = Sys} = S) ->
do_set_apps(#state{sys = Sys} = S, ChangedApps, Status) ->
%% Create new list of configured applications
- Sys2 = Sys#sys{apps = app_update_config(ChangedApps, Sys#sys.apps)},
+ {SysApps,Status2} = app_update_config(ChangedApps, Sys#sys.apps, Status),
+ Sys2 = Sys#sys{apps = SysApps},
- %% Refresh and analyse
- {S2, Apps, Status2} = refresh(S#state{sys = Sys2}, true, Status),
- Status3 = analyse(S2, Apps, Status2),
+ %% Refresh from filesystem and analyse dependencies
+ {S2, Apps, Status3} = refresh(S#state{sys = Sys2}, true, Status2),
+ Status4 = analyse(S2, Apps, Status3),
- {S2, Status3}.
+ {S2, Status4}.
%% Re-create the #sys.apps list by
%% 1) taking configurable fields from the changed #app records and
%% create new default records
%% 2) removing #app records if no configurable fields are set
%% 3) keeping #app records that are not changed
-app_update_config([Config|Configs],SysApps) ->
+app_update_config([#app{name=Name,is_escript={inlined,Escript}}|Configs],
+ SysApps,Status) ->
+ Text =
+ lists:flatten(
+ io_lib:format("Application ~p is inlined in ~p. Can not change "
+ "configuration for an inlined application.",
+ [Name,Escript])),
+ Status2 = reltool_utils:return_first_error(Status, Text),
+ app_update_config(Configs,SysApps,Status2);
+app_update_config([Config|Configs],SysApps,Status) ->
NewSysApps =
case app_set_config_only(Config) of
{delete,Name} ->
@@ -488,9 +498,9 @@ app_update_config([Config|Configs],SysApps) ->
New ->
lists:ukeymerge(#app.name,[New],SysApps)
end,
- app_update_config(Configs,NewSysApps);
-app_update_config([],SysApps) ->
- SysApps.
+ app_update_config(Configs,NewSysApps,Status);
+app_update_config([],SysApps,Status) ->
+ {SysApps,Status}.
app_set_config_only(#app{mods=ConfigMods} = Config) ->
app_set_config_only(mod_set_config_only(ConfigMods),Config).
@@ -506,13 +516,13 @@ app_set_config_only([],#app{name = Name,
excl_app_filters = undefined,
incl_archive_filters = undefined,
excl_archive_filters = undefined,
- archive_opts = undefined}) ->
+ archive_opts = undefined,
+ is_escript = false})->
{delete,Name};
app_set_config_only(Mods,#app{name = Name,
incl_cond = InclCond,
mod_cond = ModCond,
use_selected_vsn = UseSelectedVsn,
- active_dir = ActiveDir,
debug_info = DebugInfo,
app_file = AppFile,
app_type = AppType,
@@ -521,21 +531,38 @@ app_set_config_only(Mods,#app{name = Name,
incl_archive_filters = InclArchiveFilters,
excl_archive_filters = ExclArchiveFilters,
archive_opts = ArchiveOpts,
- vsn = Vsn}) ->
- (default_app(Name))#app{incl_cond = InclCond,
- mod_cond = ModCond,
- use_selected_vsn = UseSelectedVsn,
- active_dir = ActiveDir,
- debug_info = DebugInfo,
- app_file = AppFile,
- app_type = AppType,
- incl_app_filters = InclAppFilters,
- excl_app_filters = ExclAppFilters,
- incl_archive_filters = InclArchiveFilters,
- excl_archive_filters = ExclArchiveFilters,
- archive_opts = ArchiveOpts,
- vsn = Vsn,
- mods = Mods}.
+ vsn = Vsn,
+ is_escript = IsEscript,
+ label = Label,
+ info = Info,
+ active_dir = ActiveDir,
+ sorted_dirs = SortedDirs}) ->
+ App = (default_app(Name))#app{incl_cond = InclCond,
+ mod_cond = ModCond,
+ use_selected_vsn = UseSelectedVsn,
+ debug_info = DebugInfo,
+ app_file = AppFile,
+ app_type = AppType,
+ incl_app_filters = InclAppFilters,
+ excl_app_filters = ExclAppFilters,
+ incl_archive_filters = InclArchiveFilters,
+ excl_archive_filters = ExclArchiveFilters,
+ archive_opts = ArchiveOpts,
+ vsn = Vsn,
+ mods = Mods},
+
+ %% Some fields shall only be set if it is an escript, e.g. label
+ %% must never be set for any other applications since that will
+ %% prevent refreshing.
+ if IsEscript ->
+ App#app{is_escript = IsEscript,
+ active_dir = ActiveDir,
+ sorted_dirs = SortedDirs,
+ label = Label,
+ info = Info};
+ true ->
+ App
+ end.
mod_set_config_only(ConfigMods) ->
[#mod{name = Name,
@@ -1044,7 +1071,7 @@ refresh_app(#app{name = AppName,
%% And read all modules from ebin and create
%% #mod record with dependencies (uses_mods).
{AI, read_ebin_mods(Ebin, AppName), Status2};
- true ->
+ _ ->
{App#app.info, Mods, Status}
end,
@@ -1316,7 +1343,7 @@ shrink_app(A) ->
info = undefined,
mods = [],
uses_mods = undefined};
- true ->
+ true ->
{Dir, Dirs, OptVsn} =
case A#app.use_selected_vsn of
undefined ->
@@ -1881,7 +1908,7 @@ escripts_to_apps([Escript | Escripts], Apps, Status) ->
EA -> EA
end,
{Apps2, Status3} =
- escript_files_to_apps(Escript,
+ escript_files_to_apps(EscriptAppName,
lists:sort(Files),
[EscriptApp],
Apps,
@@ -1898,7 +1925,7 @@ escripts_to_apps([], Apps, Status) ->
%% Assume that all files for an app are in consecutive order
%% Assume the app info is before the mods
-escript_files_to_apps(Escript,
+escript_files_to_apps(EscriptAppName,
[{AppName, Type, Dir, ModOrInfo} | Files],
Acc,
Apps,
@@ -1914,6 +1941,7 @@ escript_files_to_apps(Escript,
{[App#app{mods = Mods} | Acc2], Status};
Acc ->
{NewApp, Status2} = init_escript_app(AppName,
+ EscriptAppName,
Dir,
missing_app_info(""),
[ModOrInfo],
@@ -1923,6 +1951,7 @@ escript_files_to_apps(Escript,
end;
app ->
{App, Status2} = init_escript_app(AppName,
+ EscriptAppName,
Dir,
ModOrInfo,
[],
@@ -1930,18 +1959,24 @@ escript_files_to_apps(Escript,
Status),
{[App | Acc], Status2}
end,
- escript_files_to_apps(Escript, Files, NewAcc, Apps, Status3);
-escript_files_to_apps(_Escript, [], Acc, Apps, Status) ->
- {lists:ukeymerge(#app.name, Acc, Apps), Status}.
+ escript_files_to_apps(EscriptAppName, Files, NewAcc, Apps, Status3);
+escript_files_to_apps(_EscriptAppName, [], Acc, Apps, Status) ->
+ {lists:ukeymerge(#app.name, lists:reverse(Acc), Apps), Status}.
-init_escript_app(AppName, Dir, Info, Mods, Apps, Status) ->
+init_escript_app(AppName, EscriptAppName, Dir, Info, Mods, Apps, Status) ->
App1 = default_app(AppName, Dir),
- App2 = App1#app{is_escript = true,
+ IsEscript =
+ if AppName=:=EscriptAppName -> true;
+ true -> {inlined, EscriptAppName}
+ end,
+ InclCond = (lists:keyfind(EscriptAppName,#app.name,Apps))#app.incl_cond,
+ App2 = App1#app{is_escript = IsEscript,
label = filename:basename(Dir, ".escript"),
info = Info,
mods = Mods,
active_dir = Dir,
- sorted_dirs = [Dir]},
+ sorted_dirs = [Dir],
+ incl_cond = InclCond},% inlined apps inherit incl from escript
case lists:keymember(AppName, #app.name, Apps) of
true ->
Error = lists:concat([AppName, ": Application name clash. ",
@@ -2022,8 +2057,10 @@ refresh_apps(_ConfigApps, [], Acc, _Force, Status) ->
{lists:reverse(Acc), Status}.
-ensure_app_info(#app{is_escript = true, active_dir = Dir, info = Info},
- Status) ->
+ensure_app_info(#app{is_escript = IsEscript, active_dir = Dir, info = Info},
+ Status)
+ when IsEscript=/=false ->
+ %% Escript or application which is inlined in an escript
{Info, Dir, Status};
ensure_app_info(#app{name = Name, sorted_dirs = []}, Status) ->
Error = lists:concat([Name, ": Missing application directory."]),
diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl
index 0fcf89a360..40d1009733 100644
--- a/lib/reltool/src/reltool_target.erl
+++ b/lib/reltool/src/reltool_target.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-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
@@ -101,7 +101,7 @@ do_gen_config(#sys{root_dir = RootDir,
|| A <- Apps,
A#app.name =/= ?MISSING_APP_NAME,
A#app.name =/= erts,
- not A#app.is_escript],
+ A#app.is_escript =/= true],
EscriptItems = [{escript,
A#app.active_dir,
emit(incl_cond, A#app.incl_cond, undefined, InclDefs)}
@@ -895,7 +895,7 @@ spec_escripts(#sys{apps = Apps}, ErtsBin, BinFiles) ->
if
Name =:= ?MISSING_APP_NAME ->
false;
- not IsEscript ->
+ IsEscript =/= true ->
false;
IsIncl; IsPre ->
{true, do_spec_escript(File, ErtsBin, BinFiles)};
@@ -957,7 +957,7 @@ spec_lib_files(#sys{apps = Apps} = Sys) ->
if
Name =:= ?MISSING_APP_NAME ->
false;
- IsEscript ->
+ IsEscript =/= false ->
false;
IsIncl; IsPre ->
true;