Bug 17370 - Can't run 'R CMD build' on Alpine Linux: 'cp' error
Summary: Can't run 'R CMD build' on Alpine Linux: 'cp' error
Status: CLOSED FIXED
Alias: None
Product: R
Classification: Unclassified
Component: System-specific (show other bugs)
Version: R 3.4.1
Hardware: All Linux
: P5 normal
Assignee: R-core
URL:
Depends on:
Blocks:
 
Reported: 2018-01-04 05:10 UTC by Ken Williams
Modified: 2018-01-05 21:05 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ken Williams 2018-01-04 05:10:01 UTC
When running `R CMD build` on Alpine Linux, we get the following error:

> * checking for file ‘/var/tsevents/DESCRIPTION’ ... OK
> cp: unrecognized option: preserve=timestamps
> BusyBox v1.27.2 (2017-11-28 16:17:30 GMT) multi-call binary.
> 
> Usage: cp [OPTIONS] SOURCE... DEST
> 
> Copy SOURCE(s) to DEST
> 
> 	-a	Same as -dpR
> 	-R,-r	Recurse
> 	-d,-P	Preserve symlinks (default if -R)
> 	-L	Follow all symlinks
> 	-H	Follow symlinks on command line
> 	-p	Preserve file attributes if possible
> 	-f	Overwrite
> 	-i	Prompt before overwrite
> 	-l,-s	Create (sym)links
> 	-u	Copy only newer files
>  ERROR
> copying to build directory failed

This is because of these lines (around line 870) in `src/library/tools/R/build.R`:


>            cp_sw <- if(Sys.info()[["sysname"]] == "Linux") ## << need GNU cp
>                ## unfortunately, '-pr' does not dereference sym.links
>                "-Lr --preserve=timestamps" else "-pr"
>            if (system(paste("cp", cp_sw, shQuote(pkgname), shQuote(Tdir)))) {
>                errorLog(Log, "copying to build directory failed")
>                do_exit(1L)
>            }

It's making the assumption that if the OS is a Linux flavor, we'll have a full-featured GNU `cp` supporting the `--preserve` flag, which on Alpine Linux isn't true.

As a workaround, I've installed the following targeted `cp` wrapper at `/usr/local/bin/cp`:

> #!/bin/sh
> 
> if [ $# -eq 4 ] && [ $1 = "-Lr" ] && [ $2 = "--preserve=timestamps" ]
> then
>   /bin/cp -pr "$3" "$4"
> else
>   /bin/cp $@
> fi

Obviously not something I really want hanging around on this system, though.

Is there something in `configure` that could help sense whether `--preserve` is supported by the system's `cp`, rather than conflating it with `Sys.info()[["sysname"]]`?
Comment 1 Martin Maechler 2018-01-05 08:32:37 UTC
Should be fixed (by Brian Ripley) in both R-devel and R-patched.

Can you please confirm?
Comment 2 Ken Williams 2018-01-05 21:05:37 UTC
Thanks, Martin, it looks to me like that change would get things working correctly, though I haven't had a chance to actually compile R & test it on that platform.

Note that it uses `cp --version`, which isn't actually supported on the two platforms I tried it on (OS X and Alpine):


Mac:
> % cp --version                       
> cp: illegal option -- -
> usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file
>        cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory


Alpine:
> / # cp --version
> cp: unrecognized option: version
> BusyBox v1.27.2 (2017-11-28 16:17:30 GMT) multi-call binary.
> 
> Usage: cp [OPTIONS] SOURCE... DEST
> 
> Copy SOURCE(s) to DEST
> 
> 	-a	Same as -dpR
> 	-R,-r	Recurse
> 	-d,-P	Preserve symlinks (default if -R)
> 	-L	Follow all symlinks
> 	-H	Follow symlinks on command line
> 	-p	Preserve file attributes if possible
> 	-f	Overwrite
> 	-i	Prompt before overwrite
> 	-l,-s	Create (sym)links
> 	-u	Copy only newer files

However, since neither of those error messages include the string "GNU coreutils", it should work fine. =)

By the way: would it be feasible to simply use R's `base::file.copy()` function instead?  It does seem to have the proper arguments to preserve mode & timestamp, and its docs say symlinks will be followed, so it would seem to fit the bill pretty well.