最近公司开发一款跨平台的产品,主要支持的平台包括linux和windows,由于我的日常工作操作系统是linux,因此要调试windows部分代码极其不方便,要么在linux下安装一个虚拟机跑windows,要么双系统重启机器进入windows,总之是比较费时且麻烦。于是不安份的情绪让我折腾了一上午时间,终于成功地在我的Gentoo Linux上构建好了windows交叉编译环境。
其实在Gentoo Linux上构建交叉编译环境非常方便,crossdev一行命令就搞定一切,关于crossdev的用法很简单,可以参考Gentoo官方网站或者Gentoo-Wiki网站上的相关文档。构建windows交叉编译环境直接执行crossdev i686-mingw32即可。
构建好交叉编译环境之后可以写个hello world程序尝试一下,i686-mingw32-gcc -o test.exe test.c,然后file test.exe即可看到文件类型为“MS-DOS executable PE for MS Windows (console) Intel 80386 32-bit”,你也可以用wine test.exe执行一下看看结果。
似乎到此就圆满结束了?为了更方便地进行交叉编译,继续往下看吧。。。
开源软件大多数采用autotools来完成项目的自动构造,我们能不能利用autotools来方便地进行管理规模稍大的项目呢?答案是肯定的,今天上午为了测试交叉编译写了一个简单的win32 service,可以通过以下链接下载:SMQService,方便懒人们快速尝试交叉编译,不过你可能马上就会遇到挫折,来看看结果吧。
debianl@ldb /data/codes/test/win32service $ ./configure --target=i686-mingw32 --host=i686-mingw32 --build=i686-mingw32 --prefix=/usr/i686-mingw32/usr
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for i686-mingw32-gcc... i686-mingw32-gcc
checking for C compiler default output file name... a.exe
checking whether the C compiler works... configure: error: cannot run C compiled programs.
If you meant to cross compile, use `--host'.
See `config.log' for more details.
仔细看一下config.log即可看出configure会采用编译器编译一个测试程序并执行,在这儿会产生一个a.exe并直接执行,在linux直接执行exe文件如果不做点工作是不行的,直接执行a.exe报错configure也就停下了,告诉你"cannot run C compiled programs",其实compiler工作得好好的,那么我们现在只要解决直接在linux下运行exe文件就可以让autotools顺利地工作了。
其实要实现这个功能很简单,编译内核时注意选上Executable file formats->Kernel support for MISC binaries,如果编译成模块modprobe binfmt_misc即可加载,然后给你的/etc/fstab里加上一行“none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0”,在系统引导完成之后执行"echo ':DOSWin:M::MZ::/usr/bin/wine:' > /proc/sys/fs/binfmt_misc/register",在Gentoo下可以将这行指令写到/etc/conf.d/local.start文件,现在再试应该就好了。
以下是我的编译日志:
debianl@ldb /data/codes/test/win32service $ ./configure --target=i686-mingw32 --host=i686-mingw32 --build=i686-mingw32 --prefix=/usr/i686-mingw32/usr
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for i686-mingw32-gcc... i686-mingw32-gcc
checking for C compiler default output file name... a.exe
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... .exe
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether i686-mingw32-gcc accepts -g... yes
checking for i686-mingw32-gcc option to accept ISO C89... none needed
checking dependency style of i686-mingw32-gcc... gcc3
checking how to run the C preprocessor... i686-mingw32-gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking stdio.h usability... yes
checking stdio.h presence... yes
checking for stdio.h... yes
checking windows.h usability... yes
checking windows.h presence... yes
checking for windows.h... yes
checking for an ANSI C-conforming const... yes
checking for inline... inline
checking for size_t... yes
checking for stdlib.h... (cached) yes
checking for GNU libc compatible malloc... yes
checking for stdlib.h... (cached) yes
checking for GNU libc compatible realloc... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating src/config.h
config.status: executing depfiles commands
debianl@ldb /data/codes/test/win32service $ make
Making all in src
make[1]: Entering directory `/data/codes/test/win32service/src'
make all-am
make[2]: Entering directory `/data/codes/test/win32service/src'
i686-mingw32-gcc -DHAVE_CONFIG_H -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
i686-mingw32-gcc -g -O2 -o SMQService.exe main.o
make[2]: Leaving directory `/data/codes/test/win32service/src'
make[1]: Leaving directory `/data/codes/test/win32service/src'
make[1]: Entering directory `/data/codes/test/win32service'
make[1]: Nothing to be done for `all-am'.
make[1]: Leaving directory `/data/codes/test/win32service'
debianl@ldb /data/codes/test/win32service $ file src/SMQService.exe
src/SMQService.exe: MS-DOS executable PE for MS Windows (console) Intel 80386 32-bit
没有评论:
发表评论