<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 8.6.10">
<title>LibrarySupport</title>
<link rel="stylesheet" href="./asciidoc.css" type="text/css">
<link rel="stylesheet" href="./pygments.css" type="text/css">


<script type="text/javascript" src="./asciidoc.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
asciidoc.install();
/*]]>*/
</script>
<link rel="stylesheet" href="./mlton.css" type="text/css">
</head>
<body class="article">
<div id="banner">
<div id="banner-home">
<a href="./Home">MLton 20201002</a>
</div>
</div>
<div id="header">
<h1>LibrarySupport</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>MLton supports both linking to and creating system-level libraries.
While Standard ML libraries should be designed with the <a href="MLBasis">MLBasis</a> system to work with other Standard ML programs,
system-level library support allows MLton to create libraries for use by other programming languages.
Even more importantly, system-level library support allows MLton to access libraries from other languages.
This article will explain how to use libraries portably with MLton.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_the_basics">The Basics</h2>
<div class="sectionbody">
<div class="paragraph"><p>A Dynamic Shared Object (DSO) is a piece of executable code written in a format understood by the operating system.
Executable programs and dynamic libraries are the two most common examples of a DSO.
They are called shared because if they are used more than once, they are only loaded once into main memory.
For example, if you start two instances of your web browser (an executable), there may be two processes running, but the program code of the executable is only loaded once.
A dynamic library, for example a graphical toolkit, might be used by several different executable programs, each possibly running multiple times.
Nevertheless, the dynamic library is only loaded once and it&#8217;s program code is shared between all of the processes.</p></div>
<div class="paragraph"><p>In addition to program code, DSOs contain a table of textual strings called symbols.
These are used in order to make the DSO do something useful, like execute.
For example, on linux the symbol <span class="monospaced">_start</span> refers to the point in the program code where the operating system should start executing the program.
Dynamic libraries generally provide many symbols, corresponding to functions which can be called and variables which can be read or written.
Symbols can be used by the DSO itself, or by other DSOs which require services.</p></div>
<div class="paragraph"><p>When a DSO creates a symbol, this is called <em>exporting</em>.
If a DSO needs to use a symbol, this is called <em>importing</em>.
A DSO might need to use symbols defined within itself or perhaps from another DSO.
In both cases, it is importing that symbol, but the scope of the import differs.
Similarly, a DSO might export a symbol for use only within itself, or it might export a symbol for use by other DSOs.
Some symbols are resolved at compile time by the linker (those used within the DSO) and some are resolved at runtime by the dynamic link loader (symbols accessed between DSOs).</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_symbols_in_mlton">Symbols in MLton</h2>
<div class="sectionbody">
<div class="paragraph"><p>Symbols in MLton are both imported and exported via the <a href="ForeignFunctionInterface">ForeignFunctionInterface</a>.
The notation <span class="monospaced">_import "symbolname"</span> imports functions, <span class="monospaced">_symbol "symbolname"</span> imports variables, and <span class="monospaced">_address "symbolname"</span> imports an address.
To create and export a symbol, <span class="monospaced">_export "symbolname"</span> creates a function symbol and <span class="monospaced">_symbol "symbolname" 'alloc'</span> creates and exports a variable.
For details of the syntax and restrictions on the supported FFI types, read the <a href="ForeignFunctionInterface">ForeignFunctionInterface</a> page.
In this discussion it only matters that every FFI use is either an import or an export.</p></div>
<div class="paragraph"><p>When exporting a symbol, MLton supports controlling the export scope.
If the symbol should only be used within the same DSO, that symbol has <em><span class="monospaced">private</span></em> scope.
Conversely, if the symbol should also be available to other DSOs the symbol has <em><span class="monospaced">public</span></em> scope.
Generally, one should have as few public exports as possible.
Since they are public, other DSOs will come to depend on them, limiting your ability to change them.
You specify the export scope in MLton by putting <span class="monospaced">private</span> or <span class="monospaced">public</span> after the symbol&#8217;s name in an FFI directive.
eg: <span class="monospaced">_export "foo" private: int-&gt;int;</span> or <span class="monospaced">_export "bar" public: int-&gt;int;</span> .</p></div>
<div class="paragraph"><p>For technical reasons, the linker and loader on various platforms need to know the scope of a symbol being imported.
If the symbol is exported by the same DSO, use <span class="monospaced">public</span> or <span class="monospaced">private</span> as appropriate.
If the symbol is exported by a different DSO, then the scope <em><span class="monospaced">external</span></em> should be used to import it.
Within a DSO, all references to a symbol must use the same scope.
MLton will check this at compile time, reporting: <span class="monospaced">symbol "foo" redeclared as public (previously external)</span>. This may cause linker errors.
However, MLton can only check usage within Standard ML.
All objects being linked into a resulting DSO must agree, and it is the programmer&#8217;s responsibility to ensure this.</p></div>
<div class="paragraph"><p>Summary of symbol scopes:</p></div>
<div class="ulist"><ul>
<li>
<p>
<span class="monospaced">private</span>: used for symbols exported within a DSO only for use within that DSO
</p>
</li>
<li>
<p>
<span class="monospaced">public</span>: used for symbols exported within a DSO that may also be used outside that DSO
</p>
</li>
<li>
<p>
<span class="monospaced">external</span>: used for importing symbols from another DSO
</p>
</li>
<li>
<p>
All uses of a symbol within a DSO (both imports and exports) must agree on the symbol scope
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_output_formats">Output Formats</h2>
<div class="sectionbody">
<div class="paragraph"><p>MLton can create executables (<span class="monospaced">-format executable</span>) and dynamic shared libraries (<span class="monospaced">-format library</span>).
To link a shared library, use <span class="monospaced">-link-opt -l&lt;dso_name&gt;</span>.
The default output format is executable.</p></div>
<div class="paragraph"><p>MLton can also create archives.
An archive is not a DSO, but it does have a collection of symbols.
When an archive is linked into a DSO, it is completely absorbed.
Other objects being compiled into the DSO should refer to the public symbols in the archive as public, since they are still in the same DSO.
However, in the interest of modular programming, private symbols in an archive cannot be used outside of that archive, even within the same DSO.</p></div>
<div class="paragraph"><p>Although both executables and libraries are DSOs, some implementation details differ on some platforms.
For this reason, MLton can create two types or archives.
A normal archive (<span class="monospaced">-format archive</span>) is appropriate for linking into an executable.
Conversely, a libarchive (<span class="monospaced">-format libarchive</span>) should be used if it will be linked into a dynamic library.</p></div>
<div class="paragraph"><p>When MLton does not create an executable, it creates two special symbols.
The symbol <span class="monospaced">libname_open</span> is a function which must be called before any other symbols are accessed.
The <span class="monospaced">libname</span> is controlled by the <span class="monospaced">-libname</span> compile option and defaults to the name of the output, with any prefixing lib stripped (eg: <span class="monospaced">foo</span> &#8594; <span class="monospaced">foo</span>, <span class="monospaced">libfoo</span> &#8594; <span class="monospaced">foo</span>).
The symbol <span class="monospaced">libname_close</span> is a function which should be called to clean up memory once done.</p></div>
<div class="paragraph"><p>Summary of <span class="monospaced">-format</span> options:</p></div>
<div class="ulist"><ul>
<li>
<p>
<span class="monospaced">executable</span>: create an executable (a DSO)
</p>
</li>
<li>
<p>
<span class="monospaced">library</span>: create a dynamic shared library (a DSO)
</p>
</li>
<li>
<p>
<span class="monospaced">archive</span>: create an archive of symbols (not a DSO) that can be linked into an executable
</p>
</li>
<li>
<p>
<span class="monospaced">libarchive</span>: create an archive of symbols (not a DSO) that can be linked into a library
</p>
</li>
</ul></div>
<div class="paragraph"><p>Related options:</p></div>
<div class="ulist"><ul>
<li>
<p>
<span class="monospaced">-libname x</span>: controls the name of the special <span class="monospaced">_open</span> and <span class="monospaced">_close</span> functions.
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_interfacing_with_c">Interfacing with C</h2>
<div class="sectionbody">
<div class="paragraph"><p>MLton can generate a C header file.
When the output format is not an executable, it creates one by default named <span class="monospaced">libname.h</span>.
This can be overridden with <span class="monospaced">-export-header foo.h</span>.
This header file should be included by any C files using the exported Standard ML symbols.</p></div>
<div class="paragraph"><p>If C is being linked with Standard ML into the same output archive or DSO,
then the C code should <span class="monospaced">#define PART_OF_LIBNAME</span> before it includes the header file.
This ensures that the C code is using the symbols with correct scope.
Any symbols exported from C should also be marked using the <span class="monospaced">PRIVATE</span>/<span class="monospaced">PUBLIC</span>/<span class="monospaced">EXTERNAL</span> macros defined in the Standard ML export header.
The declared C scope on exported C symbols should match the import scope used in Standard ML.</p></div>
<div class="paragraph"><p>An example:</p></div>
<div class="listingblock">
<div class="content"><div class="highlight"><pre><span></span><span class="cp">#define PART_OF_FOO</span>
<span class="cp">#include</span> <span class="cpf">&quot;foo.h&quot;</span><span class="cp"></span>

<span class="n">PUBLIC</span> <span class="kt">int</span> <span class="nf">cFoo</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">return</span> <span class="n">smlFoo</span><span class="p">();</span>
<span class="p">}</span>
</pre></div></div></div>
<div class="listingblock">
<div class="content"><div class="highlight"><pre><span></span><span class="k">val</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">_</span><span class="n">export</span><span class="w"> </span><span class="s">&quot;smlFoo&quot;</span><span class="w"> </span><span class="n">private</span><span class="p">:</span><span class="w"> </span><span class="n">unit</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">int</span><span class="p">;</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"></span>
<span class="k">val</span><span class="w"> </span><span class="n">cFoo</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">_</span><span class="n">import</span><span class="w"> </span><span class="s">&quot;cFoo&quot;</span><span class="w"> </span><span class="n">public</span><span class="p">:</span><span class="w"> </span><span class="n">unit</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">int</span><span class="p">;</span><span class="w"></span>
</pre></div></div></div>
</div>
</div>
<div class="sect1">
<h2 id="_operating_system_specific_details">Operating-system specific details</h2>
<div class="sectionbody">
<div class="paragraph"><p>On Windows, <span class="monospaced">libarchive</span> and <span class="monospaced">archive</span> are the same.
However, depending on this will lead to portability problems.
Windows is also especially sensitive to mixups of <em><span class="monospaced">public</span></em> and <em><span class="monospaced">external</span></em>.
If an archive is linked, make sure it&#8217;s symbols are imported as <span class="monospaced">public</span>.
If a DLL is linked, make sure it&#8217;s symbols are imported as <span class="monospaced">external</span>.
Using <span class="monospaced">external</span> instead of <span class="monospaced">public</span> will result in link errors that <span class="monospaced">__imp__foo is undefined</span>.
Using <span class="monospaced">public</span> instead of <span class="monospaced">external</span> will result in inconsistent function pointer addresses and failure to update the imported variables.</p></div>
<div class="paragraph"><p>On Linux, <span class="monospaced">libarchive</span> and <span class="monospaced">archive</span> are different.
Libarchives are quite rare, but necessary if creating a library from an archive.
It is common for a library to provide both an archive and a dynamic library on this platform.
The linker will pick one or the other, usually preferring the dynamic library.
While a quirk of the operating system allows external import to work for both archives and libraries,
portable projects should not depend on this behaviour.
On other systems it can matter how the library is linked (static or dynamic).</p></div>
</div>
</div>
</div>
<div id="footnotes"><hr></div>
<div id="footer">
<div id="footer-text">
</div>
<div id="footer-badges">
</div>
</div>
</body>
</html>
