在 Mac OS X 系统下交叉编译 C++11 程序
安装 MacPorts
首先我们需要安装 MacPorts,按照官方的指引,下载不同版本的包,比如我下载的是 Mavericks 的。
同时,我们还需要安装 Xcode 和 Xcode Command Line Tools。Xcode 可以从 AppStore 获得,Command Line Tools 在 Xcode 安装后,从 Xcode 中安装。
启动 Xcode 并接受协议,或者在终端中接受协议:
1 | sudo xcodebuild -license |
安装后,便可以在命令行中使用 port 命令了。
我使用的是订制过的 zsh,而不是系统默认的 bash,所以会提示找不到 port。这种情况下修改一下 .zshrc 配置文件便可。
1 | vim ~/.zshrc |
将 export PATH 部分修改为如下:
1 | export PATH=$HOME/bin:/usr/local/bin:$PATH:/opt/local/bin |
主要是增加了最后的:**:/opt/local/bin**
最后我们运行一下更新命令,以确保我们用的是最新版的 MacPorts:
1 | sudo port selfupdate |
安装 MXE 依赖库
为了能在 OS X 下交叉编译 Windows 下的应用,我们需要 MXE 的支持。而 MXE 需要依赖一些 MacPorts 的开源库。
官方给出的 OS X 下的安装命令如下:
1 | sudo port install autoconf automake bison cmake coreutils \ |
注意:官方推荐的安装方式里面包含 git-core,但是新版本已经用 git 来管理了,如果按照上述命令安装会报错。
我们可以使用如下命令来检查 repo 管理所使用的是 git-core 还是 git:
1 | port info repo |
如果显示如下所示使用 git 作为 repo 管理的话:
1 | repo @1.19_1 (python) |
请使用下面的命令来进行安装(去除了 git-core):
1 | sudo port install autoconf automake bison cmake coreutils \ |
如果以前安装过 MacPorts,有些包过期了,可以使用下面的命令来更新升级:
1 | sudo port upgrade outdated |
安装 MXE
首先是获得 MXE,很简单 git clone 一下就好了:
1 | git clone https://github.com/mxe/mxe.git |
MXE 默认编译的 gcc 版本是 4.8.1,最新的 4.8 版本是 4.8.3,所以,我们修改一下 src/gcc.mk 文件,讲版本号和校验修改为如下:
1 | $(PKG)_VERSION := 4.8.3 |
注意: 4.9 以后的版本编译会报错,且 4.8 系列已经支持 C++11 标准,因为 4.8.3 对我已经够用了,所以本文并不适用 4.9 系列。4.8.3 版本的编译打包时间为:5/22/14 11:22:00 AM
设置好以后,我们就开始编译 32 位版本的交叉编译环境(i686-w64-mingw32),如果需要 64 位环境的,请使用 x86_64-w64-mingw32 来替换 i686-w64-mingw32:
1 | make MXE_TARGETS='i686-w64-mingw32' gcc gmp mpfr winpthreads -j4 JOBS=4 |
默认情况下,gcc 是使用 win32 线程的。这样的话,我们就没有办法使用 pthreads 和其他一些 C++11 的新特性,所以我们还需要再第一次编译完成后,再进行一次编译。
还是修改 src/gcc.mk 文件,在包依赖的部分增加 winpthreads,同时打开 posix:
首先是 12 行的部分,增加 winpthreads 支持,修改后类似如下:
1 | $(PKG)_DEPS := mingwrt w32api mingw-w64 binutils gcc-gmp gcc-mpc gcc-mpfr winpthreads |
然后是 49 行,修改 threads 方式为 posix。修改前:
1 | --enable-threads=win32 |
修改后:
1 | --enable-threads=posix |
接着修改 src/binutils.mk,增加 –with-sysroot 来开启 sysroot 支持。
在 38 行左右,增加如下代码作为编译的参数,注意后面可能需要连接符号 “":
1 | --with-sysroot |
再次编译 gcc:
1 | make MXE_TARGETS='i686-w64-mingw32' winpthreads gcc -j4 JOBS=4 |
如何使用
编译成功后,在 MXE 的目录内,会出现一个 usr 目录,那里面就保存着编译好的交叉环境,你可以直接调用 usr/bin/i686-w64-mingw32-gcc 来启动 gcc。其他的命令也都在 usr/bin 目录内,由前缀 i686-w64-mingw32- 开头。修改你的项目的 Makefile,调用交叉编译的 gcc 便可以直接生成 Windows 平台下的可执行程序了。