3

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?

1 Answer 1

7

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,
Sign up to request clarification or add additional context in comments.

1 Comment

So unfortunately I accepted this too soon as I had copied over the my_func_r.cpp with all the header and source code at the top, not the original. When I do as you say and move matrix.h and matrix.c into src/ when I try to install the package it complains undefined symbol: _Z17freeIntegerMatrixP13IntegerMatrix. The freeIntegerMatrix function is contained in matrix.c so it doesn't seem to be linking correctly. The tests still run fine (after a slight tweak) with the new directory architecture so I don't think this is the issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.