CEF Windows环境搭建之源码编译

Chromium Embedded Framework

背景

最近由于项目需要用到内嵌浏览器,IE内核太依赖于操作系统,对H5的支持也不太好。CEF是基于chromium 项目的内嵌浏览器开源框架,已经应用到了很多产品中,而且有比较健全的论坛官方支持,是项目的不二选择。由于客户端要运行到Windows XP系统,但Chome浏览器在49版本(对应CEF3版本为2623,以下说的CEF均指CEF3)后不再支持Win7以下系统。CEF二进制发布官网上并未包含2623版本, 但CEF提供了源码发布,官方也给了源码编译文档说明,虽然按照官方文档说明进行构建,但在编译CEF 2623版本过程还是遇到不少问题,在此做个记录供网友参考。

准备编译环境

  • OS: Win7 64bit 以上系统, 至少8G内存,60G以上硬盘,最好是SSD
  • Visual Studio: VS2015u3 + Win10.0.14393 SDK + Ninja
  • Python 2.7+
  • 下载 automate-git.py 脚本

注意:

  1. 由于某些原因(你懂的),源代码是同步不下来的,建议使用VPN。另外,CEF基于chromium,源码比较大,同步源码时间比较漫长,耐心等待;
  2. 安装VS2015u3的时候,默认是不会安装Win10.0.14393 SDK的,所以需要你手动勾选;
  3. 安装python后需要将python的执行环境加入到环境变量中;

下载CEF源码

在下载CEF源码之前先了解一下自动构建脚本automate-git.py, 命令行执行:

python automate-git.py -h

可以看到源码同步、编译、发布等相关选项,每个选项都有相关说明。默认情况下同步完源代码后会自动构建并发布二进制包,由于同步源代码和构建时间都比较长,所以将同步源码和编译源码分开。先来看看目录结构:

CEF
 | --- 2623
automate
 | --- automate-git.py
 | --- sync_cef_2623.bat
 | --- build_cef_2623.bat

说明:

  • 目录CEF\2623:用于下载CEF 2623分支的源代码
  • 目录automate:用于放置自动构造相关脚本
  • automate-git.py:自动构建脚本
  • sync_cef_2623.bat:同步2623分支源码批处理脚本,具体内容往下看
  • build_cef_2623.bat:编译2623分支源码批处理脚本,具体内容往下看

以上目录结构属于个人偏好,不一定非要这样设置,关键是正确设置automate-git.py的参数。sync_cef_2623.bat用于同步CEF 2623分支源码,其内容如下:

set CEF_USE_GN=0
set GYP_DEFINES=buildtype=Official
set GYP_GENERATORS=ninja,msvs-ninja 
set GYP_MSVS_VERSION=2015
set CEF_ARCHIVE_FORMAT=tar.bz2
set DEPOT_TOOLS_WIN_TOOLCHAIN=0
python automate-git.py --download-dir=..\CEF\2623 --branch=2623 --no-build --no-distrib

sync_cef_2623.bat脚本中写入以上内容,在保证以上环境设置正确的前提下,在命令行运行sync_cef_2623.bat就可以同步源代码了,源代码有十几个G,如果网络不稳定的情况下,会花比较长的时间。

下面是一些参数说明,更多参数,请运行python automate-git.py -h查看,

  • --download-dir :设置下载源码的目录,这个地方用相对路径,下载到和automate同级的CEF\2623目录下
  • --branch :同步2623分支源码
  • --no-build :不编译
  • --no-distrib :不发布

注:

  1. 如果VPN不太稳定,可能会经常中断,造成脚本运行错误,重新运行脚本即可,源码主要有三部分,depot_tools源码cef源码和chromium源码,如果发现相应部分的源码已经同步完成,可以分别使用--no-depot-tools-update, --no-cef-update, --no-chromium-update 来不进行相应部分的代码更新。
  2. 自动构建脚本在下载源码时,并没有进度提示,比如在下载chromium/src目录时时间会非常长,会一直提示still working on src...,请耐心等待。

