grimbough / Rhdf5lib

Distribution of the HDF5 library in an R package
https://bioconductor.org/packages/Rhdf5lib/
6 stars 14 forks source link

Installation failure on R 4.1.0 (BioC 3.13) on CentOS Linux 7 #40

Closed PeteHaitch closed 3 years ago

PeteHaitch commented 3 years ago

Hi Mike,

I'm having trouble installing Rhdf5lib on one of our servers. The set of errors that occur at the end are:

Error: package or namespace load failed for ‘Rhdf5lib’ in dyn.load(file, DLLpath = DLLpath, ...):
 unable to load shared object '/stornext/Home/data/allstaff/h/hickey/R/x86_64-pc-linux-gnu-library/4.1/00LOCK-Rhdf5lib/00new/Rhdf5lib/libs/Rhdf5lib.so':
  /stornext/Home/data/allstaff/h/hickey/R/x86_64-pc-linux-gnu-library/4.1/00LOCK-Rhdf5lib/00new/Rhdf5lib/libs/Rhdf5lib.so: undefined symbol: H5get_libversion
Error: loading failed
Execution halted
ERROR: loading failed
* removing ‘/stornext/Home/data/allstaff/h/hickey/R/x86_64-pc-linux-gnu-library/4.1/Rhdf5lib’

The full output of BiocManager::install("Rhdf5lib") was too long to paste here, so I've shared it in on https://pastebin.com/uuLE69zg

