To make life easier, remake comes with little set of modules for common tasks. The list is by no means final (future versions will probably have more modules) and you can write your own. It is expected that some compilers may come with their own modules and add them to the remake’s ones.

The signatures of functions are marked by $ and @ signs — each represents one parameter. If it is @, the parameter takes multiple values. If it is $, the function is run as many times as the parameter has values, each time with a different value of the parameter. The results of all runs are put together. If there are more $ parameters, it does Cartesian product of them (eg. all combinations of the values).

The core module

This one contains some common functions, few of them are builtins (not implementable in the remake language), others some extensions around them.

echo($)

This function takes one string argument and prints it to standard output. Can be used to inform user about what is happening, doing pretty-prints during compilation and the like. Always returns empty variable.

if(@@@)

If the first parameter has at last one value, the second parameter is returned. Otherwise, the third is returned. It acts in a manner similar to C operator ?.

defined(@)

This function is a test if a variable is defined. If an undefined value is passed as it’s first parameter, it returns empty variable. Otherwise, single-value variable containing string defined is returned.

eq(@@)

Tests if both parameters are equal. It either returns variable with single string value true, or variable with zero values.

not(@), and(@@), or(@@)

Logic operations on parameters. Return value is encoded the same way as above.

default(@@)

Provides a default value for undefined variables — if the first parameter is defined, it is returned unchanged. If it is undefined, the second one is returned instead.

concat(@)

Takes a list of strings or objects as its first parameter and returns single-value string variable containing concatenation of the list.

flag_concat($@)

This one helps string of flags from list of flag values. It takes the list from second parameter, adds the first parameter to each of the values and concatenates all of these into one string, separated by spaces. For example, flag_concat("-I", "dir1" "dir2") will output "-Idir1 -Idir2 ".

loc($)

Will prepend to given string the directory of the remake script the call is located in. Can be used to list local files in the subdirectories without bothering with the full paths (and errors when you move the directory).

env($)

You pass it a name of an environment variable and its value gets returned. If the variable does not exist in current environment, variable with zero values is returned.

remove($)

Removes the file which name was provided as parameter. Nice output is printed while doing it.

eat_first($$)

Takes first parameter, drops shortest prefix that contains a character of the second parameter and returns the rest. So eat_first("This long text", " o") returns "long text". Some more general cutting function will probably appear in near future.

eat_last($$)

The same, but eats from the other end.

reverse($)

Reverses a string or object name.

split_escaped($@@)

Splits the first parameter (string or object) into smaller strings. The second parameter is list of substrings that are not separators, the third list of separators. The string is scanned from the beginning, if a non-delimiter is found, it continues after that (so if delimiter is substring of non-delimiter, it is not taken). For example, split_escaped("a b\ c", "\ ", " ") is split into "a" "b\ c". Multiple consecutive occurrences of a delimiter is taken as one (no empty strings are returned).

load_makedeps($)

Many tools return dependencies for what they do in a format suitable to be included into a makefile. This one takes single such rule as a string and returns list of such dependencies.

vartype($)

Returns string describing what kind of value it is, it is one of values:

  • string

  • object

  • function

  • class

  • method

is_*($)

These function test, if variable value is of a given type. Besides the types described above, there are printable and callable, the first one is string or object, the second anything that can be called as function.

ext($$)

If the first argument is string, it appends the second argument to it. Otherwise, it is returned unchanged. This is intended to append default extensions to file names, but if they are already objects, they have full name.

chext($$)

The same, but it removes the old extensions first.

The color module

It contains few string variables with escape sequences to change colors of output. The are:

Abstract classes

There are classes which are of no use alone, you need to inherit them. But they save some typing when you create new classes.

base(@@$)

First parameter is list of direct sources (in C, it would be the .c file, not the .h). The second is list of results (usually only one, but some tools create more than one file). The third parameter is the method that should be used as the DEFAULT method. The class adds the sources to list of dependencies and it provides method clean which removes all results. The class resides in module called base. Furthermore, it sets variables SRC and TARGET, which you may use.

If you had a command command that created file with .y extension from one with .x extensions, you could write this:

import base

class command(name) :~ base("$name.x", "$name.y", compile) {
  fun compile() {
    !"command @SRC -o @TARGET"
  }
}
compile($$$)

This class is for more specific situation. It expects you have a compiler that takes single input file and outputs an object file. Furthermore, it outputs list of dependencies of the object file to provided file. Seems complicated? For example gcc -c -MMD -MF" does this.

The first parameter is name of the file, without any suffix. The second parameter is the suffix. The third is command to be executed. The case with gcc (without any other flags) would be:

