cómo crear y usar libtool binaria .so
Pregunta
Tengo un conjunto de archivos cpp que quiero compilar directamente en un binario y también para compilar en una biblioteca compartida.
tengo
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)
Cuando ejecuto esto, los archivos cpp se compilan dos veces, una con y otra sin libtool y, a veces libtool / automake se queja
Makefile.am: object `f1.$(OBJEXT)' created both with libtool and without`
He intentado poner COMMON_SOURCES en un archivo .a pero luego se queja libtool cuando Link a .a con un .la (diciendo que no es portátil).
Lo que necesito es algo así como
bin_LTPROGRAMS=mybin
pero que existen doesnt
editar: aclaración - Estoy usando automake / autoconf. Lo que he mostrado anteriormente es la carne de mi automake Makefile.am
Solución
El problema es que las fuentes comunes necesitan ser compilados de forma diferente cuando se realizan en un objeto compartido que cuando se realizan en un archivo estático; en el caso de los antiguos por ejemplo, necesidades, g++
ser pasado la bandera -fPIC
.
Lo que sugiero es el uso de dos directorios de construcción.
Suponiendo que esta jerarquía de fuente:
./src/Makefile.am ./src/f1.cpp ./src/f2.cpp ./src/f3.cpp ./src/main.cpp ./configure.ac ./Makefile.am
se usaría algo como esto en ./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
A continuación, se crea directorios Release
y ReleaseDisableShared
en ./
. En ./Release
directorio de ejecutar:
../configure && make
y en ./ReleaseDisableShared
ejecutar:
../configure --disable-shared && make
Después de construir en cada directorio de construcción, se utiliza la mybin
en ./ReleaseDisableShared/src/mybin
y la libmylib.so
en ./Release/src/libmylib.so
.
Ver también:
Otros consejos
Enlace con la librería de fuentes comunes en concreto:
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 extremos libmylib.la
usando archivos que no deben estar vinculados a mybin
, crean un libtool conveniencia biblioteca, utilizando un Makefile.am
algo como esto:
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
Esto vinculará f1.cpp
, f2.cpp
, f3.cpp
, f4.cpp
, f5.cpp
y f6.cpp
en libmylib.la
y main.cpp
, f1.cpp
, f2.cpp
y f3.cpp
en mybin
.
Si un destino contiene CFLAGS
per-objetivo (o similar), automake
hará que los archivos de objetos separados para la construcción de ese objetivo. Trate de añadir algunas banderas no-op para mybin
, algo como:
mybin_CPPFLAGS = -I.
o
mybin_CPPFLAGS = -DDUMMY -UDUMMY
Hay que darle ficheros objeto creados con libtool una extensión diferente para que no entren en conflicto. De hecho, esos archivos son archivos de texto que contienen información de metadatos para archivos de objeto con el código reubicable y no reubicable (esto es controlado con el argumento de línea de comando gcc -fPIC). Los archivos reales creados por libtool se suelen almacenar en el subdirectorio ".libs". El makefile básica se verá así:
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 $@ $<