summary refs log tree commit diff stats
path: root/doc/backends.rst
diff options
context:
space:
mode:
authorAndrey Makarov <ph.makarov@gmail.com>2022-07-15 20:27:54 +0300
committerGitHub <noreply@github.com>2022-07-15 19:27:54 +0200
commit417b90a7e5b88bfc0ad1bfbbc81a3205c99e128e (patch)
tree676f65014d120cb19d5f8fa8b92cf27557a6f80a /doc/backends.rst
parentf35c9cf73ddb3150ab6dbe449db4975866ee8a11 (diff)
downloadNim-417b90a7e5b88bfc0ad1bfbbc81a3205c99e128e.tar.gz
Improve Markdown code blocks & start moving docs to Markdown style (#19954)
- add additional parameters parsing (other implementations will just
  ignore them). E.g. if in RST we have:

  .. code:: nim
     :test: "nim c $1"

     ...

  then in Markdown that will be:

  ```nim test="nim c $1"
  ...
  ```

- implement Markdown interpretation of additional indentation which is
  less than 4 spaces (>=4 spaces is a code block but it's not
implemented yet). RST interpretes it as quoted block, for Markdown it's
just normal paragraphs.
- add separate `md2html` and `md2tex` commands. This is to separate
  Markdown behavior in cases when it diverges w.r.t. RST significantly —
most conspicously like in the case of additional indentation above, and
also currently the contradicting inline rule of Markdown is also turned
on only in `md2html` and `md2tex`. **Rationale:** mixing Markdown and
RST arbitrarily is a way to nowhere, we need to provide a way to fix the
particular behavior. Note that still all commands have **both** Markdown
and RST features **enabled**. In this PR `*.nim` files can be processed
only in Markdown mode, while `md2html` is for `*.md` files and
`rst2html` for `*.rst` files.
- rename `*.rst` files to `.*md` as our current default behavior is
  already Markdown-ish
- convert code blocks in `docgen.rst` to Markdown style as an example.
  Other code blocks will be converted in the follow-up PRs
- fix indentation inside Markdown code blocks — additional indentation
  is preserved there
- allow more than 3 backticks open/close blocks (tildas \~ are still not
  allowed to avoid conflict with RST adornment headings) see also
https://github.com/nim-lang/RFCs/issues/355
- better error messages
- (other) fix a bug that admonitions cannot be used in sandbox mode; fix
  annoying warning on line 2711
Diffstat (limited to 'doc/backends.rst')
-rw-r--r--doc/backends.rst408
1 files changed, 0 insertions, 408 deletions
diff --git a/doc/backends.rst b/doc/backends.rst
deleted file mode 100644
index 65dd8a6f2..000000000
--- a/doc/backends.rst
+++ /dev/null
@@ -1,408 +0,0 @@
-================================
-   Nim Backend Integration
-================================
-
-:Author: Puppet Master
-:Version: |nimversion|
-
-.. default-role:: code
-.. include:: rstcommon.rst
-.. no syntax highlighting here by default:
-
-.. contents::
-  "Heresy grows from idleness." -- Unknown.
-
-
-Introduction
-============
-
-The `Nim Compiler User Guide <nimc.html>`_ documents the typical
-compiler invocation, using the `compile`:option:
-or `c`:option: command to transform a
-``.nim`` file into one or more ``.c`` files which are then compiled with the
-platform's C compiler into a static binary. However, there are other commands
-to compile to C++, Objective-C, or JavaScript. This document tries to
-concentrate in a single place all the backend and interfacing options.
-
-The Nim compiler supports mainly two backend families: the C, C++ and
-Objective-C targets and the JavaScript target. `The C like targets
-<#backends-the-c-like-targets>`_ creates source files that can be compiled
-into a library or a final executable. `The JavaScript target
-<#backends-the-javascript-target>`_ can generate a ``.js`` file which you
-reference from an HTML file or create a `standalone Node.js program
-<http://nodejs.org>`_.
-
-On top of generating libraries or standalone applications, Nim offers
-bidirectional interfacing with the backend targets through generic and
-specific pragmas.
-
-
-Backends
-========
-
-The C like targets
-------------------
-
-The commands to compile to either C, C++ or Objective-C are:
-
-//compileToC, cc          compile project with C code generator
-//compileToCpp, cpp       compile project to C++ code
-//compileToOC, objc       compile project to Objective C code
-
-The most significant difference between these commands is that if you look
-into the ``nimcache`` directory you will find ``.c``, ``.cpp`` or ``.m``
-files, other than that all of them will produce a native binary for your
-project. This allows you to take the generated code and place it directly
-into a project using any of these languages. Here are some typical command-
-line invocations:
-
-.. code:: cmd
-
-   nim c hallo.nim
-   nim cpp hallo.nim
-   nim objc hallo.nim
-
-The compiler commands select the target backend, but if needed you can
-`specify additional switches for cross-compilation
-<nimc.html#crossminuscompilation>`_ to select the target CPU, operative system
-or compiler/linker commands.
-
-
-The JavaScript target
----------------------
-
-Nim can also generate `JavaScript`:idx: code through the `js`:option: command.
-
-Nim targets JavaScript 1.5 which is supported by any widely used browser.
-Since JavaScript does not have a portable means to include another module,
-Nim just generates a long ``.js`` file.
-
-Features or modules that the JavaScript platform does not support are not
-available. This includes:
-
-* manual memory management (`alloc`, etc.)
-* casting and other unsafe operations (`cast` operator, `zeroMem`, etc.)
-* file management
-* OS-specific operations
-* threading, coroutines
-* some modules of the standard library
-* proper 64-bit integer arithmetic
-
-To compensate, the standard library has modules `catered to the JS backend
-<lib.html#pure-libraries-modules-for-js-backend>`_
-and more support will come in the future (for instance, Node.js bindings
-to get OS info).
-
-To compile a Nim module into a ``.js`` file use the `js`:option: command; the
-default is a ``.js`` file that is supposed to be referenced in an ``.html``
-file. However, you can also run the code with `nodejs`:idx:
-(`<http://nodejs.org>`_):
-
-.. code:: cmd
-
-  nim js -d:nodejs -r examples/hallo.nim
-
-If you experience errors saying that `globalThis` is not defined, be
-sure to run a recent version of Node.js (at least 12.0).
-
-
-Interfacing
-===========
-
-Nim offers bidirectional interfacing with the target backend. This means
-that you can call backend code from Nim and Nim code can be called by
-the backend code. Usually the direction of which calls which depends on your
-software architecture (is Nim your main program or is Nim providing a
-component?).
-
-
-Nim code calling the backend
-----------------------------
-
-Nim code can interface with the backend through the `Foreign function
-interface <manual.html#foreign-function-interface>`_ mainly through the
-`importc pragma <manual.html#foreign-function-interface-importc-pragma>`_.
-The `importc` pragma is the *generic* way of making backend symbols available
-in Nim and is available in all the target backends (JavaScript too). The C++
-or Objective-C backends have their respective `ImportCpp
-<manual.html#implementation-specific-pragmas-importcpp-pragma>`_ and
-`ImportObjC <manual.html#implementation-specific-pragmas-importobjc-pragma>`_
-pragmas to call methods from classes.
-
-Whenever you use any of these pragmas you need to integrate native code into
-your final binary. In the case of JavaScript this is no problem at all, the
-same HTML file which hosts the generated JavaScript will likely provide other
-JavaScript functions which you are importing with `importc`.
-
-However, for the C like targets you need to link external code either
-statically or dynamically. The preferred way of integrating native code is to
-use dynamic linking because it allows you to compile Nim programs without
-the need for having the related development libraries installed. This is done
-through the `dynlib pragma for import
-<manual.html#foreign-function-interface-dynlib-pragma-for-import>`_, though
-more specific control can be gained using the `dynlib module <dynlib.html>`_.
-
-The `dynlibOverride <nimc.html#dynliboverride>`_ command line switch allows
-to avoid dynamic linking if you need to statically link something instead.
-Nim wrappers designed to statically link source files can use the `compile
-pragma <manual.html#implementation-specific-pragmas-compile-pragma>`_ if
-there are few sources or providing them along the Nim code is easier than using
-a system library. Libraries installed on the host system can be linked in with
-the `PassL pragma <manual.html#implementation-specific-pragmas-passl-pragma>`_.
-
-To wrap native code, take a look at the `c2nim tool <https://github.com/nim-lang/c2nim/blob/master/doc/c2nim.rst>`_ which helps
-with the process of scanning and transforming header files into a Nim
-interface.
-
-C invocation example
-~~~~~~~~~~~~~~~~~~~~
-
-Create a ``logic.c`` file with the following content:
-
-.. code-block:: c
-  int addTwoIntegers(int a, int b)
-  {
-    return a + b;
-  }
-
-Create a ``calculator.nim`` file with the following content:
-
-.. code-block:: nim
-
-  {.compile: "logic.c".}
-  proc addTwoIntegers(a, b: cint): cint {.importc.}
-
-  when isMainModule:
-    echo addTwoIntegers(3, 7)
-
-With these two files in place, you can run `nim c -r calculator.nim`:cmd: and
-the Nim compiler will compile the ``logic.c`` file in addition to
-``calculator.nim`` and link both into an executable, which outputs `10` when
-run. Another way to link the C file statically and get the same effect would
-be to remove the line with the `compile` pragma and run the following
-typical Unix commands:
-
-.. code:: cmd
-
-    gcc -c logic.c
-    ar rvs mylib.a logic.o
-    nim c --passL:mylib.a -r calculator.nim
-
-Just like in this example we pass the path to the ``mylib.a`` library (and we
-could as well pass ``logic.o``) we could be passing switches to link any other
-static C library.
-
-
-JavaScript invocation example
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Create a ``host.html`` file with the following content:
-
-.. code-block::
-
-  <html><body>
-  <script type="text/javascript">
-  function addTwoIntegers(a, b)
-  {
-    return a + b;
-  }
-  </script>
-  <script type="text/javascript" src="calculator.js"></script>
-  </body></html>
-
-Create a ``calculator.nim`` file with the following content (or reuse the one
-from the previous section):
-
-.. code-block:: nim
-
-  proc addTwoIntegers(a, b: int): int {.importc.}
-
-  when isMainModule:
-    echo addTwoIntegers(3, 7)
-
-Compile the Nim code to JavaScript with `nim js -o:calculator.js
-calculator.nim`:cmd: and open ``host.html`` in a browser. If the browser supports
-javascript, you should see the value `10` in the browser's console. Use the
-`dom module <dom.html>`_ for specific DOM querying and modification procs
-or take a look at `karax <https://github.com/pragmagic/karax>`_ for how to
-develop browser-based applications.
-
-
-Backend code calling Nim
-------------------------
-
-Backend code can interface with Nim code exposed through the `exportc
-pragma <manual.html#foreign-function-interface-exportc-pragma>`_. The
-`exportc` pragma is the *generic* way of making Nim symbols available to
-the backends. By default, the Nim compiler will mangle all the Nim symbols to
-avoid any name collision, so the most significant thing the `exportc` pragma
-does is maintain the Nim symbol name, or if specified, use an alternative
-symbol for the backend in case the symbol rules don't match.
-
-The JavaScript target doesn't have any further interfacing considerations
-since it also has garbage collection, but the C targets require you to
-initialize Nim's internals, which is done calling a `NimMain` function.
-Also, C code requires you to specify a forward declaration for functions or
-the compiler will assume certain types for the return value and parameters
-which will likely make your program crash at runtime.
-
-The name `NimMain` can be influenced via the `--nimMainPrefix:prefix` switch.
-Use `--nimMainPrefix:MyLib` and the function to call is named `MyLibNimMain`.
-
-
-Nim invocation example from C
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Create a ``fib.nim`` file with the following content:
-
-.. code-block:: nim
-
-  proc fib(a: cint): cint {.exportc.} =
-    if a <= 2:
-      result = 1
-    else:
-      result = fib(a - 1) + fib(a - 2)
-
-Create a ``maths.c`` file with the following content:
-
-.. code-block:: c
-
-  #include <stdio.h>
-
-  extern int fib(int a);
-
-  int main(void)
-  {
-    NimMain();
-    for (int f = 0; f < 10; f++)
-      printf("Fib of %d is %d\n", f, fib(f));
-    return 0;
-  }
-
-Now you can run the following Unix like commands to first generate C sources
-from the Nim code, then link them into a static binary along your main C
-program:
-
-.. code:: cmd
-
-  nim c --noMain --noLinking fib.nim
-  gcc -o m -I$HOME/.cache/nim/fib_d -Ipath/to/nim/lib $HOME/.cache/nim/fib_d/*.c maths.c
-
-The first command runs the Nim compiler with three special options to avoid
-generating a `main()`:c: function in the generated files and to avoid linking the
-object files into a final binary. All the generated files are placed into the ``nimcache``
-directory. That's why the next command compiles the ``maths.c`` source plus
-all the ``.c`` files from ``nimcache``. In addition to this path, you also
-have to tell the C compiler where to find Nim's ``nimbase.h`` header file.
-
-Instead of depending on the generation of the individual ``.c`` files you can
-also ask the Nim compiler to generate a statically linked library:
-
-.. code:: cmd
-
-  nim c --app:staticLib --noMain fib.nim
-  gcc -o m -Inimcache -Ipath/to/nim/lib libfib.nim.a maths.c
-
-The Nim compiler will handle linking the source files generated in the
-``nimcache`` directory into the ``libfib.nim.a`` static library, which you can
-then link into your C program. Note that these commands are generic and will
-vary for each system. For instance, on Linux systems you will likely need to
-use `-ldl`:option: too to link in required dlopen functionality.
-
-
-Nim invocation example from JavaScript
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Create a ``mhost.html`` file with the following content:
-
-.. code-block::
-
-  <html><body>
-  <script type="text/javascript" src="fib.js"></script>
-  <script type="text/javascript">
-  alert("Fib for 9 is " + fib(9));
-  </script>
-  </body></html>
-
-Create a ``fib.nim`` file with the following content (or reuse the one
-from the previous section):
-
-.. code-block:: nim
-
-  proc fib(a: cint): cint {.exportc.} =
-    if a <= 2:
-      result = 1
-    else:
-      result = fib(a - 1) + fib(a - 2)
-
-Compile the Nim code to JavaScript with `nim js -o:fib.js fib.nim`:cmd: and
-open ``mhost.html`` in a browser. If the browser supports javascript, you
-should see an alert box displaying the text ``Fib for 9 is 34``. As mentioned
-earlier, JavaScript doesn't require an initialization call to `NimMain` or
-a similar function and you can call the exported Nim proc directly.
-
-
-Nimcache naming logic
----------------------
-
-The `nimcache`:idx: directory is generated during compilation and will hold
-either temporary or final files depending on your backend target. The default
-name for the directory depends on the used backend and on your OS but you can
-use the `--nimcache`:option: `compiler switch
-<nimc.html#compiler-usage-commandminusline-switches>`_ to change it.
-
-
-Memory management
-=================
-
-In the previous sections, the `NimMain()` function reared its head. Since
-JavaScript already provides automatic memory management, you can freely pass
-objects between the two languages without problems. In C and derivate languages
-you need to be careful about what you do and how you share memory. The
-previous examples only dealt with simple scalar values, but passing a Nim
-string to C, or reading back a C string in Nim already requires you to be
-aware of who controls what to avoid crashing.
-
-
-Strings and C strings
----------------------
-
-The manual mentions that `Nim strings are implicitly convertible to
-cstrings <manual.html#types-cstring-type>`_ which makes interaction usually
-painless. Most C functions accepting a Nim string converted to a
-`cstring` will likely not need to keep this string around and by the time
-they return the string won't be needed anymore. However, for the rare cases
-where a Nim string has to be preserved and made available to the C backend
-as a `cstring`, you will need to manually prevent the string data
-from being freed with `GC_ref <system.html#GC_ref,string>`_ and `GC_unref
-<system.html#GC_unref,string>`_.
-
-A similar thing happens with C code invoking Nim code which returns a
-`cstring`. Consider the following proc:
-
-.. code-block:: nim
-
-  proc gimme(): cstring {.exportc.} =
-    result = "Hey there C code! " & $rand(100)
-
-Since Nim's reference counting mechanism is not aware of the C code, once the
-`gimme` proc has finished it can reclaim the memory of the `cstring`.
-
-
-Custom data types
------------------
-
-Just like strings, custom data types that are to be shared between Nim and
-the backend will need careful consideration of who controls who. If you want
-to hand a Nim reference to C code, you will need to use `GC_ref
-<system.html#GC_ref,ref.T>`_ to mark the reference as used, so it does not get
-freed. And for the C backend you will need to expose the `GC_unref
-<system.html#GC_unref,ref.T>`_ proc to clean up this memory when it is not
-required anymore.
-
-Again, if you are wrapping a library which *mallocs* and *frees* data
-structures, you need to expose the appropriate *free* function to Nim so
-you can clean it up. And of course, once cleaned you should avoid accessing it
-from Nim (or C for that matter). Typically C data structures have their own
-`malloc_structure`:c: and `free_structure`:c: specific functions, so wrapping
-these for the Nim side should be enough.