2016-07-22 40 views
0

我正試圖將C庫合併到某些Rcpp代碼中。試圖使用外部庫時未定義的參考

我可以很容易地在C++程序中使用C庫。我'製作'C庫,它在/ lib文件夾中創建.a和.dll文件。然後我就可以通過在程序中的頭和命令行運行這樣使用包:

cc myfile.cpp -o myfile -Ipath.to.header path.to.lib.a -lz 

這實質上告訴編譯器採取的.cpp程序,包括頭從-I和鏈接到兩個圖書館。

如果我正確理解makevars(不幸的是我似乎並不這麼認爲),那麼使用Rcpp就不會太困難。

我的庫添加到文件夾中我的包,並在SRC我添加makevars和makevars.win看起來像這樣:

PKG_CFLAGS= 
# specify header location 
PKG_CPPFLAGS=-Ipath.to.lib/include 
# specify libs to link to 
PKG_LIBS=path.to.lib/lib/file.a -lz 
# make library 
path.to.lib/lib/file.a: 
      cd path.to.lib;$(MAKE) 

這正確「使」的u和.dll文件對於圖書館來說,然而沒有任何Rcpp魔法運行(即在構建中,我從來沒有看到編譯src文件的g++系統調用),所以「沒有創建Dll」。

我相當確定這是我makevars目標中的問題,使庫。當我從makevars中刪除這部分,並在構建包之前從命令行「創建」庫時,我使用-I和-l語句獲得正確的g++調用,但是我收到有關未定義引用的錯誤。

我注意到-l語句只包含在最後的g++調用中,最後的.dll文件被創建,但沒有包含在前面g++調用中,其中包含庫頭文件被編譯。

所以,我有兩個問題:

  • 如何解決我的makevars,使其「使」庫中,但不會在SRC編譯文件停止RCPP?

  • 我該如何處理未定義的引用?庫顯然不是標題,所以我猜它需要早期的g++調用中的-l語句,但這可能不可能。

回答

2

最好的辦法是避免複雜的src/Makevars文件。

圍繞此方法的一個簡單的方法是:使用configure來構建靜態庫,然後一旦實際構建,只需在src/Makevars中引用它即可。

我在Rblpapi(我們在其中複製外部提供的庫)和nloptr中使用該方案,在那裏我們下載nlopt源並在需要時構建它(即,當系統中沒有libnlopt時)。