in source/src/library/tools/R/install.R [439:1233]
do_install_source <- function(pkg_name, instdir, pkg_dir, desc)
{
Sys.setenv("R_INSTALL_PKG" = pkg_name)
on.exit(Sys.unsetenv("R_INSTALL_PKG"))
shlib_install <- function(instdir, arch)
{
## install.libs.R allows customization of the libs installation process
if (file.exists("install.libs.R")) {
message("installing via 'install.libs.R' to ", instdir,
domain = NA)
## the following variables are defined to be available,
## and to prevent abuse we don't expose anything else
local.env <- local({ SHLIB_EXT <- SHLIB_EXT
R_PACKAGE_DIR <- instdir
R_PACKAGE_NAME <- pkg_name
R_PACKAGE_SOURCE <- pkg_dir
R_ARCH <- arch
WINDOWS <- WINDOWS
environment()})
parent.env(local.env) <- .GlobalEnv
source("install.libs.R", local = local.env)
return(TRUE)
}
## otherwise proceed with the default which is to just copy *${SHLIB_EXT}
files <- Sys.glob(paste0("*", SHLIB_EXT))
if (length(files)) {
libarch <- if (nzchar(arch)) paste0("libs", arch) else "libs"
dest <- file.path(instdir, libarch)
message('installing to ', dest, domain = NA)
dir.create(dest, recursive = TRUE, showWarnings = FALSE)
file.copy(files, dest, overwrite = TRUE)
## not clear if this is still necessary, but sh version did so
if (!WINDOWS)
Sys.chmod(file.path(dest, files), dmode)
## macOS does not keep debugging symbols in binaries
## anymore so optionally we can create dSYMs. This is
## important since we will blow away .o files so there
## is no way to create it later.
if (dsym && startsWith(R.version$os, "darwin")) {
message(gettextf("generating debug symbols (%s)", "dSYM"),
domain = NA)
dylib <- Sys.glob(paste0(dest, "/*", SHLIB_EXT))
for (file in dylib) system(paste0("dsymutil ", file))
}
if(config_val_to_logical(Sys.getenv("_R_SHLIB_BUILD_OBJECTS_SYMBOL_TABLES_",
"TRUE"))
&& file_test("-f", "symbols.rds")) {
file.copy("symbols.rds", dest)
}
}
}
## This is only called for Makevars[.win], so assume it
## does create a shlib: not so reliably reported on Windows
## Note though that it may not create pkg_name.dll, and
## graph does not.
run_shlib <- function(pkg_name, srcs, instdir, arch)
{
args <- c(shargs, "-o", paste0(pkg_name, SHLIB_EXT), srcs)
if (WINDOWS && debug) args <- c(args, "--debug")
if (debug) message("about to run ",
"R CMD SHLIB ", paste(args, collapse = " "),
domain = NA)
if (.shlib_internal(args) == 0L) {
if(WINDOWS && !file.exists("install.libs.R")
&& !length(Sys.glob("*.dll"))) {
message("no DLL was created")
return(TRUE)
}
shlib_install(instdir, arch)
return(FALSE)
} else return(TRUE)
}
## Make the destination directories available to the developer's
## installation scripts (e.g. configure)
Sys.setenv(R_LIBRARY_DIR = lib)
if (nzchar(lib0)) {
## FIXME: is this needed?
## set R_LIBS to include the current installation directory
rlibs <- Sys.getenv("R_LIBS")
rlibs <- if (nzchar(rlibs)) paste(lib, rlibs, sep = .Platform$path.sep) else lib
Sys.setenv(R_LIBS = rlibs)
## This is needed
.libPaths(c(lib, .libPaths()))
}
Type <- desc["Type"]
if (!is.na(Type) && Type == "Frontend") {
if (WINDOWS) errmsg("'Frontend' packages are Unix-only")
starsmsg(stars, "installing *Frontend* package ", sQuote(pkg_name), " ...")
if (preclean) system(paste(MAKE, "clean"))
if (use_configure) {
if (file_test("-x", "configure")) {
res <- system(paste(paste(configure_vars, collapse = " "),
"./configure",
paste(configure_args, collapse = " ")))
if (res) pkgerrmsg("configuration failed", pkg_name)
} else if (file.exists("configure"))
errmsg("'configure' exists but is not executable -- see the 'R Installation and Administration Manual'")
}
if (file.exists("Makefile"))
if (system(MAKE)) pkgerrmsg("make failed", pkg_name)
if (clean) system(paste(MAKE, "clean"))
return()
}
if (!is.na(Type) && Type == "Translation")
errmsg("'Translation' packages are defunct")
OS_type <- desc["OS_type"]
if (WINDOWS) {
if ((!is.na(OS_type) && OS_type == "unix") && !fake)
errmsg(" Unix-only package")
} else {
if ((!is.na(OS_type) && OS_type == "windows") && !fake)
errmsg(" Windows-only package")
}
if(group.writable) { ## group-write modes if requested:
fmode <- "664"
dmode <- "775"
} else {
fmode <- "644"
dmode <- "755"
}
## At this point we check that we have the dependencies we need.
## We cannot use installed.packages() as other installs might be
## going on in parallel
pkgInfo <- .split_description(.read_description("DESCRIPTION"))
pkgs <- unique(c(names(pkgInfo$Depends), names(pkgInfo$Imports),
names(pkgInfo$LinkingTo)))
if (length(pkgs)) {
miss <- character()
for (pkg in pkgs) {
if(!length(find.package(pkg, quiet = TRUE)))
miss <- c(miss, pkg)
}
if (length(miss) > 1)
pkgerrmsg(sprintf("dependencies %s are not available",
paste(sQuote(miss), collapse = ", ")),
pkg_name)
else if (length(miss))
pkgerrmsg(sprintf("dependency %s is not available",
sQuote(miss)), pkg_name)
}
starsmsg(stars, "installing *source* package ",
sQuote(pkg_name), " ...")
stars <- "**"
res <- checkMD5sums(pkg_name, getwd())
if(!is.na(res) && res) {
starsmsg(stars,
gettextf("package %s successfully unpacked and MD5 sums checked",
sQuote(pkg_name)))
}
if (file.exists(file.path(instdir, "DESCRIPTION"))) {
## Back up a previous version
if (nzchar(lockdir)) {
if (debug) starsmsg(stars, "backing up earlier installation")
if(WINDOWS) {
file.copy(instdir, lockdir, recursive = TRUE,
copy.date = TRUE)
if (more_than_libs) unlink(instdir, recursive = TRUE)
} else if (more_than_libs)
system(paste("mv", shQuote(instdir),
shQuote(file.path(lockdir, pkg_name))))
else
file.copy(instdir, lockdir, recursive = TRUE,
copy.date = TRUE)
} else if (more_than_libs) unlink(instdir, recursive = TRUE)
dir.create(instdir, recursive = TRUE, showWarnings = FALSE)
}
if (preclean) run_clean()
if (use_configure) {
if (WINDOWS) {
if (file.exists("configure.win")) {
res <- system("sh ./configure.win")
if (res) pkgerrmsg("configuration failed", pkg_name)
} else if (file.exists("configure"))
message("\n",
" **********************************************\n",
" WARNING: this package has a configure script\n",
" It probably needs manual configuration\n",
" **********************************************\n\n", domain = NA)
} else {
## FIXME: should these be quoted?
if (file_test("-x", "configure")) {
cmd <- paste(paste(configure_vars, collapse = " "),
"./configure",
paste(configure_args, collapse = " "))
if (debug) message("configure command: ", sQuote(cmd),
domain = NA)
## in case the configure script calls SHLIB (some do)
cmd <- paste("_R_SHLIB_BUILD_OBJECTS_SYMBOL_TABLES_=false",
cmd)
res <- system(cmd)
if (res) pkgerrmsg("configuration failed", pkg_name)
} else if (file.exists("configure"))
errmsg("'configure' exists but is not executable -- see the 'R Installation and Administration Manual'")
}
}
if (more_than_libs) {
for (f in c("NAMESPACE", "LICENSE", "LICENCE", "NEWS", "NEWS.md"))
if (file.exists(f)) {
file.copy(f, instdir, TRUE)
Sys.chmod(file.path(instdir, f), fmode)
}
res <- try(.install_package_description('.', instdir, built_stamp))
if (inherits(res, "try-error"))
pkgerrmsg("installing package DESCRIPTION failed", pkg_name)
if (!file.exists(namespace <- file.path(instdir, "NAMESPACE")) ) {
if(dir.exists("R"))
errmsg("a 'NAMESPACE' file is required")
else writeLines("## package without R code", namespace)
}
}
if (install_libs && dir.exists("src") &&
length(dir("src", all.files = TRUE) > 2L)) {
starsmsg(stars, "libs")
if (!file.exists(file.path(R.home("include"), "R.h")))
## maybe even an error? But installing Fortran-based packages should work
warning("R include directory is empty -- perhaps need to install R-devel.rpm or similar", call. = FALSE)
has_error <- FALSE
linkTo <- pkgInfo$LinkingTo
if (!is.null(linkTo)) {
lpkgs <- sapply(linkTo, function(x) x[[1L]])
## we checked that these were all available earlier,
## but be cautious in case this changed.
paths <- find.package(lpkgs, quiet = TRUE)
bpaths <- basename(paths)
if (length(paths)) {
## check any version requirements
have_vers <-
(lengths(linkTo) > 1L) & lpkgs %in% bpaths
for (z in linkTo[have_vers]) {
p <- z[[1L]]
path <- paths[bpaths %in% p]
current <- readRDS(file.path(path, "Meta", "package.rds"))$DESCRIPTION["Version"]
target <- as.numeric_version(z$version)
if (!do.call(z$op, list(as.numeric_version(current), target)))
stop(gettextf("package %s %s was found, but %s %s is required by %s",
sQuote(p), current, z$op,
target, sQuote(pkgname)),
call. = FALSE, domain = NA)
}
clink_cppflags <- paste(paste0('-I"', paths, '/include"'),
collapse = " ")
Sys.setenv(CLINK_CPPFLAGS = clink_cppflags)
}
} else clink_cppflags <- ""
libdir <- file.path(instdir, paste0("libs", rarch))
dir.create(libdir, showWarnings = FALSE)
if (WINDOWS) {
owd <- setwd("src")
makefiles <- character()
if (!is.na(f <- Sys.getenv("R_MAKEVARS_USER",
NA_character_))) {
if (file.exists(f)) makefiles <- f
} else if (file.exists(f <- path.expand("~/.R/Makevars.win")))
makefiles <- f
else if (file.exists(f <- path.expand("~/.R/Makevars")))
makefiles <- f
if (file.exists("Makefile.win")) {
makefiles <- c("Makefile.win", makefiles)
message(" running 'src/Makefile.win' ...", domain = NA)
res <- system(paste("make --no-print-directory",
paste("-f", shQuote(makefiles), collapse = " ")))
if (res == 0) shlib_install(instdir, rarch)
else has_error <- TRUE
} else { ## no src/Makefile.win
srcs <- dir(pattern = "\\.([cfmM]|cc|cpp|f90|f95|mm)$",
all.files = TRUE)
archs <- if (!force_both && !grepl(" x64 ", utils::win.version()))
"i386"
else {
## see what is installed
## NB, not R.home("bin")
f <- dir(file.path(R.home(), "bin"))
f[f %in% c("i386", "x64")]
}
one_only <- !multiarch
if(!one_only && file.exists("../configure.win")) {
## for now, hardcode some exceptions
## These are packages which have arch-independent
## code in configure.win
if(!pkg_name %in% c("AnalyzeFMRI", "CORElearn",
"PearsonDS", "PKI", "RGtk2",
"RNetCDF", "RODBC", "RSclient",
"Rcpp", "Runuran", "SQLiteMap",
"XML", "arulesSequences",
"cairoDevice", "diversitree",
"foreign", "fastICA", "glmnet",
"gstat", "igraph", "jpeg", "png",
"proj4", "randtoolbox", "rgdal",
"rngWELL", "rphast", "rtfbs",
"sparsenet", "tcltk2", "tiff",
"udunits2"))
one_only <- sum(nchar(readLines("../configure.win", warn = FALSE), "bytes")) > 0
if(one_only && !force_biarch) {
if(parse_description_field(desc, "Biarch", FALSE))
force_biarch <- TRUE
else
warning("this package has a non-empty 'configure.win' file,\nso building only the main architecture\n", call. = FALSE, domain = NA)
}
}
if(force_biarch) one_only <- FALSE
if(one_only || length(archs) < 2L)
has_error <- run_shlib(pkg_name, srcs, instdir, rarch)
else {
setwd(owd)
test_archs <- archs
for(arch in archs) {
message("", domain = NA) # a blank line
starsmsg("***", "arch - ", arch)
ss <- paste("src", arch, sep = "-")
dir.create(ss, showWarnings = FALSE)
file.copy(Sys.glob("src/*"), ss, recursive = TRUE)
## avoid read-only files/dir such as nested .svn
.Call(dirchmod, ss, group.writable)
setwd(ss)
ra <- paste0("/", arch)
Sys.setenv(R_ARCH = ra, R_ARCH_BIN = ra)
has_error <- run_shlib(pkg_name, srcs, instdir, ra)
setwd(owd)
if (has_error) break
}
}
}
setwd(owd)
} else { # not WINDOWS
if (file.exists("src/Makefile")) {
arch <- substr(rarch, 2, 1000)
starsmsg(stars, "arch - ", arch)
owd <- setwd("src")
system_makefile <-
file.path(R.home(), paste0("etc", rarch), "Makeconf")
makefiles <- c(system_makefile,
makevars_site(),
"Makefile",
makevars_user())
res <- system(paste(MAKE,
paste("-f", shQuote(makefiles), collapse = " ")))
if (res == 0) shlib_install(instdir, rarch)
else has_error <- TRUE
setwd(owd)
} else { ## no src/Makefile
owd <- setwd("src")
srcs <- dir(pattern = "\\.([cfmM]|cc|cpp|f90|f95|mm)$",
all.files = TRUE)
## This allows Makevars to set OBJECTS or its own targets.
allfiles <- if (file.exists("Makevars")) c("Makevars", srcs) else srcs
wd2 <- setwd(file.path(R.home("bin"), "exec"))
archs <- Sys.glob("*")
setwd(wd2)
if (length(allfiles)) {
## if there is a configure script we install only the main
## sub-architecture
if (!multiarch || length(archs) <= 1 ||
file_test("-x", "../configure")) {
if (nzchar(rarch))
starsmsg("***", "arch - ",
substr(rarch, 2, 1000))
has_error <- run_shlib(pkg_name, srcs, instdir, rarch)
} else {
setwd(owd)
test_archs <- archs
for(arch in archs) {
if (arch == "R") {
## top-level, so one arch without subdirs
has_error <- run_shlib(pkg_name, srcs, instdir, "")
} else {
starsmsg("***", "arch - ", arch)
ss <- paste("src", arch, sep = "-")
dir.create(ss, showWarnings = FALSE)
file.copy(Sys.glob("src/*"), ss, recursive = TRUE)
setwd(ss)
ra <- paste0("/", arch)
## FIXME: do this lower down
Sys.setenv(R_ARCH = ra)
has_error <- run_shlib(pkg_name, srcs, instdir, ra)
Sys.setenv(R_ARCH = rarch)
setwd(owd)
if (has_error) break
}
}
}
} else warning("no source files found", call. = FALSE)
}
setwd(owd)
}
if (has_error)
pkgerrmsg("compilation failed", pkg_name)
## if we have subarchs, update DESCRIPTION
fi <- file.info(Sys.glob(file.path(instdir, "libs", "*")))
dirs <- basename(row.names(fi[fi$isdir %in% TRUE, ]))
## avoid DLLs installed by rogue packages
if(WINDOWS) dirs <- dirs[dirs %in% c("i386", "x64")]
if (length(dirs)) {
descfile <- file.path(instdir, "DESCRIPTION")
olddesc <- readLines(descfile, warn = FALSE)
olddesc <- grep("^Archs:", olddesc,
invert = TRUE, value = TRUE, useBytes = TRUE)
newdesc <- c(olddesc,
paste("Archs:", paste(dirs, collapse = ", "))
)
writeLines(newdesc, descfile, useBytes = TRUE)
}
} else if (multiarch) { # end of src dir
if (WINDOWS) {
wd2 <- setwd(file.path(R.home(), "bin")) # not R.home("bin")
archs <- Sys.glob("*")
setwd(wd2)
test_archs <- archs[archs %in% c("i386", "x64")]
} else {
wd2 <- setwd(file.path(R.home("bin"), "exec"))
test_archs <- Sys.glob("*")
setwd(wd2)
}
}
if (WINDOWS && "x64" %in% test_archs) {
## we cannot actually test x64 unless this is 64-bit
## Windows, even if it is installed.
if (!grepl(" x64 ", utils::win.version())) test_archs <- "i386"
}
## R files must start with a letter
if (install_R && dir.exists("R") && length(dir("R"))) {
starsmsg(stars, "R")
dir.create(file.path(instdir, "R"), recursive = TRUE,
showWarnings = FALSE)
## This cannot be done in a C locale
res <- try(.install_package_code_files(".", instdir))
if (inherits(res, "try-error"))
pkgerrmsg("unable to collate and parse R files", pkg_name)
if (file.exists(f <- file.path("R", "sysdata.rda"))) {
comp <- TRUE
## (We set .libPaths)
if(!is.na(lazycompress <- desc["SysDataCompression"])) {
comp <- switch(lazycompress,
"none" = FALSE,
"gzip" = TRUE,
"bzip2" = 2L,
"xz" = 3L,
TRUE) # default to gzip
} else if(file.size(f) > 1e6) comp <- 3L # "xz"
res <- try(sysdata2LazyLoadDB(f, file.path(instdir, "R"),
compress = comp))
if (inherits(res, "try-error"))
pkgerrmsg("unable to build sysdata DB", pkg_name)
}
if (fake) {
## Fix up hook functions so they do not attempt to
## (un)load missing compiled code, initialize ...
## This does stop them being tested at all.
if (file.exists("NAMESPACE")) {
cat("",
'.onLoad <- .onAttach <- function(lib, pkg) NULL',
'.onUnload <- function(libpaths) NULL',
sep = "\n",
file = file.path(instdir, "R", pkg_name), append = TRUE)
## <NOTE>
## Tweak fake installation to provide an 'empty'
## useDynLib() for the time being. Completely
## removing the directive results in checkFF()
## being too aggresive in the case where the
## presence of the directive enables unambiguous
## symbol resolution w/out 'PACKAGE' arguments.
## However, empty directives are not really meant
## to work ...
## encoding issues ... so need useBytes = TRUE
## FIXME: some packages have useDynLib()
## spread over several lines.
writeLines(sub("useDynLib.*", 'useDynLib("")',
readLines("NAMESPACE", warn = FALSE),
perl = TRUE, useBytes = TRUE),
file.path(instdir, "NAMESPACE"))
## </NOTE>
} else {
cat("",
'.onLoad <- function (libname, pkgname) NULL',
'.onAttach <- function (libname, pkgname) NULL',
'.onDetach <- function(libpath) NULL',
'.onUnload <- function(libpath) NULL',
'.Last.lib <- function(libpath) NULL',
sep = "\n",
file = file.path(instdir, "R", pkg_name), append = TRUE)
}
}
} # end of R
## data files must not be hidden: data() may ignore them
if (install_data && dir.exists("data") && length(dir("data"))) {
starsmsg(stars, "data")
files <- Sys.glob(file.path("data", "*")) # ignores dotfiles
if (length(files)) {
is <- file.path(instdir, "data")
dir.create(is, recursive = TRUE, showWarnings = FALSE)
file.remove(Sys.glob(file.path(instdir, "data", "*")))
file.copy(files, is, TRUE)
thislazy <- parse_description_field(desc, "LazyData",
default = lazy_data)
if (!thislazy && resave_data) {
paths <- Sys.glob(c(file.path(is, "*.rda"),
file.path(is, "*.RData")))
if (pkg_name == "cyclones")
paths <-
c(paths, Sys.glob(file.path(is, "*.Rdata")))
if (length(paths)) {
starsmsg(paste0(stars, "*"), "resaving rda files")
resaveRdaFiles(paths, compress = "auto")
}
}
Sys.chmod(Sys.glob(file.path(instdir, "data", "*")), fmode)
if (thislazy) {
starsmsg(paste0(stars, "*"),
"moving datasets to lazyload DB")
## 'it is possible that data in a package will
## make use of the code in the package, so ensure
## the package we have just installed is on the
## library path.'
## (We set .libPaths)
lazycompress <- desc["LazyDataCompression"]
if(!is.na(lazycompress))
data_compress <- switch(lazycompress,
"none" = FALSE,
"gzip" = TRUE,
"bzip2" = 2L,
"xz" = 3L,
TRUE) # default to gzip
res <- try(data2LazyLoadDB(pkg_name, lib,
compress = data_compress))
if (inherits(res, "try-error"))
pkgerrmsg("lazydata failed", pkg_name)
}
} else warning("empty 'data' directory", call. = FALSE)
}
## demos must start with a letter
if (install_demo && dir.exists("demo") && length(dir("demo"))) {
starsmsg(stars, "demo")
dir.create(file.path(instdir, "demo"), recursive = TRUE,
showWarnings = FALSE)
file.remove(Sys.glob(file.path(instdir, "demo", "*")))
res <- try(.install_package_demos(".", instdir))
if (inherits(res, "try-error"))
pkgerrmsg("ERROR: installing demos failed")
Sys.chmod(Sys.glob(file.path(instdir, "demo", "*")), fmode)
}
## dotnames are ignored.
if (install_exec && dir.exists("exec") && length(dir("exec"))) {
starsmsg(stars, "exec")
dir.create(file.path(instdir, "exec"), recursive = TRUE,
showWarnings = FALSE)
file.remove(Sys.glob(file.path(instdir, "exec", "*")))
files <- Sys.glob(file.path("exec", "*"))
if (length(files)) {
file.copy(files, file.path(instdir, "exec"), TRUE)
if (!WINDOWS)
Sys.chmod(Sys.glob(file.path(instdir, "exec", "*")), dmode)
}
}
if (install_inst && dir.exists("inst") &&
length(dir("inst", all.files = TRUE)) > 2L) {
starsmsg(stars, "inst")
i_dirs <- list.dirs("inst")[-1L] # not inst itself
i_dirs <- grep(.vc_dir_names_re, i_dirs,
invert = TRUE, value = TRUE)
## This ignores any restrictive permissions in the source
## tree, since the later .Call(dirchmod) call will
## fix the permissions.
## handle .Rinstignore:
ignore_file <- ".Rinstignore"
ignore <- if (file.exists(ignore_file)) {
ignore <- readLines(ignore_file, warn = FALSE)
ignore[nzchar(ignore)]
} else character()
for(e in ignore)
i_dirs <- grep(e, i_dirs, perl = TRUE, invert = TRUE,
value = TRUE, ignore.case = TRUE)
lapply(gsub("^inst", instdir, i_dirs),
function(p) dir.create(p, FALSE, TRUE)) # be paranoid
i_files <- list.files("inst", all.files = TRUE,
full.names = TRUE, recursive = TRUE)
i_files <- grep(.vc_dir_names_re, i_files,
invert = TRUE, value = TRUE)
for(e in ignore)
i_files <- grep(e, i_files, perl = TRUE, invert = TRUE,
value = TRUE, ignore.case = TRUE)
i_files <- i_files[!i_files %in%
c("inst/doc/Rplots.pdf", "inst/doc/Rplots.ps")]
i_files <- grep("inst/doc/.*[.](log|aux|bbl|blg|dvi)$",
i_files, perl = TRUE, invert = TRUE,
value = TRUE, ignore.case = TRUE)
## Temporary kludge
if (!dir.exists("vignettes") && ! pkgname %in% c("RCurl"))
i_files <- grep("inst/doc/.*[.](png|jpg|jpeg|gif|ps|eps)$",
i_files, perl = TRUE, invert = TRUE,
value = TRUE, ignore.case = TRUE)
i_files <- i_files[! i_files %in% "Makefile"]
i2_files <- gsub("^inst", instdir, i_files)
file.copy(i_files, i2_files)
if (!WINDOWS) {
## make executable if the source file was (for owner)
modes <- file.mode(i_files)
execs <- as.logical(modes & as.octmode("100"))
Sys.chmod(i2_files[execs], dmode)
}
if (compact_docs) {
pdfs <- dir(file.path(instdir, "doc"), pattern="\\.pdf",
recursive = TRUE, full.names = TRUE,
all.files = TRUE)
res <- compactPDF(pdfs, gs_quality = "none")
## print selectively
print(res[res$old > 1e5, ])
}
}
if (install_tests && dir.exists("tests") &&
length(dir("tests", all.files = TRUE) > 2L)) {
starsmsg(stars, "tests")
file.copy("tests", instdir, recursive = TRUE)
}
## LazyLoading/Compiling
if (install_R && dir.exists("R") && length(dir("R"))) {
BC <- if (!is.na(byte_compile)) byte_compile
else
parse_description_field(desc, "ByteCompile", default = FALSE)
rcps <- Sys.getenv("R_COMPILE_PKGS")
rcp <- switch(rcps,
"TRUE"=, "true"=, "True"=, "yes"=, "Yes"= 1,
"FALSE"=,"false"=,"False"=, "no"=, "No" = 0,
as.numeric(rcps)
)
BC <- BC || (!is.na(rcp) && rcp > 0)
if (BC) {
starsmsg(stars,
"byte-compile and prepare package for lazy loading")
## need to disable JIT
Sys.setenv(R_ENABLE_JIT = 0L)
compiler::compilePKGS(1L)
compiler::setCompilerOptions(suppressUndefined = TRUE)
} else
starsmsg(stars, "preparing package for lazy loading")
keep.source <-
parse_description_field(desc, "KeepSource",
default = keep.source)
## Something above, e.g. lazydata, might have loaded the namespace
if (isNamespaceLoaded(pkg_name))
unloadNamespace(pkg_name)
deps_only <-
config_val_to_logical(Sys.getenv("_R_CHECK_INSTALL_DEPENDS_", "FALSE"))
if(deps_only) {
env <- setRlibs(LinkingTo = TRUE)
libs0 <- .libPaths()
env <- sub("^.*=", "", env[1L])
.libPaths(c(lib0, env))
} else libs0 <- NULL
res <- try({
suppressPackageStartupMessages(.getRequiredPackages(quietly = TRUE))
makeLazyLoading(pkg_name, lib, keep.source = keep.source)
})
if (BC) compiler::compilePKGS(0L)
if (inherits(res, "try-error"))
pkgerrmsg("lazy loading failed", pkg_name)
if (!is.null(libs0)) .libPaths(libs0)
}
if (install_help) {
starsmsg(stars, "help")
if (!dir.exists("man") ||
!length(list_files_with_type("man", "docs")))
cat("No man pages found in package ", sQuote(pkg_name), "\n")
encoding <- desc["Encoding"]
if (is.na(encoding)) encoding <- "unknown"
res <- try(.install_package_Rd_objects(".", instdir, encoding))
if (inherits(res, "try-error"))
pkgerrmsg("installing Rd objects failed", pkg_name)
starsmsg(paste0(stars, "*"), "installing help indices")
## always want HTML package index
.writePkgIndices(pkg_dir, instdir)
if (build_help) {
## This is used as the default outputEncoding for latex
outenc <- desc["Encoding"]
if (is.na(outenc)) outenc <- "latin1" # or ASCII
.convertRdfiles(pkg_dir, instdir,
types = build_help_types,
outenc = outenc)
}
if (dir.exists(figdir <- file.path(pkg_dir, "man", "figures"))) {
starsmsg(paste0(stars, "*"), "copying figures")
dir.create(destdir <- file.path(instdir, "help", "figures"))
file.copy(Sys.glob(c(file.path(figdir, "*.png"),
file.path(figdir, "*.jpg"),
file.path(figdir, "*.jpeg"),
file.path(figdir, "*.svg"),
file.path(figdir, "*.pdf"))), destdir)
}
}
## pkg indices: this also tangles the vignettes (if installed)
if (install_inst || install_demo || install_help) {
starsmsg(stars, "building package indices")
res <- try(.install_package_indices(".", instdir))
if (inherits(res, "try-error"))
errmsg("installing package indices failed")
if(dir.exists("vignettes")) {
starsmsg(stars, "installing vignettes")
enc <- desc["Encoding"]
if (is.na(enc)) enc <- ""
if (!fake &&
file_test("-f", file.path("build", "vignette.rds")))
installer <- .install_package_vignettes3
## FIXME: this handles pre-3.0.2 tarballs. In the long run, delete the alternative.
else
installer <- .install_package_vignettes2
res <- try(installer(".", instdir, enc))
if (inherits(res, "try-error"))
errmsg("installing vignettes failed")
}
}
## Install a dump of the parsed NAMESPACE file
## For a fake install, use the modified NAMESPACE file we installed
if (install_R && file.exists("NAMESPACE")) {
res <- try(.install_package_namespace_info(if(fake) instdir else ".", instdir))
if (inherits(res, "try-error"))
errmsg("installing namespace metadata failed")
}
if (clean) run_clean()
if (test_load) {
## Do this in a separate R process, in case it crashes R.
starsmsg(stars, "testing if installed package can be loaded")
## FIXME: maybe the quoting as 'lib' is not quite good enough
## On a Unix-alike this calls system(input=)
## and that uses a temporary file and redirection.
cmd <- paste0("tools:::.test_load_package('", pkg_name, "', '", lib, "')")
## R_LIBS was set already. R_runR is in check.R
deps_only <-
config_val_to_logical(Sys.getenv("_R_CHECK_INSTALL_DEPENDS_", "FALSE"))
env <- if (deps_only) setRlibs(lib0, self = TRUE, quote = TRUE) else ""
if (length(test_archs) > 1L) {
msgs <- character()
opts <- "--no-save --slave"
for (arch in test_archs) {
starsmsg("***", "arch - ", arch)
out <- R_runR(cmd, opts, env = env, arch = arch)
if(length(attr(out, "status")))
msgs <- c(msgs, arch)
if(length(out))
cat(paste(c(out, ""), collapse = "\n"))
}
if (length(msgs)) {
msg <- paste("loading failed for",
paste(sQuote(msgs), collapse = ", "))
errmsg(msg) # does not return
}
} else {
opts <- if (deps_only) "--vanilla --slave"
else "--no-save --slave"
out <- R_runR(cmd, opts, env = env)
if(length(out))
cat(paste(c(out, ""), collapse = "\n"))
if(length(attr(out, "status")))
errmsg("loading failed") # does not return
}
}
}