diff options
Diffstat (limited to 'guide')
-rw-r--r-- | guide/ch01.html | 83 | ||||
-rw-r--r-- | guide/ch02.html | 163 | ||||
-rw-r--r-- | guide/ch03.html | 77 | ||||
-rw-r--r-- | guide/ch04.html | 74 | ||||
-rw-r--r-- | guide/ch05.html | 60 | ||||
-rw-r--r-- | guide/ch06.html | 226 | ||||
-rw-r--r-- | guide/ch07.html | 236 | ||||
-rw-r--r-- | guide/ch08.html | 83 | ||||
-rw-r--r-- | guide/ch09.html | 74 | ||||
-rw-r--r-- | guide/ch10.html | 75 | ||||
-rw-r--r-- | guide/index.html | 42 | ||||
-rw-r--r-- | guide/pt01.html | 42 | ||||
-rw-r--r-- | guide/pt02.html | 42 | ||||
-rw-r--r-- | guide/pt03.html | 42 |
14 files changed, 1319 insertions, 0 deletions
diff --git a/guide/ch01.html b/guide/ch01.html new file mode 100644 index 0000000..c856275 --- /dev/null +++ b/guide/ch01.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="index.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch02.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="_installation"></a>Chapter 1. Installation</h1></div></div></div><p>This chapter explains how to setup your system in +order to use Erlang.mk.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_on_unix"></a>1.1. On Unix</h2></div></div></div><p>Erlang.mk requires GNU Make to be installed. GNU Make 3.81 +or later is required. GNU Make 4.1 or later is recommended, +as this is the version Erlang.mk is developed on.</p><p>Some functionality requires that Autoconf 2.59 or later be +installed, in order to compile Erlang/OTP. Erlang/OTP may +have further requirements depending on your needs.</p><p>Erlang.mk currently requires Erlang/OTP to be installed in +order to compile Erlang projects.</p><p>Some packages may require additional libraries.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_on_windows"></a>1.2. On Windows</h2></div></div></div><p>Erlang.mk can be used on Windows inside an MSYS2 environment. +Cygwin, MSYS (the original) and native Windows (both Batch +and PowerShell) are currently not supported.</p><p>The rest of this section details how to setup Erlang/OTP and +MSYS2 in order to use Erlang.mk.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_installing_erlang_otp"></a>1.2.1. Installing Erlang/OTP</h3></div></div></div><p>Erlang.mk requires Erlang/OTP to be installed. The OTP team +provides binaries of Erlang/OTP for all major and minor releases, +available from the <a class="ulink" href="http://www.erlang.org/download.html" target="_top">official download page</a>. +It is recommended that you use the 64-bit installer unless +technically impossible. Please follow the instructions from +the installer to complete the installation.</p><p>The OTP team also provides a short guide to +<a class="ulink" href="http://www.erlang.org/download.html" target="_top">installing Erlang/OTP on Windows</a> +if you need additional references.</p><p>You can install Erlang/OTP silently using the <code class="literal">/S</code> switch +on the command line:</p><pre class="screen">C:\Users\essen\Downloads> otp_win64_18.0.exe /S</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_installing_msys2"></a>1.2.2. Installing MSYS2</h3></div></div></div><p>The only supported environment on Windows is MSYS2. MSYS2 is +a lightweight Unix-like environment for Windows that comes +with the Arch Linux package manager, <code class="literal">pacman</code>.</p><p>The MSYS2 project provides a <a class="ulink" href="http://msys2.github.io" target="_top">one click installer</a> +and instructions to set things up post-installation.</p><p>It is currently not possible to use the installer silently. +Thankfully, the MSYS2 project provides an archive that can +be used in lieu of the installer. The archive however requires +<span class="emphasis"><em>7zip</em></span> to decompress it.</p><p>First, download the +<a class="ulink" href="http://sourceforge.net/projects/msys2/files/Base/x86_64/msys2-base-x86_64-20150512.tar.xz/download" target="_top">MSYS2 base archive</a> +and extract it under <span class="emphasis"><em>C:\</em></span>. Assuming you downloaded the +archive as <span class="emphasis"><em>msys2.tar.xz</em></span> and put it in <span class="emphasis"><em>C:\</em></span>, you can +use the following commands to extract it:</p><pre class="screen">C:\> 7z x msys2.tar.xz +C:\> 7z x msys2.tar > NUL</pre><p>Then you can run the two commands needed to perform the +post-installation setup:</p><pre class="screen">C:\> C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -Sy bash pacman pacman-mirrors msys2-runtime" +C:\> C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syu"</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_installing_the_required_msys2_packages"></a>1.2.3. Installing the required MSYS2 packages</h3></div></div></div><p>After following these instructions, you can install GNU Make, +Git and any other required softwares. From an MSYS2 shell, +you can call <code class="literal">pacman</code> directly:</p><pre class="programlisting">$ pacman -S git make</pre><p>You can use <code class="literal">pacman -Ss</code> to search packages. For example, +to find all packages related to GCC:</p><pre class="programlisting">$ pacman -Ss gcc</pre><p>You can also run commands under the MSYS2 environment from +the Windows command line or batch files. This command will +install GNU Make and Git:</p><pre class="screen">C:\> C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S git make"</pre><p>You can use similar <code class="literal">bash</code> commands if you need to run programs +inside the MSYS2 environment from a batch file.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_gotchas"></a>1.2.4. Gotchas</h3></div></div></div><p>While most of the basic functionality will just work, there are +still some issues. Erlang.mk needs to be fixed to pass the +right paths when running Erlang scripts. We are working on it. +Erlang.mk is fully tested on both Linux and Windows, but is +lacking tests in the areas not yet covered by this guide, +so expect bugs to be fixed as more tests are added.</p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="index.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ch02.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/ch02.html b/guide/ch02.html new file mode 100644 index 0000000..c4afbe7 --- /dev/null +++ b/guide/ch02.html @@ -0,0 +1,163 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="ch01.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch03.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="_getting_started"></a>Chapter 2. Getting started</h1></div></div></div><p>This chapter explains how to get started using Erlang.mk.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_creating_a_folder_for_your_project"></a>2.1. Creating a folder for your project</h2></div></div></div><p>The first step is always to create a new folder that will +contain your project.</p><pre class="programlisting">$ mkdir hello_joe +$ cd hello_joe</pre><p>Most people tend to put all their projects side by side in +a common folder. We recommend keeping an organization similar +to your remote repositories. For example, for GitHub users, +put all your projects in a common folder with the same name +as your username. For example <span class="emphasis"><em>$HOME/ninenines/cowboy</em></span> for +the Cowboy project.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_downloading_erlang_mk"></a>2.2. Downloading Erlang.mk</h2></div></div></div><p>At the time of writing, Erlang.mk is unlikely to be present +in your Erlang distribution, or even in your OS packages.</p><p>The next step is therefore to download it:</p><pre class="programlisting">$ wget https://raw.githubusercontent.com/ninenines/erlang.mk/master/erlang.mk</pre><p>Or:</p><pre class="programlisting">$ curl https://raw.githubusercontent.com/ninenines/erlang.mk/master/erlang.mk</pre><p>Alternatively, just <a class="ulink" href="https://raw.githubusercontent.com/ninenines/erlang.mk/master/erlang.mk" target="_top">click on this link</a>.</p><p>Make sure you put the file inside the folder we created previously.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_getting_started_with_otp_applications"></a>2.3. Getting started with OTP applications</h2></div></div></div><p>An OTP application is an Erlang application that has a supervision +tree. In other words, it will always have processes running.</p><p>This kind of project can be automatically generated by Erlang.mk. +All you need to do is use the <code class="literal">bootstrap</code> target:</p><pre class="programlisting">$ make -f erlang.mk bootstrap</pre><p>Something similar to the following snippet will then appear +on your screen:</p><pre class="programlisting">git clone https://github.com/ninenines/erlang.mk .erlang.mk.build +Cloning into '.erlang.mk.build'... +remote: Counting objects: 4035, done. +remote: Compressing objects: 100% (12/12), done. +remote: Total 4035 (delta 8), reused 4 (delta 4), pack-reused 4019 +Receiving objects: 100% (4035/4035), 1.10 MiB | 784.00 KiB/s, done. +Resolving deltas: 100% (2442/2442), done. +Checking connectivity... done. +if [ -f build.config ]; then cp build.config .erlang.mk.build; fi +cd .erlang.mk.build && make +make[1]: Entering directory '/home/essen/tmp/hello_joe/.erlang.mk.build' +awk 'FNR==1 && NR!=1{print ""}1' core/core.mk index/*.mk core/index.mk core/deps.mk plugins/protobuffs.mk core/erlc.mk core/docs.mk core/test.mk plugins/asciidoc.mk plugins/bootstrap.mk plugins/c_src.mk plugins/ci.mk plugins/ct.mk plugins/dialyzer.mk plugins/edoc.mk plugins/elvis.mk plugins/erlydtl.mk plugins/escript.mk plugins/eunit.mk plugins/relx.mk plugins/shell.mk plugins/triq.mk plugins/xref.mk plugins/cover.mk \ + | sed 's/^ERLANG_MK_VERSION = .*/ERLANG_MK_VERSION = 1.2.0-642-gccd2b9f/' > erlang.mk +make[1]: Leaving directory '/home/essen/tmp/hello_joe/.erlang.mk.build' +cp .erlang.mk.build/erlang.mk ./erlang.mk +rm -rf .erlang.mk.build</pre><p>This is Erlang.mk bootstrapping itself. Indeed, the file you +initially downloaded contains nothing more than the code needed +to bootstrap. This operation is done only once. Consult the +<a class="ulink" href="updating.asciidoc" target="_top">Updating Erlang.mk</a> chapter for more +information.</p><p>Of course, the generated project can now be compiled:</p><pre class="programlisting">$ make</pre><p>Cheers!</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_getting_started_with_otp_libraries"></a>2.4. Getting started with OTP libraries</h2></div></div></div><p>An OTP library is an Erlang application that has no supervision +tree. In other words, it is nothing but modules.</p><p>This kind of project can also be generated by Erlang.mk, using +the <code class="literal">bootstrap-lib</code> target:</p><pre class="programlisting">$ make -f erlang.mk bootstrap-lib</pre><p>Erlang.mk will once again bootstrap itself and generate all +the files for your project. You can now compile it:</p><pre class="programlisting">$ make</pre><p>Enjoy!</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_getting_started_with_otp_releases"></a>2.5. Getting started with OTP releases</h2></div></div></div><p>An OTP release is the combination of the Erlang RunTime System (ERTS) +along with all the libraries and files that your node will need +to run. It is entirely self contained, and can often be sent as-is +to your production system and run without any extra setup.</p><p>Erlang.mk can of course bootstrap your project to generate releases. +You can use the <code class="literal">bootstrap-rel</code> target for this purpose:</p><pre class="programlisting">$ make bootstrap-rel</pre><p>This target can be combined with <code class="literal">bootstrap</code> or <code class="literal">bootstrap-lib</code> to +create a project that will build a release:</p><pre class="programlisting">$ make -f erlang.mk bootstrap-lib bootstrap-rel</pre><p>It is often very useful to keep the top-level project for +commands useful during operations, and put the components +of the system in separate applications that you will then +depend on. Consult the <a class="ulink" href="deps.asciidoc" target="_top">Packages and dependencies</a> +chapter for more information.</p><p>When you run <code class="literal">make</code> from now on, Erlang.mk will compile your +project and build the release:</p><pre class="programlisting">$ make + APP hello_joe.app.src + GEN distclean-relx-rel + GEN /home/essen/tmp/hello_joe/relx +===> Starting relx build process ... +===> Resolving OTP Applications from directories: + /home/essen/tmp/hello_joe/ebin + /usr/lib/erlang/lib + /home/essen/tmp/hello_joe/deps +===> Resolved hello_joe_release-1 +===> Including Erts from /usr/lib/erlang +===> release successfully created!</pre><p>The first time you run this command, Erlang.mk will download +<span class="emphasis"><em>relx</em></span>, the release building tool. So don’t worry if you see +more output than above.</p><p>If building the release is slow, no need to upgrade your +hardware just yet. Just consult the <a class="ulink" href="relx.asciidoc" target="_top">Releases</a> +chapter for various tips to speed up build time during +development.</p><p>You can start the release using the <span class="emphasis"><em>./_rel/hello_joe_release/bin/hello_joe_release</em></span> +script, or simply run <code class="literal">make run</code>. The latter will also compile +your project and build the release if it wasn’t already:</p><pre class="programlisting">$ make run + APP hello_joe.app.src + GEN distclean-relx-rel +===> Starting relx build process ... +===> Resolving OTP Applications from directories: + /home/essen/tmp/hello_joe/ebin + /usr/lib/erlang/lib + /home/essen/tmp/hello_joe/deps +===> Resolved hello_joe_release-1 +===> Including Erts from /usr/lib/erlang +===> release successfully created! +Exec: /home/essen/tmp/hello_joe/_rel/hello_joe_release/erts-7.0/bin/erlexec -boot /home/essen/tmp/hello_joe/_rel/hello_joe_release/releases/1/hello_joe_release -boot_var ERTS_LIB_DIR /home/essen/tmp/hello_joe/_rel/hello_joe_release/erts-7.0/../lib -env ERL_LIBS /home/essen/tmp/hello_joe/_rel/hello_joe_release/releases/1/lib -config /home/essen/tmp/hello_joe/_rel/hello_joe_release/releases/1/sys.config -args_file /home/essen/tmp/hello_joe/_rel/hello_joe_release/releases/1/vm.args -- console +Root: /home/essen/tmp/hello_joe/_rel/hello_joe_release +/home/essen/tmp/hello_joe/_rel/hello_joe_release +heart_beat_kill_pid = 16389 +Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] + +Eshell V7.0 (abort with ^G) +([email protected])1></pre><p>Simple as that!</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_using_templates"></a>2.6. Using templates</h2></div></div></div><p>It is no secret that Erlang’s OTP behaviors tend to have some +boilerplate. It is rarely an issue of course, except when +creating new modules. That’s why Erlang.mk not only comes with +templates for generating projects, but also individual modules!</p><p>You can list all available templates with the <code class="literal">list-templates</code> +target:</p><pre class="programlisting">$ make list-templates +Available templates: cowboy_http cowboy_loop cowboy_rest cowboy_ws gen_fsm gen_server ranch_protocol supervisor</pre><p>To generate a module, let’s say a <code class="literal">gen_server</code>, all you need to +do is to call <code class="literal">make new</code> with the appropriate arguments:</p><pre class="programlisting">$ make new t=gen_server n=my_server</pre><p>This will create a module located in <span class="emphasis"><em>src/my_server.erl</em></span> +using the <code class="literal">gen_server</code> template.</p><p>This module is automatically compiled the next time you run +<code class="literal">make</code>:</p><pre class="programlisting">$ make + ERLC my_server.erl + APP hello_joe.app.src</pre><p>All that’s left to do is to open it in your favorite editor +and make it do something!</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_getting_help"></a>2.7. Getting help</h2></div></div></div><p>During development, if you don’t remember the name of a target, +you can always run <code class="literal">make help</code>:</p><pre class="programlisting">$ make help +erlang.mk (version 1.2.0-642-gccd2b9f) is distributed under the terms of the ISC License. +Copyright (c) 2013-2015 Loïc Hoguin <[email protected]> + +Usage: [V=1] make [target]... + +Core targets: + all Run deps, app and rel targets in that order + app Compile the project + deps Fetch dependencies (if needed) and compile them + search q=... Search for a package in the built-in index + rel Build a release for this project, if applicable + docs Build the documentation for this project + install-docs Install the man pages for this project + check Compile and run all tests and analysis for this project + tests Run the tests for this project + clean Delete temporary and output files from most targets + distclean Delete all temporary and output files + help Display this help and exit + erlang-mk Update erlang.mk to the latest version + +Bootstrap targets: + bootstrap Generate a skeleton of an OTP application + bootstrap-lib Generate a skeleton of an OTP library + bootstrap-rel Generate the files needed to build a release + new t=TPL n=NAME Generate a module NAME based on the template TPL + list-templates List available templates +...</pre><p>This guide should provide any other answer. If not, please +open a ticket on <a class="ulink" href="https://github.com/ninenines/erlang.mk/issues" target="_top">the official repository</a> +and we will work on improving the guide.</p><p>Commercial support is available through Nine Nines. Please contact +Loïc Hoguin by sending an email to <a class="ulink" href="mailto:[email protected]" target="_top">[email protected]</a>.</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch01.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ch03.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/ch03.html b/guide/ch03.html new file mode 100644 index 0000000..757a981 --- /dev/null +++ b/guide/ch03.html @@ -0,0 +1,77 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="ch02.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch04.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="_overview"></a>Chapter 3. Overview</h1></div></div></div><p>Now that you know how to get started, let’s take a look at +what Erlang.mk can do for you.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_building_your_project"></a>3.1. Building your project</h2></div></div></div><p>Erlang.mk is first and foremost a build tool. It is especially +tailored for Erlang developers and follows widely accepted +practices in the Erlang community.</p><p>Erlang.mk will happily build all <a class="ulink" href="app.asciidoc" target="_top">Erlang-specific files</a> +you throw at it. Other kinds of files too, like C or C++ code +when you are working on <a class="ulink" href="ports.asciidoc" target="_top">a NIF or a port driver</a>.</p><p>Erlang.mk embraces the concept of <a class="ulink" href="deps.asciidoc" target="_top">source dependencies</a>. +It can fetch dependency source code using a variety of mechanisms, +including fetching from Git, Mercurial or SVN.</p><p>Erlang.mk will automatically <a class="ulink" href="relx.asciidoc" target="_top">generate releases</a> +when applicable. It can also <a class="ulink" href="escripts.asciidoc" target="_top">generate escripts</a>.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_exploring_the_package_index"></a>3.2. Exploring the package index</h2></div></div></div><p>Erlang.mk comes with a <a class="ulink" href="deps.asciidoc" target="_top">built-in package index</a>. +It is built as an extension of the dependency system and is +meant to be used for discovery purposes.</p><p>No package is ever installed, they are only used as dependencies +and are always project-specific. They can be thought of as a +shortcut over plain dependencies.</p><p>You can get a list of all packages known to Erlang.mk by using +the <code class="literal">search</code> target:</p><pre class="programlisting">$ make search</pre><p>You can also use this target to search across all packages, for +example to find all packages related to Cowboy:</p><pre class="programlisting">$ make search q=cowboy</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_generating_documentation"></a>3.3. Generating documentation</h2></div></div></div><p>Erlang.mk supports <span class="emphasis"><em>EDoc</em></span> and <span class="emphasis"><em>Asciidoc</em></span>.</p><p><a class="ulink" href="edoc.asciidoc" target="_top">EDoc</a> generates HTML documentation directly from +your source code.</p><p>While it is convenient, ask yourself: if all the documentation is +inside the source code, why not just open the source code directly? +That’s where <span class="emphasis"><em>Asciidoc</em></span> comes in.</p><p>The <a class="ulink" href="asciidoc.asciidoc" target="_top">Asciidoc</a> plugin expects all documentation +to be separate from source. It will generate HTML, PDF, man pages and +more from the documentation you write in the <span class="emphasis"><em>doc/src/</em></span> folder in +your repository.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_running_tests"></a>3.4. Running tests</h2></div></div></div><p>Erlang.mk supports a lot of different testing and static +analysis tools.</p><p>The <a class="ulink" href="shell.asciidoc" target="_top">make shell</a> command allows you +to test your project manually. You can automate these +unit tests with <a class="ulink" href="eunit.asciidoc" target="_top">EUnit</a> and test +your entire system with <a class="ulink" href="common_test.asciidoc" target="_top">Common Test</a>. +<a class="ulink" href="property_based_testing.asciidoc" target="_top">Property based testing</a> +with Triq is a strong alternative to writing unit tests +manually. <a class="ulink" href="coverage.asciidoc" target="_top">Code coverage</a> can of course +be enabled during tests.</p><p>Erlang.mk comes with features to make your life easier when +setting up and using <a class="ulink" href="ci.asciidoc" target="_top">Continuous integration</a>.</p><p>On the static analysis side of things, Erlang.mk comes with +support for <a class="ulink" href="dialyzer.asciidoc" target="_top">Dialyzer</a>, <a class="ulink" href="xref.asciidoc" target="_top">Xref</a> +and <a class="ulink" href="elvis.asciidoc" target="_top">Elvis</a>, performing success typing +analysis, cross reference and style reviewing.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_need_more"></a>3.5. Need more?</h2></div></div></div><p>Not convinced yet? You can read about <a class="ulink" href="why.asciidoc" target="_top">why you should use Erlang.mk</a> +and its <a class="ulink" href="history.asciidoc" target="_top">history</a>. And if you’re still not +convinced after that, it’s OK! The world would be boring if +everyone agreed on everything all the time.</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch02.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ch04.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/ch04.html b/guide/ch04.html new file mode 100644 index 0000000..3067c20 --- /dev/null +++ b/guide/ch04.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="ch03.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch05.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="_updating_erlang_mk"></a>Chapter 4. Updating Erlang.mk</h1></div></div></div><p>This chapter describes how to update the <span class="emphasis"><em>erlang.mk</em></span> file +in your repository.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_initial_bootstrap"></a>4.1. Initial bootstrap</h2></div></div></div><p>The first time you use Erlang.mk, it will bootstrap itself. +It always uses the most recent version for this, so you don’t +have to update after creating your project.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_updating"></a>4.2. Updating</h2></div></div></div><p>Later on though, updating becomes a necessity. Erlang.mk +developers and contributors relentlessly improve the project +and add new features; it would be a waste not to benefit +from this.</p><p>That’s why updating Erlang.mk is so simple. All you need +to do is to call <code class="literal">make erlang-mk</code>:</p><pre class="programlisting">$ make erlang-mk +git clone https://github.com/ninenines/erlang.mk .erlang.mk.build +Cloning into '.erlang.mk.build'... +remote: Counting objects: 4035, done. +remote: Compressing objects: 100% (12/12), done. +remote: Total 4035 (delta 8), reused 4 (delta 4), pack-reused 4019 +Receiving objects: 100% (4035/4035), 1.10 MiB | 1000.00 KiB/s, done. +Resolving deltas: 100% (2442/2442), done. +Checking connectivity... done. +if [ -f build.config ]; then cp build.config .erlang.mk.build; fi +cd .erlang.mk.build && make +make[1]: Entering directory '/home/essen/tmp/emkg/hello_joe/.erlang.mk.build' +awk 'FNR==1 && NR!=1{print ""}1' core/core.mk index/*.mk core/index.mk core/deps.mk plugins/protobuffs.mk core/erlc.mk core/docs.mk core/test.mk plugins/asciidoc.mk plugins/bootstrap.mk plugins/c_src.mk plugins/ci.mk plugins/ct.mk plugins/dialyzer.mk plugins/edoc.mk plugins/elvis.mk plugins/erlydtl.mk plugins/escript.mk plugins/eunit.mk plugins/relx.mk plugins/shell.mk plugins/triq.mk plugins/xref.mk plugins/cover.mk \ + | sed 's/^ERLANG_MK_VERSION = .*/ERLANG_MK_VERSION = 1.2.0-642-gccd2b9f/' > erlang.mk +make[1]: Leaving directory '/home/essen/tmp/emkg/hello_joe/.erlang.mk.build' +cp .erlang.mk.build/erlang.mk ./erlang.mk +rm -rf .erlang.mk.build</pre><p>All that’s left to do is to commit the file!</p><p>Yep, it’s that easy.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_customizing_the_build"></a>4.3. Customizing the build</h2></div></div></div><p>Erlang.mk allows you to customize which plugins are to be included +in the <span class="emphasis"><em>erlang.mk</em></span> file. You can do so by maintaining your own +<span class="emphasis"><em>build.config</em></span> file in your repository. Erlang.mk will automatically +use it the next time you run <code class="literal">make erlang-mk</code>.</p><p>The <span class="emphasis"><em>build.config</em></span> file contains the list of all files that will +be built into the resulting <span class="emphasis"><em>erlang.mk</em></span> file. You can start from +the <a class="ulink" href="https://github.com/ninenines/erlang.mk/blob/master/build.config" target="_top">most recent version</a> +and customize to your needs.</p><p>You can also name the file differently or put it in a separate folder +by modifying the value for <code class="literal">ERLANG_MK_BUILD_CONFIG</code>. You can also +tell Erlang.mk to use a different temporary directory by changing +the <code class="literal">ERLANG_MK_BUILD_DIR</code> variable.</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch03.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ch05.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/ch05.html b/guide/ch05.html new file mode 100644 index 0000000..44cb840 --- /dev/null +++ b/guide/ch05.html @@ -0,0 +1,60 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="ch04.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="pt01.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="_limitations"></a>Chapter 5. Limitations</h1></div></div></div><p>No software is perfect.</p><p>It’s very important, when evaluating and when using a tool, +to understand its limitations, so as to avoid making mistakes +and wasting valuable time.</p><p>This chapter lists all known limitations of Erlang.mk.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_erlang_must_be_available"></a>5.1. Erlang must be available</h2></div></div></div><p>Currently Erlang.mk requires you to install Erlang beforehand. +Installing Erlang is not always easy, particularly if you need +a specific version of Erlang for a specific project.</p><p>In addition, the Erlang being used must be in your <code class="literal">$PATH</code> +before you use Erlang.mk.</p><p>In the future we envision, Erlang.mk could manage the Erlang +version you need to use a project. Erlang.mk already does this +for running tests when using <code class="literal">make ci</code>, so doing this during +development is just a step away.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_spaces_in_path"></a>5.2. Spaces in path</h2></div></div></div><p>Erlang.mk will currently not work properly if the path to the +project contains spaces. To check if that is the case, use the +command <code class="literal">pwd</code>.</p><p>This issue is due to how Makefiles work. There might be ways +to solve it, we have not given up on it, but it’s very low +priority considering how simple the workaround is.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_dependency_tracking_and_modification_times"></a>5.3. Dependency tracking and modification times</h2></div></div></div><p>Erlang source files that depend on other files will have their +modification time updated when they need to be recompiled due +to a dependency having changed. This could cause some editors to +think the file changed when it didn’t.</p><p>Erlang.mk must use this method in order to be able to compile +files in one <code class="literal">erlc</code> invocation. The benefits greatly outweigh +the issue in this case and so there are currently no plans to +fix this behavior.</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch04.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="pt01.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/ch06.html b/guide/ch06.html new file mode 100644 index 0000000..38fe703 --- /dev/null +++ b/guide/ch06.html @@ -0,0 +1,226 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="pt01.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch07.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a id="_building"></a>Chapter 6. Building</h2></div></div></div><p>Erlang.mk can do a lot of things, but it is, first and +foremost, a build tool. In this chapter we will cover +the basics of building a project with Erlang.mk.</p><p>For most of this chapter, we will assume that you are +using a project <a class="ulink" href="getting_started.asciidoc" target="_top">generated by Erlang.mk</a>.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_how_to_build"></a>6.1. How to build</h2></div></div></div><p>To build a project, all you have to do is type <code class="literal">make</code>:</p><pre class="programlisting">$ make</pre><p>It will work regardless of your project: OTP applications, +library applications, NIFs, port drivers or even releases. +Erlang.mk also automatically downloads and compiles the +dependencies for your project.</p><p>All this is possible thanks to a combination of configuration +and conventions. Most of the conventions come from Erlang/OTP +itself so any seasoned Erlang developers should feel right at +home.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_what_to_build"></a>6.2. What to build</h2></div></div></div><p>Erlang.mk gives you control over three steps of the build +process, allowing you to do a partial build if needed.</p><p>A build has three phases: first any dependency is fetched +and built, then the project itself is built and finally a +release may be generated when applicable. A release is only +generated for projects specifically configured to do so.</p><p>Erlang.mk handles those three phases automatically when you +type <code class="literal">make</code>. But sometimes you just want to repeat one or +two of them.</p><p>The commands detailed in this section are most useful after +you have a successful build as they allow you to quickly +redo a step instead of going through everything. This is +especially useful for large projects or projects that end +up generating releases.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_application"></a>6.2.1. Application</h3></div></div></div><p>You can build your application specifically, without +looking at handling dependencies or generating a release, +by running the following command:</p><pre class="programlisting">$ make app</pre><p>This command is very useful if you have a lot of dependencies +and develop on a machine with slow file access, like the +Raspberry Pi and many other embedded devices.</p><p>Note that this command may fail if a required dependency +is missing.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_dependencies"></a>6.2.2. Dependencies</h3></div></div></div><p>You can build all dependencies, and nothing else, by +running the following command:</p><pre class="programlisting">$ make deps</pre><p>This will fetch and compile all dependencies and their +dependencies, recursively.</p><p><a class="ulink" href="deps.asciidoc" target="_top">Packages and dependencies</a> are covered +in the next chapter.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_release"></a>6.2.3. Release</h3></div></div></div><p>You can generate the release, skipping the steps for building +the application and dependencies, by running the following +command:</p><pre class="programlisting">$ make rel</pre><p>This command can be useful if nothing changed except the +release configuration files.</p><p>Consult the <a class="ulink" href="relx.asciidoc" target="_top">Releases</a> chapter for more +information about what releases are and how they are generated.</p><p>Note that this command may fail if a required dependency +is missing.</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_application_resource_file"></a>6.3. Application resource file</h2></div></div></div><p>When building your application, Erlang.mk will generate the +<a class="ulink" href="http://www.erlang.org/doc/man/app.html" target="_top">application resource file</a>. +This file is mandatory for all Erlang applications and is +found in <span class="emphasis"><em>ebin/$(PROJECT).app</em></span>.</p><p><code class="literal">PROJECT</code> is a variable defined in your Makefile and taken +from the name of the directory when Erlang.mk bootstraps +your project.</p><p>Erlang.mk can build the <span class="emphasis"><em>ebin/$(PROJECT).app</em></span> in two different +ways: from the configuration found in the Makefile, or from +the <span class="emphasis"><em>src/$(PROJECT).app.src</em></span> file.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_application_configuration"></a>6.3.1. Application configuration</h3></div></div></div><p>Erlang.mk automatically fills the <code class="literal">PROJECT</code> variable when +bootstrapping a new project, but everything else is up to +you. None of the values are required to build your project, +although it is recommended to fill everything relevant to +your situation.</p><div class="variablelist"><dl class="variablelist"><dt><span class="term"> +<code class="literal">PROJECT</code> +</span></dt><dd> + The name of the OTP application or library. +</dd><dt><span class="term"> +<code class="literal">PROJECT_DESCRIPTION</code> +</span></dt><dd> + Short description of the project. +</dd><dt><span class="term"> +<code class="literal">PROJECT_VERSION</code> +</span></dt><dd> + Current version of the project. +</dd><dt><span class="term"> +<code class="literal">PROJECT_REGISTERED</code> +</span></dt><dd> + List of the names of all registered processes. +</dd><dt><span class="term"> +<code class="literal">OTP_DEPS</code> +</span></dt><dd> + List of Erlang/OTP applications this project depends on, + excluding <code class="literal">erts</code>, <code class="literal">kernel</code> and <code class="literal">stdlib</code>. +</dd><dt><span class="term"> +<code class="literal">DEPS</code> +</span></dt><dd> + List of applications this project depends on that need + to be fetched by Erlang.mk. +</dd></dl></div><p>There’s no need for quotes or anything. The relevant part of +the Cowboy Makefile follows, if you need an example:</p><pre class="programlisting">PROJECT = cowboy +PROJECT_DESCRIPTION = Small, fast, modular HTTP server. +PROJECT_VERSION = 2.0.0-pre.2 +PROJECT_REGISTERED = cowboy_clock + +OTP_DEPS = crypto +DEPS = cowlib ranch</pre><p>Any space before and after the value is dropped.</p><p><a class="ulink" href="deps.asciidoc" target="_top">Dependencies</a> are covered in details in +the next chapter.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_legacy_method"></a>6.3.2. Legacy method</h3></div></div></div><p>The <span class="emphasis"><em>src/$(PROJECT).app.src</em></span> file is a legacy method of +building Erlang applications. It was introduced by the original +<code class="literal">rebar</code> build tool, of which Erlang.mk owes a great deal as it +is its main inspiration.</p><p>The <span class="emphasis"><em>.app.src</em></span> file serves as a template to generate the <span class="emphasis"><em>.app</em></span> +file. Erlang.mk will take it, fill in the <code class="literal">modules</code> value +dynamically, and save the result in <span class="emphasis"><em>ebin/$(PROJECT).app</em></span>.</p><p>When using this method, Erlang.mk cannot fill the <code class="literal">applications</code> +key from dependencies automatically, which means you need to +add them to Erlang.mk and to the <span class="emphasis"><em>.app.src</em></span> at the same time, +duplicating the work.</p><p>If you really can’t live without the legacy method, for one +reason or another, worry not; Erlang.mk will support it. And +if you need to create a new project that uses this method, you +just have to say so when bootstrapping:</p><pre class="programlisting">$ make -f erlang.mk bootstrap-lib LEGACY=1</pre></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_automatic_application_resource_file_values"></a>6.4. Automatic application resource file values</h2></div></div></div><p>When building the application resource file, Erlang.mk may +automatically add an <code class="literal">id</code> key with information about the +Git commit (if using Git), or an empty string otherwise. +It will only do this under specific conditions:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> +The application was built as a dependency of another, or +</li><li class="listitem"> +The legacy method was used, and the <span class="emphasis"><em>.app.src</em></span> file contained <code class="literal">{id, "git"}</code> +</li></ul></div><p>This value is most useful when you need to help your users, +as it allows you to know which version they run exactly by +asking them to look in the file, or by running a simple +command on their production server:</p><pre class="programlisting">1> application:get_all_key(cowboy). +{ok,[{description,"Small, fast, modular HTTP server."}, + {id,"2.0.0-pre.2-25-g0ffde50-dirty"},</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_file_formats"></a>6.5. File formats</h2></div></div></div><p>Erlang.mk supports a variety of different source file formats. +The following formats are supported natively:</p><div class="informaltable"><table cellpadding="4px" style="border-collapse: collapse;border-top: 3px solid #527bbd; border-bottom: 3px solid #527bbd; border-left: 3px solid #527bbd; border-right: 3px solid #527bbd; "><colgroup><col class="col_1" /><col class="col_2" /><col class="col_3" /><col class="col_4" /></colgroup><thead><tr><th style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"> Extension </th><th style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"> Location </th><th style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"> Description </th><th style="border-bottom: 1px solid #527bbd; " align="center" valign="top"> Output</th></tr></thead><tbody><tr><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"><p>.erl</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>src/</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>Erlang source</p></td><td style="border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>ebin/*.beam</p></td></tr><tr><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"><p>.core</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>src/</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>Core Erlang source</p></td><td style="border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>ebin/*.beam</p></td></tr><tr><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"><p>.xrl</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>src/</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>Leex source</p></td><td style="border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>src/*.erl</p></td></tr><tr><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"><p>.yrl</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>src/</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>Yecc source</p></td><td style="border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>src/*.erl</p></td></tr><tr><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"><p>.asn1</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>asn1/</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>ASN.1 files</p></td><td style="border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>include/<span class="strong"><strong>.hrl include/</strong></span>.asn1db src/*.erl</p></td></tr><tr><td style="border-right: 1px solid #527bbd; " align="left" valign="top"><p>.mib</p></td><td style="border-right: 1px solid #527bbd; " align="center" valign="top"><p>mibs/</p></td><td style="border-right: 1px solid #527bbd; " align="center" valign="top"><p>SNMP MIB files</p></td><td style="" align="center" valign="top"><p>include/<span class="strong"><strong>.hrl priv/mibs/</strong></span>.bin</p></td></tr></tbody></table></div><p>Files are always searched recursively.</p><p>The build is ordered, so that files that generate Erlang source +files are run before, and the resulting Erlang source files are +then built normally.</p><p>In addition, Erlang.mk keeps track of header files (<code class="literal">.hrl</code>) +as described at the end of this chapter. It can also compile +C code, as described in the <a class="ulink" href="ports.asciidoc" target="_top">NIFs and port drivers</a> +chapter.</p><p>Erlang.mk also comes with plugins for the following formats:</p><div class="informaltable"><table cellpadding="4px" style="border-collapse: collapse;border-top: 3px solid #527bbd; border-bottom: 3px solid #527bbd; border-left: 3px solid #527bbd; border-right: 3px solid #527bbd; "><colgroup><col class="col_1" /><col class="col_2" /><col class="col_3" /><col class="col_4" /></colgroup><thead><tr><th style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"> Extension </th><th style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"> Location </th><th style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"> Description </th><th style="border-bottom: 1px solid #527bbd; " align="center" valign="top"> Output</th></tr></thead><tbody><tr><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"><p>.dtl</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>templates/</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>Django templates</p></td><td style="border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>ebin/*.beam</p></td></tr><tr><td style="border-right: 1px solid #527bbd; " align="left" valign="top"><p>.proto</p></td><td style="border-right: 1px solid #527bbd; " align="center" valign="top"><p>src/</p></td><td style="border-right: 1px solid #527bbd; " align="center" valign="top"><p>Protocol buffers</p></td><td style="" align="center" valign="top"><p>ebin/*.beam</p></td></tr></tbody></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_compilation_options"></a>6.6. Compilation options</h2></div></div></div><p>Erlang.mk provides a few variables that you can use to customize +the build process and the resulting files.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_erlc_opts"></a>6.6.1. ERLC_OPTS</h3></div></div></div><p><code class="literal">ERLC_OPTS</code> can be used to pass some options to <code class="literal">erlc</code>, the Erlang +compiler. Erlang.mk does not restrict any option. Please refer to +the <a class="ulink" href="http://www.erlang.org/doc/man/erlc.html" target="_top">erlc Manual</a> for the +full list.</p><p>By default, Erlang.mk will set the following options:</p><pre class="programlisting">ERLC_OPTS = -Werror +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard</pre><p>In other words: warnings as errors, debug info (recommended) and +enable warnings for exported variables, shadow variables and +obsolete guard functions.</p><p>You can redefine this variable in your Makefile to change it +completely, either before or after including Erlang.mk:</p><pre class="programlisting">ERLC_OPTS = +debug_info</pre><p>You can also filter out some options from the defaults Erlang.mk +sets, by defining ERLC_OPTS after including Erlang.mk using the +<code class="literal">:=</code> operator.</p><pre class="programlisting">include erlang.mk + +ERLC_OPTS := $(filter-out -Werror,$(ERLC_OPTS))</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_erlc_exclude"></a>6.6.2. ERLC_EXCLUDE</h3></div></div></div><p><code class="literal">ERLC_EXCLUDE</code> can be used to exclude some modules from the +compilation. It’s there for handling special cases, you should +not normally need it.</p><p>To exclude a module, simply list it in the variable, either +before or after including Erlang.mk:</p><pre class="programlisting">ERLC_EXCLUDE = cowboy_http2</pre></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_cold_and_hot_builds"></a>6.7. Cold and hot builds</h2></div></div></div><p>The first time you run <code class="literal">make</code>, Erlang.mk will build everything.</p><p>The second time you run <code class="literal">make</code>, and all subsequent times, Erlang.mk +will only rebuild what changed. Erlang.mk has been optimized for +this use case, as it is the most common during development.</p><p>Erlang.mk figures out what changed by using the dependency tracking +feature of Make. Make automatically rebuilds a target if one of its +dependency has changed (for example if a header file has changed, +all the source files that include it will be rebuilt), and Erlang.mk +leverages this feature to cut down on rebuild times.</p><p>Note that this applies only to building; some other features of +Erlang.mk will run every time they are called regardless of files +changed.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_dependency_tracking"></a>6.8. Dependency tracking</h2></div></div></div><div class="note" style="margin-left: 0; margin-right: 10%;"><h3 class="title">Note</h3><p>This section is about the dependency tracking between files +inside your project, not application dependencies.</p></div><p>Erlang.mk keeps track of the dependencies between the different +files in your project. This information is kept in the <span class="emphasis"><em>$(PROJECT).d</em></span> +file in your directory. It is generated if missing, and will be +generated again after every file change, by default.</p><p>Dependency tracking is what allows Erlang.mk to know when to +rebuild Erlang files when header files, behaviors or parse +transforms have changed. Erlang.mk also automatically keeps +track of which files should be compiled first, for example +when you have behaviors used by other modules in your project.</p><p>If your project is stable, you may want to disable generating +the dependency tracking file every time you compile. You can +do this by adding the following line to your <span class="emphasis"><em>Makefile</em></span>:</p><pre class="programlisting">NO_MAKEDEP ?= 1</pre><p>As you can see, the snippet above uses <code class="literal">?=</code> instead of a +simple equal sign. This is to allow you to temporarily override +this value when you do make substantial changes to your project +(including a new header file, new module with dependencies, etc.) +and want to rebuild the dependency tracking file. You’ll be +able to use the following command:</p><pre class="programlisting">$ NO_MAKEDEP= make</pre><p>Otherwise, <code class="literal">make clean app</code> will of course force the +recompilation of your project.</p><p>Erlang.mk can also keep track of the source files generated +by other means, for example if you generate code from a data +file in your repository.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_generating_erlang_source"></a>6.9. Generating Erlang source</h2></div></div></div><p>Erlang.mk provides hooks at different stages of the build process. +When your goal is to generate Erlang source files, you can +add your own rules before or after the dependency tracking +file is generated. To do this, you would add your hook before +or after including the <span class="emphasis"><em>erlang.mk</em></span> file.</p><p>The easiest way is after:</p><pre class="programlisting">PROJECT = example + +include erlang.mk + +$(PROJECT).d:: src/generated_mod.erl + +src/generated_mod.erl:: gen-mod.sh + $(gen_verbose) ./gen-mod.sh $@</pre><p>In this case we use <code class="literal">$(gen_verbose)</code> to hide the details of +the build by default. Erlang.mk will simply say what file +is it currently generating.</p><p>When using an external script to generate the Erlang source +file, it is recommended to depend on that script, so that +the source file gets generated again when the script gets +modified.</p><p>If for whatever reason you prefer to hook before including +Erlang.mk, don’t forget to set the <code class="literal">.DEFAULT_GOAL</code> variable, +otherwise nothing will get built:</p><pre class="programlisting">PROJECT = example + +.DEFAULT_GOAL = all + +$(PROJECT).d:: src/generated_mod.erl + +include erlang.mk + +src/generated_mod.erl:: gen-mod.sh + $(gen_verbose) ./gen-mod.sh $@</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_cleaning"></a>6.10. Cleaning</h2></div></div></div><p>Building typically involves creating a lot of new files. Some +are reused in rebuilds, some are simply replaced. All can be +removed safely.</p><p>Erlang.mk provides two commands to remove them: <code class="literal">clean</code> and +<code class="literal">distclean</code>. <code class="literal">clean</code> removes all the intermediate files that +were created as a result of building, including the BEAM files, +the dependency tracking file and the generated documentation. +<code class="literal">distclean</code> removes these and more, including the downloaded +dependencies, Dialyzer’s PLT file and the generated release, +putting your directory back to the state it was before you +started working on it.</p><p>To clean:</p><pre class="programlisting">$ make clean</pre><p>Or distclean:</p><pre class="programlisting">$ make distclean</pre><p>That is the question.</p><p>Note that Erlang.mk will automatically clean some files as +part of other targets, but it will never run <code class="literal">distclean</code> if +you don’t explicitly use it.</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pt01.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pt01.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch07.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/ch07.html b/guide/ch07.html new file mode 100644 index 0000000..b054dbe --- /dev/null +++ b/guide/ch07.html @@ -0,0 +1,236 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="ch06.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch08.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a id="_packages_and_dependencies"></a>Chapter 7. Packages and dependencies</h2></div></div></div><p>Erlang.mk can fetch and compile the dependencies that your +project requires. Erlang.mk improves upon the concepts +introduced by Rebar, so they should be familiar to many +seasoned Erlang developers.</p><p>Erlang.mk is not a package manager, nor is it trying to be, +but it does include an index of Erlang packages to make +discovering useful projects easier.</p><p>This chapter will explain how to use packages, add +dependencies to your project or bundle them directly +in a single repository.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_searching_packages"></a>7.1. Searching packages</h2></div></div></div><p>Erlang.mk gives you access to nearly 500 packages, with more +being added regularly.</p><p>To find a package, search for it:</p><pre class="programlisting">$ make search q=pool</pre><p>This will return all packages matching this word, like worker +pool and acceptor pool projects.</p><p>You can also list everything and use regular command line +tools to find what you need, for example:</p><pre class="programlisting">$ make search | less</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_adding_dependencies_to_your_project"></a>7.2. Adding dependencies to your project</h2></div></div></div><p>Once you find the package you need, adding it as a dependency +to your project is a one-liner:</p><pre class="programlisting">DEPS = cowboy</pre><p>And that’s it! The next time you run <code class="literal">make</code>, Erlang.mk will +fetch and compile Cowboy. Erlang.mk will also ensure Cowboy +is available whenever you use the shell, run tests and any +other operations.</p><p>Erlang.mk will fill in the application resource file with +all applications found in <code class="literal">DEPS</code>. But not all dependencies +are Erlang applications, and not all dependencies need to +be a runtime dependency. That’s where the <code class="literal">BUILD_DEPS</code> +variable comes in: it works just like <code class="literal">DEPS</code>, except the +dependencies listed there will not be added as runtime +dependencies.</p><p>For example, you could add a parse transform project like +this to make it available only at build time:</p><pre class="programlisting">BUILD_DEPS = erlando</pre><p>Or you could depend on a C project directly, if you are +building a NIF:</p><pre class="programlisting">BUILD_DEPS = leveldb +dep_leveldb = git https://github.com/basho/leveldb 2.1.3</pre><p>This dependency will be built before your application, so +you could easily copy the resulting shared file into your +<span class="emphasis"><em>priv/</em></span> directory as part of the build process. More information +about that in the <a class="ulink" href="ports.asciidoc" target="_top">NIFs and port drivers</a> +chapter.</p><p>Another variable, <code class="literal">LOCAL_DEPS</code>, allows specifying runtime +dependencies which are part of Erlang/OTP itself, but also +dependencies that are included in the repository. Since they +are already on your system, there is no need to fetch them. +Do note that there is no way to choose the version, the +application used will be the one already on your system.</p><p>You could depend on the Crypto application, for example:</p><pre class="programlisting">LOCAL_DEPS = crypto</pre><p>Erlang.mk comes with additional types of dependencies. +It has <code class="literal">TEST_DEPS</code> for dependencies used only for testing:</p><pre class="programlisting">TEST_DEPS = ct_helper +dep_ct_helper = git https://github.com/ninenines/ct_helper master</pre><p><code class="literal">DOC_DEPS</code> for dependencies used only when building documentation:</p><pre class="programlisting">DOC_DEPS = edown</pre><p><code class="literal">REL_DEPS</code> for dependencies required to build the release, +or to include extra applications in the release:</p><pre class="programlisting">REL_DEPS = recon</pre><p>And <code class="literal">SHELL_DEPS</code> for dependencies to make available when running +the <code class="literal">make shell</code> command:</p><pre class="programlisting">SHELL_DEPS = tddreloader</pre><p>All these will be documented in more details in their respective +chapters.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_modifying_the_dependency_source_or_version"></a>7.2.1. Modifying the dependency source or version</h3></div></div></div><p>By default, Erlang.mk will look into its package index to +find the project you are looking for, if you only provide +its name. This is this case:</p><pre class="programlisting">DEPS = cowboy</pre><p>If you need a different version, you need to define another +variable. There are two ways to do this, each being useful +for different reasons.</p><p>If you simply want to change the commit number, all you +need to do is to define the <code class="literal">dep_$(DEP_NAME)_commit</code> +variable. In the case of Cowboy, this would look like this:</p><pre class="programlisting">DEPS = cowboy +dep_cowboy_commit = 2.0.0-pre.2</pre><p>Erlang.mk will use the package index to get all information +about Cowboy, except the commit number which will be overriden.</p><p>If you need to set the fetch method or repository information +too, for example because you want to use your own fork, or +simply because the project is missing from the index, you +can define the <code class="literal">dep_$(DEP_NAME)</code> variable with everything:</p><pre class="programlisting">DEPS = cowboy +dep_cowboy = git https://github.com/essen/cowboy 2.0.0-pre.2</pre><p>This will fetch Cowboy from your fork at the given commit.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_fetch_methods"></a>7.2.2. Fetch methods</h3></div></div></div><p>Erlang.mk comes with a number of different fetch methods. +You can fetch from Git, Mercurial, SVN, to name a few. +There are fetch methods that will work everywhere, and +fetch methods that will only work in a given environment.</p><p>The following table lists all existing methods:</p><div class="informaltable"><table cellpadding="4px" style="border-collapse: collapse;border-top: 3px solid #527bbd; border-bottom: 3px solid #527bbd; border-left: 3px solid #527bbd; border-right: 3px solid #527bbd; "><colgroup><col class="col_1" /><col class="col_2" /><col class="col_3" /></colgroup><thead><tr><th style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"> Name </th><th style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"> Format </th><th style="border-bottom: 1px solid #527bbd; " align="center" valign="top"> Description</th></tr></thead><tbody><tr><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"><p>git</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>git repo commit</p></td><td style="border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>Clone the Git repository and checkout the given version</p></td></tr><tr><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"><p>hg</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>hg repo commit</p></td><td style="border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>Clone the Mercurial repository and update to the given version</p></td></tr><tr><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"><p>svn</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>svn repo</p></td><td style="border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>Checkout the given SVN repository</p></td></tr><tr><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"><p>cp</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>cp path/to/repo</p></td><td style="border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>Recursively copy a local directory</p></td></tr><tr><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"><p>hex</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>hex version</p></td><td style="border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>Download the given project version from hex.pm</p></td></tr><tr><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="left" valign="top"><p>fail</p></td><td style="border-right: 1px solid #527bbd; border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>N/A</p></td><td style="border-bottom: 1px solid #527bbd; " align="center" valign="top"><p>Always fail, reserved for internal use</p></td></tr><tr><td style="border-right: 1px solid #527bbd; " align="left" valign="top"><p>legacy</p></td><td style="border-right: 1px solid #527bbd; " align="center" valign="top"><p>N/A</p></td><td style="" align="center" valign="top"><p>Legacy Erlang.mk fetcher, reserved for internal use</p></td></tr></tbody></table></div><p>The <code class="literal">git</code> and <code class="literal">hg</code> methods both have a repository and commit. +You can use any valid commit, tag or branch in that repository +for the commit value.</p><p>For example, to fetch Cowboy with tag 2.0.0-pre.2 from Git:</p><pre class="programlisting">dep_cowboy = git https://github.com/ninenines/cowboy 2.0.0-pre.2</pre><p>Or to fetch Ehsa tag 4.0.3 from Mercurial:</p><pre class="programlisting">dep_ehsa = hg https://bitbucket.org/a12n/ehsa 4.0.3</pre><p>The <code class="literal">svn</code> method only has a repository value, but that’s +simply because the SVN repository URL can also contain +the path and commit.</p><p>This would fetch an example project from the trunk:</p><pre class="programlisting">dep_ex1 = svn https://example.com/svn/trunk/project/ex1</pre><p>And this would fetch a separate example project from a +specific commit:</p><pre class="programlisting">dep_ex2 = svn svn://example.com/svn/branches/erlang-proj/ex2@264</pre><p>You can copy a directory from your machine using the <code class="literal">cp</code> method. +It only takes the path to copy from:</p><pre class="programlisting">dep_cowboy = cp $(HOME)/ninenines/cowboy</pre><p>Finally, you can use a package from the +<a class="ulink" href="https://hex.pm/" target="_top">Hex repository</a>:</p><pre class="programlisting">dep_cowboy = hex 1.0.3</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_custom_fetch_methods"></a>7.2.3. Custom fetch methods</h3></div></div></div><p>If none of the existing methods fit your use, you can simply +define your own. Erlang.mk will consider all variables that +are named as <code class="literal">dep_fetch_$(METHOD)</code> to be available fetch +methods. You can do anything inside this variable, as long +as you create a folder named <span class="emphasis"><em>$(DEPS_DIR)/$(call dep_name,$1)</em></span>. +Or in layman terms, if your dependency is Cowboy, this would +become <span class="emphasis"><em>deps/cowboy</em></span>.</p><p>To give an example, this is what the Git method does:</p><pre class="programlisting">define dep_fetch_git + git clone -q -n -- $(call dep_repo,$1) $(DEPS_DIR)/$(call dep_name,$1); \ + cd $(DEPS_DIR)/$(call dep_name,$1) && git checkout -q $(call dep_commit,$1); +endef</pre><p>Note that, like dependency information, this custom fetch method +must be written before including <span class="emphasis"><em>erlang.mk</em></span>.</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_how_deps_are_fetched_and_built"></a>7.3. How deps are fetched and built</h2></div></div></div><p>The order in which dependencies are fetched and built is well +defined. This means that Erlang.mk will get the same applications +regardless of the command or options being used.</p><p>In tree traversal terms, where the list of dependencies is a +tree, Erlang.mk fetches everything using the pre-order traversal +method. The steps can be summarized like this, starting from +the root application:</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"> +Fetch all dependencies for the application +</li><li class="listitem"> +Build first dependency +</li><li class="listitem"> +Build Nth dependency +</li><li class="listitem"> +Build last dependency +</li></ol></div><p>Every time a dependency is built, these same steps are followed, +recursively.</p><p>Do note that the first step, fetching all dependencies of +an application, is not guaranteed to be ordered. The reason +for this is that it is not possible to have the same dependency +listed twice in a single application, and therefore there can +be no conflicts. Remember, this step only fetches, at no point +are different applications built in parallel.</p><p>What about conflicts between the dependencies of different +applications? Simple. Since builds are ordered, this means +that the first version of an application that is fetched +will be the one that wins.</p><p>This means that if project A depends on projects B and C, +in this order, and that both B and C depend on a different +version of D, it will always be B’s version of D that wins, +because we fetch the dependencies of B before fetching +those from C.</p><p>Similarly, if project A depends on projects B, C and D, +regardless of the order, and A, B and C depend on a +different version of D, it will always be A’s version +that wins, because we fetch all dependencies of A before +fetching those from B or C.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_ignoring_unwanted_dependencies"></a>7.4. Ignoring unwanted dependencies</h2></div></div></div><p>Sometimes, you may want to ignore dependencies entirely. +Not even fetch them. You may want to do this because a +project you depend on depends on an application you do +not need (like a dependency for building documentation +or testing). Or maybe the dependency is already installed +on your system.</p><p>To ignore a dependency, simply add it to the <code class="literal">IGNORE_DEPS</code> +variable:</p><pre class="programlisting">IGNORE_DEPS += edown proper</pre><p>This will only ignore dependencies that are needed for +building. It is therefore safe to write:</p><pre class="programlisting">IGNORE_DEPS += edown proper +TEST_DEPS = proper</pre><p>The PropEr application will be fetched as intended when +running <code class="literal">make tests</code> or <code class="literal">make check</code>. It will however +not be fetched when running <code class="literal">make</code> or <code class="literal">make deps</code>.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_dependencies_directory"></a>7.5. Dependencies directory</h2></div></div></div><p>Dependencies are fetched in <span class="emphasis"><em>$(DEPS_DIR)</em></span>. By default this is +the <span class="emphasis"><em>deps</em></span> directory. You can change this default, but you +should only do so if it was not defined previously. Erlang.mk +uses this variable to tell dependencies where to fetch their +own dependencies.</p><p>You will therefore need to use <code class="literal">?=</code> instead of <code class="literal">=</code>. Of course, +if you know you will never use this project as a dependency, +<code class="literal">=</code> will work. But to avoid it biting you later on, do this:</p><pre class="programlisting">DEPS_DIR ?= $(CURDIR)/libs</pre><p>The <code class="literal">$(CURDIR)</code> part is important, otherwise dependencies of +dependencies will be fetched in the wrong directory.</p><p>Erlang.mk will also export the <code class="literal">REBAR_DEPS_DIR</code> variable for +compatibility with Rebar build tools, as long as they are +recent enough.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_dependencies_local_to_the_repository"></a>7.6. Dependencies local to the repository</h2></div></div></div><p>In addition to the dependencies that are fetched, Erlang.mk +also allows you to have dependencies local to your repository. +This kind of layout is sometimes called multi-application +repositories, or repositories with multiple applications.</p><p>They work exactly the same as remote dependencies, except:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> +They are not fetched +</li><li class="listitem"> +They are not autopatched +</li><li class="listitem"> +They are not deleted on <code class="literal">make distclean</code> +</li><li class="listitem"> +They are not automatically added to the application resource file +</li></ul></div><p>To properly fill the application resource file, you will +need to define the <code class="literal">LOCAL_DEPS</code> variable for each relevant +application, the same as for OTP applications.</p><p>If there is a conflict between a local dependency and a +remote dependency, then the local dependency always wins; +an error will be triggered when trying to fetch the +conflicting remote dependency.</p><p>To start using dependencies local to the repository, simply +create a folder named <span class="emphasis"><em>$(APPS_DIR)</em></span>. By default, this folder +is the <span class="emphasis"><em>apps/</em></span> directory.</p><p>You can use Erlang.mk to bootstrap local dependencies by +using the command <code class="literal">make new-app</code> or <code class="literal">make new-lib</code>. This +command will create the necessary directories and bootstrap +the application.</p><p>For example, to create a full fledged OTP application as +a local dependency:</p><pre class="programlisting">$ make new-app in=webchat</pre><p>Or, the same as an OTP library:</p><pre class="programlisting">$ make new-lib in=webchat</pre><p>Templates also work with local dependencies, from the root +directory of the project. You do need however to tell +Erlang.mk to create the files in the correct application:</p><pre class="programlisting">$ make new t=gen_server n=my_server in=webchat</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_repositories_with_no_application_at_the_root_level"></a>7.7. Repositories with no application at the root level</h2></div></div></div><p>It’s possible to use Erlang.mk with only applications in +<span class="emphasis"><em>$(APPS_DIR)</em></span>, and nothing at the root of the repository. +Just create a folder, put the <span class="emphasis"><em>erlang.mk</em></span> file in it, +write a Makefile that includes it, and start creating +your applications.</p><p>Similarly, it’s possible to have a repository with only +dependencies found in <span class="emphasis"><em>$(DEPS_DIR)</em></span>. You just need to +create a Makefile and specify the dependencies you want. +This allows you to create a repository for handling the +building of releases, for example.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_autopatch"></a>7.8. Autopatch</h2></div></div></div><p>Erlang.mk will automatically patch all the dependencies it +fetches. It needs to do this to ensure that the dependencies +become compatible with not only Erlang.mk, but also with +the version of Erlang.mk that is currently used.</p><p>When fetching a dependency, the following operations are +performed:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> +Fetch the dependency using the configured fetch method +</li><li class="listitem"> +If it contains a <span class="emphasis"><em>configure.ac</em></span> or <span class="emphasis"><em>configure.in</em></span> file, run <code class="literal">autoreconf -Wall -vif -I m4</code> +</li><li class="listitem"> +If it contains a <span class="emphasis"><em>configure</em></span> script, run it +</li><li class="listitem"> +Run autopatch on the project +</li></ul></div><p>Autopatch first checks if there is any project-specific patch +enabled. There are currently two: <code class="literal">RABBITMQ_CLIENT_PATCH</code> for +the <code class="literal">amqp_client</code> dependency, and <code class="literal">RABBITMQ_SERVER_PATCH</code> for +the <code class="literal">rabbit</code> dependency. These are needed only for RabbitMQ +versions before 3.6.0 (assuming you are using upstream RabbitMQ, +and not a fork).</p><p>Otherwise, autopatch performs different operations depending +on the kind of project it finds the dependency to be.</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> +Rebar projects are automatically converted to use Erlang.mk +as their build tool. This essentially patches Rebar out, and +fixes and converts the project to be compatible with Erlang.mk. +</li><li class="listitem"> +Erlang.mk projects have their <span class="emphasis"><em>erlang.mk</em></span> file redirect to +the top-level project’s Erlang.mk. This is to ensure that +functionality works across all dependencies, even if the +dependency’s Erlang.mk is outdated. +</li><li class="listitem"> +Other Erlang projects get a small Erlang.mk Makefile +generated automatically. +</li><li class="listitem"> +Projects with no source directory and no Makefile get an +empty Makefile generated, for compatibility purposes. +</li><li class="listitem"> +Other projects with no Makefile are left untouched. +</li></ul></div><p>You can disable the replacing of the <span class="emphasis"><em>erlang.mk</em></span> file by +defining the <code class="literal">NO_AUTOPATCH_ERLANG_MK</code> variable:</p><pre class="programlisting">NO_AUTOPATCH_ERLANG_MK = 1</pre><p>You can also disable autopatch entirely for a few select +projects using the <code class="literal">NO_AUTOPATCH</code> variable:</p><pre class="programlisting">NO_AUTOPATCH = cowboy ranch cowlib</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_skipping_deps"></a>7.9. Skipping deps</h2></div></div></div><p>It is possible to temporarily skip all dependency operations. +This is done by defining the <code class="literal">SKIP_DEPS</code> variable. Use cases +include being somewhere with no connection to download them, +or perhaps a peculiar setup.</p><p>A typical usage would be:</p><pre class="programlisting">$ make SKIP_DEPS=1</pre><p>When the variable is defined:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> +Dependencies will not be compiled or downloaded when required +</li><li class="listitem"> +The dependency directory <span class="emphasis"><em>$(DEPS_DIR)</em></span> will not be removed on <code class="literal">make distclean</code> +</li></ul></div><p>This variable only applies to remote dependencies.</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch06.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pt01.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch08.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/ch08.html b/guide/ch08.html new file mode 100644 index 0000000..27478ad --- /dev/null +++ b/guide/ch08.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="ch07.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="pt02.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a id="_compatibility_with_other_build_tools"></a>Chapter 8. Compatibility with other build tools</h2></div></div></div><p>Erlang.mk tries its best to be compatible with the other Erlang +build tools. It can use dependencies written with other build +tools in mind, and can also make your projects usable by those +build tools as well. Erlang.mk is like the cool kid that gets +along with everybody.</p><p>In this chapter I will use the term <span class="emphasis"><em>Rebar project</em></span> to refer +to a project built using Rebar 2, Rebar 3 or Mad. These three +build tools are very similar and share the same configuration +file.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_rebar_projects_as_erlang_mk_dependencies"></a>8.1. Rebar projects as Erlang.mk dependencies</h2></div></div></div><p>Erlang.mk comes with a feature called <span class="emphasis"><em>Autoload</em></span> which will +use Rebar 2 to patch any Rebar project and make it compatible +with Erlang.mk. This feature essentially patches Rebar out +and adds a Makefile to the project that Erlang.mk can then +use for building:</p><p><span class="emphasis"><em>Autoload</em></span> is documented in more details in the +<a class="ulink" href="deps.asciidoc" target="_top">Packages and dependencies</a> chapter.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_erlang_mk_projects_as_rebar_dependencies"></a>8.2. Erlang.mk projects as Rebar dependencies</h2></div></div></div><p>Erlang.mk projects can be made compatible with the Rebar family +of build tools pretty easily, as Erlang.mk will generate +all the files they require for building.</p><p>The Rebar family requires two files: a <span class="emphasis"><em>rebar.config</em></span> file +containing compilation options and the list of dependencies, +and the application resource file, found either at +<span class="emphasis"><em>ebin/$(PROJECT).app</em></span> or at <span class="emphasis"><em>src/$(PROJECT).app.src</em></span>.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_rebar_configuration"></a>8.2.1. Rebar configuration</h3></div></div></div><p>Erlang.mk comes with a target that generates a <span class="emphasis"><em>rebar.config</em></span> +file when invoked:</p><pre class="programlisting">$ make rebar.config</pre><p>Careful! This will build the file even if it already existed +before.</p><p>To build this file, Erlang.mk uses information it finds in +the <code class="literal">DEPS</code> and <code class="literal">ERLC_OPTS</code> variables, among others. This +means that the Rebar family builds your project much the +same way as Erlang.mk.</p><p>Careful though! Different build tools have different fetching +strategies. If some applications provide differing dependencies, +they might be fetched differently by other build tools. Check +the <a class="ulink" href="sanity_check.asciidoc" target="_top">Sanity check</a> chapter to find +out how to detect such issues.</p><p>You can automatically generate this file when you build +your application, by making it a dependency of the <code class="literal">app</code> +target:</p><pre class="programlisting">app:: rebar.config</pre><p>Don’t forget to commit the file when it changes!</p><p>If you run into other issues, it’s probably because you use a +feature specific to Erlang.mk, like the <code class="literal">cp</code> fetch method. +It could also be that we forgot to handle something! Sorry. +We are of course interested to hear about any compatibility +problems you may have, just open a ticket!</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_application_resource_file_2"></a>8.2.2. Application resource file</h3></div></div></div><p>Erlang.mk has two ways to generate an application resource +file: from the information found in the Makefile, or from +the information found in the <span class="emphasis"><em>src/$(PROJECT).app.src</em></span> file. +Needless to say, if you have this file in your repository, +then you don’t need to worry about compatibility with other +build tools.</p><p>If you don’t, however, it’s not much harder. Every time +Erlang.mk will compile your application, it will produce +a new <span class="emphasis"><em>ebin/$(PROJECT).app</em></span> file. Simply commit this file +when it changes. It will only change when you modify the +configuration, add or remove modules.</p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch07.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pt01.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pt02.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/ch09.html b/guide/ch09.html new file mode 100644 index 0000000..706c3bd --- /dev/null +++ b/guide/ch09.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="pt02.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="pt03.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a id="_external_plugins"></a>Chapter 9. External plugins</h2></div></div></div><p>It is often convenient to be able to keep the build files +used by all your projects in one place. Those files could +be Makefiles, configuration files, templates and more.</p><p>Erlang.mk allows you to automatically load plugins from +dependencies. Plugins can do anything, including defining +new variables, defining file templates, hooking themselves +inside the normal Erlang.mk processing or even adding new +rules.</p><p>You can load plugins using one of two methods. You can +either load all plugins from a dependency, or just one. +We will also cover conventions about writing external +plugins.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_loading_all_plugins_from_a_dependency"></a>9.1. Loading all plugins from a dependency</h2></div></div></div><p>To load plugins from a dependency, all you need to do is add +the dependency name to <code class="literal">DEP_PLUGINS</code> in addition to the list +of dependencies.</p><p>For example, if you have <code class="literal">cowboy</code> in <code class="literal">DEPS</code>, add <code class="literal">cowboy</code> in +<code class="literal">DEP_PLUGINS</code> also:</p><pre class="programlisting">DEPS = cowboy +DEP_PLUGINS = cowboy</pre><p>This will load the file <span class="emphasis"><em>plugins.mk</em></span> in the root folder of +the Cowboy repository.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_loading_one_plugin_from_a_dependency"></a>9.2. Loading one plugin from a dependency</h2></div></div></div><p>Now that we know how to load all plugins, let’s take a look +at how to load one specific plugin from a dependency.</p><p>To do this, instead of writing only the name of the dependency, +we will write its name and the path to the plugin file. This +means that writing <code class="literal">DEP_PLUGINS = cowboy</code> is equivalent to +writing <code class="literal">DEP_PLUGINS = cowboy/plugins.mk</code>.</p><p>Knowing this, if we were to load the plugin <span class="emphasis"><em>mk/dist.mk</em></span> +from Cowboy and no other, we would write the following in +our Makefile:</p><pre class="programlisting">DEPS = cowboy +DEP_PLUGINS = cowboy/mk/dist.mk</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_writing_external_plugins"></a>9.3. Writing external plugins</h2></div></div></div><p>The <span class="emphasis"><em>plugins.mk</em></span> file is a convention. It is meant to load +all the plugins from the dependency. The code for the plugin +can be written directly in <span class="emphasis"><em>plugins.mk</em></span> or be separate.</p><p>If you are providing more than one plugin with your repository, +the recommended way is to create one file per plugin in the +<span class="emphasis"><em>mk/</em></span> folder in your repository, and then include those +individual plugins in <span class="emphasis"><em>plugins.mk</em></span>.</p><p>For eaxmple, if you have two plugins <span class="emphasis"><em>mk/dist.mk</em></span> and +<span class="emphasis"><em>mk/templates.mk</em></span>, you could write the following <span class="emphasis"><em>plugins.mk</em></span> +file:</p><pre class="programlisting">THIS := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) +include $(THIS)/mk/dist.mk +include $(THIS)/mk/templates.mk</pre><p>The <code class="literal">THIS</code> variable is required to relatively include files.</p><p>This allows users to not only be able to select individual +plugins, but also select all plugins from the dependency +in one go if they wish to do so.</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pt02.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pt02.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pt03.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/ch10.html b/guide/ch10.html new file mode 100644 index 0000000..807c08b --- /dev/null +++ b/guide/ch10.html @@ -0,0 +1,75 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="pt03.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> </td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a id="_why_erlang_mk"></a>Chapter 10. Why Erlang.mk</h2></div></div></div><p>Why would you choose Erlang.mk, if not for its +<a class="ulink" href="overview.asciidoc" target="_top">many features</a>? This chapter will +attempt to answer that.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_erlang_mk_is_fast"></a>10.1. Erlang.mk is fast</h2></div></div></div><p>Erlang.mk is as fast as it gets.</p><p>Erlang.mk will group the compilation of files so as to avoid +running the BEAM more than necessary. This saves many seconds +compared to traditional Makefiles, even on small projects.</p><p>Erlang.mk will not try to be too smart. It provides a simple +solution that works for most people, and gives additional +options for projects that run into edge cases, often in the +form of extra variables or rules to be defined.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_erlang_mk_gives_you_the_full_power_of_unix"></a>10.2. Erlang.mk gives you the full power of Unix</h2></div></div></div><p>Erlang.mk is a Makefile.</p><p>You could use Erlang.mk directly without configuring anything +and it would just work. But you can also extend it greatly +either through configuration or hooks, and you can of course +add your own rules to the Makefile.</p><p>In all cases: for configuration, hooks or custom rules, you +have all the power of Unix at your disposal, and can call +any utility <span class="emphasis"><em>or even any language interpreter</em></span> you want, +every time you need to. Erlang.mk also allows you to write +scripts in this small language called Erlang directly inside +your Makefile if you ever need to…</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_erlang_mk_is_a_text_file"></a>10.3. Erlang.mk is a text file</h2></div></div></div><p>Erlang.mk is a Makefile.</p><p>Which means Erlang.mk is a simple text file. You can edit a +text file. Nothing stops you. If you run into any bug, or +behavior that does not suit you, you can just open the +<span class="emphasis"><em>erlang.mk</em></span> file in your favorite editor, fix and/or comment +a few lines, save, and try again. It’s as simple as it gets.</p><p>Currently using a binary build tool? Good luck with that.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_erlang_mk_can_manage_erlang_itself"></a>10.4. Erlang.mk can manage Erlang itself</h2></div></div></div><p>Erlang.mk isn’t written in Erlang.</p><p>That’s not a good thing, you say? Well, here’s one thing +that Erlang.mk and Makefiles can do for you that Erlang +build tool can’t easily: choose what version of Erlang is +to be used for compiling the project.</p><p>This really is a one-liner in Erlang.mk (a few more lines +if you also let it download about build Erlang directly) +and allows for even greater things, like testing your +project across all supported Erlang versions in one small +command: <code class="literal">make -k ci</code>.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_erlang_mk_can_do_more_than_erlang"></a>10.5. Erlang.mk can do more than Erlang</h2></div></div></div><p>Erlang.mk doesn’t care what your dependencies are written in.</p><p>Erlang.mk will happily compile any dependency, as long as +they come with a Makefile. The dependency can be written +in C, C++ or even Javascript… Who cares, really? If you +need Erlang.mk to fetch it, then Erlang.mk will fetch it +and compile it as needed.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_erlang_mk_integrates_nicely_in_make_and_automake_projects"></a>10.6. Erlang.mk integrates nicely in Make and Automake projects</h2></div></div></div><p>If you are planning to put your project in the middle of +a Make or Automake-based build environment, then the most +logical thing to do is to use a Makefile.</p><p>Erlang.mk will happily sit in such an environment and behave +as you expect it to.</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pt03.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pt03.html">Up</a></td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/index.html b/guide/index.html new file mode 100644 index 0000000..56731fa --- /dev/null +++ b/guide/index.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch01.html">Next</a></td></tr></table><hr /></div><div xml:lang="en" class="book" lang="en"><div class="titlepage"><div><div><h1 class="title"><a id="idm140165634858256"></a>Erlang.mk User Guide</h1></div><div><div class="author"><h3 class="author"><span class="firstname">Loïc</span> <span class="surname">Hoguin</span></h3><code class="email"><<a class="email" href="mailto:[email protected]">[email protected]</a>></code></div></div></div><hr /></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="chapter"><a href="ch01.html">1. Installation</a></span></dt><dd><dl><dt><span class="section"><a href="ch01.html#_on_unix">1.1. On Unix</a></span></dt><dt><span class="section"><a href="ch01.html#_on_windows">1.2. On Windows</a></span></dt></dl></dd><dt><span class="chapter"><a href="ch02.html">2. Getting started</a></span></dt><dd><dl><dt><span class="section"><a href="ch02.html#_creating_a_folder_for_your_project">2.1. Creating a folder for your project</a></span></dt><dt><span class="section"><a href="ch02.html#_downloading_erlang_mk">2.2. Downloading Erlang.mk</a></span></dt><dt><span class="section"><a href="ch02.html#_getting_started_with_otp_applications">2.3. Getting started with OTP applications</a></span></dt><dt><span class="section"><a href="ch02.html#_getting_started_with_otp_libraries">2.4. Getting started with OTP libraries</a></span></dt><dt><span class="section"><a href="ch02.html#_getting_started_with_otp_releases">2.5. Getting started with OTP releases</a></span></dt><dt><span class="section"><a href="ch02.html#_using_templates">2.6. Using templates</a></span></dt><dt><span class="section"><a href="ch02.html#_getting_help">2.7. Getting help</a></span></dt></dl></dd><dt><span class="chapter"><a href="ch03.html">3. Overview</a></span></dt><dd><dl><dt><span class="section"><a href="ch03.html#_building_your_project">3.1. Building your project</a></span></dt><dt><span class="section"><a href="ch03.html#_exploring_the_package_index">3.2. Exploring the package index</a></span></dt><dt><span class="section"><a href="ch03.html#_generating_documentation">3.3. Generating documentation</a></span></dt><dt><span class="section"><a href="ch03.html#_running_tests">3.4. Running tests</a></span></dt><dt><span class="section"><a href="ch03.html#_need_more">3.5. Need more?</a></span></dt></dl></dd><dt><span class="chapter"><a href="ch04.html">4. Updating Erlang.mk</a></span></dt><dd><dl><dt><span class="section"><a href="ch04.html#_initial_bootstrap">4.1. Initial bootstrap</a></span></dt><dt><span class="section"><a href="ch04.html#_updating">4.2. Updating</a></span></dt><dt><span class="section"><a href="ch04.html#_customizing_the_build">4.3. Customizing the build</a></span></dt></dl></dd><dt><span class="chapter"><a href="ch05.html">5. Limitations</a></span></dt><dd><dl><dt><span class="section"><a href="ch05.html#_erlang_must_be_available">5.1. Erlang must be available</a></span></dt><dt><span class="section"><a href="ch05.html#_spaces_in_path">5.2. Spaces in path</a></span></dt><dt><span class="section"><a href="ch05.html#_dependency_tracking_and_modification_times">5.3. Dependency tracking and modification times</a></span></dt></dl></dd><dt><span class="part"><a href="pt01.html">I. Code</a></span></dt><dd><dl><dt><span class="chapter"><a href="ch06.html">6. Building</a></span></dt><dd><dl><dt><span class="section"><a href="ch06.html#_how_to_build">6.1. How to build</a></span></dt><dt><span class="section"><a href="ch06.html#_what_to_build">6.2. What to build</a></span></dt><dt><span class="section"><a href="ch06.html#_application_resource_file">6.3. Application resource file</a></span></dt><dt><span class="section"><a href="ch06.html#_automatic_application_resource_file_values">6.4. Automatic application resource file values</a></span></dt><dt><span class="section"><a href="ch06.html#_file_formats">6.5. File formats</a></span></dt><dt><span class="section"><a href="ch06.html#_compilation_options">6.6. Compilation options</a></span></dt><dt><span class="section"><a href="ch06.html#_cold_and_hot_builds">6.7. Cold and hot builds</a></span></dt><dt><span class="section"><a href="ch06.html#_dependency_tracking">6.8. Dependency tracking</a></span></dt><dt><span class="section"><a href="ch06.html#_generating_erlang_source">6.9. Generating Erlang source</a></span></dt><dt><span class="section"><a href="ch06.html#_cleaning">6.10. Cleaning</a></span></dt></dl></dd><dt><span class="chapter"><a href="ch07.html">7. Packages and dependencies</a></span></dt><dd><dl><dt><span class="section"><a href="ch07.html#_searching_packages">7.1. Searching packages</a></span></dt><dt><span class="section"><a href="ch07.html#_adding_dependencies_to_your_project">7.2. Adding dependencies to your project</a></span></dt><dt><span class="section"><a href="ch07.html#_how_deps_are_fetched_and_built">7.3. How deps are fetched and built</a></span></dt><dt><span class="section"><a href="ch07.html#_ignoring_unwanted_dependencies">7.4. Ignoring unwanted dependencies</a></span></dt><dt><span class="section"><a href="ch07.html#_dependencies_directory">7.5. Dependencies directory</a></span></dt><dt><span class="section"><a href="ch07.html#_dependencies_local_to_the_repository">7.6. Dependencies local to the repository</a></span></dt><dt><span class="section"><a href="ch07.html#_repositories_with_no_application_at_the_root_level">7.7. Repositories with no application at the root level</a></span></dt><dt><span class="section"><a href="ch07.html#_autopatch">7.8. Autopatch</a></span></dt><dt><span class="section"><a href="ch07.html#_skipping_deps">7.9. Skipping deps</a></span></dt></dl></dd><dt><span class="chapter"><a href="ch08.html">8. Compatibility with other build tools</a></span></dt><dd><dl><dt><span class="section"><a href="ch08.html#_rebar_projects_as_erlang_mk_dependencies">8.1. Rebar projects as Erlang.mk dependencies</a></span></dt><dt><span class="section"><a href="ch08.html#_erlang_mk_projects_as_rebar_dependencies">8.2. Erlang.mk projects as Rebar dependencies</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="pt02.html">II. Advanced</a></span></dt><dd><dl><dt><span class="chapter"><a href="ch09.html">9. External plugins</a></span></dt><dd><dl><dt><span class="section"><a href="ch09.html#_loading_all_plugins_from_a_dependency">9.1. Loading all plugins from a dependency</a></span></dt><dt><span class="section"><a href="ch09.html#_loading_one_plugin_from_a_dependency">9.2. Loading one plugin from a dependency</a></span></dt><dt><span class="section"><a href="ch09.html#_writing_external_plugins">9.3. Writing external plugins</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="pt03.html">III. About Erlang.mk</a></span></dt><dd><dl><dt><span class="chapter"><a href="ch10.html">10. Why Erlang.mk</a></span></dt><dd><dl><dt><span class="section"><a href="ch10.html#_erlang_mk_is_fast">10.1. Erlang.mk is fast</a></span></dt><dt><span class="section"><a href="ch10.html#_erlang_mk_gives_you_the_full_power_of_unix">10.2. Erlang.mk gives you the full power of Unix</a></span></dt><dt><span class="section"><a href="ch10.html#_erlang_mk_is_a_text_file">10.3. Erlang.mk is a text file</a></span></dt><dt><span class="section"><a href="ch10.html#_erlang_mk_can_manage_erlang_itself">10.4. Erlang.mk can manage Erlang itself</a></span></dt><dt><span class="section"><a href="ch10.html#_erlang_mk_can_do_more_than_erlang">10.5. Erlang.mk can do more than Erlang</a></span></dt><dt><span class="section"><a href="ch10.html#_erlang_mk_integrates_nicely_in_make_and_automake_projects">10.6. Erlang.mk integrates nicely in Make and Automake projects</a></span></dt></dl></dd></dl></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ch01.html">Next</a></td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/pt01.html b/guide/pt01.html new file mode 100644 index 0000000..53b1c8d --- /dev/null +++ b/guide/pt01.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="ch05.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch06.html">Next</a></td></tr></table><hr /></div><div class="part"><div class="titlepage"><div><div><h1 class="title"><a id="_code"></a>Part I. Code</h1></div></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch05.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ch06.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/pt02.html b/guide/pt02.html new file mode 100644 index 0000000..c84cede --- /dev/null +++ b/guide/pt02.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="ch08.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch09.html">Next</a></td></tr></table><hr /></div><div class="part"><div class="titlepage"><div><div><h1 class="title"><a id="_advanced"></a>Part II. Advanced</h1></div></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch08.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ch09.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> diff --git a/guide/pt03.html b/guide/pt03.html new file mode 100644 index 0000000..73ffdf0 --- /dev/null +++ b/guide/pt03.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"/> +<title>Erlang.mk</title> +<style type="text/css"><!-- +body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px} +header {align-items:center;display:flex;justify-content:center} +header nav.left{text-align:right;width:150px} +header nav.right{text-align:left;width:150px} +header nav a{display:block;margin:1.5em 1em} +main{margin-top:2em;text-align:justify} +main h2, main h3{margin-top:2em} +a{color:#d9230f;text-decoration:none} +a:hover{text-decoration:underline} +h1, h2, h3{font-weight:normal} +h1 a{color:black} +h1 a:hover{color:#d9230f;text-decoration:none} +span.var{color:teal} +span.op{color:maroon} +span.dir{color:purple} +div.navfooter{margin-bottom:1em} +--></style> +</head> +<body> +<header> + <nav class="left"> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc">User guide</a> + <a href="https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/getting_started.asciidoc">Tutorials</a> + </nav> + <a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a> + <nav class="right"> + <a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a> + <a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a> + </nav> +</header> +<main> + +<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="ch09.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch10.html">Next</a></td></tr></table><hr /></div><div class="part"><div class="titlepage"><div><div><h1 class="title"><a id="_about_erlang_mk"></a>Part III. About Erlang.mk</h1></div></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch09.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ch10.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div> +</main> +</body> +</html> |