了解 R 中 Makevars 文件的内容(宏、变量、~/.R/Makevars 和 pkg/src/Makevars)
Understanding the contents of the Makevars file in R (macros, variables, ~/.R/Makevars and pkg/src/Makevars)
我想了解 macros/variables 在 ~/.R/Makevars
和 package_directory/src/Makevars
中设置的作用和关系,当 installing/building 拥有 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
package_directory/src/Makevars
PKG_CPPFLAGS = -I../inst/include
CXX_STD = CXX11
据我了解,使用 CXX
我们可以 select 在构建 R 包时使用 C++ 编译器,使用 CXXSTD
我们选择标准,使用 CXXFLAGS
我们添加编译器标志。使用 PKG_CPPFLAGS
我们为 C++ 预处理器添加标志,使用 CXX_STD
我们告诉我们的包使用 C++11。
我有以下问题:
CXX
和CXX98
、CXX11
和CXX14
有什么关系?
- 如果已经隐含了 C++11,
CXX11STD = -std=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
与 ~/.R/Makevars
中的 CXX11
有什么关系?
CXXFLAGS
和PKG_CXXFLAGS
有什么关系(我的例子中没有)?
我知道 Writing R Extensions and R Installation and Administration 中包含的信息,但我无法提取超出我目前理解水平的更多信息来回答上述问题。
我添加了一个 Rcpp
标签,因为我认为这些问题的答案与 Rcpp
的用户最相关,但我知道这可能与 [=] 没有直接关系41=],因此如果认为合适,可能会删除标签。
Makevars
文件,如 Writing R Extensions: 1.2.1 Using Makevars, is a variant of Make
that is unique to R. Many of the variables you have listed are called implicit variables 中所指定。给出的含义为:
Implicit rules tell make how to use customary techniques so that you do not have to specify them in detail when you want to use them.
这些implicit variables
指示应该使用 what 编译器并且 what 选项可用。
在 R 中,我们关心以下默认编译器选项:
CC Program for compiling C programs; default ‘cc’.
CXX Program for compiling C++ programs; default ‘g++’.
CPP Program for running the C preprocessor, with results to standard output; default ‘$(CC) -E’.
FC Program for compiling or preprocessing Fortran and Ratfor programs; default ‘f77’.
下一组值详细说明编译器应使用的选项。通常,所有这些选项的默认值都是空字符串。
CFLAGS Extra flags to give to the C compiler.
CXXFLAGS Extra flags to give to the C++ compiler.
CPPFLAGS Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers).
FFLAGS Extra flags to give to the Fortran compiler.
LDFLAGS Extra flags to give to compilers when they are supposed to invoke the linker, ‘ld’, such as -L. Libraries (-lfoo) should be added
to the LDLIBS variable instead.
LDLIBS Library flags or names given to compilers when they are supposed to invoke the linker, ‘ld’. LOADLIBES is a deprecated (but
still supported) alternative to LDLIBS. Non-library linker flags, such
as -L, should go in the LDFLAGS variable.
现在,R 根据不同的 C++ ISO 标准定义了 "extra" 变体。这些变体在 R Administration: Section 2.7.2 C++ Support and R Administration: Section B.7 Compile and load flags
中给出
CXX98
CXX98STD
CXX98FLAGS
CXX98PICFLAGS
CXX11
CXX11STD
CXX11FLAGS
CXX11PICFLAGS
CXX14
CXX14STD
CXX14FLAGS
CXX14PICFLAGS
CXX17
CXX17STD
CXX17FLAGS
CXX17PICFLAGS
说到这里,我们来解决第一个问题:
What is the relationship between CXX
and CXX98
, CXX11
and CXX14
?
CXX
是要使用的一般编译器选项。同时,R 根据检测到的编译标准定义了额外的 CXX
选项。也就是说,如果 -std=c++98
(CXX98
语言规范)由 CXX_STD
设置,则使用与 CXX98
关联的编译器。类似地,对于 CXX11
和 CXX14
,遵循相同的逻辑。有关详细信息,请参阅 Rcpp Gallery: Using Rcpp with C++11, C++14 and C++17。
What is the meaning of, e.g., CXX11STD = -std=c++11
if C++11 is already implied? Is it between choosing -std=c++11
and -std=gnu++11
? Should -std=gnu++11
generally be avoided for portability reasons?
CXX11STD
的意思是确定适合C++11编译的语言标准。这个选项的存在只是因为如果R选择合适的C++11编译选项的版本对于编译器来说是不正确的,你可以改变它。存在这种情况的原因是因为每个编译器对 C++11 支持的定义可能与 R Installation and Administration: 2.7.2 C++ Support:
中指示的下一个略有不同
It may be [Footnote 13] that there is no suitable flag for C++11 support, in which case a different compiler could be selected for CXX11 and its corresponding flags.
脚注 13:
This is true for earlier versions of g++ such as 4.2.1, and also for commonly-used versions of the Solaris compiler CC.
有关 gcc 批准的语言标准的详细信息,请参阅 GCC Manual: 3.4 Options Controlling C Dialect. Also, for details on using C++11 with R in a package see Writing R Extensions: Section 1.2.4 Using C++11 Code。
一般来说,我会避免显式设置这个变量。如果您必须显式设置此变量,我建议使用 -std=c++11
,因为大多数编译器都支持此声明。
Could the flags for CXXSTD
and CXXFLAGS
not just be added to CXX
, such that the first three lines reduce to CXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer
. What is the advantage in explicitly specifying CXXSTD
and CXXFLAGS
?
可能吗?是的。这样对吗?编号
为什么有 三个 个变量,每个变量都有自己的目标,而我们只能有一个?
三个 可变工作流的优点是提供不同的线路,每个线路都有不同的作用。这允许快速理解编译选项的能力。因此,与将它塞进一行中的一个变量(终端宽度为 80)相比,grok 更直接。
例如
CXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer
对
CXX = g++
CXX11STD = -std=c++11
CXXFLAGS = -fsanitize=undefined,address -fno-omit-frame-pointer
此外,如Writing R Extensions: Section 1.2.4 Using C++11 Code所示打包时,您应该选择CXX_STD
而不是CXXSTD
。这只是为了确保 R 将包注册为需要 C++xy。另一种方法是在 DESCRIPTION
文件中写入属性 SystemRequirements: C++xy
,其中 xy
表示年份。
How does CXX_STD
= CXX11
work? How is CXX11
here related to CXX11
in ~/.R/Makevars?
这设置了要使用 CXX11
设置的 C++11 编译器完成的语言的编译和链接。通过指定 CXX11
,您指定了一个 variable in Make
,它将用于编译配方下的文件:
$(OBJCXX) $(ALL_CPPFLAGS) $(ALL_OBJCXXFLAGS) -c $< -o $@
其中 $(OBJCXX)
是 CXX
,$(ALL_CPPFLAGS)
由 $(R_XTRA_CPPFLAGS) $(PKG_CPPFLAGS) $(CLINK_CPPFLAGS) $(CPPFLAGS)
给出,而 $(ALL_OBJCXXFLAGS)
有 $(PKG_OBJCXXFLAGS) $(CXXPICFLAGS) $(SHLIB_CXXFLAGS) $(OBJCXXFLAGS)
.
以上为/R/Makeconf.in
. However, the routine may be /m4/R
.
What is the relationship between CXXFLAGS
and PKG_CXXFLAGS
(not included in my example)?
这两个都指定了编译器的编译标志。 Makevars
中的顺序不同。特别地,我们有
CXXFLAGS
placed after PKG_CXXFLAGS
。 正确大多数选项是总是使用。所以,CXXFLAGS
优先于PKG_CXXFLAGS
.
Writing R Extensions: Section 5.5 Creating shared objects 中有关于 PKG_*
选项的简短说明。
附录
以下是@Dominik 在此回复的评论部分提出的问题。
Is it correct that variables defined in ~/.R/Makevars
apply globally to the installation of all packages, while variables in /src/Makevars
only apply to the present package?
是的。这是准确的。 ~/.R/Makevars
中的变量将应用于所有包,而每个包附带的 /src/Makevars
只会影响该包的设置。 /src/Makevars
中的值将优先于 ~/.R/Makevars
.
一些软件包可能附带 /src/Makevars.win
,它提供了专门用于 Windows 环境的 Makevars
文件。
Is the compilation standard used for a packages nowadays only set via CXX_STD
and not any more by PKG_CXXFLAGS
as shown in gallery.rcpp.org/articles/simple-lambda-func-c++11?
这两个标志的使用时间略有不同。特别是,CXX_STD
只能在包环境中运行。同时,与其名称相反,PKG_CXXFLAGS
影响所有编译选项。因此,当您引用上面的 Rcpp 库 post 时,您正在观察一个独立的脚本 运行。要快速进入正确的模式,需要设置 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"
。)
Does using CXX_STD=CXX11
then mean to use all the settings given by CXX
, CXXSTD
, CXXFLAGS
and CXX11PICFLAGS
?
没有。这意味着使用由以下设置的选项:
CXX11
CXX11STD
CXX11FLAGS
CXX11PICFLAGS
我想了解 macros/variables 在 ~/.R/Makevars
和 package_directory/src/Makevars
中设置的作用和关系,当 installing/building 拥有 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
package_directory/src/Makevars
PKG_CPPFLAGS = -I../inst/include
CXX_STD = CXX11
据我了解,使用 CXX
我们可以 select 在构建 R 包时使用 C++ 编译器,使用 CXXSTD
我们选择标准,使用 CXXFLAGS
我们添加编译器标志。使用 PKG_CPPFLAGS
我们为 C++ 预处理器添加标志,使用 CXX_STD
我们告诉我们的包使用 C++11。
我有以下问题:
CXX
和CXX98
、CXX11
和CXX14
有什么关系?- 如果已经隐含了 C++11,
CXX11STD = -std=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
与~/.R/Makevars
中的CXX11
有什么关系?CXXFLAGS
和PKG_CXXFLAGS
有什么关系(我的例子中没有)?
我知道 Writing R Extensions and R Installation and Administration 中包含的信息,但我无法提取超出我目前理解水平的更多信息来回答上述问题。
我添加了一个 Rcpp
标签,因为我认为这些问题的答案与 Rcpp
的用户最相关,但我知道这可能与 [=] 没有直接关系41=],因此如果认为合适,可能会删除标签。
Makevars
文件,如 Writing R Extensions: 1.2.1 Using Makevars, is a variant of Make
that is unique to R. Many of the variables you have listed are called implicit variables 中所指定。给出的含义为:
Implicit rules tell make how to use customary techniques so that you do not have to specify them in detail when you want to use them.
这些implicit variables 指示应该使用 what 编译器并且 what 选项可用。
在 R 中,我们关心以下默认编译器选项:
CC Program for compiling C programs; default ‘cc’.
CXX Program for compiling C++ programs; default ‘g++’.
CPP Program for running the C preprocessor, with results to standard output; default ‘$(CC) -E’.
FC Program for compiling or preprocessing Fortran and Ratfor programs; default ‘f77’.
下一组值详细说明编译器应使用的选项。通常,所有这些选项的默认值都是空字符串。
CFLAGS Extra flags to give to the C compiler.
CXXFLAGS Extra flags to give to the C++ compiler.
CPPFLAGS Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers).
FFLAGS Extra flags to give to the Fortran compiler.
LDFLAGS Extra flags to give to compilers when they are supposed to invoke the linker, ‘ld’, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable instead.
LDLIBS Library flags or names given to compilers when they are supposed to invoke the linker, ‘ld’. LOADLIBES is a deprecated (but still supported) alternative to LDLIBS. Non-library linker flags, such as -L, should go in the LDFLAGS variable.
现在,R 根据不同的 C++ ISO 标准定义了 "extra" 变体。这些变体在 R Administration: Section 2.7.2 C++ Support and R Administration: Section B.7 Compile and load flags
中给出CXX98 CXX98STD CXX98FLAGS CXX98PICFLAGS
CXX11 CXX11STD CXX11FLAGS CXX11PICFLAGS
CXX14 CXX14STD CXX14FLAGS CXX14PICFLAGS
CXX17 CXX17STD CXX17FLAGS CXX17PICFLAGS
说到这里,我们来解决第一个问题:
What is the relationship between
CXX
andCXX98
,CXX11
andCXX14
?
CXX
是要使用的一般编译器选项。同时,R 根据检测到的编译标准定义了额外的 CXX
选项。也就是说,如果 -std=c++98
(CXX98
语言规范)由 CXX_STD
设置,则使用与 CXX98
关联的编译器。类似地,对于 CXX11
和 CXX14
,遵循相同的逻辑。有关详细信息,请参阅 Rcpp Gallery: Using Rcpp with C++11, C++14 and C++17。
What is the meaning of, e.g.,
CXX11STD = -std=c++11
if C++11 is already implied? Is it between choosing-std=c++11
and-std=gnu++11
? Should-std=gnu++11
generally be avoided for portability reasons?
CXX11STD
的意思是确定适合C++11编译的语言标准。这个选项的存在只是因为如果R选择合适的C++11编译选项的版本对于编译器来说是不正确的,你可以改变它。存在这种情况的原因是因为每个编译器对 C++11 支持的定义可能与 R Installation and Administration: 2.7.2 C++ Support:
It may be [Footnote 13] that there is no suitable flag for C++11 support, in which case a different compiler could be selected for CXX11 and its corresponding flags.
脚注 13:
This is true for earlier versions of g++ such as 4.2.1, and also for commonly-used versions of the Solaris compiler CC.
有关 gcc 批准的语言标准的详细信息,请参阅 GCC Manual: 3.4 Options Controlling C Dialect. Also, for details on using C++11 with R in a package see Writing R Extensions: Section 1.2.4 Using C++11 Code。
一般来说,我会避免显式设置这个变量。如果您必须显式设置此变量,我建议使用 -std=c++11
,因为大多数编译器都支持此声明。
Could the flags for
CXXSTD
andCXXFLAGS
not just be added toCXX
, such that the first three lines reduce toCXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer
. What is the advantage in explicitly specifyingCXXSTD
andCXXFLAGS
?
可能吗?是的。这样对吗?编号
为什么有 三个 个变量,每个变量都有自己的目标,而我们只能有一个?
三个 可变工作流的优点是提供不同的线路,每个线路都有不同的作用。这允许快速理解编译选项的能力。因此,与将它塞进一行中的一个变量(终端宽度为 80)相比,grok 更直接。
例如
CXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer
对
CXX = g++
CXX11STD = -std=c++11
CXXFLAGS = -fsanitize=undefined,address -fno-omit-frame-pointer
此外,如Writing R Extensions: Section 1.2.4 Using C++11 Code所示打包时,您应该选择CXX_STD
而不是CXXSTD
。这只是为了确保 R 将包注册为需要 C++xy。另一种方法是在 DESCRIPTION
文件中写入属性 SystemRequirements: C++xy
,其中 xy
表示年份。
How does
CXX_STD
=CXX11
work? How isCXX11
here related toCXX11
in ~/.R/Makevars?
这设置了要使用 CXX11
设置的 C++11 编译器完成的语言的编译和链接。通过指定 CXX11
,您指定了一个 variable in Make
,它将用于编译配方下的文件:
$(OBJCXX) $(ALL_CPPFLAGS) $(ALL_OBJCXXFLAGS) -c $< -o $@
其中 $(OBJCXX)
是 CXX
,$(ALL_CPPFLAGS)
由 $(R_XTRA_CPPFLAGS) $(PKG_CPPFLAGS) $(CLINK_CPPFLAGS) $(CPPFLAGS)
给出,而 $(ALL_OBJCXXFLAGS)
有 $(PKG_OBJCXXFLAGS) $(CXXPICFLAGS) $(SHLIB_CXXFLAGS) $(OBJCXXFLAGS)
.
以上为/R/Makeconf.in
. However, the routine may be /m4/R
.
What is the relationship between
CXXFLAGS
andPKG_CXXFLAGS
(not included in my example)?
这两个都指定了编译器的编译标志。 Makevars
中的顺序不同。特别地,我们有
CXXFLAGS
placed after PKG_CXXFLAGS
。 正确大多数选项是总是使用。所以,CXXFLAGS
优先于PKG_CXXFLAGS
.
Writing R Extensions: Section 5.5 Creating shared objects 中有关于 PKG_*
选项的简短说明。
附录
以下是@Dominik 在此回复的评论部分提出的问题。
Is it correct that variables defined in
~/.R/Makevars
apply globally to the installation of all packages, while variables in/src/Makevars
only apply to the present package?
是的。这是准确的。 ~/.R/Makevars
中的变量将应用于所有包,而每个包附带的 /src/Makevars
只会影响该包的设置。 /src/Makevars
中的值将优先于 ~/.R/Makevars
.
一些软件包可能附带 /src/Makevars.win
,它提供了专门用于 Windows 环境的 Makevars
文件。
Is the compilation standard used for a packages nowadays only set via
CXX_STD
and not any more byPKG_CXXFLAGS
as shown in gallery.rcpp.org/articles/simple-lambda-func-c++11?
这两个标志的使用时间略有不同。特别是,CXX_STD
只能在包环境中运行。同时,与其名称相反,PKG_CXXFLAGS
影响所有编译选项。因此,当您引用上面的 Rcpp 库 post 时,您正在观察一个独立的脚本 运行。要快速进入正确的模式,需要设置 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"
。)
Does using
CXX_STD=CXX11
then mean to use all the settings given byCXX
,CXXSTD
,CXXFLAGS
andCXX11PICFLAGS
?
没有。这意味着使用由以下设置的选项:
CXX11 CXX11STD CXX11FLAGS CXX11PICFLAGS