Как создать двоичный и .so с помощью libtool
Вопрос
У меня есть набор файлов 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
Но это не существует
Редактировать: разъяснение - я использую Automake / AutoConf. То, что я показал выше, это мясо моего автоматики Makefile.am
Решение
Вопрос состоит в том, что общие источники должны быть скомпилированы по-разному, когда они вступают в общий объект, чем когда они превращаются в статический архив; В случае первого, например, 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
.
Смотрите также:
Другие советы
Ссылка против библиотеки общих источников конкретно:
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
.
Если цель содержит в соответствии с целью CFLAGS
(или похожие), automake
сделает отдельные объектные файлы для построения этой цели. Попробуйте добавить несколько флагов в формате mybin
, что-то типа:
mybin_CPPFLAGS = -I.
или
mybin_CPPFLAGS = -DDUMMY -UDUMMY
Вы должны дать объектные файлы, созданные с помощью LibTool другого расширения, поэтому они не конфликтуют. Фактически, эти файлы представляют собой текстовые файлы, содержащие мета-информацию для файлов объектов с ReloCatable, так и нерестозаданного кода (это управляется с аргументом командной строки GCC GCC). Настоящие файлы, созданные LibTool, обычно хранятся в подкаталоге «.Libs». Основной Makefile будет выглядеть так:
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 $@ $<