Please let me know any other information that may be helpful in debugging this issue. (I don't have admin privileges but we have a helpful sys admin).

Thanks, Pete

Session info ``` r > sessionInfo() R version 4.1.0 (2021-05-18) Platform: x86_64-pc-linux-gnu (64-bit) Running under: CentOS Linux 7 (Core) Matrix products: default BLAS: /stornext/System/data/apps/R/R-4.1.0/lib64/R/lib/libRblas.so LAPACK: /stornext/System/data/apps/R/R-4.1.0/lib64/R/lib/libRlapack.so locale: [1] LC_CTYPE=en_AU.UTF-8 LC_NUMERIC=C [3] LC_TIME=en_AU.UTF-8 LC_COLLATE=en_AU.UTF-8 [5] LC_MONETARY=en_AU.UTF-8 LC_MESSAGES=en_AU.UTF-8 [7] LC_PAPER=en_AU.UTF-8 LC_NAME=C [9] LC_ADDRESS=C LC_TELEPHONE=C [11] LC_MEASUREMENT=en_AU.UTF-8 LC_IDENTIFICATION=C attached base packages: [1] stats graphics grDevices utils datasets methods base loaded via a namespace (and not attached): [1] BiocManager_1.30.15 compiler_4.1.0 tools_4.1.0 ```
grimbough commented 3 years ago

Hi Pete,

I think the pertinent lines are the ones like:

ar: rice.o: plugin needed to handle lto object

I see -flto in your compiler flags, suggesting that link time optimisation is turned on for your system. This is failing, so the library isn't linked correctly and you get the "symbol not found" errors. I don't know if that's something your system has setup explicitly, or if it's something new in R. The following suggests maybe this was something introduced in R-4.1:

  • Configuring with flag --enable-lto=R now also uses LTO when installing the recommended packages.

  • R CMD INSTALL and R CMD SHLIB have a new flag --use-LTO to use LTO when compiling code, for use with R configured with --enable-lto=R. For R configured with --enable-lto, they have the new flag --no-use-LTO. From: https://cran.r-project.org/doc/manuals/r-release/NEWS.html

However I don't the compiler option on my R-4.1 so it could be system specific.

Do you get any further if you try this?

BiocManager::install('Rhdf5lib', configure.opts = '--no-use-LTO')
PeteHaitch commented 3 years ago

Thanks, Mike, I hadn't noticed the LTO stuff in the output. Unfortunately, neither BiocManager::install('Rhdf5lib', configure.opts = '--no-use-LTO') nor BiocManager::install('Rhdf5lib', INSTALL_opts = '--no-use-LTO') (what my sysadmin recommended) worked. I haven't carefully read the outputs (below), but they both seem to result in the same final error messages.

Incidentally, the latter form (BiocManager::install('Rhdf5lib', INSTALL_opts = '--no-use-LTO')) seems to me what is recommended based on my reading of https://cran.r-project.org/bin/windows/base/NEWS.R-devel.html and ?install.packages.

And just for luck I tried throwing both at it, but that didn't work either

grimbough commented 3 years ago

Yep, I think INSTALL_opts was what I was intending - shame it doesn't make any difference.

I don't actually know what --no-use-LTO is doing under the hood. Do you see the -flto flag in the output from R CMD config CFLAGS or R CMD config CPICFLAGS. It would be good to know where that flag is coming from.

grimbough commented 3 years ago

My hunch is that your R has been built with --enable-lto (or maybe --enable-lto=R I read conflicting info on which implements LTO during package building).

Maybe this is also useful https://cran.r-project.org/doc/manuals/r-devel/R-admin.html#LTO-with-GCC

The suggestion that you need to set these variables seems to chime with my various google hits for the error message.

AR=gcc-ar
RANLIB=gcc-ranlib
grimbough commented 3 years ago

FWIW building R with --enable-lto resulted in adding -flto to the CFLAGS used during package compilation.

I still didn't need to do anything extra to get the package to compile - it just worked. However, I note that it seems ar and gcc-ar are the same on my Ubuntu 20.04 instance:

-> % ar --version | head -n 1
GNU ar (GNU Binutils for Ubuntu) 2.34
-> % gcc-ar --version | head -n 1
GNU ar (GNU Binutils for Ubuntu) 2.34

I was also able to drop that flag by setting my own CFLAGS in $HOME/.R/Makevars. That might be helpful if you're trying to figure out whether getting rid of the -flto flag is sufficient to get it working.

PeteHaitch commented 3 years ago

Yes, our sysadmin wrote to us that "R 4.1.0 was compiled with GCC 11.1.0 and Link-Time Optimisation (LTO) enabled." Regarding your specific questions:

% R CMD config CFLAGS
-g -O2 -flto
% R CMD config CPICFLAGS
-fpic

It appears that ar and gcc-ar are the same on my system, although they are separate installations (related to our HPC module system, I presume?).

% ar --version | head -n 1
GNU ar version 2.27-34.base.el7
% gcc-ar --version | head -n 1
GNU ar version 2.27-34.base.el7
% which ar
/usr/bin/ar
% which gcc-ar
/stornext/System/data/apps/gcc/gcc-11.1.0/bin/gcc-ar

I'm going to email our sysadmin this thread and ask for his assistance. I'd rather have this fixed system-wide than having $HOME/.R/Makevars (partly because I'll almost certainly forget about this file and then run into problems when we next upgrade R or switch versions).

PeteHaitch commented 3 years ago

Good news: I've been able to install Rhdf5lib! I needed to run the following (some of it is specific to the module system on my HPC) Firstly:

module load R/4.1.0
module load gcc/11.1.0 # This is the version of GCC our R was installed with

Secondly, from R:

BiocManager::install("Rhdf5lib", INSTALL_OPTS = "--no-use-LTO")

Notably, running BiocManager::install("Rhdf5lib") in the second step did not work and led to what I think was a different series of errors: see https://pastebin.com/5MUbUrbg @grimbough do you think this an issue with the Rhdf5lib configure script or more likely the setup of my system?

This is the advice I received from my sysadmin that allowed me to install Rhdf5lib (his reply was in comments prior to this current post):

The issue is that the configure script for Rhdf5lib is not using the correct wrapper for ar or ranlib:

For the szip build:
checking for ar... ar
checking for ranlib... ranlib

For the hdf5 build:

Linking Options:
----------------
                      Libraries: static
  Statically Linked Executables:
                        LDFLAGS: -L/usr/local/lib64
                     H5_LDFLAGS:
                     AM_LDFLAGS:
                Extra libraries: -lcrypto -lcurl -lz -ldl -lm
                       Archiver: ar
                       AR_FLAGS: cr
                         Ranlib: ranlib

In our case they should either be gcc-ar and gcc-ranlib or ideally:
/stornext/System/data/apps/gcc/gcc-11.1.0/bin/gcc-ar
/stornext/System/data/apps/gcc/gcc-11.1.0/bin/gcc-ranlib

These are correctly set in the Makevars file:

/stornext/System/data/apps/R/R-4.1.0/lib64/R/etc/Makeconf

Therefore, the correct liblto_plugin.so is not used, leading to linking issues (it is actually using  ar and ralib from the system gcc, which is 4.8.5. Too old to compile lots of packages these days). I assume the configure script for Rhdf5lib is extracting the Makevars used in R, since I see the C/CPP flags being the ones in the Makeconf file.

I have made sure AR and RANLIB get passed to Rstudio, but ideally the R package being installed should check for these.

IF you are building from command line, load the gcc/11.1.0 and R/4.1.0 modules. The gcc module will set AR and RALIB as environment variables.

Hope this helps.

This is still a bit opaque to me and I'm not sure how much of the issue I had is due to our system setup vs. the configure script of Rhdf5lib. I've pasted below the output of the Makeconf file our sysadmin mentioned in case this is helpful

% cat /stornext/System/data/apps/R/R-4.1.0/lib64/R/etc/Makeconf
# etc/Makeconf.  Generated from Makeconf.in by configure.
#
# ${R_HOME}/etc/Makeconf
#
# R was configured using the following call
# (not including env. vars and site configuration)
# configure  '--prefix=/stornext/System/data/apps/R/R-4.1.0' '--enable-memory-profiling' '--enable-R-shlib' '--enable-lto' '--with-pcre2=/stornext/System/data/apps/pcre2/pcre2-10.36-gcc-11.1.0/' 'JAVA_HOME=/stornext/System/data/tools/openjdk/openjdk-13.0.2' 'PKG_CONFIG_PATH=/stornext/System/data/tools/openSSL/openSSL-1.1.1k/lib/pkgconfig' 'CC=/stornext/System/data/apps/gcc/gcc-11.1.0/bin/gcc' 'FC=/stornext/System/data/apps/gcc/gcc-11.1.0/bin/gfortran' 'CXX=/stornext/System/data/apps/gcc/gcc-11.1.0/bin/g++' 'OBJC=/stornext/System/data/apps/gcc/gcc-11.1.0/bin/gcc'

## This fails if it contains spaces, or if it is quoted
include $(R_SHARE_DIR)/make/vars.mk

AR = /stornext/System/data/apps/gcc/gcc-11.1.0/bin/gcc-ar 
BLAS_LIBS = -L"$(R_HOME)/lib$(R_ARCH)" -lRblas
C_VISIBILITY = -fvisibility=hidden
CC = /stornext/System/data/apps/gcc/gcc-11.1.0/bin/gcc
CFLAGS = -g -O2 $(LTO)
CPICFLAGS = -fpic
CPPFLAGS = -I/usr/local/include
CXX = /stornext/System/data/apps/gcc/gcc-11.1.0/bin/g++ -std=gnu++14
CXXFLAGS = -g -O2 $(LTO)
CXXPICFLAGS = -fpic
CXX11 = /stornext/System/data/apps/gcc/gcc-11.1.0/bin/g++
CXX11FLAGS = -g -O2 $(LTO)
CXX11PICFLAGS = -fpic
CXX11STD = -std=gnu++11
CXX14 = /stornext/System/data/apps/gcc/gcc-11.1.0/bin/g++
CXX14FLAGS = -g -O2 $(LTO)
CXX14PICFLAGS = -fpic
CXX14STD = -std=gnu++14
CXX17 = /stornext/System/data/apps/gcc/gcc-11.1.0/bin/g++
CXX17FLAGS = -g -O2 $(LTO)
CXX17PICFLAGS = -fpic
CXX17STD = -std=gnu++17
CXX20 = /stornext/System/data/apps/gcc/gcc-11.1.0/bin/g++
CXX20FLAGS = -g -O2 $(LTO)
CXX20PICFLAGS = -fpic
CXX20STD = -std=gnu++20
CXX_VISIBILITY = -fvisibility=hidden
DYLIB_EXT = .so
DYLIB_LD = $(CC)
DYLIB_LDFLAGS = -shared -fopenmp $(CFLAGS) $(CPICFLAGS) 
## should be used by packges for dylibs, but at the time of writing was not
DYLIB_LINK = $(DYLIB_LD) $(DYLIB_LDFLAGS) $(LDFLAGS)
ECHO = echo
ECHO_C = 
ECHO_N = -n
ECHO_T = 
F_VISIBILITY = -fvisibility=hidden
## FC is the compiler used for all Fortran as from R 3.6.0
FC = /stornext/System/data/apps/gcc/gcc-11.1.0/bin/gfortran
FCFLAGS = -g -O2 $(LTO_FC)
## additional libs needed when linking with $(FC), e.g. on some Oracle compilers
FCLIBS_XTRA = 
FFLAGS = -g -O2 $(LTO_FC)
FLIBS =  -lgfortran -lm -lquadmath
FPICFLAGS = -fpic
FOUNDATION_CPPFLAGS = 
FOUNDATION_LIBS = 
JAR = /stornext/System/data/tools/openjdk/openjdk-13.0.2/bin/jar
JAVA = /stornext/System/data/tools/openjdk/openjdk-13.0.2/bin/java
JAVAC = /stornext/System/data/tools/openjdk/openjdk-13.0.2/bin/javac
JAVAH = 
## JAVA_HOME might be used in the next three.  
## They are for packages 'JavaGD' and 'rJava'
JAVA_HOME = /stornext/System/data/tools/openjdk/openjdk-13.0.2
JAVA_CPPFLAGS = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
JAVA_LIBS = -L$(JAVA_HOME)/lib/server -ljvm
JAVA_LD_LIBRARY_PATH = $(JAVA_HOME)/lib/server
LAPACK_LIBS = -L"$(R_HOME)/lib$(R_ARCH)" -lRlapack
LDFLAGS = -L/usr/local/lib64
## we only need this is if it is external, as otherwise link to R
LIBINTL= 
LIBM = -lm
LIBR0 = -L"$(R_HOME)/lib$(R_ARCH)"
LIBR1 = -lR
LIBR = -L"$(R_HOME)/lib$(R_ARCH)" -lR
LIBS =  -lpcre2-8 -llzma -lbz2 -lz -lrt -ldl -lm -licuuc -licui18n
## needed by R CMD config
LIBnn = lib64
LIBTOOL = $(SHELL) "$(R_HOME)/bin/libtool"
## set for --enable-lto, --enable-lto=check
LTO = -flto
LTO_FC = -flto
LTO_LD = 
## set for --enable-lto=R, used in INSTALL
LTO_OPT = -flto
LTO_FC_OPT = -flto
## needed to build applications linking to static libR
MAIN_LD = $(CC)
MAIN_LDFLAGS = -Wl,--export-dynamic -fopenmp
MAIN_LINK = $(MAIN_LD) $(MAIN_LDFLAGS) $(LDFLAGS)
MKINSTALLDIRS = "$(R_HOME)/bin/mkinstalldirs"
NM = /stornext/System/data/apps/gcc/gcc-9.1.0/bin/gcc-nm -B
OBJC = /stornext/System/data/apps/gcc/gcc-11.1.0/bin/gcc
OBJCFLAGS = -g -O2 -fobjc-exceptions $(LTO)
OBJC_LIBS = -lobjc 
OBJCXX = /stornext/System/data/apps/gcc/gcc-11.1.0/bin/g++
R_ARCH = 
RANLIB = /stornext/System/data/apps/gcc/gcc-11.1.0/bin/gcc-ranlib
SAFE_FFLAGS = -g -O2 -msse2 -mfpmath=sse
SED = /usr/bin/sed
SHELL = /bin/sh
SHLIB_CFLAGS = 
SHLIB_CXXFLAGS = 
SHLIB_CXXLD = $(CXX)
SHLIB_CXXLDFLAGS = -shared $(CXXFLAGS) $(CXXPICFLAGS) $(LTO_LD)
SHLIB_CXX11LD = $(CXX11) $(CXX11STD)
SHLIB_CXX11LDFLAGS = -shared $(CXX11FLAGS) $(CXX11PICFLAGS) $(LTO_LD)
SHLIB_CXX14LD = $(CXX14) $(CXX14STD)
SHLIB_CXX14LDFLAGS = -shared $(CXX14FLAGS) $(CXX14PICFLAGS) $(LTO_LD)
SHLIB_CXX17LD = $(CXX17) $(CXX17STD)
SHLIB_CXX17LDFLAGS = -shared $(CXX17FLAGS) $(CXX17PICFLAGS) $(LTO_LD)
SHLIB_CXX20LD = $(CXX20) $(CXX20STD)
SHLIB_CXX20LDFLAGS = -shared $(CXX20FLAGS) $(CXX20PICFLAGS) $(LTO_LD)
SHLIB_EXT = .so
SHLIB_FCLD = $(FC)
SHLIB_FCLDFLAGS = -shared $(FCFLAGS) $(FPICFLAGS)
SHLIB_FFLAGS = 
SHLIB_LD = $(CC)
## used for add-on packages linked by C
SHLIB_LDFLAGS = -shared $(CFLAGS) $(CPICFLAGS) $(LTO_LD)
## used for standard packages
SHLIB_LDFLAGS_R = -shared $(CFLAGS) $(CPICFLAGS) $(LTO_LD)
SHLIB_LIBADD = 
## We want to ensure libR is picked up from $(R_HOME)/lib
## before e.g. /usr/local/lib if a version is already installed.
SHLIB_LINK = $(SHLIB_LD) $(SHLIB_LDFLAGS) $(LIBR0) $(LDFLAGS)
SHLIB_OPENMP_CFLAGS = -fopenmp
SHLIB_OPENMP_CXXFLAGS = -fopenmp
SHLIB_OPENMP_FFLAGS = -fopenmp
STRIP_STATIC_LIB = strip --strip-debug
STRIP_SHARED_LIB = strip --strip-unneeded
TCLTK_CPPFLAGS = -I/usr/include -I/usr/include 
TCLTK_LIBS = -L/usr/lib64 -ltcl8.5 -L/usr/lib64 -ltk8.5 -lX11
YACC = bison -y

## for linking to libR.a
STATIC_LIBR = # -Wl,--whole-archive "$(R_HOME)/lib$(R_ARCH)/libR.a" -Wl,--no-whole-archive $(BLAS_LIBS) $(FLIBS)  $(LIBINTL) -lreadline  $(LIBS)

## These are recorded as macros for legacy use in packages
## set on AIX, formerly for old glibc (-D__NO_MATH_INLINES)
R_XTRA_CFLAGS = 
##  was formerly set on HP-UX
R_XTRA_CPPFLAGS =  -I"$(R_INCLUDE_DIR)" -DNDEBUG
## currently unset
R_XTRA_CXXFLAGS = 
## used for gfortran in R > 3.6.0
R_XTRA_FFLAGS = -fno-optimize-sibling-calls

## SHLIB_CFLAGS SHLIB_CXXFLAGS SHLIB_FFLAGS are apparently currently unused
## SHLIB_CXXFLAGS is undocumented, there is no SHLIB_FCFLAGS
ALL_CFLAGS =  $(PKG_CFLAGS) $(CPICFLAGS) $(SHLIB_CFLAGS) $(CFLAGS)
ALL_CPPFLAGS =  -I"$(R_INCLUDE_DIR)" -DNDEBUG $(PKG_CPPFLAGS) $(CLINK_CPPFLAGS) $(CPPFLAGS) 
ALL_CXXFLAGS =  $(PKG_CXXFLAGS) $(CXXPICFLAGS) $(SHLIB_CXXFLAGS) $(CXXFLAGS)
ALL_OBJCFLAGS = $(PKG_OBJCFLAGS) $(CPICFLAGS) $(SHLIB_CFLAGS) $(OBJCFLAGS)
ALL_OBJCXXFLAGS = $(PKG_OBJCXXFLAGS) $(CXXPICFLAGS) $(SHLIB_CXXFLAGS) $(OBJCXXFLAGS)
ALL_FFLAGS = -fno-optimize-sibling-calls $(PKG_FFLAGS) $(FPICFLAGS) $(SHLIB_FFLAGS) $(FFLAGS)
## can be overridden by R CMD SHLIB
P_FCFLAGS = $(PKG_FFLAGS)
ALL_FCFLAGS = -fno-optimize-sibling-calls $(P_FCFLAGS) $(FPICFLAGS) $(SHLIB_FFLAGS) $(FCFLAGS)
## LIBR here as a couple of packages use this without SHLIB_LINK
ALL_LIBS = $(PKG_LIBS) $(SHLIB_LIBADD) $(LIBR)# $(LIBINTL)

.SUFFIXES:
.SUFFIXES: .c .cc .cpp .d .f .f90 .f95 .m .mm .M .o

.c.o:
    $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c $< -o $@
.c.d:
    @echo "making $@ from $<"
    @$(CC) -MM $(ALL_CPPFLAGS) $< > $@
.cc.o:
    $(CXX) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) -c $< -o $@
.cpp.o:
    $(CXX) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) -c $< -o $@
