diff options
44 files changed, 1227 insertions, 745 deletions
diff --git a/HOWTO/INSTALL-CROSS.md b/HOWTO/INSTALL-CROSS.md index 10f463c06d..af4b38f292 100644 --- a/HOWTO/INSTALL-CROSS.md +++ b/HOWTO/INSTALL-CROSS.md @@ -563,12 +563,6 @@ under the License. %CopyrightEnd% -Modifying This Document ------------------------ - -Before modifying this document you need to have a look at the -[$ERL_TOP/HOWTO/MARKDOWN.md][] document. - [$ERL_TOP/HOWTO/INSTALL.md]: INSTALL.md @@ -576,6 +570,4 @@ Before modifying this document you need to have a look at the [How to Build the Documentation]: INSTALL.md#The-ErlangOTP-Documentation_How-to-Build-the-Documentation [cross configuration variables]: #Currently-Used-Configuration-Variables [DESTDIR]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html - [$ERL_TOP/HOWTO/MARKDOWN.md]: MARKDOWN.md - [?TOC]: true diff --git a/HOWTO/INSTALL-WIN32.md b/HOWTO/INSTALL-WIN32.md index 94d3688f23..0387572dd3 100644 --- a/HOWTO/INSTALL-WIN32.md +++ b/HOWTO/INSTALL-WIN32.md @@ -1018,7 +1018,7 @@ Copyright and License %CopyrightBegin% -Copyright Ericsson AB 2003-2012. All Rights Reserved. +Copyright Ericsson AB 2003-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 @@ -1033,15 +1033,7 @@ under the License. %CopyrightEnd% -Modifying This Document ------------------------ - -Before modifying this document you need to have a look at the -[$ERL_TOP/HOWTO/MARKDOWN.md][] document. - - [1]: http://www.erlang.org/faq.html "mailing lists" - [$ERL_TOP/HOWTO/MARKDOWN.md]: MARKDOWN.md [?TOC]: true diff --git a/HOWTO/INSTALL.md b/HOWTO/INSTALL.md index 368947b36c..f1bb8ec853 100644 --- a/HOWTO/INSTALL.md +++ b/HOWTO/INSTALL.md @@ -4,174 +4,109 @@ Building and Installing Erlang/OTP Introduction ------------ -This document describes how to build and install Erlang/OTP-%OTP-REL%. You -are advised to read the whole document before attempting to build and install -Erlang/OTP. You can find more information about Open Source Erlang/OTP at: +This document describes how to build and install Erlang/OTP-%OTP-REL%. +Erlang/OTP should be possible to build from source on any Unix/Linux system, +including OS X. You are advised to read the whole document +before attempting to build and install Erlang/OTP. - <http://www.erlang.org/> +The source code can be downloaded from the official site of Erlang/OTP or GitHub. +* <http://www.erlang.org> +* <https://github.com/erlang/otp> -The source code for Erlang/OTP can also be found in a Git repository: - - <http://github.com/erlang/otp> - -Erlang/OTP should be possible to build from source on any Unix system, -including Mac OS X. This document describes how to native compile Erlang/OTP -on Unix. For detailed instructions on how to - -* cross compile Erlang/OTP, see the [$ERL_TOP/HOWTO/INSTALL-CROSS.md][] - document. - -* build Erlang/OTP on Windows, see the [$ERL_TOP/HOWTO/INSTALL-WIN32.md][] - document. +Required Utilities +------------------ - Binary releases for Windows can be found at - <http://www.erlang.org/download.html>. +These are the tools you need in order to unpack and build Erlang/OTP. -Before reading the above mentioned documents you are in any case advised to -read this document first, since it covers building Erlang/OTP in general as -well as other important information. +> *WARNING*: Please have a look at the [Known platform issues][] chapter +> before you start. -Daily Build and Test --------------------- -At Ericsson we have a "Daily Build and Test" that runs on: - -* Solaris 8, 9 - * Sparc32 - * Sparc64 -* Solaris 10 - * Sparc32 - * Sparc64 - * x86 -* SuSE Linux/GNU 9.4, 10.1 - * x86 -* SuSE Linux/GNU 10.0, 10.1, 11.0 - * x86 - * x86\_64 -* openSuSE 11.4 (Celadon) - * x86\_64 (valgrind) -* Fedora 7 - * PowerPC -* Fedora 14 - * x86\_64 -* Gentoo Linux/GNU 1.12.11.1 - * x86 -* Ubuntu Linux/GNU 7.04, 10.04, 10.10, 11.0 - * x86\_64 -* MontaVista Linux/GNU 4.0.1 - * PowerPC -* FreeBSD 8.2 - * x86 -* OpenBSD 5.0 - * x86\_64 -* Mac OS X 10.5.8 (Leopard), 10.7.3 (Lion), 10.9 (Mavericks) - * x86 -* Windows XP SP3, 2003, Vista, 7 - * x86 -* Windows 7 - * x86\_64 +### Unpacking ### -We also have the following "Daily Cross Builds": +* GNU unzip, or a modern uncompress. +* A TAR program that understands the GNU TAR format for long filenames. -* SuSE Linux/GNU 10.1 x86 -> SuSE Linux/GNU 10.1 x86\_64 -* SuSE Linux/GNU 10.1 x86\_64 -> Linux/GNU TILEPro64 +### Building ### -and the following "Daily Cross Build Tests": +* GNU `make` +* Compiler -- GNU C Compiler, `gcc` or the C compiler frontend for LLVM, `clang`. +* Perl 5 +* GNU `m4` -- If HiPE (native code) support is enabled. HiPE can be + disabled using `--disable-hipe` +* `ncurses`, `termcap`, or `termlib` -- The development headers and + libraries are needed, often known as `ncurses-devel`. Use + `--without-termcap` to build without any of these libraries. Note that + in this case only the old shell (without any line editing) can be used. +* `sed` -- Stream Editor for basic text transformation. -* SuSE Linux/GNU 10.1 x86\_64 +#### Building in Git #### -Versions Known NOT to Work --------------------------- +* GNU `autoconf` of at least version 2.59. Note that `autoconf` is not + needed when building an unmodified version of the released source. -* Suse linux 9.1 is shipped with a patched GCC version 3.3.3, having the - rpm named `gcc-3.3.3-41`. That version has a serious optimization bug - that makes it unusable for building the Erlang emulator. Please - upgrade GCC to a newer version before building on Suse 9.1. Suse Linux - Enterprise edition 9 (SLES9) has `gcc-3.3.3-43` and is not affected. +#### Building on OS X #### -* `gcc-4.3.0` has a serious optimizer bug. It produces an Erlang emulator - that will crash immediately. The bug is supposed to be fixed in - `gcc-4.3.1`. +* Xcode -- Download and install via the Mac App Store. + Read about [Building on a Mac][] before proceeding. -* FreeBSD had a bug which caused `kqueue`/`poll`/`select` to fail to detect - that a `writev()` on a pipe has been made. This bug should have been fixed - in FreeBSD 6.3 and FreeBSD 7.0. NetBSD and DragonFlyBSD probably have or - have had the same bug. More information can be found at: +### Installing ### - * <http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/sys_pipe.c> - * <http://lists.freebsd.org/pipermail/freebsd-arch/2007-September/006790.html> +* An `install` program that can take multiple file names. -* `getcwd()` on Solaris 9 can cause an emulator crash. If you have - async-threads enabled you can increase the stack size of the - async-threads as a temporary workaround. See the `+a` command-line - argument in the documentation of `erl(1)`. Without async-threads the - emulator is not as vulnerable to this bug, but if you hit it without - async-threads the only workaround available is to enable async-threads - and increase the stack size of the async-threads. Sun has however - released patches that fixes the issue: - > Problem Description: 6448300 large mnttab can cause stack overrun - > during Solaris 9 getcwd +Optional Utilities +------------------ - More information can be found at: +Some applications are automatically skipped if the dependencies aren't met. +Here is a list of utilities needed for those applications. You will +also find the utilities needed for building the documentation. - * <http://sunsolve.sun.com/search/document.do?assetkey=1-21-112874-40-1&searchclause=6448300> - * <http://sunsolve.sun.com/search/document.do?assetkey=1-21-114432-29-1&searchclause=6448300> +### Building ### -Required Utilities ------------------- +* OpenSSL -- The opensource toolkit for Secure Socket Layer + and Transport Layer Security. + Required for building the application `crypto`. + Further, `ssl` and `ssh` require a working crypto application and + will also be skipped if OpenSSL is missing. The `public_key` + application will available without `crypto`, but the functionality + will be very limited. + + The development package of OpenSSL including the header files are needed as well + as the binary command program `openssl`. At least version 0.9.8 of OpenSSL is required. + Read more and download from <http://www.openssl.org>. +* Oracle Java SE JDK -- The Java Development Kit (Standard Edition). + Required for building the application `jinterface` and parts of `ic` and `orber`. + At least version 1.5.0 of the JDK is required. + + Download from <http://www.oracle.com/technetwork/java/javase/downloads>. + We have also tested with IBM's JDK 1.5.0. +* X Windows -- Development headers and libraries are needed + to build the Erlang/OTP application `gs` on Unix/Linux. +* `flex` -- Headers and libraries are needed to build the flex + scanner for the `megaco` application on Unix/Linux. +* wxWidgets -- Toolkit for GUI applications. + Required for building the `wx` application. At least + version 3.0 of wxWidgets is required. -These are the tools you will need in order to unpack and build Erlang/OTP. + Download from <http://sourceforge.net/projects/wxwindows/files/3.0.0/> + or get it from GitHub: <https://github.com/wxWidgets/wxWidgets> -### Unpacking ### + Further instructions on wxWidgets, read [Building with wxErlang][]. -* GNU unzip, or a modern uncompress. -* A TAR program that understands the GNU TAR format for long filenames - (such as GNU TAR). -### Building ### -* GNU `make` -* `gcc` -- GNU C compiler -* Perl 5 -* GNU `m4` -- If HiPE (native code) support is enabled. HiPE can be - disabled using `--disable-hipe` -* `ncurses`, `termcap`, or `termlib` -- The development headers and - libraries are needed, often known as `ncurses-devel`. Use - `--without-termcap` to build without any of these libraries. Note that - in this case only the old shell (without any line editing) can be used. -* OpenSSL -- Optional, but needed for building the Erlang/OTP applications - `ssl` and `crypto`. You need the "development package" of OpenSSL, i.e. - including the header files. For building the application `ssl` the OpenSSL - binary command program `openssl` is also needed. At least version 0.9.8 - of OpenSSL is required. Can be downloaded from <http://www.openssl.org>. -* Sun Java jdk-1.5.0 or higher -- Optional but needed for building the - Erlang/OTP application `jinterface` and parts of `ic` and `orber`. Can - be downloaded from <http://java.sun.com>. We have also tested IBM's - JDK 1.5.0. -* X Windows -- Optional, but development headers and libraries are needed - to build the Erlang/OTP application `gs` on Unix/Linux. -* `sed` -- There seem to be some problems with some of the `sed` version on - Solaris. Make sure `/bin/sed` or `/usr/bin/sed` is used on the Solaris - platform. -* `flex` -- Optional, headers and libraries are needed to build the `flex` - scanner for the `megaco` application on Unix/Linux. +### Building Documentation ### -#### Building Documentation #### +* `xsltproc` -- A command line XSLT processor. -* `xsltproc` -- XSLT processor. A tool for applying XSLT stylesheets - to XML documents. Can be downloaded from + A tool for applying XSLT stylesheets + to XML documents. Download xsltproc from <http://xmlsoft.org/XSLT/xsltproc2.html>. + * `fop` -- Apache FOP print formatter (requires Java). Can be downloaded from <http://xmlgraphics.apache.org/fop>. -#### Building in Git #### -* GNU `autoconf` of at least version 2.59. Note that `autoconf` is not - needed when building an unmodified version of the released source. - -### Installing ### - -* An `install` program that can take multiple file names. How to Build and Install Erlang/OTP ----------------------------------- @@ -186,65 +121,205 @@ section below before proceeding. ### Unpacking ### -Step 1: Start by unpacking the Erlang/OTP distribution file with your GNU +Start by unpacking the Erlang/OTP distribution file with your GNU compatible TAR program. - $ gunzip -c otp_src_%OTP-VSN%.tar.gz | tar xf - + $ tar -zxf otp_src_%OTP-VSN%.tar.gz # Assuming bash/sh -alternatively: - - $ zcat otp_src_%OTP-VSN%.tar.gz | tar xf - - - -Step 2: Now cd into the base directory (`$ERL_TOP`). +Now change directory into the base directory and set the `$ERL_TOP` variable. $ cd otp_src_%OTP-VSN% + $ export ERL_TOP=`pwd` # Assuming bash/sh ### Configuring ### -Step 3: On some platforms Perl may behave strangely if certain locales are -set, so optionally you may need to set the LANG variable: - - # Bourne shell - $ LANG=C; export LANG +Run the following commands to configure the build: -or + $ ./configure [ options ] - # C-Shell - $ setenv LANG C +> *NOTE*: If you are building Erlang/OTP from git you will need to run `./otp_build autoconf` to generate +> the configure scripts. -Step 4: Run the following commands to configure the build: +By default, Erlang/OTP release will be installed in `/usr/local/{bin,lib/erlang}`. +If you for instance don't have the permission to install in the standard location, + you can install Erlang/OTP somewhere else. For example, to install in +`/opt/erlang/%OTP-VSN%/{bin,lib/erlang}`, use the `--prefix=/opt/erlang/%OTP-VSN%` option. - $ ./configure [ options ] +On some platforms Perl may behave strangely if certain locales are +set. If you get errors when building, try setting the LANG variable: -If you are building it from git you will need to run `./otp_build autoconf` to generate configure file. -By default, Erlang/OTP will be installed in `/usr/local/{bin,lib/erlang}`. -To instead install in `<BaseDir>/{bin,lib/erlang}`, use the -`--prefix=<BaseDir>` option. + $ export LANG=C # Assuming bash/sh -If you upgraded the source with some patch you may need to clean up -from previous builds before the new build. Before doing a `make clean`, -be sure to read the [Pre-built Source Release][] section below. ### Building ### -Step 5: Build the Erlang/OTP package. +Build the Erlang/OTP release. $ make + +### Testing ### + +Before installation you should test whether your build is working properly +by running our smoke test. The smoke test is a subset of the complete Erlang/OTP test suites. +First you will need to build and release the test suites. + + $ make release_tests + +This creates an additional folder in `$ERL_TOP/release` called `tests`. +Now, it's time to start the smoke test. + + $ cd release/tests/test_server + $ $ERL_TOP/bin/erl -s ts install -s ts smoke_test batch -s init stop + +To verify that everything is ok you should open `$ERL_TOP/release/tests/test_server/index.html` +in your web browser and make sure that there are zero failed test cases. + +> *NOTE*: On builds without `crypto`, `ssl` and `ssh` there is a failed test case +> for undefined functions. Verify that the failed test case log only shows calls +> to skipped applications. + ### Installing ### -Step 6: Install then Erlang/OTP package +You are now ready to install the Erlang/OTP release! +The following command will install the release on your system. $ make install -### A Closer Look at the individual Steps ### -Let us go through them in some detail. +### Running ### + +You should now have a working release of Erlang/OTP! +Jump to [System Principles][] for instructions on running Erlang/OTP. + + +### How to Build the Documentation ### + +Make sure you're in the top directory in the source tree. + + $ cd $ERL_TOP + +If you have just built Erlang/OTP in the current source tree, you have +already ran `configure` and do not need to do this again; otherwise, run +`configure`. + + $ ./configure [Configure Args] + +When building the documentation you need a full Erlang/OTP-%OTP-VSN% system in +the `$PATH`. + + $ export PATH=$ERL_TOP/bin:$PATH # Assuming bash/sh + +Build the documentation. -#### Configuring #### + $ make docs + +#### Build Issues #### + +We have sometimes experienced problems with Oracle's `java` running out of +memory when running `fop`. Increasing the amount of memory available +as follows has in our case solved the problem. + + $ export FOP_OPTS="-Xmx<Installed amount of RAM in MB>m" + +More information can be found at +* <http://xmlgraphics.apache.org/fop/0.95/running.html#memory>. + + +### How to Install the Documentation ### + +The documentation can be installed either using the `install-docs` target, +or using the `release_docs` target. + +* If you have installed Erlang/OTP using the `install` target, install + the documentation using the `install-docs` target. Install locations + determined by `configure` will be used. `$DESTDIR` can be used the + same way as when doing `make install`. + + $ make install-docs + +* If you have installed Erlang/OTP using the `release` target, install + the documentation using the `release_docs` target. You typically want + to use the same `RELEASE_ROOT` as when invoking `make release`. + + $ make release_docs RELEASE_ROOT=<release dir> + + +### Accessing the Documentation ### + +After installation you can access the documentation by + +* Reading man pages. Make sure that `erl` is referring to the + installed version. For example `/usr/local/bin/erl`. + Try viewing at the man page for Mnesia + + $ erl -man mnesia + +* Browsing the html pages by loading the page `/usr/local/lib/erlang/doc/erlang/index.html` + or `<BaseDir>/lib/erlang/doc/erlang/index.html` if the prefix option has been used. + + +### How to Install the Pre-formatted Documentation ### + +Pre-formatted [html documentation][] and [man pages][] can be downloaded from +* <http://www.erlang.org/download.html>. + +Extract the html archive in the installation directory. + + $ cd <ReleaseDir> + $ tar -zxf otp_html_%OTP-VSN%.tar.gz + +For `erl -man <page>` to work the Unix manual pages have to be +installed in the same way, i.e. + + $ cd <ReleaseDir> + $ tar -zxf otp_man_%OTP-VSN%.tar.gz + +Where `<ReleaseDir>` is + +* `<PrefixDir>/lib/erlang` if you have installed Erlang/OTP using + `make install`. +* `$DESTDIR<PrefixDir>/lib/erlang` if you have installed Erlang/OTP + using `make install DESTDIR=<TmpInstallDir>`. +* `RELEASE_ROOT` if you have installed using + `make release RELEASE_ROOT=<ReleaseDir>`. + + +Advanced configuration and build of Erlang/OTP +---------------------------------------------- + +If you want to tailor your Erlang/OTP build and installation, please read +on for detailed information about the individual steps. + +### make and $ERL\_TOP ### + +All the makefiles in the entire directory tree use the environment +variable `ERL_TOP` to find the absolute path of the installation. The +`configure` script will figure this out and set it in the top level +Makefile (which, when building, it will pass on). However, when +developing it is sometimes convenient to be able to run make in a +subdirectory. To do this you must set the `ERL_TOP` variable +before you run make. -Step 4 runs a configuration script created by the GNU autoconf utility, which +For example, assume your GNU make program is called `make` and you +want to rebuild the application `STDLIB`, then you could do: + + $ cd lib/stdlib; env ERL_TOP=<Dir> make + +where `<Dir>` would be what you find `ERL_TOP` is set to in the top level +Makefile. + +### otp\_build vs configure/make ### + +Building Erlang/OTP can be done either by using the `$ERL_TOP/otp_build` +script, or by invoking `$ERL_TOP/configure` and `make` directly. Building using +`otp_build` is easier since it involves fewer steps, but the `otp_build` build +procedure is not as flexible as the `configure`/`make` build procedure. The binary +releases for Windows that we deliver are built using `otp_build`. + +### Configuring ### + +The configure script is created by the GNU autoconf utility, which checks for system specific features and then creates a number of makefiles. The configure script allows you to customize a number of parameters; @@ -260,10 +335,10 @@ use the `--prefix` argument like this: `./configure --prefix=<Dir>`. Some of the available `configure` options are: * `--prefix=PATH` - Specify installation prefix. -* `--{enable,disable}-threads` - Thread support (enabled by default if - possible) + +* `--{enable,disable}-threads` - Thread support. This is enabled by default if possible. * `--{enable,disable}-smp-support` - SMP support (enabled by default if - possible) + a usable POSIX thread library or native Windows threads is found) * `--{enable,disable}-kernel-poll` - Kernel poll support (enabled by default if possible) * `--{enable,disable}-hipe` - HiPE support (enabled by default on supported @@ -321,9 +396,9 @@ Some of the available `configure` options are: to configure. * `--without-$app` - By default all applications in Erlang/OTP will be included in a release. If this is not wanted it is possible to specify that Erlang/OTP - should be compiled without that applications, i.e. `--without-wx`. There is - no automatic dependency handling inbetween applications. So if you disable - an application that another depends on, you also have to disable the + should be compiled without one or more applications, i.e. `--without-wx`. There is + no automatic dependency handling between applications. If you disable + an application that another application depends on, you also have to disable the dependant application. * `--enable-dirty-schedulers` - Enable the **experimental** dirty schedulers functionality. Note that the dirty schedulers functionality is experimental, @@ -334,26 +409,133 @@ Some of the available `configure` options are: If you or your system has special requirements please read the `Makefile` for additional configuration information. -#### Building #### -Step 5 builds the Erlang/OTP system. On a fast computer, this will take about -5 minutes. After completion of this step, you should have a working -Erlang/OTP system which you can try by typing `bin/erl`. This should start -up Erlang/OTP and give you a prompt: +### Building ### + +Building Erlang/OTP on a relatively fast computer takes approximately +5 minutes. To speed it up, you can utilize parallel make with the `-j<num_jobs>` option. + + $ export MAKEFLAGS=-j8 # Assuming bash/sh + $ make + +If you've upgraded the source with a patch you may need to clean up from previous +builds before the new build. +Make sure to read the [Pre-built Source Release][] section below before doing a `make clean`. + +#### Within Git #### + +When building in a Git working directory you also have to have a GNU `autoconf` +of at least version 2.59 on your system, because you need to generate the +`configure` scripts before you can start building. + +The `configure` scripts are generated by invoking `./otp_build autoconf` in +the `$ERL_TOP` directory. The `configure` scripts also have to be regenerated +when a `configure.in` or `aclocal.m4` file has been modified. Note that when +checking out a branch a `configure.in` or `aclocal.m4` file may change +content, and you may therefore have to regenerate the `configure` scripts +when checking out a branch. Regenerated `configure` scripts imply that you +have to run `configure` and build again. + +> *NOTE*: Running `./otp_build autoconf` is **not** needed when building +> an unmodified version of the released source. + +Other useful information can be found at our GitHub wiki: +* <http://wiki.github.com/erlang/otp> + +#### OS X (Darwin) #### + +Make sure that the command `hostname` returns a valid fully qualified host +name (this is configured in `/etc/hostconfig`). Otherwise you might experience +problems when running distributed systems. + +If you develop linked-in drivers (shared library) you need to link using +`gcc` and the flags `-bundle -flat_namespace -undefined suppress`. You also +include `-fno-common` in `CFLAGS` when compiling. Use `.so` as the library +suffix. + +If you have Xcode 4.3, or later, you will also need to download +"Command Line Tools" via the Downloads preference pane in Xcode. + +#### Building with wxErlang #### + +Be aware that the wxWidgets-3.0 is a new release of wxWidgets, it is not as matured +as the old releases and the OS X port still lags behind the other ports. + +Configure and build wxWidgets (on Mavericks - 10.9): + + $ ./configure --with-cocoa --prefix=/usr/local + or without support for old versions and with static libs + $ ./configure --with-cocoa --prefix=/usr/local --with-macosx-version-min=10.9 --disable-shared + $ make + $ sudo make install + $ export PATH=/usr/local/bin:$PATH + +Check that you got the correct wx-config + + $ which wx-config && wx-config --version-full + +Build Erlang/OTP + + $ export PATH=/usr/local/bin:$PATH + $ cd $ERL_TOP + $ ./configure --enable-shared-zlib + $ make + $ sudo make install + + +#### Pre-built Source Release #### + +The source release is delivered with a lot of platform independent +build results already pre-built. If you want to remove these pre-built +files, invoke `./otp_build remove_prebuilt_files` from the `$ERL_TOP` +directory. After you have done this, you can build exactly the same way +as before, but the build process will take a much longer time. + +> *WARNING*: Doing `make clean` in an arbitrary directory of the source +> tree, may remove files needed for bootstrapping the build. +> +> Doing `./otp_build save_bootstrap` from the `$ERL_TOP` directory before +> doing `make clean` will ensure that it will be possible to build after +> doing `make clean`. `./otp_build save_bootstrap` will be invoked +> automatically when `make` is invoked from `$ERL_TOP` with either the +> `clean` target, or the default target. It is also automatically invoked +> if `./otp_build remove_prebuilt_files` is invoked. + +#### How to Build a Debug Enabled Erlang RunTime System #### + +After completing all the normal building steps described above a debug +enabled runtime system can be built. To do this you have to change +directory to `$ERL_TOP/erts/emulator`. + +In this directory execute: + + $ make debug FLAVOR=$FLAVOR + +where `$FLAVOR` is either `plain` or `smp`. The flavor options will +produce a beam.debug and beam.smp.debug executable respectively. The +files are installed along side with the normal (opt) versions `beam.smp` +and `beam`. + +To start the debug enabled runtime system execute: + + $ $ERL_TOP/bin/cerl -debug - $ bin/erl - Erlang/OTP %OTP-REL% [erts-%ERTS-VSN%] [source] [smp:4:4] [async-threads:0] [kernel-poll:false] +The debug enabled runtime system features lock violation checking, +assert checking and various sanity checks to help a developer ensure +correctness. Some of these features can be enabled on a normal beam +using appropriate configure options. - Eshell V%ERTS-VSN% (abort with ^G) - 1> _ +There are other types of runtime systems that can be built as well +using the similar steps just described. -#### Installing #### + $ make $TYPE FLAVOR=$FLAVOR + +where `$TYPE` is `opt`, `gcov`, `gprof`, `debug`, `valgrind`, or `lcnt`. +These different beam types are useful for debugging and profiling +purposes. -Step 6 is optional. It installs Erlang/OTP at a standardized location (if you -change your mind about where you wish to install you can rerun step 4, -without having to do step 5 again). -##### Alternative Installation Procedures ##### +### Installing ### * Staged install using [DESTDIR][]. You can perform the install phase in a temporary directory and later move the installation into @@ -435,7 +617,7 @@ without having to do step 5 again). if you want to try the system out, running test suites, etc, before doing the real install without `EXTRA_PREFIX`. -### Symbolic Links in --bindir ### +#### Symbolic Links in --bindir #### When doing `make install` and the default installation prefix is used, relative symbolic links will be created from `/usr/local/bin` to all public @@ -449,156 +631,10 @@ passed to `configure`. One can force relative, or absolute links by passing phase. Note that such a request might cause a failure if the request cannot be satisfied. -### Pre-built Source Release ### - -The source release is delivered with a lot of platform independent -build results already pre-built. If you want to remove these pre-built -files, invoke `./otp_build remove_prebuilt_files` from the `$ERL_TOP` -directory. After you have done this, you can build exactly the same way -as before, but the build process will take a much longer time. - -> *WARNING*: Doing `make clean` in an arbitrary directory of the source -> tree, may remove files needed for bootstrapping the build. -> -> Doing `./otp_build save_bootstrap` from the `$ERL_TOP` directory before -> doing `make clean` will ensure that it will be possible to build after -> doing `make clean`. `./otp_build save_bootstrap` will be invoked -> automatically when `make` is invoked from `$ERL_TOP` with either the -> `clean` target, or the default target. It is also automatically invoked -> if `./otp_build remove_prebuilt_files` is invoked. - -### Building in Git ### - -When building in a Git working directory you also have to have a GNU `autoconf` -of at least version 2.59 on your system, because you need to generate the -`configure` scripts before you can start building. - -The `configure` scripts are generated by invoking `./otp_build autoconf` in -the `$ERL_TOP` directory. The `configure` scripts also have to be regenerated -when a `configure.in` or `aclocal.m4` file has been modified. Note that when -checking out a branch a `configure.in` or `aclocal.m4` file may change -content, and you may therefore have to regenerate the `configure` scripts -when checking out a branch. Regenerated `configure` scripts imply that you -have to run `configure` and build again. - -> *NOTE*: Running `./otp_build autoconf` is **not** needed when building -> an unmodified version of the released source. - -Other useful information can be found at our github wiki: -<http://wiki.github.com/erlang/otp> - -### make and $ERL\_TOP ### - -All the makefiles in the entire directory tree use the environment -variable `ERL_TOP` to find the absolute path of the installation. The -`configure` script will figure this out and set it in the top level -Makefile (which, when building, it will pass on). However, when -developing it is sometimes convenient to be able to run make in a -subdirectory. To do this you must set the `ERL_TOP` variable -before you run make. - -For example, assume your GNU make program is called `make` and you -want to rebuild the application `STDLIB`, then you could do: - - $ cd lib/stdlib; env ERL_TOP=<Dir> make - -where `<Dir>` would be what you find `ERL_TOP` is set to in the top level -Makefile. - -The Erlang/OTP Documentation ----------------------------- - -### How to Build the Documentation ### - -Before you can build the documentation you need to either [native build][] -or [cross build][] the Erlang/OTP system. After this you can build the -documentation as follows. - - $ cd $ERL_TOP - $ make docs - -The documentation can be installed either using the `install-docs` target, -or using the `release_docs` target. - -* If you have installed Erlang/OTP using the `install` target, install - the documentation using the `install-docs` target. Install locations - determined by `configure` will be used. `$DESTDIR` can be used the - same way as when doing `make install`. - - $ make install-docs - -* If you have installed Erlang/OTP using the `release` target, install - the documentation using the `release_docs` target. You typically want - to use the same `RELEASE_ROOT` as when invoking `make release`. - - $ make release_docs RELEASE_ROOT=<release dir> - -#### Build Issues #### - -We have sometimes experienced problems with Sun's `java` running out of -memory when running `fop`. Increasing the amount of memory available -as follows has in our case solved the problem. - - $ export FOP_OPTS="-Xmx<Installed amount of RAM in MB>m" - -More information can be found at -<http://xmlgraphics.apache.org/fop/0.95/running.html#memory>. - -### How to Install the Pre-formatted Documentation ### - -Pre-formatted [html documentation][] and [man pages][] can be downloaded at -<http://www.erlang.org/download.html>. - -For some graphical tools to find the on-line help you have to install -the HTML documentation on top of the installed OTP applications, i.e. - - $ cd <ReleaseDir> - $ gunzip -c otp_html_%OTP-VSN%.tar.gz | tar xf - - -For `erl -man <page>` to work the Unix manual pages have to be -installed in the same way, i.e. - - $ cd <ReleaseDir> - $ gunzip -c otp_man_%OTP-VSN%.tar.gz | tar xf - - -Where `<ReleaseDir>` is - -* `<PrefixDir>/lib/erlang` if you have installed Erlang/OTP using - `make install`. -* `$DESTDIR<PrefixDir>/lib/erlang` if you have installed Erlang/OTP - using `make install DESTDIR=<TmpInstallDir>`. -* `RELEASE_ROOT` if you have installed using - `make release RELEASE_ROOT=<ReleaseDir>`. - -Support for SMP (Symmetric Multi Processing) --------------------------------------------- - -An emulator with SMP support will be built by default on most platforms -if a usable POSIX thread library or native Windows threads is found. -You can force building of an SMP emulator, by using -`./configure --enable-smp-support`. However, if configure does not -automatically enable SMP support, the build is very likely to fail. +### Running ### -Use `./configure --disable-smp-support` if you for some reason do not -want to have the emulator with SMP support built. - -If SMP support is enabled, support for threaded I/O will also be turned on -(also in the emulator without SMP support). - -The `erl` command will automatically start the SMP emulator if the -computer has more than one logical processor. You can force a start -of the emulator with SMP support by passing `-smp enable` as -command line arguments to erl, and you can force a start of the -emulator without SMP support by passing `-smp disable`. - -GS (Graphic System) -------------------- - -GS now Tcl/Tk 8.4. It will be searched for when starting GS. - -Using HiPE ----------- +#### Using HiPE #### HiPE supports the following system configurations: @@ -619,12 +655,12 @@ HiPE supports the following system configurations: * FreeBSD: FreeBSD 6.1 and 6.2 in 32-bit and 64-bit modes should work. - * MacOSX/Darwin: Darwin 9.8.0 in 32-bit mode should work. + * OS X/Darwin: Darwin 9.8.0 in 32-bit mode should work. * PowerPC: All 32-bit 6xx/7xx(G3)/74xx(G4) processors should work. 32-bit mode on 970 (G5) and POWER5 processors should work. - * Linux (Yellow Dog) and Mac OSX 10.4 are supported. + * Linux (Yellow Dog) and OS X 10.4 are supported. * SPARC: All UltraSPARC processors running 32-bit user code should work. @@ -643,11 +679,11 @@ HiPE is automatically enabled on the following systems: * x86 in 32-bit mode: Linux, Solaris, FreeBSD * x86 in 64-bit mode: Linux, Solaris, FreeBSD -* PowerPC: Linux, MacOSX +* PowerPC: Linux, Mac OSX * SPARC: Linux * ARM: Linux -On other supported systems you need to `./configure --enable-hipe`. +On other supported systems, see [Advanced Configure][] on how to enable HiPE. If you are running on a platform supporting HiPE and if you have not disabled HiPE, you can compile a module into native code like this from the Erlang @@ -659,7 +695,7 @@ or 1> c(Module, [native|OtherOptions]). -Using the erlc program, write like this: +Using the erlc program, write like this $ erlc +native Module.erl @@ -674,88 +710,103 @@ Use `hipe:help_options/0` to print out the available options. 1> hipe:help_options(). -Mac OS X (Darwin) ------------------ - -Make sure that the command `hostname` returns a valid fully qualified host -name (this is configured in `/etc/hostconfig`). - -If you develop linked-in drivers (shared library) you need to link using -`gcc` and the flags `-bundle -flat_namespace -undefined suppress`. You also -include `-fno-common` in `CFLAGS` when compiling. Use `.so` as the library -suffix. - -Install `Xcode` from the `AppStore` if it is not already installed. - -If you have Xcode 4.3, or later, you will also need to download -"Command Line Tools" via the Downloads preference pane in Xcode. - -### Building with wxErlang ### +#### Running with GS #### -If you want to build the `wx` application, you will need to get wxWidgets-3.0 (or later) -(`wxWidgets-3.0.0.tar.bz2` from <http://sourceforge.net/projects/wxwindows/files/3.0.0/>) -or get it from github: - $ git clone [email protected]:wxWidgets/wxWidgets.git +The `gs` application requires the GUI toolkit Tcl/Tk to run. At least +version 8.4 is required. -Be aware that the wxWidgets-3.0 is a new release of wxWidgets, it is not as matured -as the old releases and the MacOsX port still lags behind the other ports. - -Configure and build wxWidgets (on Mavericks - 10.9): - $ ./configure --with-cocoa --prefix=/usr/local - or without support for old versions and with static libs - $ ./configure --with-cocoa --prefix=/usr/local --with-macosx-version-min=10.9 --disable-shared - $ make - $ sudo make install - $ export PATH=/usr/local/bin:$PATH +Known platform issues +--------------------- -Check that you got the correct wx-config +* Suse linux 9.1 is shipped with a patched GCC version 3.3.3, having the + rpm named `gcc-3.3.3-41`. That version has a serious optimization bug + that makes it unusable for building the Erlang emulator. Please + upgrade GCC to a newer version before building on Suse 9.1. Suse Linux + Enterprise edition 9 (SLES9) has `gcc-3.3.3-43` and is not affected. - $ which wx-config +* `gcc-4.3.0` has a serious optimizer bug. It produces an Erlang emulator + that will crash immediately. The bug is supposed to be fixed in + `gcc-4.3.1`. -### Finish up ### +* FreeBSD had a bug which caused `kqueue`/`poll`/`select` to fail to detect + that a `writev()` on a pipe has been made. This bug should have been fixed + in FreeBSD 6.3 and FreeBSD 7.0. NetBSD and DragonFlyBSD probably have or + have had the same bug. More information can be found at: -Build Erlang + * <http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/sys_pipe.c> + * <http://lists.freebsd.org/pipermail/freebsd-arch/2007-September/006790.html> - $ export PATH=/usr/local/bin:$PATH - $ cd $ERL_TOP - $ ./configure --enable-shared-zlib - $ make - $ sudo make install +* `getcwd()` on Solaris 9 can cause an emulator crash. If you have + async-threads enabled you can increase the stack size of the + async-threads as a temporary workaround. See the `+a` command-line + argument in the documentation of `erl(1)`. Without async-threads the + emulator is not as vulnerable to this bug, but if you hit it without + async-threads the only workaround available is to enable async-threads + and increase the stack size of the async-threads. Oracle has however + released patches that fixes the issue: -How to Build a Debug Enabled Erlang RunTime System --------------------------------------------------- + > Problem Description: 6448300 large mnttab can cause stack overrun + > during Solaris 9 getcwd -After completing all the normal building steps described above a debug -enabled runtime system can be built. To do this you have to change -directory to `$ERL_TOP/erts/emulator`. + More information can be found at: + * <https://getupdates.oracle.com/readme/112874-40> + * <https://getupdates.oracle.com/readme/114432-29> -In this directory execute: +* `sed` on Solaris seem to have some problems. For example on + Solaris 8, the BSD `sed` and XPG4 `sed` should be avoided. + Make sure `/bin/sed` or `/usr/bin/sed` is used on the Solaris + platform. - $ make debug FLAVOR=$FLAVOR -where `$FLAVOR` is either `plain` or `smp`. The flavor options will -produce a beam.debug and beam.smp.debug executable respectively. The -files are installed along side with the normal (opt) versions `beam.smp` -and `beam`. +Daily Build and Test +-------------------- +At Ericsson we have a "Daily Build and Test" that runs on: -To start the debug enabled runtime system execute: +* Solaris 8, 9 + * Sparc32 + * Sparc64 +* Solaris 10 + * Sparc32 + * Sparc64 + * x86 +* SuSE Linux/GNU 9.4, 10.1 + * x86 +* SuSE Linux/GNU 10.0, 10.1, 11.0 + * x86 + * x86\_64 +* openSuSE 11.4 (Celadon) + * x86\_64 (valgrind) +* Fedora 7 + * PowerPC +* Fedora 16 + * x86\_64 +* Gentoo Linux/GNU 1.12.11.1 + * x86 +* Ubuntu Linux/GNU 7.04, 10.04, 10.10, 11.04, 12.04 + * x86\_64 +* MontaVista Linux/GNU 4.0.1 + * PowerPC +* FreeBSD 10.0 + * x86 +* OpenBSD 5.4 + * x86\_64 +* OS X 10.5.8 (Leopard), 10.7.5 (Lion), 10.9.1 (Mavericks) + * x86 +* Windows XP SP3, 2003, Vista, 7 + * x86 +* Windows 7 + * x86\_64 - $ $ERL_TOP/bin/cerl -debug +We also have the following "Daily Cross Builds": -The debug enabled runtime system features lock violation checking, -assert checking and various sanity checks to help a developer ensure -correctness. Some of these features can be enabled on a normal beam -using appropriate configure options. +* SuSE Linux/GNU 10.1 x86 -> SuSE Linux/GNU 10.1 x86\_64 +* SuSE Linux/GNU 10.1 x86\_64 -> Linux/GNU TILEPro64 -There are other types of runtime systems that can be built as well -using the similar steps just described. +and the following "Daily Cross Build Tests": - $ make $TYPE FLAVOR=$FLAVOR +* SuSE Linux/GNU 10.1 x86\_64 -where `$TYPE` is `opt`, `gcov`, `gprof`, `debug`, `valgrind`, or `lcnt`. -These different beam types are useful for debugging and profiling -purposes. Authors ------- @@ -764,6 +815,7 @@ Authors are mostly listed in the application's `AUTHORS` files, that is `$ERL_TOP/lib/*/AUTHORS` and `$ERL_TOP/erts/AUTHORS`, not in the individual source files. + Copyright and License --------------------- @@ -784,30 +836,25 @@ under the License. %CopyrightEnd% -More Information ----------------- - -More information can be found at <http://www.erlang.org>. -Modifying This Document ------------------------ - -Before modifying this document you need to have a look at the -[$ERL_TOP/HOWTO/MARKDOWN.md][] document. [$ERL_TOP/HOWTO/INSTALL-CROSS.md]: INSTALL-CROSS.md [$ERL_TOP/HOWTO/INSTALL-WIN32.md]: INSTALL-WIN32.md [DESTDIR]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html - [Building in Git]: #How-to-Build-and-Install-ErlangOTP_Building-in-Git - [Pre-built Source Release]: #How-to-Build-and-Install-ErlangOTP_Prebuilt-Source-Release - [make and $ERL_TOP]: #How-to-Build-and-Install-ErlangOTP_make-and-ERLTOP + [Building in Git]: #Advanced-configuration-and-build-of-ErlangOTP_Building_Within-Git + [Advanced Configure]: #Advanced-configuration-and-build-of-ErlangOTP_Configuring + [Pre-built Source Release]: #Advanced-configuration-and-build-of-ErlangOTP_Building_Prebuilt-Source-Release + [make and $ERL_TOP]: #Advanced-configuration-and-build-of-ErlangOTP_make-and-ERLTOP [html documentation]: http://www.erlang.org/download/otp_doc_html_%OTP-VSN%.tar.gz [man pages]: http://www.erlang.org/download/otp_doc_man_%OTP-VSN%.tar.gz [the released source tar ball]: http://www.erlang.org/download/otp_src_%OTP-VSN%.tar.gz + [System Principles]: ../system_principles/system_principles + [Known platform issues]: #Known-platform-issues [native build]: #How-to-Build-and-Install-ErlangOTP [cross build]: INSTALL-CROSS.md - [$ERL_TOP/HOWTO/MARKDOWN.md]: MARKDOWN.md - - [?TOC]: true + [Required Utilities]: #Required-Utilities + [Optional Utilities]: #Optional-Utilities + [Building on a Mac]: #Advanced-configuration-and-build-of-ErlangOTP_Building_OS-X-Darwin + [Building with wxErlang]: #Advanced-configuration-and-build-of-ErlangOTP_Building_Building-with-wxErlang @@ -12,6 +12,15 @@ middle-ware to develop these systems. It includes its own distributed database, applications to interface towards other languages, debugging and release handling tools. +ERTS and BEAM +------------- +**BEAM** is the name of the virtual machine where all Erlang code is executed. +Every compiled Erlang file has the suffix .beam. The virtual machine +is sometimes referred to as the emulator. + +**ERTS** is the Erlang Runtime System where the BEAM, kernel and +standard libraries amongst others are included. + More information can be found at [erlang.org] [1]. Building and Installing @@ -57,7 +66,7 @@ Copyright and License > %CopyrightBegin% > -> Copyright Ericsson AB 2010-2012. All Rights Reserved. +> Copyright Ericsson AB 2010-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 diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 7aaded200c..e7e9b218f2 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -1784,6 +1784,15 @@ os_prompt% </pre> </desc> </func> <func> + <name name="is_map" arity="1"/> + <fsummary>Check whether a term is a map</fsummary> + <desc> + <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a map; + otherwise returns <c>false</c>.</p> + <p>Allowed in guard tests.</p> + </desc> + </func> + <func> <name name="is_number" arity="1"/> <fsummary>Check whether a term is a number</fsummary> <desc> @@ -2220,6 +2229,17 @@ os_prompt% </pre> </desc> </func> <func> + <name name="map_size" arity="1"/> + <fsummary>Return the size of a map</fsummary> + <desc> + <p>Returns an integer which is the number of key-value pairs in <c><anno>Map</anno></c>.</p> + <pre> +> <input>map_size(#{a=>1, b=>2, c=>3}).</input> +3</pre> + <p>Allowed in guard tests.</p> + </desc> + </func> + <func> <name name="max" arity="2"/> <fsummary>Return the largest of two term</fsummary> <desc> diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl index 938aac6a0e..7aba367e33 100644 --- a/erts/emulator/test/binary_SUITE.erl +++ b/erts/emulator/test/binary_SUITE.erl @@ -64,7 +64,7 @@ -export([sleeper/0,trapping_loop/4]). suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap,{minutes,2}}]. + {timetrap,{minutes,4}}]. all() -> [copy_terms, conversions, deep_lists, deep_bitstr_lists, @@ -1266,7 +1266,7 @@ deep(Config) when is_list(Config) -> deep_roundtrip(T) -> B = term_to_binary(T), - T = binary_to_term_stress(B). + T = binary_to_term(B). obsolete_funs(Config) when is_list(Config) -> erts_debug:set_internal_state(available_internal_state, true), diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl index 330bef7104..8038888796 100644 --- a/erts/emulator/test/match_spec_SUITE.erl +++ b/erts/emulator/test/match_spec_SUITE.erl @@ -42,7 +42,7 @@ -export([init_per_testcase/2, end_per_testcase/2]). init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) -> - Dog=?t:timetrap(?t:seconds(10)), + Dog=?t:timetrap(?t:seconds(30)), [{watchdog, Dog}|Config]. end_per_testcase(_Func, Config) -> diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam Binary files differindex 26f851fd7a..f1e588320b 100644 --- a/erts/preloaded/ebin/erl_prim_loader.beam +++ b/erts/preloaded/ebin/erl_prim_loader.beam diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam Binary files differindex 344176b71b..b4e22f6d74 100644 --- a/erts/preloaded/ebin/erlang.beam +++ b/erts/preloaded/ebin/erlang.beam diff --git a/erts/preloaded/ebin/erts_internal.beam b/erts/preloaded/ebin/erts_internal.beam Binary files differindex bd402f9a98..d41c833e05 100644 --- a/erts/preloaded/ebin/erts_internal.beam +++ b/erts/preloaded/ebin/erts_internal.beam diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam Binary files differindex 5d49eed469..7f2d2740e1 100644 --- a/erts/preloaded/ebin/init.beam +++ b/erts/preloaded/ebin/init.beam diff --git a/erts/preloaded/ebin/otp_ring0.beam b/erts/preloaded/ebin/otp_ring0.beam Binary files differindex 2607739d12..4d22d8bace 100644 --- a/erts/preloaded/ebin/otp_ring0.beam +++ b/erts/preloaded/ebin/otp_ring0.beam diff --git a/erts/preloaded/ebin/prim_eval.beam b/erts/preloaded/ebin/prim_eval.beam Binary files differindex d665d35ab1..efc8347b6e 100644 --- a/erts/preloaded/ebin/prim_eval.beam +++ b/erts/preloaded/ebin/prim_eval.beam diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam Binary files differindex 201252de34..6c49b5185e 100644 --- a/erts/preloaded/ebin/prim_file.beam +++ b/erts/preloaded/ebin/prim_file.beam diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam Binary files differindex ff8265414e..fe5431c5ff 100644 --- a/erts/preloaded/ebin/prim_inet.beam +++ b/erts/preloaded/ebin/prim_inet.beam diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam Binary files differindex f80d4a96e5..73be297bbb 100644 --- a/erts/preloaded/ebin/prim_zip.beam +++ b/erts/preloaded/ebin/prim_zip.beam diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam Binary files differindex dba3ec9546..193cebdc31 100644 --- a/erts/preloaded/ebin/zlib.beam +++ b/erts/preloaded/ebin/zlib.beam diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index fbc37bd955..cabbbd191f 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -1745,9 +1745,9 @@ is_pid(_Term) -> erlang:nif_error(undefined). %% Shadowed by erl_bif_types: erlang:is_map/1 --spec is_map(Map) -> boolean() when - Map :: map(). -is_map(_Map) -> +-spec is_map(Term) -> boolean() when + Term :: term(). +is_map(_Term) -> erlang:nif_error(undefined). %% Shadowed by erl_bif_types: erlang:is_port/1 diff --git a/erts/test/otp_SUITE.erl b/erts/test/otp_SUITE.erl index cd5cfcbab4..229d10ccee 100644 --- a/erts/test/otp_SUITE.erl +++ b/erts/test/otp_SUITE.erl @@ -392,12 +392,18 @@ is_bad_encoding(File) -> end. runtime_dependencies(Config) -> + %% Ignore applications intentionally not declaring dependencies + %% found by xref. + IgnoreApps = [diameter], + + %% Verify that (at least) OTP application runtime dependencies found %% by xref are listed in the runtime_dependencies field of the .app file %% of each application. Server = ?config(xref_server, Config), {ok, AE} = xref:q(Server, "AE"), SAE = lists:keysort(1, AE), + put(ignored_failures, []), {AppDep, AppDeps} = lists:foldl(fun ({App, App}, Acc) -> Acc; ({App, Dep}, {undefined, []}) -> @@ -409,8 +415,45 @@ runtime_dependencies(Config) -> end, {undefined, []}, SAE), - [] = check_apps_deps([AppDep|AppDeps]), - ok. + [] = lists:filter(fun ({missing_runtime_dependency, + AppFile, + common_test}) -> + %% The test_server app is contaminated by + %% common_test when run in a source tree. It + %% should however *not* be contaminated + %% when run in an installation. + case {filename:basename(AppFile), + is_run_in_src_tree()} of + {"test_server.app", true} -> + false; + _ -> + true + end; + (_) -> + true + end, + check_apps_deps([AppDep|AppDeps], IgnoreApps)), + case IgnoreApps of + [] -> + ok; + _ -> + Comment = lists:flatten(io_lib:format("Ignored applications: ~p " + "Ignored failures: ~p", + [IgnoreApps, + get(ignored_failures)])), + {comment, Comment} + end. + +is_run_in_src_tree() -> + %% At least currently run_erl is not present in <code-root>/bin + %% in the source tree, but present in <code-root>/bin of an + %% ordinary installation. + case file:read_file_info(filename:join([code:root_dir(), + "bin", + "run_erl"])) of + {ok, _} -> false; + {error, _} -> true + end. have_rdep(_App, [], _Dep) -> false; @@ -424,28 +467,43 @@ have_rdep(App, [RDep | RDeps], Dep) -> have_rdep(App, RDeps, Dep) end. -check_app_deps(_App, _AppFile, _AFDeps, []) -> +check_app_deps(_App, _AppFile, _AFDeps, [], _IgnoreApps) -> []; -check_app_deps(App, AppFile, AFDeps, [XRDep | XRDeps]) -> - ResOtherDeps = check_app_deps(App, AppFile, AFDeps, XRDeps), +check_app_deps(App, AppFile, AFDeps, [XRDep | XRDeps], IgnoreApps) -> + ResOtherDeps = check_app_deps(App, AppFile, AFDeps, XRDeps, IgnoreApps), case have_rdep(App, AFDeps, XRDep) of true -> ResOtherDeps; false -> - [{missing_runtime_dependency, AppFile, XRDep} | ResOtherDeps] + Failure = {missing_runtime_dependency, AppFile, XRDep}, + case lists:member(App, IgnoreApps) of + true -> + put(ignored_failures, [Failure | get(ignored_failures)]), + ResOtherDeps; + false -> + [Failure | ResOtherDeps] + end end. -check_apps_deps([]) -> +check_apps_deps([], _IgnoreApps) -> []; -check_apps_deps([{App, Deps}|AppDeps]) -> - ResOtherApps = check_apps_deps(AppDeps), +check_apps_deps([{App, Deps}|AppDeps], IgnoreApps) -> + ResOtherApps = check_apps_deps(AppDeps, IgnoreApps), AppFile = code:where_is_file(atom_to_list(App) ++ ".app"), {ok,[{application, App, Info}]} = file:consult(AppFile), case lists:keyfind(runtime_dependencies, 1, Info) of {runtime_dependencies, RDeps} -> - check_app_deps(App, AppFile, RDeps, Deps) ++ ResOtherApps; + check_app_deps(App, AppFile, RDeps, Deps, IgnoreApps) + ++ ResOtherApps; false -> - [{missing_runtime_dependencies_key, AppFile} | ResOtherApps] + Failure = {missing_runtime_dependencies_key, AppFile}, + case lists:member(App, IgnoreApps) of + true -> + put(ignored_failures, [Failure | get(ignored_failures)]), + ResOtherApps; + false -> + [Failure | ResOtherApps] + end end. %%% diff --git a/lib/common_test/src/ct_netconfc.erl b/lib/common_test/src/ct_netconfc.erl index 6fc840745d..a3861dc745 100644 --- a/lib/common_test/src/ct_netconfc.erl +++ b/lib/common_test/src/ct_netconfc.erl @@ -536,7 +536,7 @@ send(Client, SimpleXml) -> Client :: client(), SimpleXml :: simple_xml(), Timeout :: timeout(), - Result :: ok | {error,error_reason()}. + Result :: simple_xml() | {error,error_reason()}. %% @doc Send an XML document to the server. %% %% The given XML document is sent as is to the server. This function @@ -556,7 +556,7 @@ send_rpc(Client, SimpleXml) -> Client :: client(), SimpleXml :: simple_xml(), Timeout :: timeout(), - Result :: ok | {error,error_reason()}. + Result :: [simple_xml()] | {error,error_reason()}. %% @doc Send a Netconf <code>rpc</code> request to the server. %% %% The given XML document is wrapped in a valid Netconf @@ -635,7 +635,7 @@ get(Client, Filter) -> Client :: client(), Filter :: simple_xml() | xpath(), Timeout :: timeout(), - Result :: {ok,simple_xml()} | {error,error_reason()}. + Result :: {ok,[simple_xml()]} | {error,error_reason()}. %% @doc Get data. %% %% This operation returns both configuration and state data from the @@ -661,7 +661,7 @@ get_config(Client, Source, Filter) -> Source :: netconf_db(), Filter :: simple_xml() | xpath(), Timeout :: timeout(), - Result :: {ok,simple_xml()} | {error,error_reason()}. + Result :: {ok,[simple_xml()]} | {error,error_reason()}. %% @doc Get configuration data. %% %% To be able to access another source than `running', the server @@ -759,7 +759,7 @@ action(Client,Action) -> Client :: client(), Action :: simple_xml(), Timeout :: timeout(), - Result :: {ok,simple_xml()} | {error,error_reason()}. + Result :: {ok,[simple_xml()]} | {error,error_reason()}. %% @doc Execute an action. %% %% @end diff --git a/lib/diameter/src/Makefile b/lib/diameter/src/Makefile index 127406ae23..9afccf298c 100644 --- a/lib/diameter/src/Makefile +++ b/lib/diameter/src/Makefile @@ -148,7 +148,7 @@ gen/$(DICT_YRL).erl: compiler/$(DICT_YRL).yrl $(ERLC) -Werror -o $(@D) $< # Generate the app file. -$(APP_TARGET): $(APP_SRC) ../vsn.mk modules.mk +$(APP_TARGET): $(APP_SRC) ../vsn.mk modules.mk app.sed $(gen_verbose) \ M=`echo $(notdir $(APP_MODULES)) | tr ' ' ,`; \ C=`echo $(COMPILER_MODULES) | tr ' ' ,`; \ @@ -159,7 +159,8 @@ $(APP_TARGET): $(APP_SRC) ../vsn.mk modules.mk -e "s;%COMPILER%;$$C;" \ -e "s;%INFO%;$$I;" \ -e "s;%REGISTERED%;$$R;" \ - $< > $@ + $< \ + | sed -f app.sed > $@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk $(vsn_verbose) \ diff --git a/lib/diameter/src/app.sed b/lib/diameter/src/app.sed new file mode 100644 index 0000000000..7916f65002 --- /dev/null +++ b/lib/diameter/src/app.sed @@ -0,0 +1,40 @@ +# +# %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% + +# +# Generate runtime_dependencies from applications to avoid having to +# specify the same application more than once. +# + +/{runtime_dependencies,/b v +/{[-a-z]*, "[0-9.]*"}/!b +/{vsn,/b + +/%%/!H +s/{\([^,]*\)[^}]*}/\1/g +s/%%/%,/ +b + +:v + +p +x +s/\n// +s/%//g +s/\n */ /g +s/{\([^,]*\), "\([^"]*"\)}/"\1-\2/g diff --git a/lib/diameter/src/diameter.app.src b/lib/diameter/src/diameter.app.src index d2290aeccc..ac1d847753 100644 --- a/lib/diameter/src/diameter.app.src +++ b/lib/diameter/src/diameter.app.src @@ -27,13 +27,20 @@ ]}, {registered, [%REGISTERED%]}, {applications, [ - stdlib, kernel - %, syntax_tools - %, runtime_tools - %, ssl + {stdlib, "2.0"}, {kernel, "3.0"}%, {erts, "6.0"} + %% {syntax-tools, "1.6.14"} + %% {runtime-tools, "1.8.14"} + %, {ssl, "5.3.4"} ]}, {env, []}, {mod, {diameter_app, []}}, - {runtime_dependencies, ["syntax_tools-1.6.14","stdlib-2.0","ssl-5.3.4", - "runtime_tools-1.8.14","kernel-3.0","erts-6.0"]} + {runtime_dependencies, [ + ]} + %% + %% Note that ssl is only required if configured on TCP transports, + %% and syntax-tools and runtime-tools are only required if the + %% dictionary compiler and debug modules (respectively) are + %% needed/wanted at runtime, which they typically aren't. These + %% modules are the two commented lines in the 'modules' tuple. + %% ]}. diff --git a/lib/diameter/test/diameter_app_SUITE.erl b/lib/diameter/test/diameter_app_SUITE.erl index 1e262895a6..f68a18b5c2 100644 --- a/lib/diameter/test/diameter_app_SUITE.erl +++ b/lib/diameter/test/diameter_app_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-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 @@ -50,7 +50,7 @@ diameter_exprecs, diameter_make]). --define(HELP_MODULES, [diameter_dbg, +-define(INFO_MODULES, [diameter_dbg, diameter_info]). %% =========================================================================== @@ -99,13 +99,13 @@ vsn(Config) -> %% # modules/1 %% %% Ensure that the app file modules and installed modules differ by -%% compiler/help modules. +%% compiler/info modules. %% =========================================================================== modules(Config) -> Mods = fetch(modules, fetch(app, Config)), Installed = code_mods(), - Help = lists:sort(?HELP_MODULES ++ ?COMPILER_MODULES), + Help = lists:sort(?INFO_MODULES ++ ?COMPILER_MODULES), {[], Help} = {Mods -- Installed, lists:sort(Installed -- Mods)}. @@ -158,12 +158,15 @@ appvsn(Name) -> %% # xref/1 %% %% Ensure that no function in our application calls an undefined function -%% or one in an application we haven't specified as a dependency. (Almost.) +%% or one in an application we haven't declared as a dependency. (Almost.) %% =========================================================================== xref(Config) -> App = fetch(app, Config), - Mods = fetch(modules, App), + Mods = fetch(modules, App), %% modules listed in the app file + + %% List of application names extracted from runtime_dependencies. + Deps = lists:map(fun unversion/1, fetch(runtime_dependencies, App)), {ok, XRef} = xref:start(make_name(xref_test_name)), ok = xref:set_default(XRef, [{verbose, false}, {warnings, false}]), @@ -178,7 +181,9 @@ xref(Config) -> [?APP, erts | fetch(applications, App)]), {ok, Undefs} = xref:analyze(XRef, undefined_function_calls), - {ok, Called} = xref:analyze(XRef, {module_call, ?COMPILER_MODULES}), + {ok, RTmods} = xref:analyze(XRef, {module_use, Mods}), + {ok, CTmods} = xref:analyze(XRef, {module_use, ?COMPILER_MODULES}), + {ok, RTdeps} = xref:analyze(XRef, {module_call, Mods}), xref:stop(XRef), @@ -190,18 +195,41 @@ xref(Config) -> Undefs), %% diameter_tcp does call ssl despite the latter not being listed %% as a dependency in the app file since ssl is only required for - %% TLS security: it's up to a client who wants TLS it to start - %% ssl. - - [] = lists:filter(fun is_bad_dependency/1, Called). - -%% It's not strictly necessary that diameter compiler modules not -%% depend on other diameter modules but it's a simple source of build -%% errors if not encoded in the makefile (hence the test) so guard -%% against it. -is_bad_dependency(Mod) -> - lists:prefix("diameter", atom_to_list(Mod)) - andalso not lists:member(Mod, ?COMPILER_MODULES). + %% TLS security: it's up to a client who wants TLS to start ssl. + + %% Ensure that only runtime or info modules call runtime modules. + %% It's not strictly necessary that diameter compiler modules not + %% depend on other diameter modules but it's a simple source of + %% build errors if not properly encoded in the makefile so guard + %% against it. + [] = (RTmods -- Mods) -- ?INFO_MODULES, + + %% Ensure that runtime modules don't call compiler modules. + CTmods = CTmods -- Mods, + + %% Ensure that runtime modules only call other runtime modules, or + %% applications declared as in runtime_dependencies in the app + %% file. Note that the declared application versions are ignored + %% since we only know what we can see now. + [] = lists:filter(fun(M) -> not lists:member(app(M), Deps) end, + RTdeps -- Mods). + +unversion(App) -> + T = lists:dropwhile(fun is_vsn_ch/1, lists:reverse(App)), + lists:reverse(case T of [$-|TT] -> TT; _ -> T end). + +is_vsn_ch(C) -> + $0 =< C andalso C =< $9 orelse $. == C. + +app('$M_EXPR') -> %% could be anything but assume it's ok + "erts"; +app(Mod) -> + case code:which(Mod) of + preloaded -> + "erts"; + Path -> + unversion(lists:nth(3, lists:reverse(filename:split(Path)))) + end. add_application(XRef, App) -> add_application(XRef, App, code:lib_dir(App)). diff --git a/lib/edoc/src/edoc_types.erl b/lib/edoc/src/edoc_types.erl index af8f1230fb..d4e00d3ecd 100644 --- a/lib/edoc/src/edoc_types.erl +++ b/lib/edoc/src/edoc_types.erl @@ -66,6 +66,7 @@ is_new_predefined(boolean, 0) -> true; is_new_predefined(byte, 0) -> true; is_new_predefined(iodata, 0) -> true; is_new_predefined(iolist, 0) -> true; +is_new_predefined(map, 0) -> true; is_new_predefined(maybe_improper_list, 0) -> true; is_new_predefined(maybe_improper_list, 2) -> true; is_new_predefined(mfa, 0) -> true; diff --git a/lib/hipe/llvm/hipe_llvm_main.erl b/lib/hipe/llvm/hipe_llvm_main.erl index e911fb89c9..0e50c9539b 100644 --- a/lib/hipe/llvm/hipe_llvm_main.erl +++ b/lib/hipe/llvm/hipe_llvm_main.erl @@ -342,8 +342,8 @@ create_sdesc_list([{ExnLbl, SPOff} | MoreExnAndSPOffs], %% (thus, some of their arguments are passed to the stack). Because of the %% Reserved Call Frame feature that the LLVM uses, the stack descriptors %% are not correct since at the point of call the frame size is reduced -%% proportionally to the number of arguments that are passed on the stack. -%% Also the offsets of the roots need to be re-adjusted. +%% by the number of arguments that are passed on the stack. Also, the +%% offsets of the roots need to be re-adjusted. fix_stack_descriptors(_, _, [], _) -> []; fix_stack_descriptors(RelocsDict, Relocs, SDescs, ExposedClosures) -> @@ -427,30 +427,22 @@ find_offsets([{Off,Arity}|Rest], Offsets, Acc) -> [I | RestOffsets] = lists:dropwhile(fun (Y) -> Y<Off end, Offsets), find_offsets(Rest, RestOffsets, [{I, Arity}|Acc]). -%% The functions below correct the arity of calls, that are identified -%% by offset, in the stack descriptors. +%% The function below corrects the stack descriptors of calls with arguments +%% that are passed on the stack (more than NR_ARG_REGS) by subtracting the +%% number of stacked arguments from the frame size and from the offset of the +%% roots. fix_sdescs([], SDescs) -> SDescs; fix_sdescs([{Offset, Arity} | Rest], SDescs) -> case lists:keyfind(Offset, 2, SDescs) of false -> fix_sdescs(Rest, SDescs); - {?SDESC, Offset, SDesc} -> - {ExnHandler, FrameSize, StkArity, Roots} = SDesc, - DecRoot = fun(X) -> X-Arity end, - NewRootsList = lists:map(DecRoot, tuple_to_list(Roots)), - NewSDesc = - case length(NewRootsList) > 0 andalso hd(NewRootsList) >= 0 of - true -> - {?SDESC, Offset, {ExnHandler, FrameSize-Arity, StkArity, - list_to_tuple(NewRootsList)}}; - false -> - {?SDESC, Offset, {ExnHandler, FrameSize, StkArity, Roots}} - end, - RestSDescs = lists:keydelete(Offset, 2, SDescs), - fix_sdescs(Rest, [NewSDesc | RestSDescs]) + {?SDESC, Offset, {ExnHandler, FrameSize, StkArity, Roots}} -> + FixedRoots = list_to_tuple([Ri - Arity || Ri <- tuple_to_list(Roots)]), + FixedSDesc = + {?SDESC, Offset, {ExnHandler, FrameSize - Arity, StkArity, FixedRoots}}, + fix_sdescs(Rest, [FixedSDesc | lists:keydelete(Offset, 2, SDescs)]) end. - %%------------------------------------------------------------------------------ %% Miscellaneous functions %%------------------------------------------------------------------------------ diff --git a/lib/hipe/llvm/hipe_rtl_to_llvm.erl b/lib/hipe/llvm/hipe_rtl_to_llvm.erl index ba76e1d815..d7d8d1b049 100644 --- a/lib/hipe/llvm/hipe_rtl_to_llvm.erl +++ b/lib/hipe/llvm/hipe_rtl_to_llvm.erl @@ -430,12 +430,13 @@ trans_call_name(RtlCallName, Relocs, CallArgs, FinalArgs) -> case RtlCallName of PrimOp when is_atom(PrimOp) -> LlvmName = trans_prim_op(PrimOp), - Relocs1 = relocs_store(LlvmName, {call, {bif, PrimOp, length(CallArgs)}}, - Relocs), + Relocs1 = + relocs_store(LlvmName, {call, {bif, PrimOp, length(CallArgs)}}, Relocs), {"@" ++ LlvmName, [], Relocs1}; {M, F, A} when is_atom(M), is_atom(F), is_integer(A) -> - LlvmName = trans_mfa_name({M,F,A}), - Relocs1 = relocs_store(LlvmName, {call, {M,F,A}}, Relocs), + LlvmName = trans_mfa_name({M, F, A}), + Relocs1 = + relocs_store(LlvmName, {call, {M, F, length(CallArgs)}}, Relocs), {"@" ++ LlvmName, [], Relocs1}; Reg -> case hipe_rtl:is_reg(Reg) of diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl index d47eced6d8..539ce883c0 100644 --- a/lib/hipe/main/hipe.erl +++ b/lib/hipe/main/hipe.erl @@ -200,6 +200,7 @@ compile_core/4, file/1, file/2, + llvm_support_available/0, load/1, help/0, help_hiper/0, @@ -648,7 +649,18 @@ run_compiler_1(DisasmFun, IcodeFun, Options) -> %% The full option expansion is not done %% until the DisasmFun returns. {Code, CompOpts} = DisasmFun(Options), - Opts = expand_options(Options ++ CompOpts), + Opts0 = expand_options(Options ++ CompOpts), + Opts = + case proplists:get_bool(to_llvm, Opts0) andalso + not llvm_support_available() of + true -> + ?error_msg("No LLVM version 3.4 or greater " + "found in $PATH; aborting " + "native code compilation.\n", []), + ?EXIT(cant_find_required_llvm_version); + false -> + Opts0 + end, check_options(Opts), ?when_option(verbose, Options, ?debug_msg("Options: ~p.\n",[Opts])), @@ -1537,4 +1549,22 @@ check_options(Opts) -> ok end. +-spec llvm_support_available() -> boolean(). + +llvm_support_available() -> + get_llvm_version() >= 3.4. + +get_llvm_version() -> + OptStr = os:cmd("opt -version"), + SubStr = "LLVM version ", N = length(SubStr), + case string:str(OptStr, SubStr) of + 0 -> % No opt available + 0.0; + S -> + case string:to_float(string:sub_string(OptStr, S + N)) of + {error, _} -> 0.0; %XXX: Assumes no revision numbers in versioning + {Float, _} -> Float + end + end. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/lib/tools/test/eprof_SUITE.erl b/lib/tools/test/eprof_SUITE.erl index 1227d5b841..04b522de4a 100644 --- a/lib/tools/test/eprof_SUITE.erl +++ b/lib/tools/test/eprof_SUITE.erl @@ -104,7 +104,7 @@ basic(Config) when is_list(Config) -> profiling = eprof:profile([A]), true = exit(A, kill_it), profiling_stopped = eprof:stop_profiling(), - {error,_} = eprof:profile(fun() -> a = b end), + {error,_} = eprof:profile(fun() -> a = id(b) end), %% with mfa @@ -149,8 +149,7 @@ basic_option_1(Config) -> % vanilla {ok, _} = eprof:profile(fun() -> eprof_test:do(10) end, [{set_on_spawn, true}]), - [{_, MfasDo1},{_, MfasLists1}] = eprof:dump(), - Mfas1 = MfasDo1 ++ MfasLists1, + Mfas1 = lists:foldl(fun({_,Mfas},Out) -> Mfas ++ Out end, [], eprof:dump()), {value, {_, {11, _}}} = lists:keysearch({eprof_test,dec,1}, 1, Mfas1), {value, {_, { 1, _}}} = lists:keysearch({eprof_test, go,1}, 1, Mfas1), @@ -159,8 +158,7 @@ basic_option_1(Config) -> {ok, _} = eprof:profile(fun() -> eprof_test:do(10) end, [set_on_spawn]), - [{_, MfasDo2},{_, MfasLists2}] = eprof:dump(), - Mfas2 = MfasDo2 ++ MfasLists2, + Mfas2 = lists:foldl(fun({_,Mfas},Out) -> Mfas ++ Out end, [], eprof:dump()), {value, {_, {11, _}}} = lists:keysearch({eprof_test,dec,1}, 1, Mfas2), {value, {_, { 1, _}}} = lists:keysearch({eprof_test, go,1}, 1, Mfas2), {value, {_, { 9, _}}} = lists:keysearch({lists, split_2,5}, 1, Mfas2), @@ -255,3 +253,5 @@ ensure_eprof_stopped() -> Pid -> stopped=eprof:stop() end. + +id(I) -> I. diff --git a/system/doc/design_principles/applications.xml b/system/doc/design_principles/applications.xml index 228ca1f2bf..7b030115df 100644 --- a/system/doc/design_principles/applications.xml +++ b/system/doc/design_principles/applications.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1997</year><year>2013</year> + <year>1997</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -157,8 +157,9 @@ ch_app:stop([])</code> all applications have dependencies to at least <c>kernel</c> and <c>stdlib</c>.</item> </taglist> - <p>The syntax and contents of of the application resource file - are described in detail in <c>app(4)</c>.</p> + <note><p>The syntax and contents of of the application resource file + are described in detail in the<seealso marker="kernel:app"> + Application resource file reference</seealso>.</p></note> </section> <section> diff --git a/system/doc/getting_started/seq_prog.xml b/system/doc/getting_started/seq_prog.xml index 3830a34e5a..fd49102263 100644 --- a/system/doc/getting_started/seq_prog.xml +++ b/system/doc/getting_started/seq_prog.xml @@ -419,6 +419,129 @@ list_length([First | Rest]) -> </section> <section> + <title>Maps</title> + <p>Maps are a set of key to value associations. These associations + are encapsulated with "#{" and "}". To create an association from + "key" to value 42, we write:</p> +<code type="none"> +> #{ "key" => 42 }. +#{"key" => 42}</code> + <p>We will jump straight into the deep end with an example using some + interesting features.</p> + <p>The following example shows how we calculate alpha blending using + maps to reference color and alpha channels:</p> + <code type="none"> +-module(color). + +-export([new/4, blend/2]). + +-define(is_channel(V), (is_float(V) andalso V >= 0.0 andalso V =< 1.0)). + +new(R,G,B,A) when ?is_channel(R), ?is_channel(G), + ?is_channel(B), ?is_channel(A) -> + #{red => R, green => G, blue => B, alpha => A}. + +blend(Src,Dst) -> + blend(Src,Dst,alpha(Src,Dst)). + +blend(Src,Dst,Alpha) when Alpha > 0.0 -> + Dst#{ + red := red(Src,Dst) / Alpha, + green := green(Src,Dst) / Alpha, + blue := blue(Src,Dst) / Alpha, + alpha := Alpha + }; +blend(_,Dst,_) -> + Dst#{ + red := 0.0, + green := 0.0, + blue := 0.0, + alpha := 0.0 + }. + +alpha(#{alpha := SA}, #{alpha := DA}) -> + SA + DA*(1.0 - SA). + +red(#{red := SV, alpha := SA}, #{red := DV, alpha := DA}) -> + SV*SA + DV*DA*(1.0 - SA). +green(#{green := SV, alpha := SA}, #{green := DV, alpha := DA}) -> + SV*SA + DV*DA*(1.0 - SA). +blue(#{blue := SV, alpha := SA}, #{blue := DV, alpha := DA}) -> + SV*SA + DV*DA*(1.0 - SA).</code> + <p>Compile (file <c>color.erl</c>) and test:</p> + <pre> +> <input>c(color).</input> +{ok,color} +> <input>C1 = color:new(0.3,0.4,0.5,1.0).</input> +#{alpha => 1.0,blue => 0.5,green => 0.4,red => 0.3} +> <input>C2 = color:new(1.0,0.8,0.1,0.3).</input> +#{alpha => 0.3,blue => 0.1,green => 0.8,red => 1.0} +> <input>color:blend(C1,C2).</input> +#{alpha => 1.0,blue => 0.5,green => 0.4,red => 0.3} +> <input>color:blend(C2,C1).</input> +#{alpha => 1.0,blue => 0.38,green => 0.52,red => 0.51} +</pre> + <p>This example warrant some explanation:</p> + <code type="none"> +-define(is_channel(V), (is_float(V) andalso V >= 0.0 andalso V =< 1.0)).</code> + <p> + First we define a macro <c>is_channel</c> to help with our guard tests. + This is only here for convenience and to reduce syntax cluttering. + + You can read more about <seealso marker="doc/reference_manual:macros">Macros</seealso> + in the Erlang Reference Manual. + </p> + <code type="none"> +new(R,G,B,A) when ?is_channel(R), ?is_channel(G), + ?is_channel(B), ?is_channel(A) -> + #{red => R, green => G, blue => B, alpha => A}.</code> + <p> + The function <c>new/4</c> creates a new map term with and lets the keys + <c>red</c>, <c>green</c>, <c>blue</c> and <c>alpha</c> be associated + with an initial value. In this case we only allow for float + values between and including 0.0 and 1.0 as ensured by the <c>?is_channel/1</c> macro + for each argument. Only the <c>=></c> operator is allowed when creating a new map. + </p> + <p> + By calling <c>blend/2</c> on any color term created by <c>new/4</c> we can calculate + the resulting color as determined by the two maps terms. + </p> + <p> + The first thing <c>blend/2</c> does is to calculate the resulting alpha channel. + </p> + <code type="none"> +alpha(#{alpha := SA}, #{alpha := DA}) -> + SA + DA*(1.0 - SA).</code> + <p> + We fetch the value associated with key <c>alpha</c> for both arguments using + the <c>:=</c> operator. Any other keys + in the map are ignored, only the key <c>alpha</c> is required and checked for. + </p> + <p>This is also the case for functions <c>red/2</c>, <c>blue/2</c> and <c>green/2</c>.</p> + <code type="none"> +red(#{red := SV, alpha := SA}, #{red := DV, alpha := DA}) -> + SV*SA + DV*DA*(1.0 - SA).</code> + <p> + The difference here is that we check for two keys in each map argument. The other keys + are ignored. + </p> + <p> + Finally we return the resulting color in <c>blend/3</c>. + </p> + <code type="none"> +blend(Src,Dst,Alpha) when Alpha > 0.0 -> + Dst#{ + red := red(Src,Dst) / Alpha, + green := green(Src,Dst) / Alpha, + blue := blue(Src,Dst) / Alpha, + alpha := Alpha + };</code> + <p> + We update the <c>Dst</c> map with new channel values. The syntax for updating an existing key with a new value is done with <c>:=</c> operator. + </p> + </section> + + <section> <title>Standard Modules and Manual Pages</title> <p>Erlang has a lot of standard modules to help you do things. For example, the module <c>io</c> contains a lot of functions to help diff --git a/system/doc/installation_guide/Makefile b/system/doc/installation_guide/Makefile index 6923f52d8a..83210bd21f 100644 --- a/system/doc/installation_guide/Makefile +++ b/system/doc/installation_guide/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2012. All Rights Reserved. +# Copyright Ericsson AB 1996-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 @@ -58,8 +58,7 @@ XML_FILES = \ GENERATED_XML_FILES = \ INSTALL.xml \ INSTALL-CROSS.xml \ - INSTALL-WIN32.xml \ - MARKDOWN.xml + INSTALL-WIN32.xml # ---------------------------------------------------- @@ -74,8 +73,7 @@ REDIRECT_HTML_DIR = $(HTMLDIR)/source REDIRECT_HTML_FILES = \ $(REDIRECT_HTML_DIR)/INSTALL.html \ $(REDIRECT_HTML_DIR)/INSTALL-CROSS.html \ - $(REDIRECT_HTML_DIR)/INSTALL-WIN32.html \ - $(REDIRECT_HTML_DIR)/MARKDOWN.html + $(REDIRECT_HTML_DIR)/INSTALL-WIN32.html # ---------------------------------------------------- # FLAGS diff --git a/system/doc/installation_guide/install-binary.xml b/system/doc/installation_guide/install-binary.xml index 07027a39f6..af7dab6e44 100644 --- a/system/doc/installation_guide/install-binary.xml +++ b/system/doc/installation_guide/install-binary.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2000</year><year>2013</year> + <year>2000</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -31,117 +31,40 @@ <rev>C</rev> <file>install-binary.xml</file> </header> - - <section> - <title>UNIX</title> - - <section> - <title>Introduction</title> - <p>The system is delivered as a single compressed tar file.</p> - <p>To browse the on-line HTML documentation, Netscape or an equivalent - browser supporting frames is needed.</p> - </section> - - <section> - <title>Installation Procedure</title> - <p>When installed, the entire system, except for a small start-up - script, resides in a single directory tree. The location of this - directory tree can be chosen arbitrarily by the installer, and it - does not need to be in the user's <c>$PATH</c>. The only requirements - are that the file system where it is placed has enough free space, - and that the users who run Erlang/OTP have read access to it. In the - example below, the directory tree is assumed to be located at - <c>/usr/local/erlang</c>, which is here called the <em>top-level directory</em>.</p> - <p>It is assumed that you have the compressed tar file, the name of - which is <c><![CDATA[<PREFIX>.tar.gz]]></c>, where <c><![CDATA[<PREFIX>]]></c> is a string - denoting the particular Erlang/OTP release, e.g. - <c>otp_LXA_11930_sunos5_R9B</c>.</p> - <p>Wherever the string <c><![CDATA[<PREFIX>]]></c> is used below, it should - be replaced by the actual name prefix of the compressed tar file.</p> - <p>The tape archive file does not have one single directory in which - all other files are rooted. Therefore the tape archive file must be - extracted into an empty (newly created) directory.</p> - <list type="ordered"> - <item> - <p>If the <em>top-level directory</em> does not already exist, - create it:</p> - <pre> -mkdir /usr/local/erlang</pre> - </item> - <item> - <p>Change the current directory to the <em>top level directory</em>:</p> - <pre> -cd /usr/local/erlang</pre> - </item> - <item> - <p>Create the <em>installation directory</em> with an appropriate - name. For example:</p> - <pre> -mkdir otp_r7b</pre> - </item> - <item> - <p>Change to the <em>installation directory</em>, e.g.</p> - <pre> -cd otp_r7b</pre> - </item> - <item> - <p>Assuming the compressed tar file resides in the directory - <c><![CDATA[<SOME-DIR>]]></c>,. extract the compressed tar file into the - current directory:</p> - <pre> -gunzip -c <SOME-DIR>/<PREFIX>.tar.gz | tar xfp -</pre> - </item> - <item> - <p>Read the <c>README</c> file in the installation directory for - last minute updates, before proceeding.</p> - </item> - <item> - <p>Run the <c>Install</c> script in the installation directory, - with the absolute path of the installation directory as argument,</p> - <pre> -./Install /usr/local/erlang/otp_r7b</pre> - <p>and supply answers to the prompts.</p> - <p>In most cases, there is a default answer in square brackets - (<c>[]</c>). If the default is satisfactory, just press - <c><![CDATA[<Return>]]></c>. In general you are only prompted for one thing:</p> - <list type="bulleted"> - <item> - <p>"Do you want to use a minimal system startup instead of the - SASL startup?" <br></br> - - In a minimal system, only the Kernel and STDLIB applications - are loaded and started. If the SASL startup is used, the SASL - application is included as well. Normally, the minimal system - is enough.</p> - </item> - </list> - </item> - <item> - <p>Make Erlang/OTP available for users, either by putting the path - <c>/usr/local/erlang/otp_r7b/bin</c> in users <c>$PATH</c> - variable, or link the executable - <c>/usr/local/erlang/otp_r7b/bin/erl</c> accordingly, e.g.:</p> - <pre> -ln -s /usr/local/erlang/otp_r7b/bin/erl /usr/local/bin/erl </pre> - </item> - </list> - </section> - </section> - <section> <title>Windows</title> <section> <title>Introduction</title> - <p>The system is delivered as a single <c>.exe</c> file.</p> - <p>To browse the on-line HTML documentation, Netscape or an equivalent - browser supporting frames is needed.</p> + <p>The system is delivered as a Windows Installer executable. + Get it from our <url href="http://www.erlang.org/download.html">download page</url>.</p> </section> <section> - <title>Installation Procedure</title> + <title>Installation</title> <p>The installation procedure is is automated. Double-click the <c>.exe</c> file icon and follow the instructions.</p> </section> + <section> + <title>Verification</title> + <list type="bulleted"> + <item> + <p>Start Erlang/OTP by double-clicking on the Erlang shortcut icon on the + desktop.</p> + <p>Expect a command line window to pop up with an output looking something like this:</p> + <pre> + Erlang/OTP 17 [erts-6.0] [64-bit] [smp:2:2] + + Eshell V6.0 (abort with ^G) + 1></pre> + </item> + <item> + <p>Exit by entering the command <c>halt()</c>,</p> + <pre> + 2> <input>halt().</input></pre> + <p>which will close the Erlang/OTP shell. </p> + </item> + </list> + </section> </section> </chapter> diff --git a/system/doc/installation_guide/part.xml b/system/doc/installation_guide/part.xml index 19808fd165..02bf98db7c 100644 --- a/system/doc/installation_guide/part.xml +++ b/system/doc/installation_guide/part.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2000</year><year>2013</year> + <year>2000</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -32,9 +32,7 @@ <p>How to install Erlang/OTP on UNIX or Windows.</p> </description> <xi:include href="install-binary.xml"/> - <xi:include href="verification.xml"/> <xi:include href="INSTALL.xml"/> <xi:include href="INSTALL-CROSS.xml"/> <xi:include href="INSTALL-WIN32.xml"/> - <xi:include href="MARKDOWN.xml"/> </part>
\ No newline at end of file diff --git a/system/doc/installation_guide/verification.xml b/system/doc/installation_guide/verification.xml deleted file mode 100644 index 391ddfb7b8..0000000000 --- a/system/doc/installation_guide/verification.xml +++ /dev/null @@ -1,102 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE chapter SYSTEM "chapter.dtd"> - -<chapter> - <header> - <copyright> - <year>2000</year><year>2013</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>Installation Verification</title> - <prepared>Peter Högfeldt</prepared> - <responsible>Peter Högfeldt</responsible> - <docno></docno> - <approved>(Peter Högfeldt</approved> - <checked></checked> - <date>1997-05-26</date> - <rev>C</rev> - <file>verification.xml</file> - </header> - <p>This chapter is about verifying your installation by performing - a few simple tests to see that your system is properly installed.</p> - - <section> - <title>UNIX</title> - <list type="bulleted"> - <item> - <p>Start Erlang/OTP from the command line,</p> - <pre> - unix> erl</pre> - <p>Expect the following output:</p> - <pre> - Erlang (BEAM) emulator version 5.0.1 [threads] - - Eshell V5.0.1 (abort with ^G) - 1></pre> - </item> - <item> - <p>Start the GS-based toolbar from the Erlang shell, </p> - <pre> - 1> <input>toolbar:start().</input></pre> - <p>and check that the toolbar window pops up. - </p> - <p><em>Note:</em> The trailing full stop (<c>"."</c>) is an end marker - for all commands in the Erlang shell, and must be entered for a - command to begin execution.</p> - </item> - <item> - <p>Exit by entering the command <c>halt()</c>,</p> - <pre> - 2> <input>halt().</input></pre> - <p>which should end both the toolbar window and the command line window. </p> - </item> - </list> - </section> - - <section> - <title>Windows</title> - <list type="bulleted"> - <item> - <p>Start Erlang/OTP by double-clicking on the Erlang shortcut icon on the - desktop.</p> - <p>Expect a command line window to pop up with the following output,</p> - <pre> - Erlang (BEAM) emulator version 5.0.1 [threads] - - Eshell V5.0.1 (abort with ^G) - 1></pre> - </item> - <item> - <p>Start the GS-based toolbar from the Erlang shell, </p> - <pre> - 1> <input>toolbar:start().</input></pre> - <p>and check that the toolbar window pops up. - </p> - <p><em>Note:</em> The trailing full stop (<c>"."</c>) is an end marker - for all commands in the Erlang shell, and must be entered for a - command to begin execution.</p> - </item> - <item> - <p>Exit by entering the command <c>halt()</c>,</p> - <pre> - 2> <input>halt().</input></pre> - <p>which should end both the toolbar window and the command line window. </p> - </item> - </list> - </section> -</chapter> - diff --git a/system/doc/installation_guide/xmlfiles.mk b/system/doc/installation_guide/xmlfiles.mk index 3995c607af..c443334cd7 100644 --- a/system/doc/installation_guide/xmlfiles.mk +++ b/system/doc/installation_guide/xmlfiles.mk @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2009-2013. All Rights Reserved. +# Copyright Ericsson AB 2009-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 @@ -18,8 +18,6 @@ # INST_GUIDE_CHAPTER_FILES = \ install-binary.xml \ - verification.xml \ INSTALL.xml \ INSTALL-CROSS.xml \ - INSTALL-WIN32.xml \ - MARKDOWN.xml + INSTALL-WIN32.xml diff --git a/system/doc/reference_manual/data_types.xml b/system/doc/reference_manual/data_types.xml index 8c690d6b86..0031664dfb 100644 --- a/system/doc/reference_manual/data_types.xml +++ b/system/doc/reference_manual/data_types.xml @@ -190,6 +190,38 @@ adam </section> <section> + <title>Map</title> + <p>Compound data type with a variable number of key-value associations:</p> + <pre> +#{Key1=>Value1,...,KeyN=>ValueN}</pre> + <p>Each key-value association in the map is called an + <em>association pair</em>. The key and value parts of the pair are + called <em>elements</em>. The number of association pairs is said to be + the <em>size</em> of the map.</p> + <p>There exists a number of BIFs to manipulate maps.</p> + <p>Examples:</p> + <pre> +1> <input>M1 = #{name=>adam,age=>24,date=>{july,29}}.</input> +#{age => 24,date => {july,29},name => adam} +2> <input>maps:get(name,M1).</input> +adam +3> <input>maps:get(date,M1).</input> +{july,29} +4> <input>M2 = maps:update(age,25,M1).</input> +#{age => 25,date => {july,29},name => adam} +5> <input>map_size(M).</input> +3 +6> <input>map_size(#{}).</input> +0</pre> + <p>A collection of maps processing functions can be found in + the STDLIB module <seealso marker="stdlib:maps"><c>maps</c></seealso>.</p> + <p>Read more about <seealso marker="maps">Maps</seealso>.</p> + <note> + <p>Maps are considered experimental during OTP 17.</p> + </note> + </section> + + <section> <title>List</title> <p>Compound data type with a variable number of terms.</p> <pre> diff --git a/system/doc/reference_manual/expressions.xml b/system/doc/reference_manual/expressions.xml index e9de3e006e..37208710fe 100644 --- a/system/doc/reference_manual/expressions.xml +++ b/system/doc/reference_manual/expressions.xml @@ -56,7 +56,7 @@ Expr1 + Expr2</code> <marker id="term"></marker> <title>Terms</title> <p>The simplest form of expression is a term, that is an integer, - float, atom, string, list or tuple. + float, atom, string, list, map or tuple. The return value is the term itself.</p> </section> @@ -1348,6 +1348,9 @@ end</pre> <cell align="left" valign="middle"><c>is_list/1</c></cell> </row> <row> + <cell align="left" valign="middle"><c>is_map/1</c></cell> + </row> + <row> <cell align="left" valign="middle"><c>is_number/1</c></cell> </row> <row> @@ -1398,6 +1401,9 @@ end</pre> <cell align="left" valign="middle"><c>length(List)</c></cell> </row> <row> + <cell align="left" valign="middle"><c>map_size(Map)</c></cell> + </row> + <row> <cell align="left" valign="middle"><c>node()</c></cell> </row> <row> diff --git a/system/doc/reference_manual/maps.xml b/system/doc/reference_manual/maps.xml new file mode 100644 index 0000000000..78808ce4a2 --- /dev/null +++ b/system/doc/reference_manual/maps.xml @@ -0,0 +1,274 @@ +<?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>Maps</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + <file>maps.xml</file> + </header> + + <note> + <p>Maps are considered experimental during OTP 17 and may be subject to change.</p> + <p>The documentation below describes it being possible to use arbitrary + expressions or variables as keys, this is <em>NOT</em> implemented in the current + version of Erlang/OTP.</p> + <p>Exceptions returns <c>badarg</c> instead of <c>badmap</c>, this will change in + the future releases.</p> + </note> + + <section> + <title>Creating Maps</title> + <p> + Constructing a new map is done by letting an expression <c>K</c> be associated with + another expression <c>V</c>: + </p> + <code>#{ K => V }</code> + <p> + New maps may include multiple associations at construction by listing every + association: + </p> + <code>#{ K1 => V1, .., Kn => Vn }</code> + <p> + An empty map is constructed by not associating any terms with each other: + </p> + <code>#{}</code> + <p> + All keys and values in the map are terms. Any expression is first evaluated and + then the resulting terms are used as <em>key</em> and <em>value</em> respectively. + </p> + <p> + Keys and values are separated by the <c>=></c> arrow and associations are + separated by <c>,</c>. + </p> + + <p> + Examples: + </p> + <code> +M0 = #{}, % empty map +M1 = #{a => <<"hello">>}, % single association with literals +M2 = #{1 => 2, b => b}, % multiple associations with literals +M3 = #{k => {A,B}}, % single association with variables +M4 = #{{"w", 1} => f()}. % compound key associated with an evaluated expression</code> + <p> + where, <c>A</c> and <c>B</c> are any expressions and <c>M0</c> through <c>M4</c> + are the resulting map terms. + </p> + <p> + If two matching keys are declared, the latter key will take precedence. + </p> + <p> + Example: + </p> + +<pre> +1> <input>#{1 => a, 1 => b}.</input> +#{1 => b } +2> <input>#{1.0 => a, 1 => b}.</input> +#{1 => b, 1.0 => a} +</pre> + <p> + The order in which the expressions constructing the keys and their + associated values are evaluated is not defined. The syntactic order of + the key-value pairs in the construction is of no relevance, except in + the above mentioned case of two matching keys. + </p> + </section> + + <section> + <title>Updating Maps</title> + <p> + Updating a map has similar syntax as constructing it. + </p> + <p> + An expression defining the map to be updated is put in front of the expression + defining the keys to be updated and their respective values. + </p> + <code>M#{ K => V }</code> + <p> + where <c>M</c> is a term of type map and <c>K</c> and <c>V</c> are any expression. + </p> + <p> + If key <c>K</c> does not match any existing key in the map, a new association + will be created from key <c>K</c> to value <c>V</c>. If key <c>K</c> matches + an existing key in map <c>M</c> its associated value will be replaced by the + new value <c>V</c>. In both cases the evaluated map expression will return a new map. + </p> + <p> + If <c>M</c> is not of type map an exception of type <c>badmap</c> is thrown. + </p> + <p> + To only update an existing value, the following syntax is used, + </p> + <code>M#{ K := V } </code> + <p> + where <c>M</c> is an term of type map, <c>V</c> is an expression and <c>K</c> + is an expression which evaluates to an existing key in <c>M</c>. + </p> + <p> + If key <c>K</c> does not match any existing keys in map <c>M</c> an exception + of type <c>badarg</c> will be triggered at runtime. If a matching key <c>K</c> + is present in map <c>M</c> its associated value will be replaced by the new + value <c>V</c> and the evaluated map expression returns a new map. + </p> + <p> + If <c>M</c> is not of type map an exception of type <c>badmap</c> is thrown. + </p> + <p> + Examples: + </p> + <code> +M0 = #{}, +M1 = M0#{a => 0}, +M2 = M1#{a => 1, b => 2}, +M3 = M2#{"function" => fun() -> f() end}, +M4 = M3#{a := 2, b := 3}. % 'a' and 'b' was added in `M1` and `M2`.</code> + <p> + where <c>M0</c> is any map. It follows that <c>M1 .. M4</c> are maps as well. + </p> + <p> + More Examples: + </p> +<pre> +1> <input>M = #{1 => a}.</input> +#{1 => a } +2> <input>M#{1.0 => b}.</input> +#{1 => a, 1.0 => b}. +3> <input>M#{1 := b}.</input> +#{1 => b} +4> <input>M#{1.0 := b}.</input> +** exception error: bad argument +</pre> + <p> + As in construction, the order in which the key and value expressions + are evaluated is not defined. The + syntactic order of the key-value pairs in the update is of no + relevance, except in the case where two keys match, in which + case the latter value is used. + </p> + </section> + + <section> + <title>Maps in Patterns</title> + <p> + Matching of key-value associations from maps is done in the following way: + </p> + + <code>#{ K := V } = M</code> + <p> + where <c>M</c> is any map. The key <c>K</c> has to be an expression with bound + variables or a literals, and <c>V</c> can be any pattern with either bound or + unbound variables. + </p> + <p> + If the variable <c>V</c> is unbound, it will be bound to the value associated + with the key <c>K</c>, which has to exist in the map <c>M</c>. If the variable + <c>V</c> is bound, it has to match the value associated with <c>K</c> in <c>M</c>. + </p> + <p> Example: </p> +<code> +1> <input>M = #{"tuple" => {1,2}}.</input> +#{"tuple" => {1,2}} +2> <input>#{"tuple" := {1,B}} = M.</input> +#{"tuple" => {1,2}} +3> <input>B.</input> +2.</code> + <p> + This will bind variable <c>B</c> to integer <c>2</c>. + </p> + <p> + Similarly, multiple values from the map may be matched: + </p> + <code>#{ K1 := V1, .., Kn := Vn } = M</code> + <p> + where keys <c>K1 .. Kn</c> are any expressions with literals or bound variables. If all + keys exist in map <c>M</c> all variables in <c>V1 .. Vn</c> will be matched to the + associated values of their respective keys. + </p> + <p> + If the matching conditions are not met, the match will fail, either with + </p> + <list> + <item> + a <c>badmatch</c> exception, if used in the context of the matching operator + as in the example, + </item> + <item> + or resulting in the next clause being tested in function heads and + case expressions. + </item> + </list> + <p> + Matching in maps only allows for <c>:=</c> as delimiters of associations. + The order in which keys are declared in matching has no relevance. + </p> + <p> + Duplicate keys are allowed in matching and will match each pattern associated + to the keys. + </p> + <code>#{ K := V1, K := V2 } = M</code> + <p> + Matching an expression against an empty map literal will match its type but + no variables will be bound: + </p> + <code>#{} = Expr</code> + <p> + This expression will match if the expression <c>Expr</c> is of type map, otherwise + it will fail with an exception <c>badmatch</c>. + </p> + <section> + <title>Matching syntax: Example with literals in function heads</title> + <p> + Matching of literals as keys are allowed in function heads. + </p> + <code> +%% only start if not_started +handle_call(start, From, #{ state := not_started } = S) -> +... + {reply, ok, S#{ state := start }}; + +%% only change if started +handle_call(change, From, #{ state := start } = S) -> +... + {reply, ok, S#{ state := changed }};</code> + </section> + </section> + <section> + <title>Maps in Guards</title> + <p> + Maps are allowed in guards as long as all sub-expressions are valid guard expressions. + </p> + <p> + Two guard BIFs handles maps: + </p> + <list> + <item> + <seealso marker="erts:erlang#is_map/1">is_map/1</seealso> + </item> + <item> + <seealso marker="erts:erlang#map_size/1">map_size/1</seealso> + </item> + </list> + </section> +</chapter> diff --git a/system/doc/reference_manual/modules.xml b/system/doc/reference_manual/modules.xml index cd4c3a1b1b..f0ec7ef165 100644 --- a/system/doc/reference_manual/modules.xml +++ b/system/doc/reference_manual/modules.xml @@ -53,10 +53,10 @@ fact(0) -> % | <pre> -Tag(Value).</pre> <p><c>Tag</c> must be an atom, while <c>Value</c> must be a literal - term. As a convenience in user-defined attributes, the literal term - <c>Value</c> the syntax <c>Name/Arity</c> - (where <c>Name</c> is an atom and <c>Arity</c> a positive integer) - will be translated to <c>{Name,Arity}</c>.</p> + term. As a convenience in user-defined attributes, if the literal term + <c>Value</c> has the syntax <c>Name/Arity</c> + (where <c>Name</c> is an atom and <c>Arity</c> a positive integer), + the term <c>Name/Arity</c> will be translated to <c>{Name,Arity}</c>.</p> <p>Any module attribute can be specified. The attributes are stored in the compiled code and can be retrieved by calling diff --git a/system/doc/reference_manual/part.xml b/system/doc/reference_manual/part.xml index ee8f3dd7eb..36fb888748 100644 --- a/system/doc/reference_manual/part.xml +++ b/system/doc/reference_manual/part.xml @@ -36,6 +36,7 @@ <xi:include href="typespec.xml"/> <xi:include href="expressions.xml"/> <xi:include href="macros.xml"/> + <xi:include href="maps.xml"/> <xi:include href="records.xml"/> <xi:include href="errors.xml"/> <xi:include href="processes.xml"/> diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml index 71aec732cf..cc35c6eb21 100644 --- a/system/doc/reference_manual/typespec.xml +++ b/system/doc/reference_manual/typespec.xml @@ -100,6 +100,7 @@ | Fun | Integer | List + | Map | Tuple | Union | UserDefined %% described in Section 6.3 @@ -126,10 +127,17 @@ | nonempty_improper_list(Type1, Type2) %% Type1 and Type2 as above | nonempty_list(Type) %% Proper non-empty list + Map :: map() %% stands for a map of any size + | #{} %% stands for a map of any size + | #{PairList} + Tuple :: tuple() %% stands for a tuple of any size | {} | {TList} + PairList :: Type => Type + | Type => Type, PairList + TList :: Type | Type, TList @@ -275,6 +283,10 @@ Records have been extended to possibly contain type information. This is described in the sub-section <seealso marker="#typeinrecords">"Type information in record declarations"</seealso> below. </p> + <note> + <p>Map types, both <c>map()</c> and <c>#{ ... }</c>, are considered experimental during OTP 17.</p> + <p>No type information of maps pairs, only the containing map types, are used by Dialyzer in OTP 17.</p> + </note> </section> <section> diff --git a/system/doc/reference_manual/xmlfiles.mk b/system/doc/reference_manual/xmlfiles.mk index 6886c8c7cf..181e6f8042 100644 --- a/system/doc/reference_manual/xmlfiles.mk +++ b/system/doc/reference_manual/xmlfiles.mk @@ -24,6 +24,7 @@ REF_MAN_CHAPTER_FILES = \ functions.xml \ expressions.xml \ macros.xml \ + maps.xml \ records.xml \ errors.xml \ processes.xml \ diff --git a/system/doc/system_principles/system_principles.xml b/system/doc/system_principles/system_principles.xml index 4f2202fdd1..70c69b1dab 100644 --- a/system/doc/system_principles/system_principles.xml +++ b/system/doc/system_principles/system_principles.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1996</year><year>2013</year> + <year>1996</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -34,13 +34,12 @@ <p>An Erlang runtime system is started with the command <c>erl</c>:</p> <pre> % <input>erl</input> -Erlang (BEAM) emulator version 5.2.3.5 [hipe] [threads:0] +Erlang/OTP 17 [erts-6.0] [hipe] [smp:8:8] -Eshell V5.2.3.5 (abort with ^G) +Eshell V6.0 (abort with ^G) 1> </pre> <p><c>erl</c> understands a number of command line arguments, see - <c>erl(1)</c>. A number of them are also described in this - chapter.</p> + <c>erl(1)</c>. A number of them are also described in this chapter.</p> <p>Application programs can access the values of the command line arguments by calling one of the functions <c>init:get_argument(Key)</c>, or <c>init:get_arguments()</c>. |