aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sasl/examples/src/target_system.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sasl/examples/src/target_system.erl')
-rw-r--r--lib/sasl/examples/src/target_system.erl259
1 files changed, 259 insertions, 0 deletions
diff --git a/lib/sasl/examples/src/target_system.erl b/lib/sasl/examples/src/target_system.erl
new file mode 100644
index 0000000000..0e1e0b2324
--- /dev/null
+++ b/lib/sasl/examples/src/target_system.erl
@@ -0,0 +1,259 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2011. 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
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(target_system).
+-export([create/1, create/2, install/2]).
+
+%% Note: RelFileName below is the *stem* without trailing .rel,
+%% .script etc.
+%%
+
+%% create(RelFileName)
+%%
+create(RelFileName) ->
+ create(RelFileName,[]).
+
+create(RelFileName,SystoolsOpts) ->
+ RelFile = RelFileName ++ ".rel",
+ Dir = filename:dirname(RelFileName),
+ PlainRelFileName = filename:join(Dir,"plain"),
+ PlainRelFile = PlainRelFileName ++ ".rel",
+ io:fwrite("Reading file: ~p ...~n", [RelFile]),
+ {ok, [RelSpec]} = file:consult(RelFile),
+ io:fwrite("Creating file: ~p from ~p ...~n",
+ [PlainRelFile, RelFile]),
+ {release,
+ {RelName, RelVsn},
+ {erts, ErtsVsn},
+ AppVsns} = RelSpec,
+ PlainRelSpec = {release,
+ {RelName, RelVsn},
+ {erts, ErtsVsn},
+ lists:filter(fun({kernel, _}) ->
+ true;
+ ({stdlib, _}) ->
+ true;
+ (_) ->
+ false
+ end, AppVsns)
+ },
+ {ok, Fd} = file:open(PlainRelFile, [write]),
+ io:fwrite(Fd, "~p.~n", [PlainRelSpec]),
+ file:close(Fd),
+
+ io:fwrite("Making \"~s.script\" and \"~s.boot\" files ...~n",
+ [PlainRelFileName,PlainRelFileName]),
+ make_script(PlainRelFileName,SystoolsOpts),
+
+ io:fwrite("Making \"~s.script\" and \"~s.boot\" files ...~n",
+ [RelFileName, RelFileName]),
+ make_script(RelFileName,SystoolsOpts),
+
+ TarFileName = filename:join(Dir,RelFileName ++ ".tar.gz"),
+ io:fwrite("Creating tar file ~p ...~n", [TarFileName]),
+ make_tar(RelFileName,SystoolsOpts),
+
+ TmpDir = filename:join(Dir,"tmp"),
+ io:fwrite("Creating directory ~p ...~n",[TmpDir]),
+ file:make_dir(TmpDir),
+
+ io:fwrite("Extracting ~p into directory ~p ...~n", [TarFileName,TmpDir]),
+ extract_tar(TarFileName, TmpDir),
+
+ TmpBinDir = filename:join([TmpDir, "bin"]),
+ ErtsBinDir = filename:join([TmpDir, "erts-" ++ ErtsVsn, "bin"]),
+ io:fwrite("Deleting \"erl\" and \"start\" in directory ~p ...~n",
+ [ErtsBinDir]),
+ file:delete(filename:join([ErtsBinDir, "erl"])),
+ file:delete(filename:join([ErtsBinDir, "start"])),
+
+ io:fwrite("Creating temporary directory ~p ...~n", [TmpBinDir]),
+ file:make_dir(TmpBinDir),
+
+ io:fwrite("Copying file \"~s.boot\" to ~p ...~n",
+ [PlainRelFileName, filename:join([TmpBinDir, "start.boot"])]),
+ copy_file(PlainRelFileName++".boot",filename:join([TmpBinDir, "start.boot"])),
+
+ io:fwrite("Copying files \"epmd\", \"run_erl\" and \"to_erl\" from \n"
+ "~p to ~p ...~n",
+ [ErtsBinDir, TmpBinDir]),
+ copy_file(filename:join([ErtsBinDir, "epmd"]),
+ filename:join([TmpBinDir, "epmd"]), [preserve]),
+ copy_file(filename:join([ErtsBinDir, "run_erl"]),
+ filename:join([TmpBinDir, "run_erl"]), [preserve]),
+ copy_file(filename:join([ErtsBinDir, "to_erl"]),
+ filename:join([TmpBinDir, "to_erl"]), [preserve]),
+
+ StartErlDataFile = filename:join([TmpDir, "releases", "start_erl.data"]),
+ io:fwrite("Creating ~p ...~n", [StartErlDataFile]),
+ StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]),
+ write_file(StartErlDataFile, StartErlData),
+
+ io:fwrite("Recreating tar file ~p from contents in directory ~p ...~n",
+ [TarFileName,TmpDir]),
+ {ok, Tar} = erl_tar:open(TarFileName, [write, compressed]),
+ %% {ok, Cwd} = file:get_cwd(),
+ %% file:set_cwd("tmp"),
+ ErtsDir = "erts-"++ErtsVsn,
+ erl_tar:add(Tar, filename:join(TmpDir,"bin"), "bin", []),
+ erl_tar:add(Tar, filename:join(TmpDir,ErtsDir), ErtsDir, []),
+ erl_tar:add(Tar, filename:join(TmpDir,"releases"), "releases", []),
+ erl_tar:add(Tar, filename:join(TmpDir,"lib"), "lib", []),
+ erl_tar:close(Tar),
+ %% file:set_cwd(Cwd),
+ io:fwrite("Removing directory ~p ...~n",[TmpDir]),
+ remove_dir_tree(TmpDir),
+ ok.
+
+
+install(RelFileName, RootDir) ->
+ TarFile = RelFileName ++ ".tar.gz",
+ io:fwrite("Extracting ~p ...~n", [TarFile]),
+ extract_tar(TarFile, RootDir),
+ StartErlDataFile = filename:join([RootDir, "releases", "start_erl.data"]),
+ {ok, StartErlData} = read_txt_file(StartErlDataFile),
+ [ErlVsn, _RelVsn| _] = string:tokens(StartErlData, " \n"),
+ ErtsBinDir = filename:join([RootDir, "erts-" ++ ErlVsn, "bin"]),
+ BinDir = filename:join([RootDir, "bin"]),
+ io:fwrite("Substituting in erl.src, start.src and start_erl.src to\n"
+ "form erl, start and start_erl ...\n"),
+ subst_src_scripts(["erl", "start", "start_erl"], ErtsBinDir, BinDir,
+ [{"FINAL_ROOTDIR", RootDir}, {"EMU", "beam"}],
+ [preserve]),
+ io:fwrite("Creating the RELEASES file ...\n"),
+ create_RELEASES(RootDir,
+ filename:join([RootDir, "releases", RelFileName])).
+
+%% LOCALS
+
+%% make_script(RelFileName,Opts)
+%%
+make_script(RelFileName,Opts) ->
+ systools:make_script(RelFileName, [no_module_tests,
+ {outdir,filename:dirname(RelFileName)}
+ |Opts]).
+
+%% make_tar(RelFileName,Opts)
+%%
+make_tar(RelFileName,Opts) ->
+ RootDir = code:root_dir(),
+ systools:make_tar(RelFileName, [{erts, RootDir},
+ {outdir,filename:dirname(RelFileName)}
+ |Opts]).
+
+%% extract_tar(TarFile, DestDir)
+%%
+extract_tar(TarFile, DestDir) ->
+ erl_tar:extract(TarFile, [{cwd, DestDir}, compressed]).
+
+create_RELEASES(DestDir, RelFileName) ->
+ release_handler:create_RELEASES(DestDir, RelFileName ++ ".rel").
+
+subst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) ->
+ lists:foreach(fun(Script) ->
+ subst_src_script(Script, SrcDir, DestDir,
+ Vars, Opts)
+ end, Scripts).
+
+subst_src_script(Script, SrcDir, DestDir, Vars, Opts) ->
+ subst_file(filename:join([SrcDir, Script ++ ".src"]),
+ filename:join([DestDir, Script]),
+ Vars, Opts).
+
+subst_file(Src, Dest, Vars, Opts) ->
+ {ok, Conts} = read_txt_file(Src),
+ NConts = subst(Conts, Vars),
+ write_file(Dest, NConts),
+ case lists:member(preserve, Opts) of
+ true ->
+ {ok, FileInfo} = file:read_file_info(Src),
+ file:write_file_info(Dest, FileInfo);
+ false ->
+ ok
+ end.
+
+%% subst(Str, Vars)
+%% Vars = [{Var, Val}]
+%% Var = Val = string()
+%% Substitute all occurrences of %Var% for Val in Str, using the list
+%% of variables in Vars.
+%%
+subst(Str, Vars) ->
+ subst(Str, Vars, []).
+
+subst([$%, C| Rest], Vars, Result) when $A =< C, C =< $Z ->
+ subst_var([C| Rest], Vars, Result, []);
+subst([$%, C| Rest], Vars, Result) when $a =< C, C =< $z ->
+ subst_var([C| Rest], Vars, Result, []);
+subst([$%, C| Rest], Vars, Result) when C == $_ ->
+ subst_var([C| Rest], Vars, Result, []);
+subst([C| Rest], Vars, Result) ->
+ subst(Rest, Vars, [C| Result]);
+subst([], _Vars, Result) ->
+ lists:reverse(Result).
+
+subst_var([$%| Rest], Vars, Result, VarAcc) ->
+ Key = lists:reverse(VarAcc),
+ case lists:keysearch(Key, 1, Vars) of
+ {value, {Key, Value}} ->
+ subst(Rest, Vars, lists:reverse(Value, Result));
+ false ->
+ subst(Rest, Vars, [$%| VarAcc ++ [$%| Result]])
+ end;
+subst_var([C| Rest], Vars, Result, VarAcc) ->
+ subst_var(Rest, Vars, Result, [C| VarAcc]);
+subst_var([], Vars, Result, VarAcc) ->
+ subst([], Vars, [VarAcc ++ [$%| Result]]).
+
+copy_file(Src, Dest) ->
+ copy_file(Src, Dest, []).
+
+copy_file(Src, Dest, Opts) ->
+ {ok,_} = file:copy(Src, Dest),
+ case lists:member(preserve, Opts) of
+ true ->
+ {ok, FileInfo} = file:read_file_info(Src),
+ file:write_file_info(Dest, FileInfo);
+ false ->
+ ok
+ end.
+
+write_file(FName, Conts) ->
+ {ok, Fd} = file:open(FName, [write]),
+ file:write(Fd, Conts),
+ file:close(Fd).
+
+read_txt_file(File) ->
+ {ok, Bin} = file:read_file(File),
+ {ok, binary_to_list(Bin)}.
+
+remove_dir_tree(Dir) ->
+ remove_all_files(".", [Dir]).
+
+remove_all_files(Dir, Files) ->
+ lists:foreach(fun(File) ->
+ FilePath = filename:join([Dir, File]),
+ case filelib:is_dir(FilePath) of
+ true ->
+ {ok, DirFiles} = file:list_dir(FilePath),
+ remove_all_files(FilePath, DirFiles),
+ file:del_dir(FilePath);
+ _ ->
+ file:delete(FilePath)
+ end
+ end, Files).