Reputation:
In my project, modules are organized in subdirs for tidiness.
My project dir hierarchy:
$ 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: contains int main(){}
, src/log/log.cpp contains void f(){}
.
Invoking make
produces (edited for brevity):
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
The problem is the first three lines: log.cpp is compiled twice!
The question: why isn't it just compiled once -- taking half the time?
note: I have no idea what I'm doing -- autotools is black magic to me, but we have to use it in our place. The docs are incomprehensible to me.
Upvotes: 3
Views: 1023
Reputation: 31263
By default Libtool creates two types of libraries: static and shared. (aka libfoo.a and libfoo.so)
Static and shard require different compilation flags. Dynamic libraries -- shared objects use Position Independent Code with following gcc flags:
-fPIC -DPIC
Static are not. You can force build only one type by specifing
./configure --disable-shared
or
./configure --disable-static
Rationale
Usually when library is provided for user it provide in two setups -- static for development that allows create pure static builds and dynamic for use by most of programs that use this library. So, usually when you install library in the system you only install shared object. (aka libfoo_XYZ.deb)
When you add development version (aka libfoo-dev_XYZ.deb) you add headers and statically build version of the library that allows users make staic builds if they whant.
This is common practice for shipping libraries in UNIX. Thus libtool does this for you automatically.
Upvotes: 3