aboutsummaryrefslogtreecommitdiff
path: root/documentation/manual.html
blob: 6580f5325ae38da6411b692334b3dec43b19fea5 (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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
<!DOCTYPE html>

<html lang="en">
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta name="description" content="Serial communication library for Akka and Scala.">

	<link rel="shortcut icon" type="image/png" href="https://jodersky.github.io/flow/assets/images/logo.png"/>

	<title>flow</title>

	<link rel="stylesheet" href="https://jodersky.github.io/flow/assets/lib/bootstrap/css/bootstrap.min.css">
	<link rel="stylesheet" href="https://jodersky.github.io/flow/assets/lib/fontawesome/css/font-awesome.min.css">
	<link rel="stylesheet" href="https://jodersky.github.io/flow/assets/stylesheets/solarized-dark.css">
	<link rel="stylesheet" href="https://jodersky.github.io/flow/assets/stylesheets/main.css">

	<script src="https://jodersky.github.io/flow/assets/lib/jquery/jquery-1.11.3.min.js"></script>
</head>
<body>
	
	
<header>
  <nav class="navbar navbar-static-top navbar-default">
    <div class="container">
      <div class="navbar-header">
	<a class="navbar-brand" href="https://jodersky.github.io/flow">
	  <img src="https://jodersky.github.io/flow/assets/images/logo.png" alt="flow logo">
	  flow
	</a>
      </div>
      <ul class="nav navbar-nav navbar-right">
	<li><a href="https://jodersky.github.io/flow/documentation">Documentation & Help</a></li>
	<li><a href="https://jodersky.github.io/flow/downloads">Download</a></li>
	<li><a href="https://github.com/jodersky/flow">GitHub</a></li>
      </ul>
    </div>
  </nav>
</header>


<div class="container">
<h1 id="content">Content</h1>
<ul id="markdown-toc">
  <li><a href="#content" id="markdown-toc-content">Content</a></li>
  <li><a href="#getting-started" id="markdown-toc-getting-started">Getting Started</a>    <ul>
      <li><a href="#including-native-library" id="markdown-toc-including-native-library">Including Native Library</a>        <ul>
          <li><a href="#the-easy-way" id="markdown-toc-the-easy-way">The Easy Way</a></li>
          <li><a href="#maximum-portability" id="markdown-toc-maximum-portability">Maximum Portability</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li><a href="#communication-protocol" id="markdown-toc-communication-protocol">Communication Protocol</a>    <ul>
      <li><a href="#opening-a-port" id="markdown-toc-opening-a-port">Opening a Port</a></li>
      <li><a href="#writing-data" id="markdown-toc-writing-data">Writing Data</a></li>
      <li><a href="#receiving-data" id="markdown-toc-receiving-data">Receiving Data</a></li>
      <li><a href="#closing-a-port" id="markdown-toc-closing-a-port">Closing a Port</a></li>
      <li><a href="#resources-and-error-handling" id="markdown-toc-resources-and-error-handling">Resources and Error Handling</a></li>
    </ul>
  </li>
  <li><a href="#watching-ports" id="markdown-toc-watching-ports">Watching Ports</a>    <ul>
      <li><a href="#subscribing" id="markdown-toc-subscribing">Subscribing</a></li>
      <li><a href="#notifications" id="markdown-toc-notifications">Notifications</a></li>
      <li><a href="#unsubscribing" id="markdown-toc-unsubscribing">Unsubscribing</a></li>
      <li><a href="#resource-handling" id="markdown-toc-resource-handling">Resource Handling</a></li>
      <li><a href="#requirements" id="markdown-toc-requirements">Requirements</a></li>
    </ul>
  </li>
  <li><a href="#building-from-source" id="markdown-toc-building-from-source">Building from Source</a>    <ul>
      <li><a href="#building-scala-sources" id="markdown-toc-building-scala-sources">Building Scala Sources</a></li>
      <li><a href="#building-native-sources" id="markdown-toc-building-native-sources">Building Native Sources</a>        <ul>
          <li><a href="#aside-autotools-introduction" id="markdown-toc-aside-autotools-introduction">Aside: Autotools Introduction</a></li>
          <li><a href="#build-process" id="markdown-toc-build-process">Build Process</a></li>
          <li><a href="#creating-a-fat-jar" id="markdown-toc-creating-a-fat-jar">Creating a Fat Jar</a></li>
          <li><a href="#note-about-versioning" id="markdown-toc-note-about-versioning">Note About Versioning</a></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

<h1 id="getting-started">Getting Started</h1>
<p>Flow uses SBT as build system. To get started, include a dependency to flow in your project:</p>

<div class="highlighter-rouge"><pre class="highlight"><code><span class="n">libraryDependencies</span> <span class="o">+=</span> <span class="s">"com.github.jodersky"</span> <span class="o">%%</span> <span class="s">"flow"</span> <span class="o">%</span> <span class="s">"2.4.0-M1"</span>
</code></pre>
</div>

<p>Next, you need to include flow’s native library that supports communication for serial devices.</p>

<h2 id="including-native-library">Including Native Library</h2>
<p>There are two options to include the native library:</p>

<ol>
  <li>
    <p>Using an easy, pre-packaged dependency, avialble only for certain OSes.</p>
  </li>
  <li>
    <p>Including the library manually for maximum portability.</p>
  </li>
</ol>

<p>It is recommended that you use the first option for testing purposes or end-user applications. The second option is recomended for libraries, since it leaves more choice to the end-user.</p>

<h3 id="the-easy-way">The Easy Way</h3>
<p>In case your OS/architecture combination is present in the “supported platforms” table in the downloads section, add a second dependency to your project:</p>

<div class="highlighter-rouge"><pre class="highlight"><code><span class="n">libraryDependencies</span> <span class="o">+=</span> <span class="s">"com.github.jodersky"</span> <span class="o">%</span> <span class="s">"flow-native"</span> <span class="o">%</span> <span class="s">"2.4.0-M1"</span> <span class="o">%</span> <span class="s">"runtime"</span>
</code></pre>
</div>

<p>This will add a jar to your classpath containing native libraries for various platforms. At run time, the correct library for the current platform is selected, extracted and loaded. This solution enables running applications seamlessly, as if they were pure JVM applications.</p>

<h3 id="maximum-portability">Maximum Portability</h3>
<p>First, obtain a copy of the native library, either by <a href="#building-from-source">building flow</a> or by <a href="https://jodersky.github.io/flow/downloads">downloading</a> a precompiled version. In order to work with this version of flow, native libraries need to be of major version 3 and minor version greater or equal to 0.</p>

<p>Second, for every end-user application that relies on flow, manually add the native library for the current platform to the JVM’s library path. This can be achieved through various ways, notably:</p>

<ul>
  <li>
    <p>Per application:
Run your program with the command-line option <code class="highlighter-rouge">-Djava.library.path=".:&lt;folder containing libflow3.so&gt;"</code>. E.g. <code class="highlighter-rouge">java -Djava.library.path=".:/home/&lt;folder containing libflow3.so&gt;" -jar your-app.jar</code></p>
  </li>
  <li>
    <p>System- or user-wide:</p>

    <ul>
      <li>
        <p>Copy the native library to a place that is on the default Java library path and run your application normally. Such places usually include <code class="highlighter-rouge">/usr/lib</code> and <code class="highlighter-rouge">/usr/local/lib</code>.</p>
      </li>
      <li>
        <p>Install a native package from the downloads section</p>
      </li>
    </ul>
  </li>
</ul>

<hr />

<h1 id="communication-protocol">Communication Protocol</h1>
<p>The following is a general guide on the usage of flow. If you prefer a complete example, check out the code contained in the <a href="https://github.com/jodersky/flow/tree/master/flow-samples">flow-samples</a> directory.</p>

<p>Flow’s API follows that of an actor based system, where each actor is assigned specific functions involved in serial communication. The two main actor types are:</p>

<ol>
  <li>
    <p>Serial “manager”. The manager is a singleton actor that is instantiated once per actor system, a reference to it may be obtained with <code class="highlighter-rouge">IO(Serial)</code>. It is typically used to open serial ports (see following section).</p>
  </li>
  <li>
    <p>Serial “operators”. Operators are created once per open serial port and serve as an intermediate between client code and native code dealing with serial data transmission and reception. They isolate the user from threading issues and enable the reactive dispatch of incoming data. A serial operator is said to be “associated” to its underlying open serial port.</p>
  </li>
</ol>

<p>The messages understood by flow’s actors are all contained in the <code class="highlighter-rouge">com.github.jodersky.flow.Serial</code> object. They are well documented and should serve as the entry point when searching the API documentation.</p>

<h2 id="opening-a-port">Opening a Port</h2>
<p>A serial port is opened by sending an <code class="highlighter-rouge">Open</code> message to the serial manager. The response varies on the outcome of opening the underlying serial port.</p>

<ol>
  <li>
    <p>In case of failure, the serial manager will respond with a <code class="highlighter-rouge">CommandFailed</code> message to the original sender. The message contains details on the reason to why the opening failed.</p>
  </li>
  <li>
    <p>In case of success, the sender is notified with an <code class="highlighter-rouge">Opened</code> message. This message is sent from an operator actor, spawned by the serial manager. It is useful to capture the sender (i.e. the operator) of this message as all further communication with the newly opened port must pass through the operator.</p>
  </li>
</ol>

<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">import</span> <span class="nn">com.github.jodersky.flow.</span><span class="o">{</span> <span class="nc">Serial</span><span class="o">,</span> <span class="nc">SerialSettings</span><span class="o">,</span> <span class="nc">AccessDeniedException</span> <span class="o">}</span>

<span class="k">val</span> <span class="n">port</span> <span class="k">=</span> <span class="s">"/dev/ttyXXX"</span>
<span class="k">val</span> <span class="n">settings</span> <span class="k">=</span> <span class="nc">SerialSettings</span><span class="o">(</span>
  <span class="n">baud</span> <span class="k">=</span> <span class="mi">115200</span><span class="o">,</span>
  <span class="n">characterSize</span> <span class="k">=</span> <span class="mi">8</span><span class="o">,</span>
  <span class="n">twoStopBits</span> <span class="k">=</span> <span class="kc">false</span><span class="o">,</span>
  <span class="n">parity</span> <span class="k">=</span> <span class="nc">Parity</span><span class="o">.</span><span class="nc">None</span>
<span class="o">)</span>

<span class="nc">IO</span><span class="o">(</span><span class="nc">Serial</span><span class="o">)</span> <span class="o">!</span> <span class="nc">Serial</span><span class="o">.</span><span class="nc">Open</span><span class="o">(</span><span class="n">port</span><span class="o">,</span> <span class="n">settings</span><span class="o">)</span>

<span class="k">def</span> <span class="n">receive</span> <span class="k">=</span> <span class="o">{</span>
  <span class="k">case</span> <span class="nc">Serial</span><span class="o">.</span><span class="nc">CommandFailed</span><span class="o">(</span><span class="n">cmd</span><span class="k">:</span> <span class="kt">Serial.Open</span><span class="o">,</span> <span class="n">reason</span><span class="k">:</span> <span class="kt">AccessDeniedException</span><span class="o">)</span> <span class="k">=&gt;</span>
    <span class="n">println</span><span class="o">(</span><span class="s">"You're not allowed to open that port!"</span><span class="o">)</span>
  <span class="k">case</span> <span class="nc">Serial</span><span class="o">.</span><span class="nc">CommandFailed</span><span class="o">(</span><span class="n">cmd</span><span class="k">:</span> <span class="kt">Serial.Open</span><span class="o">,</span> <span class="n">reason</span><span class="o">)</span> <span class="k">=&gt;</span>
	<span class="n">println</span><span class="o">(</span><span class="s">"Could not open port for some other reason: "</span> <span class="o">+</span> <span class="n">reason</span><span class="o">.</span><span class="n">getMessage</span><span class="o">)</span>
  <span class="k">case</span> <span class="nc">Serial</span><span class="o">.</span><span class="nc">Opened</span><span class="o">(</span><span class="n">settings</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="o">{</span>
    <span class="k">val</span> <span class="n">operator</span> <span class="k">=</span> <span class="n">sender</span>
    <span class="c1">//do stuff with the operator, e.g. context become opened(op)
</span>  <span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>

<h2 id="writing-data">Writing Data</h2>
<p>Writing data is as simple as sending a <code class="highlighter-rouge">Write</code> message to an operator. The data to send is an instance of <code class="highlighter-rouge">akka.util.ByteString</code>:</p>

<div class="highlighter-rouge"><pre class="highlight"><code><span class="n">operator</span> <span class="o">!</span> <span class="nc">Serial</span><span class="o">.</span><span class="nc">Write</span><span class="o">(</span><span class="n">data</span><span class="o">)</span>
</code></pre>
</div>

<p>Optionally, an acknowledgement for sent data can be requested by adding an <code class="highlighter-rouge">ack</code> parameter to a <code class="highlighter-rouge">Write</code> message. The <code class="highlighter-rouge">ack</code> parameter is of type <code class="highlighter-rouge">Int =&gt; Serial.Event</code>, i.e. a function that takes the number of actual bytes written and returns an event. Note that “bytes written” refers to bytes enqueued in a kernel buffer; no guarantees can be made on the actual transmission of the data.</p>

<div class="highlighter-rouge"><pre class="highlight"><code>
<span class="k">case</span> <span class="k">class</span> <span class="nc">MyPacketAck</span><span class="o">(</span><span class="n">wrote</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Serial</span><span class="o">.</span><span class="nc">Event</span>

<span class="n">operator</span> <span class="o">!</span> <span class="nc">Serial</span><span class="o">.</span><span class="nc">Write</span><span class="o">(</span><span class="n">data</span><span class="o">,</span> <span class="nc">MyPacketAck</span><span class="o">(</span><span class="k">_</span><span class="o">))</span>
<span class="n">operator</span> <span class="o">!</span> <span class="nc">Serial</span><span class="o">.</span><span class="nc">Write</span><span class="o">(</span><span class="n">data</span><span class="o">,</span> <span class="n">n</span> <span class="k">=&gt;</span> <span class="nc">MyPacketAck</span><span class="o">(</span><span class="n">n</span><span class="o">))</span>

<span class="k">def</span> <span class="n">receive</span> <span class="k">=</span> <span class="o">{</span>
  <span class="k">case</span> <span class="nc">MyPacketAck</span><span class="o">(</span><span class="n">n</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">println</span><span class="o">(</span><span class="s">"Wrote "</span> <span class="o">+</span> <span class="n">n</span> <span class="o">+</span> <span class="s">" bytes of data"</span><span class="o">)</span>
<span class="o">}</span>

</code></pre>
</div>

<h2 id="receiving-data">Receiving Data</h2>
<p>The actor that opened a serial port (referred to as the client), exclusively receives incomming messages from the operator. These messages are in the form of <code class="highlighter-rouge">akka.util.ByteString</code>s and wrapped in a <code class="highlighter-rouge">Received</code> object.</p>

<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">def</span> <span class="n">receive</span> <span class="k">=</span> <span class="o">{</span>
  <span class="k">case</span> <span class="nc">Serial</span><span class="o">.</span><span class="nc">Received</span><span class="o">(</span><span class="n">data</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">println</span><span class="o">(</span><span class="s">"Received data: "</span> <span class="o">+</span> <span class="n">data</span><span class="o">.</span><span class="n">toString</span><span class="o">)</span>
<span class="o">}</span>
</code></pre>
</div>

<h2 id="closing-a-port">Closing a Port</h2>
<p>A port is closed by sending a <code class="highlighter-rouge">Close</code> message to its operator:
~~~scala
operator ! Serial.Close
~~~
The operator will close the underlying serial port and respond with a final <code class="highlighter-rouge">Closed</code> message before terminating.</p>

<h2 id="resources-and-error-handling">Resources and Error Handling</h2>
<p>The operator has a deathwatch on the client actor that opened the port, this means that if the latter crashes, the operator closes the port and equally terminates, freeing any allocated resources.</p>

<p>The opposite is not true by default, i.e. if the operator crashes (this can happen for example on IO errors) it dies silently and the client is not informed. Therefore, it is recommended that the client keep a deathwatch on the operator.</p>

<hr />

<h1 id="watching-ports">Watching Ports</h1>
<p>As of version 2.2.0, flow can watch directories for new files. On most unix systems this can be used for watching for new serial ports in <code class="highlighter-rouge">/dev/</code>.
Watching happens through a message-based, publish-subscribe protocol as explained in the sections below.</p>

<h2 id="subscribing">Subscribing</h2>
<p>A client actor may watch – i.e subscribe to notifications on – a directory by sending a <code class="highlighter-rouge">Watch</code> command to the serial manager.</p>

<p>Should an error be encountered whilst trying to obtain the watch, the manager will respond with a <code class="highlighter-rouge">CommandFailed</code> message.
Otherwise, the client may be considered “subscribed” to the directory and the serial manager will thenceforth notify
the client on new files.</p>

<div class="highlighter-rouge"><pre class="highlight"><code><span class="nc">IO</span><span class="o">(</span><span class="nc">Serial</span><span class="o">)</span> <span class="o">!</span> <span class="nc">Serial</span><span class="o">.</span><span class="nc">Watch</span><span class="o">(</span><span class="s">"/dev/"</span><span class="o">)</span>

<span class="k">def</span> <span class="n">receive</span> <span class="k">=</span> <span class="o">{</span>
  <span class="k">case</span> <span class="nc">Serial</span><span class="o">.</span><span class="nc">CommandFailed</span><span class="o">(</span><span class="n">w</span><span class="k">:</span> <span class="kt">Watch</span><span class="o">,</span> <span class="n">reason</span><span class="o">)</span> <span class="k">=&gt;</span>
    <span class="n">println</span><span class="o">(</span><span class="n">s</span><span class="s">"Cannot obtain a watch on ${w.directory}: ${reason.getMessage}"</span><span class="o">)</span>
<span class="o">}</span>

</code></pre>
</div>

<h2 id="notifications">Notifications</h2>
<p>Whilst subscribed to a directory, a client actor is informed of any new files in said directory by receiving
<code class="highlighter-rouge">Connected</code> messages from the manager.</p>

<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">def</span> <span class="n">receive</span> <span class="k">=</span> <span class="o">{</span>
  <span class="k">case</span> <span class="nc">Serial</span><span class="o">.</span><span class="nc">Connected</span><span class="o">(</span><span class="n">port</span><span class="o">)</span> <span class="k">if</span> <span class="n">port</span> <span class="n">matches</span> <span class="s">"/dev/ttyUSB\\d+"</span> <span class="k">=&gt;</span>
    <span class="c1">// do something with the available port, e.g.
</span>    <span class="c1">// IO(Serial) ! Open(port, settings)
</span><span class="o">}</span>
</code></pre>
</div>

<h2 id="unsubscribing">Unsubscribing</h2>
<p>Unsubscribing from events on a directory is done by sending an <code class="highlighter-rouge">Unsubscribe</code> message to the serial manager.</p>

<div class="highlighter-rouge"><pre class="highlight"><code><span class="nc">IO</span><span class="o">(</span><span class="nc">Serial</span><span class="o">)</span> <span class="o">!</span> <span class="nc">Unwatch</span><span class="o">(</span><span class="s">"/dev/"</span><span class="o">)</span>
</code></pre>
</div>

<h2 id="resource-handling">Resource Handling</h2>
<p>Note that the manager has a deathwatch on every subscribed client. Hence, should a client die, any underlying resources will be freed.</p>

<h2 id="requirements">Requirements</h2>
<p>Flow uses Java’s <code class="highlighter-rouge">WatchService</code>s under the hood, therefore a Java runtime of a version of at least 1.7 is required.</p>

<hr />

<h1 id="building-from-source">Building from Source</h1>
<p>A complete build of flow involves two parts</p>

<ol>
  <li>
    <p>Building Scala sources (the front-end), resulting in a platform independent artifact (i.e. a jar file).</p>
  </li>
  <li>
    <p>Building C sources (the back-end), yielding a native library that may only be used on systems resembling the platform for which it was compiled.</p>
  </li>
</ol>

<p>Both steps are independent, their only interaction being a header file generated by the JDK utility <code class="highlighter-rouge">javah</code> (see <code class="highlighter-rouge">sbt javah</code> for details), and may therefore be built in any order.</p>

<h2 id="building-scala-sources">Building Scala Sources</h2>
<p>Run <code class="highlighter-rouge">sbt flow-main/packageBin</code> in the base directory. This simply compiles Scala sources as with any standard sbt project and packages the resulting class files in a jar.</p>

<h2 id="building-native-sources">Building Native Sources</h2>
<p>The back-end is managed by GNU Autotools and all relevant files are contained in <code class="highlighter-rouge">flow-native</code>.</p>

<aside class="notice">
  <h3 id="aside-autotools-introduction">Aside: Autotools Introduction</h3>
  <p>Autotools is a suite of programs constituting a sort of “meta-build system”. It is used to generate a platform-independent build script known as <code class="highlighter-rouge">./configure</code>, which, when run, will analyze the current system (search for a C compiler, required libraries etc) and produce a <code class="highlighter-rouge">Makefile</code>. The makefile in turn is system-specific and can be used to create the final binary. In summary the build process is as follows:</p>

  <ol>
    <li>Autotools (specifically the program <code class="highlighter-rouge">autoreconf</code>) generates <code class="highlighter-rouge">./configure</code>, this happens on the developer’s machine</li>
    <li><code class="highlighter-rouge">./configure</code> is run on the host computer</li>
    <li><code class="highlighter-rouge">make</code> is run to produce a binary, also on the host computer</li>
  </ol>

  <p>In a typical, source-controlled repository, only a bootstrapping script that calls Autotools is checked into version control. However, source <em>releases</em> include the generated <code class="highlighter-rouge">./configure</code> script. An end-user then downloads a source release and only has to run <code class="highlighter-rouge">./configure &amp;&amp; make</code>.</p>

  <p>However, since flow does currently not provide source releases (not to be confused with source repository or Git tags), the developer’s machine is the same as the host machine and so the bootstrapping process always needs to be performed.</p>
</aside>

<h3 id="build-process">Build Process</h3>

<p>Several steps are involved in producing the native library:</p>

<ol>
  <li>
    <p>Bootstrap the build (run this once, if <code class="highlighter-rouge">./configure</code> does not exist).</p>

    <ol>
      <li>Check availability of dependencies: autotools and libtool (on Debian-based systems run <code class="highlighter-rouge">apt-get install build-essential autoconf automake libtool</code>)</li>
      <li>Run <code class="highlighter-rouge">./bootstrap</code></li>
    </ol>
  </li>
  <li>
    <p>Compile</p>

    <ol>
      <li>Check availability of dependencies: C compiler and JDK (1.8 or above)</li>
      <li>Run <code class="highlighter-rouge">./configure &amp;&amp; make</code>.
<em>Note: should you encounter an error about a missing “jni.h” file, try setting the JAVA_HOME environment variable to point to base path of your JDK installation.</em></li>
    </ol>
  </li>
  <li>
    <p>Install</p>

    <p>The native library is now ready and can be:</p>

    <ul>
      <li>
        <p>copied to a local directory: <code class="highlighter-rouge">DESTDIR=$(pwd)/&lt;directory&gt; make install</code></p>
      </li>
      <li>
        <p>installed system-wide: <code class="highlighter-rouge">make install</code></p>
      </li>
      <li>
        <p>put into a “fat” jar, useful for dependency management with SBT (see next section)</p>
      </li>
    </ul>
  </li>
</ol>

<h3 id="creating-a-fat-jar">Creating a Fat Jar</h3>
<p>The native library produced in the previous step may be bundled into a “fat” jar so that it can be included in SBT projects through its regular dependency mechanisms. In this process, SBT basically acts as a wrapper script around Autotools, calling the native build process and packaging generated libraries. Running <code class="highlighter-rouge">sbt flow-native/packageBin</code> in the base directory produces the fat jar in <code class="highlighter-rouge">flow-native/target</code>.</p>

<p>Note: an important feature of fat jars is to include native libraries for several platforms. To copy binaries compiled on other platforms to the fat jar, place them in a subfolder of <code class="highlighter-rouge">flow-native/lib_native</code>. The subfolder should have the name <code class="highlighter-rouge">com/github/jodersky/flow/native/$(arch)-$(kernel)</code>, where <code class="highlighter-rouge">arch</code> and <code class="highlighter-rouge">kernel</code> are, respectively, the lower-case values returned by <code class="highlighter-rouge">uname -m</code> and <code class="highlighter-rouge">uname -s</code>.</p>

<h3 id="note-about-versioning">Note About Versioning</h3>
<p>The project and package versions follow a <a href="http://semver.org/">semantic</a> pattern: <code class="highlighter-rouge">M.m.p</code>, where</p>

<ul>
  <li>
    <p><code class="highlighter-rouge">M</code> is the major version, representing backwards incompatible changes</p>
  </li>
  <li>
    <p><code class="highlighter-rouge">m</code> is the minor version, indicating backwards compatible changes such as new feature additions</p>
  </li>
  <li>
    <p><code class="highlighter-rouge">p</code> is the patch number, representing internal modifications such as bug-fixes</p>
  </li>
</ul>

<p>Usually (following most Linux distribution’s conventions), shared libraries produced by a project <code class="highlighter-rouge">name</code> of version <code class="highlighter-rouge">M.m.p</code> are named <code class="highlighter-rouge">libname.so.M.m.p</code>. However, since when accessing shared libraries through the JVM, only the <code class="highlighter-rouge">name</code> can be specified and no particular version, the convention adopted by flow is to append <code class="highlighter-rouge">M</code> to the library name and always keep the major version at zero. E.g. <code class="highlighter-rouge">libflow.so.3.1.2</code> becomes <code class="highlighter-rouge">libflow3.so.0.1.2</code>.</p>

</div>




    <script src="https://jodersky.github.io/flow/assets/lib/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>