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/log/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 对我来说是黑魔法,但我们必须在我们的地方使用它。 这些文档对我来说难以理解。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
默认情况下,Libtool 创建两种类型的库:静态库和共享库。 (又名 libfoo.a 和 libfoo.so)
静态和分片需要不同的编译标志。 动态库——共享对象
使用具有以下 gcc 标志的位置无关代码:
静态不是。 您可以通过指定
或
基本原理
来强制仅构建一种类型。通常,当向用户提供库时,它会提供两种设置 - 静态用于开发,允许创建纯静态构建和动态供大多数人使用
使用该库的程序。 所以,通常当你在系统中安装库时
您只安装共享对象。 (又名 libfoo_XYZ.deb)
当您添加开发版本(又名 libfoo-dev_XYZ.deb)时,您会添加标头并静态
库的构建版本,允许用户根据需要进行静态构建。
这是 UNIX 中传送库的常见做法。 因此 libtool 这样做是为了
你自动。
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:
Static are not. You can force build only one type by specifing
or
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.