aboutsummaryrefslogtreecommitdiffstats
path: root/system/doc/system_principles/create_target.xml
diff options
context:
space:
mode:
authorSiri Hansen <[email protected]>2011-11-25 15:31:55 +0100
committerSiri Hansen <[email protected]>2011-12-01 16:14:56 +0100
commite39c093f4cdc55084d27d378d64dd2bc464dec0b (patch)
treeb1deac6954a00be9889b11443010c8abc7f5d424 /system/doc/system_principles/create_target.xml
parent08ea3af8528ad0920021ecc230a66eb5ee59bc86 (diff)
downloadotp-e39c093f4cdc55084d27d378d64dd2bc464dec0b.tar.gz
otp-e39c093f4cdc55084d27d378d64dd2bc464dec0b.tar.bz2
otp-e39c093f4cdc55084d27d378d64dd2bc464dec0b.zip
Rename create_target.xml to create_target.xmlsrc to prepare for codeinclude
Diffstat (limited to 'system/doc/system_principles/create_target.xml')
-rw-r--r--system/doc/system_principles/create_target.xml497
1 files changed, 0 insertions, 497 deletions
diff --git a/system/doc/system_principles/create_target.xml b/system/doc/system_principles/create_target.xml
deleted file mode 100644
index 7d9f4681b9..0000000000
--- a/system/doc/system_principles/create_target.xml
+++ /dev/null
@@ -1,497 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2002</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- 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.
-
- </legalnotice>
-
- <title>Creating a First Target System</title>
- <prepared>Peter H&ouml;gfeldt</prepared>
- <responsible></responsible>
- <docno></docno>
- <approved></approved>
- <checked></checked>
- <date>2002-09-17</date>
- <rev>A</rev>
- <file>create_target.xml</file>
- </header>
-
- <section>
- <title>Introduction</title>
- <p>When creating a system using Erlang/OTP, the most simple way is
- to install Erlang/OTP somewhere, install the application specific
- code somewhere else, and then start the Erlang runtime system,
- making sure the code path includes the application specific code.</p>
- <p>Often it is not desirable to use an Erlang/OTP system as is. A
- developer may create new Erlang/OTP compliant applications for a
- particular purpose, and several original Erlang/OTP applications
- may be irrelevant for the purpose in question. Thus, there is a
- need to be able to create a new system based on a given
- Erlang/OTP system, where dispensable applications are removed,
- and a set of new applications that are included in the new
- system. Documentation and source code is irrelevant and is
- therefore not included in the new system.</p>
- <p>This chapter is about creating such a system, which we call a
- <em>target system</em>.</p>
- <p>In the following sections we consider creating target systems with
- different requirements of functionality:</p>
- <list type="bulleted">
- <item>a <em>basic target system</em> that can be started by
- calling the ordinary <c>erl</c> script, </item>
- <item>a <em>simple target system</em> where also code
- replacement in run-time can be performed, and</item>
- <item>an <em>embedded target system</em> where there is also
- support for logging output from the system to file for later
- inspection, and where the system can be started automatically
- at boot time. </item>
- </list>
- <p>We only consider the case when Erlang/OTP is running on a UNIX
- system.</p>
- <p>There is an example Erlang module <c>target_system.erl</c> that
- contains functions for creating and installing a target system.
- That module is used in the examples below. The source code of
- the module is listed at the end of this chapter.</p>
- </section>
-
- <section>
- <title>Creating a Target System</title>
- <p>It is assumed that you have a working Erlang/OTP system structured
- according to the OTP Design Principles.</p>
- <p><em>Step 1.</em> First create a <c>.rel</c> file (see
- <c>rel(4)</c>) that specifies the <c>erts</c> version
- and lists all applications that should be included in the new
- basic target system. An example is the following
- <c>mysystem.rel</c> file:</p>
- <code type="none">
-%% mysystem.rel
-{release,
- {"MYSYSTEM", "FIRST"},
- {erts, "5.1"},
- [{kernel, "2.7"},
- {stdlib, "1.10"},
- {sasl, "1.9.3"},
- {pea, "1.0"}]}. </code>
- <p>The listed applications are not only original Erlang/OTP
- applications but possibly also new applications that you have
- written yourself (here examplified by the application
- <c>pea</c>). </p>
- <p><em>Step 2.</em> From the directory where the <c>mysystem.rel</c>
- file reside, start the Erlang/OTP system:</p>
- <pre>
-os> <input>erl -pa /home/user/target_system/myapps/pea-1.0/ebin</input></pre>
- <p>where also the path to the <c>pea-1.0</c> ebin directory is
- provided. </p>
- <p><em>Step 3.</em> Now create the target system: </p>
- <pre>
-1> <input>target_system:create("mysystem").</input></pre>
- <p>The <c>target_system:create/1</c> function does the following:</p>
- <list type="ordered">
- <item>Reads the <c>mysystem.rel</c> file, and creates a new file
- <c>plain.rel</c> which is identical to former, except that it
- only lists the <c>kernel</c> and <c>stdlib</c> applications. </item>
- <item>From the <c>mysystem.rel</c> and <c>plain.rel</c> files
- creates the files <c>mysystem.script</c>,
- <c>mysystem.boot</c>, <c>plain.script</c>, and
- <c>plain.boot</c> through a call to
- <c>systools:make_script/2</c>.</item>
- <item>
- <p>Creates the file <c>mysystem.tar.gz</c> by a call to
- <c>systools:make_tar/2</c>. That file has the following
- contents:</p>
- <code type="none">
-erts-5.1/bin/
-releases/FIRST/start.boot
-releases/mysystem.rel
-lib/kernel-2.7/
-lib/stdlib-1.10/
-lib/sasl-1.9.3/
-lib/pea-1.0/ </code>
- <p>The file <c>releases/FIRST/start.boot</c> is a copy of our
- <c>mysystem.boot</c>, and a copy of the original
- <c>mysystem.rel</c> has been put in the <c>releases</c>
- directory.</p>
- </item>
- <item>Creates the temporary directory <c>tmp</c> and extracts the tar file
- <c>mysystem.tar.gz</c> into that directory. </item>
- <item>Deletes the <c>erl</c> and <c>start</c> files from
- <c>tmp/erts-5.1/bin</c>. XXX Why.</item>
- <item>Creates the directory <c>tmp/bin</c>.</item>
- <item>Copies the previously creates file <c>plain.boot</c> to
- <c>tmp/bin/start.boot</c>.</item>
- <item>Copies the files <c>epmd</c>, <c>run_erl</c>, and
- <c>to_erl</c> from the directory <c>tmp/erts-5.1/bin</c> to
- the directory <c>tmp/bin</c>.</item>
- <item>Creates the file <c>tmp/releases/start_erl.data</c> with the
- contents "5.1 FIRST".
- </item>
- <item>Recreates the file <c>mysystem.tar.gz</c> from the directories
- in the directory <c>tmp</c>, and removes <c>tmp</c>.</item>
- </list>
- </section>
-
- <section>
- <title>Installing a Target System</title>
- <p><em>Step 4.</em> Install the created target system in a
- suitable directory. </p>
- <pre>
-2> <input>target_system:install("mysystem", "/usr/local/erl-target").</input></pre>
- <p>The function <c>target_system:install/2</c> does the following:
- </p>
- <list type="ordered">
- <item>Extracts the tar file <c>mysystem.tar.gz</c> into the target
- directory <c>/usr/local/erl-target</c>.</item>
- <item>In the target directory reads the file <c>releases/start_erl.data</c>
- in order to find the Erlang runtime system version ("5.1").</item>
- <item>Substitutes <c>%FINAL_ROOTDIR%</c> and <c>%EMU%</c> for
- <c>/usr/local/erl-target</c> and <c>beam</c>, respectively, in
- the files <c>erl.src</c>, <c>start.src</c>, and
- <c>start_erl.src</c> of the target <c>erts-5.1/bin</c>
- directory, and puts the resulting files <c>erl</c>,
- <c>start</c>, and <c>run_erl</c> in the target <c>bin</c>
- directory.</item>
- <item>Finally the target <c>releases/RELEASES</c> file is created
- from data in the <c>releases/mysystem.rel</c> file.</item>
- </list>
- </section>
-
- <section>
- <title>Starting a Target System</title>
- <p>Now we have a target system that can be started in various ways.</p>
- <p>We start it as a <em>basic target system</em> by invoking</p>
- <pre>
-os> <input>/usr/local/erl-target/bin/erl</input></pre>
- <p>where only the <c>kernel</c> and <c>stdlib</c> applications are
- started, i.e. the system is started as an ordinary development
- system. There are only two files needed for all this to work:
- <c>bin/erl</c> file (obtained from <c>erts-5.1/bin/erl.src</c>)
- and the <c>bin/start.boot</c> file (a copy of <c>plain.boot</c>).</p>
- <p>We can also start a distributed system (requires <c>bin/epmd</c>).</p>
- <p>To start all applications specified in the original
- <c>mysystem.rel</c> file, use the <c>-boot</c> flag as follows:</p>
- <pre>
-os> <input>/usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FIRST/start</input></pre>
- <p>We start a <em>simple target system</em> as above. The only difference
- is that also the file <c>releases/RELEASES</c> is present for
- code replacement in run-time to work.</p>
- <p>To start an <em>embedded target system</em> the shell script
- <c>bin/start</c> is used. That shell script calls
- <c>bin/run_erl</c>, which in turn calls <c>bin/start_erl</c>
- (roughly, <c>start_erl</c> is an embedded variant of
- <c>erl</c>). </p>
- <p>The shell script <c>start</c> is only an example. You should
- edit it to suite your needs. Typically it is executed when the
- UNIX system boots.</p>
- <p><c>run_erl</c> is a wrapper that provides logging of output from
- the run-time system to file. It also provides a simple mechanism
- for attaching to the Erlang shell (<c>to_erl</c>).</p>
- <p><c>start_erl</c> requires the root directory
- (<c>"/usr/local/erl-target"</c>), the releases directory
- (<c>"/usr/local/erl-target/releases"</c>), and the location of
- the <c>start_erl.data</c> file. It reads the run-time system
- version (<c>"5.1"</c>) and release version (<c>"FIRST"</c>) from
- the <c>start_erl.data</c> file, starts the run-time system of the
- version found, and provides <c>-boot</c> flag specifying the boot
- file of the release version found
- (<c>"releases/FIRST/start.boot"</c>).</p>
- <p><c>start_erl</c> also assumes that there is <c>sys.config</c> in
- release version directory (<c>"releases/FIRST/sys.config</c>). That
- is the topic of the next section (see below).</p>
- <p>The <c>start_erl</c> shell script should normally not be
- altered by the user.</p>
- </section>
-
- <section>
- <title>System Configuration Parameters</title>
- <p>As was pointed out above <c>start_erl</c> requires a
- <c>sys.config</c> in the release version directory
- (<c>"releases/FIRST/sys.config"</c>). If there is no such a
- file, the system start will fail. Hence such a file has to
- added as well.</p>
- <p></p>
- <p>If you have system configuration data that are neither file
- location dependent nor site dependent, it may be convenient to
- create the <c>sys.config</c> early, so that it becomes a part of
- the target system tar file created by
- <c>target_system:create/1</c>. In fact, if you create, in the
- current directory, not only the <c>mysystem.rel</c> file, but
- also a <c>sys.config</c> file, that latter file will be tacitly
- put in the apropriate directory.</p>
- </section>
-
- <section>
- <title>Differences from the Install Script</title>
- <p>The above <c>install/2</c> procedure differs somewhat from that
- of the ordinary <c>Install</c> shell script. In fact, <c>create/1</c>
- makes the release package as complete as possible, and leave to the
- <c>install/2</c> procedure to finish by only considering location
- dependent files.</p>
- </section>
-
- <section>
- <title>Listing of target_system.erl</title>
- <code type="none"><![CDATA[
--module(target_system).
--include_lib("kernel/include/file.hrl").
--export([create/1, install/2]).
--define(BUFSIZE, 8192).
-
-%% Note: RelFileName below is the *stem* without trailing .rel,
-%% .script etc.
-%%
-
-%% create(RelFileName)
-%%
-create(RelFileName) ->
- RelFile = RelFileName ++ ".rel",
- io:fwrite("Reading file: \"~s\" ...~n", [RelFile]),
- {ok, [RelSpec]} = file:consult(RelFile),
- io:fwrite("Creating file: \"~s\" from \"~s\" ...~n",
- ["plain.rel", 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("plain.rel", [write]),
- io:fwrite(Fd, "~p.~n", [PlainRelSpec]),
- file:close(Fd),
-
- io:fwrite("Making \"plain.script\" and \"plain.boot\" files ...~n"),
- make_script("plain"),
-
- io:fwrite("Making \"~s.script\" and \"~s.boot\" files ...~n",
- [RelFileName, RelFileName]),
- make_script(RelFileName),
-
- TarFileName = io_lib:fwrite("~s.tar.gz", [RelFileName]),
- io:fwrite("Creating tar file \"~s\" ...~n", [TarFileName]),
- make_tar(RelFileName),
-
- io:fwrite("Creating directory \"tmp\" ...~n"),
- file:make_dir("tmp"),
-
- io:fwrite("Extracting \"~s\" into directory \"tmp\" ...~n", [TarFileName]),
- extract_tar(TarFileName, "tmp"),
-
- TmpBinDir = filename:join(["tmp", "bin"]),
- ErtsBinDir = filename:join(["tmp", "erts-" ++ ErtsVsn, "bin"]),
- io:fwrite("Deleting \"erl\" and \"start\" in directory \"~s\" ...~n",
- [ErtsBinDir]),
- file:delete(filename:join([ErtsBinDir, "erl"])),
- file:delete(filename:join([ErtsBinDir, "start"])),
-
- io:fwrite("Creating temporary directory \"~s\" ...~n", [TmpBinDir]),
- file:make_dir(TmpBinDir),
-
- io:fwrite("Copying file \"plain.boot\" to \"~s\" ...~n",
- [filename:join([TmpBinDir, "start.boot"])]),
- copy_file("plain.boot", filename:join([TmpBinDir, "start.boot"])),
-
- io:fwrite("Copying files \"epmd\", \"run_erl\" and \"to_erl\" from \n"
- "\"~s\" to \"~s\" ...~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(["tmp", "releases", "start_erl.data"]),
- io:fwrite("Creating \"~s\" ...~n", [StartErlDataFile]),
- StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]),
- write_file(StartErlDataFile, StartErlData),
-
- io:fwrite("Recreating tar file \"~s\" from contents in directory "
- "\"tmp\" ...~n", [TarFileName]),
- {ok, Tar} = erl_tar:open(TarFileName, [write, compressed]),
- {ok, Cwd} = file:get_cwd(),
- file:set_cwd("tmp"),
- erl_tar:add(Tar, "bin", []),
- erl_tar:add(Tar, "erts-" ++ ErtsVsn, []),
- erl_tar:add(Tar, "releases", []),
- erl_tar:add(Tar, "lib", []),
- erl_tar:close(Tar),
- file:set_cwd(Cwd),
- io:fwrite("Removing directory \"tmp\" ...~n"),
- remove_dir_tree("tmp"),
- ok.
-
-
-install(RelFileName, RootDir) ->
- TarFile = RelFileName ++ ".tar.gz",
- io:fwrite("Extracting ~s ...~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)
-%%
-make_script(RelFileName) ->
- Opts = [no_module_tests],
- systools:make_script(RelFileName, Opts).
-
-%% make_tar(RelFileName)
-%%
-make_tar(RelFileName) ->
- RootDir = code:root_dir(),
- systools:make_tar(RelFileName, [{erts, RootDir}]).
-
-%% 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, InFd} = file:open(Src, [raw, binary, read]),
- {ok, OutFd} = file:open(Dest, [raw, binary, write]),
- do_copy_file(InFd, OutFd),
- file:close(InFd),
- file:close(OutFd),
- case lists:member(preserve, Opts) of
- true ->
- {ok, FileInfo} = file:read_file_info(Src),
- file:write_file_info(Dest, FileInfo);
- false ->
- ok
- end.
-
-do_copy_file(InFd, OutFd) ->
- case file:read(InFd, ?BUFSIZE) of
- {ok, Bin} ->
- file:write(OutFd, Bin),
- do_copy_file(InFd, OutFd);
- eof ->
- 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]),
- {ok, FileInfo} = file:read_file_info(FilePath),
- case FileInfo#file_info.type of
- directory ->
- {ok, DirFiles} = file:list_dir(FilePath),
- remove_all_files(FilePath, DirFiles),
- file:del_dir(FilePath);
- _ ->
- file:delete(FilePath)
- end
- end, Files).
- ]]></code>
- </section>
-</chapter>
-