sprite-make

sprite-make is used to convert Curry files into various other formats. One may select which stages of the Compilation Pipeline to run. The targets are ICurry (--icy), JSON (--json), C++ (--cxx) and the shared object of the C++ backend (--so); the options --jobs, --curry2icurry and --rewrite-flat are described in the manual below.

Sprite uses this program to compile the Curry library before installation. Users can rely on it to transform files for inspection, or to statically compile Curry programs.

To view the help content say:

sprite-make -h

For more detailed information say:

sprite-make --man

sprite-make Manual

usage: sprite-make [-h] [-c] [--curry2icurry TOOL] [--cxx] [--so] [-g GOAL]
                   [-i] [-j] [--jobs N] [-k] [-M] [-o OUTPUT] [-q]
                   [--rewrite-flat] [-S] [-t] [-z]
                   [names ...]

Make ICurry files.

positional arguments:
  names                Curry modules or source files to process

options:
  -h, --help           show this help message and exit
  -c, --compact        compact JSON output
  --curry2icurry TOOL  the route from Curry to ICurry: frontend (the Curry
                       front end and the built-in translation) or icurry (the
                       icurry program)
  --cxx                make C++ files
  --so                 make shared objects for the C++ backend (implies --cxx)
  -g, --goal GOAL      specifies the goal of a generated program
  -i, --icy            make ICY files
  -j, --json           make JSON files
  --jobs N             make up to N modules at once, each in a child process
                       (auto: one per processor); the imports of a module are
                       made first
  -k, --keep-going     keep working after an error
  -M, --man            show detailed usage
  -o, --output OUTPUT  specify the output file
  -q, --quiet          work quietly
  --rewrite-flat       run the step from Curry to ICurry again, current or
                       not: the front end, the rewrite of the FlatCurry file
                       by the binding optimization and the set0 lift, and the
                       translation (implies --icy; needs the source; --jobs 1)
  -S, --subdir         print the subdirectory to which output files are
                       written then exit
  -t, --tidy           remove intermediate files generated by this program
  -z, --zip            zip JSON output with zlib (adds .z extension)

Executes the toolchain to compile Curry code.

This program uses timestamps and prerequisites to lazily update targets. Each positional argument can be a Curry module name, a Curry source file, or an ICurry file (extension: .icy). Modules are located by searching the CURRYPATH environment variable; the imports of a program given as a source file are searched in the directory of the file first, as PAKCS searches, so a program and the modules beside it need no CURRYPATH. An ICurry file can only be converted to JSON; the JSON file is written beside it.

Two processes that compile one module into one product directory, such as a background compile of the C++ backend and this program, never write at once: the compile runs under a lock file beside the products (<Module>.lock), the second process waits for the first, and it compiles nothing when the first wrote a current object.

The target formats follow. Curry-formatted ICurry (extension: .icy) is generated with the -i,--icy option. These files can be read into Curry programs using the standard module ICurry.Files.readICurry.

JSON-formatted ICurry (extension: .json) is generated with the -j,--json option. This format is more suitable when a Curry interpreter is not available. Sprite only reads the JSON format. Note that an ICY file is the prerequisite of JSON, meaning that --json implies --icy.

C++ (extension: .cpp) is generated with the --cxx option, which implies --json and --icy. The shared object of the C++ backend (extension: .so) is generated with the --so option, which implies --cxx and needs the C++ compiler that Sprite was configured with. The installation procedure uses --so to compile the Curry library. The -g,--goal option names the goal of a generated program.

Following the conventions of other Curry systems, output files are by default written to <dir>/.curry/sprite-pakcs-3.4.1, where <dir> is the directory containing the source code. For example, a curry file /path/to/A.curry gives rise to /path/to/.curry/sprite-pakcs-3.4.1/A.icy and /path/to/.curry/sprite-pakcs-3.4.1/A.json. The -o,--output option can be used to specify the output file.

The -c,--compact option causes JSON output to be compacted by removing insignificant whitespace. Compacted JSON is less human-readable but smaller.

The -t,--tidy option removes intermediate files generated in the compilation process.

The -z,--zip option causes JSON output to be compressed, in which case a .z extension is appended to the JSON file. JSON that is both compacted and zipped is often smaller than JSON that is only zipped.

The --curry2icurry option names the route from Curry to ICurry. frontend runs the Curry front end and then the built-in translation from FlatCurry; icurry runs the icurry program. The default is the value of SPRITE_CURRY2ICURRY, else the choice made by configure, else whichever tool is installed.

The --rewrite-flat option runs the step from Curry to ICurry of every named module again, whether or not its files are current, without the ICurry cache: the front end (which leaves a current FlatCurry file as it is), the rewrite step, which rewrites the FlatCurry file in place when the binding optimization replaces an equality or the set0 lift lifts a call (curry.toolchain.flat2icurry.rewrite_file), and the translation. The option implies --icy, so it stands alone; the later steps of another target follow as usual from the new ICurry file. Use it on a module whose products were made before the FlatCurry file was rewritten, so that the file on disk and the products agree; the module must have its source. The option runs the modules in this process (--jobs 1).

