From 6e4fcfabb728dfa2114a4076a4d8247caf25fe09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Tue, 29 Dec 2015 00:29:21 +0100 Subject: Update user guide --- guide/about.html | 37 ++++++ guide/asciidoc.html | 37 ++++++ guide/building.html | 223 ++++++++++++++++++++++++++++++++++++ guide/ch01.html | 80 ------------- guide/ch02.html | 164 --------------------------- guide/ch03.html | 72 ------------ guide/ch04.html | 69 ----------- guide/ch05.html | 55 --------- guide/ch06.html | 223 ------------------------------------ guide/ch07.html | 233 -------------------------------------- guide/ch08.html | 99 ---------------- guide/ch09.html | 56 --------- guide/ch10.html | 37 ------ guide/ch11.html | 78 ------------- guide/ch12.html | 37 ------ guide/ch13.html | 37 ------ guide/ch14.html | 46 -------- guide/ch15.html | 75 ------------ guide/ch16.html | 37 ------ guide/ch17.html | 37 ------ guide/ch18.html | 37 ------ guide/ch19.html | 37 ------ guide/ch20.html | 66 ----------- guide/ch21.html | 37 ------ guide/ch22.html | 69 ----------- guide/ch23.html | 70 ------------ guide/ch24.html | 67 ----------- guide/ch25.html | 86 -------------- guide/ci.html | 37 ++++++ guide/code.html | 37 ++++++ guide/compat.html | 78 +++++++++++++ guide/contributing.html | 86 ++++++++++++++ guide/coverage.html | 37 ++++++ guide/ct.html | 60 ++++++++++ guide/deps.html | 233 ++++++++++++++++++++++++++++++++++++++ guide/dialyzer.html | 66 +++++++++++ guide/docs.html | 37 ++++++ guide/edoc.html | 37 ++++++ guide/escript.html | 37 ++++++ guide/eunit.html | 75 ++++++++++++ guide/getting_started.html | 164 +++++++++++++++++++++++++++ guide/history.html | 67 +++++++++++ guide/index.html | 2 +- guide/installation.html | 80 +++++++++++++ guide/limitations.html | 55 +++++++++ guide/overview.html | 72 ++++++++++++ guide/plugins.html | 37 ++++++ guide/plugins_usage.html | 69 +++++++++++ guide/ports.html | 99 ++++++++++++++++ guide/property_based_testing.html | 37 ++++++ guide/pt01.html | 37 ------ guide/pt02.html | 37 ------ guide/pt03.html | 37 ------ guide/pt04.html | 37 ------ guide/pt05.html | 37 ------ guide/relx.html | 56 +++++++++ guide/shell.html | 46 ++++++++ guide/tests.html | 37 ++++++ guide/updating.html | 69 +++++++++++ guide/why.html | 70 ++++++++++++ guide/xref.html | 37 ++++++ 61 files changed, 2113 insertions(+), 2090 deletions(-) create mode 100644 guide/about.html create mode 100644 guide/asciidoc.html create mode 100644 guide/building.html delete mode 100644 guide/ch01.html delete mode 100644 guide/ch02.html delete mode 100644 guide/ch03.html delete mode 100644 guide/ch04.html delete mode 100644 guide/ch05.html delete mode 100644 guide/ch06.html delete mode 100644 guide/ch07.html delete mode 100644 guide/ch08.html delete mode 100644 guide/ch09.html delete mode 100644 guide/ch10.html delete mode 100644 guide/ch11.html delete mode 100644 guide/ch12.html delete mode 100644 guide/ch13.html delete mode 100644 guide/ch14.html delete mode 100644 guide/ch15.html delete mode 100644 guide/ch16.html delete mode 100644 guide/ch17.html delete mode 100644 guide/ch18.html delete mode 100644 guide/ch19.html delete mode 100644 guide/ch20.html delete mode 100644 guide/ch21.html delete mode 100644 guide/ch22.html delete mode 100644 guide/ch23.html delete mode 100644 guide/ch24.html delete mode 100644 guide/ch25.html create mode 100644 guide/ci.html create mode 100644 guide/code.html create mode 100644 guide/compat.html create mode 100644 guide/contributing.html create mode 100644 guide/coverage.html create mode 100644 guide/ct.html create mode 100644 guide/deps.html create mode 100644 guide/dialyzer.html create mode 100644 guide/docs.html create mode 100644 guide/edoc.html create mode 100644 guide/escript.html create mode 100644 guide/eunit.html create mode 100644 guide/getting_started.html create mode 100644 guide/history.html create mode 100644 guide/installation.html create mode 100644 guide/limitations.html create mode 100644 guide/overview.html create mode 100644 guide/plugins.html create mode 100644 guide/plugins_usage.html create mode 100644 guide/ports.html create mode 100644 guide/property_based_testing.html delete mode 100644 guide/pt01.html delete mode 100644 guide/pt02.html delete mode 100644 guide/pt03.html delete mode 100644 guide/pt04.html delete mode 100644 guide/pt05.html create mode 100644 guide/relx.html create mode 100644 guide/shell.html create mode 100644 guide/tests.html create mode 100644 guide/updating.html create mode 100644 guide/why.html create mode 100644 guide/xref.html diff --git a/guide/about.html b/guide/about.html new file mode 100644 index 0000000..94433a3 --- /dev/null +++ b/guide/about.html @@ -0,0 +1,37 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Part V. About Erlang.mk

+
+ + diff --git a/guide/asciidoc.html b/guide/asciidoc.html new file mode 100644 index 0000000..b7bdb86 --- /dev/null +++ b/guide/asciidoc.html @@ -0,0 +1,37 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 12. Asciidoc documentation

Placeholder chapter.

+
+ + diff --git a/guide/building.html b/guide/building.html new file mode 100644 index 0000000..903cc9f --- /dev/null +++ b/guide/building.html @@ -0,0 +1,223 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 6. Building

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.

For most of this chapter, we will assume that you are +using a project generated by Erlang.mk.

6.1. How to build

To build a project, all you have to do is type make:

$ make

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.

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.

6.2. What to build

Erlang.mk gives you control over three steps of the build +process, allowing you to do a partial build if needed.

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.

Erlang.mk handles those three phases automatically when you +type make. But sometimes you just want to repeat one or +two of them.

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.

6.2.1. Application

You can build your application and dependencies without +generating a release by running the following command:

$ make app

To build your application without touching dependencies +at all, you can use the SKIP_DEPS variable:

$ make app SKIP_DEPS=1

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.

Note that this command may fail if a required dependency +is missing.

6.2.2. Dependencies

You can build all dependencies, and nothing else, by +running the following command:

$ make deps

This will fetch and compile all dependencies and their +dependencies, recursively.

Packages and dependencies are covered +in the next chapter.

6.2.3. Release

It is not possible to build the release without at least +building the application itself, unless of course if there’s +no application to begin with.

To generate the release, make will generally suffice with +a normal Erlang.mk. A separate target is however available, +and will take care of building the release, after building +the application and all dependencies:

$ make rel

Consult the Releases chapter for more +information about what releases are and how they are generated.

6.3. Application resource file

When building your application, Erlang.mk will generate the +application resource file. +This file is mandatory for all Erlang applications and is +found in ebin/$(PROJECT).app.

PROJECT is a variable defined in your Makefile and taken +from the name of the directory when Erlang.mk bootstraps +your project.

Erlang.mk can build the ebin/$(PROJECT).app in two different +ways: from the configuration found in the Makefile, or from +the src/$(PROJECT).app.src file.

6.3.1. Application configuration

Erlang.mk automatically fills the PROJECT 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.

+PROJECT +
+ The name of the OTP application or library. +
+PROJECT_DESCRIPTION +
+ Short description of the project. +
+PROJECT_VERSION +
+ Current version of the project. +
+PROJECT_REGISTERED +
+ List of the names of all registered processes. +
+LOCAL_DEPS +
+ List of Erlang/OTP applications this project depends on, + excluding erts, kernel and stdlib, or list of + dependencies local to this repository (in APPS_DIR). +
+DEPS +
+ List of applications this project depends on that need + to be fetched by Erlang.mk. +

There’s no need for quotes or anything. The relevant part of +the Cowboy Makefile follows, if you need an example:

PROJECT = cowboy
+PROJECT_DESCRIPTION = Small, fast, modular HTTP server.
+PROJECT_VERSION = 2.0.0-pre.2
+PROJECT_REGISTERED = cowboy_clock
+
+LOCAL_DEPS = crypto
+DEPS = cowlib ranch

Any space before and after the value is dropped.

Dependencies are covered in details in +the next chapter.

6.3.2. Legacy method

The src/$(PROJECT).app.src file is a legacy method of +building Erlang applications. It was introduced by the original +rebar build tool, of which Erlang.mk owes a great deal as it +is its main inspiration.

The .app.src file serves as a template to generate the .app +file. Erlang.mk will take it, fill in the modules value +dynamically, and save the result in ebin/$(PROJECT).app.

When using this method, Erlang.mk cannot fill the applications +key from dependencies automatically, which means you need to +add them to Erlang.mk and to the .app.src at the same time, +duplicating the work.

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:

$ make -f erlang.mk bootstrap-lib LEGACY=1

6.4. Automatic application resource file values

When building the application resource file, Erlang.mk may +automatically add an id key with information about the +Git commit (if using Git), or an empty string otherwise. +It will only do this under specific conditions:

  • +The application was built as a dependency of another, or +
  • +The legacy method was used, and the .app.src file contained {id, "git"} +

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:

