Проверка пакета R: оптимизируйте способ создания и проверки библиотек DLL. - PullRequest
0 голосов
/ 04 октября 2018

Я хочу оптимизировать процесс сборки пакета.У меня в pckgname / src какой-то фортран-код (f90):

pckgname/src/FortranFile1.f90   
pckgname/src/FortranFile2.f90   

Я нахожусь под RStudio.Когда я собираю пакет, он создает папки src-i386 и src-x64, внутри которых создаются исполняемые файлы в .o

pckgname/src-i386/FortranFile1.o  
pckgname/src-i386/FortranFile2.o   
pckgname/src-x64/FortranFile1.o  
pckgname/src-x64/FortranFile2.o   

, затем в каждую из этих папок из .o создаются файлы dll.файлы:

pckgname/src-i386/dllname.dll
pckgname/src-x64/dllname.dll

после этого, если я хочу успешно проверить код, мне нужно вручную скопировать вставить dll в эти две папки (в предыдущей версии вопроса я написал код вместо dll, который может иметьпривело к недоразумениям)

pckgname/inst/libs/x64/dllname.dll
pckgname/libs/X64/dllname.dll  

Мой вопрос: это нормально, что я должен это сделать, или есть более короткий путь без необходимости копировать вручную вставить dllname.dll
в эти две папки?Это действительно может быть источником ошибки.

Примечание: если я не копирую dll в указанные папки, я получаю следующие сообщения об ошибках (в переводе с французского):

Error in inDL(x, as.logical(local), as.logical(now), ...) : 
impossible to load shared object 'C:/Users/username/Documents/pckgname/inst/libs/x64/dllname.dll':
LoadLibrary failure:  The specified module can't be found

Error in inDL(x, as.logical(local), as.logical(now), ...) : 
impossible to load shared object 'C:/Users/username/Documents/pckgname/libs/x64/dllname.dll':
LoadLibrary failure:  The specified module can't be found.
[...]
`cleanup` is deprecated 

Ответы [ 2 ]

0 голосов
/ 07 августа 2019

Нет, это не нормально, и есть решение этой проблемы.Используйте Makevars.win .Причиной вашей проблемы является то, что .dll ищут зависимости в местах, определенных переменной окружения PATH, и относительных путях, определенных во время компоновки.Связывание выполняется при запуске команды R CMD INSTALL, как указано в настройках Mingw плюс некоторые пользовательские параметры, определенные в файле Makevars.win (зависит от платформы Windows).Как только результирующая библиотека будет скопирована, привязка к местам, где находились зависимые .dll, может нарушиться, поэтому, если вы поместите dll в место, где обычно находятся зависимые библиотеки, например, $(R_HOME)/bin/$(ARCH)/,

cp -f <your library relative path>.dll $(R_HOME)/bin/$(ARCH)/<your library>.dll

во время проверки R тоже будет искать ваши зависимости, поэтому вы не пропустите эти зависимости.Очень грубое решение, но оно сработало в моем случае.

0 голосов
/ 04 октября 2018

Краткий ответ

Это нормально, что я должен это сделать?

Нет .Если path/to/package является каталогом, в котором вы разрабатываете свой пакет, и у вас все настроено для того, чтобы ваш пакет правильно вызывал подпрограммы на Фортране (см. «Длинный ответ»), вы можете запустить

R CMD build path/to/package

в командной строке, и для вас будет создан тарбол со всем в нужном месте (обратите внимание, вам понадобится Rtools для этого).Тогда вы сможете запустить

R CMD check packagename_versionnumber.tar.gz

из командной строки, чтобы проверить ваш пакет, без каких-либо проблем (вытекающих из того, что файлы .dll находятся в неправильном месте - у вас могут быть другие проблемы, вв этом случае я бы предложил задать новый вопрос с ошибкой, предупреждением или примечанием, перечисленными в вопросе).

Если вы предпочитаете работать только с R, вы можете даже

devtools::check("path/to/package")

без необходимости запускать devtools::build() или R CMD build ("devtools :: check () ... [b] отменяет пакет перед проверкой") - глава Хадли о проверке ; см. также Карл Броман глава о проверке ).

Длинный ответ

Я думаю, что ваш вопрос потенциально связан с тремя проблемами:

  1. Разница между каталогамиструктура пакетов до и после их установки.(Вы можете прочитать раздел «Что такое пакет?» Главы Структура пакета Хэдли - к счастью R CMD build в командной строке или devtools::build() в R позаботится об этом за вас)
  2. Использование INSTALL против BUILD (из комментариев к исходной версии этого ответа)
  3. Правильный способ настройки пакета для вызова подпрограмм Fortran.

Возможно, вам понадобится немало советов по процессу разработки пакетов R.Некоторые хорошие руководства включают (в порядке возрастания детализации):

  • Пакетный праймер Карла Бромана R
  • Пакеты Хэдли Уикхема R
  • Расширения Writing R manual

В частности, есть некоторые подробности о скомпилированном коде в пакете R, о которых вы, возможно, захотите знать.Возможно, вы захотите сначала прочитать главу Хэдли о скомпилированном коде (у Broman его нет), но затем вам действительно нужно прочитать большую часть руководства по Writing R Extensions, в частности разделы 1.1, 1.2, 1.5.4 и 1.6, и все главы 5 и 6.

Тем временем я настроил репозиторий GitHub здесь , который демонстрирует игрушечный пример пакета R FortranExample, который показываетКак правильно настроить пакет с кодом Fortran.Я предпринял следующие шаги:

  1. Создайте базовую структуру пакета, используя devtools::create("FortranExample").
  2. Удалите строку «Зависит» в DESCRIPTION, так как она устанавливает зависимость от R> = 3.5.1, который выдает предупреждение при проверке (теперь я также изменил поле «Лицензия», чтобы исключить предупреждение о том, что не указана правильная лицензия).
  3. Создайте каталог src/ и добавьтеТам есть код Fortran (он просто удваивает двойное значение).
  4. Используйте tools::package_native_routine_registration_skeleton("FortranExample"), чтобы сгенерировать код регистрации символа, который я поместил в src/init.c (см. Запись расширений R, раздел 5.4).
  5. Создайте красивую оболочку R для использования .Fortran() для вызова кода Фортрана (помещен в R/example_function.R).
  6. В этом же файле используйте тег #' @useDynLib FortranExample Roxygen для добавления useDynLib(FortranExample) к *Файл 1095 *;если вы не используете Roxygen, вы можете поместить его туда вручную (см. Writing R Extensions 1.5.4 и 5.2).

Теперь у нас есть пакет, который правильно настроен для работы с кодом Fortran,Я проверил на компьютере Windows (под управлением Windows 8.1 и R 3.5.1) как пути запуска

R CMD build FortranExample
R CMD check FortranExample_0.0.0.9000.tar.gz

из командной строки, так и запуска

devtools::check("FortranExample")

из RОшибок не было, и единственным предупреждением была упомянутая выше проблема «Лицензия».

После устранения последствий запуска devtools::check("FortranExample") (по какой-то причине опция cleanup устарела;см. ниже функцию R, чтобы справиться с этим для вас, вдохновленный devtools::clean_dll()), я использовал

devtools::install("FortranExample")

для успешной установки пакета и проверки его функции, получая:

FortranExample::example_function(2.0)
# [1] 4

Упомянутая мной функция очистки

clean_source_dirs <- function(path) {
    paths <- file.path(path, paste0("src", c("", "-i386", "-x64")))
    file_pattern <- "\\.o|so|dll|a|sl|dyl"
    unlink(list.files(path = paths, pattern = file_pattern, full.names = TRUE))
}
...