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

¿Fue útil?

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 $@ $<
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top