web-dev-qa-db-fra.com

Comprendre le contenu du fichier Makevars dans R (macros, variables, ~ / .R / Makevars et pkg / src / Makevars)

J'essaie de comprendre le rôle et la relation des macros/variables définies dans ~/.R/Makevars Et package_directory/src/Makevars Lors de l'installation/de la création de packages R propres. Supposons que ces fichiers ressemblent à

~/.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

répertoire_package/src/Makevars

PKG_CPPFLAGS = -I../inst/include
CXX_STD = CXX11

Si je comprends bien, avec CXX, nous pouvons sélectionner le compilateur pour C++ lors de la construction de packages R; avec CXXSTD, nous avons choisi la norme et avec CXXFLAGS, nous ajoutons des indicateurs de compilation. Avec PKG_CPPFLAGS, Nous ajoutons des indicateurs pour le préprocesseur C++ et avec CXX_STD, Nous indiquons que nos paquets utilisent C++ 11.

J'ai les questions suivantes:

  • Quelle est la relation entre CXX et CXX98, CXX11 Et CXX14?
  • Quelle est la signification de, par exemple, CXX11STD = -std=c++11 Si C++ 11 est déjà impliqué? Est-ce entre choisir entre -std=c++11 Et -std=gnu++11? Faut-il généralement éviter -std=gnu++11 Pour des raisons de portabilité?
  • Les drapeaux pour CXXSTD et CXXFLAGS ne pourraient-ils pas simplement être ajoutés à CXX, de sorte que les trois premières lignes soient réduites à CXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer. Quel est l’avantage de spécifier explicitement CXXSTD et CXXFLAGS?
  • Comment fonctionne CXX_STD = CXX11? Comment CXX11 Est-il lié ici à CXX11 Dans ~/.R/Makevars?
  • Quelle est la relation entre CXXFLAGS et PKG_CXXFLAGS (Non inclus dans mon exemple)?

Je suis conscient des informations contenues dans Writing R Extensions et Installation et administration de R , mais je ne suis pas en mesure d'extraire plus d'informations que mon niveau de compréhension actuel pour répondre à la question ci-dessus. des questions.

J'ajoute une balise Rcpp parce que je suppose que les réponses à ces questions seront les plus pertinentes pour les utilisateurs de Rcpp, mais je suis conscient que ce n'est probablement pas directement lié à Rcpp, la balise peut donc être supprimée si cela est jugé approprié.

42
NoBackingDown

Le fichier Makevars, comme spécifié dans Writing R Extensions: 1.2.1 avec Makevars , est une variante de Make c'est-à-dire unique à R. Beaucoup des variables que vous avez énumérées s'appellent variables implicites . La signification est donnée comme:

Les règles implicites indiquent aux utilisateurs comment utiliser les techniques habituelles afin que vous n'ayez pas à les spécifier en détail lorsque vous souhaitez les utiliser.

Ces variables implicites dictent quoi le compilateur doit être utilisé et quoi les options sont disponibles.

