comment créer binaire et .so en utilisant libtool
Question
J'ai un ensemble de fichiers cpp que je veux compiler directement dans un fichier binaire et aussi de compiler dans une bibliothèque partagée.
Je
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)
Quand je lance ce les fichiers cpp sont compilés deux fois, une fois avec libtool et une fois sans et parfois libtool / automake se plaint
Makefile.am: object `f1.$(OBJEXT)' created both with libtool and without`
J'ai essayé de mettre COMMON_SOURCES dans un fichier .a mais quand je libtool se plaint liez une .a avec un .la (affirmant que son non portable).
Ce que je dois quelque chose comme
bin_LTPROGRAMS=mybin
mais cela n'existe
edit: clarification - J'utilise automake / autoconf. Ce que je l'ai montré ci-dessus est la viande de mon automake Makefile.am
La solution
Le problème est que les sources communes doivent être compilées différemment quand ils sont faits dans un objet partagé que quand ils sont faits dans une archive statique; dans le cas de l'ancien, par exemple, g++
doit être passé le drapeau -fPIC
.
Ce que je suggère est d'utiliser deux répertoires de construction.
En supposant cette hiérarchie source:
./src/Makefile.am ./src/f1.cpp ./src/f2.cpp ./src/f3.cpp ./src/main.cpp ./configure.ac ./Makefile.am
vous pouvez utiliser quelque chose comme ça dans ./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
Ensuite, vous créez des répertoires Release
et ReleaseDisableShared
dans ./
. Dans le répertoire ./Release
vous exécutez:
../configure && make
et ./ReleaseDisableShared
vous exécutez:
../configure --disable-shared && make
Après la construction dans chaque répertoire de construction, vous utilisez la mybin
à ./ReleaseDisableShared/src/mybin
et libmylib.so
à ./Release/src/libmylib.so
.
Voir aussi:
Autres conseils
Link contre la bibliothèque de sources communes spécifiquement:
bin_PROGRAMS = mybin
lib_LTLIBRARIES = libmylib.la
mybin_SOURCES = main.cpp
mybin_LDADD = libmylib.la
libmylib_la_SOURCES = f1.cpp f2.cpp f3.cpp
Si libmylib.la
finit par utiliser des fichiers qui ne doivent pas être liés à mybin
, créez un libtool commodité bibliothèque , en utilisant un quelque chose Makefile.am
comme ceci:
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
reliera f1.cpp
, f2.cpp
, f3.cpp
, f4.cpp
, f5.cpp
et f6.cpp
dans libmylib.la
et main.cpp
, f1.cpp
, f2.cpp
et f3.cpp
dans mybin
.
Si une cible contient CFLAGS
par cible (ou similaire), automake
fera des fichiers objet pour la construction de cet objectif. Essayez d'ajouter des drapeaux no-op à mybin
, quelque chose comme:
mybin_CPPFLAGS = -I.
ou
mybin_CPPFLAGS = -DDUMMY -UDUMMY
Vous devez donner des fichiers objets créés avec libtool une extension différente de sorte qu'ils ne sont pas en conflit. En fait, ces fichiers sont des fichiers texte contenant des méta-informations pour les fichiers objets avec le code délocalisables et non délocalisables (ceci est contrôlé avec l'argument de ligne de commande gcc -fPIC). Les fichiers réels créés par libtool sont généralement stockés dans sous-répertoire « .libs ». Le makefile de base ressemblera à ceci:
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 $@ $<