在 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
2
3
4
sudo port install autoconf automake bison cmake coreutils \
flex gettext git-core glib2 gsed intltool libffi \
libtool openssl p5-xml-parser pkgconfig scons \
wget xz

注意:官方推荐的安装方式里面包含 git-core,但是新版本已经用 git 来管理了,如果按照上述命令安装会报错。

我们可以使用如下命令来检查 repo 管理所使用的是 git-core 还是 git:

1
port info repo

如果显示如下所示使用 git 作为 repo 管理的话:

1
2
3
4
5
6
7
8
9
10
repo @1.19_1 (python)

Description: Repo is a tool that we built on top of Git. Repo helps us manage the many Git repositories, does the uploads to our revision control system , and automates parts of the Android
development workflow. Repo is not meant to replace Git, only to make it easier to work with Git in the context of Android.
Homepage: http://source.android.com/source/git-repo.html

Runtime Dependencies: git
Platforms: darwin
License: Apache-2
Maintainers: nomaintainer@macports.org

请使用下面的命令来进行安装(去除了 git-core):

1
2
3
4
sudo port install autoconf automake bison cmake coreutils \
flex gettext glib2 gsed intltool libffi \
libtool openssl p5-xml-parser pkgconfig scons \
wget xz

如果以前安装过 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
2
$(PKG)_VERSION  := 4.8.3
$(PKG)_CHECKSUM := da0a2b9ec074f2bf624a34f3507f812ebb6e4dce

注意: 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 平台下的可执行程序了。