aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2014-03-10 17:44:25 +0100
committerRickard Green <[email protected]>2014-03-20 16:24:48 +0100
commite310677df7b3ce6506b35044abafcb507caa7e07 (patch)
tree010088a792b400cc87f44e02054f951a8071417f
parent0453d4ebd924f504e8d37ac5830ecc28ccc15046 (diff)
downloadotp-e310677df7b3ce6506b35044abafcb507caa7e07.tar.gz
otp-e310677df7b3ce6506b35044abafcb507caa7e07.tar.bz2
otp-e310677df7b3ce6506b35044abafcb507caa7e07.zip
Verify runtime_dependencies when running 'otp_build patch_app'
-rw-r--r--Makefile.in8
-rw-r--r--erts/Makefile.in5
-rw-r--r--erts/doc/src/erlang.xml4
-rw-r--r--erts/etc/win32/nsis/erlang.nsi1
-rw-r--r--erts/etc/win32/nsis/erlang20.nsi1
-rw-r--r--lib/kernel/doc/src/app.xml21
-rw-r--r--make/otp_released_app.mk43
-rw-r--r--make/otp_subdir.mk9
-rwxr-xr-xmake/verify_runtime_dependencies313
-rwxr-xr-xotp_build74
-rw-r--r--otp_versions.table0
-rw-r--r--system/doc/installation_guide/otp_version.xml96
-rw-r--r--system/doc/installation_guide/part.xml1
-rw-r--r--system/doc/installation_guide/xmlfiles.mk1
-rw-r--r--system/doc/system_principles/part.xml1
-rw-r--r--system/doc/system_principles/versions.xml267
-rw-r--r--system/doc/system_principles/xmlfiles.mk3
17 files changed, 706 insertions, 142 deletions
diff --git a/Makefile.in b/Makefile.in
index bfaf749465..c667eb5f79 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -397,9 +397,9 @@ endif
ERL_TOP=$(ERL_TOP) PATH=$(INST_PATH_PREFIX)"$${PATH}" \
$(MAKE) BUILD_ALL=1 TESTROOT="$(RELEASE_ROOT)" release
ifeq ($(RELEASE_ROOT),)
- $(INSTALL_DATA) "$(ERL_TOP)/OTP_VERSION" "$(OTP_DEFAULT_RELEASE_PATH)"
+ $(INSTALL_DATA) "$(ERL_TOP)/OTP_VERSION" "$(OTP_DEFAULT_RELEASE_PATH)/releases/@OTP_REL@"
else
- $(INSTALL_DATA) "$(ERL_TOP)/OTP_VERSION" "$(RELEASE_ROOT)"
+ $(INSTALL_DATA) "$(ERL_TOP)/OTP_VERSION" "$(RELEASE_ROOT)/releases/@OTP_REL@"
endif
# ---------------------------------------------------------------
@@ -1038,9 +1038,9 @@ install.Install:
install.otp_version:
ifeq ($(ERLANG_LIBDIR),)
- $(INSTALL_DATA) "$(ERL_TOP)/OTP_VERSION" "$(OTP_DEFAULT_RELEASE_PATH)"
+ $(INSTALL_DATA) "$(ERL_TOP)/OTP_VERSION" "$(OTP_DEFAULT_RELEASE_PATH)/releases/@OTP_REL@"
else
- $(INSTALL_DATA) "$(ERL_TOP)/OTP_VERSION" "$(ERLANG_LIBDIR)"
+ $(INSTALL_DATA) "$(ERL_TOP)/OTP_VERSION" "$(ERLANG_LIBDIR)/releases/@OTP_REL@"
endif
#
diff --git a/erts/Makefile.in b/erts/Makefile.in
index e3db37d3fd..47298cccba 100644
--- a/erts/Makefile.in
+++ b/erts/Makefile.in
@@ -48,6 +48,7 @@ debug opt clean:
( cd $$d && $(MAKE) $@ FLAVOR=$(FLAVOR) ) || exit $$? ; \
fi ; \
done
+ (cd preloaded/src && $(MAKE) ../ebin/erts.app)
# ----------------------------------------------------------------------
# These are "convenience targets", provided as shortcuts for developers
@@ -135,6 +136,10 @@ release:
( cd $$d && $(MAKE) $@ ) || exit $$? ; \
fi ; \
done
+ ( $(MAKE) -f "$(ERL_TOP)/make/otp_released_app.mk" \
+ APP_PWD="$(ERL_TOP)/erts" APP_VSN=VSN APP=erts \
+ TESTROOT="$(TESTROOT)" update) \
+ || exit $$?
.PHONY: release_docs
release_docs:
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index aeded7c719..b06d5aeb12 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -6121,8 +6121,8 @@ ok
<c>erlang:system_info()</c> argument giving the exact OTP
version. This since the exact OTP version in the general case
is hard to determine. For more information see
- <seealso marker="doc/installation_guide:otp_version">the
- documentation of the OTP version in the installation
+ <seealso marker="doc/system_principles:versions">the
+ documentation of versions in the system principles
guide</seealso>.</p>
</item>
<tag><marker id="system_info_port_parallelism"><c>port_parallelism</c></marker></tag>
diff --git a/erts/etc/win32/nsis/erlang.nsi b/erts/etc/win32/nsis/erlang.nsi
index 162e634148..f4fd2b4cdb 100644
--- a/erts/etc/win32/nsis/erlang.nsi
+++ b/erts/etc/win32/nsis/erlang.nsi
@@ -93,7 +93,6 @@ SectionIn 1 RO
skip_silent_mode:
SetOutPath "$INSTDIR"
- File "${TESTROOT}\OTP_VERSION"
File "${TESTROOT}\Install.ini"
File "${TESTROOT}\Install.exe"
File /r "${TESTROOT}\releases"
diff --git a/erts/etc/win32/nsis/erlang20.nsi b/erts/etc/win32/nsis/erlang20.nsi
index 3ee33e8121..3333c4a9aa 100644
--- a/erts/etc/win32/nsis/erlang20.nsi
+++ b/erts/etc/win32/nsis/erlang20.nsi
@@ -144,7 +144,6 @@ Section "Development" SecErlangDev
SectionIn 1 RO
SetOutPath "$INSTDIR"
- File "${TESTROOT}\OTP_VERSION"
File "${TESTROOT}\Install.ini"
File "${TESTROOT}\Install.exe"
SetOutPath "$INSTDIR\releases"
diff --git a/lib/kernel/doc/src/app.xml b/lib/kernel/doc/src/app.xml
index 8f968cc988..b24a2bd7bd 100644
--- a/lib/kernel/doc/src/app.xml
+++ b/lib/kernel/doc/src/app.xml
@@ -90,6 +90,8 @@ RTDeps [ApplicationVersion] []
<c>description</c>, <c>vsn</c>, <c>modules</c>, <c>registered</c>
and <c>applications</c>. The other keys are ignored by
<c>systools</c>.</p>
+ <warning><p>The <c>RTDeps</c> type was introduced in OTP 17.0 and
+ might be subject to changes during the OTP 17 release.</p></warning>
<taglist>
<tag><c>description</c></tag>
<item>
@@ -188,10 +190,10 @@ RTDeps [ApplicationVersion] []
start phases must be a subset of the set of phases defined
for the primary application. Refer to <em>OTP Design Principles</em> for more information.</p>
</item>
- <tag><c>runtime_dependencies</c></tag>
- <item>A list of application versions that the application
+ <tag><marker id="runtime_dependencies"><c>runtime_dependencies</c></marker></tag>
+ <item><p>A list of application versions that the application
depends on. An example of such an application version is
- "kernel-3.0". Application versions specified as runtime
+ <c>"kernel-3.0"</c>. Application versions specified as runtime
dependencies are minimum requirements. That is, a larger
application version than the one specified in the
dependency satisfies the requirement. For information on
@@ -202,7 +204,18 @@ RTDeps [ApplicationVersion] []
specifies a source code version. An additional indirect
requirement is that installed binary application of
the specified version has been built so that it is
- compatible with the rest of the system.
+ compatible with the rest of the system.</p>
+ <p>Some dependencies might only be required in specific runtime
+ scenarios. In the case such optional dependencies exist, these are
+ specified and documented in the corresponding "App" documentation
+ of the specific application.</p>
+ <warning><p>The <c>runtime_dependencies</c> key was introduced in
+ OTP 17.0. The type of its value might be subject to changes during
+ the OTP 17 release.</p></warning>
+ <warning><p>All runtime dependencies specified in OTP applications
+ during the OTP 17 release might not be completely correct. This
+ is actively worked on. Declared runtime dependencies in OTP
+ applications are expected to be correct in OTP 18.</p></warning>
</item>
</taglist>
</section>
diff --git a/make/otp_released_app.mk b/make/otp_released_app.mk
new file mode 100644
index 0000000000..fb5205ab23
--- /dev/null
+++ b/make/otp_released_app.mk
@@ -0,0 +1,43 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2014. 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%
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+include $(APP_PWD)/vsn.mk
+include $(ERL_TOP)/make/otp_default_release_path.mk
+
+RELEASED_APP_VSN=$(APP)-$($(APP_VSN))
+ifeq ($(TESTROOT),)
+REL_DIR=$(OTP_DEFAULT_RELEASE_PATH)/releases/$(SYSTEM_VSN)
+else
+REL_DIR=$(TESTROOT)/releases/$(SYSTEM_VSN)
+endif
+INST_APP_VSNS=$(REL_DIR)/installed_application_versions
+
+.PHONY: update
+
+update:
+ test -d "$(REL_DIR)" || mkdir -p "$(REL_DIR)" ; \
+ if test ! -f "$(INST_APP_VSNS)" ; then \
+ echo "$(RELEASED_APP_VSN)" > "$(INST_APP_VSNS)" || exit 1; \
+ else \
+ if test x = x`grep $(RELEASED_APP_VSN) "$(INST_APP_VSNS)"` ; then \
+ echo $(RELEASED_APP_VSN) >> "$(INST_APP_VSNS)" || exit 1; \
+ fi ; \
+ fi
+
diff --git a/make/otp_subdir.mk b/make/otp_subdir.mk
index f31ab05c87..e6a75cce17 100644
--- a/make/otp_subdir.mk
+++ b/make/otp_subdir.mk
@@ -44,5 +44,14 @@ opt debug release docs release_docs tests release_tests clean depend valgrind st
fi ; \
done ; \
if test -f vsn.mk; then \
+ if test release = $@ && test ! -f SKIP; then \
+ app=`basename $$app_pwd` ; \
+ app_vsn=`echo $$app | sed "y|abcdefghijklmnopqrstuvwxyz|ABCDEFGHIJKLMNOPQRSTUVWXYZ|"` ; \
+ app_vsn=$${app_vsn}_VSN ; \
+ ( $(MAKE) -f "$(ERL_TOP)/make/otp_released_app.mk" \
+ APP_PWD="$$app_pwd" APP_VSN=$$app_vsn APP=$$app \
+ TESTROOT="$(TESTROOT)" update) \
+ || exit $$? ; \
+ fi ; \
echo "=== Leaving application" `basename $$app_pwd` ; \
fi
diff --git a/make/verify_runtime_dependencies b/make/verify_runtime_dependencies
new file mode 100755
index 0000000000..b8eea06b6e
--- /dev/null
+++ b/make/verify_runtime_dependencies
@@ -0,0 +1,313 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. 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%
+%%
+
+%%%-------------------------------------------------------------------
+%%% @author Rickard Green <[email protected]>
+%%% @copyright (C) 2014, Rickard Green
+%%% @doc
+%%% Verify runtime dependencies when patching OTP applications.
+%%% @end
+%%% Created : 4 Mar 2014 by Rickard Green <[email protected]>
+%%%-------------------------------------------------------------------
+
+-mode(compile).
+
+-export([main/1]).
+
+main(Args) ->
+ {Force, Release, SourceDir, TargetDir, AppList} = parse_args(Args,
+ false,
+ [],
+ [],
+ [],
+ []),
+ SourceAppInfo = read_source_app_info(AppList, SourceDir),
+ AppVsnsTab0 = current_target_app_vsns(TargetDir, Release),
+ AppVsnsTab1 = add_source_app_vsns(SourceAppInfo, AppVsnsTab0),
+ case verify_runtime_deps(SourceAppInfo, AppVsnsTab1, true) of
+ true ->
+ ok;
+ false ->
+ case Force of
+ true ->
+ warn("Your OTP development system was updated with "
+ "unfulfilled runtime dependencies. The system "
+ "may not be working as expected.", []);
+ false ->
+ err("Unfulfilled runtime dependencies. "
+ "See warnings above.~n", [])
+ end
+ end,
+ halt(0).
+
+parse_args(["-force" | Args], _, Release, SourceDir, TargetDir, Apps) ->
+ parse_args(Args, true, Release, SourceDir, TargetDir, Apps);
+parse_args(["-release", Release | Args], Force, _, SourceDir, TargetDir, Apps) ->
+ parse_args(Args, Force, Release, SourceDir, TargetDir, Apps);
+parse_args(["-source", SourceDir | Args], Force, Release, _, TargetDir, Apps) ->
+ parse_args(Args, Force, Release, SourceDir, TargetDir, Apps);
+parse_args(["-target", TargetDir | Args], Force, Release, SourceDir, _, Apps) ->
+ parse_args(Args, Force, Release, SourceDir, TargetDir, Apps);
+parse_args([App | Args], Force, Release, SourceDir, TargetDir, OldApps) ->
+ parse_args(Args, Force, Release, SourceDir, TargetDir, [App | OldApps]);
+parse_args([], _, [], _, _, _) ->
+ err("Missing release~n", []);
+parse_args([], _, _, [], _, _) ->
+ err("Missing source directory~n", []);
+parse_args([], _, _, _, [], _) ->
+ err("Missing target directory~n", []);
+parse_args([], _, _, _, _, []) ->
+ err("Missing applications~n");
+parse_args([], Force, Release, SourceDir, TargetDir, Apps) ->
+ {Force, Release, SourceDir, TargetDir, Apps}.
+
+
+%warn(Format) ->
+% warn(Format, []).
+
+warn(Format, Args) ->
+ io:format(standard_error, "WARNING: " ++ Format, Args).
+
+err(Format) ->
+ err(Format, []).
+
+err(Format, Args) ->
+ io:format(standard_error, "ERROR: " ++ Format, Args),
+ halt(1).
+
+read_file(FileName) ->
+ case file:read_file(FileName) of
+ {ok, Content} ->
+ binary_to_list(Content);
+ {error, Error} ->
+ err("Failed to read ~s: ~p~n", [FileName, Error])
+ end.
+
+consult_file(FileName) ->
+ case file:consult(FileName) of
+ {ok, Terms} ->
+ Terms;
+ {error, Error} ->
+ err("Failed to consult ~s: ~p~n", [FileName, Error])
+ end.
+
+current_target_app_vsns(TargetDir, Release) ->
+ IAV = read_file(filename:join([TargetDir, "releases", Release,
+ "installed_application_versions"])),
+ DirList = string:tokens(IAV, "\n\r\t "),
+ LibDir = filename:join(TargetDir, "lib"),
+ make_app_vsns_tab(DirList, LibDir, gb_trees:empty()).
+
+make_app_vsns_tab([], _LibDir, GBT) ->
+ GBT;
+make_app_vsns_tab([AppVer | AppVsns], LibDir, GBT0) ->
+ GBT1 = try
+ case file:read_file_info(filename:join(LibDir, AppVer)) of
+ {ok, _FInfo} ->
+ [App, Vsn] = string:tokens(AppVer, "-"),
+ add_app_vsn(App, Vsn, GBT0);
+ _ ->
+ GBT0
+ end
+ catch
+ _:_ ->
+ warn("Unexpected directory: ~p~n",
+ [filename:join(LibDir, AppVer)]),
+ GBT0
+ end,
+ make_app_vsns_tab(AppVsns, LibDir, GBT1).
+
+add_app_vsn(App, VsnList, GBT) when is_atom(App) ->
+ Vsn = parse_vsn(VsnList),
+ case gb_trees:lookup(App, GBT) of
+ none ->
+ gb_trees:insert(App, [Vsn], GBT);
+ {value, Vsns} ->
+ gb_trees:update(App, [Vsn | Vsns], GBT)
+ end;
+add_app_vsn(AppStr, VsnList, GBT) ->
+ add_app_vsn(list_to_atom(AppStr), VsnList, GBT).
+
+add_source_app_vsns([], AppVsnsTab) ->
+ AppVsnsTab;
+add_source_app_vsns([{App, Vsn, _IReqs} | AI], AppVsnsTab) ->
+ add_source_app_vsns(AI, add_app_vsn(App, Vsn, AppVsnsTab)).
+
+read_source_app_info([], _SourceDir) ->
+ [];
+read_source_app_info([App | Apps], SourceDir) ->
+ AppFile = case App of
+ "erts" ->
+ filename:join([SourceDir, "erts", "preloaded", "ebin",
+ "erts.app"]);
+ _ ->
+ filename:join([SourceDir, "lib", App, "ebin",
+ App ++ ".app"])
+ end,
+ AppAtom = list_to_atom(App),
+ case consult_file(AppFile) of
+ [{application, AppAtom, InfoList}] ->
+ Vsn = case lists:keyfind(vsn, 1, InfoList) of
+ {vsn, V} ->
+ V;
+ _ ->
+ err("Missing vsn in ~p~n", AppFile)
+ end,
+ AI = case lists:keyfind(runtime_dependencies, 1, InfoList) of
+ {runtime_dependencies, IReqs} ->
+ case parse_inst_reqs(IReqs) of
+ error ->
+ err("Failed to parse runtime_dependencies in ~p~n",
+ [AppFile]);
+ ParsedIReqs ->
+ {AppAtom, Vsn, ParsedIReqs}
+ end;
+ _ ->
+ {AppAtom, Vsn, []}
+ end,
+ [AI | read_source_app_info(Apps, SourceDir)];
+ _ ->
+ err("Failed to parse ~p~n", [AppFile])
+ end.
+
+parse_vsn(VsnStr) ->
+ list_to_tuple(lists:map(fun (IL) ->
+ list_to_integer(IL)
+ end, string:tokens(VsnStr, "."))).
+
+parse_inst_reqs(InstReqs) ->
+ try
+ parse_inst_reqs_aux(InstReqs)
+ catch
+ _ : _ ->
+ error
+ end.
+
+parse_inst_reqs_aux([]) ->
+ [];
+parse_inst_reqs_aux([IR | IRs]) ->
+ [App, VsnStr] = string:tokens(IR, "-"),
+ [{list_to_atom(App), parse_vsn(VsnStr)} | parse_inst_reqs_aux(IRs)].
+
+make_app_vsn_str({App, VsnTup}) ->
+ make_app_vsn_str(tuple_to_list(VsnTup), [atom_to_list(App), $-]).
+
+make_app_vsn_str([I], Acc) ->
+ lists:flatten([Acc, integer_to_list(I)]);
+make_app_vsn_str([I | Is], Acc) ->
+ make_app_vsn_str(Is, [Acc, integer_to_list(I), $.]).
+
+missing_min_req(App, AppVsn, IReq) ->
+ warn("Unfulfilled runtime dependency for application ~p-~s: ~s~n",
+ [App, AppVsn, make_app_vsn_str(IReq)]).
+
+verify_runtime_deps([], _AppVsnsTab, Res) ->
+ Res;
+verify_runtime_deps([{App, Vsn, IReqs} | SAIs], AppVsnsTab, Res0) ->
+ Res = lists:foldl(
+ fun ({IRApp, IRMinVsn} = InstReq, AccRes) ->
+ case gb_trees:lookup(IRApp, AppVsnsTab) of
+ none ->
+ missing_min_req(App, Vsn, InstReq),
+ false;
+ {value, AppVsns} ->
+ try
+ lists:foreach(
+ fun (AppVsn) ->
+ case meets_min_req(AppVsn, IRMinVsn) of
+ true ->
+ throw(true);
+ false ->
+ false
+ end
+ end,
+ AppVsns),
+ missing_min_req(App, Vsn, InstReq),
+ false
+ catch
+ throw : true ->
+ AccRes
+ end
+ end
+ end,
+ Res0,
+ IReqs),
+ verify_runtime_deps(SAIs, AppVsnsTab, Res).
+
+meets_min_req(Vsn, Vsn) ->
+ true;
+meets_min_req({X}, VsnReq) ->
+ meets_min_req({X, 0, 0}, VsnReq);
+meets_min_req({X, Y}, VsnReq) ->
+ meets_min_req({X, Y, 0}, VsnReq);
+meets_min_req(Vsn, {X}) ->
+ meets_min_req(Vsn, {X, 0, 0});
+meets_min_req(Vsn, {X, Y}) ->
+ meets_min_req(Vsn, {X, Y, 0});
+meets_min_req({X, _Y, _Z}, {XReq, _YReq, _ZReq}) when X > XReq ->
+ true;
+meets_min_req({X, Y, _Z}, {X, YReq, _ZReq}) when Y > YReq ->
+ true;
+meets_min_req({X, Y, Z}, {X, Y, ZReq}) when Z > ZReq ->
+ true;
+meets_min_req({_X, _Y, _Z}, {_XReq, _YReq, _ZReq}) ->
+ false;
+meets_min_req(Vsn, VsnReq) ->
+ gp_meets_min_req(mk_gp_vsn_list(Vsn), mk_gp_vsn_list(VsnReq)).
+
+gp_meets_min_req([X, Y, Z | _Vs], [X, Y, Z]) ->
+ true;
+gp_meets_min_req([X, Y, Z | _Vs], [XReq, YReq, ZReq]) ->
+ meets_min_req({X, Y, Z}, {XReq, YReq, ZReq});
+gp_meets_min_req([X, Y, Z | Vs], [X, Y, Z | VReqs]) ->
+ gp_meets_min_req_tail(Vs, VReqs);
+gp_meets_min_req(_Vsn, _VReq) ->
+ %% Versions on different version branches, i.e., the minimum
+ %% required functionality is not included in Vsn.
+ false.
+
+gp_meets_min_req_tail([V | Vs], [V | VReqs]) ->
+ gp_meets_min_req_tail(Vs, VReqs);
+gp_meets_min_req_tail([], []) ->
+ true;
+gp_meets_min_req_tail([_V | _Vs], []) ->
+ true;
+gp_meets_min_req_tail([V | _Vs], [VReq]) when V > VReq ->
+ true;
+gp_meets_min_req_tail(_Vs, _VReqs) ->
+ %% Versions on different version branches, i.e., the minimum
+ %% required functionality is not included in Vsn.
+ false.
+
+mk_gp_vsn_list(Vsn) ->
+ [X, Y, Z | Tail] = tuple_to_list(Vsn),
+ [X, Y, Z | remove_trailing_zeroes(Tail)].
+
+remove_trailing_zeroes([]) ->
+ [];
+remove_trailing_zeroes([0 | Vs]) ->
+ case remove_trailing_zeroes(Vs) of
+ [] -> [];
+ NewVs -> [0 | NewVs]
+ end;
+remove_trailing_zeroes([V | Vs]) ->
+ [V | remove_trailing_zeroes(Vs)].
diff --git a/otp_build b/otp_build
index 6e016c88d2..b629bf54d4 100755
--- a/otp_build
+++ b/otp_build
@@ -52,7 +52,7 @@ usage ()
echo " release [-a] <target_dir> - creates full release to <target_dir>"
echo " smp [-a] - build an Erlang system, smp flavor only"
echo " tests <dir> - Build testsuites to <dir>"
- echo " patch_app <target_dir> <app1>... - build given apps to <target_dir>"
+ echo " patch_app [-f] <target_dir> <app1>... - build given apps to <target_dir>"
echo " If core apps are patched, new start scripts will be created"
echo " and 'Install' must be run again."
echo ""
@@ -1209,25 +1209,37 @@ do_patch_app ()
if [ X`$MAKE is_cross_configured` = Xyes ]; then
TARGET=`$MAKE target_configured`
fi
+ if [ "x$1" = "x-f" ]; then
+ force="-force"
+ shift
+ else
+ force=
+ fi
target_dir=$1
- if [ ! -d $target_dir/releases/$otp_major_vsn ]; then
+ if [ ! -d "$target_dir/releases/$otp_major_vsn" ]; then
echo "No OTP $otp_major_vsn installation in $target_dir" 1>&2
exit 1
fi
shift
- otp_version=`cat "$target_dir/OTP_VERSION"` || { echo "Not able to read $target_dir/OTP_VERSION" 1>&2; exit 1; }
- { echo "$otp_version" | sed "s|^\([^\*]*\)\**|\1\*\*|g" > $target_dir/OTP_VERSION; } 2>/dev/null || { echo "Not able to update $target_dir/OTP_VERSION" 1>&2; exit 1; }
+ otp_version=`cat "$target_dir/releases/$otp_major_vsn/OTP_VERSION"` || { echo "Not able to read $target_dir/releases/$otp_major_vsn/OTP_VERSION" 1>&2; exit 1; }
+ { echo "$otp_version" | sed "s|^\([^\*]*\)\**|\1\*\*|g" > "$target_dir/releases/$otp_major_vsn/OTP_VERSION"; } 2>/dev/null || { echo "Not able to update $target_dir/OTP_VERSION" 1>&2; exit 1; }
+
+ PATH="$ERL_TOP/bootstrap/bin:$PATH" $ERL_TOP/make/verify_runtime_dependencies -release "$otp_major_vsn" -source "$ERL_TOP" -target "$target_dir" $force "$@"
+
+ if [ $? -ne 0 ]; then
+ exit $?
+ fi
# Build all applications to target
for app in "$@"; do
if [ "$app" = "erts" ] && [ -d $ERL_TOP/$app ]; then
(cd $ERL_TOP/$app && $MAKE MAKE="$MAKE" TARGET=$TARGET \
- TESTROOT=$target_dir release) || exit 1
+ TESTROOT="$target_dir" release) || exit 1
elif [ "$app" != "erts" ] && [ -d $ERL_TOP/lib/$app ]; then
(cd $ERL_TOP/lib/$app && $MAKE MAKE="$MAKE" TARGET=$TARGET \
- TESTROOT=$target_dir release) || exit 1
+ TESTROOT="$target_dir" release) || exit 1
else
echo "Invalid application $app" 1>&2
exit 1
@@ -1254,19 +1266,19 @@ do_patch_app ()
# and find the old versions for those not included
if [ "X$update_rel" != "X" ]; then
if [ "X$erts_vsn" = "X" ]; then
- erts_vsns=`ls -d $target_dir/erts-* | sed "s|$target_dir/erts-\([0-9\.].*\)|\1|g"`
+ erts_vsns=`ls -d "$target_dir"/erts-* | sed "s|$target_dir/erts-\([0-9\.].*\)|\1|g"`
erts_vsn=`echo "$erts_vsns" | sort -t '.' -g | tail -n 1`
fi
if [ "X$kernel_vsn" = "X" ]; then
- kernel_vsns=`ls -d $target_dir/lib/kernel-* | sed "s|$target_dir/lib/kernel-\([0-9\.].*\)|\1|g"`
+ kernel_vsns=`ls -d "$target_dir"/lib/kernel-* | sed "s|$target_dir/lib/kernel-\([0-9\.].*\)|\1|g"`
kernel_vsn=`echo "$kernel_vsns" | sort -t '.' -g | tail -n 1`
fi
if [ "X$stdlib_vsn" = "X" ]; then
- stdlib_vsns=`ls -d $target_dir/lib/stdlib-* | sed "s|$target_dir/lib/stdlib-\([0-9\.].*\)|\1|g"`
+ stdlib_vsns=`ls -d "$target_dir"/lib/stdlib-* | sed "s|$target_dir/lib/stdlib-\([0-9\.].*\)|\1|g"`
stdlib_vsn=`echo "$stdlib_vsns" | sort -t '.' -g | tail -n 1`
fi
if [ "X$sasl_vsn" = "X" ]; then
- sasl_vsns=`ls -d $target_dir/lib/sasl-* | sed "s|$target_dir/lib/sasl-\([0-9\.].*\)|\1|g"`
+ sasl_vsns=`ls -d "$target_dir"/lib/sasl-* | sed "s|$target_dir/lib/sasl-\([0-9\.].*\)|\1|g"`
sasl_vsn=`echo "$sasl_vsns" | sort -t '.' -g | tail -n 1`
fi
@@ -1274,42 +1286,42 @@ do_patch_app ()
start_clean="{release, {\"OTP APN 181 01\",\"$otp_major_vsn\"}, {erts, \"$erts_vsn\"},\n [{kernel,\"$kernel_vsn\"},\n {stdlib,\"$stdlib_vsn\"}]}.\n"
start_sasl="{release, {\"OTP APN 181 01\",\"$otp_major_vsn\"}, {erts, \"$erts_vsn\"},\n [{kernel,\"$kernel_vsn\"},\n {stdlib,\"$stdlib_vsn\"},\n {sasl,\"$sasl_vsn\"}]}.\n"
- tmp_dir=$target_dir/tmp;
- if [ ! -d $tmp_dir ]; then
- mkdir $tmp_dir
+ tmp_dir="$target_dir/tmp";
+ if [ ! -d "$tmp_dir" ]; then
+ mkdir "$tmp_dir"
fi
- echo $start_sasl > $tmp_dir/start_sasl.rel
- echo $start_clean > $tmp_dir/start_clean.rel
- echo $start_clean > $tmp_dir/no_dot_erlang.rel
+ echo "$start_sasl" > "$tmp_dir/start_sasl.rel"
+ echo "$start_clean" > "$tmp_dir/start_clean.rel"
+ echo "$start_clean" > "$tmp_dir/no_dot_erlang.rel"
- erlc=$ERL_TOP/bootstrap/bin/erlc
- if [ ! -x $erlc ]; then
+ erlc="$ERL_TOP/bootstrap/bin/erlc"
+ if [ ! -x "$erlc" ]; then
echo "erlc not found, can not create .script and .boot files" 1>&2
exit 1
fi
- $erlc -I$target_dir/lib/*/ebin -o$tmp_dir $tmp_dir/start_sasl.rel || exit 1
- $erlc -I$target_dir/lib/*/ebin -o$tmp_dir +no_warn_sasl $tmp_dir/start_clean.rel || exit 1
- $erlc -I$target_dir/lib/*/ebin -o$tmp_dir +no_warn_sasl +no_dot_erlang $tmp_dir/no_dot_erlang.rel || exit 1
+ $erlc -I"$target_dir"/lib/*/ebin -o$tmp_dir $tmp_dir/start_sasl.rel || exit 1
+ $erlc -I"$target_dir"/lib/*/ebin -o$tmp_dir +no_warn_sasl $tmp_dir/start_clean.rel || exit 1
+ $erlc -I"$target_dir"/lib/*/ebin -o$tmp_dir +no_warn_sasl +no_dot_erlang $tmp_dir/no_dot_erlang.rel || exit 1
# Generate RELEASES file
- erl=$ERL_TOP/bootstrap/bin/erl
- if [ ! -x $erl ]; then
+ erl="$ERL_TOP/bootstrap/bin/erl"
+ if [ ! -x "$erl" ]; then
echo "erl not found, can not create RELEASES file" 1>&2
exit 1
fi
- $erl -noinput +B -eval "release_handler:create_RELEASES(\"%ERL_ROOT%\", \"$tmp_dir\", \"$tmp_dir/start_sasl.rel\", []), halt()" || exit 1
+ "$erl" -noinput +B -eval "release_handler:create_RELEASES(\"%ERL_ROOT%\", \"$tmp_dir\", \"$tmp_dir/start_sasl.rel\", []), halt()" || exit 1
# If all good so far, move generated files into target area
- mv $tmp_dir/RELEASES $target_dir/releases/RELEASES.src
- mv $tmp_dir/* $target_dir/releases/$otp_major_vsn
- rmdir $tmp_dir
+ mv "$tmp_dir/RELEASES" "$target_dir/releases/RELEASES.src"
+ mv "$tmp_dir"/* "$target_dir/releases/$otp_major_vsn"
+ rmdir "$tmp_dir"
# Remove old start scripts (forces a new run of Install)
- rm -f $target_dir/releases/RELEASES
- rm -f $target_dir/bin/*.script
- rm -f $target_dir/bin/*.boot
- rm -f $target_dir/bin/erl
+ rm -f "$target_dir"/releases/RELEASES
+ rm -f "$target_dir"/bin/*.script
+ rm -f "$target_dir"/bin/*.boot
+ rm -f "$target_dir"/bin/erl
fi
}
diff --git a/otp_versions.table b/otp_versions.table
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/otp_versions.table
diff --git a/system/doc/installation_guide/otp_version.xml b/system/doc/installation_guide/otp_version.xml
deleted file mode 100644
index 0ce5144160..0000000000
--- a/system/doc/installation_guide/otp_version.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2014</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>OTP version</title>
- <prepared></prepared>
- <responsible></responsible>
- <docno></docno>
- <approved></approved>
- <checked></checked>
- <date>2014-02-19</date>
- <rev></rev>
- <file>otp_version.xml</file>
- </header>
- <p>As of OTP release 17, the OTP release number corresponds to
- the major part of the OTP version. The OTP version as a concept was
- introduced in OTP 17. In the normal case, the OTP version will be
- constructed as
- <c>&lt;Major&gt;.&lt;Minor&gt;.&lt;Patch&gt;</c> where <c>&lt;Major&gt;</c>
- is the most significant part. However, more dot separated parts than
- this may exist. The dot separated parts consists of integers. If all
- parts less significant than <c>&lt;Minor&gt;</c> equals <c>0</c>, they
- are omitted. The three normal parts
- <c>&lt;Major&gt;.&lt;Minor&gt;.&lt;Patch&gt;</c> will be changed as
- follows:</p>
- <taglist>
- <tag><c>&lt;Major&gt;</c></tag><item>Increased when major changes,
- including incompatibilities, have been made.</item>
- <tag><c>&lt;Minor&gt;</c></tag><item>Increased when new functionality
- has been added.</item>
- <tag><c>&lt;Patch&gt;</c></tag><item>Increased when pure bug fixes
- have been made.</item>
- </taglist>
- <p>When a part in the version number is increased, all less significant
- parts are set to <c>0</c>. Release candidates have an <c>-rc&lt;N&gt;</c>
- suffix. The suffix <c>-rc0</c> will be used during development up to
- the first release candidate.</p>
-
- <p>OTP of a specific version is a set of applications of
- specific versions. The application versions identified by
- an OTP version corresponds to application versions that
- have been tested together by the Erlang/OTP team at Ericsson AB.
- An OTP system can however be put together with applications from
- different OTP versions. Such a combination of application versions
- has not been tested by the Erlang/OTP team. It is therefore
- <em>always preferred to use OTP applications from one single OTP
- version</em>.</p>
-
- <p>Application versions will be managed the same way as the OTP version.
- Application versions part of a release candidate will however not have an
- <c>-rc&lt;N&gt;</c> suffix as the OTP version. Also note that a major
- increment in an application version does not necessarily imply a major
- increment of the OTP version. This depends on whether the
- major change in the application is considered as a major change for
- OTP as a whole or not.</p>
-
- <p>In an OTP source code tree as well as in an installed OTP
- development system, the OTP version can be read from the text
- file <c>OTP_VERSION</c> in the OTP installation root directory
- (<seealso marker="kernel:code#root_dir/0"><c>code:root_dir()</c></seealso>).</p>
- <p>If the version read from the <c>OTP_VERSION</c> file in a
- development system has a <c>**</c> suffix, the system has been
- patched using the <c>$ERL_TOP/otp_build patch_app</c> tool. In
- this case, the system consists of application versions from
- multiple OTP versions. The version preceding the <c>**</c>
- suffix corresponds to the OTP version of the base system that
- has been patched. Note that if a development system is updated by
- other means than <c>$ERL_TOP/otp_build patch_app</c>, the
- <c>OTP_VERSION</c> file may identify wrong OTP version.</p>
-
- <p>On a target system (see the
- <seealso marker="doc/system_principles:create_target">system principles</seealso>
- documentation) no <c>OTP_VERSION</c> file will exist. This since
- one easily can create a target system where it is hard to even
- determine the base OTP version.</p>
-</chapter>
-
diff --git a/system/doc/installation_guide/part.xml b/system/doc/installation_guide/part.xml
index 150df39512..19808fd165 100644
--- a/system/doc/installation_guide/part.xml
+++ b/system/doc/installation_guide/part.xml
@@ -31,7 +31,6 @@
<description>
<p>How to install Erlang/OTP on UNIX or Windows.</p>
</description>
- <xi:include href="otp_version.xml"/>
<xi:include href="install-binary.xml"/>
<xi:include href="verification.xml"/>
<xi:include href="INSTALL.xml"/>
diff --git a/system/doc/installation_guide/xmlfiles.mk b/system/doc/installation_guide/xmlfiles.mk
index 245491ab94..3995c607af 100644
--- a/system/doc/installation_guide/xmlfiles.mk
+++ b/system/doc/installation_guide/xmlfiles.mk
@@ -17,7 +17,6 @@
# %CopyrightEnd%
#
INST_GUIDE_CHAPTER_FILES = \
- otp_version.xml \
install-binary.xml \
verification.xml \
INSTALL.xml \
diff --git a/system/doc/system_principles/part.xml b/system/doc/system_principles/part.xml
index 915d5aca9b..811428baae 100644
--- a/system/doc/system_principles/part.xml
+++ b/system/doc/system_principles/part.xml
@@ -31,5 +31,6 @@
<xi:include href="system_principles.xml"/>
<xi:include href="error_logging.xml"/>
<xi:include href="create_target.xml"/>
+ <xi:include href="versions.xml"/>
</part>
diff --git a/system/doc/system_principles/versions.xml b/system/doc/system_principles/versions.xml
new file mode 100644
index 0000000000..6bfa9d1eed
--- /dev/null
+++ b/system/doc/system_principles/versions.xml
@@ -0,0 +1,267 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2014</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>Versions</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date>2014-02-19</date>
+ <rev></rev>
+ <file>versions.xml</file>
+ </header>
+ <section><title>OTP Version</title>
+ <p>As of OTP release 17, the OTP release number corresponds to
+ the major part of the OTP version. The OTP version as a concept was
+ introduced in OTP 17. The <seealso marker="#version_scheme">version
+ scheme</seealso> used is described in more detail below.</p>
+
+ <p>OTP of a specific version is a set of applications of specific
+ versions. The application versions identified by an OTP version
+ corresponds to application versions that have been tested together
+ by the Erlang/OTP team at Ericsson AB. An OTP system can however be
+ put together with applications from different OTP versions. Such a
+ combination of application versions has not been tested by the
+ Erlang/OTP team. It is therefore <em>always preferred to use OTP
+ applications from one single OTP version</em>.</p>
+
+ <p>Release candidates have an <c>-rc&lt;N&gt;</c>
+ suffix. The suffix <c>-rc0</c> will be used during development up to
+ the first release candidate.</p>
+
+ <section><title>Retrieving Current OTP Version</title>
+ <p>In an OTP source code tree, the OTP version can be read from
+ the text file <c>&lt;OTP source root&gt;/OTP_VERSION</c>. The
+ absolute path to the file can be constructed by calling
+ <c>filename:join([<seealso marker="kernel:code#root_dir/0">code:root_dir()</seealso>, "OTP_VERSION"])</c>.</p>
+ <p>In an installed OTP development system, the OTP version can be read
+ from the text file <c>&lt;OTP installation root&gt;/releases/&lt;OTP release number&gt;/OTP_VERSION</c>.
+ The absolute path to the file can by constructed by calling
+ <c>filename:join([<seealso marker="kernel:code#root_dir/0">code:root_dir()</seealso>, "releases", <seealso marker="erts:erlang#system_info_otp_release">erlang:system_info(otp_release)</seealso>, "OTP_VERSION"]).</c></p>
+ <p>If the version read from the <c>OTP_VERSION</c> file in a
+ development system has a <c>**</c> suffix, the system has been
+ patched using the
+ <seealso marker="doc/installation_guide:PATCH-APP"><c>$ERL_TOP/otp_build patch_app</c></seealso>
+ tool. In this case, the system consists of application versions from
+ multiple OTP versions. The version preceding the <c>**</c>
+ suffix corresponds to the OTP version of the base system that
+ has been patched. Note that if a development system is updated by
+ other means than <c>$ERL_TOP/otp_build patch_app</c>, the
+ <c>OTP_VERSION</c> file may identify wrong OTP version.</p>
+
+ <p>No <c>OTP_VERSION</c> file will be placed in a
+ <seealso marker="create_target">target system</seealso> created
+ by OTP tools. This since one easily can create a target system
+ where it is hard to even determine the base OTP version. You may,
+ however, place such a file there yourself if you know the OTP
+ version.</p>
+ </section>
+
+ <section><title>OTP Versions Table</title>
+ <p>The text file <c>&lt;OTP source root&gt;/otp_versions.table</c>
+ part of the source code contains information about all OTP versions
+ from OTP 17.0 up to current OTP version. Each line contains information
+ about application versions part of a specific OTP version, and is on
+ the format:</p>
+<pre>
+&lt;OtpVersion&gt; : &lt;ChangedAppVersions&gt; # &lt;UnchangedAppVersions&gt;
+</pre>
+ <p><c>&lt;OtpVersion&gt;</c> is on the format <c>OTP-&lt;VSN&gt;</c>, i.e.,
+ the same as the git tag used to identify the source.
+ <c>&lt;ChangedAppVersions&gt;</c> and <c>&lt;UnchangedAppVersions&gt;</c>
+ are white space separated lists of application versions on the
+ format <c>&lt;application&gt;-&lt;vsn&gt;</c>.
+ <c>&lt;ChangedAppVersions&gt;</c> corresponds to changed applications
+ with new version numbers in this OTP version, and
+ <c>&lt;UnchangedAppVersions&gt;</c> corresponds to unchanged application
+ versions in this OTP version. Both of them might be empty, although
+ not at the same time. If &lt;ChangedAppVersions&gt; is empty, no changes
+ has been made that change the build result of any application. This could
+ for example be a pure bug fix of the build system. The order of lines
+ is undefined.</p>
+ <p>Using ordinary UNIX tools like <c>sed</c> and <c>grep</c> one
+ can easily find answers to various questions like:</p>
+ <taglist>
+ <tag>Which OTP versions are <c>kernel-3.0</c> part of?</tag>
+ <item><p><c> $ grep 'kernel-3\.0' otp_versions.table</c></p></item>
+ <tag>In which OTP version was <c>kernel-3.0</c> introduced?</tag>
+ <item><p><c> $ sed 's/#.*//;/kernel-3\.0/!d' otp_versions.table</c></p></item>
+ </taglist>
+ <p>The above commands give a bit more information than the exact answers,
+ but adequate information when manually searching for answers to these
+ questions.</p>
+ <warning><p>The format of the <c>otp_versions.table</c> might be subject
+ to changes during the OTP 17 release.</p></warning>
+ </section>
+ </section>
+
+ <section><title>Application Version</title>
+ <p>As of OTP 17.0 application versions will use the same
+ <seealso marker="#version_scheme">version scheme</seealso> as the
+ OTP version. Application versions part of a release candidate will
+ however not have an <c>-rc&lt;N&gt;</c> suffix as the OTP version.
+ Also note that a major increment in an application version does not
+ necessarily imply a major increment of the OTP version. This depends
+ on whether the major change in the application is considered as a
+ major change for OTP as a whole or not.</p>
+ </section>
+
+ <marker id="version_scheme"/>
+ <section><title>Version Scheme</title>
+ <note>Note that the version scheme was changed as of OTP 17.0. This implies
+ that application versions used prior to OTP 17.0 do not adhere to this
+ version scheme. <seealso marker="#otp_17_0_app_versions">A list of
+ application versions used in OTP 17.0</seealso> can be found
+ at the end of this document.</note>
+
+ <p>In the normal case, a version will be constructed as
+ <c>&lt;Major&gt;.&lt;Minor&gt;.&lt;Patch&gt;</c> where <c>&lt;Major&gt;</c>
+ is the most significant part. However, more dot separated parts than
+ this may exist. The dot separated parts consists of non-negative integers.
+ If all parts less significant than <c>&lt;Minor&gt;</c> equals <c>0</c>,
+ they are omitted. The three normal parts
+ <c>&lt;Major&gt;.&lt;Minor&gt;.&lt;Patch&gt;</c> will be changed as
+ follows:</p>
+ <taglist>
+ <tag><c>&lt;Major&gt;</c></tag><item>Increased when major changes,
+ including incompatibilities, have been made.</item>
+ <tag><c>&lt;Minor&gt;</c></tag><item>Increased when new functionality
+ has been added.</item>
+ <tag><c>&lt;Patch&gt;</c></tag><item>Increased when pure bug fixes
+ have been made.</item>
+ </taglist>
+ <p>When a part in the version number is increased, all less significant
+ parts are set to <c>0</c>.</p>
+
+ <p>An application version or an OTP version identifies source code
+ versions. That is, it does not imply anything about how the application
+ or OTP has been built.</p>
+
+ <section><title>Order of Versions</title>
+ <p>Version numbers in general are only partially ordered. However,
+ normal version numbers (with three parts) as of OTP 17.0 have a total
+ or linear order. This applies both to normal OTP versions and
+ normal application versions.</p>
+
+ <p>When comparing two version numbers that have an order, one
+ compare each part as ordinary integers from the most
+ significant part towards less significant parts. The order is
+ defined by the first parts of the same significance that
+ differ. An OTP version with a larger version include all
+ changes that that are part of a smaller OTP version. The same
+ goes for application versions.</p>
+
+ <p>In the general case, versions may have more than three parts. In
+ this case the versions are only partially ordered. Note that such
+ versions are only used in exceptional cases. When an extra
+ part (out of the normal three parts) is added to a version number,
+ a new branch of versions is made. The new branch has a linear
+ order against the base version. However, versions on different
+ branches have no order. Since they have no order, we
+ only know that they all include what is included in their
+ closest common ancestor. When branching multiple times from the
+ same base version, <c>0</c> parts are added between the base
+ version and the least significant <c>1</c> part until a unique
+ version is found. Versions that have an order can be compared
+ as described in the paragraph above.</p>
+
+ <p>An example of branched versions: The version <c>6.0.2.1</c>
+ is a branched version from the base version <c>6.0.2</c>.
+ Versions on the form <c>6.0.2.&lt;X&gt;</c> can be compared
+ with normal versions smaller than or equal to <c>6.0.2</c>,
+ and other versions on the form <c>6.0.2.&lt;X&gt;</c>. The
+ version <c>6.0.2.1</c> will include all changes in
+ <c>6.0.2</c>. However, <c>6.0.3</c> will most likely
+ <em>not</em> include all changes in <c>6.0.2.1</c> (note that
+ these versions have no order). A second branched version from the base
+ version <c>6.0.2</c> will be version <c>6.0.2.0.1</c>, and a
+ third branched version will be <c>6.0.2.0.0.1</c>.</p>
+ </section>
+ </section>
+
+ <marker id="otp_17_0_app_versions"/>
+ <section><title>OTP 17.0 Application Versions</title>
+ <p>The following application versions were part of OTP 17.0. If
+ the normal part of an applications version number compares
+ as smaller than the corresponding application version in this list,
+ the version number does not adhere to the version scheme introduced
+ in OTP 17.0 and should be considered as not having an order against
+ versions used as of OTP 17.0.</p>
+ <list>
+ <item><c>asn1-3.0</c></item>
+ <item><c>common_test-1.8</c></item>
+ <item><c>compiler-5.0</c></item>
+ <item><c>cosEvent-2.1.15</c></item>
+ <item><c>cosEventDomain-1.1.14</c></item>
+ <item><c>cosFileTransfer-1.1.16</c></item>
+ <item><c>cosNotification-1.1.21</c></item>
+ <item><c>cosProperty-1.1.17</c></item>
+ <item><c>cosTime-1.1.14</c></item>
+ <item><c>cosTransactions-1.2.14</c></item>
+ <item><c>crypto-3.3</c></item>
+ <item><c>debugger-4.0</c></item>
+ <item><c>dialyzer-2.7</c></item>
+ <item><c>diameter-1.6</c></item>
+ <item><c>edoc-0.7.13</c></item>
+ <item><c>eldap-1.0.3</c></item>
+ <item><c>erl_docgen-0.3.5</c></item>
+ <item><c>erl_interface-3.7.16</c></item>
+ <item><c>erts-6.0</c></item>
+ <item><c>et-1.5</c></item>
+ <item><c>eunit-2.2.7</c></item>
+ <item><c>gs-1.5.16</c></item>
+ <item><c>hipe-3.10.3</c></item>
+ <item><c>ic-4.3.5</c></item>
+ <item><c>inets-5.10</c></item>
+ <item><c>jinterface-1.5.9</c></item>
+ <item><c>kernel-3.0</c></item>
+ <item><c>megaco-3.17.1</c></item>
+ <item><c>mnesia-4.12</c></item>
+ <item><c>observer-2.0</c></item>
+ <item><c>odbc-2.10.20</c></item>
+ <item><c>orber-3.6.27</c></item>
+ <item><c>os_mon-2.2.15</c></item>
+ <item><c>ose-1.0</c></item>
+ <item><c>otp_mibs-1.0.9</c></item>
+ <item><c>parsetools-2.0.11</c></item>
+ <item><c>percept-0.8.9</c></item>
+ <item><c>public_key-0.22</c></item>
+ <item><c>reltool-0.6.5</c></item>
+ <item><c>runtime_tools-1.8.14</c></item>
+ <item><c>sasl-2.4</c></item>
+ <item><c>snmp-4.25.1</c></item>
+ <item><c>ssh-3.0.1</c></item>
+ <item><c>ssl-5.3.4</c></item>
+ <item><c>stdlib-2.0</c></item>
+ <item><c>syntax_tools-1.6.14</c></item>
+ <item><c>test_server-3.7</c></item>
+ <item><c>tools-2.6.14</c></item>
+ <item><c>typer-0.9.6</c></item>
+ <item><c>webtool-0.8.10</c></item>
+ <item><c>wx-1.2</c></item>
+ <item><c>xmerl-1.3.7</c></item>
+ </list>
+ </section>
+</chapter>
+
diff --git a/system/doc/system_principles/xmlfiles.mk b/system/doc/system_principles/xmlfiles.mk
index 4cbc00ed52..9743949798 100644
--- a/system/doc/system_principles/xmlfiles.mk
+++ b/system/doc/system_principles/xmlfiles.mk
@@ -19,4 +19,5 @@
SYSTEM_PRINCIPLES_CHAPTER_FILES = \
system_principles.xml \
error_logging.xml \
- create_target.xml
+ create_target.xml \
+ versions.xml