skia是一个开源的矢量渲染引擎,不仅用于Google Chrome浏览器,新兴的Android开放手机平台也采用skia作为绘图处理。
编译skia需要一个稳定的上网环境(一定要有科学上网环境,不然没有办法拉取第三方库,网上也有说通过配置一些来获取第三方库的,但我都出现了各种问题,花了一天都没有解决,最后还是找到一个科学上网环境来解决的)
1. 环境准备
skia源码 https://github.com/google/skia.git
skia 官网 https://skia.org/
python2.7 版本(不要使用3.0以上的版本)
git clone https://github.com/google/skia.git
2. 拉取第三方库
python.exe tools/git-sync-deps
使用了梯子也有可能出现拉取不下来的情况,需要给git设置代理。
给git设置代理
//设置全局代理;
git config --global http.proxy 127.0.0.1:10809
git config --global https.proxy 127.0.0.1:10809
//通过这个拉取代码;
python.exe tools/git-sync-deps
//拉取完成之后重置回来
git config --global --unset http.proxy
git config --global --unset https.proxy
拉取之后出现下面的内容基本就代表成功了.
3. 编译
//sln工程 动态库
.\bin\gn gen out/sln --ide=vs --args="is_component_build=true is_debug=false"
//sln工程 静态库,静态库可以设置为md的运行库,一般静态库生成的都是MT的运行库
.\bin\gn gen out/static2 --ide=vs --args="is_debug=false extra_cflags=[\"/MD\"]"
//编译webassembly skia目录下(出现了一些问题尚没有编译过)
.\modules\canvaskit\compile.sh
.\bin\gn gen cmake --args="is_component_build=true is_debug=false" --ide=json --json-ide-script=../../gn/gn_to_cmake.py
4. 测试
执行生成的viewer程序
skia的webassembly编译
1. 使用官网编译方式,提供库给web端使用
//skia目录下,执行下面的语句(使用git bash 控制台)
.\modules\canvaskit\compile.sh
这种方式遇到了很多问题,在执行时出现了ninja fatal:%1不是有效的32位程序,没有比较明确的日志打印,暂时不知道怎么解决,同时因为偏向linux环境,在windows下解决起来还是比较麻烦。
中途尝试过用windows的wsl,但因为vpn代理问题不能很好的解决,
2. 作为本地库的一部分编译,将自己编写的程序给web使用
- 部署emsdk环境
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
#安装最新版本,下面的命令都需要科学上网,否则下载非常容易出问题
emsdk install latest
#安装指定版本
emsdk install 1.40.1
#使用最新版本
emsdk activate latest
#配置环境
emsdk_env.bat
#测试是否安装成功的主要命令有
emcc -v //获取emcc的版本号
emcmake cmake . //某个cmakelists.txt文件,需要主要的是python可能会没有安装,或者因为使用的是免安装的python版本出现各类问题。最好的解决办法就是使用安装版本,然后在环境变量中配置好emsdk的各种环境变量
- 将gn工程转为我们熟知的cmake工程
//执行emsdk下的emsdk_env.bat 设置环境变量(支持内部有emsdk的版本,否则可能会出错)
.\bin\gn gen cmake --args="is_debug=false is_official_build=true is_component_build=false werror=true target_cpu=\"wasm\" skia_use_angle=false skia_use_dng_sdk=false skia_use_webgl=true skia_use_expat=false skia_use_fontconfig=false skia_use_freetype=true skia_use_libheif=false skia_use_libjpeg_turbo_decode=true skia_use_libjpeg_turbo_encode=true skia_use_libpng_decode=true skia_use_libpng_encode=true skia_use_libwebp_decode=true skia_use_libwebp_encode=true skia_use_lua=false skia_use_piex=false skia_use_system_freetype2=false skia_use_system_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false skia_use_vulkan=false skia_use_wuffs=true skia_use_zlib=true skia_enable_gpu=true skia_use_icu=true skia_use_system_icu=false skia_use_harfbuzz=true skia_use_system_harfbuzz=false skia_enable_fontmgr_custom_directory=false skia_enable_fontmgr_custom_embedded=true skia_enable_fontmgr_custom_empty=false skia_use_freetype_woff2=true skia_enable_skshaper=true skia_enable_skparagraph=true skia_enable_pdf=false skia_canvaskit_force_tracing=true skia_canvaskit_profile_build=false skia_canvaskit_enable_skp_serialization=true skia_canvaskit_enable_effects_deserialization=true skia_canvaskit_enable_skottie=true skia_canvaskit_include_viewer=false skia_canvaskit_enable_particles=true skia_canvaskit_enable_pathops=true skia_canvaskit_enable_rt_shader=true skia_canvaskit_enable_sksl_trace=true skia_canvaskit_enable_matrix_helper=true skia_canvaskit_enable_canvas_bindings=true skia_canvaskit_enable_font=true skia_canvaskit_enable_embedded_font=true skia_canvaskit_enable_alias_font=true skia_canvaskit_enable_paragraph=true" --ide=json --json-ide-script=../../gn/gn_to_cmake.py
![image.png](https://img-blog.csdnimg.cn/img_convert/dac596ee1964bea4a2429a410b57816b.png#clientId=ub72ba3af-7553-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=221&id=u2b94a43c&margin=[object Object]&name=image.png&originHeight=442&originWidth=1449&originalType=binary&ratio=1&rotation=0&showTitle=false&size=109104&status=done&style=none&taskId=u9cd1dc2e-be08-4477-9958-2b4e6b2b1a4&title=&width=724.5)
在windows10下可能会出现找不到C:\Program Files (x86)\Windows Kits\include\ 内部头文件的问题,是因为BUILDCONFIG.gn中写死了winsdk的路径,需要修改这个文件的源码
- 执行cmake配置,在skia目录下生成了一个cmake的目录
##使用的是mingw编译,如果没有,需要下载mingw编译器(可以下载Qt,自带了mingw编译器,正常情况下不会有什么问题。切换到skia的cmake目录(该目录是刚才生成cmake工程目录)
emcmake cmake .
- 执行make
emmake make
在编译feetype2的时候可能会出现“系统找不到执行的路径”,是因为ftbuild.h,ftopation.h的头文件路径找不到造成的,修改生成的cmake
set("target" "third_party__freetype2")
list(APPEND "${target}__cf_srcs"
"F:/soft/skia/third_party/externals/freetype/src/autofit/autofit.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftbase.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftbbox.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftbitmap.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftdebug.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftfstype.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftgasp.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftglyph.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftinit.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftmm.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftpatent.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftstroke.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftsynth.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftsystem.c"
"F:/soft/skia/third_party/externals/freetype/src/base/fttype1.c"
"F:/soft/skia/third_party/externals/freetype/src/base/ftwinfnt.c"
"F:/soft/skia/third_party/externals/freetype/src/cff/cff.c"
"F:/soft/skia/third_party/externals/freetype/src/cid/type1cid.c"
"F:/soft/skia/third_party/externals/freetype/src/gzip/ftgzip.c"
"F:/soft/skia/third_party/externals/freetype/src/psaux/psaux.c"
"F:/soft/skia/third_party/externals/freetype/src/pshinter/pshinter.c"
"F:/soft/skia/third_party/externals/freetype/src/psnames/psnames.c"
"F:/soft/skia/third_party/externals/freetype/src/raster/raster.c"
"F:/soft/skia/third_party/externals/freetype/src/sfnt/sfnt.c"
"F:/soft/skia/third_party/externals/freetype/src/smooth/smooth.c"
"F:/soft/skia/third_party/externals/freetype/src/truetype/truetype.c"
"F:/soft/skia/third_party/externals/freetype/src/type1/type1.c")
set(freetarget ${target})
add_library("${freetarget}" STATIC ${${target}__cf_srcs})
set_property(TARGET "${freetarget}" APPEND PROPERTY INCLUDE_DIRECTORIES
"F:/soft/skia/third_party/freetype2")
##修改下面ftmodule.h 和ftoption.h的<>头文件为引号头文件如 #FT_CONFIG_MODULES_H=\"\include\freetype-no-#type1\ftmodule.h\";FT_CONFIG_OPTIONS_H=\"\include\freetype-no-type1\ftoption.h\"
set_target_properties("${freetarget}" PROPERTIES COMPILE_DEFINITIONS "FT2_BUILD_LIBRARY;FT_CONFIG_MODULES_H=\"\include\freetype-no-type1\ftmodule.h\";FT_CONFIG_OPTIONS_H=\"\include\freetype-no-type1\ftoption.h\";FT_CONFIG_OPTION_USE_BROTLI;NDEBUG;SK_FREETYPE_MINIMUM_RUNTIME_VERSION=(((FREETYPE_MAJOR) << 24) | ((FREETYPE_MINOR) << 16) | ((FREETYPE_PATCH) << 8));")
set_target_properties("${freetarget}" PROPERTIES COMPILE_FLAGS "-w -Wno-attributes -fstrict-aliasing -fPIC -fvisibility=hidden --sysroot=F:/soft/skia/third_party/externals/emsdk/upstream/emscripten/cache/sysroot -sMAIN_MODULE=1 -O3 -isystem F:/soft/skia/third_party/externals/freetype/include -isystem F:/soft/skia/third_party/libpng -isystem F:/soft/skia/third_party/externals/libpng -isystem F:/soft/skia/third_party/externals/brotli/c/include ")
set_target_properties("${freetarget}" PROPERTIES LINK_FLAGS "--sysroot=F:/soft/skia/third_party/externals/emsdk/upstream/emscripten/cache/sysroot ")
target_link_libraries("${freetarget}"
"third_party__libpng"
"third_party__brotli")
编译结果
内部修改了生成canvaskit.js的名字,原名字是modules__canvaskit_canvaskit.js.js 通过修改CMakeLists.ext 文件中关于modules__canvaskit_canvaskit.js这个的目标文件名而来.
//生成的index.html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<canvas id=foo width=300 height=300></canvas>
<script type="text/javascript"
src="canvaskit.js.js"></script>
<script type="text/javascript">
const ckLoaded = CanvasKitInit({
locateFile: (file) =>file});
ckLoaded.then((CanvasKit) => {
const surface = CanvasKit.MakeCanvasSurface('foo');
const paint = new CanvasKit.Paint();
paint.setColor(CanvasKit.Color4f(0.9, 0, 0, 1.0));
paint.setStyle(CanvasKit.PaintStyle.Stroke);
paint.setAntiAlias(true);
const rr = CanvasKit.RRectXY(CanvasKit.LTRBRect(10, 60, 210, 260), 25, 15);
function draw(canvas) {
canvas.clear(CanvasKit.WHITE);
canvas.drawRRect(rr, paint);
}
surface.drawOnce(draw);
});
</script>
<!-- Add the javascript glue code (index.js) as generated by Emscripten -->
<p>Minimal example of animating the HTML5 canvas from C++ using SDL through WebAssembly.</p>
</body>
</html>
#启动服务,默认是当前文件夹上下的index.html文件
emrun --no_browser --port 8080 .