While you should read the rest of the user documentation, you might want to start with a simple tutorial.

Simple C program with dependencies

Let’s assume you have a directory with a hello world source code. The source code is divided into several files:

Remake has module for compiling C source codes, so we will just import it and tell it to handle the rest. So save this into file called REM:

import C                # This will import the module

TARGETS += cprogram('hello' 'world', 'hello')
                        # And this asks to compile program called 'hello'

If you run remake now, it will compile it and program hello will appear.

There are few thinks to highlight. The TARGETS variable contains all the things you want to produce by compilation. If we had more programs to compile, there would be more of them listed here.

The cprogram comes from the C module and handles compilation of the whole program. It’s first argument is list of source files. The second is the name of the result. All the remake modules are written in a way you do not specify the file extensions. It’s because there are places, where the extensions are dependant on platform (on UNIX, you will get program called hello, but if someone took care and ported remake to Windows, it would produce hello.exe).

Finally, the cprogram handles all dependencies — it will compile all the object files from the source files and will recompile them, if some of them (or needed header files) changes. You do not need to provide list of header files, since they are found automatically.

Multiple directories

As the size of program grows with time, it is advisable to split it into multiple directories. So when our hello world program becomes larger, we split it into directories world and hello, each having few files.

Surely, we could list all the files in the cprogram parameter with relative paths and be done. But it would be better if files would be listed in local REM files.

We first create the REM in top-level directory:

import C

descend ('hello/', 'world/')

TARGETS += cprogram(sources, 'hello')

global sources

Now we use variable to store the list of source files. It will be filled inside the child REM scripts.

The global sources directive says that sources variable in all child files should be this one. Otherwise assignment to a variable makes it only local and it would not propagate outside of them.

The descend directive says we would like remake to examine REM file in the given directory.

The child script would look like this:

import core

parent '../'

sources += loc('file1' 'file2')

The parent directive is not strictly required in child script. But if we run remake in the subdirectory, it will know this is not the top-level script and will look for it. If it was not present, it would consider the local REM file as top-level one and would try to find TARGETS variable here.

The loc function takes its arguments and prepends them with local directory path. If this REM file would be in the world directory, it would output world/file1 and world/file2. It lives in the core module, so we need to import that one.