2010-08-30 18 views
9

Tengo un conjunto de archivos cpp que quiero compilar directamente en un archivo binario y también para compilar en una biblioteca compartida.cómo crear archivos binarios y .so usando libtool

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 vez con libtool y otra sin él y, a veces libtool/automake se queja

Makefile.am: object `f1.$(OBJEXT)' created both with libtool and without` 

He intentado poner COMMON_SOURCES en una. un archivo pero luego libtool se queja cuando enlace un .a con un .la (diciendo que no es portátil).

Lo que necesito es algo así como

bin_LTPROGRAMS=mybin 

pero eso no existen

edición: aclaración - Estoy usando automake/autoconf. Lo que he mostrado anteriormente es la base de mi automake Makefile.am

+0

no creo que usted puede hacer bibliotecas compartidas con libtool. Creo que necesitas usar el compilador. Pero has olvidado algunos detalles. Parece que está utilizando alguna forma de auto fabricación, etc. Por lo tanto, debe indicarnos la configuración exacta que está utilizando (ya que no parece ser una marca recta). –

+3

libtool es específicamente para hacer bibliotecas compartidas http://www.gnu.org/software/libtool/manual/libtool.html – pm100

+0

¿Por qué quieres crear 'libmylib.so', pero en lugar de vincular' mybin' a este compartido objeto, enlace estáticamente en las fuentes que lo componen? –

Respuesta

3

La cuestión es que las fuentes comunes necesitan ser compilados de forma diferente cuando se realizan en un objeto compartido de cuando se están convirtiendo en un archivo estático; en el caso del primero, por ejemplo, g++ necesita pasar el indicador -fPIC.

Lo que sugiero es utilizar dos directorios de compilación.

Suponiendo que esta jerarquía de origen:

 
./src/Makefile.am 
./src/f1.cpp 
./src/f2.cpp 
./src/f3.cpp 
./src/main.cpp 
./configure.ac 
./Makefile.am 

que 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, crear directorios y ReleaseReleaseDisableShared en ./. En el directorio ./Release ejecutar:

../configure && make 

y en ./ReleaseDisableShared ejecutar:

../configure --disable-shared && make 

Después de construir en cada directorio de construcción, se utiliza el mybin en ./ReleaseDisableShared/src/mybin y la libmylib.so en ./Release/src/libmylib.so.

Consulte también:

+0

esto es lo que terminé haciendo, aproximadamente (necesito tanto el binario como el lib para compilar ambos en 2 directorios diferentes) – pm100

0

Debe dar a los archivos de objetos creados con libtool una extensión diferente para que no entren en conflicto. De hecho, esos archivos son archivos de texto que contienen metainformación para ambos archivos de objeto con código reubicable y no reubicable (esto se controla con el argumento de línea de comando -fPIC gcc). Los archivos reales creados por libtool generalmente se almacenan 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 [email protected] $< $(LDLIBS) 

%.o: %.cpp 
    $(COMPILE.cc) -o [email protected] $< 

%.lo: %.cpp 
    $(LIBTOOL) --mode=compile --tag=CXX $(COMPILE.cc) -o [email protected] $< 
+0

Thx. Pero automake hace exactamente esto. Es por eso que termino con el mensaje de error de tener tanto .o como .lo. Lo que necesito es compilar solo una vez para .lo y tener los archivos .lo vinculados en el binario y el lib. La única diferencia entre el .o y .lo es que uno tiene -fPIC y el otro no (y el código de vinculación -fPIC en el binario es inofensivo) – pm100

+1

No se puede vincular con archivos .lo, esos son solo archivos de texto y no un objeto código. En mi ejemplo, sin embargo, compila dos veces. Si desea vincular el objeto con archivos de código no reubicables (".o") creados por libtool, puede encontrarlos en su directorio de compilación, bajo el subdirectorio ".libs". –

4

Enlace con la librería de fuentes comunes específicamente:

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 termina usando archivos que no deben estar vinculados a mybin, crear un libtool convenience library, 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.

+0

hice esto pero terminé con libmylib.la enlazado dinámicamente en mybin. Lo quiero estático Puse mybin_LDFLAGS = -static pero igual terminó siendo dinámico – pm100

+0

Si quiere que 'mybin' esté vinculado estáticamente, creo que libtool querrá que ponga' mybin_LDFLAGS = -all-static', no '-static'. Ver 'info (libtool) Modo enlace'. Tenga en cuenta que esto romperá las compilaciones '--disable-static', a menos que haga algo como' AM_CONDITIONAL ([HAVE_STATIC], [test "$ enable_static" = yes]) 'y ponga el' -all-static' dentro de un condicional. –

+0

@ pm100: cuando dices que probaste esto, ¿enlazaste directamente con 'libmylib.la', o con una biblioteca de conveniencia? Puede darse el caso de que una biblioteca de conveniencia se vincule estáticamente, y eso será lo menos problemático para usted. Intenta usar una biblioteca de conveniencia. –

1

Si un destino contiene por objetivo CFLAGS (o similar), automake creará archivos de objeto separados para compilar ese objetivo. Trate de añadir algunas banderas no-op para mybin, algo así como:

mybin_CPPFLAGS = -I. 

o

mybin_CPPFLAGS = -DDUMMY -UDUMMY 
+2

gross: P ...... –

Cuestiones relacionadas