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:
CXX
et CXX98
, CXX11
Et CXX14
?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é?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
?CXX_STD = CXX11
? Comment CXX11
Est-il lié ici à CXX11
Dans ~/.R/Makevars
?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é.
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
etCXXFLAGS
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 explicitementCXXSTD
etCXXFLAGS
?
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 $@
_
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 .
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 parCXX
,CXXSTD
,CXXFLAGS
et _CXX11PICFLAGS
_?
Cela signifie utiliser les options définies par:
CXX11 CXX11STD CXX11FLAGS CXX11PICFLAGS