Ответ 1
Файл Makevars
, указанный в Написание R-расширений: 1.2.1 Использование Makevars, является вариантом Make
, который является уникальным для R. Многие из перечисленных вами переменных называются неявные переменные. Значение задается как:
Неявные правила говорят о том, как использовать обычные методы, чтобы вам не нужно было подробно их указывать, когда вы хотите их использовать.
Эти неявные переменные диктуйте, какой компилятор должен использоваться и какие варианты доступны.
Внутри R мы заботимся о следующих параметрах компилятора по умолчанию:
CC Программа для компиляции программ на C; default 'cc.
CXX Программа для компиляции программ на C++; default 'g++.
CPP Программа для запуска препроцессора C с результатами для стандартного вывода; default '$ (CC) -E.
FC Программа для компиляции или предварительной обработки программ Fortran и Ratfor; default 'f77.
Следующий набор значений указывает, какие параметры должны использоваться компилятором. В общем случае значения по умолчанию для всех этих параметров представляют собой пустую строку.
CFLAGS Дополнительные флаги для компилятора C.
CXXFLAGS Дополнительные флаги для компилятора С++.
CPPFLAGS Дополнительные флаги для предоставления препроцессору C и программам, которые его используют (компиляторы C и Fortran).
FFLAGS Дополнительные флаги для компилятора Fortran.
LDFLAGS Дополнительные флаги для компиляторов, когда они должны вызывать компоновщик ld, например -L. Библиотеки (-lfoo) следует добавить вместо переменной LDLIBS.
LDLIBS Флаги библиотеки или имена, присваиваемые компиляторам, когда они должны вызывать компоновщик, 'ld. LOADLIBES является устаревшим (но все еще поддерживается), альтернативной LDLIBS. Небиблиотечные флаги компоновки, такие как как -L, должен идти в переменной LDFLAGS.
Теперь R определяет "дополнительные" варианты в терминах различных стандартов С++ ISO. Эти варианты приведены в R Administration: Раздел 2.7.2 Поддержка С++ и R Администрирование: Раздел B.7 Компилировать и загружать флаги
CXX98 CXX98STD CXX98FLAGS CXX98PICFLAGS
CXX11 CXX11STD CXX11FLAGS CXX11PICFLAGS
CXX14 CXX14STD CXX14FLAGS CXX14PICFLAGS
CXX17 CXX17STD CXX17FLAGS CXX17PICFLAGS
Сказав это, давайте рассмотрим первый вопрос:
Какова связь между
CXX
иCXX98
,CXX11
иCXX14
?
CXX
- это общая опция компилятора. Между тем, R определяет дополнительные опции CXX
для использования в зависимости от установленного стандарта компиляции. То есть, если -std=c++98
(CXX98
спецификация языка), заданная CXX_STD
, тогда используется компилятор, связанный с CXX98
. Аналогично, для CXX11
и CXX14
следует следующая логика. Подробнее см. Галерея Rcpp: Использование Rcpp с С++ 11, С++ 14 и С++ 17.
В чем смысл, например,
CXX11STD = -std=c++11
, если С++ 11 уже подразумевается? Это между выбором-std=c++11
и-std=gnu++11
? Следует ли избегать-std=gnu++11
по причинам мобильности?
Значение CXX11STD
заключается в определении соответствующего языка для компиляции С++ 11. Этот параметр существует просто потому, что если версия R для выбора соответствующей компиляции С++ 11 неверна для компилятора, вы можете ее изменить. Причина этого заключается в том, что каждый компилятор может определить поддержку С++ 11 несколько иначе, чем следующую, как указано в R Установка и администрирование: 2.7.2 Поддержка С++:
Может быть [Сноска 13], что для поддержки С++ 11 нет подходящего флага, и в этом случае для CXX11 и соответствующих флагов может быть выбран другой компилятор.
Сноска 13:
Это справедливо для более ранних версий g++, таких как 4.2.1, а также для часто используемых версий компилятора Solaris CC.
Подробнее о языковых стандартах, одобренных gcc, см. Руководство GCC: 3.4 Опции Управление диалектом C. Кроме того, для получения подробной информации об использовании С++ 11 с R в пакете см. Написание R-расширений: Раздел 1.2.4 Использование кода С++ 11.
Как правило, я бы не стал явно устанавливать эту переменную. Если вы должны явно установить эту переменную, я бы рекомендовал перейти с -std=c++11
, поскольку большинство компиляторов поддерживают это объявление.
Могут ли флаги для
CXXSTD
иCXXFLAGS
не просто добавляться вCXX
, так что первые три строки уменьшаются доCXX = g++ -std=c++11 -fsanitize=undefined,address -fno-omit-frame-pointer
. В чем преимущество явного указанияCXXSTD
иCXXFLAGS
?
Возможно ли это? Да. Это правильно? Нет.
Почему есть три переменные, каждая из которых имеет свою собственную цель, когда мы просто можем ее использовать?
Преимущества трех переменных рабочего процесса предоставляют разные строки, каждая из которых имеет определенную роль. Это позволяет быстро понять вариант компиляции. Таким образом, гораздо более прямолинейно смотреть, сравнивая, что он переполнен одной переменной на одной линии (с шириной терминала 80).
например.
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
Кроме того, вы должны выбрать CXX_STD
над CXXSTD
при упаковке, как показано в Написание расширений R: Раздел 1.2.4 Использование кода С++ 11. Это просто, чтобы гарантировать, что R зарегистрировал пакет как требующий С++ xy. Альтернативой является запись в файле DESCRIPTION
атрибута SystemRequirements: C++xy
, где xy
обозначает год.
Как работает
CXX_STD
=CXX11
? КакCXX11
здесь связано сCXX11
в ~/.R/Makevars?
Это устанавливает компиляцию и привязку для языка, который должен быть выполнен с помощью компилятора С++ 11, установленного CXX11
. Задав CXX11
, вы указываете переменную в Make
, которая будет использоваться для компиляции файла по рецепту:
$(OBJCXX) $(ALL_CPPFLAGS) $(ALL_OBJCXXFLAGS) -c $< -o [email protected]
где $(OBJCXX)
CXX
, $(ALL_CPPFLAGS)
задается $(R_XTRA_CPPFLAGS) $(PKG_CPPFLAGS) $(CLINK_CPPFLAGS) $(CPPFLAGS)
, а $(ALL_OBJCXXFLAGS)
имеет $(PKG_OBJCXXFLAGS) $(CXXPICFLAGS) $(SHLIB_CXXFLAGS) $(OBJCXXFLAGS)
.
Вышеизложенное следует /R/Makeconf.in
. Однако процедура может быть /m4/R
.
Какова связь между
CXXFLAGS
иPKG_CXXFLAGS
(не включена в мой пример)?
Оба они задают флаги компиляции компилятора. Порядок, в котором они записаны в Makevars
, отличается. В частности, мы имеем
CXXFLAGS
размещен после PKG_CXXFLAGS
. Всегда используется самый правильный вариант. Итак, CXXFLAGS
имеет приоритет над PKG_CXXFLAGS
.
В в Написание расширений R: раздел 5.5 Создание общих объектов.
Добавление
Ниже приведены вопросы, заданные @Dominik в разделе комментариев этого ответа.
Правильно ли, что переменные, определенные в
~/.R/Makevars
, применимы глобально к установке всех пакетов, а переменные в/src/Makevars
применимы только к данному пакету?
Да. Это точно. Переменные внутри ~/.R/Makevars
будут применяться ко всем пакетам, тогда как /src/Makevars
, который поставляется с каждым пакетом, будет влиять только на настройки для этого пакета. Значения в /src/Makevars
будут иметь приоритет над ~/.R/Makevars
.
Некоторые пакеты могут поставляться с /src/Makevars.win
, который предоставляет файл Makevars
специально для среды Windows.
Является ли стандарт компиляции для пакетов в настоящее время установленным только через
CXX_STD
и не более чем наPKG_CXXFLAGS
, как показано в gallery.rcpp.org/articles/simple-lambda-func-c++11?
Существует небольшое различие между этими двумя флагами. В частности, CXX_STD
работает только в среде пакета. Между тем, вопреки его имени, PKG_CXXFLAGS
, влияет на все параметры компиляции. Таким образом, при цитировании вышеупомянутого сообщения галереи Rcpp вы выполняете автономный запуск script. Чтобы быстро включить правильный режим, для которого требуется 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"
.)
Используется ли
CXX_STD=CXX11
для использования всех настроек, заданныхCXX
,CXXSTD
,CXXFLAGS
иCXX11PICFLAGS
?
Нет. Это означает использование опций, установленных:
CXX11 CXX11STD CXX11FLAGS CXX11PICFLAGS