2016-03-26 32 views
6

Rcpp'yi BayesOpt C++ kütüphanesinden işlevselliğe genişletmek için Rcpp'yi kullanmaya çalışıyorum. Uzun süreli bir R kullanıcısıyım ancak C++ için yeni ve çalışıyorum. bazı problemlere. Bir paket kurmak için Rcpp vinyetlerini takip ettim, ki bu da dış C++ kitaplıklarını getirmenin en iyi yoludur.Rcpp: Paylaşılan nesneyi yükleyemiyor, tanımsız sembol

BayesOpt klasörüne ve kütüphanesine PKC_CPPFLAGS ve PKG_LIBS seçeneklerini src/Makevars'a ekledim ve baysOpt bazı başlık dosyaları için #include kullanan tek bir .cpp dosyası (call it test.cpp) src/var. Bu dosyada, vermek istediğim işlevin üzerinde // [[Rcpp::export]] var.

R CMD check mypackage çalıştırdığımda, kitaplık başarıyla çalışıyor gibi görünüyor - günlüğe bakarak, her şey "yüklü" olan paketi yüklemeye çalışana kadar iyi gider. Sonra, hata günlüğüne

** testing if installed package can be loaded 
Error in dyn.load(file, DLLpath = DLLpath, ...) : 
    unable to load shared object '/home/me/p3/mypackage.Rcheck/mypackage/libs/mypackage.so': 
    /home/me/p3/mypackage.Rcheck/mypackage/libs/mypackage.so: undefined symbol: _ZTIN8bayesopt13DiscreteModelE 

'u aldım. echo _ZTIN8bayesopt13DiscreteModelE | c++filt, bayesOpt üstbilgilerini kullanan test.cpp dosyasındaki ilk nesne olan typeinfo for bayesopt::DiscreteModel değerini verir. Buna bir çözüm için yüksek ve düşük baktım, ama bir tane bulamıyorum. Makevarların kütüphanede doğru bir şekilde işaret ettiğine inanmak isterim, çünkü ilk kurulum kontrolü sırasında başlık dosyalarını bulabilir - bu sadece aday paketini tanımlarken bu tanımlanmamış sembol hatası alırken. Dış kütüphaneleri kullanan bir Rcpp örneğine baktım, ama baktığım cevaplarda bir Dirk, RcppGSL, Makevars'ı dolduran 3500+ satırlık bir betik çizdi ve ayrıştırması biraz zor. .

Kimsenin yardımına minnettarım - son çare herşeyi src içine dökmek ama bu zaten hantal ve daha da zarif bir şekilde organize edilmiş bir kütüphane için zarif görünüyor.

cevap

7

Otomatik olarak oluşturulmuş olan configure komut dosyasına bakmayın - kaynağı olan configure.ac dosyasına bakın ve hangi 5 satırın hepsinin (aşağıya bakın) yanı sıra belki de 5 satırlık kurulum ve bitirme çizgisine bakın.

Özetle, her iki başlık için (-I... aracılığıyla) ve bağlantı oluşturmaya (-L... -l... aracılığıyla) gerek duymanız yeterlidir.

Ve bunun için

biz src/Makevars.in bunu: Her iki (özünde) configure ve configure.ac aracılığıyla ayarlanır @[email protected] ile gösterilir

# set by configure 
GSL_CFLAGS = @GSL_CFLAGS@ 
GSL_LIBS = @[email protected] 

# combine with standard arguments for R 
PKG_CPPFLAGS = $(GSL_CFLAGS) -I../inst/include 
PKG_LIBS = $(GSL_LIBS) 

iki değişken sadece buna sahip iddia sonra gsl-config çağırır:

## Use gsl-config to find arguments for compiler and linker flags 
## 
## Check for non-standard programs: gsl-config(1) 
AC_PATH_PROG([GSL_CONFIG], [gsl-config]) 
## If gsl-config was found, let's use it 
if test "${GSL_CONFIG}" != ""; then 
    # Use gsl-config for header and linker arguments 
    GSL_CFLAGS=`${GSL_CONFIG} --cflags` 
    GSL_LIBS=`${GSL_CONFIG} --libs` 
else 
    AC_MSG_ERROR([gsl-config not found, is GSL installed?]) 
fi 

Son on yıl içinde oluşturulan diğer birçok kitaplık, aynı amaçla kullanılan pkg-config adlı benzer (ancak daha genel) bir aracı kullanır. kütüphaneyi kullanan programlara derleme ve linker bayraklarını katın.

Ve hem mıyım , yorumunuz inanmak istiyorum

o doğru kütüphanede Makevars noktaları, ilk kurulum kontrolü sırasında başlık dosyaları bulmak mümkün olduğu için

Eğer bağlama ya da belki değil kitaplığınızın sistem hükmü derleme dizildi var ama değil gösterir. Yine, RcppGSL için oluşturma sırasında son satır Ar ve matematik kütüphanesi ile de iki GSL ilgili kitaplıkları üç kaynak dosyaları bağlayan

g++ -shared -L/usr/lib/R/lib -o RcppGSL.so \ 
RcppExports.o fastLm.o setErrorHandler.o \ 
-L/usr/lib/x86_64-linux-gnu -lgsl -lgslcblas \ 
-lm -L/usr/lib/R/lib -lR 

(kısalık için düzenlenmiş) aşağıdaki gibidir. Yapınızda benzer bir şey görmelisiniz veya doğru şekilde kurulmuyor.

Düzenleme: Eğer paket BayesOpt paket halinde, o zaman o src/Makevars bir statik kütüphane ve listeye içine inşa etmek gerekir. Bu farklı bir kullanım örneğidir: RcppGSL için sistemi GSL yüklemesini ararız. Yerel farklıdır. Her iki durumla ilgilenen nloptr paketini inceleyebilirsiniz.

+0

Hızlı ve eksiksiz yanıt için teşekkürler Dirk. Her iki yoldan devam etmeden önce - Rcpp ile R paketlerini geliştirirken bir sistem kurulumunu arayarak C++ kaynak kodunu bir statik kitaplık olarak paketlemeye göre "en iyi uygulama" var mı? C++ kütüphanesi daha "ortak" olduğunda sistem kurulumlarını aramak belki daha pratik midir? – user2476581

+2

Tam olarak. Daha özel bir kütüphaneyle çalışırken, genellikle onu paketlemeniz gerekir. Biraz daha fazla iş, biraz daha uzun bir derleme zamanı, ama siz aslında kendiniz yerdesiniz. –

+0

Tamam, bunu statik bir kütüphaneye dönüştürmeye karar verdim. Birkaç takip: 1. Statik kütüphaneyi "mypackage/inst" veya "mypackage/src" 'ye, pratik olarak mı kurmalıyım? Her iki durumda da 'R CMD mypackage'ı çalıştırdığımda, kütüphanelerin bir kaynak pakete dahil edilmemesi gerektiği uyarısını da aldım. Bu uyarı kullanım durumumla alakasız mı? – user2476581