Getting Started with Rtinycc

knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
tcc_bind <- Rtinycc::tcc_bind
tcc_compile <- Rtinycc::tcc_compile
tcc_ffi <- Rtinycc::tcc_ffi
tcc_global <- Rtinycc::tcc_global
tcc_include_paths <- Rtinycc::tcc_include_paths
tcc_lib_paths <- Rtinycc::tcc_lib_paths
tcc_link <- Rtinycc::tcc_link
tcc_path <- Rtinycc::tcc_path
tcc_source <- Rtinycc::tcc_source

Rtinycc bundles TinyCC and exposes two layers:

The package is designed around explicit data conversion. You declare the C signature you want, Rtinycc generates the wrapper code, and the compiled object exposes ordinary R-callable functions.

Toolchain Paths

The bundled TinyCC installation is discoverable from R:

tcc_path()
tcc_include_paths()
tcc_lib_paths()

These helpers are useful when you need to inspect the bundled toolchain or bridge Rtinycc with other build logic.

A Minimal FFI Example

The usual entry point is tcc_ffi(). You add C source, declare the function signatures you want to expose, and compile once:

ffi <- tcc_ffi() |>
  tcc_source(
    "
    static double affine(double x, double slope, double intercept) {
      return slope * x + intercept;
    }
    "
  ) |>
  tcc_bind(
    affine = list(
      args = list("f64", "f64", "f64"),
      returns = "f64"
    )
  ) |>
  tcc_compile()

ffi$affine(2, 3, 4)

The wrapper takes care of converting R numerics to double and converting the C return value back to an R scalar.

Managing Globals

You can also expose C globals through generated getter and setter helpers:

ffi_globals <- tcc_ffi() |>
  tcc_source(
    "
    int shared_counter = 1;

    void bump_counter(void) {
      shared_counter += 1;
    }
    "
  ) |>
  tcc_bind(
    bump_counter = list(args = list(), returns = "void")
  ) |>
  tcc_global("shared_counter", "i32") |>
  tcc_compile()

ffi_globals$global_shared_counter_get()
ffi_globals$bump_counter()
ffi_globals$global_shared_counter_get()

This pattern is useful for wrapping small stateful C helpers without dropping to the lower-level libtcc API.

When to Use tcc_link()

tcc_compile() is for source you provide directly. tcc_link() is for binding to functions that already exist in a shared library. The high-level binding format is the same, so you can move between generated code and linked code without changing the R-side calling convention. See the Linking External Libraries vignette for the external-linking workflow and the platform-specific runtime notes.



Try the Rtinycc package in your browser

Any scripts or data that you put into this service are public.

Rtinycc documentation built on April 28, 2026, 1:07 a.m.