Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reload(): Unload dynamic libraries #119

Closed
wch opened this issue Jul 23, 2012 · 3 comments
Closed

reload(): Unload dynamic libraries #119

wch opened this issue Jul 23, 2012 · 3 comments

Comments

@wch
Copy link
Member

wch commented Jul 23, 2012

Presently, to unload and reload a compiled library during development, you can do this:

library.dynam.unload('c_test', '~/R-dev/c_test/')
install()

test_func()

It would be good to automate the unloading process by making reload() automatically do it. The dynLibs() function might be helpful for finding the path of the loaded library.

This should also be tested on Windows and Linux. According to ?dyn.load, unloading won't work on Solaris.

@wch
Copy link
Member Author

wch commented Jul 23, 2012

Normally, the dynamic library has the same name as the package, so this should work:

pkgname <- 'c_test'
pkgpath <- system.file(package=pkgname)
library.dynam.unload(pkgname, pkgpath)

But in case there are multiple libraries in that path, it might be better to search the .dynLibs() for all libraries that contain the pkgpath:

dynlib_paths <- vapply(.dynLibs(), function(x) x[["path"]], character(1))

# List all the libraries under that path
# Need to be careful since the string matches anywhere, not just at the beginning
dynlib_paths[grepl(pkgpath, dynlib_paths, fixed=TRUE)]

It appears that most packages have library files with the same name as the package. But there are some exceptions. A find in my library path turns up a few:

./data.table/libs/x86_64/datatable.so
./data.table/libs/x86_64/datatable.so.dSYM/Contents/Resources/DWARF/datatable.so
./rgl/libs/i386/aglrgl.so
./rgl/libs/i386/aglrgl.so.dSYM/Contents/Resources/DWARF/aglrgl.so
./rgl/libs/i386/rgl.so
./rgl/libs/i386/rgl.so.dSYM/Contents/Resources/DWARF/rgl.so
./rgl/libs/x86_64/aglrgl.so
./rgl/libs/x86_64/aglrgl.so.dSYM/Contents/Resources/DWARF/aglrgl.so
./rgl/libs/x86_64/rgl.so
./rgl/libs/x86_64/rgl.so.dSYM/Contents/Resources/DWARF/rgl.so

@wch
Copy link
Member Author

wch commented Jul 24, 2012

This code should unload all the loaded libraries from a given package:

library(bitops)
# Show what's loaded
.dynLibs()

pkgname <- 'bitops'
# Get installation path for the package
pkgpath <- system.file(package=pkgname)

# Get a vector of paths for all loaded libs
dynlib_paths <- vapply(.dynLibs(), function(x) x[["path"]], character(1))

# Find which of the lib paths start with pkgpath
pkgmatch <- pkgpath == substr(dynlib_paths, 1, nchar(pkgpath))

# Get matching lib paths and strip off leading path and extension (.so or .dll)
libnames <- sub("\\.[^\\.]*$", "", basename(dynlib_paths[pkgmatch]))

library.dynam.unload(libnames, pkgpath)

# Show what's loaded
.dynLibs()

# We can also unload the package
detach(paste("package", pkgname, sep =":"), character.only = TRUE, force = TRUE, unload = TRUE)

I tried experimenting with plyr, but it appears that it can't be unloaded because devtools depends on testthat, which depends on stringr, which depends on plyr.

Also, it appears that some packages are nice enough to have an .onUnload function that does it automatically:

> MASS:::.onUnload
function (libpath) 
library.dynam.unload("MASS", libpath)
<environment: namespace:MASS>

@wch
Copy link
Member Author

wch commented Aug 13, 2012

Implemented in #137.

@wch wch closed this as completed Aug 13, 2012
@lock lock bot locked and limited conversation to collaborators Sep 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant