12.2 Embedding Modules via C🔗ℹ

raco ctool is provided by the "cext-lib" package.

The --c-mods mode for raco ctool takes a set of Racket modules and generates a C source file that can be used as part of program that embeds the Racket runtime system. See Embedding into a Program (BC) in Inside: Racket C API for an explanation of embedding programs. The --mods mode is similar, but it generates the raw bytes for the compiled module without encoding the bytes in C declarations.

The generated source or compiled file embeds the specified modules. Generated C source defines a declare_modules function that puts the module declarations into a namespace. Thus, using the output of raco ctool --c-mods, a program can embed Racket with a set of modules so that it does not need a "collects" directory to load modules at run time.

If the embedded modules refer to runtime files, the files can be gathered by supplying the --runtime argument to raco ctool --c-mods, specifying a directory dir to hold the files. Normally, dir is a relative path, and files are found at run time in dir relative to the executable, but a separate path (usually relative) for run time can be specified with --runtime-access.

Typically, raco ctool --c-mods is used with ++lib to specify a collection-based module path. For example,

  raco ctool --c-mods base.c ++lib racket/base

generates a "base.c" whose declare_modules function makes racket/base available for use via the scheme_namespace_require or scheme_dynamic_require functions within the embedding application.

When a module file is provided to raco ctool --c-mods, then declare_modules declares a module with the symbolic name of the module file. For example,

  raco ctool --c-mods base.c hello.rkt

creates a declare_modules that defines the module 'hello, which could be required into the current namespace with (namespace-require ''hello) or similarly at the C level:

  p = scheme_make_pair(scheme_intern_symbol("quote"),

                       scheme_make_pair(scheme_intern_symbol("hello"),

                                        scheme_make_null()));

  scheme_namespace_require(p);