import compiler

class gcc($name) :~ compile(name, 'c', 'gcc -c -MMD -MF') { }

Now the class will even track dynamic dependencies (like headers).

The class lives in the compiler module.

Language compilers

The C language

For compilation of C language, use the C module. It contains 3 classes.

ccompile($)

This one takes source file (the first parameter is the source without the extension) and produces the object file. It is influenced by several variables:

C_INCLUDES

List of directories to search for includes in (usually passed to compilers with the -I flag).

C_DEFINES

List of definitions for C preprocessor (usually passed to compilers with the -D flag).

CFLAGS

Any additional flags for the compiler.

clink(@$)

Takes list of object files (the first parameter) and links them into an executable (with name provided by the second parameter). It is influenced by these variables:

C_LIBDIRS

List of directories to search for libraries.

C_LIBS

List to libraries to link against.

C_LD_FLAGS

Additional flags for the compiler.

cprogram(@$)

It is combination of the above two. The first parameter is list of C source files, the second name of output executable. It is influenced by all the variables described above.

You may expect classes for creating libraries in near future.

The C++ language

It is in the Cpp module. It has the same functions and variables as C, only they start with cpp instead of c (resp. CPP instead of C in case of variables).

The Haskell language

Basic support for compiling Haskell is inside the haskell module. This module needs many improvements, as there are files which are not considered, the dependency tracking is not really correct and it is purely configurable.

hcompile($)

Compiles a .hs (passed without extension) file into an object file. It isn’t influenced by any configuration variables.

hlink(@$)

Links object files (passed as the first parameter) into an executable (name provided as the second parameter). You can pass additional linker parameter trough the H_LD_FLAGS variable.

Documentation

There is the asciidoc module with a class of the same name. It supports the asciidoc documentation system. It takes single parameter, which is the name of input (without the .txt).

Its behaviour can be modified by these variables:

ADOC_BACKEND

The backend to use. Corresponds to the -b flag.

ADOC_EXT

If you use some backend unknown to remake (any other than docbook, html4, xhtml11), you need to set the result file extension manually, by this variable.

ADOC_DOCTYPE

The document type to build. Corresponds to the -d flag.

ADOC_ATTRIBUTES

List of attributes, corresponds to the -a flag.

ADOC_CONFFILES

List of config files to load, corresponds to the -f flag. This way is preferred over setting in ADOC_FLAGS, since it adds the config files into dependencies.

ADOC_FLAGS

Any additional flags to the command.

Code tags

The ctags module contains tools for creating tags for your code. It contains two classes, both take list of all files to scan (this time with extensions, since you pass both headers and source files to it, so they can not be guessed automatically).

tags(@)

Uses the exuberant-ctags command and produces tags file in top-level project directory.

cscope(@)

Uses the cscope command to generate cscope.out in top-level project directory.

This module is not configurable yet.

Module run

This module is for running scripts without need of writing classes for each of them. It contains the run_local($$$$) class. The first parameter is name of local script (or executable, it can be even result of other compilation). Second contains parameters for the script. Third and fourth are input and output files for the script. They are put to standard input, resp. taken from standard output of the script.

Module install

If you want your build-system to be able to install the result, you may want to use this. The module contains single class, installer($$). The first argument is the file (or object) to install. The second says where (eg. you would put executables into bin). You do not need to put slashes in the beginning or end of this string.

The module modifies its behaviour by these variables:

PREFIX

It does exactly what you would expect — installs under this directory. If no prefix is specified, installs directly under /.

INSTALL_NAME

By default, it installs and uses the original file name. Setting this makes installer rename it to provided name.

INSTALL_OWNER

Set owner of the file (and directories created for it) to this owner. If not set, leaves untouched.

INSTALL_GROUP

The same, but with group.

INSTALL_CHOWN

Changes the permissions of the resulting file. Can be directly mode (like 0644), or chmod-encoded modification (like a+rX,u+w).

INSTALL_DIR_MODE

Permission mode of directories created for the file. Must be mode (like 0755).

DESTDIR

Many packaging tools compile software for some prefix, but install them to separate directory and when all goes well, they copy them into live system (or pack). DESTDIR is for this purpose — set it to the separate directory.

If you wanted to install a program, you would write something like:

import C
import install

TARGETS += installer(cprogram('hello' 'world', 'hello), 'bin')
PREFIX := default(inherited PREFIX, '/usr')
INSTALL_CHMOD := '0755'
INSTALL_DIR_MODE := '0755'

This will add two new methods — install and uninstall. However, uninstall does not remove the directories automatically created for the files.