摘要
如何在cygwin下正确编译Boost。cygwin并未提供epoll, kqueue等框架的模拟,在cygwin下使用Boost.Asio应该使用Windows提供的IOCP API。在Boost.Filesystem中,Boost将cygwin视为Windows平台,所以它使用Windows API而非Posix API来操作文件,这导致无法访问到cygwin模拟的一些文件路径。本文将简单描述这些问题的解决方法。
前言部分
如果你想在Vistual Studio下使用boost的话大可不必如此麻烦。请自行搜索其他教程。
要在cygwin下编译,请自行安装cygwin环境,gcc,g++
正文部分
解压源码
tar -xvf boost_1_63_0.tar.bz2
cd boost_1_63_0/
配置项目
./bootstrap.sh
编译选项说明
添加缺少的定义
由于cygwin没有提供epoll函数,要使用Boost.Asio的话只能使用Windows IOCP的API。需要定义__USE_W32_SOCKETS宏。
其实Boost.Asio是一个header only的库。这些定义不用在编译boost的时候添加,但为了保险起见,我们还是将它加入到编译参数里。在Boost中使用Posix API还是Windows API
从某种角度而言,cygwin可以视为一个特殊的操作系统。他在Windows API的基础上封装了一层Posix API。
大多数情况下,使用cygwin时可以忽略你在Windows的环境下工作。
但要使用cygwin的模拟,则必须使用cygwin提供的Posix API。比如你要访问cygwin环境下模拟的/usr, /tmp等目录,若使用Windows API就无法访问到。The library’s implementation code treats Cygwin as a Windows platform,
and thus uses the Windows API and uses Windows path syntax as the
native path syntax.以上是Boost原文中的话。意思是boost将cygwin视为Windows平台,使用Windows API。只支持Windows原生路径。
这意味着Boost.Filesystem将绕过cygwin的模拟,直接使用Windows API,那么你的应用使用Boost.Filesystem时,将无法使用到cygwin对路径的模拟,也无法访问到。/dev, /pro, /tmp, /usr, /home等Posix风格的路径,这似乎与cygwin的初衷相悖。这一点在boost社区中也有所争议。
如果你需要选择Posix API,那么需要对源码进行稍作修改将文件 ${boost_root}/boost/system/api_config.hpp中
# if defined(_WIN32) || defined(__CYGWIN__) // Windows default, including MinGW and Cygwin
修改为
# if defined(_WIN32) // Windows default, including MinGW
(警告:我并不确定这样修改会不会带来其他隐患,请酌情使用。如果你有更好的方法,希望也能分享出来)
增加编译选项 -fpermissive
编译过程中,编译器可能由于检查严格而大量报错。导致编译失败,建议一定加这一个选项
3. 开始编译
./b2 cxxflags='-std=gnu++11 -D__USE_W32_SOCKETS -D"__MSABI_LONG(x)=(x)" -fpermissive'
4. 安装
./b2 install