-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.c
c.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
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. –
@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
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. –