编译包Rcpp,RcppProgress时,"2个用于体系结构的重复符号"

ric*_*rey 2 c++ r ld rcpp

我怀疑这个问题源于对c ++的误解,但是因为我使用Rcpp,所以我已经标记了这个问题.我创建了两个函数,每个函数都在一个单独的.cpp文件中.

f1.cpp:

// [[Rcpp::depends(RcppProgress)]]
#include <progress.hpp>

using namespace Rcpp;

// [[Rcpp::export]]
NumericVector f1(int n)
{
    int i;
    Progress p(n, true);
    NumericVector x(n);

    for( i = 0 ; i < n ; i++ )
    {
      if (Progress::check_abort() )
        Rcpp::stop("Operation cancelled by interrupt.");

      p.increment(); // update progress

      x[i] = Rf_rnorm(0,1);
    }
    return x;
}
Run Code Online (Sandbox Code Playgroud)

f2.cpp:

// [[Rcpp::depends(RcppProgress)]]
#include <progress.hpp>

using namespace Rcpp;

// [[Rcpp::export]]
NumericVector f2(int n)
{
    int i;
    Progress p(n, true);
    NumericVector x(n);

    for( i = 0 ; i < n ; i++ )
    {
      if (Progress::check_abort() )
        Rcpp::stop("Operation cancelled by interrupt.");

      p.increment(); // update progress

      x[i] = Rf_rgamma(1,1);
    }
    return x;
}
Run Code Online (Sandbox Code Playgroud)

他们都依赖于RcppProgress.当我只使用其中一个文件编译我的包时,我没有问题.但是当我用两者编译时,我得到链接器错误:

duplicate symbol __Z14checkInterruptv in:
    f1.o
    f2.o
duplicate symbol __ZN8Progress18_monitor_singletonE in:
    f1.o
    f2.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)

我认为这意味着我需要将#include <progress.hpp>每个cpp文件中包含一个单独的头文件,但我已经尝试过,但没有运气.我还使用Rcpp/RcppProgress查看了其他软件包,但是我不应该更改它.

T.C*_*.C. 8

这不是你的错.这是RcppProgress作者的错.他们progress.hpp

class Progress {
   // ...
private: // ===== INSTANCE VARIABLES
    static InterruptableProgressMonitor* _monitor_singleton;
};

InterruptableProgressMonitor* Progress::_monitor_singleton = 0;  // <-- this defines _monitor_singleton
Run Code Online (Sandbox Code Playgroud)

同样,它们interrupts.hpp间接包含在内

bool checkInterrupt() {
    return (R_ToplevelExec(chkIntFn, NULL) == FALSE);
}
Run Code Online (Sandbox Code Playgroud)

当您将标头包含在两个单独的转换单元(即.cpp文件)中时,两者都会导致一个定义规则违规,表现为您获得的链接器错误.要解决此问题,您需要以某种方式重新排列代码,以便只.cpp包含一个文件progress.hpp(例如,将两个文件合并为一个文件),或者对其头文件进行一些编辑.