使用 cpp 代码编译和链接 R 包时出现奇怪的 SHLIB 行为

Odd SHLIB behavior while compiling and linking an R package with cpp code

我正在编译一个 R 包,其中包含来自第三方的 .cpp 个源文件。要将 .cpp 文件编译成静态库,我使用 Makevars.win 文件 (link). I stumbled upon an odd behavior of SHLIB on Windows only, while trying to fix another problem related to parallel make which revealed that I had a misplaced parenthesis defining $(SHLIB) as ($SHLIB) in Makevars and Makevars.win files (link).

长话短说,我在 MakevarsMakevars.win 文件中将 $(SHLIB) 错误地写成了 ($SHILB)。更正该错误在 LinuxOSX 机器上没有错误,但在 Windows ($SHLIB) 上工作,但 $(SHLIB) 给我以下错误:

C:\Rtools\mingw_64\bin\nm.exe: cvode_bandpre_impl.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: cvode_bbdpre_impl.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: cvode_diag_impl.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: cvode_direct_impl.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: cvode_impl.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: cvode_spils_impl.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: cvode.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: cvode_bandpre.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: cvode_bbdpre.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: cvode_diag.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: cvode_direct.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: cvode_impl.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: cvode_spils.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: fnvector_serial.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: nvector_serial.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_band.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_config.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_dense.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_direct.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_fconfig.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_fnvector.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_iterative.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_linearsolver.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_math.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_matrix.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_nvector.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_pcg.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_sparse.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_spbcgs.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_spfgmr.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_spgmr.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_sptfqmr.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_types.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sundials_version.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: fsunlinsol_dense.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sunlinsol_band.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sunlinsol_dense.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sunlinsol_pcg.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sunlinsol_spbcgs.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sunlinsol_spfgmr.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sunlinsol_spgmr.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sunlinsol_sptfqmr.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: fsunmatrix_dense.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: fsunmatrix_band.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sunmatrix_band.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sunmatrix_dense.h: File format not recognized
C:\Rtools\mingw_64\bin\nm.exe: sunmatrix_sparse.h: File format not recognized
c:/Rtools/mingw_64/bin/g++ -shared -s -static-libgcc -o sundialr.dll tmp.def cvode.o RcppExports.o -LC:/PROGRA~1/R/R-34~1.1/bin/x64 -lRlapack -LC:/PROGRA~1/R/R-34~1.1/bin/x64 -lRblas -lgfortran -lm -lquadmath -L../inst/ -lsundials_all -Ld:/Compiler/gcc-4.9.3/local330/lib/x64 -Ld:/Compiler/gcc-4.9.3/local330/lib -LC:/PROGRA~1/R/R-34~1.1/bin/x64 -lR
../inst//libsundials_all.a(cvode_bandpre.o):cvode_bandpre.c:(.text+0x679): undefined reference to `SUNBandLinearSolver'
../inst//libsundials_all.a(cvode_bandpre.o):cvode_bandpre.c:(.text+0x360): undefined reference to `SUNLinSolSetup_Band'
../inst//libsundials_all.a(cvode_bbdpre.o):cvode_bbdpre.c:(.text+0x819): undefined reference to `SUNBandLinearSolver'
../inst//libsundials_all.a(cvode_bbdpre.o):cvode_bbdpre.c:(.text+0x2ea): undefined reference to `SUNLinSolSetup_Band'
collect2.exe: error: ld returned 1 exit status
no DLL was created
ERROR: compilation failed for package 'sundialr'

我知道 undefined reference 错误消息是链接错误,但我不确定为什么我会收到头文件的 File format not recognized 错误消息。更有趣的是,当 WRE 文档谈论 $(SHLIB) 而不是 ($SHLIB) 时,为什么在 Makevars.win 文件中用 ($SHLIB) 替换 $(SHLIB) 一切正常。事实上,该包通过了所有 CRAN 检查,并且一直在 CRAN 上,直到最近 ($SHLIB) in Makevars.win

任何人都可以解释为什么会发生这种情况以及我现在如何解决 $(SHLIB) 遇到的错误。我想在我的代码中替换错误的 ($SHLIB) 。谢谢!

您的 SOURCES_* 变量混合了 .c.h 文件。 .c.o 替换为 OBJECTS_SUNDIALS_ALL,但 .h 文件保留在其中。这些似乎在构建静态库时混淆了 nm.exe。如果从 SOURCES_* 变量中删除 .h 文件,File format not recognized 消息应该消失。