Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | <!DOCTYPE html>\r |
2 | <html lang="en">\r | |
3 | <head>\r | |
4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\r | |
5 | <meta name="generator" content="AsciiDoc 8.6.9">\r | |
6 | <title>LibrarySupport</title>\r | |
7 | <link rel="stylesheet" href="./asciidoc.css" type="text/css">\r | |
8 | <link rel="stylesheet" href="./pygments.css" type="text/css">\r | |
9 | \r | |
10 | \r | |
11 | <script type="text/javascript" src="./asciidoc.js"></script>\r | |
12 | <script type="text/javascript">\r | |
13 | /*<![CDATA[*/\r | |
14 | asciidoc.install();\r | |
15 | /*]]>*/\r | |
16 | </script>\r | |
17 | <link rel="stylesheet" href="./mlton.css" type="text/css">\r | |
18 | </head>\r | |
19 | <body class="article">\r | |
20 | <div id="banner">\r | |
21 | <div id="banner-home">\r | |
22 | <a href="./Home">MLton 20180207</a>\r | |
23 | </div>\r | |
24 | </div>\r | |
25 | <div id="header">\r | |
26 | <h1>LibrarySupport</h1>\r | |
27 | </div>\r | |
28 | <div id="content">\r | |
29 | <div id="preamble">\r | |
30 | <div class="sectionbody">\r | |
31 | <div class="paragraph"><p>MLton supports both linking to and creating system-level libraries.\r | |
32 | While Standard ML libraries should be designed with the <a href="MLBasis">MLBasis</a> system to work with other Standard ML programs,\r | |
33 | system-level library support allows MLton to create libraries for use by other programming languages.\r | |
34 | Even more importantly, system-level library support allows MLton to access libraries from other languages.\r | |
35 | This article will explain how to use libraries portably with MLton.</p></div>\r | |
36 | </div>\r | |
37 | </div>\r | |
38 | <div class="sect1">\r | |
39 | <h2 id="_the_basics">The Basics</h2>\r | |
40 | <div class="sectionbody">\r | |
41 | <div class="paragraph"><p>A Dynamic Shared Object (DSO) is a piece of executable code written in a format understood by the operating system.\r | |
42 | Executable programs and dynamic libraries are the two most common examples of a DSO.\r | |
43 | They are called shared because if they are used more than once, they are only loaded once into main memory.\r | |
44 | 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.\r | |
45 | A dynamic library, for example a graphical toolkit, might be used by several different executable programs, each possibly running multiple times.\r | |
46 | Nevertheless, the dynamic library is only loaded once and it’s program code is shared between all of the processes.</p></div>\r | |
47 | <div class="paragraph"><p>In addition to program code, DSOs contain a table of textual strings called symbols.\r | |
48 | These are used in order to make the DSO do something useful, like execute.\r | |
49 | 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.\r | |
50 | Dynamic libraries generally provide many symbols, corresponding to functions which can be called and variables which can be read or written.\r | |
51 | Symbols can be used by the DSO itself, or by other DSOs which require services.</p></div>\r | |
52 | <div class="paragraph"><p>When a DSO creates a symbol, this is called <em>exporting</em>.\r | |
53 | If a DSO needs to use a symbol, this is called <em>importing</em>.\r | |
54 | A DSO might need to use symbols defined within itself or perhaps from another DSO.\r | |
55 | In both cases, it is importing that symbol, but the scope of the import differs.\r | |
56 | Similarly, a DSO might export a symbol for use only within itself, or it might export a symbol for use by other DSOs.\r | |
57 | 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>\r | |
58 | </div>\r | |
59 | </div>\r | |
60 | <div class="sect1">\r | |
61 | <h2 id="_symbols_in_mlton">Symbols in MLton</h2>\r | |
62 | <div class="sectionbody">\r | |
63 | <div class="paragraph"><p>Symbols in MLton are both imported and exported via the <a href="ForeignFunctionInterface">ForeignFunctionInterface</a>.\r | |
64 | 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.\r | |
65 | 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.\r | |
66 | For details of the syntax and restrictions on the supported FFI types, read the <a href="ForeignFunctionInterface">ForeignFunctionInterface</a> page.\r | |
67 | In this discussion it only matters that every FFI use is either an import or an export.</p></div>\r | |
68 | <div class="paragraph"><p>When exporting a symbol, MLton supports controlling the export scope.\r | |
69 | If the symbol should only be used within the same DSO, that symbol has <em><span class="monospaced">private</span></em> scope.\r | |
70 | Conversely, if the symbol should also be available to other DSOs the symbol has <em><span class="monospaced">public</span></em> scope.\r | |
71 | Generally, one should have as few public exports as possible.\r | |
72 | Since they are public, other DSOs will come to depend on them, limiting your ability to change them.\r | |
73 | You specify the export scope in MLton by putting <span class="monospaced">private</span> or <span class="monospaced">public</span> after the symbol’s name in an FFI directive.\r | |
74 | eg: <span class="monospaced">_export "foo" private: int->int;</span> or <span class="monospaced">_export "bar" public: int->int;</span> .</p></div>\r | |
75 | <div class="paragraph"><p>For technical reasons, the linker and loader on various platforms need to know the scope of a symbol being imported.\r | |
76 | If the symbol is exported by the same DSO, use <span class="monospaced">public</span> or <span class="monospaced">private</span> as appropriate.\r | |
77 | 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.\r | |
78 | Within a DSO, all references to a symbol must use the same scope.\r | |
79 | MLton will check this at compile time, reporting: <span class="monospaced">symbol "foo" redeclared as public (previously external)</span>. This may cause linker errors.\r | |
80 | However, MLton can only check usage within Standard ML.\r | |
81 | All objects being linked into a resulting DSO must agree, and it is the programmer’s responsibility to ensure this.</p></div>\r | |
82 | <div class="paragraph"><p>Summary of symbol scopes:</p></div>\r | |
83 | <div class="ulist"><ul>\r | |
84 | <li>\r | |
85 | <p>\r | |
86 | <span class="monospaced">private</span>: used for symbols exported within a DSO only for use within that DSO\r | |
87 | </p>\r | |
88 | </li>\r | |
89 | <li>\r | |
90 | <p>\r | |
91 | <span class="monospaced">public</span>: used for symbols exported within a DSO that may also be used outside that DSO\r | |
92 | </p>\r | |
93 | </li>\r | |
94 | <li>\r | |
95 | <p>\r | |
96 | <span class="monospaced">external</span>: used for importing symbols from another DSO\r | |
97 | </p>\r | |
98 | </li>\r | |
99 | <li>\r | |
100 | <p>\r | |
101 | All uses of a symbol within a DSO (both imports and exports) must agree on the symbol scope\r | |
102 | </p>\r | |
103 | </li>\r | |
104 | </ul></div>\r | |
105 | </div>\r | |
106 | </div>\r | |
107 | <div class="sect1">\r | |
108 | <h2 id="_output_formats">Output Formats</h2>\r | |
109 | <div class="sectionbody">\r | |
110 | <div class="paragraph"><p>MLton can create executables (<span class="monospaced">-format executable</span>) and dynamic shared libraries (<span class="monospaced">-format library</span>).\r | |
111 | To link a shared library, use <span class="monospaced">-link-opt -l<dso_name></span>.\r | |
112 | The default output format is executable.</p></div>\r | |
113 | <div class="paragraph"><p>MLton can also create archives.\r | |
114 | An archive is not a DSO, but it does have a collection of symbols.\r | |
115 | When an archive is linked into a DSO, it is completely absorbed.\r | |
116 | 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.\r | |
117 | 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>\r | |
118 | <div class="paragraph"><p>Although both executables and libraries are DSOs, some implementation details differ on some platforms.\r | |
119 | For this reason, MLton can create two types or archives.\r | |
120 | A normal archive (<span class="monospaced">-format archive</span>) is appropriate for linking into an executable.\r | |
121 | Conversely, a libarchive (<span class="monospaced">-format libarchive</span>) should be used if it will be linked into a dynamic library.</p></div>\r | |
122 | <div class="paragraph"><p>When MLton does not create an executable, it creates two special symbols.\r | |
123 | The symbol <span class="monospaced">libname_open</span> is a function which must be called before any other symbols are accessed.\r | |
124 | 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> → <span class="monospaced">foo</span>, <span class="monospaced">libfoo</span> → <span class="monospaced">foo</span>).\r | |
125 | The symbol <span class="monospaced">libname_close</span> is a function which should be called to clean up memory once done.</p></div>\r | |
126 | <div class="paragraph"><p>Summary of <span class="monospaced">-format</span> options:</p></div>\r | |
127 | <div class="ulist"><ul>\r | |
128 | <li>\r | |
129 | <p>\r | |
130 | <span class="monospaced">executable</span>: create an executable (a DSO)\r | |
131 | </p>\r | |
132 | </li>\r | |
133 | <li>\r | |
134 | <p>\r | |
135 | <span class="monospaced">library</span>: create a dynamic shared library (a DSO)\r | |
136 | </p>\r | |
137 | </li>\r | |
138 | <li>\r | |
139 | <p>\r | |
140 | <span class="monospaced">archive</span>: create an archive of symbols (not a DSO) that can be linked into an executable\r | |
141 | </p>\r | |
142 | </li>\r | |
143 | <li>\r | |
144 | <p>\r | |
145 | <span class="monospaced">libarchive</span>: create an archive of symbols (not a DSO) that can be linked into a library\r | |
146 | </p>\r | |
147 | </li>\r | |
148 | </ul></div>\r | |
149 | <div class="paragraph"><p>Related options:</p></div>\r | |
150 | <div class="ulist"><ul>\r | |
151 | <li>\r | |
152 | <p>\r | |
153 | <span class="monospaced">-libname x</span>: controls the name of the special <span class="monospaced">_open</span> and <span class="monospaced">_close</span> functions.\r | |
154 | </p>\r | |
155 | </li>\r | |
156 | </ul></div>\r | |
157 | </div>\r | |
158 | </div>\r | |
159 | <div class="sect1">\r | |
160 | <h2 id="_interfacing_with_c">Interfacing with C</h2>\r | |
161 | <div class="sectionbody">\r | |
162 | <div class="paragraph"><p>MLton can generate a C header file.\r | |
163 | When the output format is not an executable, it creates one by default named <span class="monospaced">libname.h</span>.\r | |
164 | This can be overridden with <span class="monospaced">-export-header foo.h</span>.\r | |
165 | This header file should be included by any C files using the exported Standard ML symbols.</p></div>\r | |
166 | <div class="paragraph"><p>If C is being linked with Standard ML into the same output archive or DSO,\r | |
167 | then the C code should <span class="monospaced">#define PART_OF_LIBNAME</span> before it includes the header file.\r | |
168 | This ensures that the C code is using the symbols with correct scope.\r | |
169 | 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.\r | |
170 | The declared C scope on exported C symbols should match the import scope used in Standard ML.</p></div>\r | |
171 | <div class="paragraph"><p>An example:</p></div>\r | |
172 | <div class="listingblock">\r | |
173 | <div class="content"><div class="highlight"><pre><span class="cp">#define PART_OF_FOO</span>\r | |
174 | <span class="cp">#include</span> <span class="cpf">"foo.h"</span><span class="cp"></span>\r | |
175 | \r | |
176 | <span class="n">PUBLIC</span> <span class="kt">int</span> <span class="nf">cFoo</span><span class="p">()</span> <span class="p">{</span>\r | |
177 | <span class="k">return</span> <span class="n">smlFoo</span><span class="p">();</span>\r | |
178 | <span class="p">}</span>\r | |
179 | </pre></div></div></div>\r | |
180 | <div class="listingblock">\r | |
181 | <div class="content"><div class="highlight"><pre><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">"smlFoo"</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">-></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">=></span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"></span>\r | |
182 | <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">"cFoo"</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">-></span><span class="w"> </span><span class="n">int</span><span class="p">;</span><span class="w"></span>\r | |
183 | </pre></div></div></div>\r | |
184 | </div>\r | |
185 | </div>\r | |
186 | <div class="sect1">\r | |
187 | <h2 id="_operating_system_specific_details">Operating-system specific details</h2>\r | |
188 | <div class="sectionbody">\r | |
189 | <div class="paragraph"><p>On Windows, <span class="monospaced">libarchive</span> and <span class="monospaced">archive</span> are the same.\r | |
190 | However, depending on this will lead to portability problems.\r | |
191 | Windows is also especially sensitive to mixups of <em><span class="monospaced">public</span></em> and <em><span class="monospaced">external</span></em>.\r | |
192 | If an archive is linked, make sure it’s symbols are imported as <span class="monospaced">public</span>.\r | |
193 | If a DLL is linked, make sure it’s symbols are imported as <span class="monospaced">external</span>.\r | |
194 | 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>.\r | |
195 | 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>\r | |
196 | <div class="paragraph"><p>On Linux, <span class="monospaced">libarchive</span> and <span class="monospaced">archive</span> are different.\r | |
197 | Libarchives are quite rare, but necessary if creating a library from an archive.\r | |
198 | It is common for a library to provide both an archive and a dynamic library on this platform.\r | |
199 | The linker will pick one or the other, usually preferring the dynamic library.\r | |
200 | While a quirk of the operating system allows external import to work for both archives and libraries,\r | |
201 | portable projects should not depend on this behaviour.\r | |
202 | On other systems it can matter how the library is linked (static or dynamic).</p></div>\r | |
203 | </div>\r | |
204 | </div>\r | |
205 | </div>\r | |
206 | <div id="footnotes"><hr></div>\r | |
207 | <div id="footer">\r | |
208 | <div id="footer-text">\r | |
209 | </div>\r | |
210 | <div id="footer-badges">\r | |
211 | </div>\r | |
212 | </div>\r | |
213 | </body>\r | |
214 | </html>\r |