编译CEF源码

源代码下载完成后,就可以进行编译了,编译2623版本,可能会遇到一些编译错误,如果你不想亲自试一下这些编译错误,请直接看下节编译错误解决办法。编译源码用脚本build_cef_2623.bat,其内容如下:

set CEF_USE_GN=0
set GYP_DEFINES=buildtype=Official
set GYP_GENERATORS=ninja,msvs-ninja 
set GYP_MSVS_VERSION=2015
set CEF_ARCHIVE_FORMAT=tar.bz2
set DEPOT_TOOLS_WIN_TOOLCHAIN=0
python automate-git.py --download-dir=..\CEF\2623 --branch=2623 --no-update --no-depot-tools-update --verbose-build --force-build --no-debug-build --force-distrib

build_cef_2623.bat脚本中写入以上内容,就可以进行release版本的编译和发布了,以下是一些参数说明:

  • --no-update :不更新cefchromium源码
  • --no-depot-tools-update : 不更新depot-tools源码
  • --verbose-build : 开启编译日志,该参数比较重要,编译出错时方便定位问题,相关编译错误见下节
  • --force-build : 强制编译。在编译失败时,重新运行脚本能重新编译,不加该参数,则会提示out目录已存在
  • --no-debug-build : 不进行debug版本的编译,之所以加该参数是因为如果debugrelease一起编译,时间会比较长,产生的二进制也比较大,如果你的空间足够,时间足够,可以去掉该参数
  • --force-distrib :强制发布二进制包,如果已经发布过,再次运行脚本会重新生成二进制发布包

此外还有其它编译参数供选择,请运行python automate-git.py -h查看.

解决编译错误

在编译过程中,你可能会遇到以下编译或链接错误, 以我的CEF源码所在位置e:\repos\cef\2623为例:

编译错误1

如果你用的系统locale是中国,可能会遇到一些字符集相关的编码错误,需要更改系统区域设置,Win10系统下修改如下,其它系统请自行google
控制面板 > 时钟、语言和区域 > 区域 > 管理 > 更新系统区域设置...
修改为:
英语(美国)

编译错误2

e:\repos\cef\2623\chromium\src\google_apis\gaia\oauth2_token_service.cc(313):
error C2220: warning treated as error - no 'object' file generated
warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits

该编译错误比较明显,具体请参考MSDN,根据路径打开oauth2_token_service.cc,定位到313行, 将:

  int64_t exponential_backoff_in_seconds = 1 << retry_num;

修改为:

  int64_t exponential_backoff_in_seconds = 1i64 << retry_num;

编译错误3

e:\repos\cef\2623\chromium\src\ui\gl\gl_bindings_skia_in_process.cc(920): note: while trying to match the argument list '(GrGLInterface::GLPtr<GrGLMapBufferRangeProc>, overloaded-function)'

从编译器给出的错误提示,可以看出是函数参数不匹配,打开gl_bindings_skia_in_process.cc, 定位到920行:

  functions->fMapBufferRange = StubGLMapBufferRange;

functions是类型是GrGLInterface::Functions ,根据gl_bindings_skia_in_process.cc头部引用的头文件,打开e:\repos\cef\2623\chromium\src\third_party\skia\include\gpu\gl\GrGLInterface.h,可以看到fMapBufferRange的类型为GrGLMapBufferRangeProc,其声明在e:\repos\cef\2623\chromium\src\third_party\skia\include\gpu\gl\GrGLFunctions.h中,声明如下:

