用mingw编译javascript v8
因为期望按照这篇Flymake Mode for Emacs/JavaScript V8 edition 里说的办法,用v8引擎来作为Emacs上的javascript代码的lint/flymake工具,所以我需要在Windows下编译v8引擎。不过v8编写时是以微软的编译器为平台的,我没这东西,所以我尝试在mingw下编译它。
其实v8的代码已经有其它人提交了一些支持mingw的补丁,比如这个:Issue 64 - v8 - Support additional toolchains on Windows , 但编译中我还是碰到不少问题, 这里记录一下过程中碰到的问题以及解决办法,以便其它网友有类似的需求时少走弯路。
- 安装Python + SCons, 因为v8的代码不用make, 而是用的SCons。记得将python安装目录加到环境变量PATH里去(比如set PATH=e:\python27;e:\python27\scripts;%PATH%)
- 修改scons的 SCons/Tool/__init__.py里面tool_list函数,将win32平台下linkers, c_compilers, cxx_compilers的设置改为优先使用gnulink, mingw, g++ (不管你机器上是否安装了Visual Studio,都得改这个。也许SCons有命令行参数或者配置文件让其优先使用指定的工具,但我不熟,是根据StackOverflow上这个帖子的说法来改的:http://stackoverflow.com/questions/328718/v8-javascript-engine-on-windows-mingw )
- 安装mingw + msys,可以用mingw提供的安装向导mingw-get-inst 来装
- 用SVN下载v8源代码: svn checkout http://v8.googlecode.com/svn/trunk/ v8
- 修改v8代码里面的SConstruct文件,给V8_EXTRA_FLAGS里的os:win32设置添加如下一行 'LIBS': ['winmm', 'ws2_32']
- 在msys下执行 scons.py snapshot=on library (可根据需要添加library=[shared|static]参数,这取决于你想编译一个动态库还是静态库。不过即使用scons.py snapshot=on library=static d8的方式编译命令行程序d8, 这个d8仅仅是不需要d8.dll和d8preparser.dll, 但仍然需要libgcc_s_dw2-1.dll和libstdc++-6.dll这两个动态库。我还不知道什么方法可以免除这个负担)。
P.S. 最后编译jslint的时候,需要这样:g++ -o jslint jslint.cpp -Iinclude -L. -lv8 -lws2_32 -lwinmm 不能把jslint.cpp放在最后,这样会出现一些函数找不到实现的问题(虽然在Linux下是没有问题的)
$ diff -u lib/site-packages/scons-2.1.0/SCons/Tool/__init__.py.orig lib/site-packages/scons-2.1.0/SCons/Tool/__init__.py --- lib/site-packages/scons-2.1.0/SCons/Tool/__init__.py.orig 2011-09-09 21:31:08 +0800 +++ lib/site-packages/scons-2.1.0/SCons/Tool/__init__.py 2011-10-06 15:42:42 +0800 @@ -557,10 +557,10 @@ # change these search orders, update the man page as well. if str(platform) == 'win32': "prefer Microsoft tools on Windows" - linkers = ['mslink', 'gnulink', 'ilink', 'linkloc', 'ilink32' ] - c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ] - cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'c++', 'bcc32' ] - assemblers = ['masm', 'nasm', 'gas', '386asm' ] + linkers = ['gnulink', 'mslink', 'ilink', 'linkloc', 'ilink32' ] + c_compilers = ['mingw', 'gcc', 'msvc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ] + cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++', 'bcc32' ] + assemblers = ['gas', 'masm', 'nasm', '386asm' ] fortran_compilers = ['gfortran', 'g77', 'ifl', 'cvf', 'f95', 'f90', 'fortran'] ars = ['mslib', 'ar', 'tlib'] other_plat_tools=['msvs','midl']
$ diff -u v8-read-only/SConstruct.orig v8-read-only/SConstruct --- v8-read-only/SConstruct.orig 2011-10-06 17:45:38 +0800 +++ v8-read-only/SConstruct 2011-10-06 16:16:18 +0800 @@ -132,6 +132,7 @@ 'os:win32': { 'CCFLAGS': ['-DWIN32'], 'CXXFLAGS': ['-DWIN32'], + 'LIBS': ['winmm', 'ws2_32'] }, 'arch:ia32': { 'CPPDEFINES': ['V8_TARGET_ARCH_IA32'],
$ diff -u v8-read-only/src/d8.cc.orig v8-read-only/src/d8.cc --- v8-read-only/src/d8.cc.orig 2011-10-06 17:46:10 +0800 +++ v8-read-only/src/d8.cc 2011-10-06 16:51:18 +0800 @@ -816,7 +816,7 @@ static FILE* FOpen(const char* path, const char* mode) { -#if (defined(_WIN32) || defined(_WIN64)) +#if ((defined(_WIN32) || defined(_WIN64)) && !defined(__GNUC__)) FILE* result; if (fopen_s(&result, path, mode) == 0) { return result;
参考:
- V8 Javascript Engine - How to Download and Build V8
- v8 wiki : BuildingOnWindows - Detailed instructions for building V8 on Windows