aboutsummaryrefslogtreecommitdiffstats
path: root/guide/ports.html
blob: a741cbabdef8a37452d35129a177eba2a58e8b57 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Erlang.mk User Guide</title>
<style type="text/css"><!--
body{background:white;color:black;font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;justify-content:center;margin:0 auto;padding:0;width:600px}
header {align-items:center;display:flex;justify-content:center}
header nav.left{text-align:right;width:150px}
header nav.right{text-align:left;width:150px}
header nav a{display:block;margin:1.5em 1em}
main{margin-top:2em;text-align:justify}
main h2, main h3{margin-top:2em}
main h1, main div.chapter>div.titlepage h2{font-size:2em;margin-top:.67em}
a{color:#d9230f;text-decoration:none}
a:hover{text-decoration:underline}
a.xref{display:none}
h1, h2, h3{font-weight:normal}
div.navfooter{margin-bottom:1em}
--></style>
</head>
<body>
<header>
	<nav class="left">
		<a href="index.html">User guide</a>
		<a href="getting_started.html">Tutorials</a>
	</nav>
	<a href="/" class="logo"><img src="../res/logo-small.png" alt="Erlang.mk" title="Erlang.mk: A build tool for Erlang that just works" height="200" width="206"/></a>
	<nav class="right">
		<a href="https://github.com/ninenines/erlang.mk/tree/master/index">470+ packages</a>
		<a href="https://github.com/ninenines/erlang.mk/issues">Issues?</a>
	</nav>
</header>
<main>

<div class="navheader"><table width="100%" summary="Navigation header"><tr><td width="20%" align="left"><a accesskey="p" href="deps.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="relx.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a id="ports"></a>Chapter 8. NIFs and port drivers</h2></div></div></div><p>Erlang.mk can not only build Erlang projects, but also the C code
that some projects come with, like NIFs and port drivers.</p><p>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 <code class="literal">make</code>.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_c_source_code_location_and_erlang_environment"></a>8.1. C source code location and Erlang environment</h2></div></div></div><p>The C source code should be located in the <span class="emphasis"><em>$(C_SRC_DIR)</em></span> directory.
It defaults to <span class="emphasis"><em>c_src/</em></span>. Should you need to modify it, all you
need to do is to set the variable in your Makefile before including
Erlang.mk:</p><pre class="programlisting">C_SRC_DIR = $(CURDIR)/my_nif_source</pre><p>When this directory exists, Erlang.mk will automatically create a
file named <span class="emphasis"><em>$(C_SRC_ENV)</em></span>. This file defaults to <span class="emphasis"><em>$(C_SRC_DIR)/env.mk</em></span>.
This can also be changed:</p><pre class="programlisting">C_SRC_ENV = $(C_SRC_DIR)/erlang_env.mk</pre><p>It contains a few variable definitions for the environment used for the build:</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
<code class="literal">ERTS_INCLUDE_DIR</code>
</span></dt><dd>
    Path to the ERTS include files (<span class="emphasis"><em>erl_driver.h</em></span>, <span class="emphasis"><em>erl_nif.h</em></span> and more).
</dd><dt><span class="term">
<code class="literal">ERL_INTERFACE_INCLUDE_DIR</code>
</span></dt><dd>
    Path to the Erl_Interface include files (<span class="emphasis"><em>ei.h</em></span> and related).
</dd><dt><span class="term">
<code class="literal">ERL_INTERFACE_LIB_DIR</code>
</span></dt><dd>
    Path to the Erl_Interface static libraries.
</dd></dl></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_using_a_custom_makefile"></a>8.2. Using a custom Makefile</h2></div></div></div><p>Erlang.mk will automatically run <code class="literal">make</code> if it detects a Makefile
in <span class="emphasis"><em>$(C_SRC_DIR)/Makefile</em></span>.</p><p>The Makefile should have at least two targets: a default target
(which can be anything, for example <code class="literal">all</code>) which is invoked when
building the C code, and a <code class="literal">clean</code> target invoked when cleaning
it.</p><p>You can include the <span class="emphasis"><em>env.mk</em></span> file to benefit from the Erlang
environment detection:</p><pre class="programlisting">include env.mk</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_using_erlang_mk_directly"></a>8.3. Using Erlang.mk directly</h2></div></div></div><p>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 <span class="emphasis"><em>$(C_SRC_DIR)</em></span>.</p><p>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:</p><pre class="programlisting">C_SRC_TYPE = executable</pre><p>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.</p><p>For shared libraries, the generated file name will be
<span class="emphasis"><em>$(C_SRC_OUTPUT)$(C_SRC_SHARED_EXTENSION)</em></span>, with the default
being <span class="emphasis"><em>$(CURDIR)/priv/$(PROJECT)</em></span> followed by the extension:
<code class="literal">.dll</code> on Windows, <code class="literal">.so</code> everywhere else.</p><p>For executables, the generated file name is
<span class="emphasis"><em>$(C_SRC_OUTPUT)$(C_SRC_EXECUTABLE_EXTENSION)</em></span>, with the same
default except for the extension: <code class="literal">.exe</code> on Windows, and otherwise
nothing.</p><p>Erlang.mk sets appropriate compile and linker flags by default.
These flags vary depending on the platform, and can of course
be overriden.</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
<code class="literal">CC</code>
</span></dt><dd>
    The compiler to be used.
</dd><dt><span class="term">
<code class="literal">CFLAGS</code>
</span></dt><dd>
    C compiler flags.
</dd><dt><span class="term">
<code class="literal">CXXFLAGS</code>
</span></dt><dd>
    C++ compiler flags.
</dd><dt><span class="term">
<code class="literal">LDFLAGS</code>
</span></dt><dd>
    Linker flags.
</dd><dt><span class="term">
<code class="literal">LDLIBS</code>
</span></dt><dd>
    Libraries to link against.
</dd></dl></div><p>The source files are automatically gathered from the contents
of <span class="emphasis"><em>$(C_SRC_DIR)</em></span>. Erlang.mk looks for <span class="emphasis"><em>.c</em></span>, <span class="emphasis"><em>.C</em></span>, <span class="emphasis"><em>.cc</em></span> and <span class="emphasis"><em>.cpp</em></span>
source files. You can define the variable <code class="literal">SOURCES</code> to manually
list the files to compile.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_propagating_compile_and_linker_flags_to_sub_makefiles"></a>8.4. Propagating compile and linker flags to sub-Makefiles</h2></div></div></div><p>In some cases it might be necessary to propagate the flags
you just defined to the sub-Makefiles of your local project.
You generally can’t just export those as this could impact
the building of dependencies.</p><p>Makefiles allow you to export variables for specific targets.
When doing this, the variables will be exported only when
this target runs, and not for other targets. It is therefore
possible to export them when building the C code without
impacting other build steps.</p><p>By adding this to your Makefile all five variables will be
made available to sub-Makefiles when building C code:</p><pre class="programlisting">app-c_src: export CC +=
app-c_src: export CFLAGS +=
app-c_src: export CPPFLAGS +=
app-c_src: export LDFLAGS +=
app-c_src: export LDLIBS +=</pre><p>Appending an empty string to the existing value is necessary
because Makefiles expect an assignment for target-specific
exports. Alternatively you can set a new value:</p><pre class="programlisting">app-c_src: export CFLAGS = -O3</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="deps.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="code.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="relx.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div>
</main>
</body>
</html>