-fPIC
是僅編譯標誌。如果在鏈接時包含它,編譯器會對此提出投訴。如果您正在使用Makefile
編譯項目(您未包括如何使用問題中引用的變量),最好的方法是在PKG_CFLAGS
中定義-fPIC
,以防您的項目僅包含共享對象目標。我不知道Makevars的情況,但可能後續的討論會給你一些關於如何解決你的問題的提示。
如果你正在構建的程序和共享庫,最好的辦法是定義一個新的.SUFFIXES
依賴(姑且稱之爲.pic_o
),並定義一個名爲PKG_SHAREDCFLAGS=-fPIC
變量,然後包括一個規則來編譯這些依賴,因爲這片斷所示:
PKG_SHAREDCPPFLAGS = -fPIC
.SUFFIXES: .pic_o
.c.pic_o:
$(CPP) $(PKG_CPPFLAGS) $(PKG_SHAREDCPPFLAGS) -c [email protected] -o $<
libshared.so_objs = a.pic_o b.pic_o c.pic_o
libshared.so: $(libshared.so_objs)
$(CPP) $(PKG_LDFLAGS) $(LDFLAGS) -o [email protected] $(libshared.so_objs) $(libshared.so_libs)
.pic_o
是.o
文件與PIC
標誌編譯(又名P osition 我 ndependent ç ODE)這是需要用於將要成爲共享對象的一部分的對象文件。
將所有代碼編譯爲-fPIC
並不危險,因爲鏈接器將PIC文件靜態鏈接到代碼中沒有問題(位置獨立文件只會在程序中引入一點開銷,因爲編譯器會保留一個偏移寄存器控制庫的最終加載位置,這樣可以減少一個寄存器的使用)引入新的.pic_o
後綴將允許生成靜態和動態版本的庫,因此靜態版本只鏈接編譯時沒有編譯的對象-fPIC
動態的使用PIC。假設您有一個庫,由a.c
,b.c
c.c
文件組成,並且您想從它們生成動態庫和靜態庫。下面的方法將成功:
# All the targets.
targets=libA.a libA.so.3.0
TOCLEAN += $(targets)
# object files of the libA.a static library.
libA.a_objs = a.o b.o c.o
TOCLEAN += $(libA.a_objs)
# object files of the libA.so.3.0 dynamic library.
libA.so.3.0_objs = a.pic_o b.pic_o c.pic_o
TOCLEAN += $(libA.so.3.0_objs)
libA.so.3.0_libs = -lc
all: $(targets)
clean:
rm -f $(TOCLEAN)
.PHONY: all
.SUFFIXES: .pic_o
libA.a: $(libA.a_objs)
$(AR) -r [email protected] $?
$(RANLIB) [email protected]
.c.pic_o:
$(CC) $(CFLAGS) -fPIC -c $< -o [email protected]
libA.so.3.0: $(libA.so.3.0_objs)
$(LD) -shared $(libA.so.3.0_objs) $(libA.so.3.0_libs) -o [email protected]
和執行:
[email protected]:~/pru_19091$ make clean all
rm -f libA.a libA.so.3.0 a.o b.o c.o a.pic_o b.pic_o c.pic_o
cc -O2 -pipe -c a.c -o a.o
cc -O2 -pipe -c b.c -o b.o
cc -O2 -pipe -c c.c -o c.o
ar -r libA.a a.o b.o c.o
ar: warning: creating libA.a
ranlib libA.a
cc -O2 -pipe -fPIC -c a.c -o a.pic_o
cc -O2 -pipe -fPIC -c b.c -o b.pic_o
cc -O2 -pipe -fPIC -c c.c -o c.pic_o
ld -shared a.pic_o b.pic_o c.pic_o -lc -o libA.so.3.0
想我碰文件b.c
:
[email protected]:~/pru_19091$ touch b.c
[email protected]:~/pru_19091$ make
cc -O2 -pipe -c b.c -o b.o
ar -r libA.a b.o
ranlib libA.a
cc -O2 -pipe -fPIC -c b.c -o b.pic_o
ld -shared a.pic_o b.pic_o c.pic_o -lc -o libA.so.3.0
你的問題有沒有關係RCPP,真的,但表示存在問題,你正在創建一個可用的R包(考慮到你自己施加的限制)。一個十幾年來一直在做這件事的oldie-but-goldie是Matrix軟件包,它的[src/Makevars](https://github.com/cran/Matrix/blob/master/src/Makevars)可能會幫助你您。 –
@DirkEddelbuettel「你的問題與Rcpp無關,」爲了其他讀者,你怎麼知道這一點?這是什麼意思?在devtools :: load_all()後,錯誤狀態爲「用-fPIC重新編譯」,即使包含此標誌。這看起來像一個Rcpp問題:http:// stackoverflow。com/questions/21094740/linking-rcpp-to-interp2d-gsl-type-library – EB2127
如何設置'src/Makevars'與使用編譯代碼的R包相關。對於Rcpp,我們只是使用標準的R構建工具和說明,這就是您遇到的問題。並且很簡單:錯誤信息來自編譯器,您用來驅動它的工具可能是'devtools'。再次,沒有Rcpp在這裏。 –