Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Added --genRedist, rewrote nimrtl/nimhcr compilation docs #11742

Closed
wants to merge 12 commits into from
10 changes: 10 additions & 0 deletions compiler/cmdlinehelper.nim
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ proc processCmdLineAndProjectPath*(self: NimProg, conf: ConfigRef) =
else:
conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile getCurrentDir())

proc processGenRedist*(conf: ConfigRef) =
case conf.projectName
of "nimrtl": defineSymbol(conf.symbols, "createNimRtl")
of "nimhcr": defineSymbol(conf.symbols, "createNimHcr")
else: rawMessage(conf, errGenerated, "invalid input for genRedist")
conf.projectFull = canonicalizePath(
conf, AbsoluteFile (conf.libpath / (RelativeDir conf.projectFull)))

proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: ConfigRef): bool =
loadConfigs(DefaultConfig, cache, conf) # load all config files
if self.suggestMode:
Expand Down Expand Up @@ -86,6 +94,8 @@ proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: Confi
self.processCmdLine(passCmd2, "", conf)
if conf.command == "":
rawMessage(conf, errGenerated, "command missing")
if optGenRedist in conf.globalOptions:
processGenRedist(conf)

let graph = newModuleGraph(cache, conf)
graph.suggestMode = self.suggestMode
Expand Down
5 changes: 5 additions & 0 deletions compiler/commands.nim
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,11 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
else:
undefSymbol(conf.symbols, "hotcodereloading")
undefSymbol(conf.symbols, "useNimRtl")
of "genredist":
incl(conf.globalOptions, {optGenRedist, optGenDynLib})
excl(conf.globalOptions, optGenGuiApp)
defineSymbol(conf.symbols, "library")
defineSymbol(conf.symbols, "dll")
of "oldnewlines":
case arg.normalize
of "","on":
Expand Down
1 change: 1 addition & 0 deletions compiler/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ type # please make sure we have under 32 options
optDocInternal # generate documentation for non-exported symbols
optMixedMode # true if some module triggered C++ codegen
optListFullPaths # use full paths in toMsgFilename
optGenRedist # generate redists (e.g. nimrtl/hcr)
optNoNimblePath
optHotCodeReloading
optDynlibOverrideAll
Expand Down
2 changes: 2 additions & 0 deletions doc/advopt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,5 @@ Advanced options:
--profiler:on|off enable profiling; requires `import nimprof`, and
works better with `--stackTrace:on`
see also https://nim-lang.github.io/Nim/estp.html
--genRedist generate standard redistributables
(set [projectfile] to nimrtl|nimhcr)
13 changes: 6 additions & 7 deletions doc/hcr.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
Hot code reloading
===================================

The `hotCodeReloading`:idx: option enables special compilation mode where
changes in the code can be applied automatically to a running program.
The code reloading happens at the granularity of an individual module.
When a module is reloaded, any newly added global variables will be
initialized, but all other top-level code appearing in the module won't
be re-executed and the state of all existing global variables will be
preserved.
The `hotCodeReloading`:idx: option enables a special compilation mode where
changes in the code can be applied automatically to a running program. The code
reloading happens at the granularity of an individual module. When a module is
reloaded, any newly added global variables will be initialized, but all other
top-level code appearing in the module won't be re-executed and the state of all
existing global variables will be preserved.


Basic workflow
Expand Down
49 changes: 41 additions & 8 deletions doc/nimc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -326,20 +326,53 @@ They are:
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 supports the generation of dynamic libraries. However, there must be only
one instance of the GC per process/address space, meaning that if multiple Nim
DLLs are used by the same binary, the DLLs must link to the ``nimrtl`` dynamic
library.

**Note for UNIX**: If any Nim DLL (including ``libnimrtl.so`` and
``libnimhcr.so``) is to be directly included with your application in the same
folder as the app binary, the app's ``rpath`` variable should be set to
``$ORIGIN``. The reason for this is because the dynamic library linker for
UNIX-like systems *does not* search for dynamic libraries in the same folder
(unlike Windows), unless the ``rpath`` variable is set otherwise in the binary
to search for in the app directory.

For an app binary built in Nim, an easy way to set the ``rpath`` variable
correctly is by including the following line in your source code:

nim c -d:release lib/nimrtl.nim
.. code-block:: Nim
when defined(unix): {.passL: "-Wl,-rpath='$ORIGIN'"}

``nimrtl``
----------

The ``nimrtl`` library contains both Nim's memory manager as well as significant
section of the standard library (containing commonly used utilities). The
``nimrtl`` library can be generated with the command::

nim c --genRedist nimrtl.nim

To link against ``nimrtl.dll`` use the command::
To link against ``nimrtl`` 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!
**Note**: Currently the creation of ``nimrtl`` with thread support has never
been tested and is unlikely to work!

``nimhcr``
----------
awr1 marked this conversation as resolved.
Show resolved Hide resolved
`See here <hcr.html>`_ for further information on hot-code-reloading.

Nim's hot-code-reloading support requires the app binary to link to both
``nimrtl`` as well as another library, ``nimhcr``. Similarly to how ``nimrtl``
was built, you can generate this library via the following command::

nim c --genRedist nimhcr.nim

Application binaries intended to be code-reloadable should be compiled with the
``--hotcodereloading`` option.

Additional compilation switches
===============================
Expand Down
6 changes: 3 additions & 3 deletions tests/dll/test_nimhcr_integration.bat
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
set NIM=nim
set NIM_FLAGS=-d:debug
set NIM_FLAGS=-d:debug --genRedist

%NIM% c --outdir:"." %NIM_FLAGS% ../../lib/nimrtl.nim
%NIM% c --outdir:"." %NIM_FLAGS% ../../lib/nimhcr.nim
%NIM% c --outdir:"." %NIM_FLAGS% nimrtl.nim
%NIM% c --outdir:"." %NIM_FLAGS% nimhcr.nim

set HCR_FLAGS=--forceBuild --hotCodeReloading:on --nimcache:nimcache %NIM_FLAGS%

Expand Down
6 changes: 3 additions & 3 deletions tests/dll/test_nimhcr_integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ set -e

rm -rf nimcache

NIM_FLAGS=${*:- -d:debug}
NIM_FLAGS=${*:- -d:debug --genRedist}
NIM=nim

$NIM c --outdir:"." $NIM_FLAGS ../../lib/nimrtl.nim
$NIM c --outdir:"." $NIM_FLAGS ../../lib/nimhcr.nim
$NIM c --outdir:"." $NIM_FLAGS nimrtl.nim
$NIM c --outdir:"." $NIM_FLAGS nimhcr.nim

echo ===== Compiling HCR Integration Test =====
HCR_FLAGS="--forceBuild --hotCodeReloading:on --nimcache:nimcache $NIM_FLAGS"
Expand Down