Libtool lenteur, double bâtiment?
Question
Dans mon projet, les modules sont organisés en subdirs par souci de cohérence.
Mon projet hiérarchie dir:
$ 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 / log / Makefile.am:
INCLUDES = $(all_includes)
METASOURCES = AUTO
noinst_LTLIBRARIES = liblog.la
liblog_la_SOURCES = log.cpp
src / main.cpp:. contient int main(){}
, src / log / log.cpp contient void f(){}
invocation make
produit (édité par souci de concision):
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
Le problème est les trois premières lignes: log.cpp est compilé deux fois
La question: Pourquoi est-ce pas juste compilé une fois - en prenant la moitié du temps
Note: Je ne sais pas ce que je fais - autotools est la magie noire pour moi, mais nous devons l'utiliser à notre place. Les documents sont incompréhensibles pour moi.
La solution
Par défaut Libtool crée deux types de bibliothèques: statiques et partagées. (Aka libtruc.a et libfoo.so)
statique et tesson exigent des drapeaux de compilation différentes. bibliothèques dynamiques - objets partagés Position d'utilisation du code indépendant avec des drapeaux suivants gcc:
-fPIC -DPIC
statique ne sont pas. Vous pouvez forcer la construction d'un seul type par specifing
./configure --disable-shared
ou
./configure --disable-static
Justification
Habituellement, lorsque la bibliothèque est fournie pour l'utilisateur à fournir, dans deux configurations - statique pour le développement qui permet de créer statique et dynamique pur construit pour être utilisé par la plupart des programmes qui utilisent cette bibliothèque. Donc, généralement lorsque vous installez la bibliothèque dans le système vous installez uniquement un objet partagé. (Aka libfoo_XYZ.deb)
Lorsque vous ajoutez la version de développement (aka libfoo-dev_XYZ.deb) vous ajoutez les en-têtes et statiquement construire la version de la bibliothèque qui permet aux utilisateurs font construit STAIC si elles whant.
Cette pratique est courante pour les bibliothèques d'expédition sous UNIX. Ainsi fait cela pour libtool automatiquement.