分享

webkit在win32下的编译规则

 quasiceo 2014-01-20
分类: 浏览器 makefile 浏览器 2010-12-27 22:25 5136人阅读 评论(7) 收藏 举报

最近有人在windows 7下的webkit编译不过去,问我该怎么解决。我看了一下,主要是SVGAnimationElement.cpp等文件编译不过去,这里面使用了开启svg后的一些枚举变量,但webkit在编译时生成的WebKitBuild/include/WebCore/CSSPropertyNames.h文件里面并没有生成这些枚举变量,我检查一些编译选项,配置都是OK的,我又看了一下webkit的编译规则,发现CSSPropertyNames.h的生成是依赖CSSPropertyNames.in等文件。解决方法也简单:将CSSPropertyNames.in等文件里面加上一行后再删除,再编译就OK了。为什么这样就可以了呢?愿意是windows下的makefile的编译依赖并不像linux下那么可靠,有时候windows版的makefile工具在编译出错了也更新了文件的修改时间,导致下次makefile再检查时认为文件没改变,从而跳过去了,上面所说的CSSPropertyNames.in就是这种情况。前面我的blog里面也写了一下webki编译方面的文章,网上也有一些类似的文章,也有很多网友在webkit编译不过时发帖询问,所以我觉得很多人对webkit是如何编译的并不是太清楚,导致编译出错了不知道原因,自然也不知道如何去解决这个问题。久而久之,越来越多的人就会发现编译webkit都是一个问题,更不用说去研究webkit了。为了帮助这些人克服对webkit编译的恐惧,我这几天详细看了一下webkit在windows下的编译规则,写也这篇类似于总结的文章。

1. 目录划分

在webkit源码的根目录下,有Makefile,CMakeLists.txt,android.mk,WebKit.pro等文件与编译有关,其中makefile主要用于linux环境下,windows上虽然用了cygwin,却并没有使用这个makefile去编译;CMakeLists.txt主要是用于cmake环境下,这是一个跨平台的编译环境,但我发现在windows下使用cmake编译的人并不多,这可能主要是因为webkit官网介绍的主要是cgywin+vs的编译方式导致的;WebKit.pro是qt环境下的编译规则,qt自己定了一套编译规则,做了一个类似于makefile的工具qmake,是跨平台的,但是得下一套qt的编译环境或sdk,所以这个也主要是qt的人在维护,不过qt版的webkit发展还是不错的;android.mk是android下webkit的编译规则。这篇文件要介绍的windows编译规则在根目录并没有包含,而是在下面的子目录下实现的,原因可能是这套规则(cygwin+vs)只适合于windows平台,不是一个common的东西,所以不能放在根目录下,cygwin+vs这套环境主要是apple的人在维护,safari的windows版本应该也是使用这套环境编译出来的。顺便提一下,chrome下的编译规则后缀是gypi,例如webcore目录下的WebCore.gypi文件。

 image

webkit主要由3部分组成:JavaScriptCore,WebCore,WebKit。JavaScriptCore下主要是浏览器使用的javascript引擎代码,当使用v8引擎时,这个目录是不参加编译的;WebCore下的代码是浏览器的核心了,包括网页解析,layout,render等,dom规范和css规范的也是在这里面实现的,如果像知道浏览器里面的window对象是如何实现的,可以去WebCore/dom下看看,WebCore下与平台相关的是针对不同平台有不同的目录,编译依赖也是不一样的;WebKit下是提供给浏览器外壳的接口的实现代码。最终,JavaScriptCore被编译成了JavaScriptCore.dll,webcore和webkit目录被编译成了webkit.dll。JavaScriptCore.dll以dll export的方式导出了函数供webcore和webkit使用,webkit.dll则是以COM的方式提供接口给浏览器外壳(例如safari.exe)使用。如果你对比一下webkit目录在mac和windows上的实现,就会发现Object-C和COM的概念有很多方面是相似,只不过Object-C在语言级别将COM思想的一些复杂实现简化了。

