diff options
Diffstat (limited to 'doc/nimc.rst')
-rw-r--r-- | doc/nimc.rst | 474 |
1 files changed, 474 insertions, 0 deletions
diff --git a/doc/nimc.rst b/doc/nimc.rst new file mode 100644 index 000000000..eb1beb549 --- /dev/null +++ b/doc/nimc.rst @@ -0,0 +1,474 @@ +=================================== + Nim Compiler User Guide +=================================== + +:Author: Andreas Rumpf +:Version: |nimversion| + +.. contents:: + + "Look at you, hacker. A pathetic creature of meat and bone, panting and + sweating as you run through my corridors. How can you challenge a perfect, + immortal machine?" + + +Introduction +============ + +This document describes the usage of the *Nim compiler* +on the different supported platforms. It is not a definition of the Nim +programming language (therefore is the `manual <manual.html>`_). + +Nim is free software; it is licensed under the +`MIT License <http://www.opensource.org/licenses/mit-license.php>`_. + + +Compiler Usage +============== + +Command line switches +--------------------- +Basic command line switches are: + +Usage: + +.. include:: basicopt.txt + +---- + +Advanced command line switches are: + +.. include:: advopt.txt + + + +List of warnings +---------------- + +Each warning can be activated individually with ``--warning[NAME]:on|off`` or +in a ``push`` pragma. + +========================== ============================================ +Name Description +========================== ============================================ +CannotOpenFile Some file not essential for the compiler's + working could not be opened. +OctalEscape The code contains an unsupported octal + sequence. +Deprecated The code uses a deprecated symbol. +ConfigDeprecated The project makes use of a deprecated config + file. +SmallLshouldNotBeUsed The letter 'l' should not be used as an + identifier. +EachIdentIsTuple The code contains a confusing ``var`` + declaration. +ShadowIdent A local variable shadows another local + variable of an outer scope. +User Some user defined warning. +========================== ============================================ + + +Verbosity levels +---------------- + +===== ============================================ +Level Description +===== ============================================ +0 Minimal output level for the compiler. +1 Displays compilation of all the compiled files, including those imported + by other modules or through the `compile pragma<#compile-pragma>`_. + This is the default level. +2 Displays compilation statistics, enumerates the dynamic + libraries that will be loaded by the final binary and dumps to + standard output the result of applying `a filter to the source code + <filters.html>`_ if any filter was used during compilation. +3 In addition to the previous levels dumps a debug stack trace + for compiler developers. +===== ============================================ + + +Compile time symbols +-------------------- + +Through the ``-d:x`` or ``--define:x`` switch you can define compile time +symbols for conditional compilation. The defined switches can be checked in +source code with the `when statement <manual.html#when-statement>`_ and +`defined proc <system.html#defined>`_. The typical use of this switch is to +enable builds in release mode (``-d:release``) where certain safety checks are +omitted for better performance. Another common use is the ``-d:ssl`` switch to +activate `SSL sockets <sockets.html>`_. + +Additionally, you may pass a value along with the symbol: ``-d:x=y`` +which may be used in conjunction with the `compile time define +pragmas<manual.html#implementation-specific-pragmas-compile-time-define-pragmas>`_ +to override symbols during build time. + + +Configuration files +------------------- + +**Note:** The *project file name* is the name of the ``.nim`` file that is +passed as a command line argument to the compiler. + + +The ``nim`` executable processes configuration files in the following +directories (in this order; later files overwrite previous settings): + +1) ``$nim/config/nim.cfg``, ``/etc/nim.cfg`` (UNIX) or ``%NIMROD%/config/nim.cfg`` (Windows). This file can be skipped with the ``--skipCfg`` command line option. +2) ``/home/$user/.config/nim.cfg`` (UNIX) or ``%APPDATA%/nim.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option. +3) ``$parentDir/nim.cfg`` where ``$parentDir`` stands for any parent directory of the project file's path. These files can be skipped with the ``--skipParentCfg`` command line option. +4) ``$projectDir/nim.cfg`` where ``$projectDir`` stands for the project file's path. This file can be skipped with the ``--skipProjCfg`` command line option. +5) A project can also have a project specific configuration file named ``$project.nim.cfg`` that resides in the same directory as ``$project.nim``. This file can be skipped with the ``--skipProjCfg`` command line option. + + +Command line settings have priority over configuration file settings. + +The default build of a project is a `debug build`:idx:. To compile a +`release build`:idx: define the ``release`` symbol:: + + nim c -d:release myproject.nim + + +Search path handling +-------------------- + +Nim has the concept of a global search path (PATH) that is queried to +determine where to find imported modules or include files. If multiple files are +found an ambiguity error is produced. + +``nim dump`` shows the contents of the PATH. + +However before the PATH is used the current directory is checked for the +file's existence. So if PATH contains ``$lib`` and ``$lib/bar`` and the +directory structure looks like this:: + + $lib/x.nim + $lib/bar/x.nim + foo/x.nim + foo/main.nim + other.nim + +And ``main`` imports ``x``, ``foo/x`` is imported. If ``other`` imports ``x`` +then both ``$lib/x.nim`` and ``$lib/bar/x.nim`` match and so the compiler +should reject it. Currently however this check is not implemented and instead +the first matching file is used. + + +Generated C code directory +-------------------------- +The generated files that Nim produces all go into a subdirectory called +``nimcache`` in your project directory. This makes it easy to delete all +generated files. Files generated in this directory follow a naming logic which +you can read about in the `Nim Backend Integration document +<backends.html#nimcache-naming-logic>`_. + +However, the generated C code is not platform independent. C code generated for +Linux does not compile on Windows, for instance. The comment on top of the +C file lists the OS, CPU and CC the file has been compiled for. + + +Compilation cache +================= + +**Warning**: The compilation cache is still highly experimental! + +The ``nimcache`` directory may also contain so called `rod`:idx: +or `symbol files`:idx:. These files are pre-compiled modules that are used by +the compiler to perform `incremental compilation`:idx:. This means that only +modules that have changed since the last compilation (or the modules depending +on them etc.) are re-compiled. However, per default no symbol files are +generated; use the ``--symbolFiles:on`` command line switch to activate them. + +Unfortunately due to technical reasons the ``--symbolFiles:on`` needs +to *aggregate* some generated C code. This means that the resulting executable +might contain some cruft even when dead code elimination is turned on. So +the final release build should be done with ``--symbolFiles:off``. + +Due to the aggregation of C code it is also recommended that each project +resides in its own directory so that the generated ``nimcache`` directory +is not shared between different projects. + + +Cross compilation +================= + +To cross compile, use for example:: + + nim c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim + +Then move the C code and the compile script ``compile_myproject.sh`` to your +Linux i386 machine and run the script. + +Another way is to make Nim invoke a cross compiler toolchain:: + + nim c --cpu:arm --os:linux myproject.nim + +For cross compilation, the compiler invokes a C compiler named +like ``$cpu.$os.$cc`` (for example arm.linux.gcc) and the configuration +system is used to provide meaningful defaults. For example for ``ARM`` your +configuration file should contain something like:: + + arm.linux.gcc.path = "/usr/bin" + arm.linux.gcc.exe = "arm-linux-gcc" + arm.linux.gcc.linkerexe = "arm-linux-gcc" + + +DLL generation +============== + +Nim supports the generation of DLLs. However, there must be only one +instance of the GC per process/address space. This instance is contained in +``nimrtl.dll``. This means that every generated Nim DLL depends +on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command:: + + nim c -d:release lib/nimrtl.nim + +To link against ``nimrtl.dll`` use the command:: + + nim c -d:useNimRtl myprog.nim + +**Note**: Currently the creation of ``nimrtl.dll`` with thread support has +never been tested and is unlikely to work! + + +Additional compilation switches +=============================== + +The standard library supports a growing number of ``useX`` conditional defines +affecting how some features are implemented. This section tries to give a +complete list. + +================== ========================================================= +Define Effect +================== ========================================================= +``release`` Turns off runtime checks and turns on the optimizer. +``useWinAnsi`` Modules like ``os`` and ``osproc`` use the Ansi versions + of the Windows API. The default build uses the Unicode + version. +``useFork`` Makes ``osproc`` use ``fork`` instead of ``posix_spawn``. +``useNimRtl`` Compile and link against ``nimrtl.dll``. +``useMalloc`` Makes Nim use C's `malloc`:idx: instead of Nim's + own memory manager, ableit prefixing each allocation with + its size to support clearing memory on reallocation. + This only works with ``gc:none``. +``useRealtimeGC`` Enables support of Nim's GC for *soft* realtime + systems. See the documentation of the `gc <gc.html>`_ + for further information. +``nodejs`` The JS target is actually ``node.js``. +``ssl`` Enables OpenSSL support for the sockets module. +``memProfiler`` Enables memory profiling for the native GC. +``uClibc`` Use uClibc instead of libc. (Relevant for Unix-like OSes) +================== ========================================================= + + + +Additional Features +=================== + +This section describes Nim's additional features that are not listed in the +Nim manual. Some of the features here only make sense for the C code +generator and are subject to change. + + +LineDir option +-------------- +The ``lineDir`` option can be turned on or off. If turned on the +generated C code contains ``#line`` directives. This may be helpful for +debugging with GDB. + + +StackTrace option +----------------- +If the ``stackTrace`` option is turned on, the generated C contains code to +ensure that proper stack traces are given if the program crashes or an +uncaught exception is raised. + + +LineTrace option +---------------- +The ``lineTrace`` option implies the ``stackTrace`` option. If turned on, +the generated C contains code to ensure that proper stack traces with line +number information are given if the program crashes or an uncaught exception +is raised. + +Debugger option +--------------- +The ``debugger`` option enables or disables the *Embedded Nim Debugger*. +See the documentation of endb_ for further information. + + +Breakpoint pragma +----------------- +The *breakpoint* pragma was specially added for the sake of debugging with +ENDB. See the documentation of `endb <endb.html>`_ for further information. + + +DynlibOverride +============== + +By default Nim's ``dynlib`` pragma causes the compiler to generate +``GetProcAddress`` (or their Unix counterparts) +calls to bind to a DLL. With the ``dynlibOverride`` command line switch this +can be prevented and then via ``--passL`` the static library can be linked +against. For instance, to link statically against Lua this command might work +on Linux:: + + nim c --dynlibOverride:lua --passL:liblua.lib program.nim + + +Backend language options +======================== + +The typical compiler usage involves using the ``compile`` or ``c`` 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. More details +can be read in the `Nim Backend Integration document <backends.html>`_. + + +Nim documentation tools +======================= + +Nim provides the `doc`:idx: and `doc2`:idx: commands to generate HTML +documentation from ``.nim`` source files. Only exported symbols will appear in +the output. For more details `see the docgen documentation <docgen.html>`_. + +Nim idetools integration +======================== + +Nim provides language integration with external IDEs through the +idetools command. See the documentation of `idetools <idetools.html>`_ +for further information. + +.. + Nim interactive mode + ==================== + + The Nim compiler supports an interactive mode. This is also known as + a `REPL`:idx: (*read eval print loop*). If Nim has been built with the + ``-d:useGnuReadline`` switch, it uses the GNU readline library for terminal + input management. To start Nim in interactive mode use the command + ``nim secret``. To quit use the ``quit()`` command. To determine whether an input + line is an incomplete statement to be continued these rules are used: + + 1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace). + 2. The line starts with a space (indentation). + 3. The line is within a triple quoted string literal. However, the detection + does not work if the line contains more than one ``"""``. + + +Nim for embedded systems +======================== + +The standard library can be avoided to a point where C code generation +for 16bit micro controllers is feasible. Use the `standalone`:idx: target +(``--os:standalone``) for a bare bones standard library that lacks any +OS features. + +To make the compiler output code for a 16bit target use the ``--cpu:avr`` +target. + +For example, to generate code for an `AVR`:idx: processor use this command:: + + nim c --cpu:avr --os:standalone --deadCodeElim:on --genScript x.nim + +For the ``standalone`` target one needs to provide +a file ``panicoverride.nim``. +See ``tests/manyloc/standalone/panicoverride.nim`` for an example +implementation. Additionally, users should specify the +amount of heap space to use with the ``-d:StandaloneHeapSize=<size>`` +command line switch. Note that the total heap size will be +``<size> * sizeof(float64)``. + + +Nim for realtime systems +======================== + +See the documentation of Nim's soft realtime `GC <gc.html>`_ for further +information. + + +Debugging with Nim +================== + +Nim comes with its own *Embedded Nim Debugger*. See +the documentation of endb_ for further information. + + +Optimizing for Nim +================== + +Nim has no separate optimizer, but the C code that is produced is very +efficient. Most C compilers have excellent optimizers, so usually it is +not needed to optimize one's code. Nim has been designed to encourage +efficient code: The most readable code in Nim is often the most efficient +too. + +However, sometimes one has to optimize. Do it in the following order: + +1. switch off the embedded debugger (it is **slow**!) +2. turn on the optimizer and turn off runtime checks +3. profile your code to find where the bottlenecks are +4. try to find a better algorithm +5. do low-level optimizations + +This section can only help you with the last item. + + +Optimizing string handling +-------------------------- + +String assignments are sometimes expensive in Nim: They are required to +copy the whole string. However, the compiler is often smart enough to not copy +strings. Due to the argument passing semantics, strings are never copied when +passed to subroutines. The compiler does not copy strings that are a result from +a procedure call, because the callee returns a new string anyway. +Thus it is efficient to do: + +.. code-block:: Nim + var s = procA() # assignment will not copy the string; procA allocates a new + # string already + +However it is not efficient to do: + +.. code-block:: Nim + var s = varA # assignment has to copy the whole string into a new buffer! + +For ``let`` symbols a copy is not always necessary: + +.. code-block:: Nim + let s = varA # may only copy a pointer if it safe to do so + + +If you know what you're doing, you can also mark single string (or sequence) +objects as `shallow`:idx:\: + +.. code-block:: Nim + var s = "abc" + shallow(s) # mark 's' as shallow string + var x = s # now might not copy the string! + +Usage of ``shallow`` is always safe once you know the string won't be modified +anymore, similar to Ruby's `freeze`:idx:. + + +The compiler optimizes string case statements: A hashing scheme is used for them +if several different string constants are used. So code like this is reasonably +efficient: + +.. code-block:: Nim + case normalize(k.key) + of "name": c.name = v + of "displayname": c.displayName = v + of "version": c.version = v + of "os": c.oses = split(v, {';'}) + of "cpu": c.cpus = split(v, {';'}) + of "authors": c.authors = split(v, {';'}) + of "description": c.description = v + of "app": + case normalize(v) + of "console": c.app = appConsole + of "gui": c.app = appGUI + else: quit(errorStr(p, "expected: console or gui")) + of "license": c.license = UnixToNativePath(k.value) + else: quit(errorStr(p, "unknown variable: " & k.key)) |