The --jobs N option makes up to N modules at once. Each module is made by a child process that runs this program on that module alone; auto is one child per processor. The imports of a module are made before the module, so no two children write the files that this program makes for one module (the ICurry, JSON, C++ and shared-object files). A module whose files are current gets no child. The order does not cover the interface files of the Curry front end (.fint, .fcy): the front end writes those of an import on its own when they are missing, so two children whose modules import one module without them write them at once. Run the front-end step of such a tree (products copied without their interface files) with --jobs 1. Before the children start, this process builds the precompiled header of the C++ backend when it is missing, so the children find it. The option covers the modules named on the command line and the modules they import. The installation procedure passes the job count of make.

The product cache. The C++ backend keeps a copy of each shared object it compiles, with the generated C++ and the ABI stamp, in a cache directory outside the tree (SPRITE_PRODUCT_CACHE; by default under the cache directory of the user). An entry is found by content: the digest of the ABI stamp, the text of the module and of the modules it imports, and the facts that shape the generated code. A module whose entry is in the cache is neither generated nor compiled; its files are placed beside the source with a stamp for this installation. A module in the temporary directory of the system is not cached. At the end of a run that restored or stored a product this program prints one line with the two counts, sprite-make: product cache: N restored, M stored, unless -q was given; under --jobs the counts of the children are summed. See the page on environment variables.

Products made before the rewrite. The ICurry file of a module counts as stale when the FlatCurry file of the front end beside the source holds a Boolean equality the binding optimization replaces and neither file holds constrEq, or holds a set0 call the set0 lift lifts and the ICurry file lacks the lifted function: a pair translated before the routes rewrote the file with that pass, from an older tree or from the overlay archive of the tests (curry.toolchain._curry2icurry.translated_before_rewrite). The step from Curry to ICurry runs again for such a module, as for a changed source: the front end leaves the current file, the rewrite step rewrites it, and the translation follows. At the end of a run that made such a module again this program prints sprite-make: pre-rewrite pairs: N translated again, unless -q was given; under --jobs the counts of the children are summed. When the ICurry cache held the entry of the module (the test drivers keep one), the cache writes the ICurry file, and the rewrite step runs over the FlatCurry file as after a translation; the line then ends in , M from the ICurry cache. The modules of the Curry library are not judged; their ICurry is committed. A FlatCurry file larger than 256 KB, or one that cannot be written again, is not judged either, with a warning.

Environment Variables

CURRYPATH

a colon-separated list of paths to search for Curry modules. The directory of a program given as a source file is searched first.

SPRITE_PRODUCT_CACHE

the directory of the product cache; the empty string turns the cache off.

SPRITE_CURRY2ICURRY

names the route from Curry to ICurry: frontend or icurry.

SPRITE_LOG_LEVEL

adjusts logging output. Values are CRITICAL, ERROR, WARNING (default), INFO, and DEBUG.

SPRITE_FRONTEND_WARNINGS

set to 0 silences the warnings of the Curry front end (overlapping rules), which a run otherwise reports once per module through the log at the WARNING level. -q silences them too.

Examples

The following converts A.curry to the ICurry file A.icy. Module A is found by searching CURRYPATH. The output is placed at <dir>/.curry/sprite-pakcs-3.4.1/A.icy, where <dir> is the directory containing A.curry:

% sprite-make --icy A.curry

The following creates a compacted, zipped JSON file:

% sprite-make --json -czt /path/to/A.curry

The output is written to /path/to/.curry/sprite-pakcs-3.4.1/A.json.z. The intermediate file /path/to/.curry/sprite-pakcs-3.4.1/A.icy will be removed unless it was up-to-date prior to the command running.

Generating ICurry

To convert a Curry file to ICurry, supply --icy. To convert Peano.curry, for instance, say:

cd examples
sprite-make --icy Peano.curry

This places the output file in the subdirectory used for caching intermediates. To print this location say:

sprite-make --subdir

You can specify the output file with -o:

sprite-make --icy Peano.curry -o Peano.icy

Generating JSON

To generate JSON, supply --json:

sprite-make --json Peano.curry -o Peano.json

Since ICurry is a prerequisite of JSON in the compilation pipeline, building JSON implies building ICurry.

Additional options are provided to compact JSON (--compact), compress it with zlib (--zip), and remove intermediate files (--tidy).

Generating Shared Objects

The C++ backend compiles each module into a shared object. To build one ahead of time, supply --so. This implies --cxx, which writes the C++ source, and needs the C++ compiler that Sprite was configured with:

sprite-make --so Peano.curry

The object is written to .curry/sprite-pakcs-<ver>/Peano.so, beside its ABI stamp (Peano.so.abi): a digest of the runtime headers the generated code includes, the flags it was compiled with, the compiler of the build and the format of the generated code, and the real path of the installation. The object has the SONAME sprite-Peano.so.<format> and names the objects of the modules it imports by their SONAME, so it holds no path (readelf -d shows none). The compile also stores the object, the C++ source and the stamp in the product cache, from which a later compile of the same module under the same conditions places them instead of running the compiler (SPRITE_PRODUCT_CACHE; see Development Variables). The installation uses --so to compile the Curry library, so that the first import after make stage compiles nothing.