"RcppArmadilloExtensions/sample.h" R 包构建步骤中的链接器错误
"RcppArmadilloExtensions/sample.h" Linker Error in R Package Build Step
我正在制作一个 R 包,它在某些源文件中使用了 Rcpp::RcppArmadillo::sample()
函数。特别是,我在 4 个不同的 cpp 文件中使用了该函数,并且在每个文件中我都添加了这一行 #include <RcppArmadilloExtensions/sample.h>
以包含所需的头文件。
一切正常,直到我想通过命令 R CMD build mypackage
构建包。我收到 duplicate symbol 错误,其中提到的头文件中定义的大多数函数都被列为重复符号。例如,ProbSampleNoReplace
、FixProb
、SampleReplace
和 WalkerProbSampleReplace
等函数都被列为在这 4 个 cpp 文件之间重复。
我搜索了这个问题,解决方案是在 .cpp
文件而不是 .h
文件中定义变量或函数以防止重复,如果需要,请使用 extern
在任何其他 cpp
文件中使用这些变量。但我认为该解决方案不适用于此处,因为头文件不是我编写的,我不想对位于 here.
的 sample.h
头文件进行任何更改
有什么解决这个问题的建议吗?预先感谢您的帮助。
根据德克的评论,这最终对我有用:
我删除了每个文件顶部多余的 headers 并将其放在一个地方。这可以通过两种方式完成。一种是放在一个访问函数中,可以在任何需要的地方调用。
另一种选择是,如果您的整个项目不是那么大,您可以将 header #include <RcppArmadilloExtensions/sample.h>
放在主 .cpp
文件之上,其中包含您的项目与多个职能。我实际上为我自己的项目做了后一种选择。
我能够使用@amir-nik 在他 2021 年 6 月 16 日的回答中陈述的第一个选项。
One is to put it in one access function that can be called anywhere needed.
由于我花了很长时间才弄清楚如何去做,所以我在这里提供了一个完整的示例,以防大家感兴趣。
首先,我制作了如下源文件sample.cpp
。重载是因为我需要采样函数来处理两种不同的向量类型。
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadilloExtensions/sample.h>
arma::vec sample(const arma::vec& x, const int& size, const bool& replace, const arma::vec& probs){
return Rcpp::RcppArmadillo::sample(x, size, replace, probs);
}
arma::uvec sample(const arma::uvec& x, const int& size, const bool& replace, const arma::vec& probs){
return Rcpp::RcppArmadillo::sample(x, size, replace, probs);
}
接下来,我制作了这个头文件sample.h
:
#ifndef SAMPLE_H
#define SAMPLE_H
#include <RcppArmadillo.h>
arma::vec sample(const arma::vec& x, const int& size, const bool& replace, const arma::vec& probs);
arma::uvec sample(const arma::uvec& x, const int& size, const bool& replace, const arma::vec& probs);
#endif
现在,通过编写 #include "sample.h"
,我可以在我的所有代码中使用 Rcpp::RcppArmadillo::sample()
。
我正在制作一个 R 包,它在某些源文件中使用了 Rcpp::RcppArmadillo::sample()
函数。特别是,我在 4 个不同的 cpp 文件中使用了该函数,并且在每个文件中我都添加了这一行 #include <RcppArmadilloExtensions/sample.h>
以包含所需的头文件。
一切正常,直到我想通过命令 R CMD build mypackage
构建包。我收到 duplicate symbol 错误,其中提到的头文件中定义的大多数函数都被列为重复符号。例如,ProbSampleNoReplace
、FixProb
、SampleReplace
和 WalkerProbSampleReplace
等函数都被列为在这 4 个 cpp 文件之间重复。
我搜索了这个问题,解决方案是在 .cpp
文件而不是 .h
文件中定义变量或函数以防止重复,如果需要,请使用 extern
在任何其他 cpp
文件中使用这些变量。但我认为该解决方案不适用于此处,因为头文件不是我编写的,我不想对位于 here.
sample.h
头文件进行任何更改
有什么解决这个问题的建议吗?预先感谢您的帮助。
根据德克的评论,这最终对我有用:
我删除了每个文件顶部多余的 headers 并将其放在一个地方。这可以通过两种方式完成。一种是放在一个访问函数中,可以在任何需要的地方调用。
另一种选择是,如果您的整个项目不是那么大,您可以将 header #include <RcppArmadilloExtensions/sample.h>
放在主 .cpp
文件之上,其中包含您的项目与多个职能。我实际上为我自己的项目做了后一种选择。
我能够使用@amir-nik 在他 2021 年 6 月 16 日的回答中陈述的第一个选项。
One is to put it in one access function that can be called anywhere needed.
由于我花了很长时间才弄清楚如何去做,所以我在这里提供了一个完整的示例,以防大家感兴趣。
首先,我制作了如下源文件sample.cpp
。重载是因为我需要采样函数来处理两种不同的向量类型。
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadilloExtensions/sample.h>
arma::vec sample(const arma::vec& x, const int& size, const bool& replace, const arma::vec& probs){
return Rcpp::RcppArmadillo::sample(x, size, replace, probs);
}
arma::uvec sample(const arma::uvec& x, const int& size, const bool& replace, const arma::vec& probs){
return Rcpp::RcppArmadillo::sample(x, size, replace, probs);
}
接下来,我制作了这个头文件sample.h
:
#ifndef SAMPLE_H
#define SAMPLE_H
#include <RcppArmadillo.h>
arma::vec sample(const arma::vec& x, const int& size, const bool& replace, const arma::vec& probs);
arma::uvec sample(const arma::uvec& x, const int& size, const bool& replace, const arma::vec& probs);
#endif
现在,通过编写 #include "sample.h"
,我可以在我的所有代码中使用 Rcpp::RcppArmadillo::sample()
。