backends.txt 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. ================================
  2. Nim Backend Integration
  3. ================================
  4. :Author: Puppet Master
  5. :Version: |nimversion|
  6. .. contents::
  7. "Heresy grows from idleness." -- Unknown.
  8. Introduction
  9. ============
  10. The `Nim Compiler User Guide <nimc.html>`_ documents the typical
  11. compiler invocation, using the ``compile`` or ``c`` command to transform a
  12. ``.nim`` file into one or more ``.c`` files which are then compiled with the
  13. platform's C compiler into a static binary. However there are other commands
  14. to compile to C++, Objective-C or JavaScript. This document tries to
  15. concentrate in a single place all the backend and interfacing options.
  16. The Nim compiler supports mainly two backend families: the C, C++ and
  17. Objective-C targets and the JavaScript target. `The C like targets`_ creates
  18. source files which can be compiled into a library or a final executable. `The
  19. JavaScript target`_ can generate a ``.js`` file which you reference from an
  20. HTML file or create a `standalone nodejs program <http://nodejs.org>`_.
  21. On top of generating libraries or standalone applications, Nim offers
  22. bidirectional interfacing with the backend targets through generic and
  23. specific pragmas.
  24. Backends
  25. ========
  26. The C like targets
  27. ------------------
  28. The commands to compile to either C, C++ or Objective-C are:
  29. //compileToC, cc compile project with C code generator
  30. //compileToCpp, cpp compile project to C++ code
  31. //compileToOC, objc compile project to Objective C code
  32. The most significant difference between these commands is that if you look
  33. into the ``nimcache`` directory you will find ``.c``, ``.cpp`` or ``.m``
  34. files, other than that all of them will produce a native binary for your
  35. project. This allows you to take the generated code and place it directly
  36. into a project using any of these languages. Here are some typical command
  37. line invocations::
  38. $ nim c hallo.nim
  39. $ nim cpp hallo.nim
  40. $ nim objc hallo.nim
  41. The compiler commands select the target backend, but if needed you can
  42. `specify additional switches for cross compilation
  43. <nimc.html#cross-compilation>`_ to select the target CPU, operative system
  44. or compiler/linker commands.
  45. The JavaScript target
  46. ---------------------
  47. Nim can also generate `JavaScript`:idx: code through the ``js`` command.
  48. However, the JavaScript code generator is experimental!
  49. Nim targets JavaScript 1.5 which is supported by any widely used browser.
  50. Since JavaScript does not have a portable means to include another module,
  51. Nim just generates a long ``.js`` file.
  52. Features or modules that the JavaScript platform does not support are not
  53. available. This includes:
  54. * manual memory management (``alloc``, etc.)
  55. * casting and other unsafe operations (``cast`` operator, ``zeroMem``, etc.)
  56. * file management
  57. * most modules of the Standard library
  58. * proper 64 bit integer arithmetic
  59. * unsigned integer arithmetic
  60. However, the modules `strutils <strutils.html>`_, `math <math.html>`_, and
  61. `times <times.html>`_ are available! To access the DOM, use the `dom
  62. <dom.html>`_ module that is only available for the JavaScript platform.
  63. To compile a Nim module into a ``.js`` file use the ``js`` command; the
  64. default is a ``.js`` file that is supposed to be referenced in an ``.html``
  65. file. However, you can also run the code with `nodejs`:idx:, a `software
  66. platform for easily building fast, scalable network applications
  67. <http://nodejs.org>`_::
  68. nim js -d:nodejs -r examples/hallo.nim
  69. Interfacing
  70. ===========
  71. Nim offers bidirectional interfacing with the target backend. This means
  72. that you can call backend code from Nim and Nim code can be called by
  73. the backend code. Usually the direction of which calls which depends on your
  74. software architecture (is Nim your main program or is Nim providing a
  75. component?).
  76. Nim code calling the backend
  77. ----------------------------
  78. Nim code can interface with the backend through the `Foreign function
  79. interface <manual.html#foreign-function-interface>`_ mainly through the
  80. `importc pragma <manual.html#importc-pragma>`_. The ``importc`` pragma is the
  81. *generic* way of making backend symbols available in Nim and is available
  82. in all the target backends (JavaScript too). The C++ or Objective-C backends
  83. have their respective `ImportCpp <manual.html#implementation-specific-pragmas-importcpp-pragma>`_ and
  84. `ImportObjC <manual.html#implementation-specific-pragmas-importobjc-pragma>`_ pragmas to call methods from
  85. classes.
  86. Whenever you use any of these pragmas you need to integrate native code into
  87. your final binary. In the case of JavaScript this is no problem at all, the
  88. same html file which hosts the generated JavaScript will likely provide other
  89. JavaScript functions which you are importing with ``importc``.
  90. However, for the C like targets you need to link external code either
  91. statically or dynamically. The preferred way of integrating native code is to
  92. use dynamic linking because it allows you to compile Nim programs without
  93. the need for having the related development libraries installed. This is done
  94. through the `dynlib pragma for import
  95. <manual.html#dynlib-pragma-for-import>`_, though more specific control can be
  96. gained using the `dynlib module <dynlib.html>`_.
  97. The `dynlibOverride <nimc.html#dynliboverride>`_ command line switch allows
  98. to avoid dynamic linking if you need to statically link something instead.
  99. Nim wrappers designed to statically link source files can use the `compile
  100. pragma <nimc.html#compile-pragma>`_ if there are few sources or providing
  101. them along the Nim code is easier than using a system library. Libraries
  102. installed on the host system can be linked in with the `PassL pragma
  103. <nimc.html#passl-pragma>`_.
  104. To wrap native code, take a look at the `c2nim tool <c2nim.html>`_ which helps
  105. with the process of scanning and transforming header files into a Nim
  106. interface.
  107. C invocation example
  108. ~~~~~~~~~~~~~~~~~~~~
  109. Create a ``logic.c`` file with the following content:
  110. .. code-block:: c
  111. int addTwoIntegers(int a, int b)
  112. {
  113. return a + b;
  114. }
  115. Create a ``calculator.nim`` file with the following content:
  116. .. code-block:: nim
  117. {.compile: "logic.c".}
  118. proc addTwoIntegers(a, b: cint): cint {.importc.}
  119. when isMainModule:
  120. echo addTwoIntegers(3, 7)
  121. With these two files in place, you can run ``nim c -r calculator.nim`` and
  122. the Nim compiler will compile the ``logic.c`` file in addition to
  123. ``calculator.nim`` and link both into an executable, which outputs ``10`` when
  124. run. Another way to link the C file statically and get the same effect would
  125. be remove the line with the ``compile`` pragma and run the following typical
  126. Unix commands::
  127. $ gcc -c logic.c
  128. $ ar rvs mylib.a logic.o
  129. $ nim c --passL:mylib.a -r calculator.nim
  130. Just like in this example we pass the path to the ``mylib.a`` library (and we
  131. could as well pass ``logic.o``) we could be passing switches to link any other
  132. static C library.
  133. JavaScript invocation example
  134. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  135. Create a ``host.html`` file with the following content:
  136. .. code-block::
  137. <html><body>
  138. <script type="text/javascript">
  139. function addTwoIntegers(a, b)
  140. {
  141. return a + b;
  142. }
  143. </script>
  144. <script type="text/javascript" src="calculator.js"></script>
  145. </body></html>
  146. Create a ``calculator.nim`` file with the following content (or reuse the one
  147. from the previous section):
  148. .. code-block:: nim
  149. proc addTwoIntegers(a, b: int): int {.importc.}
  150. when isMainModule:
  151. echo addTwoIntegers(3, 7)
  152. Compile the Nim code to JavaScript with ``nim js -o:calculator.js
  153. calculator.nim`` and open ``host.html`` in a browser. If the browser supports
  154. javascript, you should see the value ``10``. In JavaScript the `echo proc
  155. <system.html#echo>`_ will modify the HTML DOM and append the string. Use the
  156. `dom module <dom.html>`_ for specific DOM querying and modification procs.
  157. Backend code calling Nim
  158. ------------------------
  159. Backend code can interface with Nim code exposed through the `exportc
  160. pragma <manual.html#exportc-pragma>`_. The ``exportc`` pragma is the *generic*
  161. way of making Nim symbols available to the backends. By default the Nim
  162. compiler will mangle all the Nim symbols to avoid any name collision, so
  163. the most significant thing the ``exportc`` pragma does is maintain the Nim
  164. symbol name, or if specified, use an alternative symbol for the backend in
  165. case the symbol rules don't match.
  166. The JavaScript target doesn't have any further interfacing considerations
  167. since it also has garbage collection, but the C targets require you to
  168. initialize Nim's internals, which is done calling a ``NimMain`` function.
  169. Also, C code requires you to specify a forward declaration for functions or
  170. the compiler will assume certain types for the return value and parameters
  171. which will likely make your program crash at runtime.
  172. The Nim compiler can generate a C interface header through the ``--header``
  173. command line switch. The generated header will contain all the exported
  174. symbols and the ``NimMain`` proc which you need to call before any other
  175. Nim code.
  176. Nim invocation example from C
  177. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  178. Create a ``fib.nim`` file with the following content:
  179. .. code-block:: nim
  180. proc fib(a: cint): cint {.exportc.} =
  181. if a <= 2:
  182. result = 1
  183. else:
  184. result = fib(a - 1) + fib(a - 2)
  185. Create a ``maths.c`` file with the following content:
  186. .. code-block:: c
  187. #include "fib.h"
  188. #include <stdio.h>
  189. int main(void)
  190. {
  191. NimMain();
  192. for (int f = 0; f < 10; f++)
  193. printf("Fib of %d is %d\n", f, fib(f));
  194. return 0;
  195. }
  196. Now you can run the following Unix like commands to first generate C sources
  197. form the Nim code, then link them into a static binary along your main C
  198. program::
  199. $ nim c --noMain --noLinking --header:fib.h fib.nim
  200. $ gcc -o m -Inimcache -Ipath/to/nim/lib nimcache/*.c maths.c
  201. The first command runs the Nim compiler with three special options to avoid
  202. generating a ``main()`` function in the generated files, avoid linking the
  203. object files into a final binary, and explicitly generate a header file for C
  204. integration. All the generated files are placed into the ``nimcache``
  205. directory. That's why the next command compiles the ``maths.c`` source plus
  206. all the ``.c`` files form ``nimcache``. In addition to this path, you also
  207. have to tell the C compiler where to find Nim's ``nimbase.h`` header file.
  208. Instead of depending on the generation of the individual ``.c`` files you can
  209. also ask the Nim compiler to generate a statically linked library::
  210. $ nim c --app:staticLib --noMain --header fib.nim
  211. $ gcc -o m -Inimcache -Ipath/to/nim/lib libfib.nim.a maths.c
  212. The Nim compiler will handle linking the source files generated in the
  213. ``nimcache`` directory into the ``libfib.nim.a`` static library, which you can
  214. then link into your C program. Note that these commands are generic and will
  215. vary for each system. For instance, on Linux systems you will likely need to
  216. use ``-ldl`` too to link in required dlopen functionality.
  217. Nim invocation example from JavaScript
  218. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  219. Create a ``mhost.html`` file with the following content:
  220. .. code-block::
  221. <html><body>
  222. <script type="text/javascript" src="fib.js"></script>
  223. <script type="text/javascript">
  224. alert("Fib for 9 is " + fib(9));
  225. </script>
  226. </body></html>
  227. Create a ``fib.nim`` file with the following content (or reuse the one
  228. from the previous section):
  229. .. code-block:: nim
  230. proc fib(a: cint): cint {.exportc.} =
  231. if a <= 2:
  232. result = 1
  233. else:
  234. result = fib(a - 1) + fib(a - 2)
  235. Compile the Nim code to JavaScript with ``nim js -o:fib.js fib.nim`` and
  236. open ``mhost.html`` in a browser. If the browser supports javascript, you
  237. should see an alert box displaying the text ``Fib for 9 is 34``. As mentioned
  238. earlier, JavaScript doesn't require an initialisation call to ``NimMain`` or
  239. similar function and you can call the exported Nim proc directly.
  240. Nimcache naming logic
  241. ---------------------
  242. The `nimcache`:idx: directory is generated during compilation and will hold
  243. either temporary or final files depending on your backend target. The default
  244. name for the directory is ``nimcache`` but you can use the ``--nimcache``
  245. `compiler switch <nimc.html#command-line-switches>`_ to change it.
  246. Nimcache and C like targets
  247. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  248. The C like backends will place their temporary ``.c``, ``.cpp`` or ``.m`` files
  249. in the ``nimcache`` directory. The naming of these files follows the pattern
  250. ``nimblePackageName_`` + ``nimSource``:
  251. * Filenames for modules imported from `nimble packages
  252. <https://github.com/nim-lang/nimble>`_ will end up with
  253. ``nimblePackageName_module.c``. For example, if you import the
  254. ``argument_parser`` module from the same name nimble package you
  255. will end up with a ``argument_parser_argument_parser.c`` file
  256. under ``nimcache``. The name of the nimble package comes from the
  257. ``proj.nimble`` file, the actual contents are not read by the
  258. compiler.
  259. * Filenames for non nimble packages (like your project) will be
  260. renamed from ``.nim`` to have the extension of your target backend
  261. (from now on ``.c`` for these examples), but otherwise nothing
  262. else will change. This will quickly break if your project consists
  263. of a main ``proj.nim`` file which includes a ``utils/proj.nim``
  264. file: both ``proj.nim`` files will generate the same name ``proj.c``
  265. output in the ``nimcache`` directory overwriting themselves!
  266. * Filenames for modules found in the standard library will be named
  267. ``stdlib_module.c``. Unless you are doing something special, you
  268. will end up with at least ``stdlib_system.c``, since the `system
  269. module <system.html>`_ is always imported automatically. Same for
  270. the `hashes module <hashes.html>`_ which will be named
  271. ``stdlib_hashes.c``. The ``stdlib_`` prefix comes from the *fake*
  272. ``lib/stdlib.nimble`` file.
  273. To find the name of a nimble package the compiler searches for a ``*.nimble``
  274. file in the parent directory hierarchy of whatever module you are compiling.
  275. Even if you are in a subdirectory of your project, a parent ``*.nimble`` file
  276. will influence the naming of the nimcache name. This means that on Unix systems
  277. creating the file ``~/foo.nimble`` will automatically prefix all nimcache files
  278. not part of another package with the string ``foo_``.
  279. Nimcache and the Javascript target
  280. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  281. Unless you explicitly use the ``-o:filename.js`` switch as mentioned in the
  282. previous examples, the compiler will create a ``filename.js`` file in the
  283. ``nimcache`` directory using the name of your input nim file. There are no
  284. other temporary files generated, the output is always a single self contained
  285. ``.js`` file.
  286. Memory management
  287. =================
  288. In the previous sections the ``NimMain()`` function reared its head. Since
  289. JavaScript already provides automatic memory management, you can freely pass
  290. objects between the two language without problems. In C and derivate languages
  291. you need to be careful about what you do and how you share memory. The
  292. previous examples only dealt with simple scalar values, but passing a Nim
  293. string to C, or reading back a C string in Nim already requires you to be
  294. aware of who controls what to avoid crashing.
  295. Strings and C strings
  296. ---------------------
  297. The manual mentions that `Nim strings are implicitly convertible to
  298. cstrings <manual.html#cstring-type>`_ which makes interaction usually
  299. painless. Most C functions accepting a Nim string converted to a
  300. ``cstring`` will likely not need to keep this string around and by the time
  301. they return the string won't be needed any more. However, for the rare cases
  302. where a Nim string has to be preserved and made available to the C backend
  303. as a ``cstring``, you will need to manually prevent the string data from being
  304. freed with `GC_ref <system.html#GC_ref>`_ and `GC_unref
  305. <system.html#GC_unref>`_.
  306. A similar thing happens with C code invoking Nim code which returns a
  307. ``cstring``. Consider the following proc:
  308. .. code-block:: nim
  309. proc gimme(): cstring {.exportc.} =
  310. result = "Hey there C code! " & $random(100)
  311. Since Nim's garbage collector is not aware of the C code, once the
  312. ``gimme`` proc has finished it can reclaim the memory of the ``cstring``.
  313. However, from a practical standpoint, the C code invoking the ``gimme``
  314. function directly will be able to use it since Nim's garbage collector has
  315. not had a chance to run *yet*. This gives you enough time to make a copy for
  316. the C side of the program, as calling any further Nim procs *might* trigger
  317. garbage collection making the previously returned string garbage. Or maybe you
  318. are `yourself triggering the collection <gc.html>`_.
  319. Custom data types
  320. -----------------
  321. Just like strings, custom data types that are to be shared between Nim and
  322. the backend will need careful consideration of who controls who. If you want
  323. to hand a Nim reference to C code, you will need to use `GC_ref
  324. <system.html#GC_ref>`_ to mark the reference as used, so it does not get
  325. freed. And for the C backend you will need to expose the `GC_unref
  326. <system.html#GC_unref>`_ proc to clean up this memory when it is not required
  327. any more.
  328. Again, if you are wrapping a library which *mallocs* and *frees* data
  329. structures, you need to expose the appropriate *free* function to Nim so
  330. you can clean it up. And of course, once cleaned you should avoid accessing it
  331. from Nim (or C for that matter). Typically C data structures have their own
  332. ``malloc_structure`` and ``free_structure`` specific functions, so wrapping
  333. these for the Nim side should be enough.
  334. Thread coordination
  335. -------------------
  336. When the ``NimMain()`` function is called Nim initializes the garbage
  337. collector to the current thread, which is usually the main thread of your
  338. application. If your C code later spawns a different thread and calls Nim
  339. code, the garbage collector will fail to work properly and you will crash.
  340. As long as you don't use the threadvar emulation Nim uses native thread
  341. variables, of which you get a fresh version whenever you create a thread. You
  342. can then attach a GC to this thread via
  343. .. code-block:: nim
  344. system.setupForeignThreadGc()
  345. It is **not** safe to disable the garbage collector and enable it after the
  346. call from your background thread even if the code you are calling is short
  347. lived.
  348. Before the thread exits, you should tear down the thread's GC to prevent memory
  349. leaks by calling
  350. .. code-block:: nim
  351. system.tearDownForeignThreadGc()