在webkit的其他目录,与编译相关的目录还有WebKitLibraries,WebKitTools等。WebKitLibraries里面放着编译依赖的头文件和lib,例如icu,libxml,sqlite的头文件和lib,当我们执行update-webkit命令时,有一步就是从apple官网下载WebKitSupportLibrary.zip,然后解压到WebKitLibraries目录下;WebKitTools主要放着一些工具和例子,与编译相关的主要放着WebKitTools/Scripts目录下,例如update-webkit和build-webkit都是放在这下面,这个目录下perl脚本居多,bat(cmd)和py占少数。这种多种语言混在一起在编译环境里面是很常见的,从中我们可以学到一点的是用最适合的工具和语言做你想做的事情,没必要去争谁好谁坏,每个工具和语言都有自己的优点和弱点,用刀就要用刀刃。工具始终是工具,总有被淘汰的时候和地方,我们真正要关注的是我们的目标。

在windows下,很多人第一次编译webkit都是在cygwin的命令行里面执行build-webkit开始的,build-webkit其实也是调用vs的devenv.exe编译的,只不过它是在命令行编译,而更多人在后期都会使用vs ide去编译,因为比较直观和熟悉。当vs ide有一个问题是有点占内存,它的智能提示会经常扫描文件,弄得cpu占有率很高,最终智能提示生成的ncb文件也很大,不过这个有一个好处是调试的时候比较好找对应的函数实现(如果你的机器够强劲,装上Visual Assist X插件会更好)。vs工程在各个目录的位置如下:

JavaScriptCore:D:/tools/cygwin/home/xufan/WebKit/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj,D:/tools/cygwin/home/xufan/WebKit/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj等

WebCore:D:/tools/cygwin/home/xufan/WebKit/WebCore/WebCore.vcproj下的WebCore.vcproj等

Webkit:D:/tools/cygwin/home/xufan/WebKit/WebKit/win/WebKit.vcproj下的WebKit.vcproj等

整个webkit solution的文件是D:/tools/cygwin/home/xufan/WebKit/WebKit/win/WebKit.vcproj/WebKit.sln,双击可以用vs ide打开。

下面将从webkit的目录挑出一些代表性的编译规则进行讨论:

2. WebKitTools/Scripts目录

首先从update-webkit脚本说起,这个脚本主要是调用svn update(或git)去更新代码(80,81行),然后调用update-webkit-auxiliary-libs,update-webkit-auxiliary-libs通过curl下载WebKitSupportLibrary.zip(92行),最后解压到WebKitLibraries目录下(96行,116行)。

接下来看build-webkit脚本,build-webkit脚本的前344行主要是将命令行参数转换为perl里面的变量,289行到315行可以看到build-webkit支持的参数:

Usage: $programName [options] [options to pass to build system]
  --help                            Show this help message
  --clean                           Cleanup the build directory
  --debug                           Compile in debug mode
  --wincairo                        Build using Cairo (rather than CoreGraphics) on Windows
  --chromium                        Build the Chromium port on Mac/Win/Linux
  --gtk                             Build the GTK+ port
  --qt                              Build the Qt port
  --efl                             Build the EFL port
  --inspector-frontend              Copy changes to the inspector front-end files to the build directory

  --install-headers=          Set installation path for the headers (Qt only)
  --install-libs=             Set installation path for the libraries (Qt only)
  --v8                              Use V8 as JavaScript engine (Qt only)

  --prefix=                   Set installation prefix to the given path (Gtk/Efl only)
  --makeargs=            Optional Makefile flags

  --minimal                         No optional features, unless explicitly enabled.

 

