Search code examples
rr-packagerd

Behavior of `R CMD build` depending of Rd content


R CMD build behaves differently whether a Rd file contains \PR{} or not. See Writing R Extensions for details on the macros.

Example when a Rd file does not contain \PR{}:

$ R CMD build test
* checking for file 'test/DESCRIPTION' ... OK
* preparing 'test':
* checking DESCRIPTION meta-information ... OK
* installing the package to process help pages
* saving partial Rd database
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
* building 'test_0.1.tar.gz'

Example when a Rd file contains \PR{}:

$ R CMD build test
* checking for file 'test/DESCRIPTION' ... OK
* preparing 'test':
* checking DESCRIPTION meta-information ... OK
* installing the package to process help pages
* saving partial Rd database
* building the PDF package manual      # <- this
Hmm ... looks like a package           # <- this
Converting Rd files to LaTeX           # <- this
Creating pdf output from LaTeX ...     # <- this
Saving output to 'xxx/test.pdf' ...    # <- this
Done                                   # <- this
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
* building 'test_0.1.tar.gz'

The additional stage (i.e. building the PDF package manual, which can be quite slow on an old computer...) is due to the call to ..Rd2pdf() in .build_packages(). However I do not understand what triggers this stage. In addition, it is triggered only for \PR{} and not for other macros such as \CRANpkg{} and \doi{}.

Can someone trace back what happens and why? The question is on base R functions only. I do not use helpers such as package:devtools.

Minimal test package

Package structure:

test
test/man
test/man/one.Rd
test/R
test/R/one.R
test/DESCRIPTION
test/NAMESPACE

test/man/one.Rd:

\name{one}
\alias{one}
\title{Get One}
\description{
Rd file containing or not the PR macro:
\PR{1} % comment/uncomment this line as needed
but containing other macros:
\CRANpkg{ggplot2} and \doi{10.1002/wics.147}
}
\usage{
one()
}

test/R/one.R:

one <- function() 1

test/DESCRIPTION:

Package: test
Version: 0.1
Title: Test
Author: Nobody
Maintainer: Nobody <[email protected]>
Description: Test.
License: GPL-3

test/NAMESPACE:

export(one)

Build, check, and install with:

$ R CMD build test
$ R CMD check test_0.1.tar.gz
$ R CMD INSTALL test_0.1.tar.gz

Solution

  • Here's an explanation of the mechanism that led to this difference.

    You can see the system macro definitions in the file at file.path(R.home(), "share/Rd/macros/system.Rd"). The definition for \PR is

    \newcommand{\PR}{\Sexpr[results=rd]{tools:::Rd_expr_PR(#1)}}
    

    The definitions for the others you mention are

    \newcommand{\CRANpkg}{\href{https://CRAN.R-project.org/package=#1}{\pkg{#1}}}
    
    \newcommand{\doi}{\Sexpr[results=rd,stage=build]{tools:::Rd_expr_doi("#1")}}
    

    The \CRANpkg macro doesn't execute R code, so it doesn't trigger a package install.

    The \doi macro executes code at build time.

    Just above the code you linked, you see this test:

    needRefman <- manual &&
            parse_description_field(desc, "BuildManual", TRUE) &&
            any(vapply(db,
                       function(Rd)
                           any(getDynamicFlags(Rd)[c("install", "render")]),
                       NA))
    

    The manual variable defaults to TRUE, but the command line option --no-manual sets it to FALSE. The next part of the test says you can suppress the manual by a field in the DESCRIPTION file.

    The getDynamicFlags() function is looking for code in Rd files executed at install or render time, not build time, so the \doi macro doesn't trigger the build of the reference manual.

    The \PR macro doesn't specify the stage when it runs, and the documentation seems silent on the default run time, but apparently getDynamicFlags(Rd)[c("install", "render")] returns TRUE for it. I'd guess the default is render time, in case the URL for the bug database changes in some future version of R. [Edit: the docs do say that the default is "install".]

    So to suppress this build, put BuildManual: false in the DESCRIPTION file or --no-manual on the R CMD build command line.