我正在使用Qt Creator创建一个静态库,这个库将用于更大的基于GUI的应用程序。我之前使用过Rcpp,但是把R作为我的起点 - 所以将R数据移动到C ++函数来做东西并得到结果,我习惯用R studio来做。这次我开始在一个Qt项目中,我需要一个表来存储一些数据,而Rcpp :: Dataframe很适合这项工作,就像一些矢量类一样。在我的.cpp源文件中,我有include语句#include <Rcpp.h>
,我在网上看了一下,发现了一个在Qt中使用的Rcpp / RInside库的例子 - 虽然它更多的是关于RInside而不是Rcpp:{{3 }}
似乎有些东西需要添加到.pro文件中才能让qmake做正确的事情。我在下面附带的.pro文件中包含了我认为Rcpp所需的内容。我遇到的问题是,在.pro文件中包含Rcpp内容和.cpp文件中的include语句之前,包含在下面的.pro文件中也可以看到的bpp库不会导致编译中的任何错误或警告。在包含R和Rcpp的语句包含在.pro文件中之后,我收到很多警告和一个与bpp组件有关的错误,特别是:/local/yrq12edu/local/bpp/dev/include/Bpp/Numeric/NumConstants.h:96: error: expected unqualified-id before numeric constant
。还有很多Wunused-parameter
消息,这些消息中的大多数似乎都来自bpp内的文件。这是我第一次不得不处理这样的事情,尽管我已经阅读了很多Qt文档,但我仍然是一个非常新鲜的Qt新手。为什么在使用bpp之前我没有得到任何错误,但现在得到它们我已经尝试将Rcpp包含在我的Qt项目中?我该怎么办才能采取措施解决这个问题?
#-------------------------------------------------
#
# Project created by QtCreator 2014-09-05T23:27:21
#
#-------------------------------------------------
QT -= core gui
TARGET = libHybRIDS
TEMPLATE = lib
CONFIG += staticlib
SOURCES += hybridsengine.cpp
HEADERS += hybridsengine.h
INCLUDEPATH += /local/yrq12edu/local/bpp/dev/include
LIBS += -L/local/yrq12edu/local/bpp/dev/lib -lbpp-core
LIBS += -L/local/yrq12edu/local/bpp/dev/lib -lbpp-seq
# Set R home directory
R_HOME = $$system(R RHOME)
# Set Rcpp include and lib flags.
RCPPINCL = $$system($$R_HOME/bin/Rscript -e \'Rcpp:::CxxFlags\(\)\')
RCPPLIBS = $$system($$R_HOME/bin/Rscript -e \'Rcpp:::LdFlags\(\)\')
# Set R cpp and ld flags. Also for BLAS and LAPACK it uses.
RCPPFLAGS = $$system($$R_HOME/bin/R CMD config --cppflags)
RLDFLAGS = $$system($$R_HOME/bin/R CMD config --ldflags)
RBLAS = $$system($$R_HOME/bin/R CMD config BLAS_LIBS)
RLAPACK = $$system($$R_HOME/bin/R CMD config LAPACK_LIBS)
RCPPWARNING = -Wno-unused-parameter
QMAKE_CXXFLAGS += $$RCPPWARNING $$RCPPFLAGS $$RCPPINCL
QMAKE_LFLAGS += $$RLDFLAGS $$RBLAS $$RLAPACK $$RCPPLIBS
unix {
target.path = /usr/lib
INSTALLS += target
}
修改 以下建议我使用了RInside / examples / qt中的示例pro文件作为起点 - 保持语句的顺序:
#-------------------------------------------------
#
# Project created by QtCreator 2014-09-05T23:27:21
#
#-------------------------------------------------
QT -= core gui
TARGET = libHybRIDS
TEMPLATE = lib
CONFIG += staticlib
SOURCES += hybridsengine.cpp
HEADERS += hybridsengine.h
## comment this out if you need a different version of R,
## and set set R_HOME accordingly as an environment variable
R_HOME = $$system(R RHOME)
#message("R_HOME is" $$R_HOME)
## include headers and libraries for R
RCPPFLAGS = $$system($$R_HOME/bin/R CMD config --cppflags)
RLDFLAGS = $$system($$R_HOME/bin/R CMD config --ldflags)
RBLAS = $$system($$R_HOME/bin/R CMD config BLAS_LIBS)
RLAPACK = $$system($$R_HOME/bin/R CMD config LAPACK_LIBS)
## if you need to set an rpath to R itself, also uncomment
RRPATH = -Wl,-rpath,$$R_HOME/lib
## include headers and libraries for Rcpp interface classes
## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted
RCPPINCL = $$system($$R_HOME/bin/Rscript -e \"Rcpp:::CxxFlags\(\)\")
RCPPLIBS = $$system($$R_HOME/bin/Rscript -e \"Rcpp:::LdFlags\(\)\")
## for some reason when building with Qt we get this each time
## /usr/local/lib/R/site-library/Rcpp/include/Rcpp/module/Module_generated_ctor_signature.h:25: warning: unused parameter ‘classname
## so we turn unused parameter warnings off
## no longer needed with Rcpp 0.9.3 or later
#RCPPWARNING = -Wno-unused-parameter
## include headers and libraries for RInside embedding classes
RINSIDEINCL = $$system($$R_HOME/bin/Rscript -e \"RInside:::CxxFlags\(\)\")
RINSIDELIBS = $$system($$R_HOME/bin/Rscript -e \"RInside:::LdFlags\(\)\")
## compiler etc settings used in default make rules
QMAKE_CXXFLAGS += $$RCPPWARNING $$RCPPFLAGS $$RCPPINCL $$RINSIDEINCL
QMAKE_LIBS += $$RLDFLAGS $$RBLAS $$RLAPACK $$RINSIDELIBS $$RCPPLIBS
## addition clean targets
QMAKE_CLEAN += qtdensity Makefile
unix {
target.path = /usr/lib
INSTALLS += target
}
在我的陈述中包含来自之前或之后的与rnspp和Rcpp有关的陈述的bpp库会导致与之前相同的错误。
来自bpp的.h文件的内容是:
#ifndef _NUMCONSTANTS_H_
#define _NUMCONSTANTS_H_
#include <cmath>
#include <limits>
namespace bpp {
/**
* @brief this static class contains several useful constant values.
*
* This classe uses function in order to avoid the infamous "static initialization order fiasco".
* C++0x solves this...
*/
class NumConstants
{
public:
/**
* @name Golden ratio.
*
* The golden ratio, @f$\phi@f$ is equal to @f$\frac{1+\sqrt{5}}{2} = 1.6180339887498948482\ldots@f$.
* We also define @f$R=\phi-1@f$ and @f$C = 1 - R@f$.
* @{
*/
static double GOLDEN_RATIO_PHI() { return (1. + sqrt(5.)) / 2.; }
static double GOLDEN_RATIO_R() { return GOLDEN_RATIO_PHI() - 1.; }
static double GOLDEN_RATIO_C() { return 1. - GOLDEN_RATIO_R(); }
/** @} */
static double MEGA() { return 1e6; }
static double KILO() { return 1e3; }
static double DECI() { return 1e-1; }
static double CENTI() { return 1e-2; }
static double MILLI() { return 1e-3; }
static double MICRO() { return 1e-6; }
static double NANO() { return 1e-9; }
static double PICO() { return 1e-12; }
static double SMALL() { return 1e-6; }
static double TINY() { return 1e-12; }
static double VERY_TINY() { return 1e-20; }
static double VERY_BIG() { return static_cast<double>(1.7E+23); }
/**
* @name Define those constants in case they would not be available in stl/limits.
*
* @{
*/
static double INF() { return std::numeric_limits<double>::has_infinity ? -log(0) : std::numeric_limits<double>::max(); }
static double PINF() { return std::numeric_limits<double>::has_infinity ? -log(0) : std::numeric_limits<double>::max(); }
static double MINF() { return std::numeric_limits<double>::has_infinity ? log(0) : std::numeric_limits<double>::min(); }
static double NaN() { return NAN; }
/** @} */
static double PI() { return 3.141593; }
};
}//end of namespace bpp.
#endif //_NUMCONSTANTS_H_
答案 0 :(得分:0)
这是一个猜测:在R_ext/Constants.h
中,我们有:
trunk/src/include/R_ext/Constants.h
28:#define M_PI 3.141592653589793238462643383279502884197169399375
32:#define PI M_PI
该宏定义与PI
的函数定义冲突。所以你会想到例如。
#include <R.h> // pulls in 'R_ext/Constants.h'
#include "Bpp stuff" // definition for function named PI collides with macro
会给出潜在的错误。 PI
的R宏定义会泄漏到Bpp
,因此在预处理器完成后,此行:
static double PI() { return 3.141593; }
看起来像
static double 3.141592653589793238462643383279502884197169399375() { return 3.141593; }
并且编译器只能说&#39; wat&#39;。这就是为什么包括订单可能很重要 - 包括Bpp
首先要避免宏观污染。
通过定义#define STRICT_R_HEADERS
(因为条目包含的内容),可以避免这种污染。