Вопрос

У меня есть набор файлов 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 $@ $<
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top