tutorial - rccp
ComprensiĆ³n del contenido del archivo Makevars en R(macros, variables, ~/.R/Makevars y pkg/src/Makevars) (1)
Estoy tratando de entender el rol y la relación de las macros / variables establecidas en ~/.R/Makevars
y ~/.R/Makevars
package_directory/src/Makevars
al instalar / construir paquetes R propios. Supongamos que estos archivos parecen
~ / .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
directorio_paquete / src / Makevars
PKG_CPPFLAGS = -I../inst/include
CXX_STD = CXX11
Según tengo entendido, con CXX
podemos seleccionar el compilador para C ++ al crear paquetes R, con CXXSTD
elegimos el estándar y con CXXFLAGS
agregamos indicadores de compilación. Con PKG_CPPFLAGS
agregamos indicadores para el preprocesador de C ++ y con CXX_STD
decimos que nuestros paquetes usan C ++ 11.
Tengo las siguientes preguntas:
- ¿Cuál es la relación entre
CXX
yCXX98
,CXX11
yCXX14
? - ¿Cuál es el significado de, por ejemplo,
CXX11STD = -std=c++11
si C ++ 11 ya está implícito? ¿Es entre elegir-std=c++11
y-std=gnu++11
? ¿Debe-std=gnu++11
generalmente-std=gnu++11
por razones de portabilidad? - ¿Es posible que las banderas para
CXXSTD
yCXXFLAGS
no se agreguen aCXX
, de manera que las tres primeras líneas se reduzcan aCXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer
? ¿Cuál es la ventaja de especificar explícitamenteCXXSTD
yCXXFLAGS
? - ¿Cómo funciona
CXX_STD = CXX11
? ¿Cómo se relacionaCXX11
aquí conCXX11
en~/.R/Makevars
? - ¿Cuál es la relación entre
CXXFLAGS
yPKG_CXXFLAGS
(no incluido en mi ejemplo)?
Soy consciente de la información contenida en Writing R Extensions y R Installation and Administration , pero no puedo extraer más información más allá de mi nivel actual de comprensión para responder las preguntas anteriores.
Estoy agregando una etiqueta Rcpp
porque supongo que las respuestas a estas preguntas serán las más relevantes para los usuarios de Rcpp
, pero soy consciente de que esto probablemente no esté directamente relacionado con Rcpp
, por lo que la etiqueta podría eliminarse si se considera apropiado.
El archivo Makevars
, como se especifica en Escribir Extensiones R: 1.2.1 Usar Makevars , es una variante de Make
que es exclusiva de R. Muchas de las variables que ha enumerado se llaman variables implícitas . El significado se da como:
Las reglas implícitas indican cómo utilizar las técnicas habituales para que no tenga que especificarlas en detalle cuando desee usarlas.
Estas variables implícitas dictan qué compilador se debe usar y qué opciones están disponibles.
Dentro de R , nos preocupan las siguientes opciones de compilación predeterminadas:
Programa CC para compilar programas en C; por defecto ''cc''.
Programa CXX para compilar programas en C ++; por defecto ''g ++''.
Programa CPP para ejecutar el preprocesador C, con resultados a salida estándar; por defecto ''$ (CC) -E''.
Programa FC para compilar o preprocesar los programas Fortran y Ratfor; por defecto ''f77''.
El siguiente conjunto de valores detalla qué opciones debe usar el compilador. En general, los valores predeterminados para todas estas opciones son una cadena vacía.
CFLAGS Extra flags para dar al compilador de C.
CXXFLAGS Banderas extra para dar al compilador de C ++.
CPPFLAGS Indicadores adicionales para entregar al preprocesador de C y los programas que lo utilizan (los compiladores de C y Fortran).
FFLAGS Banderas extra para dar al compilador de Fortran.
LDFLAGS Banderas adicionales para dar a los compiladores cuando se supone que invocan el enlazador, ''ld'', como -L. Las bibliotecas (-lfoo) deben agregarse a la variable LDLIBS en su lugar.
LDLIBS Las banderas de la biblioteca o los nombres dados a los compiladores cuando deben invocar el enlazador, ''ld''. LOADLIBES es una alternativa en desuso (pero aún compatible) a LDLIBS. Los indicadores de vinculador que no son de biblioteca, como -L, deben ir en la variable LDFLAGS.
Ahora, R define variantes "adicionales" en términos de diferentes estándares ISO de C ++. Estas variantes se dan en la Administración R: Sección 2.7.2 Soporte C ++ y Administración R: Sección B.7 Compilación y carga de banderas
CXX98 CXX98STD CXX98FLAGS CXX98PICFLAGS
CXX11 CXX11STD CXX11FLAGS CXX11PICFLAGS
CXX14 CXX14STD CXX14FLAGS CXX14PICFLAGS
CXX17 CXX17STD CXX17FLAGS CXX17PICFLAGS
Dicho esto, abordemos la primera pregunta:
¿Cuál es la relación entre
CXX
yCXX98
,CXX11
yCXX14
?
CXX
es la opción de compilador general a usar. Mientras tanto, R define opciones de CXX
adicionales para usar dependiendo del estándar de compilación detectado. Es decir, si -std=c++98
(especificación de lenguaje CXX98
) establecido por CXX_STD
, entonces se usa el compilador asociado con CXX98
. Del mismo modo, para CXX11
y CXX14
, sigue la misma lógica. Vea la Galería de Rcpp: Uso de Rcpp con C ++ 11, C ++ 14 y C ++ 17 para más detalles.
¿Cuál es el significado de, por ejemplo,
CXX11STD = -std=c++11
si C ++ 11 ya está implícito? ¿Es entre elegir-std=c++11
y-std=gnu++11
? ¿Debe-std=gnu++11
generalmente-std=gnu++11
por razones de portabilidad?
El significado de CXX11STD
es determinar el estándar de lenguaje apropiado para la compilación de C ++ 11. Esta opción existe simplemente porque si la versión de R de seleccionar la opción de compilación de C ++ 11 apropiada es incorrecta para el compilador, puede cambiarla. La razón por la que esto existe es porque cada compilador puede definir el soporte de C ++ 11 de manera ligeramente diferente al siguiente, como se indica en Instalación y administración de R: 2.7.2 Soporte de C ++ :
Puede ser [Nota 13] que no haya un indicador adecuado para el soporte de C ++ 11, en cuyo caso podría seleccionarse un compilador diferente para CXX11 y sus indicadores correspondientes.
Nota 13:
Esto es cierto para las versiones anteriores de g ++, como 4.2.1, y también para las versiones de uso común del compilador CC de Solaris.
Para obtener detalles sobre los estándares de idioma aprobados por gcc, consulte el Manual de GCC: 3.4 Opciones que controlan el dialecto C. Además, para obtener detalles sobre el uso de C ++ 11 con R en un paquete, consulte Escritura de extensiones R: Sección 1.2.4 Uso del código C ++ 11 .
En general, evitaría establecer explícitamente esta variable. Si debe establecer esta variable explícitamente, recomendaría ir con -std=c++11
ya que la mayoría de los compiladores admiten esta declaración.
¿Es posible que las banderas para
CXXSTD
yCXXFLAGS
no se agreguen aCXX
, de manera que las tres primeras líneas se reduzcan aCXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer
? ¿Cuál es la ventaja de especificar explícitamenteCXXSTD
yCXXFLAGS
?
¿Es posible? Sí. ¿Es correcto? No.
¿Por qué tenemos tres variables cada una con su propio objetivo cuando podríamos simplemente tener una?
Las ventajas de un flujo de trabajo de tres variables proporcionan diferentes líneas, cada una con un rol distinto. Esto permite la capacidad de comprender rápidamente la opción de compilación. Por lo tanto, es mucho más sencillo de asimilar cuando se lo compara en una sola variable (con un ancho de terminal de 80).
p.ej
CXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer
vs
CXX = g++
CXX11STD = -std=c++11
CXXFLAGS = -fsanitize=undefined,address -fno-omit-frame-pointer
Además, debe optar por CXX_STD
sobre CXXSTD
al empaquetar, como se muestra en Escribir Extensiones R: Sección 1.2.4 Uso del Código C ++ 11 . Esto es simplemente para garantizar que R haya registrado el paquete como que requiere C ++ xy. La alternativa es escribir en el archivo de DESCRIPTION
el atributo SystemRequirements: C++xy
, donde xy
denota el año.
¿Cómo funciona
CXX_STD
=CXX11
? ¿Cómo se relacionaCXX11
aquí conCXX11
en ~ / .R / Makevars?
Esto establece la compilación y el enlace para el lenguaje que se realizará con el compilador C ++ 11 establecido por CXX11
. Al especificar CXX11
, está especificando una variable en Make
que se usará para compilar el archivo bajo la receta:
$(OBJCXX) $(ALL_CPPFLAGS) $(ALL_OBJCXXFLAGS) -c $< -o $@
donde $(OBJCXX)
es CXX
, $(ALL_CPPFLAGS)
viene dado por $(R_XTRA_CPPFLAGS) $(PKG_CPPFLAGS) $(CLINK_CPPFLAGS) $(CPPFLAGS)
, $(PKG_OBJCXXFLAGS) $(CXXPICFLAGS) $(SHLIB_CXXFLAGS) $(OBJCXXFLAGS)
.
Lo anterior sigue /R/Makeconf.in
. Sin embargo, la rutina puede ser /m4/R
¿Cuál es la relación entre
CXXFLAGS
yPKG_CXXFLAGS
(no incluido en mi ejemplo)?
Ambos especifican las banderas de compilación del compilador. El orden en que están escritos en los Makevars
es diferente. En particular, hemos colocado PKG_CXXFLAGS
después de PKG_CXXFLAGS
. Siempre se usa la opción más correcta . Entonces, CXXFLAGS
tiene prioridad sobre PKG_CXXFLAGS
.
Hay una breve nota sobre las opciones de PKG_*
en Writing R Extensions: Sección 5.5 Crear objetos compartidos .
Apéndice
Las siguientes son preguntas formuladas por @Dominik en la sección de comentarios de esta respuesta.
¿Es correcto que las variables definidas en
~/.R/Makevars
apliquen globalmente a la instalación de todos los paquetes, mientras que las variables en/src/Makevars
solo se apliquen al paquete actual?
Sí. Esto es preciso. Las variables dentro de ~/.R/Makevars
se aplicarán a todos los paquetes, mientras que /src/Makevars
que se envía con cada paquete solo influirá en la configuración de ese paquete. Los valores en /src/Makevars
tendrán prioridad sobre ~/.R/Makevars
.
Algunos paquetes pueden enviarse con /src/Makevars.win
, que proporciona un archivo Makevars
específicamente para el entorno de Windows.
¿El estándar de compilación utilizado para un paquete en la actualidad solo se establece a través de
CXX_STD
y no más porPKG_CXXFLAGS
como se muestra en gallery.rcpp.org/articles/simple-lambda-func-c++11?
Hay una ligera diferencia entre cuándo se deben usar estas dos banderas. En particular, CXX_STD
solo funciona en un entorno de paquete. Mientras tanto, a diferencia de su nombre, PKG_CXXFLAGS
, afecta a todas las opciones de compilación. Por lo tanto, cuando cita la publicación de la galería Rcpp anterior, está observando un script independiente que se está ejecutando. Para activar rápidamente el modo correcto, eso requiere establecer PKG_CXXFLAGS
y no la definición CXX_STD
.
Ahora, perdóneme por ir a una breve tangente en la historia de las opciones de compilación de uso independiente ... El uso de PKG_CXXFLAGS
es un poco anticuado. De hecho, el enfoque preferido en R 3.4 es establecer la variable de entorno USE_CXX11 = "yes"
. Entre R 3.1 y R 3.3, el estándar era establecer la variable de entorno USE_CXX1X = "yes"
. Antes de esos casos, se PKG_CXXFLAGS ="-std=c++11"
el uso de PKG_CXXFLAGS ="-std=c++11"
. (Excepto en Windows, que necesitaba PKG_CXXFLAGS ="-std=c++0x"
.)
¿
CXX_STD=CXX11
significa, entonces, usar todos los ajustes dados porCXX
,CXXSTD
,CXXFLAGS
yCXX11PICFLAGS
?
No. Esto significa usar las opciones establecidas por:
CXX11 CXX11STD CXX11FLAGS CXX11PICFLAGS