rwolst
rwolst

Reputation: 13672

Compiling multiple source files in Rcpp

I have the following directory structure

my_func
    - my_func_r.cpp
    - my_func.c
    - my_func.h
    - my_func_test.c
    - matrix/
      - matrix.h
      - matrix.c

The matrix directory contains some matrix structures in matrix.h and some initialisation, free, print etc. functions in matrix.c. The my_func.h file is something like

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "matrix/matrix.h"

... some structures and templates ...

The my_func.c file is then

#include "my_func.h"

... helper functions ...

int my_func(...) {
    ... my_func stuff ...     
    return 0;
}

The my_func_test.c is something like

#include "my_func.h"

int main() {
    ... some test ...
    return 0;
}

With gcc/g++ I can run this fine with

gcc my_func_test.c my_func.c matrix/matrix.c -o test -lm

The final file my_func_r.cpp is an interface between the Rcpp structures and the structures used in my_func.c. It is currently something like

#include "my_func.h"
#include <Rcpp.h>

// [[Rcpp::export]]
int my_func_r(Rcpp::List x, ...) {
    ... convert inputs to structure recognised by my_func.h ...       
    ... run my_func.c ...
    ... put returned objects back into one of the R structure ...

    return 0;
}

The problem I have is if I now run

sourceCpp('my_func_r.cpp', verbose=TRUE, rebuild=TRUE)

It complains about missing symbols for functions located in matrix/matrix.c. A workaround is to simply paste all my header and source code from both the my_func and matrix files at the top of my_func_r.cpp.

This however feels a very unsatisfactory solution especially for code maintenance. What is the easiest way to accomplish what I am trying to do?

Upvotes: 3

Views: 1426

Answers (1)

Dirk is no longer here
Dirk is no longer here

Reputation: 368231

Quick ones:

  1. This is not really particular to Rcpp per se
  2. You are simply struggling with a more advanced / complicated src/ directory in an R build.
  3. There is official documentation about this in Writing R Extensions, and the questions has come up here on SO before.
  4. You could compile a libmatrix.a first in the subdirectory and link to that. This is doable via a simple src/Makevars but still discouraged. So read on.
  5. But this is a self-inflicted wound. Just copy matrix.h and matrix.c into src/, adjust the include path, and you are done.
  6. As always: Create a package. Don't use sourceCpp() on larger setup. It is not made for that,

Upvotes: 7

Related Questions