Getting Started with Rtinycc

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()
#> [1] "/tmp/RtmpnGtaiV/Rinstb110b545d486a/Rtinycc/tinycc/bin/tcc"
tcc_include_paths()
#> [1] "/tmp/RtmpnGtaiV/Rinstb110b545d486a/Rtinycc/tinycc/include"        
#> [2] "/tmp/RtmpnGtaiV/Rinstb110b545d486a/Rtinycc/tinycc/lib/tcc/include"
tcc_lib_paths()
#> [1] "/tmp/RtmpnGtaiV/Rinstb110b545d486a/Rtinycc/tinycc/lib/tcc"
#> [2] "/tmp/RtmpnGtaiV/Rinstb110b545d486a/Rtinycc/tinycc/lib"

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)
#> [1] 10

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()
#> [1] 1
ffi_globals$bump_counter()
#> NULL
ffi_globals$global_shared_counter_get()
#> [1] 2

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