Медлительность Libtool, двойное построение?
Вопрос
В моем проекте модули организованы во вложенные папки для удобства.
Иерархия директорий моего проекта:
$ ls -R
.: configure.in Makefile.am Makefile.cvs src
./src: log Makefile.am main.cpp
./src/log: log.cpp Makefile.am
configure.in:
AC_INIT(configure.in)
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(myapp, 0.1)
AC_LANG_CPLUSPLUS
AC_PROG_CXX
AM_PROG_LIBTOOL
AC_OUTPUT(Makefile src/Makefile src/log/Makefile)
Makefile.am:
AUTOMAKE_OPTIONS = foreign
SUBDIRS = src
Файл Makefile.cvs:
default:
aclocal
libtoolize --force --copy
autoheader
automake --add-missing --copy
autoconf
src/Makefile.am - файл на сервере
bin_PROGRAMS = myapp
myapp_SOURCES = main.cpp
SUBDIRS = log
myapp_LDADD = $(top_builddir)/src/log/liblog.la
src/журнал/Makefile.am:
INCLUDES = $(all_includes)
METASOURCES = AUTO
noinst_LTLIBRARIES = liblog.la
liblog_la_SOURCES = log.cpp
src/main.cpp: содержит int main(){}
, src/log/log.cpp содержит void f(){}
.
Вызывающий make
производит (отредактировано для краткости):
libtool --mode=compile g++ -MT log.lo -MD -MP -MF .deps/log.Tpo -c -o log.lo log.cpp
libtool: compile: g++ -MT log.lo -MD -MP -MF .deps/log.Tpo -c log.cpp -fPIC -DPIC -o .libs/log.o
libtool: compile: g++ -MT log.lo -MD -MP -MF .deps/log.Tpo -c log.cpp -o log.o >/dev/null 2>&1
mv -f .deps/log.Tpo .deps/log.Plo
libtool --mode=link g++ -o liblog.la log.lo
libtool: link: ar cru .libs/liblog.a .libs/log.o
libtool: link: ranlib .libs/liblog.a
libtool: link: ( cd ".libs" && rm -f "liblog.la" && ln -s "../liblog.la" "liblog.la" )
g++ -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.cpp
mv -f .deps/main.Tpo .deps/main.Po
libtool --mode=link g++ -o myapp main.o ../src/log/liblog.la
libtool: link: g++ -o myapp main.o ../src/log/.libs/liblog.a
Проблема в первых трех строках: log.cpp компилируется дважды!
Этот вопрос: почему он просто не компилируется один раз, что занимает половину времени?
примечание: Я понятия не имею, что я делаю - autotools для меня - черная магия, но мы должны использовать ее на нашем месте.Документы для меня непонятны.
Решение
По умолчанию Libtool создает два типа библиотек:статичный и общий.(он же libfoo.a и libfoo.so)
Для Static и shard требуются разные флаги компиляции.Динамические библиотеки - разделяемые объекты используйте код, не зависящий от позиции, со следующими флагами gcc:
-fPIC -DPIC
Статические - нет.Вы можете принудительно создать только один тип, указав
./configure --disable-shared
или
./configure --disable-static
Обоснование
Обычно, когда библиотека предоставляется пользователю, она предоставляется в двух вариантах - статическая для разработки, что позволяет создавать чисто статические сборки, и динамическая для использования большинством программ, использующих эту библиотеку.Итак, обычно, когда вы устанавливаете библиотеку в системе вы устанавливаете только общий объект.(он же libfoo_XYZ.deb)
Когда вы добавляете версию для разработки (она же libfoo-dev_XYZ.deb), вы добавляете заголовки и статически создаете версию библиотеки, которая позволяет пользователям выполнять простые сборки, если они захотят.
Это обычная практика для доставки библиотек в UNIX.Таким образом, libtool делает это за вас автоматически.