Libtool 速度慢,双重构建?

发布于 2024-07-13 13:47:26 字数 2306 浏览 9 评论 0原文

在我的项目中,模块被组织在子目录中以保持整洁。

我的项目目录层次结构:

$ 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏天碎花小短裙 2024-07-20 13:47:26

默认情况下,Libtool 创建两种类型的库:静态库和共享库。 (又名 libfoo.a 和 libfoo.so)

静态和分片需要不同的编译标志。 动态库——共享对象
使用具有以下 gcc 标志的位置无关代码:

-fPIC -DPIC

静态不是。 您可以通过指定

./configure --disable-shared

./configure --disable-static

基本原理

来强制仅构建一种类型。通常,当向用户提供库时,它会提供两种设置 - 静态用于开发,允许创建纯静态构建和动态供大多数人使用
使用该库的程序。 所以,通常当你在系统中安装库时
您只安装共享对象。 (又名 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:

-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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文