diff options
Diffstat (limited to 'doc/src/guide')
-rw-r--r-- | doc/src/guide/app.asciidoc | 146 | ||||
-rw-r--r-- | doc/src/guide/book.asciidoc | 14 | ||||
-rw-r--r-- | doc/src/guide/compat.asciidoc | 88 | ||||
-rw-r--r-- | doc/src/guide/external_plugins.asciidoc | 7 | ||||
-rw-r--r-- | doc/src/guide/installation.asciidoc | 112 | ||||
-rw-r--r-- | doc/src/guide/limitations.asciidoc | 45 | ||||
-rw-r--r-- | doc/src/guide/why.asciidoc | 80 |
7 files changed, 482 insertions, 10 deletions
diff --git a/doc/src/guide/app.asciidoc b/doc/src/guide/app.asciidoc index a04c5a9..5c097f6 100644 --- a/doc/src/guide/app.asciidoc +++ b/doc/src/guide/app.asciidoc @@ -165,6 +165,36 @@ 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: + +[source,bash] +$ make -f erlang.mk bootstrap-lib LEGACY=1 + +=== 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: + +[source,erlang] +---- +1> application:get_all_key(cowboy). +{ok,[{description,"Small, fast, modular HTTP server."}, + {id,"2.0.0-pre.2-25-g0ffde50-dirty"}, +---- + === File formats Erlang.mk supports a variety of different source file formats. @@ -201,6 +231,56 @@ Erlang.mk also comes with plugins for the following formats: | .proto | src/ | Protocol buffers | ebin/*.beam |=== +=== Compilation options + +Erlang.mk provides a few variables that you can use to customize +the build process and the resulting files. + +==== 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 http://www.erlang.org/doc/man/erlc.html[erlc Manual] for the +full list. + +By default, Erlang.mk will set the following options: + +[source,make] +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: + +[source,make] +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. + +[source,make] +---- +include erlang.mk + +ERLC_OPTS := $(filter-out -Werror,$(ERLC_OPTS)) +---- + +==== 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: + +[source,make] +ERLC_EXCLUDE = cowboy_http2 + === Cold and hot builds The first time you run `make`, Erlang.mk will build everything. @@ -235,10 +315,64 @@ 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. -=== Generated source files === +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': + +[source,make] +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: + +[source,bash] +$ 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. + +=== 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: -Generated source files are supported: they should be listed as -dependencies to `$(PROJECT).d`: +[source,make] +---- +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: [source,make] ---- @@ -250,14 +384,10 @@ $(PROJECT).d:: src/generated_mod.erl include erlang.mk -src/generated_mod.erl:: +src/generated_mod.erl:: gen-mod.sh $(gen_verbose) ./gen-mod.sh $@ ---- -Note how `.DEFAULT_GOAL` is set to `all` near the beginning. Without -this, `$(PROJECT).d` would become the default target, changing the -expected behavior of this `Makefile`. - === Cleaning Building typically involves creating a lot of new files. Some diff --git a/doc/src/guide/book.asciidoc b/doc/src/guide/book.asciidoc index e42e5bf..2056dad 100644 --- a/doc/src/guide/book.asciidoc +++ b/doc/src/guide/book.asciidoc @@ -4,12 +4,26 @@ = Erlang.mk User Guide Loïc Hoguin <[email protected]> +include::installation.asciidoc[Installation] + include::getting_started.asciidoc[Getting started] include::overview.asciidoc[Overview] include::updating.asciidoc[Updating Erlang.mk] +include::limitations.asciidoc[Limitations] + += Code + +include::app.asciidoc[Building] + +include::compat.asciidoc[Compatibility with other build tools] + = Advanced include::external_plugins.asciidoc[External plugins] + += About Erlang.mk + +include::why.asciidoc[Why erlang.mk?] diff --git a/doc/src/guide/compat.asciidoc b/doc/src/guide/compat.asciidoc new file mode 100644 index 0000000..61386e7 --- /dev/null +++ b/doc/src/guide/compat.asciidoc @@ -0,0 +1,88 @@ +== 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. + +=== 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 +link:deps.asciidoc[Packages and dependencies] chapter. + +=== 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'. + +==== Rebar configuration + +Erlang.mk comes with a target that generates a 'rebar.config' +file when invoked: + +[source,bash] +$ 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 link:sanity_check.asciidoc[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: + +[source,make] +---- +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! + +==== 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/doc/src/guide/external_plugins.asciidoc b/doc/src/guide/external_plugins.asciidoc index e5fdbd7..027b1b9 100644 --- a/doc/src/guide/external_plugins.asciidoc +++ b/doc/src/guide/external_plugins.asciidoc @@ -65,8 +65,11 @@ For eaxmple, if you have two plugins 'mk/dist.mk' and file: [source,make] -include mk/dist.mk -include mk/templates.mk +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 diff --git a/doc/src/guide/installation.asciidoc b/doc/src/guide/installation.asciidoc new file mode 100644 index 0000000..94232b8 --- /dev/null +++ b/doc/src/guide/installation.asciidoc @@ -0,0 +1,112 @@ +== Installation + +This chapter explains how to setup your system in +order to use Erlang.mk. + +=== 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. + +=== 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. + +==== 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 http://www.erlang.org/download.html[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 +http://www.erlang.org/download.html[installing Erlang/OTP on Windows] +if you need additional references. + +You can install Erlang/OTP silently using the `/S` switch +on the command line: + +[source,batch] +C:\Users\essen\Downloads> otp_win64_18.0.exe /S + +==== 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 http://msys2.github.io[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 +http://sourceforge.net/projects/msys2/files/Base/x86_64/msys2-base-x86_64-20150512.tar.xz/download[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: + +[source,batch] +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: + +[source,batch] +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" + +==== 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: + +[source,bash] +$ pacman -S git make + +You can use `pacman -Ss` to search packages. For example, +to find all packages related to GCC: + +[source,bash] +$ pacman -Ss 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: + +[source,batch] +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. + +==== 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/doc/src/guide/limitations.asciidoc b/doc/src/guide/limitations.asciidoc new file mode 100644 index 0000000..86ca918 --- /dev/null +++ b/doc/src/guide/limitations.asciidoc @@ -0,0 +1,45 @@ +== 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. + +=== 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. + +=== 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. + +=== 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/doc/src/guide/why.asciidoc b/doc/src/guide/why.asciidoc new file mode 100644 index 0000000..37aa676 --- /dev/null +++ b/doc/src/guide/why.asciidoc @@ -0,0 +1,80 @@ +== Why Erlang.mk + +Why would you choose Erlang.mk, if not for its +link:overview.asciidoc[many features]? This chapter will +attempt to answer that. + +=== 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. + +=== 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... + +=== 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. + +=== 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 about 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`. + +=== 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. + +=== 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. |