1> application:get_all_key(cowboy).
+{ok,[{description,"Small, fast, modular HTTP server."},
+     {id,"2.0.0-pre.2-25-g0ffde50-dirty"},

6.5. File formats

Erlang.mk supports a variety of different source file formats. +The following formats are supported natively:

Extension Location Description Output

.erl

src/

Erlang source

ebin/*.beam

.core

src/

Core Erlang source

ebin/*.beam

.xrl

src/

Leex source

src/*.erl

.yrl

src/

Yecc source

src/*.erl

.asn1

asn1/

ASN.1 files

include/.hrl include/.asn1db src/*.erl

.mib

mibs/

SNMP MIB files

include/.hrl priv/mibs/.bin

Files are always searched recursively.

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.

In addition, Erlang.mk keeps track of header files (.hrl) +as described at the end of this chapter. It can also compile +C code, as described in the NIFs and port drivers +chapter.

Erlang.mk also comes with plugins for the following formats:

Extension Location Description Output

.dtl

templates/

Django templates

ebin/*.beam

.proto

src/

Protocol buffers

ebin/*.beam

6.6. Compilation options

Erlang.mk provides a few variables that you can use to customize +the build process and the resulting files.

6.6.1. ERLC_OPTS

ERLC_OPTS can be used to pass some options to erlc, the Erlang +compiler. Erlang.mk does not restrict any option. Please refer to +the erlc Manual for the +full list.

By default, Erlang.mk will set the following options:

ERLC_OPTS = -Werror +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard

In other words: warnings as errors, debug info (recommended) and +enable warnings for exported variables, shadow variables and +obsolete guard functions.

You can redefine this variable in your Makefile to change it +completely, either before or after including Erlang.mk:

ERLC_OPTS = +debug_info

You can also filter out some options from the defaults Erlang.mk +sets, by defining ERLC_OPTS after including Erlang.mk using the +:= operator.

include erlang.mk
+
+ERLC_OPTS := $(filter-out -Werror,$(ERLC_OPTS))

6.6.2. ERLC_EXCLUDE

ERLC_EXCLUDE can be used to exclude some modules from the +compilation. It’s there for handling special cases, you should +not normally need it.

To exclude a module, simply list it in the variable, either +before or after including Erlang.mk:

ERLC_EXCLUDE = cowboy_http2

6.7. Cold and hot builds

The first time you run make, Erlang.mk will build everything.

The second time you run make, 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.

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.

Note that this applies only to building; some other features of +Erlang.mk will run every time they are called regardless of files +changed.

6.8. Dependency tracking

Note

This section is about the dependency tracking between files +inside your project, not application dependencies.

Erlang.mk keeps track of the dependencies between the different +files in your project. This information is kept in the $(PROJECT).d +file in your directory. It is generated if missing, and will be +generated again after every file change, by default.

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.

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 Makefile:

NO_MAKEDEP ?= 1

As you can see, the snippet above uses ?= 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:

$ NO_MAKEDEP= make

Otherwise, make clean app will of course force the +recompilation of your project.

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.

6.9. Generating Erlang source

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 erlang.mk file.

The easiest way is after:

PROJECT = example
+
+include erlang.mk
+
+$(PROJECT).d:: src/generated_mod.erl
+
+src/generated_mod.erl:: gen-mod.sh
+    $(gen_verbose) ./gen-mod.sh $@

In this case we use $(gen_verbose) to hide the details of +the build by default. Erlang.mk will simply say what file +is it currently generating.

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.

If for whatever reason you prefer to hook before including +Erlang.mk, don’t forget to set the .DEFAULT_GOAL variable, +otherwise nothing will get built:

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 $@

6.10. Cleaning

Building typically involves creating a lot of new files. Some +are reused in rebuilds, some are simply replaced. All can be +removed safely.

Erlang.mk provides two commands to remove them: clean and +distclean. clean 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. +distclean 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.

To clean:

$ make clean

Or distclean:

$ make distclean

That is the question.

Note that Erlang.mk will automatically clean some files as +part of other targets, but it will never run distclean if +you don’t explicitly use it.

+
+ + diff --git a/guide/ch01.html b/guide/ch01.html deleted file mode 100644 index da70bee..0000000 --- a/guide/ch01.html +++ /dev/null @@ -1,80 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 1. Installation

This chapter explains how to setup your system in -order to use Erlang.mk.

1.1. On Unix

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.

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.

Erlang.mk currently requires Erlang/OTP to be installed in -order to compile Erlang projects.

Some packages may require additional libraries.

1.2. On Windows

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.

The rest of this section details how to setup Erlang/OTP and -MSYS2 in order to use Erlang.mk.

1.2.1. Installing Erlang/OTP

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 official download page. -It is recommended that you use the 64-bit installer unless -technically impossible. Please follow the instructions from -the installer to complete the installation.

The OTP team also provides a short guide to -installing Erlang/OTP on Windows -if you need additional references.

You can install Erlang/OTP silently using the /S switch -on the command line:

C:\Users\essen\Downloads> otp_win64_18.0.exe /S

1.2.2. Installing MSYS2

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, pacman.

The MSYS2 project provides a one click installer -and instructions to set things up post-installation.

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 -7zip to decompress it.

First, download the -MSYS2 base archive -and extract it under C:\. Assuming you downloaded the -archive as msys2.tar.xz and put it in C:\, you can -use the following commands to extract it:

C:\> 7z x msys2.tar.xz
-C:\> 7z x msys2.tar > NUL

Then you can run the two commands needed to perform the -post-installation setup:

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"

1.2.3. Installing the required MSYS2 packages

After following these instructions, you can install GNU Make, -Git and any other required softwares. From an MSYS2 shell, -you can call pacman directly:

$ pacman -S git make

You can use pacman -Ss to search packages. For example, -to find all packages related to GCC:

$ pacman -Ss gcc

If you are going to compile C/C++ code, you will need to -install this package, as Erlang.mk cannot use the normal -"gcc" package:

$ pacman -S mingw-w64-x86_64-gcc

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:

C:\> C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S git make"

You can use similar bash commands if you need to run programs -inside the MSYS2 environment from a batch file.

1.2.4. Gotchas

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.

-
- - diff --git a/guide/ch02.html b/guide/ch02.html deleted file mode 100644 index 9a31c26..0000000 --- a/guide/ch02.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 2. Getting started

This chapter explains how to get started using Erlang.mk.

2.1. Creating a folder for your project

The first step is always to create a new folder that will -contain your project.

$ mkdir hello_joe
-$ cd hello_joe

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 $HOME/ninenines/cowboy for -the Cowboy project.

2.2. Downloading Erlang.mk

At the time of writing, Erlang.mk is unlikely to be present -in your Erlang distribution, or even in your OS packages.

The next step is therefore to download it:

$ wget https://raw.githubusercontent.com/ninenines/erlang.mk/master/erlang.mk

Or:

$ curl https://raw.githubusercontent.com/ninenines/erlang.mk/master/erlang.mk

Alternatively, just click on this link.

Make sure you put the file inside the folder we created previously.

2.3. Getting started with OTP applications

An OTP application is an Erlang application that has a supervision -tree. In other words, it will always have processes running.

This kind of project can be automatically generated by Erlang.mk. -All you need to do is use the bootstrap target:

$ make -f erlang.mk bootstrap

Something similar to the following snippet will then appear -on your screen:

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

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 -Updating Erlang.mk chapter for more -information.

Of course, the generated project can now be compiled:

$ make

Cheers!

2.4. Getting started with OTP libraries

An OTP library is an Erlang application that has no supervision -tree. In other words, it is nothing but modules.

This kind of project can also be generated by Erlang.mk, using -the bootstrap-lib target:

$ make -f erlang.mk bootstrap-lib

Erlang.mk will once again bootstrap itself and generate all -the files for your project. You can now compile it:

$ make

Enjoy!

2.5. Getting started with OTP releases

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.

Erlang.mk can of course bootstrap your project to generate releases. -You can use the bootstrap-rel target for this purpose:

$ make bootstrap-rel

This target can be combined with bootstrap or bootstrap-lib to -create a project that will build a release:

$ make -f erlang.mk bootstrap-lib bootstrap-rel

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 Packages and dependencies -chapter for more information.

When you run make from now on, Erlang.mk will compile your -project and build the release:

$ 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!

The first time you run this command, Erlang.mk will download -relx, the release building tool. So don’t worry if you see -more output than above.

If building the release is slow, no need to upgrade your -hardware just yet. Just consult the Releases -chapter for various tips to speed up build time during -development.

You can start the release using the ./_rel/hello_joe_release/bin/hello_joe_release -script, or simply run make run. The latter will also compile -your project and build the release if it wasn’t already:

$ 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)
-(hello_joe@127.0.0.1)1>

Simple as that!

2.6. Using spaces instead of tabs

Erlang.mk defaults to tabs when creating files from templates. -This is in part because of a personal preference, and in part -because it is much easier to convert tabs to spaces than the -opposite.

Use the SP variable if you prefer spaces. Set it to the number -of spaces per indentation level you want.

For example, if you prefer two spaces per indentation level:

$ make -f erlang.mk bootstrap SP=2

When you bootstrap the project initially, the variable automatically -gets added to the Makefile, so you only need to provide it when -you get started.

2.7. Using templates

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!

You can list all available templates with the list-templates -target:

$ make list-templates
-Available templates: cowboy_http cowboy_loop cowboy_rest cowboy_ws gen_fsm gen_server ranch_protocol supervisor

To generate a module, let’s say a gen_server, all you need to -do is to call make new with the appropriate arguments:

$ make new t=gen_server n=my_server

This will create a module located in src/my_server.erl -using the gen_server template.

This module is automatically compiled the next time you run -make:

$ make
- ERLC   my_server.erl
- APP    hello_joe.app.src

All that’s left to do is to open it in your favorite editor -and make it do something!

2.8. Getting help

During development, if you don’t remember the name of a target, -you can always run make help:

$ 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 <essen@ninenines.eu>
-
-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
-...

This guide should provide any other answer. If not, please -open a ticket on the official repository -and we will work on improving the guide.

Commercial support is available through Nine Nines. Please contact -Loïc Hoguin by sending an email to contact@ninenines.eu.

-
- - diff --git a/guide/ch03.html b/guide/ch03.html deleted file mode 100644 index 861748e..0000000 --- a/guide/ch03.html +++ /dev/null @@ -1,72 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 3. Overview

Now that you know how to get started, let’s take a look at -what Erlang.mk can do for you.

3.1. Building your project

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.

Erlang.mk will happily build all Erlang-specific files -you throw at it. Other kinds of files too, like C or C++ code -when you are working on a NIF or a port driver.

Erlang.mk embraces the concept of source dependencies. -It can fetch dependency source code using a variety of mechanisms, -including fetching from Git, Mercurial or SVN.

Erlang.mk will automatically generate releases -when applicable. It can also generate escripts.

3.2. Exploring the package index

Erlang.mk comes with a built-in package index. -It is built as an extension of the dependency system and is -meant to be used for discovery purposes.

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.

You can get a list of all packages known to Erlang.mk by using -the search target:

$ make search

You can also use this target to search across all packages, for -example to find all packages related to Cowboy:

$ make search q=cowboy

3.3. Generating documentation

Erlang.mk supports EDoc and Asciidoc.

EDoc generates HTML documentation directly from -your source code.

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 Asciidoc comes in.

The Asciidoc 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 doc/src/ folder in -your repository.

3.4. Running tests

Erlang.mk supports a lot of different testing and static -analysis tools.

The make shell command allows you -to test your project manually. You can automate these -unit tests with EUnit and test -your entire system with Common Test. -Property based testing -with Triq is a strong alternative to writing unit tests -manually. Code coverage can of course -be enabled during tests.

Erlang.mk comes with features to make your life easier when -setting up and using Continuous integration.

On the static analysis side of things, Erlang.mk comes with -support for Dialyzer, Xref -and Elvis, performing success typing -analysis, cross reference and style reviewing.

3.5. Need more?

Not convinced yet? You can read about why you should use Erlang.mk -and its history. 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.

-
- - diff --git a/guide/ch04.html b/guide/ch04.html deleted file mode 100644 index c2e8e70..0000000 --- a/guide/ch04.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 4. Updating Erlang.mk

This chapter describes how to update the erlang.mk file -in your repository.

4.1. Initial bootstrap

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.

4.2. Updating

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.

That’s why updating Erlang.mk is so simple. All you need -to do is to call make erlang-mk:

$ 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

All that’s left to do is to commit the file!

Yep, it’s that easy.

4.3. Customizing the build

Erlang.mk allows you to customize which plugins are to be included -in the erlang.mk file. You can do so by maintaining your own -build.config file in your repository. Erlang.mk will automatically -use it the next time you run make erlang-mk.

The build.config file contains the list of all files that will -be built into the resulting erlang.mk file. You can start from -the most recent version -and customize to your needs.

You can also name the file differently or put it in a separate folder -by modifying the value for ERLANG_MK_BUILD_CONFIG. You can also -tell Erlang.mk to use a different temporary directory by changing -the ERLANG_MK_BUILD_DIR variable.

-
- - diff --git a/guide/ch05.html b/guide/ch05.html deleted file mode 100644 index 79849a6..0000000 --- a/guide/ch05.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 5. Limitations

No software is perfect.

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.

This chapter lists all known limitations of Erlang.mk.

5.1. Erlang must be available

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.

In addition, the Erlang being used must be in your $PATH -before you use Erlang.mk.

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 make ci, so doing this during -development is just a step away.

5.2. Spaces in path

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 pwd.

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.

5.3. Dependency tracking and modification times

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.

Erlang.mk must use this method in order to be able to compile -files in one erlc invocation. The benefits greatly outweigh -the issue in this case and so there are currently no plans to -fix this behavior.

-
- - diff --git a/guide/ch06.html b/guide/ch06.html deleted file mode 100644 index e067443..0000000 --- a/guide/ch06.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 6. Building

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.

For most of this chapter, we will assume that you are -using a project generated by Erlang.mk.

6.1. How to build

To build a project, all you have to do is type make:

$ make

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.

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.

6.2. What to build

Erlang.mk gives you control over three steps of the build -process, allowing you to do a partial build if needed.

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.

Erlang.mk handles those three phases automatically when you -type make. But sometimes you just want to repeat one or -two of them.

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.

6.2.1. Application

You can build your application and dependencies without -generating a release by running the following command:

$ make app

To build your application without touching dependencies -at all, you can use the SKIP_DEPS variable:

$ make app SKIP_DEPS=1

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.

Note that this command may fail if a required dependency -is missing.

6.2.2. Dependencies

You can build all dependencies, and nothing else, by -running the following command:

$ make deps

This will fetch and compile all dependencies and their -dependencies, recursively.

Packages and dependencies are covered -in the next chapter.

6.2.3. Release

It is not possible to build the release without at least -building the application itself, unless of course if there’s -no application to begin with.

To generate the release, make will generally suffice with -a normal Erlang.mk. A separate target is however available, -and will take care of building the release, after building -the application and all dependencies:

$ make rel

Consult the Releases chapter for more -information about what releases are and how they are generated.

6.3. Application resource file

When building your application, Erlang.mk will generate the -application resource file. -This file is mandatory for all Erlang applications and is -found in ebin/$(PROJECT).app.

PROJECT is a variable defined in your Makefile and taken -from the name of the directory when Erlang.mk bootstraps -your project.

Erlang.mk can build the ebin/$(PROJECT).app in two different -ways: from the configuration found in the Makefile, or from -the src/$(PROJECT).app.src file.

6.3.1. Application configuration

Erlang.mk automatically fills the PROJECT 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.

-PROJECT -
- The name of the OTP application or library. -
-PROJECT_DESCRIPTION -
- Short description of the project. -
-PROJECT_VERSION -
- Current version of the project. -
-PROJECT_REGISTERED -
- List of the names of all registered processes. -
-LOCAL_DEPS -
- List of Erlang/OTP applications this project depends on, - excluding erts, kernel and stdlib, or list of - dependencies local to this repository (in APPS_DIR). -
-DEPS -
- List of applications this project depends on that need - to be fetched by Erlang.mk. -

There’s no need for quotes or anything. The relevant part of -the Cowboy Makefile follows, if you need an example:

PROJECT = cowboy
-PROJECT_DESCRIPTION = Small, fast, modular HTTP server.
-PROJECT_VERSION = 2.0.0-pre.2
-PROJECT_REGISTERED = cowboy_clock
-
-LOCAL_DEPS = crypto
-DEPS = cowlib ranch

Any space before and after the value is dropped.

Dependencies are covered in details in -the next chapter.

6.3.2. Legacy method

The src/$(PROJECT).app.src file is a legacy method of -building Erlang applications. It was introduced by the original -rebar build tool, of which Erlang.mk owes a great deal as it -is its main inspiration.

The .app.src file serves as a template to generate the .app -file. Erlang.mk will take it, fill in the modules value -dynamically, and save the result in ebin/$(PROJECT).app.

When using this method, Erlang.mk cannot fill the applications -key from dependencies automatically, which means you need to -add them to Erlang.mk and to the .app.src at the same time, -duplicating the work.

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:

$ make -f erlang.mk bootstrap-lib LEGACY=1

6.4. Automatic application resource file values

When building the application resource file, Erlang.mk may -automatically add an id key with information about the -Git commit (if using Git), or an empty string otherwise. -It will only do this under specific conditions:

  • -The application was built as a dependency of another, or -
  • -The legacy method was used, and the .app.src file contained {id, "git"} -

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:

1> application:get_all_key(cowboy).
-{ok,[{description,"Small, fast, modular HTTP server."},
-     {id,"2.0.0-pre.2-25-g0ffde50-dirty"},

6.5. File formats

Erlang.mk supports a variety of different source file formats. -The following formats are supported natively:

Extension Location Description Output

.erl

src/

Erlang source

ebin/*.beam

.core

src/

Core Erlang source

ebin/*.beam

.xrl

src/

Leex source

src/*.erl

.yrl

src/

Yecc source

src/*.erl

.asn1

asn1/

ASN.1 files

include/.hrl include/.asn1db src/*.erl

.mib

mibs/

SNMP MIB files

include/.hrl priv/mibs/.bin

Files are always searched recursively.

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.

In addition, Erlang.mk keeps track of header files (.hrl) -as described at the end of this chapter. It can also compile -C code, as described in the NIFs and port drivers -chapter.

Erlang.mk also comes with plugins for the following formats:

Extension Location Description Output

.dtl

templates/

Django templates

ebin/*.beam

.proto

src/

Protocol buffers

ebin/*.beam

6.6. Compilation options

Erlang.mk provides a few variables that you can use to customize -the build process and the resulting files.

6.6.1. ERLC_OPTS

ERLC_OPTS can be used to pass some options to erlc, the Erlang -compiler. Erlang.mk does not restrict any option. Please refer to -the erlc Manual for the -full list.

By default, Erlang.mk will set the following options:

ERLC_OPTS = -Werror +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard

In other words: warnings as errors, debug info (recommended) and -enable warnings for exported variables, shadow variables and -obsolete guard functions.

You can redefine this variable in your Makefile to change it -completely, either before or after including Erlang.mk:

ERLC_OPTS = +debug_info

You can also filter out some options from the defaults Erlang.mk -sets, by defining ERLC_OPTS after including Erlang.mk using the -:= operator.

include erlang.mk
-
-ERLC_OPTS := $(filter-out -Werror,$(ERLC_OPTS))

6.6.2. ERLC_EXCLUDE

ERLC_EXCLUDE can be used to exclude some modules from the -compilation. It’s there for handling special cases, you should -not normally need it.

To exclude a module, simply list it in the variable, either -before or after including Erlang.mk:

ERLC_EXCLUDE = cowboy_http2

6.7. Cold and hot builds

The first time you run make, Erlang.mk will build everything.

The second time you run make, 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.

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.

Note that this applies only to building; some other features of -Erlang.mk will run every time they are called regardless of files -changed.

6.8. Dependency tracking

Note

This section is about the dependency tracking between files -inside your project, not application dependencies.

Erlang.mk keeps track of the dependencies between the different -files in your project. This information is kept in the $(PROJECT).d -file in your directory. It is generated if missing, and will be -generated again after every file change, by default.

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.

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 Makefile:

NO_MAKEDEP ?= 1

As you can see, the snippet above uses ?= 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:

$ NO_MAKEDEP= make

Otherwise, make clean app will of course force the -recompilation of your project.

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.

6.9. Generating Erlang source

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 erlang.mk file.

The easiest way is after:

PROJECT = example
-
-include erlang.mk
-
-$(PROJECT).d:: src/generated_mod.erl
-
-src/generated_mod.erl:: gen-mod.sh
-    $(gen_verbose) ./gen-mod.sh $@

In this case we use $(gen_verbose) to hide the details of -the build by default. Erlang.mk will simply say what file -is it currently generating.

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.

If for whatever reason you prefer to hook before including -Erlang.mk, don’t forget to set the .DEFAULT_GOAL variable, -otherwise nothing will get built:

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 $@

6.10. Cleaning

Building typically involves creating a lot of new files. Some -are reused in rebuilds, some are simply replaced. All can be -removed safely.

Erlang.mk provides two commands to remove them: clean and -distclean. clean 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. -distclean 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.

To clean:

$ make clean

Or distclean:

$ make distclean

That is the question.

Note that Erlang.mk will automatically clean some files as -part of other targets, but it will never run distclean if -you don’t explicitly use it.

-
- - diff --git a/guide/ch07.html b/guide/ch07.html deleted file mode 100644 index be4e48a..0000000 --- a/guide/ch07.html +++ /dev/null @@ -1,233 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 7. Packages and dependencies

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.

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.

This chapter will explain how to use packages, add -dependencies to your project or bundle them directly -in a single repository.

7.1. Searching packages

Erlang.mk gives you access to nearly 500 packages, with more -being added regularly.

To find a package, search for it:

$ make search q=pool

This will return all packages matching this word, like worker -pool and acceptor pool projects.

You can also list everything and use regular command line -tools to find what you need, for example:

$ make search | less

7.2. Adding dependencies to your project

Once you find the package you need, adding it as a dependency -to your project is a one-liner:

DEPS = cowboy

And that’s it! The next time you run make, 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.

Erlang.mk will fill in the application resource file with -all applications found in DEPS. But not all dependencies -are Erlang applications, and not all dependencies need to -be a runtime dependency. That’s where the BUILD_DEPS -variable comes in: it works just like DEPS, except the -dependencies listed there will not be added as runtime -dependencies.

For example, you could add a parse transform project like -this to make it available only at build time:

BUILD_DEPS = erlando

Or you could depend on a C project directly, if you are -building a NIF:

BUILD_DEPS = leveldb
-dep_leveldb = git https://github.com/basho/leveldb 2.1.3

This dependency will be built before your application, so -you could easily copy the resulting shared file into your -priv/ directory as part of the build process. More information -about that in the NIFs and port drivers -chapter.

Another variable, LOCAL_DEPS, 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.

You could depend on the Crypto application, for example:

LOCAL_DEPS = crypto

Erlang.mk comes with additional types of dependencies. -It has TEST_DEPS for dependencies used only for testing:

TEST_DEPS = ct_helper
-dep_ct_helper = git https://github.com/ninenines/ct_helper master

DOC_DEPS for dependencies used only when building documentation:

DOC_DEPS = edown

REL_DEPS for dependencies required to build the release, -or to include extra applications in the release:

REL_DEPS = recon

And SHELL_DEPS for dependencies to make available when running -the make shell command:

SHELL_DEPS = tddreloader

All these will be documented in more details in their respective -chapters.

7.2.1. Modifying the dependency source or version

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:

DEPS = cowboy

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.

If you simply want to change the commit number, all you -need to do is to define the dep_$(DEP_NAME)_commit -variable. In the case of Cowboy, this would look like this:

DEPS = cowboy
-dep_cowboy_commit = 2.0.0-pre.2

Erlang.mk will use the package index to get all information -about Cowboy, except the commit number which will be overriden.

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 dep_$(DEP_NAME) variable with everything:

DEPS = cowboy
-dep_cowboy = git https://github.com/essen/cowboy 2.0.0-pre.2

This will fetch Cowboy from your fork at the given commit.

7.2.2. Fetch methods

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.

The following table lists all existing methods:

Name Format Description

git

git repo commit

Clone the Git repository and checkout the given version

git-submodule

git-submodule

Initialize and update the Git submodule

hg

hg repo commit

Clone the Mercurial repository and update to the given version

svn

svn repo

Checkout the given SVN repository

cp

cp path/to/repo

Recursively copy a local directory

hex

hex version

Download the given project version from hex.pm

fail

N/A

Always fail, reserved for internal use

legacy

N/A

Legacy Erlang.mk fetcher, reserved for internal use

The git and hg methods both have a repository and commit. -You can use any valid commit, tag or branch in that repository -for the commit value.

For example, to fetch Cowboy with tag 2.0.0-pre.2 from Git:

dep_cowboy = git https://github.com/ninenines/cowboy 2.0.0-pre.2

Or to fetch Ehsa tag 4.0.3 from Mercurial:

dep_ehsa = hg https://bitbucket.org/a12n/ehsa 4.0.3

Git also comes with a concept of submodules. Erlang.mk can -automatically initializes and updates submodules for dependencies, -as long as they were added beforehand using git submodule add:

dep_cowboy = git-submodule

The svn method only has a repository value, but that’s -simply because the SVN repository URL can also contain -the path and commit.

This would fetch an example project from the trunk:

dep_ex1 = svn https://example.com/svn/trunk/project/ex1

And this would fetch a separate example project from a -specific commit:

dep_ex2 = svn svn://example.com/svn/branches/erlang-proj/ex2@264

You can copy a directory from your machine using the cp method. -It only takes the path to copy from:

dep_cowboy = cp $(HOME)/ninenines/cowboy

Finally, you can use a package from the -Hex repository:

dep_cowboy = hex 1.0.3

7.2.3. Custom fetch methods

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 dep_fetch_$(METHOD) to be available fetch -methods. You can do anything inside this variable, as long -as you create a folder named $(DEPS_DIR)/$(call dep_name,$1). -Or in layman terms, if your dependency is Cowboy, this would -become deps/cowboy.

To give an example, this is what the Git method does:

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

Note that, like dependency information, this custom fetch method -must be written before including erlang.mk.

7.3. How deps are fetched and built

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.

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:

  1. -Fetch all dependencies for the application -
  2. -Build first dependency -
  3. -Build Nth dependency -
  4. -Build last dependency -

Every time a dependency is built, these same steps are followed, -recursively.

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.

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.

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.

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.

7.4. Ignoring unwanted dependencies

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.

To ignore a dependency, simply add it to the IGNORE_DEPS -variable:

IGNORE_DEPS += edown proper

This will only ignore dependencies that are needed for -building. It is therefore safe to write:

IGNORE_DEPS += edown proper
-TEST_DEPS = proper

The PropEr application will be fetched as intended when -running make tests or make check. It will however -not be fetched when running make or make deps.

7.5. Dependencies directory

Dependencies are fetched in $(DEPS_DIR). By default this is -the deps 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.

You will therefore need to use ?= instead of =. Of course, -if you know you will never use this project as a dependency, -= will work. But to avoid it biting you later on, do this:

DEPS_DIR ?= $(CURDIR)/libs

The $(CURDIR) part is important, otherwise dependencies of -dependencies will be fetched in the wrong directory.

Erlang.mk will also export the REBAR_DEPS_DIR variable for -compatibility with Rebar build tools, as long as they are -recent enough.

7.6. Dependencies local to the repository

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.

They work exactly the same as remote dependencies, except:

  • -They are not fetched -
  • -They are not autopatched -
  • -They are not deleted on make distclean -
  • -They are not automatically added to the application resource file -

To properly fill the application resource file, you will -need to define the LOCAL_DEPS variable for each relevant -application, the same as for OTP applications.

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.

To start using dependencies local to the repository, simply -create a folder named $(APPS_DIR). By default, this folder -is the apps/ directory.

You can use Erlang.mk to bootstrap local dependencies by -using the command make new-app or make new-lib. This -command will create the necessary directories and bootstrap -the application.

For example, to create a full fledged OTP application as -a local dependency:

$ make new-app in=webchat

Or, the same as an OTP library:

$ make new-lib in=webchat

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:

$ make new t=gen_server n=my_server in=webchat

7.7. Repositories with no application at the root level

It’s possible to use Erlang.mk with only applications in -$(APPS_DIR), and nothing at the root of the repository. -Just create a folder, put the erlang.mk file in it, -write a Makefile that includes it, and start creating -your applications.

Similarly, it’s possible to have a repository with only -dependencies found in $(DEPS_DIR). 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.

7.8. Autopatch

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.

When fetching a dependency, the following operations are -performed:

  • -Fetch the dependency using the configured fetch method -
  • -If it contains a configure.ac or configure.in file, run autoreconf -Wall -vif -I m4 -
  • -If it contains a configure script, run it -
  • -Run autopatch on the project -

Autopatch first checks if there is any project-specific patch -enabled. There are currently two: RABBITMQ_CLIENT_PATCH for -the amqp_client dependency, and RABBITMQ_SERVER_PATCH for -the rabbit dependency. These are needed only for RabbitMQ -versions before 3.6.0 (assuming you are using upstream RabbitMQ, -and not a fork).

Otherwise, autopatch performs different operations depending -on the kind of project it finds the dependency to be.

  • -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. -
  • -Erlang.mk projects have their erlang.mk 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. -
  • -Other Erlang projects get a small Erlang.mk Makefile -generated automatically. -
  • -Projects with no source directory and no Makefile get an -empty Makefile generated, for compatibility purposes. -
  • -Other projects with no Makefile are left untouched. -

You can disable the replacing of the erlang.mk file by -defining the NO_AUTOPATCH_ERLANG_MK variable:

NO_AUTOPATCH_ERLANG_MK = 1

You can also disable autopatch entirely for a few select -projects using the NO_AUTOPATCH variable:

NO_AUTOPATCH = cowboy ranch cowlib

7.9. Skipping deps

It is possible to temporarily skip all dependency operations. -This is done by defining the SKIP_DEPS variable. Use cases -include being somewhere with no connection to download them, -or perhaps a peculiar setup.

A typical usage would be:

$ make SKIP_DEPS=1

When the variable is defined:

  • -Dependencies will not be compiled or downloaded when required -
  • -The dependency directory $(DEPS_DIR) will not be removed on make distclean -

This variable only applies to remote dependencies.

-
- - diff --git a/guide/ch08.html b/guide/ch08.html deleted file mode 100644 index 756d96a..0000000 --- a/guide/ch08.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 8. NIFs and port drivers

Erlang.mk can not only build Erlang projects, but also the C code -that some projects come with, like NIFs and port drivers.

There are two ways to build the C code: using a custom Makefile, -or making Erlang.mk do it directly. The C code will be built -as needed when you run make.

8.1. C source code location and Erlang environment

The C source code should be located in the $(C_SRC_DIR) directory. -It defaults to c_src/. Should you need to modify it, all you -need to do is to set the variable in your Makefile before including -Erlang.mk:

C_SRC_DIR = $(CURDIR)/my_nif_source

When this directory exists, Erlang.mk will automatically create a -file named $(C_SRC_ENV). This file defaults to $(C_SRC_DIR)/env.mk. -This can also be changed:

C_SRC_ENV = $(C_SRC_DIR)/erlang_env.mk

It contains a few variable definitions for the environment used for the build:

-ERTS_INCLUDE_DIR -
- Path to the ERTS include files (erl_driver.h, erl_nif.h and more). -
-ERL_INTERFACE_INCLUDE_DIR -
- Path to the Erl_Interface include files (ei.h and related). -
-ERL_INTERFACE_LIB_DIR -
- Path to the Erl_Interface static libraries. -

8.2. Using a custom Makefile

Erlang.mk will automatically run make if it detects a Makefile -in $(C_SRC_DIR)/Makefile.

The Makefile should have at least two targets: a default target -(which can be anything, for example all) which is invoked when -building the C code, and a clean target invoked when cleaning -it.

You can include the env.mk file to benefit from the Erlang -environment detection:

include env.mk

8.3. Using Erlang.mk directly

You don’t need to write a Makefile to build C source code, however. -Erlang.mk comes with rules to build both shared libraries and -executables, using the source files it finds in $(C_SRC_DIR).

By default, Erlang.mk will create a shared library. To change -this and create an executable instead, put this in your Makefile -before including Erlang.mk:

C_SRC_TYPE = executable

The generated file name varies depending on the type of project -you have (shared library or executable) and on the platform you -build the project on.

For shared libraries, the generated file name will be -$(C_SRC_OUTPUT)$(C_SRC_SHARED_EXTENSION), with the default -being $(CURDIR)/priv/$(PROJECT) followed by the extension: -.dll on Windows, .so everywhere else.

For executables, the generated file name is -$(C_SRC_OUTPUT)$(C_SRC_EXECUTABLE_EXTENSION), with the same -default except for the extension: .exe on Windows, and otherwise -nothing.

Erlang.mk sets appropriate compile and linker flags by default. -These flags vary depending on the platform, and can of course -be overriden.

-CC -
- The compiler to be used. -
-CFLAGS -
- C compiler flags. -
-CXXFLAGS -
- C++ compiler flags. -
-LDFLAGS -
- Linker flags. -
-LDLIBS -
- Libraries to link against. -

The source files are automatically gathered from the contents -of $(C_SRC_DIR). Erlang.mk looks for .c, .C, .cc and .cpp -source files. You can define the variable SOURCES to manually -list the files to compile.

-
- - diff --git a/guide/ch09.html b/guide/ch09.html deleted file mode 100644 index b0dc8fd..0000000 --- a/guide/ch09.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 9. Releases

Erlang.mk relies on Relx for generating releases. This -chapter covers the Erlang.mk-specific bits. Consult the -Relx website for more information.

9.1. Setup

Erlang.mk will create a release if it detects a Relx configuration -file in the $(RELX_CONFIG) location. This defaults to -$(CURDIR)/relx.config. You can override it by defining -the variable before including Erlang.mk:

RELX_CONFIG = $(CURDIR)/webchat.config

Relx does not need to be installed. Erlang.mk will download -and build it automatically.

The Relx executable will be saved in the $(RELX) file. This -location defaults to $(CURDIR)/relx and can be overriden.

9.2. Configuration

You can specify additional Relx options using the RELX_OPTS -variable. For example, to enable dev_mode:

RELX_OPTS = -d true

While you can specify the output directory for the release -in the Relx options directly, Erlang.mk provides a specific -variable for it: RELX_OUTPUT_DIR. It defaults to the _rel -directory. You can also override it:

RELX_OUTPUT_DIR = /path/to/staging/directory

9.3. Generating the release

Now that you’re all set, all you need to do is generate the -release. As mentioned before, Erlang.mk will automatically -generate it when it detects the $(RELX_CONFIG) file. This -means the following command will also build the release:

$ make

If you need to generate the release, and only the release, -the rel target can be used:

$ make rel

9.4. Running the release

Erlang.mk provides a convenience function for running the -release with one simple command:

$ make run

This command will also build the project and generate the -release if they weren’t already. It starts the release in -console mode, meaning you will also have a shell ready to -use to check things as needed.

-
- - diff --git a/guide/ch10.html b/guide/ch10.html deleted file mode 100644 index 533c1a2..0000000 --- a/guide/ch10.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 10. Escripts

Placeholder chapter.

-
- - diff --git a/guide/ch11.html b/guide/ch11.html deleted file mode 100644 index 140a2eb..0000000 --- a/guide/ch11.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 11. Compatibility with other build tools

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.

In this chapter I will use the term Rebar project 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.

11.1. Rebar projects as Erlang.mk dependencies

Erlang.mk comes with a feature called Autoload 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:

Autoload is documented in more details in the -Packages and dependencies chapter.

11.2. Erlang.mk projects as Rebar dependencies

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.

The Rebar family requires two files: a rebar.config file -containing compilation options and the list of dependencies, -and the application resource file, found either at -ebin/$(PROJECT).app or at src/$(PROJECT).app.src.

11.2.1. Rebar configuration

Erlang.mk comes with a target that generates a rebar.config -file when invoked:

$ make rebar.config

Careful! This will build the file even if it already existed -before.

To build this file, Erlang.mk uses information it finds in -the DEPS and ERLC_OPTS variables, among others. This -means that the Rebar family builds your project much the -same way as Erlang.mk.

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 Sanity check chapter to find -out how to detect such issues.

You can automatically generate this file when you build -your application, by making it a dependency of the app -target:

app:: rebar.config

Don’t forget to commit the file when it changes!

If you run into other issues, it’s probably because you use a -feature specific to Erlang.mk, like the cp 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!

11.2.2. Application resource file

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 src/$(PROJECT).app.src 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.

If you don’t, however, it’s not much harder. Every time -Erlang.mk will compile your application, it will produce -a new ebin/$(PROJECT).app file. Simply commit this file -when it changes. It will only change when you modify the -configuration, add or remove modules.

-
- - diff --git a/guide/ch12.html b/guide/ch12.html deleted file mode 100644 index 9b19e69..0000000 --- a/guide/ch12.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 12. Asciidoc documentation

Placeholder chapter.

-
- - diff --git a/guide/ch13.html b/guide/ch13.html deleted file mode 100644 index 7188967..0000000 --- a/guide/ch13.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 13. EDoc comments

Placeholder chapter.

-
- - diff --git a/guide/ch14.html b/guide/ch14.html deleted file mode 100644 index 6225aeb..0000000 --- a/guide/ch14.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 14. Erlang shell

Erlang.mk provides a convenient target for starting a shell -with all the paths set properly to experiment with your code.

14.1. Configuration

The SHELL_DEPS variable can be used to define dependencies -that are only to be used when the make shell command is called. -For example, if you want to use kjell as your shell:

SHELL_DEPS = kjell

Dependencies are downloaded and compiled the first time you -run the make shell command.

You can customize the executable used to start the Erlang shell. -To continue with our example, if you want to use kjell as your -shell, you also need to change SHELL_ERL and point it to the -kjell executable:

SHELL_ERL = $(DEPS_DIR)/kjell/bin/kjell

You can specify additional options to be used when starting the -shell using the SHELL_OPTS variable:

SHELL_OPTS = -setcookie chocolate

Any of the usual erl options can be used, including -eval:

SHELL_OPTS = -eval 'my_app:run()'

14.2. Usage

To start the shell, all you need is the following command:

$ make shell

The shell can be stopped as usual with a double Ctrl+C or the -command q()..

-
- - diff --git a/guide/ch15.html b/guide/ch15.html deleted file mode 100644 index acc6469..0000000 --- a/guide/ch15.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 15. EUnit

EUnit is the tool of choice for unit testing. Erlang.mk -automates a few things on top of EUnit, including the -discovery and running of unit tests.

15.1. Writing tests

The EUnit user guide -is the best place to learn how to write tests. Of note is -that all functions ending with _test or _test_ will be -picked up as EUnit test cases.

Erlang.mk will automatically pick up tests found in any of -the Erlang modules of your application. It will also pick up -tests located in the $(TEST_DIR) directory, which defaults -to test/.

It is generally a good practice to hide test code from -the code you ship to production. With Erlang.mk, you can -do this thanks to the TEST macro. It is only defined -when running tests:

-ifdef(TEST).
-
-%% Insert tests here.
-
--endif.

Be careful, however, if you include the EUnit header file, -as it also defines the TEST macro. Make sure to only include -it inside an ifdef block, otherwise tests will always be -compiled.

-ifdef(TEST).
-
--include_lib(\"eunit/include/eunit.hrl\").
-
-%% Insert tests here.
-
--endif.

Erlang.mk will automatically recompile your code when you -perform a normal build after running tests, and vice versa.

15.2. Configuration

The EUNIT_OPTS variable allows you to specify additional -EUnit options. Options are documented in the -EUnit manual. -At the time of writing, the only available option is verbose:

EUNIT_OPTS = verbose

The EUNIT_ERL_OPTS variable allows you to specify options -to be passed to erl when running EUnit tests. For example, -you can load the vm.args and sys.config files:

EUNIT_ERL_OPTS = -args_file rel/vm.args -config rel/sys.config

15.3. Usage

To run all tests (including EUnit):

$ make tests

To run all tests and static checks (including EUnit):

$ make check

You can also run EUnit separately:

$ make eunit

EUnit will be quiet by default, only outputting errors. -You can easily make it verbose for a single invocation:

$ make eunit EUNIT_OPTS=verbose

Erlang.mk allows you to run all tests from a specific -module, or a specific test case from that module, using -the variable t.

For example, to run all tests from the cow_http_hd -module (instead of all tests from the entire project), -one could write:

$ make eunit t=cow_http_hd

Similarly, to run a specific test case:

$ make eunit t=cow_http_hd:parse_accept_test_

To do the same against a multi-application repository, -you can use the -C option:

$ make -C apps/my_app eunit t=my_module:hello_test

Note that this also applies to dependencies. From Cowboy, -you can run the following directly:

$ make -C deps/cowlib eunit t=cow_http_hd

Finally, code coverage is available, -but covered in its own chapter.

-
- - diff --git a/guide/ch16.html b/guide/ch16.html deleted file mode 100644 index 2c71c11..0000000 --- a/guide/ch16.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 16. Common Test

Placeholder chapter.

-
- - diff --git a/guide/ch17.html b/guide/ch17.html deleted file mode 100644 index edf141e..0000000 --- a/guide/ch17.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 17. Property based testing

Placeholder chapter.

-
- - diff --git a/guide/ch18.html b/guide/ch18.html deleted file mode 100644 index f882401..0000000 --- a/guide/ch18.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 18. Code coverage

Placeholder chapter.

-
- - diff --git a/guide/ch19.html b/guide/ch19.html deleted file mode 100644 index 2ae3d8e..0000000 --- a/guide/ch19.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 19. Continuous integration

Placeholder chapter.

-
- - diff --git a/guide/ch20.html b/guide/ch20.html deleted file mode 100644 index 8a59b86..0000000 --- a/guide/ch20.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 20. Dialyzer

Dialyzer is a tool that will detect discrepancies in your -program. It does so using a technique known as success -typing analysis which has the advantage of providing no -false positives. Dialyzer is able to detect type errors, -dead code and more.

Erlang.mk provides a wrapper around Dialyzer.

20.1. How it works

Dialyzer requires a PLT file to work. The PLT file contains -the analysis information from all applications which are not -expected to change, or rarely do. These would be all the -dependencies of the application or applications you are -currently working on, including standard applications in -Erlang/OTP itself.

Dialyzer can generate this PLT file. Erlang.mk includes rules -to automatically generate the PLT file when it is missing.

Once the PLT file is generated, Dialyzer can perform the -analysis in record time.

20.2. Configuration

In a typical usage scenario, no variable needs to be set. -The defaults should be enough. Do note however that the -dependencies need to be set properly using the DEPS and -LOCAL_DEPS variables.

The DIALYZER_PLT file indicates where the PLT file will -be written to (and read from). By default this is -$(PROJECT).plt in the project’s directory. Note that -the DIALYZER_PLT variable is exported and is understood -by Dialyzer directly.

The PLT_APPS variable can be used to add additional -applications to the PLT. You can either list application -names or paths to these applications.

Erlang.mk defines two variables for specifying options -for the analysis: DIALYZER_DIRS and DIALYZER_OPTS. -The former one defines which directories should be part -of the analysis. The latter defines what extra warnings -Dialyzer should report.

Note that Erlang.mk enables the race condition warnings -by default. As it can take considerably large resources -to run, you may want to disable it on larger projects.

20.3. Usage

To perform an analysis, run the following command:

$ make dialyze

This will create the PLT file if it doesn’t exist.

The analysis will also be performed when you run the -following command, alongside tests:

$ make check

You can use the plt target to create the PLT file if -it doesn’t exist. This is normally not necessary as -Dialyzer creates it automatically.

The PLT file will be removed when you run make distclean.

-
- - diff --git a/guide/ch21.html b/guide/ch21.html deleted file mode 100644 index 32dab50..0000000 --- a/guide/ch21.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 21. Xref

Placeholder chapter.

-
- - diff --git a/guide/ch22.html b/guide/ch22.html deleted file mode 100644 index 0e5c000..0000000 --- a/guide/ch22.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 22. External plugins

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.

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.

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.

22.1. Loading all plugins from a dependency

To load plugins from a dependency, all you need to do is add -the dependency name to DEP_PLUGINS in addition to the list -of dependencies.

For example, if you have cowboy in DEPS, add cowboy in -DEP_PLUGINS also:

DEPS = cowboy
-DEP_PLUGINS = cowboy

This will load the file plugins.mk in the root folder of -the Cowboy repository.

22.2. Loading one plugin from a dependency

Now that we know how to load all plugins, let’s take a look -at how to load one specific plugin from a dependency.

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 DEP_PLUGINS = cowboy is equivalent to -writing DEP_PLUGINS = cowboy/plugins.mk.

Knowing this, if we were to load the plugin mk/dist.mk -from Cowboy and no other, we would write the following in -our Makefile:

DEPS = cowboy
-DEP_PLUGINS = cowboy/mk/dist.mk

22.3. Writing external plugins

The plugins.mk 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 plugins.mk or be separate.

If you are providing more than one plugin with your repository, -the recommended way is to create one file per plugin in the -mk/ folder in your repository, and then include those -individual plugins in plugins.mk.

For example, if you have two plugins mk/dist.mk and -mk/templates.mk, you could write the following plugins.mk -file:

THIS := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
-include $(THIS)/mk/dist.mk
-include $(THIS)/mk/templates.mk

The THIS variable is required to relatively include files.

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.

-
- - diff --git a/guide/ch23.html b/guide/ch23.html deleted file mode 100644 index fa71745..0000000 --- a/guide/ch23.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 23. Why Erlang.mk

Why would you choose Erlang.mk, if not for its -many features? This chapter will -attempt to answer that.

23.1. Erlang.mk is fast

Erlang.mk is as fast as it gets.

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.

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.

23.2. Erlang.mk gives you the full power of Unix

Erlang.mk is a Makefile.

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.

In all cases: for configuration, hooks or custom rules, you -have all the power of Unix at your disposal, and can call -any utility or even any language interpreter 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…

23.3. Erlang.mk is a text file

Erlang.mk is a Makefile.

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 -erlang.mk file in your favorite editor, fix and/or comment -a few lines, save, and try again. It’s as simple as it gets.

Currently using a binary build tool? Good luck with that.

23.4. Erlang.mk can manage Erlang itself

Erlang.mk isn’t written in Erlang.

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.

This really is a one-liner in Erlang.mk (a few more lines -if you also let it download and build Erlang directly) -and allows for even greater things, like testing your -project across all supported Erlang versions in one small -command: make -k ci.

23.5. Erlang.mk can do more than Erlang

Erlang.mk doesn’t care what your dependencies are written in.

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.

23.6. Erlang.mk integrates nicely in Make and Automake projects

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.

Erlang.mk will happily sit in such an environment and behave -as you expect it to.

-
- - diff --git a/guide/ch24.html b/guide/ch24.html deleted file mode 100644 index d7470c0..0000000 --- a/guide/ch24.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 24. Short history

This chapter aims to be a brief record of the life of the -Erlang.mk project.

24.1. Before Erlang.mk

Erlang.mk originates from the Cowboy project. Cowboy started -as a Rebar project and I, Loïc Hoguin, was very happy with it -for a couple years. Over time however I started getting annoyed -and frustrated by a number of things, including bad defaults, -changing defaults and overall slowness.

In particular, at the time I gave up on Rebar, the Cowboy -test suite was taking about five minutes to run. A quick experiment -showed I could get much lower times by simply invoking ct_run -directly. On January 4th, 2013, the Cowboy test suite took less -than a minute to complete.

Following this success I started removing a little more and, -on the fateful day of January 5th, 2013, removed the dependency -on Rebar entirely. Rebar, and in particular the concept of -dependencies, was, and still is, a pretty strong influence.

Erlang.mk was conceived.

A few months passed and, on May 1st, 2013, the Erlang.mk -repository was created. Erlang.mk was born.

Little did I know how much it would grow.

24.2. Lifetime of the project

Erlang.mk would eventually become a much larger file able to -deal with many more projects than just Cowboy. From the birth -of the project, the biggest force for growth was user contributions, -because Erlang.mk appealed to a variety of people with different -needs, needs that Erlang.mk was not fulfilling yet.

The project was split into smaller files focused on a different -feature each, and a build script was written to build the single -Erlang.mk file.

A test suite was contributed by a user, and later taken as a basis -for the current, much more complete test suite. Turns out testing -a Makefile is pretty straightforward.

A package index was added to solve the problem of discovering -Erlang projects.

After trying to see if Erlang build tools could cooperate, the -decision was made to improve compatibility with existing Rebar -projects by patching Rebar out, using Rebar. This feature, called -autopatch, proved very successful and made Erlang.mk compatible -with more than 90% of all Erlang projects.

Erlang.mk documentation was much improved and the Erlang.mk website -was created in the summer of 2015.

Over the year of 2015, Erlang.mk went from curiosity to a serious -alternative to other Erlang build tools. The user base increased -immensely and large projects started using it, including RabbitMQ -from the 3.6.0 release onward.

A bright future lies ahead.

-
- - diff --git a/guide/ch25.html b/guide/ch25.html deleted file mode 100644 index 983e946..0000000 --- a/guide/ch25.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Chapter 25. Contributing

You are welcome and encouraged to contribute.

This is how.

25.1. Priorities

From the most important to the least important:

  • -Bugs -
  • -Package issues/additions -
  • -Refactoring -
  • -Features -

25.2. Bugs

If you have found a bug, you should open a ticket. Include -everything relevant including the command you used, output, -a link to the code that triggers the issue, why you think -this is a bug, etc.

If you think you have found a bug but you are not sure, you -should open a ticket as previously explained.

If you have found a bug and you need it to be solved RIGHT -NOW, open a ticket as previously explained.

Once you have opened a ticket, be patient, try to answer -questions in a timely manner and confirm that the bug was -indeed fixed when it is.

If you can’t be patient, either try to solve the bug and -contribute the fix back or become a paying customer.

25.3. Code

The code is located in the core/*.mk and plugins/*.mk files. -The tests are located in the test/Makefile and test/*.mk files.

If you have a fix or a hack for a bug, you should open a -pull request. Any fix should include a test case that fails -before the fix and is working after.

If you have a test case that reproduces a bug, but no fix for -it, you should open a pull request.

Changes need to be tested with at least the make check -command. A specific test case can be tested using make check c=CASE -with CASE the name of the target to run. Output can be -modulated using the V variable, which is an integer -from 0 to 4. A typical use would be make check c=dialyzer V=3. -The value 4 is particular and shows expanded commands right -before they are executed.

To run tests in parallel, use the -j option. It is generally -a good idea to also use the -k option to run all tests even -if one fails. For example: make check -j 32 -k.

Some changes should be tested against all packages. Continue -reading for more details on testing them.

25.4. Packages

You can search existing packages using the make search q=STRING -command. This can be done both from an Erlang.mk project or -directly from the Erlang.mk repository.

Packages can be added to the index using the pkg_add.sh script.

$ git clone https://github.com/$YOURUSERNAME/erlang.mk
-$ cd erlang.mk
-$ ./pkg_add.sh cowboy git https://github.com/ninenines/cowboy 1.0.0
-  http://ninenines.eu "Small, fast and modular HTTP server."
-$ git push origin master

Before sending a pull request, you should test your package. -You can use the following command: make check p=PACKAGE, -where PACKAGE is the name of the package, for example -cowboy.

To test all packages, the make packages command can be used. -This can take a long time. Some packages will fail with certain -versions of Erlang, or if a prerequisite is missing from your system. -You can of course speed things up using the -j and -k flags.

After all packages have been tested, you can run the command -make summary to know what changed since the previous run.

25.5. Documentation

The documentation is always right.

If you think you have found a mistake in the documentation, -this is a bug. You can either open a ticket or send a pull -request.

To make sure that the documentation changes work, install -Asciidoc on your system and run make docs.

25.6. Feature requests

If you have an awesome idea or need something that Erlang.mk -doesn’t provide yet, open a ticket. Provide as much detail as -possible.

If you have code, great! Open a pull request as previously -explained.

If not, you can still improve your feature request by writing -the related documentation.

-
- - diff --git a/guide/ci.html b/guide/ci.html new file mode 100644 index 0000000..24d8fa7 --- /dev/null +++ b/guide/ci.html @@ -0,0 +1,37 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 19. Continuous integration

Placeholder chapter.

+
+ + diff --git a/guide/code.html b/guide/code.html new file mode 100644 index 0000000..6d2e4f9 --- /dev/null +++ b/guide/code.html @@ -0,0 +1,37 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Part I. Code

+
+ + diff --git a/guide/compat.html b/guide/compat.html new file mode 100644 index 0000000..076df8d --- /dev/null +++ b/guide/compat.html @@ -0,0 +1,78 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 11. Compatibility with other build tools

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.

In this chapter I will use the term Rebar project 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.

11.1. Rebar projects as Erlang.mk dependencies

Erlang.mk comes with a feature called Autoload 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:

Autoload is documented in more details in the +Packages and dependencies chapter.

11.2. Erlang.mk projects as Rebar dependencies

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.

The Rebar family requires two files: a rebar.config file +containing compilation options and the list of dependencies, +and the application resource file, found either at +ebin/$(PROJECT).app or at src/$(PROJECT).app.src.

11.2.1. Rebar configuration

Erlang.mk comes with a target that generates a rebar.config +file when invoked:

$ make rebar.config

Careful! This will build the file even if it already existed +before.

To build this file, Erlang.mk uses information it finds in +the DEPS and ERLC_OPTS variables, among others. This +means that the Rebar family builds your project much the +same way as Erlang.mk.

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 Sanity check chapter to find +out how to detect such issues.

You can automatically generate this file when you build +your application, by making it a dependency of the app +target:

app:: rebar.config

Don’t forget to commit the file when it changes!

If you run into other issues, it’s probably because you use a +feature specific to Erlang.mk, like the cp 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!

11.2.2. Application resource file

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 src/$(PROJECT).app.src 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.

If you don’t, however, it’s not much harder. Every time +Erlang.mk will compile your application, it will produce +a new ebin/$(PROJECT).app file. Simply commit this file +when it changes. It will only change when you modify the +configuration, add or remove modules.

+
+ + diff --git a/guide/contributing.html b/guide/contributing.html new file mode 100644 index 0000000..ba91d94 --- /dev/null +++ b/guide/contributing.html @@ -0,0 +1,86 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 25. Contributing

You are welcome and encouraged to contribute.

This is how.

25.1. Priorities

From the most important to the least important:

  • +Bugs +
  • +Package issues/additions +
  • +Refactoring +
  • +Features +

25.2. Bugs

If you have found a bug, you should open a ticket. Include +everything relevant including the command you used, output, +a link to the code that triggers the issue, why you think +this is a bug, etc.

If you think you have found a bug but you are not sure, you +should open a ticket as previously explained.

If you have found a bug and you need it to be solved RIGHT +NOW, open a ticket as previously explained.

Once you have opened a ticket, be patient, try to answer +questions in a timely manner and confirm that the bug was +indeed fixed when it is.

If you can’t be patient, either try to solve the bug and +contribute the fix back or become a paying customer.

25.3. Code

The code is located in the core/*.mk and plugins/*.mk files. +The tests are located in the test/Makefile and test/*.mk files.

If you have a fix or a hack for a bug, you should open a +pull request. Any fix should include a test case that fails +before the fix and is working after.

If you have a test case that reproduces a bug, but no fix for +it, you should open a pull request.

Changes need to be tested with at least the make check +command. A specific test case can be tested using make check c=CASE +with CASE the name of the target to run. Output can be +modulated using the V variable, which is an integer +from 0 to 4. A typical use would be make check c=dialyzer V=3. +The value 4 is particular and shows expanded commands right +before they are executed.

To run tests in parallel, use the -j option. It is generally +a good idea to also use the -k option to run all tests even +if one fails. For example: make check -j 32 -k.

Some changes should be tested against all packages. Continue +reading for more details on testing them.

25.4. Packages

You can search existing packages using the make search q=STRING +command. This can be done both from an Erlang.mk project or +directly from the Erlang.mk repository.

Packages can be added to the index using the pkg_add.sh script.

$ git clone https://github.com/$YOURUSERNAME/erlang.mk
+$ cd erlang.mk
+$ ./pkg_add.sh cowboy git https://github.com/ninenines/cowboy 1.0.0
+  http://ninenines.eu "Small, fast and modular HTTP server."
+$ git push origin master

Before sending a pull request, you should test your package. +You can use the following command: make check p=PACKAGE, +where PACKAGE is the name of the package, for example +cowboy.

To test all packages, the make packages command can be used. +This can take a long time. Some packages will fail with certain +versions of Erlang, or if a prerequisite is missing from your system. +You can of course speed things up using the -j and -k flags.

After all packages have been tested, you can run the command +make summary to know what changed since the previous run.

25.5. Documentation

The documentation is always right.

If you think you have found a mistake in the documentation, +this is a bug. You can either open a ticket or send a pull +request.

To make sure that the documentation changes work, install +Asciidoc on your system and run make docs.

25.6. Feature requests

If you have an awesome idea or need something that Erlang.mk +doesn’t provide yet, open a ticket. Provide as much detail as +possible.

If you have code, great! Open a pull request as previously +explained.

If not, you can still improve your feature request by writing +the related documentation.

+
+ + diff --git a/guide/coverage.html b/guide/coverage.html new file mode 100644 index 0000000..58fbe16 --- /dev/null +++ b/guide/coverage.html @@ -0,0 +1,37 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 18. Code coverage

Placeholder chapter.

+
+ + diff --git a/guide/ct.html b/guide/ct.html new file mode 100644 index 0000000..c6b62f2 --- /dev/null +++ b/guide/ct.html @@ -0,0 +1,60 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 16. Common Test

Common Test is Erlang’s functional testing framework. +Erlang.mk automates the discovery and running of Common +Test suites.

16.1. Writing tests

The Common Test user guide +is the best place to learn how to write tests. Erlang.mk +requires that file names for test suites end with _SUITE.erl +and that the files be located in the $(TEST_DIR) directory. +This defaults to test/.

16.2. Configuration

The CT_OPTS variable allows you to set extra Common Test +options. Options are documented in the +Common Test user guide. +You can use it to set Common Test hooks, for example:

CT_OPTS = -ct_hooks cowboy_ct_hook

The CT_SUITES variable can be used to override what +Common Test suites Erlang.mk will be aware of. It does +not normally need to be set as Erlang.mk will find the +test suites automatically.

The name of the suite is the part before _SUITE.erl. +If the file is named http_SUITE.erl, the test suite +is http:

CT_SUITES = http ws

16.3. Usage

To run all tests (including Common Test):

$ make tests

To run all tests and static checks (including Common Test):

$ make check

You can also run Common Test separately:

$ make ct

Erlang.mk will create targets for all test suites it finds. +If you have a file named test/http_SUITE.erl, then the +target ct-http will run that specific test suite:

$ make ct-http

Erlang.mk provides a convenient way to run a specific +group or a specific test case within a specific group, +using the variable t. Note that this only applies to +suite-specific targets, like the ct-http example above.

To run all tests from the http_compress group in the +http_SUITE test suite, write:

$ make ct-http t=http_compress

Similarly, to run a specific test case in that group:

$ make ct-http t=http_compress:headers_dupe

To do the same against a multi-application repository, +you can use the -C option:

$ make -C apps/my_app ct-http t=my_group:my_case

Note that this also applies to dependencies. When using Cowboy +as a dependency, you can run the following directly:

$ make -C deps/cowboy ct-http t=http_compress

Finally, code coverage is available, +but covered in its own chapter.

+
+ + diff --git a/guide/deps.html b/guide/deps.html new file mode 100644 index 0000000..8fdacdb --- /dev/null +++ b/guide/deps.html @@ -0,0 +1,233 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 7. Packages and dependencies

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.

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.

This chapter will explain how to use packages, add +dependencies to your project or bundle them directly +in a single repository.

7.1. Searching packages

Erlang.mk gives you access to nearly 500 packages, with more +being added regularly.

To find a package, search for it:

$ make search q=pool

This will return all packages matching this word, like worker +pool and acceptor pool projects.

You can also list everything and use regular command line +tools to find what you need, for example:

$ make search | less

7.2. Adding dependencies to your project

Once you find the package you need, adding it as a dependency +to your project is a one-liner:

DEPS = cowboy

And that’s it! The next time you run make, 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.

Erlang.mk will fill in the application resource file with +all applications found in DEPS. But not all dependencies +are Erlang applications, and not all dependencies need to +be a runtime dependency. That’s where the BUILD_DEPS +variable comes in: it works just like DEPS, except the +dependencies listed there will not be added as runtime +dependencies.

For example, you could add a parse transform project like +this to make it available only at build time:

BUILD_DEPS = erlando

Or you could depend on a C project directly, if you are +building a NIF:

BUILD_DEPS = leveldb
+dep_leveldb = git https://github.com/basho/leveldb 2.1.3

This dependency will be built before your application, so +you could easily copy the resulting shared file into your +priv/ directory as part of the build process. More information +about that in the NIFs and port drivers +chapter.

Another variable, LOCAL_DEPS, 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.

You could depend on the Crypto application, for example:

LOCAL_DEPS = crypto

Erlang.mk comes with additional types of dependencies. +It has TEST_DEPS for dependencies used only for testing:

TEST_DEPS = ct_helper
+dep_ct_helper = git https://github.com/ninenines/ct_helper master

DOC_DEPS for dependencies used only when building documentation:

DOC_DEPS = edown

REL_DEPS for dependencies required to build the release, +or to include extra applications in the release:

REL_DEPS = recon

And SHELL_DEPS for dependencies to make available when running +the make shell command:

SHELL_DEPS = tddreloader

All these will be documented in more details in their respective +chapters.

7.2.1. Modifying the dependency source or version

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:

DEPS = cowboy

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.

If you simply want to change the commit number, all you +need to do is to define the dep_$(DEP_NAME)_commit +variable. In the case of Cowboy, this would look like this:

DEPS = cowboy
+dep_cowboy_commit = 2.0.0-pre.2

Erlang.mk will use the package index to get all information +about Cowboy, except the commit number which will be overriden.

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 dep_$(DEP_NAME) variable with everything:

DEPS = cowboy
+dep_cowboy = git https://github.com/essen/cowboy 2.0.0-pre.2

This will fetch Cowboy from your fork at the given commit.

7.2.2. Fetch methods

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.

The following table lists all existing methods:

Name Format Description

git

git repo commit

Clone the Git repository and checkout the given version

git-submodule

git-submodule

Initialize and update the Git submodule

hg

hg repo commit

Clone the Mercurial repository and update to the given version

svn

svn repo

Checkout the given SVN repository

cp

cp path/to/repo

Recursively copy a local directory

hex

hex version

Download the given project version from hex.pm

fail

N/A

Always fail, reserved for internal use

legacy

N/A

Legacy Erlang.mk fetcher, reserved for internal use

The git and hg methods both have a repository and commit. +You can use any valid commit, tag or branch in that repository +for the commit value.

For example, to fetch Cowboy with tag 2.0.0-pre.2 from Git:

dep_cowboy = git https://github.com/ninenines/cowboy 2.0.0-pre.2

Or to fetch Ehsa tag 4.0.3 from Mercurial:

dep_ehsa = hg https://bitbucket.org/a12n/ehsa 4.0.3

Git also comes with a concept of submodules. Erlang.mk can +automatically initializes and updates submodules for dependencies, +as long as they were added beforehand using git submodule add:

dep_cowboy = git-submodule

The svn method only has a repository value, but that’s +simply because the SVN repository URL can also contain +the path and commit.

This would fetch an example project from the trunk:

dep_ex1 = svn https://example.com/svn/trunk/project/ex1

And this would fetch a separate example project from a +specific commit:

dep_ex2 = svn svn://example.com/svn/branches/erlang-proj/ex2@264

You can copy a directory from your machine using the cp method. +It only takes the path to copy from:

dep_cowboy = cp $(HOME)/ninenines/cowboy

Finally, you can use a package from the +Hex repository:

dep_cowboy = hex 1.0.3

7.2.3. Custom fetch methods

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 dep_fetch_$(METHOD) to be available fetch +methods. You can do anything inside this variable, as long +as you create a folder named $(DEPS_DIR)/$(call dep_name,$1). +Or in layman terms, if your dependency is Cowboy, this would +become deps/cowboy.

To give an example, this is what the Git method does:

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

Note that, like dependency information, this custom fetch method +must be written before including erlang.mk.

7.3. How deps are fetched and built

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.

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:

  1. +Fetch all dependencies for the application +
  2. +Build first dependency +
  3. +Build Nth dependency +
  4. +Build last dependency +

Every time a dependency is built, these same steps are followed, +recursively.

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.

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.

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.

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.

7.4. Ignoring unwanted dependencies

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.

To ignore a dependency, simply add it to the IGNORE_DEPS +variable:

IGNORE_DEPS += edown proper

This will only ignore dependencies that are needed for +building. It is therefore safe to write:

IGNORE_DEPS += edown proper
+TEST_DEPS = proper

The PropEr application will be fetched as intended when +running make tests or make check. It will however +not be fetched when running make or make deps.

7.5. Dependencies directory

Dependencies are fetched in $(DEPS_DIR). By default this is +the deps 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.

You will therefore need to use ?= instead of =. Of course, +if you know you will never use this project as a dependency, += will work. But to avoid it biting you later on, do this:

DEPS_DIR ?= $(CURDIR)/libs

The $(CURDIR) part is important, otherwise dependencies of +dependencies will be fetched in the wrong directory.

Erlang.mk will also export the REBAR_DEPS_DIR variable for +compatibility with Rebar build tools, as long as they are +recent enough.

7.6. Dependencies local to the repository

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.

They work exactly the same as remote dependencies, except:

  • +They are not fetched +
  • +They are not autopatched +
  • +They are not deleted on make distclean +
  • +They are not automatically added to the application resource file +

To properly fill the application resource file, you will +need to define the LOCAL_DEPS variable for each relevant +application, the same as for OTP applications.

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.

To start using dependencies local to the repository, simply +create a folder named $(APPS_DIR). By default, this folder +is the apps/ directory.

You can use Erlang.mk to bootstrap local dependencies by +using the command make new-app or make new-lib. This +command will create the necessary directories and bootstrap +the application.

For example, to create a full fledged OTP application as +a local dependency:

$ make new-app in=webchat

Or, the same as an OTP library:

$ make new-lib in=webchat

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:

$ make new t=gen_server n=my_server in=webchat

7.7. Repositories with no application at the root level

It’s possible to use Erlang.mk with only applications in +$(APPS_DIR), and nothing at the root of the repository. +Just create a folder, put the erlang.mk file in it, +write a Makefile that includes it, and start creating +your applications.

Similarly, it’s possible to have a repository with only +dependencies found in $(DEPS_DIR). 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.

7.8. Autopatch

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.

When fetching a dependency, the following operations are +performed:

  • +Fetch the dependency using the configured fetch method +
  • +If it contains a configure.ac or configure.in file, run autoreconf -Wall -vif -I m4 +
  • +If it contains a configure script, run it +
  • +Run autopatch on the project +

Autopatch first checks if there is any project-specific patch +enabled. There are currently two: RABBITMQ_CLIENT_PATCH for +the amqp_client dependency, and RABBITMQ_SERVER_PATCH for +the rabbit dependency. These are needed only for RabbitMQ +versions before 3.6.0 (assuming you are using upstream RabbitMQ, +and not a fork).

Otherwise, autopatch performs different operations depending +on the kind of project it finds the dependency to be.

  • +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. +
  • +Erlang.mk projects have their erlang.mk 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. +
  • +Other Erlang projects get a small Erlang.mk Makefile +generated automatically. +
  • +Projects with no source directory and no Makefile get an +empty Makefile generated, for compatibility purposes. +
  • +Other projects with no Makefile are left untouched. +

You can disable the replacing of the erlang.mk file by +defining the NO_AUTOPATCH_ERLANG_MK variable:

NO_AUTOPATCH_ERLANG_MK = 1

You can also disable autopatch entirely for a few select +projects using the NO_AUTOPATCH variable:

NO_AUTOPATCH = cowboy ranch cowlib

7.9. Skipping deps

It is possible to temporarily skip all dependency operations. +This is done by defining the SKIP_DEPS variable. Use cases +include being somewhere with no connection to download them, +or perhaps a peculiar setup.

A typical usage would be:

$ make SKIP_DEPS=1

When the variable is defined:

  • +Dependencies will not be compiled or downloaded when required +
  • +The dependency directory $(DEPS_DIR) will not be removed on make distclean +

This variable only applies to remote dependencies.

+
+ + diff --git a/guide/dialyzer.html b/guide/dialyzer.html new file mode 100644 index 0000000..dc9245f --- /dev/null +++ b/guide/dialyzer.html @@ -0,0 +1,66 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 20. Dialyzer

Dialyzer is a tool that will detect discrepancies in your +program. It does so using a technique known as success +typing analysis which has the advantage of providing no +false positives. Dialyzer is able to detect type errors, +dead code and more.

Erlang.mk provides a wrapper around Dialyzer.

20.1. How it works

Dialyzer requires a PLT file to work. The PLT file contains +the analysis information from all applications which are not +expected to change, or rarely do. These would be all the +dependencies of the application or applications you are +currently working on, including standard applications in +Erlang/OTP itself.

Dialyzer can generate this PLT file. Erlang.mk includes rules +to automatically generate the PLT file when it is missing.

Once the PLT file is generated, Dialyzer can perform the +analysis in record time.

20.2. Configuration

In a typical usage scenario, no variable needs to be set. +The defaults should be enough. Do note however that the +dependencies need to be set properly using the DEPS and +LOCAL_DEPS variables.

The DIALYZER_PLT file indicates where the PLT file will +be written to (and read from). By default this is +$(PROJECT).plt in the project’s directory. Note that +the DIALYZER_PLT variable is exported and is understood +by Dialyzer directly.

The PLT_APPS variable can be used to add additional +applications to the PLT. You can either list application +names or paths to these applications.

Erlang.mk defines two variables for specifying options +for the analysis: DIALYZER_DIRS and DIALYZER_OPTS. +The former one defines which directories should be part +of the analysis. The latter defines what extra warnings +Dialyzer should report.

Note that Erlang.mk enables the race condition warnings +by default. As it can take considerably large resources +to run, you may want to disable it on larger projects.

20.3. Usage

To perform an analysis, run the following command:

$ make dialyze

This will create the PLT file if it doesn’t exist.

The analysis will also be performed when you run the +following command, alongside tests:

$ make check

You can use the plt target to create the PLT file if +it doesn’t exist. This is normally not necessary as +Dialyzer creates it automatically.

The PLT file will be removed when you run make distclean.

+
+ + diff --git a/guide/docs.html b/guide/docs.html new file mode 100644 index 0000000..8eb46ea --- /dev/null +++ b/guide/docs.html @@ -0,0 +1,37 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Part II. Documentation

+
+ + diff --git a/guide/edoc.html b/guide/edoc.html new file mode 100644 index 0000000..13e57e6 --- /dev/null +++ b/guide/edoc.html @@ -0,0 +1,37 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 13. EDoc comments

Placeholder chapter.

+
+ + diff --git a/guide/escript.html b/guide/escript.html new file mode 100644 index 0000000..fab46fb --- /dev/null +++ b/guide/escript.html @@ -0,0 +1,37 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 10. Escripts

Placeholder chapter.

+
+ + diff --git a/guide/eunit.html b/guide/eunit.html new file mode 100644 index 0000000..e421b69 --- /dev/null +++ b/guide/eunit.html @@ -0,0 +1,75 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 15. EUnit

EUnit is the tool of choice for unit testing. Erlang.mk +automates a few things on top of EUnit, including the +discovery and running of unit tests.

15.1. Writing tests

The EUnit user guide +is the best place to learn how to write tests. Of note is +that all functions ending with _test or _test_ will be +picked up as EUnit test cases.

Erlang.mk will automatically pick up tests found in any of +the Erlang modules of your application. It will also pick up +tests located in the $(TEST_DIR) directory, which defaults +to test/.

It is generally a good practice to hide test code from +the code you ship to production. With Erlang.mk, you can +do this thanks to the TEST macro. It is only defined +when running tests:

-ifdef(TEST).
+
+%% Insert tests here.
+
+-endif.

Be careful, however, if you include the EUnit header file, +as it also defines the TEST macro. Make sure to only include +it inside an ifdef block, otherwise tests will always be +compiled.

-ifdef(TEST).
+
+-include_lib(\"eunit/include/eunit.hrl\").
+
+%% Insert tests here.
+
+-endif.

Erlang.mk will automatically recompile your code when you +perform a normal build after running tests, and vice versa.

15.2. Configuration

The EUNIT_OPTS variable allows you to specify additional +EUnit options. Options are documented in the +EUnit manual. +At the time of writing, the only available option is verbose:

EUNIT_OPTS = verbose

The EUNIT_ERL_OPTS variable allows you to specify options +to be passed to erl when running EUnit tests. For example, +you can load the vm.args and sys.config files:

EUNIT_ERL_OPTS = -args_file rel/vm.args -config rel/sys.config

15.3. Usage

To run all tests (including EUnit):

$ make tests

To run all tests and static checks (including EUnit):

$ make check

You can also run EUnit separately:

$ make eunit

EUnit will be quiet by default, only outputting errors. +You can easily make it verbose for a single invocation:

$ make eunit EUNIT_OPTS=verbose

Erlang.mk allows you to run all tests from a specific +module, or a specific test case from that module, using +the variable t.

For example, to run all tests from the cow_http_hd +module (instead of all tests from the entire project), +one could write:

$ make eunit t=cow_http_hd

Similarly, to run a specific test case:

$ make eunit t=cow_http_hd:parse_accept_test_

To do the same against a multi-application repository, +you can use the -C option:

$ make -C apps/my_app eunit t=my_module:hello_test

Note that this also applies to dependencies. From Cowboy, +you can run the following directly:

$ make -C deps/cowlib eunit t=cow_http_hd

Finally, code coverage is available, +but covered in its own chapter.

+
+ + diff --git a/guide/getting_started.html b/guide/getting_started.html new file mode 100644 index 0000000..3ffaa9a --- /dev/null +++ b/guide/getting_started.html @@ -0,0 +1,164 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 2. Getting started

This chapter explains how to get started using Erlang.mk.

2.1. Creating a folder for your project

The first step is always to create a new folder that will +contain your project.

$ mkdir hello_joe
+$ cd hello_joe

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 $HOME/ninenines/cowboy for +the Cowboy project.

2.2. Downloading Erlang.mk

At the time of writing, Erlang.mk is unlikely to be present +in your Erlang distribution, or even in your OS packages.

The next step is therefore to download it:

$ wget https://raw.githubusercontent.com/ninenines/erlang.mk/master/erlang.mk

Or:

$ curl https://raw.githubusercontent.com/ninenines/erlang.mk/master/erlang.mk

Alternatively, just click on this link.

Make sure you put the file inside the folder we created previously.

2.3. Getting started with OTP applications

An OTP application is an Erlang application that has a supervision +tree. In other words, it will always have processes running.

This kind of project can be automatically generated by Erlang.mk. +All you need to do is use the bootstrap target:

$ make -f erlang.mk bootstrap

Something similar to the following snippet will then appear +on your screen:

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

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 +Updating Erlang.mk chapter for more +information.

Of course, the generated project can now be compiled:

$ make

Cheers!

2.4. Getting started with OTP libraries

An OTP library is an Erlang application that has no supervision +tree. In other words, it is nothing but modules.

This kind of project can also be generated by Erlang.mk, using +the bootstrap-lib target:

$ make -f erlang.mk bootstrap-lib

Erlang.mk will once again bootstrap itself and generate all +the files for your project. You can now compile it:

$ make

Enjoy!

2.5. Getting started with OTP releases

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.

Erlang.mk can of course bootstrap your project to generate releases. +You can use the bootstrap-rel target for this purpose:

$ make bootstrap-rel

This target can be combined with bootstrap or bootstrap-lib to +create a project that will build a release:

$ make -f erlang.mk bootstrap-lib bootstrap-rel

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 Packages and dependencies +chapter for more information.

When you run make from now on, Erlang.mk will compile your +project and build the release:

$ 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!

The first time you run this command, Erlang.mk will download +relx, the release building tool. So don’t worry if you see +more output than above.

If building the release is slow, no need to upgrade your +hardware just yet. Just consult the Releases +chapter for various tips to speed up build time during +development.

You can start the release using the ./_rel/hello_joe_release/bin/hello_joe_release +script, or simply run make run. The latter will also compile +your project and build the release if it wasn’t already:

$ 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)
+(hello_joe@127.0.0.1)1>

Simple as that!

2.6. Using spaces instead of tabs

Erlang.mk defaults to tabs when creating files from templates. +This is in part because of a personal preference, and in part +because it is much easier to convert tabs to spaces than the +opposite.

Use the SP variable if you prefer spaces. Set it to the number +of spaces per indentation level you want.

For example, if you prefer two spaces per indentation level:

$ make -f erlang.mk bootstrap SP=2

When you bootstrap the project initially, the variable automatically +gets added to the Makefile, so you only need to provide it when +you get started.

2.7. Using templates

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!

You can list all available templates with the list-templates +target:

$ make list-templates
+Available templates: cowboy_http cowboy_loop cowboy_rest cowboy_ws gen_fsm gen_server ranch_protocol supervisor

To generate a module, let’s say a gen_server, all you need to +do is to call make new with the appropriate arguments:

$ make new t=gen_server n=my_server

This will create a module located in src/my_server.erl +using the gen_server template.

This module is automatically compiled the next time you run +make:

$ make
+ ERLC   my_server.erl
+ APP    hello_joe.app.src

All that’s left to do is to open it in your favorite editor +and make it do something!

2.8. Getting help

During development, if you don’t remember the name of a target, +you can always run make help:

$ 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 <essen@ninenines.eu>
+
+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
+...

This guide should provide any other answer. If not, please +open a ticket on the official repository +and we will work on improving the guide.

Commercial support is available through Nine Nines. Please contact +Loïc Hoguin by sending an email to contact@ninenines.eu.

+
+ + diff --git a/guide/history.html b/guide/history.html new file mode 100644 index 0000000..e4b24e6 --- /dev/null +++ b/guide/history.html @@ -0,0 +1,67 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 24. Short history

This chapter aims to be a brief record of the life of the +Erlang.mk project.

24.1. Before Erlang.mk

Erlang.mk originates from the Cowboy project. Cowboy started +as a Rebar project and I, Loïc Hoguin, was very happy with it +for a couple years. Over time however I started getting annoyed +and frustrated by a number of things, including bad defaults, +changing defaults and overall slowness.

In particular, at the time I gave up on Rebar, the Cowboy +test suite was taking about five minutes to run. A quick experiment +showed I could get much lower times by simply invoking ct_run +directly. On January 4th, 2013, the Cowboy test suite took less +than a minute to complete.

Following this success I started removing a little more and, +on the fateful day of January 5th, 2013, removed the dependency +on Rebar entirely. Rebar, and in particular the concept of +dependencies, was, and still is, a pretty strong influence.

Erlang.mk was conceived.

A few months passed and, on May 1st, 2013, the Erlang.mk +repository was created. Erlang.mk was born.

Little did I know how much it would grow.

24.2. Lifetime of the project

Erlang.mk would eventually become a much larger file able to +deal with many more projects than just Cowboy. From the birth +of the project, the biggest force for growth was user contributions, +because Erlang.mk appealed to a variety of people with different +needs, needs that Erlang.mk was not fulfilling yet.

The project was split into smaller files focused on a different +feature each, and a build script was written to build the single +Erlang.mk file.

A test suite was contributed by a user, and later taken as a basis +for the current, much more complete test suite. Turns out testing +a Makefile is pretty straightforward.

A package index was added to solve the problem of discovering +Erlang projects.

After trying to see if Erlang build tools could cooperate, the +decision was made to improve compatibility with existing Rebar +projects by patching Rebar out, using Rebar. This feature, called +autopatch, proved very successful and made Erlang.mk compatible +with more than 90% of all Erlang projects.

Erlang.mk documentation was much improved and the Erlang.mk website +was created in the summer of 2015.

Over the year of 2015, Erlang.mk went from curiosity to a serious +alternative to other Erlang build tools. The user base increased +immensely and large projects started using it, including RabbitMQ +from the 3.6.0 release onward.

A bright future lies ahead.

+
+ + diff --git a/guide/index.html b/guide/index.html index 3917974..f977737 100644 --- a/guide/index.html +++ b/guide/index.html @@ -31,7 +31,7 @@ div.navfooter{margin-bottom:1em}
-

Erlang.mk User Guide

Loïc Hoguin


Table of Contents

1. Installation
1.1. On Unix
1.2. On Windows
2. Getting started
2.1. Creating a folder for your project
2.2. Downloading Erlang.mk
2.3. Getting started with OTP applications
2.4. Getting started with OTP libraries
2.5. Getting started with OTP releases
2.6. Using spaces instead of tabs
2.7. Using templates
2.8. Getting help
3. Overview
3.1. Building your project
3.2. Exploring the package index
3.3. Generating documentation
3.4. Running tests
3.5. Need more?
4. Updating Erlang.mk
4.1. Initial bootstrap
4.2. Updating
4.3. Customizing the build
5. Limitations
5.1. Erlang must be available
5.2. Spaces in path
5.3. Dependency tracking and modification times
I. Code
6. Building
6.1. How to build
6.2. What to build
6.3. Application resource file
6.4. Automatic application resource file values
6.5. File formats
6.6. Compilation options
6.7. Cold and hot builds
6.8. Dependency tracking
6.9. Generating Erlang source
6.10. Cleaning
7. Packages and dependencies
7.1. Searching packages
7.2. Adding dependencies to your project
7.3. How deps are fetched and built
7.4. Ignoring unwanted dependencies
7.5. Dependencies directory
7.6. Dependencies local to the repository
7.7. Repositories with no application at the root level
7.8. Autopatch
7.9. Skipping deps
8. NIFs and port drivers
8.1. C source code location and Erlang environment
8.2. Using a custom Makefile
8.3. Using Erlang.mk directly
9. Releases
9.1. Setup
9.2. Configuration
9.3. Generating the release
9.4. Running the release
10. Escripts
11. Compatibility with other build tools
11.1. Rebar projects as Erlang.mk dependencies
11.2. Erlang.mk projects as Rebar dependencies
II. Documentation
12. Asciidoc documentation
13. EDoc comments
III. Tests
14. Erlang shell
14.1. Configuration
14.2. Usage
15. EUnit
15.1. Writing tests
15.2. Configuration
15.3. Usage
16. Common Test
17. Property based testing
18. Code coverage
19. Continuous integration
20. Dialyzer
20.1. How it works
20.2. Configuration
20.3. Usage
21. Xref
IV. Third-party plugins
22. External plugins
22.1. Loading all plugins from a dependency
22.2. Loading one plugin from a dependency
22.3. Writing external plugins
V. About Erlang.mk
23. Why Erlang.mk
23.1. Erlang.mk is fast
23.2. Erlang.mk gives you the full power of Unix
23.3. Erlang.mk is a text file
23.4. Erlang.mk can manage Erlang itself
23.5. Erlang.mk can do more than Erlang
23.6. Erlang.mk integrates nicely in Make and Automake projects
24. Short history
24.1. Before Erlang.mk
24.2. Lifetime of the project
25. Contributing
25.1. Priorities
25.2. Bugs
25.3. Code
25.4. Packages
25.5. Documentation
25.6. Feature requests
+

Erlang.mk User Guide

Loïc Hoguin


Table of Contents

1. Installation
1.1. On Unix
1.2. On Windows
2. Getting started
2.1. Creating a folder for your project
2.2. Downloading Erlang.mk
2.3. Getting started with OTP applications
2.4. Getting started with OTP libraries
2.5. Getting started with OTP releases
2.6. Using spaces instead of tabs
2.7. Using templates
2.8. Getting help
3. Overview
3.1. Building your project
3.2. Exploring the package index
3.3. Generating documentation
3.4. Running tests
3.5. Need more?
4. Updating Erlang.mk
4.1. Initial bootstrap
4.2. Updating
4.3. Customizing the build
5. Limitations
5.1. Erlang must be available
5.2. Spaces in path
5.3. Dependency tracking and modification times
I. Code
6. Building
6.1. How to build
6.2. What to build
6.3. Application resource file
6.4. Automatic application resource file values
6.5. File formats
6.6. Compilation options
6.7. Cold and hot builds
6.8. Dependency tracking
6.9. Generating Erlang source
6.10. Cleaning
7. Packages and dependencies
7.1. Searching packages
7.2. Adding dependencies to your project
7.3. How deps are fetched and built
7.4. Ignoring unwanted dependencies
7.5. Dependencies directory
7.6. Dependencies local to the repository
7.7. Repositories with no application at the root level
7.8. Autopatch
7.9. Skipping deps
8. NIFs and port drivers
8.1. C source code location and Erlang environment
8.2. Using a custom Makefile
8.3. Using Erlang.mk directly
9. Releases
9.1. Setup
9.2. Configuration
9.3. Generating the release
9.4. Running the release
10. Escripts
11. Compatibility with other build tools
11.1. Rebar projects as Erlang.mk dependencies
11.2. Erlang.mk projects as Rebar dependencies
II. Documentation
12. Asciidoc documentation
13. EDoc comments
III. Tests
14. Erlang shell
14.1. Configuration
14.2. Usage
15. EUnit
15.1. Writing tests
15.2. Configuration
15.3. Usage
16. Common Test
16.1. Writing tests
16.2. Configuration
16.3. Usage
17. Property based testing
18. Code coverage
19. Continuous integration
20. Dialyzer
20.1. How it works
20.2. Configuration
20.3. Usage
21. Xref
IV. Third-party plugins
22. External plugins
22.1. Loading all plugins from a dependency
22.2. Loading one plugin from a dependency
22.3. Writing external plugins
V. About Erlang.mk
23. Why Erlang.mk
23.1. Erlang.mk is fast
23.2. Erlang.mk gives you the full power of Unix
23.3. Erlang.mk is a text file
23.4. Erlang.mk can manage Erlang itself
23.5. Erlang.mk can do more than Erlang
23.6. Erlang.mk integrates nicely in Make and Automake projects
24. Short history
24.1. Before Erlang.mk
24.2. Lifetime of the project
25. Contributing
25.1. Priorities
25.2. Bugs
25.3. Code
25.4. Packages
25.5. Documentation
25.6. Feature requests
diff --git a/guide/installation.html b/guide/installation.html new file mode 100644 index 0000000..99f7344 --- /dev/null +++ b/guide/installation.html @@ -0,0 +1,80 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 1. Installation

This chapter explains how to setup your system in +order to use Erlang.mk.

1.1. On Unix

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.

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.

Erlang.mk currently requires Erlang/OTP to be installed in +order to compile Erlang projects.

Some packages may require additional libraries.

1.2. On Windows

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.

The rest of this section details how to setup Erlang/OTP and +MSYS2 in order to use Erlang.mk.

1.2.1. Installing Erlang/OTP

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 official download page. +It is recommended that you use the 64-bit installer unless +technically impossible. Please follow the instructions from +the installer to complete the installation.

The OTP team also provides a short guide to +installing Erlang/OTP on Windows +if you need additional references.

You can install Erlang/OTP silently using the /S switch +on the command line:

C:\Users\essen\Downloads> otp_win64_18.0.exe /S

1.2.2. Installing MSYS2

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, pacman.

The MSYS2 project provides a one click installer +and instructions to set things up post-installation.

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 +7zip to decompress it.

First, download the +MSYS2 base archive +and extract it under C:\. Assuming you downloaded the +archive as msys2.tar.xz and put it in C:\, you can +use the following commands to extract it:

C:\> 7z x msys2.tar.xz
+C:\> 7z x msys2.tar > NUL

Then you can run the two commands needed to perform the +post-installation setup:

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"

1.2.3. Installing the required MSYS2 packages

After following these instructions, you can install GNU Make, +Git and any other required softwares. From an MSYS2 shell, +you can call pacman directly:

$ pacman -S git make

You can use pacman -Ss to search packages. For example, +to find all packages related to GCC:

$ pacman -Ss gcc

If you are going to compile C/C++ code, you will need to +install this package, as Erlang.mk cannot use the normal +"gcc" package:

$ pacman -S mingw-w64-x86_64-gcc

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:

C:\> C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S git make"

You can use similar bash commands if you need to run programs +inside the MSYS2 environment from a batch file.

1.2.4. Gotchas

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.

+
+ + diff --git a/guide/limitations.html b/guide/limitations.html new file mode 100644 index 0000000..9345ba2 --- /dev/null +++ b/guide/limitations.html @@ -0,0 +1,55 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 5. Limitations

No software is perfect.

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.

This chapter lists all known limitations of Erlang.mk.

5.1. Erlang must be available

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.

In addition, the Erlang being used must be in your $PATH +before you use Erlang.mk.

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 make ci, so doing this during +development is just a step away.

5.2. Spaces in path

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 pwd.

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.

5.3. Dependency tracking and modification times

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.

Erlang.mk must use this method in order to be able to compile +files in one erlc invocation. The benefits greatly outweigh +the issue in this case and so there are currently no plans to +fix this behavior.

+
+ + diff --git a/guide/overview.html b/guide/overview.html new file mode 100644 index 0000000..c32df52 --- /dev/null +++ b/guide/overview.html @@ -0,0 +1,72 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 3. Overview

Now that you know how to get started, let’s take a look at +what Erlang.mk can do for you.

3.1. Building your project

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.

Erlang.mk will happily build all Erlang-specific files +you throw at it. Other kinds of files too, like C or C++ code +when you are working on a NIF or a port driver.

Erlang.mk embraces the concept of source dependencies. +It can fetch dependency source code using a variety of mechanisms, +including fetching from Git, Mercurial or SVN.

Erlang.mk will automatically generate releases +when applicable. It can also generate escripts.

3.2. Exploring the package index

Erlang.mk comes with a built-in package index. +It is built as an extension of the dependency system and is +meant to be used for discovery purposes.

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.

You can get a list of all packages known to Erlang.mk by using +the search target:

$ make search

You can also use this target to search across all packages, for +example to find all packages related to Cowboy:

$ make search q=cowboy

3.3. Generating documentation

Erlang.mk supports EDoc and Asciidoc.

EDoc generates HTML documentation directly from +your source code.

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 Asciidoc comes in.

The Asciidoc 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 doc/src/ folder in +your repository.

3.4. Running tests

Erlang.mk supports a lot of different testing and static +analysis tools.

The make shell command allows you +to test your project manually. You can automate these +unit tests with EUnit and test +your entire system with Common Test. +Property based testing +with Triq is a strong alternative to writing unit tests +manually. Code coverage can of course +be enabled during tests.

Erlang.mk comes with features to make your life easier when +setting up and using Continuous integration.

On the static analysis side of things, Erlang.mk comes with +support for Dialyzer, Xref +and Elvis, performing success typing +analysis, cross reference and style reviewing.

3.5. Need more?

Not convinced yet? You can read about why you should use Erlang.mk +and its history. 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.

+
+ + diff --git a/guide/plugins.html b/guide/plugins.html new file mode 100644 index 0000000..e1a6622 --- /dev/null +++ b/guide/plugins.html @@ -0,0 +1,37 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Part IV. Third-party plugins

+
+ + diff --git a/guide/plugins_usage.html b/guide/plugins_usage.html new file mode 100644 index 0000000..a72e402 --- /dev/null +++ b/guide/plugins_usage.html @@ -0,0 +1,69 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 22. External plugins

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.

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.

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.

22.1. Loading all plugins from a dependency

To load plugins from a dependency, all you need to do is add +the dependency name to DEP_PLUGINS in addition to the list +of dependencies.

For example, if you have cowboy in DEPS, add cowboy in +DEP_PLUGINS also:

DEPS = cowboy
+DEP_PLUGINS = cowboy

This will load the file plugins.mk in the root folder of +the Cowboy repository.

22.2. Loading one plugin from a dependency

Now that we know how to load all plugins, let’s take a look +at how to load one specific plugin from a dependency.

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 DEP_PLUGINS = cowboy is equivalent to +writing DEP_PLUGINS = cowboy/plugins.mk.

Knowing this, if we were to load the plugin mk/dist.mk +from Cowboy and no other, we would write the following in +our Makefile:

DEPS = cowboy
+DEP_PLUGINS = cowboy/mk/dist.mk

22.3. Writing external plugins

The plugins.mk 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 plugins.mk or be separate.

If you are providing more than one plugin with your repository, +the recommended way is to create one file per plugin in the +mk/ folder in your repository, and then include those +individual plugins in plugins.mk.

For example, if you have two plugins mk/dist.mk and +mk/templates.mk, you could write the following plugins.mk +file:

THIS := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
+include $(THIS)/mk/dist.mk
+include $(THIS)/mk/templates.mk

The THIS variable is required to relatively include files.

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.

+
+ + diff --git a/guide/ports.html b/guide/ports.html new file mode 100644 index 0000000..b09ea2a --- /dev/null +++ b/guide/ports.html @@ -0,0 +1,99 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 8. NIFs and port drivers

Erlang.mk can not only build Erlang projects, but also the C code +that some projects come with, like NIFs and port drivers.

There are two ways to build the C code: using a custom Makefile, +or making Erlang.mk do it directly. The C code will be built +as needed when you run make.

8.1. C source code location and Erlang environment

The C source code should be located in the $(C_SRC_DIR) directory. +It defaults to c_src/. Should you need to modify it, all you +need to do is to set the variable in your Makefile before including +Erlang.mk:

C_SRC_DIR = $(CURDIR)/my_nif_source

When this directory exists, Erlang.mk will automatically create a +file named $(C_SRC_ENV). This file defaults to $(C_SRC_DIR)/env.mk. +This can also be changed:

C_SRC_ENV = $(C_SRC_DIR)/erlang_env.mk

It contains a few variable definitions for the environment used for the build:

+ERTS_INCLUDE_DIR +
+ Path to the ERTS include files (erl_driver.h, erl_nif.h and more). +
+ERL_INTERFACE_INCLUDE_DIR +
+ Path to the Erl_Interface include files (ei.h and related). +
+ERL_INTERFACE_LIB_DIR +
+ Path to the Erl_Interface static libraries. +

8.2. Using a custom Makefile

Erlang.mk will automatically run make if it detects a Makefile +in $(C_SRC_DIR)/Makefile.

The Makefile should have at least two targets: a default target +(which can be anything, for example all) which is invoked when +building the C code, and a clean target invoked when cleaning +it.

You can include the env.mk file to benefit from the Erlang +environment detection:

include env.mk

8.3. Using Erlang.mk directly

You don’t need to write a Makefile to build C source code, however. +Erlang.mk comes with rules to build both shared libraries and +executables, using the source files it finds in $(C_SRC_DIR).

By default, Erlang.mk will create a shared library. To change +this and create an executable instead, put this in your Makefile +before including Erlang.mk:

C_SRC_TYPE = executable

The generated file name varies depending on the type of project +you have (shared library or executable) and on the platform you +build the project on.

For shared libraries, the generated file name will be +$(C_SRC_OUTPUT)$(C_SRC_SHARED_EXTENSION), with the default +being $(CURDIR)/priv/$(PROJECT) followed by the extension: +.dll on Windows, .so everywhere else.

For executables, the generated file name is +$(C_SRC_OUTPUT)$(C_SRC_EXECUTABLE_EXTENSION), with the same +default except for the extension: .exe on Windows, and otherwise +nothing.

Erlang.mk sets appropriate compile and linker flags by default. +These flags vary depending on the platform, and can of course +be overriden.

+CC +
+ The compiler to be used. +
+CFLAGS +
+ C compiler flags. +
+CXXFLAGS +
+ C++ compiler flags. +
+LDFLAGS +
+ Linker flags. +
+LDLIBS +
+ Libraries to link against. +

The source files are automatically gathered from the contents +of $(C_SRC_DIR). Erlang.mk looks for .c, .C, .cc and .cpp +source files. You can define the variable SOURCES to manually +list the files to compile.

+
+ + diff --git a/guide/property_based_testing.html b/guide/property_based_testing.html new file mode 100644 index 0000000..753856b --- /dev/null +++ b/guide/property_based_testing.html @@ -0,0 +1,37 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 17. Property based testing

Placeholder chapter.

+
+ + diff --git a/guide/pt01.html b/guide/pt01.html deleted file mode 100644 index 06a0679..0000000 --- a/guide/pt01.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Part I. Code

-
- - diff --git a/guide/pt02.html b/guide/pt02.html deleted file mode 100644 index 8127606..0000000 --- a/guide/pt02.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Part II. Documentation

-
- - diff --git a/guide/pt03.html b/guide/pt03.html deleted file mode 100644 index 23b74bf..0000000 --- a/guide/pt03.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Part III. Tests

-
- - diff --git a/guide/pt04.html b/guide/pt04.html deleted file mode 100644 index caea47c..0000000 --- a/guide/pt04.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Part IV. Third-party plugins

-
- - diff --git a/guide/pt05.html b/guide/pt05.html deleted file mode 100644 index b3b80a4..0000000 --- a/guide/pt05.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Erlang.mk User Guide - - - -
- - - -
-
- -

Part V. About Erlang.mk

-
- - diff --git a/guide/relx.html b/guide/relx.html new file mode 100644 index 0000000..e1671dc --- /dev/null +++ b/guide/relx.html @@ -0,0 +1,56 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 9. Releases

Erlang.mk relies on Relx for generating releases. This +chapter covers the Erlang.mk-specific bits. Consult the +Relx website for more information.

9.1. Setup

Erlang.mk will create a release if it detects a Relx configuration +file in the $(RELX_CONFIG) location. This defaults to +$(CURDIR)/relx.config. You can override it by defining +the variable before including Erlang.mk:

RELX_CONFIG = $(CURDIR)/webchat.config

Relx does not need to be installed. Erlang.mk will download +and build it automatically.

The Relx executable will be saved in the $(RELX) file. This +location defaults to $(CURDIR)/relx and can be overriden.

9.2. Configuration

You can specify additional Relx options using the RELX_OPTS +variable. For example, to enable dev_mode:

RELX_OPTS = -d true

While you can specify the output directory for the release +in the Relx options directly, Erlang.mk provides a specific +variable for it: RELX_OUTPUT_DIR. It defaults to the _rel +directory. You can also override it:

RELX_OUTPUT_DIR = /path/to/staging/directory

9.3. Generating the release

Now that you’re all set, all you need to do is generate the +release. As mentioned before, Erlang.mk will automatically +generate it when it detects the $(RELX_CONFIG) file. This +means the following command will also build the release:

$ make

If you need to generate the release, and only the release, +the rel target can be used:

$ make rel

9.4. Running the release

Erlang.mk provides a convenience function for running the +release with one simple command:

$ make run

This command will also build the project and generate the +release if they weren’t already. It starts the release in +console mode, meaning you will also have a shell ready to +use to check things as needed.

+
+ + diff --git a/guide/shell.html b/guide/shell.html new file mode 100644 index 0000000..ba172d6 --- /dev/null +++ b/guide/shell.html @@ -0,0 +1,46 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 14. Erlang shell

Erlang.mk provides a convenient target for starting a shell +with all the paths set properly to experiment with your code.

14.1. Configuration

The SHELL_DEPS variable can be used to define dependencies +that are only to be used when the make shell command is called. +For example, if you want to use kjell as your shell:

SHELL_DEPS = kjell

Dependencies are downloaded and compiled the first time you +run the make shell command.

You can customize the executable used to start the Erlang shell. +To continue with our example, if you want to use kjell as your +shell, you also need to change SHELL_ERL and point it to the +kjell executable:

SHELL_ERL = $(DEPS_DIR)/kjell/bin/kjell

You can specify additional options to be used when starting the +shell using the SHELL_OPTS variable:

SHELL_OPTS = -setcookie chocolate

Any of the usual erl options can be used, including -eval:

SHELL_OPTS = -eval 'my_app:run()'

14.2. Usage

To start the shell, all you need is the following command:

$ make shell

The shell can be stopped as usual with a double Ctrl+C or the +command q()..

+
+ + diff --git a/guide/tests.html b/guide/tests.html new file mode 100644 index 0000000..f99c07e --- /dev/null +++ b/guide/tests.html @@ -0,0 +1,37 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Part III. Tests

+
+ + diff --git a/guide/updating.html b/guide/updating.html new file mode 100644 index 0000000..a207549 --- /dev/null +++ b/guide/updating.html @@ -0,0 +1,69 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 4. Updating Erlang.mk

This chapter describes how to update the erlang.mk file +in your repository.

4.1. Initial bootstrap

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.

4.2. Updating

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.

That’s why updating Erlang.mk is so simple. All you need +to do is to call make erlang-mk:

$ 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

All that’s left to do is to commit the file!

Yep, it’s that easy.

4.3. Customizing the build

Erlang.mk allows you to customize which plugins are to be included +in the erlang.mk file. You can do so by maintaining your own +build.config file in your repository. Erlang.mk will automatically +use it the next time you run make erlang-mk.

The build.config file contains the list of all files that will +be built into the resulting erlang.mk file. You can start from +the most recent version +and customize to your needs.

You can also name the file differently or put it in a separate folder +by modifying the value for ERLANG_MK_BUILD_CONFIG. You can also +tell Erlang.mk to use a different temporary directory by changing +the ERLANG_MK_BUILD_DIR variable.

+
+ + diff --git a/guide/why.html b/guide/why.html new file mode 100644 index 0000000..863606e --- /dev/null +++ b/guide/why.html @@ -0,0 +1,70 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 23. Why Erlang.mk

Why would you choose Erlang.mk, if not for its +many features? This chapter will +attempt to answer that.

23.1. Erlang.mk is fast

Erlang.mk is as fast as it gets.

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.

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.

23.2. Erlang.mk gives you the full power of Unix

Erlang.mk is a Makefile.

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.

In all cases: for configuration, hooks or custom rules, you +have all the power of Unix at your disposal, and can call +any utility or even any language interpreter 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…

23.3. Erlang.mk is a text file

Erlang.mk is a Makefile.

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 +erlang.mk file in your favorite editor, fix and/or comment +a few lines, save, and try again. It’s as simple as it gets.

Currently using a binary build tool? Good luck with that.

23.4. Erlang.mk can manage Erlang itself

Erlang.mk isn’t written in Erlang.

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.

This really is a one-liner in Erlang.mk (a few more lines +if you also let it download and build Erlang directly) +and allows for even greater things, like testing your +project across all supported Erlang versions in one small +command: make -k ci.

23.5. Erlang.mk can do more than Erlang

Erlang.mk doesn’t care what your dependencies are written in.

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.

23.6. Erlang.mk integrates nicely in Make and Automake projects

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.

Erlang.mk will happily sit in such an environment and behave +as you expect it to.

+
+ + diff --git a/guide/xref.html b/guide/xref.html new file mode 100644 index 0000000..de9bc8d --- /dev/null +++ b/guide/xref.html @@ -0,0 +1,37 @@ + + + + +Erlang.mk User Guide + + + +
+ + + +
+
+ +

Chapter 21. Xref

Placeholder chapter.

+
+ + -- cgit v1.2.3