wie erstellen binären und .so mit libtool
Frage
Ich habe eine Reihe von CPP-Dateien, dass ich direkt in ein binäres kompilieren wollen und auch in eine gemeinsame Bibliothek zu kompilieren.
Ich habe
bin_PROGRAMS=mybin
lib_LTLIBRARIES=libmylib.la
COMMON_SOURCES=f1.cpp f2.cpp f3.cpp
mybin_SOURCES=main.cpp $(COMMON_SOURCES)
libmylib_la_SOURCES=$(COMMON_SOURCES)
Wenn ich laufen diese die CPP-Dateien zweimal kompiliert werden, einmal mit und einmal ohne libtool und manchmal libtool / auto klagt
Makefile.am: object `f1.$(OBJEXT)' created both with libtool and without`
habe ich versucht, COMMON_SOURCES in eine .a-Datei setzen, aber dann libtool beschwert, wenn ich eine .a mit einem .la verknüpfen (sagen, es ist nicht tragbar).
Was ich brauche, ist so etwas wie
bin_LTPROGRAMS=mybin
, aber das tut exist
edit: Klarstellung - ich bin mit auto / autoconf. Was ich oben ist das Fleisch von meinem auto Makefile.am
gezeigtLösung
Das Problem ist, dass die gemeinsamen Quellen müssen unterschiedlich kompiliert werden, wenn sie in einem gemeinsamen Objekt gemacht werden, als wenn sie in ein statisches Archiv gemacht werden; im Fall der ehemaligen, zum Beispiel g++
Bedürfnisse der -fPIC
Flagge übergeben werden.
Was ich vorschlagen, ist die Verwendung von zwei Build-Verzeichnisse.
Unter der Annahme dieser Quellhierarchie:
./src/Makefile.am ./src/f1.cpp ./src/f2.cpp ./src/f3.cpp ./src/main.cpp ./configure.ac ./Makefile.am
Sie so etwas wie dies in ./src/Makefile.am
verwenden würden:
bin_PROGRAMS = mybin lib_LTLIBRARIES = libmylib.la mybin_SOURCES = main.cpp mybin_LDADD = libmylib.la libmylib_la_SOURCES = f1.cpp f2.cpp f3.cpp
Dann erstellen Sie Verzeichnisse Release
und ReleaseDisableShared
in ./
. Im Verzeichnis ./Release
Sie ausführen:
../configure && make
und in ./ReleaseDisableShared
Sie laufen:
../configure --disable-shared && make
Nach dem in jedem Build-Verzeichnis erstellen, verwenden Sie die mybin
bei ./ReleaseDisableShared/src/mybin
und die libmylib.so
bei ./Release/src/libmylib.so
.
Siehe auch:
Andere Tipps
Link gegen die Bibliothek von gemeinsamen Quellen im Einzelnen:
bin_PROGRAMS = mybin
lib_LTLIBRARIES = libmylib.la
mybin_SOURCES = main.cpp
mybin_LDADD = libmylib.la
libmylib_la_SOURCES = f1.cpp f2.cpp f3.cpp
Wenn libmylib.la
Ende Dateien verwenden, die nicht in mybin
verknüpft werden soll, erstellen Sie eine libtool Bequemlichkeit Bibliothek , ein Makefile.am
so etwas wie dies mit:
bin_PROGRAMS = mybin
noinst_LTLIBRARIES = libcommon.la
lib_LTLIBRARIES = libmylib.la
mybin_SOURCES = main.cpp
mybin_LDADD = libcommon.la
libmylib_la_SOURCES = f4.cpp f5.cpp f6.cpp
libmylib_la_LIBADD = libcommon.la
libcommon_la_SOURCES = f1.cpp f2.cpp f3.cpp
Dies wird verlinken f1.cpp
, f2.cpp
, f3.cpp
, f4.cpp
, f5.cpp
und f6.cpp
in libmylib.la
und main.cpp
, f1.cpp
, f2.cpp
und f3.cpp
in mybin
.
Wenn ein Ziel pro-Ziel enthält CFLAGS
(oder ähnlich), automake
werden getrennte Objektdateien machen für dieses Ziel zu bauen. Versuchen Sie, einige no-op-Flags zu mybin
, so etwas wie:
mybin_CPPFLAGS = -I.
oder
mybin_CPPFLAGS = -DDUMMY -UDUMMY
Sie haben Objektdateien mit libtool einer anderen Erweiterung geschaffen geben, damit sie nicht in Konflikt zu tun. In der Tat sind diese Dateien Textdateien Metainformationen für beiden Objektdateien mit verschiebbarem und nicht-relocatable Code enthalten (dies wird mit -fPIC gcc Befehlszeilenargument gesteuert). Die eigentlichen Dateien, die von libtool erstellt werden, in der Regel in „.libs“ Unterverzeichnis gespeichert. Die grundlegende Make-Datei wie folgt aussehen:
CC = $(CXX)
LIBTOOL = libtool --quiet
SRC = lib.cpp test.cpp
LIB_SRC = lib.cpp $(SRC)
LIB_OBJ = $(LIB_SRC:.cpp=.lo)
EXE_SRC = exe.cpp $(SRC)
EXE_OBJ = $(EXE_SRC:.cpp=.o)
EXE = test
LIB = libmylib.la
all: $(EXE) $(LIB)
clean:
$(RM) *.o *.lo $(EXE) $(LIB)
$(EXE): $(EXE_OBJ)
$(LIB): $(LIB_OBJ)
$(LIBTOOL) --tag=CXX --mode=link $(LINK.cc) -shared -version-info 1:0 -rpath $(shell readlink -f .) -o $@ $< $(LDLIBS)
%.o: %.cpp
$(COMPILE.cc) -o $@ $<
%.lo: %.cpp
$(LIBTOOL) --mode=compile --tag=CXX $(COMPILE.cc) -o $@ $<