看到群里在讨论boost,于是想着装个boost试试,但前后用了差不多一整天,最后发现是macOS上不能进行静态编译。

首先是安装编译Boost

https://solarianprogrammer.com/2018/08/07/compiling-boost-gcc-clang-macos/

我按照这个教程编译boost,用的是clang。

测试Boost

动态编译

我用下面的程序进行测试:

#include <iostream>
#include <string>
#include <boost/regex.hpp>

int main(void) {
    std::string s = " who,lives:in-a,pineapple        under  the  sea? ";
    boost::regex re(",|:|-|//s+");
    boost::sregex_token_iterator p(s.begin(), s.end(), re, -1);
    boost::sregex_token_iterator end;
    while (p != end) {
        std::cout << *p++ << std::endl;
    }
}

测试编译:

g++ test_boost.cc -I$BOOST_ROOT/include -L$BOOST_ROOT/lib -lboost_regex

编译成功,运行可执行文件报错:

dyld: Library not loaded: @rpath/libboost_regex.dylib
  Referenced from: /Users/barriery/Desktop/CodeTest/./a.out
  Reason: image not found
[1]    1746 abort      ./a.out

报错信息是找不到动态链接库libboost_regex.dylib,故在LD_LIBRARY_PATH中添加路径:

export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$BOOST_PATH/lib"

顺利运行。

静态编译

上面采用了动态编译,接下来我想试下静态编译:

g++ test_boost.cc -I$BOOST_ROOT/include -L$BOOST_ROOT/lib -lboost_regex -static

编译失败:

ld: library not found for -lcrt0.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)

关于lcrt0.o这个文件,我找到了这个:

https://stackoverflow.com/questions/3801011/ld-library-not-found-for-lcrt0-o-on-osx-10-6-with-gcc-clang-static-flag:

This option will not work on Mac OS X unless all libraries (including libgcc.a) have also been compiled with -static. Since neither a static version of libSystem.dylib nor crt0.o are provided, this option is not useful to most people.

https://stackoverflow.com/questions/5259249/creating-static-mac-os-x-c-build:

Tying user binaries to the internal implementation of Mac OS X libraries and interfaces would limit our ability to update and enhance Mac OS X. Instead, dynamic linking is supported

这里指出将二进制文件绑定到macOS库和接口的内部实现将限制更新和增强macOS的能力,故不提供libSystem文件的静态版本,所以macOS上无法进行静态编译。

不使用static选项重新编译了一下:

g++ test_boost.cc -I$BOOST_ROOT/include $BOOST_ROOT/lib/liblboost_regex.a

查看生成的可执行文件使用的动态链接库:

» otool a.out -L
a.out:
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)

其中libSystem不允许被静态绑定。