我想了解在设置宏/变量的作用和关系,~/.R/Makevars以及package_directory/src/Makevars安装时/构建自己的R包.假设这些文件看起来像
〜/ .R/Makevars
CXX = g++
CXXSTD = -std=c++11
CXXFLAGS = -fsanitize=undefined,address -fno-omit-frame-pointer
CXX98 = g++
CXX98STD = -std=c++98
CXX11 = g++
CXX11STD = -std=c++11
CXX14 = g++
CXX14STD = -std=c++14
Run Code Online (Sandbox Code Playgroud)
package_directory/SRC/Makevars
PKG_CPPFLAGS = -I../inst/include
CXX_STD = CXX11
Run Code Online (Sandbox Code Playgroud)
据我所知,CXX我们可以在构建R包时为C++选择编译器,CXXSTD我们选择标准并CXXFLAGS添加编译器标志.随着PKG_CPPFLAGS我们为C++预处理器添加标志,CXX_STD我们告诉我们的包使用C++ 11.
我有以下问题:
CXX和CXX98,CXX11和CXX14?CXX11STD = -std=c++11如果已经隐含了C++ 11,那意味着什么?是在选择-std=c++11和-std=gnu++11?应该-std=gnu++11通常避免针对便携性的原因?CXXSTD,CXXFLAGS而不只是添加CXX,以便前三行减少到CXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer.明确指定CXXSTD和CXXFLAGS?的优点是什么?CXX_STD = CXX11工作怎么样?如何CXX11在这里涉及到CXX11的~/.R/Makevars?CXXFLAGS和之间的关系是什么PKG_CXXFLAGS(不包括在我的例子中)? 我知道编写R扩展和R安装和管理中包含的信息,但我无法提取超出目前理解水平的更多信息来回答上述问题.
我正在添加一个Rcpp标签,因为我认为这些问题的答案与用户最相关Rcpp,但我知道这可能与之没有直接关系Rcpp,因此如果认为合适,标签可能会被删除.
coa*_*ess 80
该Makevars文件,在指定的写作R附加:1.2.1使用Makevars,是的变体Make是独特的,以R.许多已上市被称为变量的隐含变量.含义如下:
隐式规则告诉如何使用习惯技术,以便在您想要使用它们时不必详细指定它们.
这些隐含变量 决定什么样的编译器应使用哪些选项.
在R中,我们关注以下默认编译器选项:
用于编制C计划的CC计划; 默认'cc'.
用于编译C++程序的CXX程序; 默认'g ++'.
用于运行C预处理器的CPP程序,其结果为标准输出; 默认'$(CC)-E'.
用于编译或预处理Fortran和Ratfor程序的FC程序; 默认'f77'.
下一组值详细说明了编译器应使用的选项.通常,所有这些选项的默认值都是空字符串.
CFLAGS为C编译器提供的额外标志.
CXXFLAGS为C++编译器提供的额外标志.
CPPFLAGS提供给C预处理器和使用它的程序的额外标志(C和Fortran编译器).
FFLAGS为Fortran编译器提供的额外标志.
LDFLAGS额外标志,当它们应该调用链接器'ld'时给予编译器,例如-L.应该将库(-lfoo)添加到LDLIBS变量中.
LDLIBS库标志或名称,当它们应该调用链接器时,给予编译器"ld".LOADLIBES是LDLIBS的弃用(但仍受支持)替代方案.非库链接器标志(如-L)应包含在LDFLAGS变量中.
现在,R根据不同的C++ ISO标准定义了"额外"变体.这些变体在R管理中给出:第2.7.2节C++支持和R管理:第B.7节编译和加载标志
CXX98 CXX98STD CXX98FLAGS CXX98PICFLAGS
CXX11 CXX11STD CXX11FLAGS CXX11PICFLAGS
CXX14 CXX14STD CXX14FLAGS CXX14PICFLAGS
CXX17 CXX17STD CXX17FLAGS CXX17PICFLAGS
说完这个,让我们解决第一个问题:
什么是之间的关系
CXX和CXX98,CXX11和CXX14?
CXX是要使用的常规编译器选项.同时,RCXX根据检测到的编译标准定义了要使用的其他选项.也就是说,如果 -std=c++98(CXX98语言规范)设置为CXX_STD,则使用与之关联的编译器CXX98.同样,对于CXX11和CXX14,同样的逻辑如下.有关更多详细信息,请参阅Rcpp Gallery:将Rcpp与C++ 11,C++ 14和C++ 17一起使用.
例如,
CXX11STD = -std=c++11如果已经隐含了C++ 11,那意味着什么?是在选择-std=c++11和-std=gnu++11?应该-std=gnu++11通常避免针对便携性的原因?
其含义CXX11STD是确定C++ 11编译的相应语言标准.此选项的存在只是因为如果R选择适当的C++ 11编译选项的版本对于编译器不正确,则可以更改它.这种情况的原因是因为每个编译器可能会定义C++ 11支持与下一个不同,如R安装和管理中所示:2.7.2 C++支持:
可能是[脚注13]没有适合C++ 11支持的标志,在这种情况下,可以为CXX11及其相应的标志选择不同的编译器.
脚注13:
对于早期版本的g ++(例如4.2.1)以及常用版本的Solaris编译器CC都是如此.
有关gcc批准的语言标准的详细信息,请参阅GCC手册:3.4控制C语言的选项.另外,有关在包中使用带有R的 C++ 11的详细信息,请参阅编写R扩展:第1.2.4节使用C++ 11代码.
通常,我会避免显式设置此变量.如果你必须明确设置这个变量,我建议你去,-std=c++11因为大多数编译器支持这个声明.
是否可以添加标志
CXXSTD,CXXFLAGS而不只是添加CXX,以便前三行减少到CXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer.明确指定CXXSTD和CXXFLAGS?的优点是什么?
可能吗?是.这样对吗?没有.
当我们只有一个变量时,为什么有三个变量各自有自己的目标?
三变量工作流程的优点是提供不同的行,每行都有不同的作用.这允许快速理解编译选项的能力.因此,当它被塞入一条线上的一个变量(终端宽度为80)时,它更直接.
例如
CXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer
Run Code Online (Sandbox Code Playgroud)
VS
CXX = g++
CXX11STD = -std=c++11
CXXFLAGS = -fsanitize=undefined,address -fno-omit-frame-pointer
Run Code Online (Sandbox Code Playgroud)
此外,您应该在打包时选择CXX_STD结束CXXSTD,如编写R扩展:第1.2.4节"使用C++ 11代码"所示.这只是为了确保R将包注册为需要C++ xy.另一种方法是在DESCRIPTION文件中写入属性SystemRequirements: C++xy,其中xy表示年份.
怎么样
CXX_STD=CXX11工作?CXX11在这里如何与CXX11〜/ .R/Makevars相关?
这将设置要使用C++ 11编译器设置的语言的编译和链接CXX11.通过指定CXX11,您将指定一个变量,Make用于在配方下编译文件:
$(OBJCXX) $(ALL_CPPFLAGS) $(ALL_OBJCXXFLAGS) -c $< -o $@
Run Code Online (Sandbox Code Playgroud)
这里$(OBJCXX)是CXX,$(ALL_CPPFLAGS)由下式给出$(R_XTRA_CPPFLAGS) $(PKG_CPPFLAGS) $(CLINK_CPPFLAGS) $(CPPFLAGS),并$(ALL_OBJCXXFLAGS)有$(PKG_OBJCXXFLAGS) $(CXXPICFLAGS) $(SHLIB_CXXFLAGS) $(OBJCXXFLAGS)
.
以上如下/R/Makeconf.in.但是,例程可能是/m4/R.
CXXFLAGS和之间的关系是什么PKG_CXXFLAGS(不包括在我的例子中)?
这两个都指定了编译器的编译标志.它们写入的顺序Makevars是不同的.特别是,我们已经
CXXFLAGS放置了 PKG_CXXFLAGS.在右大多数选项始终使用.所以,CXXFLAGS优先于PKG_CXXFLAGS.
关于编写R扩展中的PKG_*选项的简要说明:第5.5节创建共享对象.
以下是@Dominik在本回复的评论部分中提出的问题.
是否正确定义的变量
~/.R/Makevars全局应用于所有包的安装,而变量/src/Makevars仅适用于当前包?
是.这是准确的.其中的变量~/.R/Makevars将适用于所有包,而/src/Makevars每个包附带的变量只会影响该包的设置.值/src/Makevars将优先于~/.R/Makevars.
某些软件包可能附带/src/Makevars.win,它提供Makevars专门用于Windows环境的文件.
现在用于包的编译标准是否仅通过gallery.rcpp.org/articles/simple-lambda-func-c++11中的设置
CXX_STD而不是设置PKG_CXXFLAGS?
应该使用这两个标志之间存在细微差别.特别是,CXX_STD仅在包环境中可操作.同时,与其名称相反PKG_CXXFLAGS,会影响所有编译选项.因此,当您引用上述Rcpp图库文章时,您正在观察正在运行的独立脚本.要快速搞正确的模式,这需要PKG_CXXFLAGS进行设置,并没有在CXX_STD定义.
现在,请原谅我对独立使用编译选项的历史进行简要介绍....使用PKG_CXXFLAGS有点老派.实际上,R 3.4中的首选方法是设置环境变量USE_CXX11 = "yes".在R 3.1和R 3.3之间,标准是设置环境变量USE_CXX1X = "yes".在这些情况之前,PKG_CXXFLAGS ="-std=c++11"优选使用.(在Windows上除外,需要PKG_CXXFLAGS ="-std=c++0x".)
是否使用
CXX_STD=CXX11则意味着使用由给定的所有设置CXX,CXXSTD,CXXFLAGS和CXX11PICFLAGS?
不.这意味着使用以下设置的选项:
CXX11 CXX11STD CXX11FLAGS CXX11PICFLAGS