Author: Michal Burda
Date: 2026-01-08

# Build Rules

#### Michal Burda

#### 2026-01-08

## Introduction

This vignette describes the various types of build rules available in `rmake` for defining how targets are built from their dependencies.

For information on project management (initialization, running builds, cleaning), see the rmake Project Management vignette. For advanced features like tasks and templates, see the Tasks and Templates vignette.

## Common Rule Parameters

All rule functions have the following common parameters:

- `target` - Character vector of files to create
- `depends` - Character vector of prerequisite files (optional)
- `task` - Task name(s) for grouping (default: “all”)
- `params` - Parameters to pass to scripts (optional for some rules)

Each rule executes in a separate R process (no shared state).

Note: The `task` parameter is covered in detail in the Tasks and Templates vignette, and the `params` parameter is explained in the parameterized execution section of that vignette.

## Pre-defined Rule Types

### rRule()

Executes an R script using `Rscript`. The rule is triggered when any dependency or the script itself changes.

    rRule(target, script, depends = NULL, params = list(), task = "all")

Parameters:

- `target` - Name of the output file to be created
- `script` - Name of the R script to execute
- `depends` - Vector of file names that the script depends on, or `NULL`
- `params` - List of R values that become available within the script in a `params` variable
- `task` - Character vector of parent task names

Example:

    rRule(target = "output.rds",
          script = "process.R",
          depends = "input.csv")

### markdownRule()

Renders a document from R Markdown using `rmarkdown::render()`.

    markdownRule(target, script, depends = NULL, format = "all",
                 params = list(), task = "all")

Parameters:

- `target` - Name of the output file to be created
- `script` - Name of the R Markdown file to render
- `depends` - Vector of file names that the markdown script depends on, or `NULL`
- `format` - Output format specification (see below)
- `params` - List of R values available within the script in a `params` variable
- `task` - Character vector of parent task names

Format Options:

- `"all"` - All formats defined in the Rmd file
- `"html_document"` - HTML web page
- `"pdf_document"` - PDF document
- `"word_document"` - Microsoft Word
- `"odt_document"` - OpenDocument Text
- `"rtf_document"` - Rich Text Format
- `"md_document"` - Markdown
- Vector of format names for multiple formats

Example:

    markdownRule(target = "report.pdf",
                 script = "report.Rmd",
                 depends = "data.rds",
                 format = "pdf_document")

### knitrRule()

Executes knitr to create a text file using `knitr::knit()`. This is useful for processing Sweave-style documents (.Rnw files).

    knitrRule(target, script, depends = NULL, params = list(), task = "all")

Parameters:

- `target` - Name of the output file to be created
- `script` - Name of the Rnw file to be rendered
- `depends` - Vector of file names that the knitr script depends on, or `NULL`
- `params` - List of R values available within the script in a `params` variable
- `task` - Character vector of parent task names

Example:

    knitrRule(target = "report.tex",
              script = "report.Rnw",
              depends = c("data1.csv", "data2.csv"))

### copyRule()

Copies a file from one location to another. The rule executes `$(CP) depends[1] target`.

    copyRule(target, depends, task = "all")

Parameters:

- `target` - Target file name to copy the file to
- `depends` - Name of the file to copy from (only the first element is used)
- `task` - Character vector of parent task names

Example:

    copyRule(target = "backup/data.csv",
             depends = "data.csv")

### depRule()

Defines a dependency between targets without providing any execution script. This is useful when you want to specify that a target depends on another target but don’t need to execute any command to build it.

    depRule(target, depends = NULL, task = "all")

Parameters:

- `target` - Target file name that depends on `depends`
- `depends` - Character vector of prerequisite file names
- `task` - Character vector of parent task names

Example:

    # Ensure all preprocessing is done before starting the analysis
    depRule(target = "analysis-ready",
            depends = c("data1.rds", "data2.rds", "data3.rds"))

### subdirRule()

Runs the make process in a subdirectory. The subdirectory is assumed to contain its own `Makefile`. This rule executes `make <targetTask>` in the specified subdirectory.

    subdirRule(target, depends = NULL, task = "all", targetTask = "all")

Parameters:

- `target` - Name of the subdirectory
- `depends` - Must be `NULL`
- `task` - Character vector of parent task names
- `targetTask` - What task to execute in the subdirectory (default: “all”)

Example:

    subdirRule(target = "subproject",
               targetTask = "all")

### offlineRule()

Forces manual action within the build process. Shows a custom error message instructing the user to perform a task manually. This is useful when transformation requires manual intervention.

    offlineRule(target, message, depends = NULL, task = "all")

Parameters:

- `target` - Name of the file to be created manually
- `message` - Custom message to display to the user
- `depends` - Vector of prerequisite file names, or `NULL`
- `task` - Character vector of parent task names

Example:

    offlineRule(target = "cleaned_data.csv",
                message = "Please manually clean data.csv and save as cleaned_data.csv",
                depends = "data.csv")

## Custom Rules

Create custom rules using the general `rule()` function:

    rule(target, depends = NULL, build = NULL, clean = NULL,
         task = "all", phony = FALSE)

Arguments:

- `target` - Target file names
- `depends` - Prerequisite file names
- `build` - Shell commands to build targets
- `clean` - Shell commands to clean targets
- `task` - Task assignment
- `phony` - Whether target is a non-file target (TRUE/FALSE)

Predefined Make Variables:

- `$(R)` - Path to Rscript binary
- `$(RM)` - File deletion command
- `$(CP)` - File copy command

Example with NodeJS:

    r <- rule(target = "test.json",
              depends = "test.js",
              build = "node test.js",
              clean = "$(RM) test.json")

Define custom Make variables:

    defaultVars["JS"] <- "/usr/bin/node"

    job <- list(rule(target = "test.json",
                     depends = "test.js",
                     build = "$(JS) test.js",
                     clean = "$(RM) test.json"))

### Using inShell()

The `inShell()` function converts R expressions to shell commands:

    inShell({ result <- 1 + 1; saveRDS(result, "result.rds") })
    #> [1] "$(R) - <<'EOFrmake'"                 "{"
    #> [3] "    result <- 1 + 1"                 "    saveRDS(result, \"result.rds\")"
    #> [5] "}"                                   "EOFrmake"

Example rule using inShell():

    rule(target = "result.rds",
         build = inShell({ result <- 1 + 1; saveRDS(result, "result.rds") }),
         clean = "$(RM) result.rds")

Note: Overuse of `inShell()` is not recommended. Prefer separate script files so Make can detect changes.

## Summary

`rmake` provides a comprehensive set of rule types:

- rRule(): Execute R scripts
- markdownRule(): Render R Markdown documents
- knitrRule(): Process knitr/Sweave documents
- copyRule(): Copy files
- depRule(): Define dependencies without execution
- subdirRule(): Run make in subdirectories
- offlineRule(): Require manual intervention
- rule(): Create custom rules with shell commands

## See Also

For more information on related topics, see these vignettes:

- Getting Started with rmake: Introduction and basic usage
- rmake Project Management: Project initialization, running builds, and cleaning
- Tasks and Templates: Advanced features including tasks, parameterized execution, and rule templates