Dans [~ # ~] r [~ # ~], nous nous soucions des options de compilation par défaut suivantes:

[~ # ~] cc [~ # ~] Programme de compilation de programmes C; "cc" par défaut.

[~ # ~] cxx [~ # ~] Programme de compilation de programmes C++. Par défaut, ‘g ++’.

[~ # ~] cpp [~ # ~] Programme permettant d'exécuter le préprocesseur C, avec les résultats obtenus en sortie standard. défaut '$ (CC) -E'.

[~ # ~] fc [~ # ~] Programme de compilation ou de prétraitement des programmes Fortran et Ratfor; "f77" par défaut.

Le prochain ensemble de valeurs details what les options devraient être utilisées par le compilateur. En général, les valeurs par défaut pour toutes ces options sont une chaîne vide.

[~ # ~] cflags [~ # ~] Drapeaux supplémentaires à donner au compilateur C.

[~ # ~] cxxflags [~ # ~] Drapeaux supplémentaires à donner au compilateur C++.

[~ # ~] cppflags [~ # ~] Drapeaux supplémentaires à donner au préprocesseur C et aux programmes qui l'utilisent (les compilateurs C et Fortran).

[~ # ~] fflags [~ # ~] Drapeaux supplémentaires à donner au compilateur Fortran.

[~ # ~] ldflags [~ # ~] Drapeaux supplémentaires à donner aux compilateurs lorsqu'ils sont censés appeler l'éditeur de liens, 'ld', tels que -L. Les bibliothèques (-lfoo) doivent plutôt être ajoutées à la variable LDLIBS.

[~ # ~] ldlibs [~ # ~] Drapeaux ou noms de bibliothèques donnés aux compilateurs lorsqu’ils sont supposés appeler l’éditeur de liens, "ld". LOADLIBES est une alternative obsolète (mais toujours prise en charge) à LDLIBS. Les indicateurs d'éditeur de liens autres que les bibliothèques, tels que -L, doivent figurer dans la variable LDFLAGS.

Maintenant, [~ # ~] r [~ # ~] définit des variantes "extra" en termes de différentes normes ISO C++. Ces variantes sont données dans les Administration R: Section 2.7.2 Support C++ et Administration R: Section B.7 Compiler et charger les indicateurs

CXX98 CXX98STD CXX98FLAGS CXX98PICFLAGS

CXX11 CXX11STD CXX11FLAGS CXX11PICFLAGS

CXX14 CXX14STD CXX14FLAGS CXX14PICFLAGS

CXX17 CXX17STD CXX17FLAGS CXX17PICFLAGS


Cela dit, abordons la première question:

Quelle est la relation entre CXX et _CXX98_, _CXX11_ et _CXX14_?

CXX est l'option générale du compilateur à utiliser. Pendant ce temps, [~ # ~] r [~ # ~] définit des options supplémentaires CXX à utiliser en fonction du standard de compilation détecté. En d’autres termes, si _-std=c++98_ (_CXX98_ spéc. Langage) est défini par _CXX_STD_, le compilateur associé à _CXX98_ est utilisé. De même, pour _CXX11_ et _CXX14_, la même logique suit. Voir Galerie Rcpp: Utiliser Rcpp avec C++ 11, C++ 14 et C++ 17 pour plus de détails.


Quelle est la signification de, par exemple, _CXX11STD = -std=c++11_ si C++ 11 est déjà impliqué? Est-ce entre choisir _-std=c++11_ et _-std=gnu++11_? Faut-il généralement éviter _-std=gnu++11_ pour des raisons de transférabilité?

La signification de _CXX11STD_ est de déterminer le standard de langage approprié pour la compilation C++ 11. Cette option existe simplement parce que si la version de [~ # ~] r [~ # ~] de la sélection de l'option de compilation C++ 11 appropriée est incorrecte pour le compilateur, vous pouvez la modifier. Cela s'explique par le fait que chaque compilateur peut définir le support C++ 11 légèrement différemment du suivant, comme indiqué dans Installation et administration de R: 2.7.2 Support C++ :

Il se peut que [Note 13] il n'existe pas d'indicateur approprié pour la prise en charge de C++ 11, auquel cas un compilateur différent pourrait être sélectionné pour CXX11 et les indicateurs correspondants.

Note de bas de page 13:

Cela est vrai pour les versions antérieures de g ++ telles que 4.2.1, ainsi que pour les versions couramment utilisées du compilateur Solaris CC.

Pour plus de détails sur les normes linguistiques approuvées par gcc, voir Manuel GCC: 3.4 Options Contrôle du dialecte C . De plus, pour plus de détails sur l’utilisation de C++ 11 avec [~ # ~] r [~ # ~] dans un paquet, voir Ecriture d’extensions R: Section 1.2.4, Utilisation de C + +11 Code .

En général, j'éviterais de définir explicitement cette variable. Si vous devez définir explicitement cette variable, je vous recommanderais d'utiliser _-std=c++11_, car la majorité des compilateurs prennent en charge cette déclaration.


Les indicateurs pour CXXSTD et CXXFLAGS ne seraient-ils pas simplement ajoutés à CXX, de sorte que les trois premières lignes soient réduites à _CXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer_. Quel est l'avantage de spécifier explicitement CXXSTD et CXXFLAGS?

C'est possible? Oui. Est ce juste? Non.

Pourquoi avoir trois des variables ayant chacune leur propre objectif alors que nous pourrions simplement n'en avoir qu'une?

Les avantages d'un flux de travaux variable trois fournissent à chaque ligne un rôle distinct. Cela permet de comprendre rapidement l’option de compilation. Ainsi, il est beaucoup plus simple de parler de grok que de le classer dans une seule variable sur une ligne (avec une largeur terminale de 80).

par exemple.

_CXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer
_

contre

_CXX = g++ 
CXX11STD = -std=c++11
CXXFLAGS = -fsanitize=undefined,address -fno-omit-frame-pointer
_

De plus, vous devriez opter pour _CXX_STD_ par rapport à CXXSTD lors du conditionnement, comme indiqué dans Writing R Extensions: Section 1.2.4 Utilisation du code C++ 11 . Il s’agit simplement de s’assurer que R a inscrit le package comme nécessitant C++ xy. L'alternative consiste à écrire dans le fichier DESCRIPTION l'attribut _SystemRequirements: C++xy_, où xy indique l'année.


Comment fonctionne _CXX_STD_ = _CXX11_? Comment _CXX11_ est-il lié ici à _CXX11_ dans ~/.R/Makevars?

Cela définit la compilation et la liaison du langage à effectuer avec le compilateur C++ 11 défini par _CXX11_. En spécifiant _CXX11_, vous spécifiez une variable dans Make qui sera utilisée pour compiler le fichier dans la recette:

_$(OBJCXX) $(ALL_CPPFLAGS) $(ALL_OBJCXXFLAGS) -c $< -o $@
_

$(OBJCXX) est CXX, $(ALL_CPPFLAGS) est donné par $(R_XTRA_CPPFLAGS) $(PKG_CPPFLAGS) $(CLINK_CPPFLAGS) $(CPPFLAGS) et $(ALL_OBJCXXFLAGS) a $(PKG_OBJCXXFLAGS) $(CXXPICFLAGS) $(SHLIB_CXXFLAGS) $(OBJCXXFLAGS) .

Ce qui précède suit _/R/Makeconf.in_ . Cependant, la routine peut être _/m4/R_ .


Quelle est la relation entre CXXFLAGS et _PKG_CXXFLAGS_ (non inclus dans mon exemple)?

Ces deux éléments spécifient les indicateurs de compilation du compilateur. L'ordre dans lequel ils sont écrits dans le Makevars est différent. En particulier, nous avons CXXFLAGS placé après _PKG_CXXFLAGS_ . L'option right la plupart des choix est toujours utilisée. Donc, CXXFLAGS a priorité sur _PKG_CXXFLAGS_.

Il existe une brève note sur les options _PKG_*_ dans Writing R Extensions: Section 5.5 Création d'objets partagés .

Addenda

Les questions suivantes ont été posées par @Dominik dans la section commentaires de cette réponse.


Est-il exact que les variables définies dans _~/.R/Makevars_ s'appliquent globalement à l'installation de tous les packages, alors que les variables dans _/src/Makevars_ s'appliquent uniquement au package actuel?

Oui. C'est exact Les variables comprises dans _~/.R/Makevars_ s'appliqueront à tous les packages, tandis que _/src/Makevars_ fourni avec chaque package n'influencera que les paramètres de ce package. Les valeurs dans _/src/Makevars_ auront priorité sur _~/.R/Makevars_.

Certains paquets peuvent être livrés avec _/src/Makevars.win_, qui fournit un fichier Makevars spécifiquement pour l'environnement Windows.


La norme de compilation utilisée pour les paquets est-elle actuellement définie uniquement par _CXX_STD_ et non plus par _PKG_CXXFLAGS_ comme indiqué dans gallery.rcpp.org/articles/simple-lambda-func-c++11?

Il y a une légère différence entre le moment où ces deux drapeaux doivent être utilisés. En particulier, _CXX_STD_ est uniquement opérationnel dans un environnement de package. Pendant ce temps, contrairement à son nom, _PKG_CXXFLAGS_ affecte toutes les options de compilation. Ainsi, lorsque vous citez le message de la galerie Rcpp ci-dessus, vous observez l'exécution d'un script autonome. Pour activer rapidement le mode correct, il faut que _PKG_CXXFLAGS_ soit défini et pas la définition de _CXX_STD_.

Maintenant, pardonnez-moi d’avoir une brève tangente sur l’histoire de utilisation autonome options de compilation .... L’utilisation de _PKG_CXXFLAGS_ est un peu ancienne école. En fait, l’approche privilégiée dans R 3.4 consiste à définir la variable d’environnement _USE_CXX11 = "yes"_. Entre R 3.1 et R 3.3, la norme consistait à définir la variable d'environnement _USE_CXX1X = "yes"_. Avant ces cas, l’utilisation de _PKG_CXXFLAGS ="-std=c++11"_ était préférée. (Sauf sous Windows, qui avait besoin de _PKG_CXXFLAGS ="-std=c++0x"_.)


Utiliser _CXX_STD=CXX11_ signifie-t-il alors utiliser tous les paramètres donnés par CXX, CXXSTD, CXXFLAGS et _CXX11PICFLAGS_?

Cela signifie utiliser les options définies par:

CXX11 CXX11STD CXX11FLAGS CXX11PICFLAGS

75
coatless