我如何静态编译boost_iostreams?

时间:2013-08-22 07:08:18

标签: c++ boost compilation makefile static-linking

我是创建Makefile的新手。我可以在使用动态链接时成功编译我的程序,但在尝试静态编译时,我得到“未定义的引用”错误。

CC=g++
CXXFLAGS= -g -Wall -Wextra
#LDFLAGS= -g -l boost_iostreams #this works for dynamic linking
LDFLAGS= -Wl,-Bstatic -lboost_iostreams -Wl,-Bdynamic 

default: zoneParserTester

zoneParser:
    $(CC) $(CXXFLAGS) $(LDFLAGS) $@.cpp

zoneParserTester: zoneParser.o
    $(CC) $(CXXFLAGS) $(LDFLAGS) zoneParser.o -o $@ $@.cpp 

gzExample:
    $(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ $@.cpp

在网上搜索之后,似乎使用的正确参数是:“ - WI,-Bstatic -lboost_iostreams -Wl,-Bdynamic”。谁能告诉我我做错了什么?

1 个答案:

答案 0 :(得分:2)

您缺少静态和动态链接之间的重要区别。将应用程序A动态链接到库B将在运行时引入库B 所有依赖项,而无需明确指定它们。静态链接应用程序时,还需要在链接时包含库B的所有依赖项(以及依赖项的依赖项等),其顺序与依赖项链相同(因此,如果应用程序A依赖于库B,库B依赖于库C,您必须按顺序指定库;对于.o文件也是如此。

要弄清楚特定库的整个依赖链(及其顺序)可能有点麻烦。有时链接期间的错误消息可以为您提供一些提示。如果这没有帮助,还有其他几种方法:

  1. 做出明智的猜测:猜测libboost_iostreams所依赖的一种方法是查看库的动态版本所依赖的内容。您可以使用ldd工具执行此操作:

    $ ldd /usr/lib/libboost_iostreams.so.1.46.1 
    

    在我的电脑上,它取决于libz和libbz2。所以我非常确定如果您添加

    ,您的应用程序将会链接
    -lbz2 -lz
    

    到您链接应用程序的行。我不确定-Wl,-Bstatic是否必要。对我来说,只需指定-static即可:

     $ gcc -static -o test test.cpp -lboost_iostreams -lbz2 -lz
    
  2. 使用pkg-config:大多数软件包(遗憾的是不提升)将安装pkg-config文件,这些文件会跟踪您必须如何链接程序以使用特定库。例如,假设你想静态链接到libcairo:

    $ pkg-config --static --libs cairo
    -pthread -lcairo -lgobject-2.0 -lffi -lpixman-1 -lfontconfig -lexpat -lfreetype -lpng12 -lz -lm -lxcb-shm -lxcb-render -lXrender -lglib-2.0 -lrt -lpcre -lX11 -lpthread -lxcb -lXau -lXdmcp 
    
  3. 使用.la文件和libtool:这是一种有点弃用的方法,并且越来越不再使用,因此.la文件的可用性将取决于您的发行版。 libtool是另一个解决这个问题的工具。链接时,不使用直接使用g ++,而是使用名为libtool的包装器:

    $ libtool --mode=link gcc -static -o my_app -lboost_iostreams
    

    libtool将尝试添加必要的库并自动将它们传递给gcc。它通过搜索与库名称相同的文件(在您的情况下为libboost_iostreams),但使用后缀.la(而不是.a)来完成此操作。如果在文本编辑器中打开.la文件,您将看到它列出了libboost_iostreams的依赖项。我个人不喜欢libtool,设置起来有点棘手,而且越来越不再使用了。我可能只是查看.la文件并手动添加依赖项。