knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) tcc_compile <- Rtinycc::tcc_compile tcc_link <- Rtinycc::tcc_link is_windows <- .Platform$OS.type == "windows" find_system_math_library <- function() { if (is_windows) { return(NULL) } sysname <- as.character(unname(Sys.info()[["sysname"]])) paths <- unique(Rtinycc:::tcc_library_search_paths(sysname)) # On Linux prefer the unversioned `libm.so`, which on glibc systems is a # GNU ld script that pulls in libm.so.6 plus libmvec.so.1; TinyCC handles # those scripts. Fall back to the SONAME-versioned file only if the dev # symlink is absent (some minimal containers). patterns <- switch( sysname, Linux = c("^libm\\.so$", "^libm\\.so(\\.[0-9]+)+$"), Darwin = c("^libSystem\\.B\\.dylib$", "^libm\\.dylib$"), character(0) ) for (pattern in patterns) { for (path in paths) { if (!dir.exists(path)) { next } candidates <- list.files( path, pattern = pattern, full.names = TRUE ) if (length(candidates) > 0L) { return(candidates[[1]]) } } } NULL } math_lib_path <- find_system_math_library() math_link_ok <- !is.null(math_lib_path) && tryCatch( { Rtinycc::tcc_link( math_lib_path, symbols = list(sqrt = list(args = list("f64"), returns = "f64")) ) TRUE }, error = function(e) FALSE )
tcc_link() is the external-library counterpart to tcc_compile().
Instead of compiling only the C source you provide, it generates wrappers for
symbols that already exist in a shared library and links those wrappers with
TinyCC.
The important contract is:
Rtinycc generates the conversion layertcc_link() Is ForUse tcc_link() when the implementation already exists elsewhere and you want
an R-facing wrapper with the same calling style as tcc_compile().
Typical uses are:
On Unix-like systems, the math library is a simple example because common
functions such as sqrt() and cos() are usually resolved from the system
math runtime. For robustness, this vignette resolves an actual runtime library
file instead of relying on a short name. On Linux that is typically a versioned
libm.so.* file, while on macOS the resolver prefers libSystem.B.dylib.
math <- tcc_link( math_lib_path, symbols = list( sqrt = list(args = list("f64"), returns = "f64"), cos = list(args = list("f64"), returns = "f64") ) ) math$sqrt(25) math$cos(0)
On Windows, the same family of CRT functions is typically provided through the
UCRT. In Rtinycc, that runtime detail is handled by the bundled TinyCC setup
and configure.win; user-facing code should generally think in terms of “CRT
functions are available” rather than depending on a specific historical import
library name.
You can include a small amount of helper code in the same TinyCC unit while still linking against an external library:
math_helpers <- tcc_link( math_lib_path, symbols = list( sqrt = list(args = list("f64"), returns = "f64"), hypot2_checked = list(args = list("f64", "f64"), returns = "f64") ), user_code = " #include <math.h> double hypot2_checked(double x, double y) { if (x < 0 || y < 0) { return NAN; } return sqrt(x * x + y * y); } " ) math_helpers$hypot2_checked(3, 4) is.nan(math_helpers$hypot2_checked(-1, 4))
This is often enough for:
tcc_link() accepts either:
"m" or "sqlite3"When given a full path, Rtinycc adds the containing directory and asks TinyCC
to link that exact file name. This matters for versioned runtime libraries such
as libm.so.6, which are not interchangeable with a generic development
symlink such as libm.so on every Linux distribution. When given a short name,
TinyCC resolves it through its configured library search paths.
This means the R-side binding declaration stays the same even when deployment changes from “use the system copy” to “use this exact shared object”.
tcc_compile()Use tcc_compile() when your primary artifact is new C code shipped from R.
Use tcc_link() when the primary implementation already lives in a shared
library and you want Rtinycc to generate the wrapper layer around it.
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.