build-webkit接下来调用的很多函数都是在webkitdirs.pm里面定义的(build-webkit的第40行:use webkitdirs),例如productDir(),这个是webkit输出结果的目录,从productDir的实现来看,输出目录主要是由WEBKITOUTPUTDIR这个环境变量决定的(webkitdirs.pm的119行),如果不存在则用根目录下的WebKitBuild目录(154行:$baseProductDir = "$sourceDir/WebKitBuild";)。360行到500行都是做一些检查工作,开始编译是从500行到551行,如下:

  1. # Build, and abort if the build fails.   
  2. for my $dir (@projects) {   
  3.     chdir $dir or die;   
  4.     my $result = 0;  
  5.     # For Gtk and Qt the WebKit project builds all others   
  6.     if ((isGtk() || isQt()) && $dir ne "WebKit") {   
  7.         chdir ".." or die;   
  8.         next;   
  9.     }  
  10.     if (isGtk()) {   
  11.         $result = buildGtkProject($dir, $clean,  @options);   
  12.     } elsif (isQt()) {   
  13.         $result = buildQMakeQtProject($dir, $clean, @options);   
  14.     } elsif (isAppleMacWebKit()) {   
  15.         $dir = "MiniBrowser" if $dir eq "WebKitTools/MiniBrowser";   
  16.         my @local_options = @options;   
  17.         push @local_options, XcodeCoverageSupportOptions() if $coverageSupport && $dir ne "ANGLE";   
  18.         $result = buildXCodeProject($dir, $clean, @local_options, @ARGV);   
  19.     } elsif (isAppleWinWebKit()) {   
  20.         if ($dir eq "WebKit") {   
  21.             $result = buildVisualStudioProject("win/WebKit.vcproj/WebKit.sln", $clean);   
  22.         }   
  23.     }   
  24.     # Various build* calls above may change the CWD.   
  25.     chdirWebKit();  
  26.     if (exitStatus($result)) {   
  27.         my $scriptDir = relativeScriptsDir();   
  28.         if (usingVisualStudioExpress()) {   
  29.             # Visual Studio Express is so lame it can't stdout build failures.   
  30.             # So we find its logs and dump them to the console ourselves.   
  31.             system(File::Spec->catfile($scriptDir, "print-vse-failure-logs"));   
  32.         }   
  33.         if (isAppleWinWebKit()) {   
  34.             print "/n/n===== BUILD FAILED ======/n/n";   
  35.             print "Please ensure you have run $scriptDir/update-webkit to install dependencies./n/n";   
  36.             my $baseProductDir = baseProductDir();   
  37.             print "You can view build errors by checking the BuildLog.htm files located at:/n$baseProductDir/obj//./n";   
  38.         }   
  39.         exit exitStatus($result);   
  40.     }   
  41. }  
 

在cygwin+vs的环境下执行的是:buildVisualStudioProject("win/WebKit.vcproj/WebKit.sln", $clean),buildVisualStudioProject的代码如下(在webkitdirs.pm的1205行):

  1. sub buildVisualStudioProject   
  2. {   
  3.     my ($project, $clean) = @_;   
  4.     setupCygwinEnv();  
  5.     my $config = configurationForVisualStudio();  
  6.     dieIfWindowsPlatformSDKNotInstalled() if $willUseVCExpressWhenBuilding;  
  7.     chomp($project = `cygpath -w "$project"`) if isCygwin();   
  8.     my $action = "/build";   
  9.     if ($clean) {   
  10.         $action = "/clean";   
  11.     }  
  12.     my @command = ($vcBuildPath, $project, $action, $config);  
  13.     print join(" ", @command), "/n";   
  14.     return system @command;   
  15. }  
 

setupCygwinEnv主要是通过环境变量去查找vs的安装位置,然后调用pdevenv脚本(1094行)去根据vs的版本调用不同的脚本去设置vs编译环境。vsvars32.bat和devenv.com应该大家都比较熟(不知道的可以看看开始菜单里面的Visual Studio 2005 Command Prompt快捷方式的指向),调用它们就是在pdevenv脚本里面做的。

最终调用vs的脚本展开后的形式可以看cygwin的命令行输出(见上面的my @command = ($vcBuildPath, $project, $action, $config);及其下面的一行),我这边是:

/home/xufan/Webkit/WebKitTools/Scripts/pdevenv win/WebKit.vcproj/WebKit.sln /build Debug_Cairo_CFLite

调用devenv.exe之后,编译规则就完全是vs的规则了,入口是WebKit/win/WebKit.vcproj/WebKit.sln,比较重要的工程是上面所说的JavaScriptCore.vcproj,WebCore.vcproj和WebKit.vcproj这几个工程了。

今天就先到这了,明天接着写这些比较重要的vs工程,重点包括js dom的对象(例如window对象)粘合(glue)到javascriptCore的代码是如何自动生成的,如果根据css关键字生成代码,webcore下面文件的编译顺序和规则等。

更多 0

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多