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

È stato utile?

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 $@ $<
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top