typedef GrGLvoid* (GR_GL_FUNCTION_TYPE* GrGLMapBufferRangeProc(GrGLenum target, 
                                            GrGLintptr offset, 
                                            GrGLsizeiptr length, 
                                            GrGLbitfield access);

再看gl_bindings_skia_in_process.ccStubGLMapBufferRange的定义:

void* GR_GL_FUNCTION_TYPE StubGLMapBufferRange(GLenum target,
                                               GLintptr offset,
                                               GLsizeiptr length,
                                               GLbitfield access) {
    return glMapBufferRange(target, offset, length, access);
}

从上面可以看出,的确是参数类型不匹配,其它StubXXX函数也有同样的问题,清楚了这个问题后,就好修复了,在gl_bindings_skia_in_process.cc,找到所有以GL开头的类型,将其增加前缀Gr就行了,这样一个个改比较麻烦,我们只需要重新typedef一下即可,需要typedef的类型不多,修改如下,在gl_bindings_skia_in_process.cc 19行处插入以下代码:

typedef GrGLenum GLenum;
typedef GrGLuint GLuint;
typedef GrGLchar GLchar;
typedef GrGLclampf GLclampf;
typedef GrGLint GLint;
typedef GrGLbitfield GLbitfield;
typedef GrGLsizeiptr GLsizeiptr;
typedef GrGLboolean GLboolean;
typedef GrGLsizei GLsizei;
typedef GrGLfloat GLfloat;
typedef GrGLintptr GLintptr;

编译错误4

e:\repos\cef\2623\chromium\src\third_party\swiftshader\include\egl\eglext.h(752): error C2061: syntax error: identifier 'EGLAttrib'
e:\repos\cef\2623\chromium\src\third_party\swiftshader\include\egl\eglext.h(753): error C2061: syntax error: identifier 'EGLAttrib'
e:\repos\cef\2623\chromium\src\third_party\swiftshader\include\egl\eglext.h(1057): error C2061: syntax error: identifier 'EGLAttrib'
e:\repos\cef\2623\chromium\src\third_party\swiftshader\include\egl\eglext.h(1121): error C2061: syntax error: identifier 'EGLAttrib'

编译错误也比较明确,就是找不到EGLAttrib类型,CEF论坛中已经给出了答案, 修改方法是打开eglext.h, 在代码typedef intptr_t EGLAttribKHR;(62行)后插入以下代码:

typedef EGLAttribKHR EGLAttrib; 

编译错误5

ffmpeg.lib(ffmpeg.wavdec.obj) : error LNK2001: unresolved external symbol _ff_w64_guid_data
libcef.dll : fatal error LNK1120: 1 unresolved externals

这个是一个链接错误,找不到外部符号_ff_w64_guid_data,一开始不知道怎么修复这个错误,那就google吧,好在已经有网友给出了解决办法,请参考:

修改方法是分别打开e:\repos\cef\2623\chromium\src\third_party\ffmpeg\ffmpeg_generated.gni
e:\repos\cef\2623\chromium\src\third_party\ffmpeg\ffmpeg_generated.gypi,

在 libavformat/wavdec.c 前加上 libavformat/w64.c

发布二进制包

编译完成后,二进制发布包默认生成路径在e:\repos\cef\2623\chromium\src\cef\binary_distrib, 二进制发布包的编译请参考我的另一文章CEF Windows环境搭建之二进制发布.
另外在e:\repos\cef\2623\chromium\src\out\Release中其实已经生成了cefclient.exe(如果编译的是debug版本,则在Debug目录),在命令行执行:

cefclient.exe --url=https://www.baidu.com
cefclient.exe

其它问题

将编译好的二进制拷贝到Windows XP系统下运行,发现Debug版本会崩溃,Release能正常工作。Debug版本加上--single-process参数,能够正常运行,但退出时也会崩溃。该问题可以参考链接:Crash on Windows XPCEF维护者
Marshall Greenblatt 已经给出了解决方法;鉴于CEF 2623 Release版本在XP下工作良好,且不需要在XP下进行调试工作,CEF 2623版本的编译工作可以告一段落。

更多参考

  1. https://bitbucket.org/chromiumembedded/cef/
  2. http://blog.csdn.net/yufei_lgq/article/details/53838270
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容