[Rd] Upgrading a package to which other packages are LinkingTo

Gábor Csárdi csardi.gabor at gmail.com
Wed Jan 25 15:04:59 CET 2017


FWIW I wrote a tool that tests which dependencies of a package are
build-time dependencies:
https://github.com/r-hub/builddeps

It is not very smart, just "brute-force", really. It tries to install the
package several times, leaving out one dependency at a time, and if the
installation fails, then the missing package is a build-time dependency.
(First it tries with the LinkingTo dependencies only, and if that succeeds,
then these are the only build time dependncies.)

It does download all dependent packages, and runs R CMD install several
times, so it is expensive. It is better to run it with binary packages.

It is mostly trivial, except that
1) it needs to edit DESCRIPTION and NAMESPACE to omit a dependency.
DESCRIPTION is easy, NAMESPACE somewhat more difficult, because there is a
parser for it, but no "writer".
2) the dependencies need to be considered in a topological order, otherwise
one gets wrong answers.

I wrote this mainly for R-hub, to know which binary packages need to be
rebuilt after a package update, but if you use it and have feedback, please
email me or open an issue in the GitHub repo.

Gabor

On Fri, Dec 16, 2016 at 9:27 PM, Gábor Csárdi <csardi.gabor at gmail.com>
wrote:

> I think that this problem is actually more general than just ABI
> versioning. The common definition of ABI refers to compiled code, but
> with R packages similar problems might happen (and they to happen)
> without any compiled code.
>
> I think the key issue is the concept of build-time dependencies. While
> R packages usually does not distinguish between build-time and
> run-time dependencies, they still do exist, and I think ideally we
> would need to treat them differently.
>
> AFAIK LinkingTo is the only form of a build-time dependency, that is
> completely explicit, so it is relatively easy to handle. The other
> frequent of build-time dependency is a function call to the other
> package, that happens at install time. E.g. with references or R6*
> classes you frequently include code like this in yourpackage:
>
> myclass <- R6::R6Class(...)
>
> and this code is evaluated at install time. So if the R6 package is
> updated, the installed version myclass in yourpackage is not affected
> at all. In fact, if the new version of R6 is not compatible with the
> myclass object created by the old version, then yourpackage will be
> broken. (This AFAIK cannot happen with R6, so it is not the best
> example, but it can happen in other similar cases.)
>
> The key here is that R6 is a build-time dependency of yourpackage,
> similarly to packages linking to (i.e. LinkingTo) Rpp.
>
> Another possible type of build-time dependency is if you put objects
> from another package in yourpackage. E.g.
>
> myfun <- otherpkg::fun
>
> Then a copy of otherpkg::fun will be saved in yourpackage. If you
> install a new version of otherpkg, yourpackage is unaffected, and if
> otherpkg::fun uses some (possibly internal) API from otherpkg, that
> has changed in the new version of otherpkg, you might easily end up
> with a broken yourpackage again.
>
> I think one lesson is to avoid running code at install time. This is
> not a new thing, AFAIR it is even mentioned in 'Writing R extensions'.
> Instead of running code at install time, you might consider running it
> in `.onLoad()`, and then these "problems" go away. But you obviously
> cannot always avoid it.
>
> Gabor
>
> * I think the R6 package is great, and I am not speaking in any way
> against it. I just needed an example, and I know R6 much better than
> reference classes, or other similar packages.
>

	[[alternative HTML version deleted]]



More information about the R-devel mailing list