TileDB-R icon indicating copy to clipboard operation
TileDB-R copied to clipboard

Providing access to the TileDB-R shared libraries in downstream packages

Open LTLA opened this issue 1 year ago • 6 comments

I have an R package (beachmat.tiledb) that vendors a C++ library that links to the TileDB C++ library. I would like my package to be installable even if TileDB is not installed in the system, so I was going to download the TileDB release binaries myself. However, I noticed that tiledb-R's installation directory already contains a copy of the binaries in its tiledb/ directory. I would like to be able to use these binaries to avoid having to duplicate tiledb-R's configure.ac in my own package. (This also avoids the creation of redundant copies of the TileDB binaries scattered throughout the user's R installation directory.)

Would you consider adding a little function that sets up the Makevars flags for downstream packages to link to these binaries? Based on the configure.ac, it would look something like this (for Linux/MacOS):

pkgconfig <- function(opt = c("PKG_CXX_FLAGS", "PKG_CXX_LIBS")) {
    opt <- match.arg(opt)
    pkgdir <- system.file(package='tiledb')
    vendored <- system.file('tiledb', package='tiledb')

    if (vendored != "") {
        if (opt == "PKG_CXX_FLAGS") {
            return(sprintf("-I%s/include -I%s/include", pkgdir, vendored))
        } else if (opt == "PKG_CXX_LIBS") {
            return(sprintf("-ltiledb -L%s/lib -L%s/lib", pkgdir, vendored))
        }
    }

    pc <- Sys.which("pkg-config")
    if (pc != "") {
        if (system2("pkg-config", c("--exists", "tiledb")) == 0) {
            if (opt == "PKG_CXX_FLAGS"){
                return(system2("pkg-config", c("--cflags", "tiledb"), stdout=TRUE))
            } else if (opt == "PKG_CXX_LIBS") {
                return(system2("pkg-config", c("--libs", "tiledb"), stdout=TRUE))
            }
        }
    }

    if (opt == "PKG_CXX_FLAGS"){
        return("")
    } else if (opt == "PKG_CXX_LIBS") {
        return("-ltiledb")
    }
}

Downstream packages could then create a little Makevars as shown below, allowing their C++ code to compile against tiledb-R's copy of the binaries (or the system libraries, if available).

CXX_STD = CXX17
PKG_LIBS=$(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript" -e 'tiledb::pkgconfig("PKG_CXX_LIBS")') 
PKG_CPPFLAGS=$(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript" -e 'tiledb::pkgconfig("PKG_CXX_FLAGS")') 

This could be (easily?) extended to Windows, if the newly built static library was deposited somewhere in inst/ so that pkgconfig() could reference it later in their Makevars.win.

FWIW this proposal is based on the strategy used by the Rhdf5lib and Rhtslib packages.

LTLA avatar Nov 08 '24 00:11 LTLA