2016-11-21 3 views
0

ich dabei bin der Verknüpfung eine statische Bibliothek und dynamische Bibliothek, aber ich in diesen Fehler laufen:Verknüpfung von dynamischen und statischen Bibliotheken RCPP

/usr/bin/ld: ../src/SeqLib/bin//libseqlib.a(libseqlib_a-FermiAssembler.o): relocation R_X86_64_32S against `_ZNSs4_Rep20_S_empty_rep_storageE' can not be used when making a shared object; recompile with -fPIC 

Hier ist, wie meine makevars Datei wie folgt aussieht:

(cd SeqLib; ./configure --enable-shared; make) 
PKG_CPPFLAGS= -I../src/SeqLib/ -I../src/SeqLib/fermi-lite/ -I../src/SeqLib/htslib/cram/ -I../src/SeqLib/htslib/htslib/ -I../src/SeqLib/htslib/ -I../src/SeqLib/bwa/ 
PKG_LIBS=-fPIC -enable-shared-lib -L../src/SeqLib/bin/ -lbwa -lfml -lhts -lseqlib 

Ich verstehe nicht, warum ich diesen Fehler erhalte, wenn ich die -fPIC Option in der PKG_LIBS Variable einschließe.

+1

Ihre Frage nichts mit RCPP zu tun haben, wirklich, aber zeigen Probleme, die Sie haben ein funktionierendes R-Paket (aufgrund Ihrer selbst auferlegten Einschränkungen). Ein Oldie-but-Goldie, der das seit über einem Jahrzehnt tut, ist das Matrix-Paket und seine [src/Makevars] (https://github.com/cran/Matrix/blob/master/src/Makevars) können helfen Sie. –

+1

@DirkEddelbuettel "Ihre Frage hat nichts mit Rcpp zu tun." Um der anderen Leser willen, woher wissen Sie das? Was bedeutet das? Der Fehler besagt "Kompilieren mit -fPIC" nach "Devtools :: load_all()", auch wenn dieses Flag enthalten ist. Dies sieht wie ein Rcpp-Problem aus: http: // stackoverflow.com/questions/21094740/linking-rcpp-zu-interp2d-gsl-type-library – EB2127

+1

Wie Sie 'src/Makevars' einrichten, ist relevant für R-Pakete mit kompiliertem Code. Für Rcpp verwenden wir nur Standard-R-Build-Tools und -Anweisungen, und damit haben Sie Probleme. Und um es klar zu sagen: Die Fehlermeldung kommt vom Compiler, das Tool, mit dem Sie es steuern, kann 'Devtools' sein. Auch hier ist kein Rcpp drin. –

Antwort

2

-fPIC ist ein Kompilieren nur Flagge. Wenn Sie es beim Linken einbeziehen, wird sich der Compiler darüber beschweren. Wenn Sie eine Makefile verwenden, um Ihr Projekt zu kompilieren (Sie haben nicht verwendet, wie Sie die in Ihrer Frage zitierten Variablen verwenden), ist der beste Ansatz, -fPIC in der PKG_CFLAGS zu definieren, falls Ihr Projekt nur gemeinsame Objektziele enthält. Ich kenne den Fall eines Makevars nicht, aber wahrscheinlich wird die folgende Diskussion Ihnen einige Hinweise geben, wie Sie Ihr Problem lösen können.

Wenn Sie Programme bauen und gemeinsam genutzte Bibliotheken, der beste Ansatz ist es, eine neue .SUFFIXES Abhängigkeit zu definieren (nennen wir es .pic_o) und eine Variable definieren genannt PKG_SHAREDCFLAGS=-fPIC und umfasst dann eine Regel, diese Abhängigkeiten zu kompilieren, wie dieser Ausschnitt zeigt:

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 sind .o Dateien mit der PIC kompilierte flag (aka P osition I ndependent C ode), die erforderlich ist, für Objektdateien, die Teil eines gemeinsamen Objekts sein werden.

Es ist nicht gefährlich, all Ihren Code als zu kompilieren, da der Linker kein Problem hat, PIC-Dateien statisch in Ihren Code einzubinden (positionsunabhängige Dateien verursachen nur einen kleinen Overhead in Ihrem Programm, da der Compiler ein Offset-Register reserviert Die Einführung eines neuen .pic_o Suffix ermöglicht es, statische und dynamische Versionen Ihrer Bibliothek zu erstellen, so dass die statische nur Objekte verknüpft, die ohne kompiliert wurden und die dynamische verwendet die PIC. Nehmen wir an, Sie haben eine Bibliothek, bestehend aus a.c, b.cc.c Dateien, und Sie möchten eine dynamische und eine statische Bibliothek von ihnen erstellen. Der folgende Ansatz wird Erfolg:

# 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] 

und Ausführung:

[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 

Angenommen, ich berühre Datei 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 
Verwandte Themen