tutorial rccp r rcpp

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 y CXX98 , CXX11 y CXX14 ?
  • ¿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 y CXXFLAGS no se agreguen a CXX , de manera que las tres primeras líneas se reduzcan a CXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer ? ¿Cuál es la ventaja de especificar explícitamente CXXSTD y CXXFLAGS ?
  • ¿Cómo funciona CXX_STD = CXX11 ? ¿Cómo se relaciona CXX11 aquí con CXX11 en ~/.R/Makevars ?
  • ¿Cuál es la relación entre CXXFLAGS y PKG_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 y CXX98 , CXX11 y CXX14 ?

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 y CXXFLAGS no se agreguen a CXX , de manera que las tres primeras líneas se reduzcan a CXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer ? ¿Cuál es la ventaja de especificar explícitamente CXXSTD y CXXFLAGS ?

¿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 relaciona CXX11 aquí con CXX11 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 y PKG_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 por PKG_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 por CXX , CXXSTD , CXXFLAGS y CXX11PICFLAGS ?

No. Esto significa usar las opciones establecidas por:

CXX11 CXX11STD CXX11FLAGS CXX11PICFLAGS