come creare e binari .quindi, utilizzando libtool
Domanda
Ho una serie di file cpp che voglio compilare direttamente in un file binario e anche di compilare una libreria condivisa.
Ho
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)
Quando ho eseguito questo il cpp file vengono compilati due volte, una volta con libtool e una senza e, a volte, libtool/automake si lamenta
Makefile.am: object `f1.$(OBJEXT)' created both with libtool and without`
Ho provato a mettere COMMON_SOURCES in un .un file ma poi libtool si lamenta quando ho un link .una con un .la (dicendo che il suo non portatile).
Quello che mi serve è qualcosa di simile
bin_LTPROGRAMS=mybin
ma che non esiste
edit:chiarimento - sto usando automake/autoconf.Quello che ho mostrato sopra è la carne del mio automake Makefile.am
Soluzione
Il problema è che le fonti comuni devono essere compilati in modo diverso quando sono fatti in un oggetto condiviso, rispetto a quando sono fatti in un archivio statico;in caso di ex, per esempio, g++
deve essere passato il -fPIC
la bandiera.
Quello che suggerisco è l'utilizzo di due build directory.
Supponendo che questa fonte gerarchia:
./src/Makefile.am ./src/f1.cpp ./src/f2.cpp ./src/f3.cpp ./src/main.cpp ./configure.ac ./Makefile.am
si dovrebbe usare qualcosa di simile a questo ./src/Makefile.am
:
bin_PROGRAMS = mybin lib_LTLIBRARIES = libmylib.la mybin_SOURCES = main.cpp mybin_LDADD = libmylib.la libmylib_la_SOURCES = f1.cpp f2.cpp f3.cpp
Quindi si crea directory Release
e ReleaseDisableShared
in ./
.Nella directory ./Release
si esegue:
../configure && make
e in ./ReleaseDisableShared
si esegue:
../configure --disable-shared && make
Dopo la costruzione in ogni directory di compilazione, è possibile utilizzare il mybin
a ./ReleaseDisableShared/src/mybin
e il libmylib.so
a ./Release/src/libmylib.so
.
Vedere anche:
Altri suggerimenti
Link contro il libreria delle origini comuni, in particolare:
bin_PROGRAMS = mybin
lib_LTLIBRARIES = libmylib.la
mybin_SOURCES = main.cpp
mybin_LDADD = libmylib.la
libmylib_la_SOURCES = f1.cpp f2.cpp f3.cpp
Se libmylib.la
finisce per utilizzare i file che non deve essere legata in mybin
, creare un libtool convenienza biblioteca, utilizzando un Makefile.am
qualcosa di simile a questo:
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
Questo link f1.cpp
, f2.cpp
, f3.cpp
, f4.cpp
, f5.cpp
e f6.cpp
in libmylib.la
e main.cpp
, f1.cpp
, f2.cpp
e f3.cpp
in mybin
.
Se un bersaglio contiene al bersaglio CFLAGS
(o simili), automake
farà separare i file oggetto per la costruzione di quella di destinazione.Prova ad aggiungere alcuni no-op bandiere mybin
, qualcosa come:
mybin_CPPFLAGS = -I.
o
mybin_CPPFLAGS = -DDUMMY -UDUMMY
Devi dare un oggetto file creati con libtool estensione diversa, in modo che non siano in conflitto.Infatti, questi file sono file di testo contenenti informazioni di meta per entrambi i file oggetto con riposizionabile e non dal codice rilocabile (questo è controllato con -fPIC gcc argomento della riga di comando).Il vero file creati da libtool sono in genere memorizzati in ".libs" sottodirectory.La base makefile sarà simile a questa:
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 $@ $<