.cc.d:
    @echo "making $@ from $<"
    @$(CXX) -M $(ALL_CPPFLAGS) $< > $@
.cpp.d:
    @echo "making $@ from $<"
    @$(CXX) -M $(ALL_CPPFLAGS) $< > $@
.m.o:
    $(OBJC) $(ALL_CPPFLAGS) $(ALL_OBJCFLAGS) -c $< -o $@
.m.d:
    @echo "making $@ from $<"
    @$(OBJC) -MM $(ALL_CPPFLAGS) $< > $@
.mm.o:
    $(OBJCXX) $(ALL_CPPFLAGS) $(ALL_OBJCXXFLAGS) -c $< -o $@
.M.o:
    $(OBJCXX) $(ALL_CPPFLAGS) $(ALL_OBJCXXFLAGS) -c $< -o $@
.f.o:
    $(FC) $(ALL_FFLAGS) -c $< -o $@
.f95.o:
    $(FC) $(ALL_FCFLAGS) -c  $< -o $@
.f90.o:
    $(FC) $(ALL_FCFLAGS) -c  $< -o $@
grimbough commented 3 years ago

Thanks for the pull request @miesav I've merged that, which hopefully fixes the problem and @PeteHaitch can just install using the usual mechanism.

I couldn't see a way to get the compilation of libhdf5 to obey the INSTALL_opts=--no-use-LTO setting, as R CMD config CFLAGS retains the original setting with -flto. As such I've added an new configure option that will allow it to be turned off in both locations e.g.

BiocManager::install('Rhdf5lib', INSTALL_opts="--no-use-LTO", configure.args = "--disable-lto")

This is now also in the vignette in case anyone else runs into the issue https://github.com/grimbough/Rhdf5lib/blob/6f09c5d443a0f1753869e222431e1fcc5fedd155/vignettes/Rhdf5lib.Rmd#L72-L80

I'll make it available in devel first (version 1.15.1) and then port the changes to the release branch once I've seen it's passing the Bioconductor build ok.

PeteHaitch commented 3 years ago

Thanks Mike

grimbough commented 3 years ago

I haven't seen any problems on the builder, so these changes are now in BioC 3.13 (Rhdf5lib 1.14.1). Please re-open the issue if you try installing and still encounter problems.

PeteHaitch commented 3 years ago

I tested by installing from GitHub with BiocManager::install('grimbough/Rhdf5lib@RELEASE_3_13') and everything worked :) Thanks for your great work maintaining this package, Mike.