" 2个用于架构的重复符号"在编译包Rcpp时,RcppProgress

时间:2014-09-07 09:26:24

标签: 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;
}

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;
}

他们都依赖于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)

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

1 个答案:

答案 0 :(得分:8)

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

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

InterruptableProgressMonitor* Progress::_monitor_singleton = 0;  // <-- this defines _monitor_singleton

同样,间接包含的interrupts.hpp包含

bool checkInterrupt() {
    return (R_ToplevelExec(chkIntFn, NULL) == FALSE);
}

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