代码之家  ›  专栏  ›  技术社区  ›  JRR

链接到另一个包-未定义的符号

  •  1
  • JRR  · 技术社区  · 7 年前

    我试图使用包中的c++类 rlas (在起重机上)。我写了如下:

    #include <Rcpp.h>
    #include <rlasstreamer.h>
    
    // [[Rcpp::depends(rlas)]]
    
    using namespace Rcpp;
    
    // [[Rcpp::export]]
    void f(CharacterVector file)
    {
      RLASstreamer lasstreamer(file);
      return;
    }
    

    LinkingTo: Rcpp,rlas 在里面 DESCRIPTION . 该包进行编译,因此找到了头,但未链接库:

    undefined symbol: _ZN12RLASstreamerD1Ev
    

    linkage命令看起来与 RLA

    g++ -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o pkgname.so function_f.o RcppExports.o -L/usr/lib/R/lib -lR
    

    Makevars home/ .

    PKG_LIBS= /home/user/R/x86_64-pc-linux-gnu-library/3.4/rlas/libs/rlas.so
    

    而且有效!

    我相信这是 Rcpp::depends RLA

    1 回复  |  直到 7 年前
        1
  •  1
  •   Ralf Stubner    7 年前

    而不是在 Makevars 您可以在 configure . 下面是一些可用于查找库位置的R代码:

    libs.dir <- system.file( "libs", package = "rlas")
    paste0(libs.dir, .Platform$file.sep, "rlas", .Platform$dynlib.ext)
    

    rlas rlas.package.skeleton 功能。例如,请参阅我的RcppArrayFire包:

    编辑:这里有一个计算出来的例子:

    创建包骨架对目录的更改

    $ Rscript -e "Rcpp::Rcpp.package.skeleton()"
    $ cd anRpackage
    

    创建或更新一些文件:

    $ cat configure
    #!/bin/sh
    RLAS_LIBS=`Rscript -e "cat(system.file('libs', 'rlas.so', package = 'rlas'))"`
    sed -e "s|@RLAS_LIBS@|${RLAS_LIBS}|" src/Makevars.in > src/Makevars
    
    $ cat cleanup
    #!/bin/sh
    rm -f src/Makevars src/*.o src/*.so
    
    $ cat src/Makevars.in 
    PKG_LIBS = @RLAS_LIBS@
    
    $ cat src/rcpp_hello_world.cpp 
    #include <Rcpp.h>
    #include <rlasstreamer.h>
    
    // [[Rcpp::export]]
    void rcpp_hello_world() {
      RLASstreamer lasstreamer("foo");
      return;
    }
    
    $ grep rlas DESCRIPTION
    LinkingTo: Rcpp, rlas
    

    编译Rcpp属性:

    $ Rscript -e "Rcpp::compileAttributes()"
    

    $ R CMD build .
    [...]
    $ R CMD check anRpackage_1.0.tar.gz 
    [...]
    $ R CMD INSTALL anRpackage_1.0.tar.gz 
    [...]
    g++ -shared -L/usr/lib/R/lib -Wl,-z,relro -o anRpackage.so RcppExports.o rcpp_hello_world.o /usr/local/lib/R/site-library/rlas/libs/rlas.so -L/usr/lib/R/lib -lR
    [...]
    

    这里,来自链接器的命令行很有趣。它表明 rlas.so

    $ Rscript -e "anRpackage::rcpp_hello_world()"
    ERROR: cannot open file 'foo'
    ERROR: cannot open lasreadertxt with file name 'foo'
    Fehler in anRpackage::rcpp_hello_world() : 
      LASlib internal error. See message above.
    Execution halted
    

    所以当我们得到一个错误时,这是一个来自LASlib的错误,它包含在 苏莱士 . 如果我们看看 ldd 苏莱士

    $ ldd ~/R/x86_64-pc-linux-gnu-library/3.5/anRpackage/libs/anRpackage.so
        linux-vdso.so.1 (0x00007ffe4c79d000)
        /usr/local/lib/R/site-library/rlas/libs/rlas.so (0x00007fede63fc000)
        libR.so => /usr/lib/libR.so (0x00007fede5d7a000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fede59f8000)
    [...]
    
    推荐文章