как создать двоичный файл и .so с помощью libtool - PullRequest
9 голосов
/ 31 августа 2010

У меня есть набор файлов cpp, которые я хочу скомпилировать непосредственно в двоичный файл, а также скомпилировать в общую библиотеку.

У меня есть

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)

Когда я запускаю этоФайлы cpp компилируются дважды, один раз с помощью libtool, один раз без, а иногда libtool / automake жалуется

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

Я пытался поместить COMMON_SOURCES в файл .a, но затем libtool жалуется, когда я связываю .a с .la(говорит, что он не переносимый).

Мне нужно что-то вроде

bin_LTPROGRAMS=mybin

, но этого не существует

edit: разъяснение - я использую automake / autoconf.То, что я показал выше, - это мясо моего автопроизводителя Makefile.am

Ответы [ 4 ]

4 голосов
/ 02 сентября 2010

Ссылка на библиотеку общих источников, а именно:

bin_PROGRAMS = mybin
lib_LTLIBRARIES = libmylib.la

mybin_SOURCES = main.cpp
mybin_LDADD = libmylib.la
libmylib_la_SOURCES = f1.cpp f2.cpp f3.cpp

Если libmylib.la заканчивается использованием файлов, которые не должны быть связаны с mybin, создайте удобную библиотеку libtool , используя Makefile.am примерно так:

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

Это свяжет f1.cpp, f2.cpp, f3.cpp, f4.cpp, f5.cpp и f6.cpp в libmylib.laи main.cpp, f1.cpp, f2.cpp и f3.cpp в mybin.

3 голосов
/ 03 сентября 2010

Проблема в том, что общие источники должны компилироваться иначе, когда они превращаются в общий объект, чем когда они превращаются в статический архив; в случае первого, например, g++ необходимо передать флаг -fPIC.

Я предлагаю использовать две директории сборки.

Предполагая эту исходную иерархию:

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

вы бы использовали что-то подобное в ./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

Затем вы создаете каталоги Release и ReleaseDisableShared в ./. В каталоге ./Release вы запускаете:

../configure && make

и в ./ReleaseDisableShared вы запускаете:

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

После сборки в каждом каталоге сборки вы используете mybin в ./ReleaseDisableShared/src/mybin и libmylib.so в ./Release/src/libmylib.so.

Смотри также:

2 голосов
/ 03 сентября 2010

Если цель содержит для каждой цели CFLAGS (или подобное), automake создаст отдельные объектные файлы для построения этой цели.Попробуйте добавить несколько неактивных флагов в mybin, например:

mybin_CPPFLAGS = -I.

или

mybin_CPPFLAGS = -DDUMMY -UDUMMY
0 голосов
/ 02 сентября 2010

Вы должны дать объектным файлам, созданным с помощью libtool, другое расширение, чтобы они не конфликтовали.Фактически, эти файлы представляют собой текстовые файлы, содержащие метаинформацию для объектных файлов с перемещаемым и неразмещаемым кодом (это контролируется аргументом командной строки -fPIC gcc).Реальные файлы, созданные libtool, обычно хранятся в подкаталоге ".libs".Основной make-файл будет выглядеть так:

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 $@ $<
...