编译 CEF3 chromium 2623 /mp3/mp4 稳定、终结版 2018-08
前言
- 以前编译过多次CEF2623,很久了,老代码不慎丢失,需要重新编译。翻看之前的编译记录,以及其它推荐文章,发现还有诸多细节问题,有不稳定的隐患。
- 本次强调稳定编译,处理了在编译过程中,容易忽略的问题,尽可能的去除潜在的不稳定隐患,特别是Patch补丁与WinSDK版本问题,以及VS版本兼容/XP兼容/SandBox调试符号等问题。
- CEF2623已是停止维护版本,有很多不稳定因素,编译器的版本、SDK版本、环境变量等如果不匹配,很可能出现交叉编译。此次尽量以最稳定、兼容的方式来编译,否则一个不稳定的核心在你的工程里面做主导,如果运行出现问题,并不排除核心的稳定性问题。
- 为求稳定,重装了系统,仅安装VS2013+Win10SDK 10240以及高速梯子,梯子也比较给力,高的时可达到10M/s的速度,编译时间为2018-08。
- 此次编译使用双CPU 16核 32线程,内存64G + SSD,因此编译速度相当快,纯32位release编译时只用了不到半小时,做了多项测试,以比较编译结果,务必编译出最稳定的核心
- 此次按流程编译很顺利,一气呵成,并未遇到什么疑难杂症,因此把流程记录下来。除了添加MP3/MP4/解码支持,以及GLX头,基本上没动什么源码。
- 附,编译后的库, 下载地址: https://download.csdn.net/download/ijiabao520/10642167
强调
- 源码下载完后,切不可立即修改源码,否则官方的patch补丁可能会被忽略甚至误打以及损坏源码。Patch打完之后,建议禁止Patch脚本,再可进行修改。
- Windows 10 SDK 选择10240。 若选择高版本,比如10586,已证实实际上是Win81SDK的头和库,配10586的DLL(可参见编译日志)。本着务实精神,下载谷歌浏览器Chrome 49.2623.110(XP最终版),查看
d3dcompiler_47.dll
版本,上有标明版本为10.0.10240.16384
- 选择VS2013u4+。官方说vs2015是实验性的,不稳定,XP下会崩溃,即使修改源码,也补不了潜在的隐患。
- 默认C盘安装编译工具,避免潜在的交叉编译。
- depot_tools 优先路径
- 安装完,复制 dbghelp.dll 到发行包,兼容XP
- 前期出错可增量编译,排错成功后,删除out目录,重新一次性编译
- 2623仅为支持xp系统, 若要稳定,尽量使用最新版(当前最新版为68.3440)
- 最新版CEF编译参见另一篇文章,编译方式切不可完全参照此文,
且完全不需修改源码并支持mp3/mp4
。
下载系统需求
Win10SDK 10240:
https://developer.microsoft.com/en-us/windows/downloads/sdk-archive注:chromium-2623使用SDK-10240 (WIN10 RTM第一版),应该使用此版本(源码编译路径写死了),为避免交叉编译,删除已有的高版本;使用其它版本要么无法编译,要么最终的库文件用起来不稳定(SDK10586,参见文尾注解)
win官方已不提供10240版下载,可以在vs2015光盘中找到并独立直接安装, vs2017(联机安装版1.2M)有全部SDK下载安装(安装时选择单个组件,只勾选SDK10240)
安装完后确认
C:\Program Files (x86)\Windows Kits\10\Include
目录下只有个10.0.10240.0
https://bitbucket.org/chromiumembedded/cef/raw/master/tools/automate/automate-git.py
devtools
如果您的系统安装了python2.7,可以直接运行automate-git.py, 会自动下载此工具,下载后仍需要设置环境变量。
devtools地址: https://storage.googleapis.com/chrome-infra/depot_tools.zip
**VisualStudio 2013 **
建议使用 VS2013up5, 文档中指出支持2013u4 or 2015u1,但2015是实验性的,非常不建议,且源码中到处都是vs2015的兼容处理代码,后期用来开发还可能会崩溃,如果坚持使用此版,需要做修改,参见结尾附注
官方文档
分支与编译以及系统需求
https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding官方注明: WinXP+, VS2013u4 or VS2015u1 (experimental), Win10 SDK, Ninja
使用automate编译,官方指南
https://bitbucket.org/chromiumembedded/cef/wiki/AutomatedBuildSetup.md
安装需知
-
设置语言,否则会出现编码错误。控制面版=>区域=>管理=>非Unicode程序的语言=>更改系统区域设置=> 英语(美国)。我有强迫症,直接装的英文版Win10
-
所有组件一律默认安装路径(C盘),如果不在C盘,建议不要折腾了,可能折腾成功的时间比重装系统还慢,也不敢保证最终编译结果是否稳定。
修改默认路径参见
cef/tools/gclient_hook.py
,第35行,需要设置以下环境(爱折腾的可以试试):# set WIN_CUSTOM_TOOLCHAIN=1 # set VS_ROOT=<VS root directory> # set SDK_ROOT=<Platform SDK root directory> # set INCLUDE=<VS include paths> # set PATH=<VS executable paths> # set LIB=<VS library paths>
-
硬盘预留200G空间,内存建议是16G,在编译64位时,内存占用达到了恐怖的14G,CPU虽然是32线程,也是100%利用率,机箱温度高的吓人。
设置工作区
-
我们需要下载后离线编译,因此先安装depot_tools, 再下载源码
-
工作目录在d:\cef3, 下载的
automate-git.py
放入 -
下载的depot_tools 解压后放入,然后命令行进入depot_tools, 运行
update_depot_tools.bat
-
建立d:\cef3\cefvars.bat
@echo off if defined BAO_CEF_ENV goto END echo setup cef vars... set BAO_CEF_ENV=1 set PATH=D:\cef3\depot_tools;%PATH% set CEF_ARCHIVE_FORMAT=tar.bz2 set CEF_USE_GN=0 set DEPOT_TOOLS_WIN_TOOLCHAIN=0 set GYP_DEFINES=buildtype=Official proprietary_codecs=1 ffmpeg_branding=Chrome set GYP_GENERATORS=ninja,msvs-ninja set GYP_MSVS_VERSION=2013 :END @echo on
-
上述
proprietary_codecs=1 ffmpeg_branding=Chrome
是支持MP3/MP4/h264
,实测可用。 -
命令行进入 d:\cef3, 准备就绪 (以下命令均在此目录下执行)
检出、下载源代码:
- 经测试,–force-clean 是清除所有已下载的文件
- 强迫症的朋友肯定要尽量一气呵成,断网全新重下,保证源码的完整、正确性。
call cefenv.bat
python automate-git.py --download-dir=d:\cef3\source --depot-tools-dir=d:\cef3\depot_tools --branch=2623 --no-build --no-distrib --force-clean
编译前需知
- 上述下载完成后,源码最干净的,在编译、修改前做好备份(连同depot_tools)是一个好主意。
- 特别注意,下载完成后,不要立即修改源码!!因为每次编译时都会对源码与patch文件比较,进行Patch补要,修复官方已提交的Bug,如果源码被修改,Patch补丁会忽略或失效,甚至会因为Patch不匹配而损坏源码。
- 一定要在Patch打过之后(编译一次), 再修改源码。(确认Patch打好后,再禁止Patch是个方法,参见下文注解)
- 下载后,可离线编译,指定
--depot-tools-dir, --no-depot-tools-update --no-update
即可
编译、发行 32bit Release版:
- 我们要的就是此版进行开发,以兼容XP, 附注的添加mp3/mp4支持是必须的。
- 第一次编译可能不成功,但必须先编译一次,使其对源文件打完patch,我们才可以对其进行修改.
- 除了附注的已知问题(官方Bug)是必须修改的,其它问题不可盲目地根据已知的错误信息修改,除非遇到同样问题再修改相关代码。
- 编译的时候可以查看 source/build-2623-*.log大小,如果大于130M,则基本上没有啥问题了。
call cefenv.bat
python automate-git.py --download-dir=d:\cef3\source --depot-tools-dir=d:\cef3\depot_tools --branch=2623 --no-update --no-debug-build --build-log-file --verbose-build --force-build --force-distrib
修改源码前,先禁止Patch
-
修改源码前,确定Patch已打过了。修改之后最好禁用Patch文件,避免多次Patch造成不稳定的隐患。按理说,Patch文件是按行比较,如果手动修改了文件之后,patch会识别,如果对应的行与Patch不同,会被忽略。
-
首次编译时在终端输出信息确认patch全部成功:
Patching build configuration and source files for CEF... ________ running 'd:\cef3\depot_tools\win_tools-2_7_6_bin\python\bin\python.exe tools/patcher.py --patch-config patch/patch.cfg' in 'd:\cef3\source\chromium\src\cef' --> successfully patched .. --> successfully patched .. ..... Generating CEF project files... ... 走到此处说明patch已打好, 此后出现错误不要紧
-
修改 chromium\src\cef\patch\patch.cfg, 在结尾添加一行,使下次编译不再打patch
patches = []
如果release编译成功,可以添加debug版
- debug版仅用于调试,开发项目时也不建议使用此版, debug版编译时间是上面的3到5倍之慢
- 据测试,即使官方编译的其它branch版本,debug版会强制抛出异常,均不可用于项目发布
call cefenv.bat
python automate-git.py --download-dir=d:\cef3\source --depot-tools-dir=d:\cef3\depot_tools --no-depot-tools-update --branch=2623 --no-update --no-release-build --build-log-file --verbose-build --force-distrib --force-build
打包发行Debug + Release 版本(生成最终开发包)
- 最终发行包路径为:
src\cef\binary_distrib
call cefenv.bat
python automate-git.py --download-dir=d:\cef3\source --depot-tools-dir=d:\cef3\depot_tools --no-depot-tools-update --branch=2623 --no-update --no-build --force-distrib
编译、打包64位版本
-
如果32位编译通过,则64位编译也没什么问题
-
64位必定是win7+系统,建议使用高版本cef3来生成64位程序,以达到更优化、稳定的64位程序
-
编译前需设置环境变量,或直接执行一次
vcvars64.bat
。实测编译时并不需要设置,发行时需要设置set CEF_VCVARS=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\vcvars64.bat
-
与32位参数一样,最后补上 --x64-build
编译、发行64位 Release版本
仍然是先编译release, 这个比较快,出现错误后可及时修改
call cefenv.bat
set CEF_VCVARS=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\vcvars64.bat
python automate-git.py --download-dir=d:\cef3\source --depot-tools-dir=d:\cef3\depot_tools --no-depot-tools-update --branch=2623 --no-update --no-debug-build --build-log-file --verbose-build --force-distrib --force-build --x64-build
编译、发行64位 Debug版本
call cefenv.bat
set CEF_VCVARS=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\vcvars64.bat
python automate-git.py --download-dir=d:\cef3\source --depot-tools-dir=d:\cef3\depot_tools --no-depot-tools-update --branch=2623 --no-update --no-release-build --build-log-file --verbose-build --force-distrib --force-build --x64-build
发行 64位 Release+Debug版本
call cefenv.bat
set CEF_VCVARS=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\vcvars64.bat
python automate-git.py --download-dir=d:\cef3\source --depot-tools-dir=d:\cef3\depot_tools --no-depot-tools-update --branch=2623 --no-update --no-build --force-distrib --x64-build
附加多媒体解码支持:
-
上述环境变量已设置支持mp3/mp4/h264,实测可行,若不生效,做下面设置:
-
打开
source\chromium\src\cef\cef.gypi
, 在第一段variables
节下添加:
'variables': {
# 添加两行:
'proprietary_codecs': 1,
'ffmpeg_branding': 'Chrome',
- 除mp3/mp4外,修改源码以添加更多解码器:
- 打开
src\third_party\ffmpeg\chromium\config\Chrome\win{ia32, x64}\config.h
(两个文件) ,在FFMPEG_CONFIGURATION
宏里追加(双引号内,尾部,补空格,中间没有换行! 将编辑器设置不自动换行,以免出错):
--enable-decoder='rv10,rv20,rv30,rv40,cook,h263,h263i,mpeg4,msmpeg4v1,msmpeg4v2,msmpeg4v3,amrnb,amrwb,ac3,flv' --enable-demuxer='rm,mpegvideo,avi,avisynth,h263,aac,amr,ac3,flv,mpegts,mpegtsraw' --enable-parser='mpegvideo,rv30,rv40,h263,mpeg4video,ac3'
// 原代码如下:
#define FFMPEG_CONFIGURATION "--disable-everything......... 将上述代码追加在此处"
编译完毕,需要做的
-
xp下运行需要拷贝
dbghelp.dll
,放在运行目录, 源文件在:source\chromium\src\build\win\dbghelp_xp\dbghelp.dll
-
cef_sandbox.lib是合并生成的,并未包含调试符号pdb,需要调试时还应该拷贝调试符号, 放在发行目录Debug/Release。(调试时需要cef源码)
# 可以看到此Lib是这样合成的: \chromium\src\cef\tools\make_distrib.py sandbox_libs = [ 'obj\\base\\base.lib', 'obj\\base\\base_static.lib', 'obj\\cef\\cef_sandbox.lib', 'obj\\base\\third_party\\dynamic_annotations\\dynamic_annotations.lib', 'obj\\sandbox\\sandbox.lib', ] # 因此需要复制以下文件: # src/out/Release|Release_x64|Debug|Debug_x64目录下: ./obj/base/base.c.pdb ./obj/base/base.cc.pdb ./obj/base/base_static.cc.pdb ./obj/cef/cef_sandbox.cc.pdb ./obj/base/third_party/dynamic_annotations/dynamic_annotations.c.pdb ./obj/sandbox/sandbox.cc.pdb # 下面一个脚本快速复制到 d:/tmp (Linux Ubuntu1804 子系统) cd source/chromium/src/out/Release mkdir -pv /mnt/d/tmp for file in $(echo "base.c.pdb base.cc.pdb base_static.cc.pdb cef_sandbox.cc.pdb dynamic_annotations.c.pdb sandbox.cc.pdb"); do find . -name $file -exec cp -v {} /mnt/d/tmp/ \;; done
已知编译期错误(必设)
忽略警告
- 视警告为错误
wraning as error
, 项目默认设置了高级别警告,会将警告视为错误,并停止编译
修改src\build\common.gypi,有两处, 搜索 'WarnAsError': 'true' 改为 'WarnAsError': 'false'
去除死代码
gl_bindings_skia_in_process.cc和 gl_bindings_skia_in_process.hh已经死代码了
官方有说明,详见: https://codereview.chromium.org/1673323002 , 下载patch打之,或按patch修改:
- 修改
src/ui/gl/BUILD.gn
src/ui/gl/gl.gyp
, 查找上述两个文件名称,注释掉此行(行首加#号) - 另外
src/ui/gl/BUILD.gn
, 注释掉skia那一行:
deps = [
"//base/third_party/dynamic_annotations",
# "//skia",
]
EGL语法、类型错误
错误:EGLSync, EGLAttrib 类型未定义(error C2061):
FAILED: obj/ui/gl/gl.egl_util.obj
cef3\source\chromium\src\third_party\swiftshader\include\egl\eglext.h(625) : error C2061: ????: ???"EGLSync"
修改
src\third_party\swiftshader\include\egl\eglext.h
, 第61、62行:
typedef void *EGLSyncKHR, *EGLSync;
typedef intptr_t EGLAttribKHR, EGLAttrib;
/// 注:上述修改遵循原始定义。EGLSync, EGLAttrib的类型定义参见同目录下的egl.h, 第240,241行.
编译顺序 browser_host_impl.cc(666): error C2039
- 修改:
src/cef/cef.gyp
文件, 1127行附近, 把print_view_manager_base.h
和print_view_manager_base.cc
往上移两行 (放到print_view_manager.h
和print_view_manager.cc
前面) :
'libcef/browser/printing/print_view_manager_base.cc',
'libcef/browser/printing/print_view_manager_base.h',
'libcef/browser/printing/print_view_manager.cc', # 原先这两行在上面,下移两行
'libcef/browser/printing/print_view_manager.h',
automate-git.py 版本问题 (2018/08/13, 不可盲目修改)
ninja: fatal: chdir to 'out\Release_' - No such file or directory
-------- Running "ninja -v -C out\Release_ cefclient" in "d:\cef3\source\chromium\src"...
...
subprocess.CalledProcessError: Command '['ninja', '-v', '-C', 'out\\Release_', 'cefclient']' returned non-zero exit status 1
-
可能是
automate-git.p
y经常更新以适配新的CEF版本,导致不兼容旧版本了(在之前编译过,并未出现此类错误,可换早期版本的automate-git.py) -
改 automate-git.py, 507行左右, 函数名:get_build_directory_name(is_debug):
# 函数第一行看出来 build_dir = (...) + '_', 在编译32位时,目录尾部多了一个下划线, 64位没问题 将 return build_dir 改为: return build_dir.rstrip('_')
-
为避免此事,在每一个cef-branch分支源码里,包含了一个旧版的automate-git.py, 此文件即是当时分支发布时期使用的脚本,路径在:下载目录/cef/tools/automate/automate-git.py,如果新版本不可用,可尝试使用此脚本。
其它错误
此为以前编译时发现的,不可盲目修改,编译遇到此类问题再修改。此次编译并未出现此类错误。
GL_CONTEXT_LOST_KHR 标识符未定义(error c2065, 仅debug 模式报错)
FAILED: obj/ui/gl/gl.gl_gl_api_implementation.obj
d:\cef3\source\chromium\src\ui\gl\gl_gl_api_implementation.cc(562) : error C2065: "GL_CONTEXT_LOST_KHR": ???????
常量
GL_CONTEXT_LOST_KHR
的值为0x0507
, 定义在gl_bindings.h
, 第320行因此修改
chromium\src\ui\gl\gl_gl_api_implementation.cc
, 在第18行下面添加新行:
#ifndef GL_CONTEXT_LOST_KHR
#define GL_CONTEXT_LOST_KHR 0x0507
#endif
无法识别的符号 __ff_w64_guid_data
-
修改
src/third_party/ffmpeg/ffmpeg_generated.gypi
, 在585行libavformat/vorbiscomment.c
后面添加libavformat/w64.c
'libavformat/vorbiscomment.c', 'libavformat/w64.c', # 此行为修改过的
ACTION Copying D3D Compiler DLL错误
- 选对上述Win10SDK版本(完整安装)
Win10SDK 版本及兼容问题
-
使用SDK10586, 编译完毕时,看编译日志,32位全部指定了81SDK目录,完全没有SDK10目录的影子;64位日志,小部分指定81SDK目录,大部分代码仍然指定了10240目录(如果目录不存在,实际默认还是81目录):
ninja: Entering directory `out\Release_x64' [1/15597] d:\cef3\depot_tools\win_tools-2_7_6_bin\python\bin\python.exe gyp-win-tool midl-wrapper environment.x64 gen\third_party\isimpledom ISimpleDOMDocument.tlb ISimpleDOMDocument.h ISimpleDOMDocument.dlldata.c ISimpleDOMDocument_i.c ISimpleDOMDocument_p.c ..\..\third_party\isimpledom\ISimpleDOMDocument.idl "-IC:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\um" "-IC:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\winrt" /char signed /env x64 /Oicf
-
后来使用10240版本编译,编译日志32/64位里全部指定10240目录,8.1目录字样完全消失。
-
参考官方Chrome浏览器xp最终版(49.0.2623.110), 查看其d3dcompiler_47.dll的版本,正是10.0.10240.16384
-
综上,我觉得10586版本虽然可以编译成功,在运行时不有稳定的隐患。个人保留了两版编译结果,以便后期在出问题时切换版本以排查是否核心问题。
VS2015 thread-safe 兼容(xp)
本次为了稳定性,放弃了2015的编译,此为以前编译出现的问题,其它问题不再列出
参见 http://stackoverflow.com/questions/32517234/access-violation-on-static-initialization http://blog.csdn.net/qsy2000/article/details/52915317
此篇说明,使用VS2013时mode and is not thread-safe,所以2015需要加一个编译参数,禁用thread-safe
# 修改 src/build/common.gypi, 在3299行附近
['OS=="win" and MSVS_VERSION == "2015"', {
'msvs_settings': {
'VCCLCompilerTool': {
'AdditionalOptions': [
# Work around crbug.com/526851, bug in VS 2015 RTM compiler.
'/Zc:sizedDealloc-',
'/Zc:threadSafeInit-', # 此行是手动添加的
],
},
},
}],
手动编译多版本cef_sandbox (备用)
- cef_sandbox.lib限制死了原始编译器的版本,项目用的VS要于原始VS版本一致。如果跨版本使用,就要重新编译源码了。
- 可保留源码,使用其它版本VS,单独编译一个cef_sandbox.lib,做为备用。
- 需要编译以下库:‘dynamic_annotations’, ‘base’, ‘base_static’, ‘sandbox’, ‘cef_sandbox’
- 先清除out目录,再重建工作区,然后用其它版本的VS编译上述库文件
- 以下是32位编译, 依次在终端运行
call cefenv.bat
# 换VS版本
set GYP_MSVS_VERSION=2015
rem 重建out目录,并编译cef_sandbox release/debug 版本
python automate-git.py --download-dir=d:\cef3\source --depot-tools-dir=d:\cef3\depot_tools --no-depot-tools-update --branch=2623 --no-update --verbose-build --force-build --build-target=cef_sandbox --no-distrib
再将上述的--target=cef_sandbox, 依次改为 'dynamic_annotations', 'base', 'base_static', 'sandbox' 并运行
# 成功后,复制以下文件,到一个临时目录
'obj\\base\\base.lib',
'obj\\base\\base_static.lib',
'obj\\cef\\cef_sandbox.lib',
'obj\\base\\third_party\\dynamic_annotations\\dynamic_annotations.lib',
'obj\\sandbox\\sandbox.lib',
# 进入临时目录,合成最终lib
call C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\vcvars32.bat
lib /out:cef_sandbox_release.lib base.lib base_static.lib dynamic_annotations.lib sandbox.lib cef_sandbox.lib
# 需要调试符号的话,参见上文
- 64位
call cefenv.bat
# 换VS版本
set GYP_MSVS_VERSION=2015
set CEF_VCVARS=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\vcvars64.bat
# 添加--x64-build, 与32位一样,依次编译所需
python automate-git.py --download-dir=d:\cef3\source --depot-tools-dir=d:\cef3\depot_tools --no-depot-tools-update --branch=2623 --no-update --verbose-build --force-build --build-target=cef_sandbox --no-distrib --x64-build