r-lib / later

Schedule an R function or formula to run after a specified period of time.
https://r-lib.github.io/later
Other
137 stars 27 forks source link

Installation fails on x86_64-linux-musl (with solution) #135

Closed skratkk closed 4 years ago

skratkk commented 4 years ago

Installation fails on x86_64-linux-musl:

terminal[~/Downloads]$ sudo R CMD INSTALL later/
* installing to library '/usr/lib/R/library'
* installing *source* package 'later' ...
** package 'later' successfully unpacked and MD5 sums checked
** using staged installation
Running configure script
-latomic linker flag not needed.
** libs
g++ -std=gnu++11 -shared -L/usr/lib64/R/lib -o later.so RcppExports.o callback_registry.o debug.o init.o later.o later_posix.o later_win32.o timer_posix.o timestamp_unix.o timestamp_win32.o tinycthread.o -pthread -L/usr/lib64/R/lib -lR
installing to /usr/lib/R/library/00LOCK-later/00new/later/libs
** R
** inst
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded from temporary location
Error: package or namespace load failed for 'later' in dyn.load(file, DLLpath = DLLpath, ...):
 unable to load shared object '/usr/lib/R/library/00LOCK-later/00new/later/libs/later.so':
  Error relocating /usr/lib/R/library/00LOCK-later/00new/later/libs/later.so: backtrace: symbol not found
Error: loading failed
Execution halted
ERROR: loading failed
* removing '/usr/lib/R/library/later'
* restoring previous '/usr/lib/R/library/later'

Under x86_64-linux-musl the function backtrace is contained in library /usr/lib/libexecinfo.so, so it is sufficient to link that:

terminal[~/Downloads]$ cd later/src/
terminal[~/Downloads/later/src]$ g++ -std=gnu++11 -shared -L/usr/lib64/R/lib -o later.so RcppExports.o callback_registry.o debug.o init.o later.o later_posix.o later_win32.o timer_posix.o timestamp_unix.o timestamp_win32.o tinycthread.o -pthread -L/usr/lib64/R/lib -lR -lexecinfo
terminal[~/Downloads/later/src]$ cd ../..
terminal[~/Downloads]$ sudo R CMD INSTALL later/
* installing to library '/usr/lib/R/library'
* installing *source* package 'later' ...
** package 'later' successfully unpacked and MD5 sums checked
** using staged installation
Running configure script
-latomic linker flag not needed.
** libs
make: Nothing to be done for 'all'.
installing to /usr/lib/R/library/00LOCK-later/00new/later/libs
** R
** inst
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded from temporary location
** checking absolute paths in shared objects and dynamic libraries
** testing if installed package can be loaded from final location
** testing if installed package keeps a record of temporary installation path
* DONE (later)

Therefore, I found it is sufficient to modify the Makevars.in file, adding -lexecinfo at the end of the PKG_LIBS definition:

PKG_LIBS = -pthread -lexecinfo @extra_pkg_libs@
wch commented 4 years ago

Thanks for the report. What distribution are you using?

The fix will probably require a change to the configure script -- I'm guessing that adding -lexecinfo will break things on other platforms.

wch commented 4 years ago

I don't see the string backtrace anywhere in the sources for httpuv or for later. Do you know where it's coming from?

skratkk commented 4 years ago

I'm using voidlinux with the musl library instead of glibc:

https://docs.voidlinux.org/installation/musl.html

This issue is related to Rcpp on musl, since the backtrace function is called from there, see file

/usr/lib/R/library/Rcpp/include/Rcpp/exceptions_impl.h

In fact, this other issue might be related: https://github.com/rstudio/httpuv/issues/280, since Alpine Linux can also run on musl, as discussed in these two more threads:

https://www.reddit.com/r/voidlinux/comments/i4l87f/tidyverse_install_on_void_musl_not_working/

https://github.com/RcppCore/Rcpp/issues/448

Adding -lexecinfo for everyone will indeed break compilation on other platforms. I suppose one should define PKG_LIBS dynamically, based on the value of environmental variables, such as MACHTYPE=x86_64-unknown-linux-musl. I tried to do so, with no avail. Failing all else, my "manual" solution could be used by the minority of R users on x86_64-linux-musl.

wch commented 4 years ago

It looks like Rcpp is supposed to not include execinfo.h or call backtrace() when musl is used. It does this by checking if __MUSL__ is defined: https://github.com/RcppCore/Rcpp/blob/c5a97a3092bb038dc4236133144ebdb877764a72/inst/include/Rcpp/exceptions_impl.h#L26-L36 https://github.com/RcppCore/Rcpp/blob/c5a97a3092bb038dc4236133144ebdb877764a72/inst/include/Rcpp/exceptions_impl.h#L76-L88

musl itself doesn't define __MUSL__ because the maintainers believe it shouldn't be defined: https://wiki.musl-libc.org/faq.html

However, Alpine linux does define __MUSL__ for R, because of this specific problem with Rcpp: https://git.alpinelinux.org/aports/tree/community/R/APKBUILD#n26

The root of this problem is in Rcpp, and they have a solution they're comfortable with. I'd suggest editing your user-level Makevars or system-level Makeconf file to add -D__MUSL__.

(Note that rstudio/httpuv#280 is a different issue.)