分析下Skia的构建系统,详细编译过程參看Windows下从源代码编译Skia。这里以ninja为例来分析。运行以下三条命令就能够完毕编译:

SET "GYP_GENERATORS=ninja"
python bin/sync-and-gyp
ninja -C out\Release

“python bin/sync-and-gyp”会生成ninja脚本。以下来分析脚本层级以及某个模块的脚本内容和结构。

关于ninja,參考https://ninja-build.org/manual.htmlhttp://guiquanz.me/2014/07/28/a_intro_to_Ninja/

ninja脚本层级及模块脚本说明

skia\gyp以下的gyp脚本是模板。运行sync-and-gyp时会依据这些模板来动态生成实际的构建脚本。非常多模块依赖、条件等都能够在这个文件夹下的gyp或gypi中找到。

sync-and-gyp之后。out\Release\build.ninja。是总的编译脚本。里面定义了all,还定义了默认编译目标为most。

most相应的ninja脚本是out\Release\obj\gyp\most.ninja。

假设想编译某个单独的模块,能够运行“ninja module_name”,比方“ninja images”,“ninja giflib”等。

详细到某个模块的编译脚本,都在out\Release\obj\gyp\文件夹下。某个模块的ninja脚本中,定义了详细的编译规则。以images.ninja(相应skia_images.lib)为例来说明下,它的内容例如以下:

arch = environment.x86
cc = $cl_x86
cxx = $cl_x86
cc_host = $cl_x86
cxx_host = $cl_x86
asm = $ml_x86
build obj\gyp\images.actions_depends.stamp: stamp obj\gyp\libjpeg-turbo.lib $
obj\gyp\libwebp.actions_depends.stamp pdbname_c = images.pdb
pdbname_cc = images.pdb
pchprefix = images
defines = -DSK_INTERNAL -DSK_GAMMA_SRGB -DSK_GAMMA_APPLY_TO_A8 $
-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1 -DSK_SUPPORT_GPU=0 $
-DSK_FORCE_DISTANCE_FIELD_TEXT=0 -DSK_BUILD_FOR_WIN32 $
-D_CRT_SECURE_NO_WARNINGS -DGR_GL_FUNCTION_TYPE=__stdcall $
-D_HAS_EXCEPTIONS=0 -DNDEBUG -DNDEBUG
asmflags =
rcflags = /I..\..\gyp
includes = -I..\..\include\images -I..\..\include\private -I..\..\src\lazy $
-I..\..\src\core -I..\..\src\image -I..\..\include\c $
-I..\..\include\config -I..\..\include\core -I..\..\include\pathops $
-I..\..\gyp\config\win -I..\..\third_party\externals\libjpeg-turbo $
-I..\..\third_party\externals\libpng -I..\..\third_party\libpng $
-I..\..\third_party\externals\giflib -I..\..\third_party\giflib $
-I..\..\third_party\etc1 -I..\..\third_party\ktx $
-I..\..\third_party\externals\libwebp\src -I..\..\include\utils $
-I..\..\src\utils -I..\..\include\utils\win
midl_includes =
cflags = /wd4275 /wd4345 /wd4355 /Ox /Ot /fp:precise /W3 /WX /Zi /GR- /MD $
/we4189 /arch:SSE2 /FS
cflags_c = -DSK_A32_SHIFT=24 -DSK_B32_SHIFT=16 -DSK_G32_SHIFT=8 $
-DSK_R32_SHIFT=0 -DSK_A32_SHIFT=24 -DSK_B32_SHIFT=16 -DSK_G32_SHIFT=8 $
-DSK_R32_SHIFT=0
cflags_cc = -DSK_A32_SHIFT=24 -DSK_B32_SHIFT=16 -DSK_G32_SHIFT=8 $
-DSK_R32_SHIFT=0 -DSK_A32_SHIFT=24 -DSK_B32_SHIFT=16 -DSK_G32_SHIFT=8 $
-DSK_R32_SHIFT=0 /TP
arflags = build obj\src\images\images.bmpdecoderhelper.obj: cxx $
..\..\src\images\bmpdecoderhelper.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkDecodingImageGenerator.obj: cxx $
..\..\src\images\SkDecodingImageGenerator.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkForceLinking.obj: cxx $
..\..\src\images\SkForceLinking.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageDecoder.obj: cxx $
..\..\src\images\SkImageDecoder.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageDecoder_FactoryRegistrar.obj: cxx $
..\..\src\images\SkImageDecoder_FactoryRegistrar.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageDecoder_wbmp.obj: cxx $
..\..\src\images\SkImageDecoder_wbmp.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageDecoder_pkm.obj: cxx $
..\..\src\images\SkImageDecoder_pkm.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageDecoder_ktx.obj: cxx $
..\..\src\images\SkImageDecoder_ktx.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageDecoder_astc.obj: cxx $
..\..\src\images\SkImageDecoder_astc.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageDecoder_libbmp.obj: cxx $
..\..\src\images\SkImageDecoder_libbmp.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageDecoder_libico.obj: cxx $
..\..\src\images\SkImageDecoder_libico.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageDecoder_libwebp.obj: cxx $
..\..\src\images\SkImageDecoder_libwebp.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageDecoder_libjpeg.obj: cxx $
..\..\src\images\SkImageDecoder_libjpeg.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageDecoder_libpng.obj: cxx $
..\..\src\images\SkImageDecoder_libpng.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageDecoder_libgif.obj: cxx $
..\..\src\images\SkImageDecoder_libgif.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageEncoder.obj: cxx $
..\..\src\images\SkImageEncoder.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageEncoder_Factory.obj: cxx $
..\..\src\images\SkImageEncoder_Factory.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkImageEncoder_argb.obj: cxx $
..\..\src\images\SkImageEncoder_argb.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkJpegUtility.obj: cxx $
..\..\src\images\SkJpegUtility.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkMovie.obj: cxx ..\..\src\images\SkMovie.cpp $
|| obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkPageFlipper.obj: cxx $
..\..\src\images\SkPageFlipper.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\images\images.SkScaledBitmapSampler.obj: cxx $
..\..\src\images\SkScaledBitmapSampler.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\ports\images.SkImageGenerator_skia.obj: cxx $
..\..\src\ports\SkImageGenerator_skia.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp
build obj\src\ports\images.SkImageDecoder_WIC.obj: cxx $
..\..\src\ports\SkImageDecoder_WIC.cpp || $
obj\gyp\libjpeg-turbo.actions_rules_copies.stamp build skia_images.lib: alink obj\src\images\images.bmpdecoderhelper.obj $
obj\src\images\images.SkDecodingImageGenerator.obj $
obj\src\images\images.SkForceLinking.obj $
obj\src\images\images.SkImageDecoder.obj $
obj\src\images\images.SkImageDecoder_FactoryRegistrar.obj $
obj\src\images\images.SkImageDecoder_wbmp.obj $
obj\src\images\images.SkImageDecoder_pkm.obj $
obj\src\images\images.SkImageDecoder_ktx.obj $
obj\src\images\images.SkImageDecoder_astc.obj $
obj\src\images\images.SkImageDecoder_libbmp.obj $
obj\src\images\images.SkImageDecoder_libico.obj $
obj\src\images\images.SkImageDecoder_libgif.obj $
obj\src\images\images.SkImageDecoder_libwebp.obj $
obj\src\images\images.SkImageDecoder_libjpeg.obj $
obj\src\images\images.SkImageDecoder_libpng.obj $
obj\src\images\images.SkImageEncoder.obj $
obj\src\images\images.SkImageEncoder_Factory.obj $
obj\src\images\images.SkImageEncoder_argb.obj $
obj\src\images\images.SkJpegUtility.obj $
obj\src\images\images.SkMovie.obj $
obj\src\images\images.SkPageFlipper.obj $
obj\src\images\images.SkScaledBitmapSampler.obj $
obj\src\ports\images.SkImageGenerator_skia.obj $
obj\src\ports\images.SkImageDecoder_WIC.obj || $
obj\gyp\images.actions_depends.stamp
libflags =

能够看到,ninja脚本分例如以下几部分:

  • 编译平台和工具链
  • 编译选项(defines、cflags、includes等)
  • 编译规则(build obj開始的语句)
  • 生成库的规则(build skia_images.lib那行)

假设我们要改动某个子模块,依据上面分析,就能够改动相应的ninja脚本,defines能够添加一些宏定义,includes能够设置包括路径。cflags、cflags_c、cflags_cc能够设置编译选项。

要添加一个文件,按以下做就可以:

  1. 能够新增一条build obj语句,设置某个cpp文件的编译规则
  2. build skia_images.lib语句中添加第1步里生成的obj文件

有了这些基础,就能够单独改动某个模块了。

要单独编译某个模块,能够參考以下的命令:

ninja images
ninja codec

要清理某个模块,能够參考以下的命令:

ninja -t clean images

模块间的依赖

skia\gyp以下的gyp脚本是模板,运行sync-and-gyp时会依据这些模板来动态生成实际的构建脚本。这里的一些gyp脚本定义了模块间的依赖关系。比方images.gyp,有这些依赖:

  'dependencies': [
'core.gyp:*',
'giflib.gyp:giflib',
'libjpeg-turbo-selector.gyp:libjpeg-turbo-selector',
'etc1.gyp:libetc1',
'ktx.gyp:libSkKTX',
'libwebp.gyp:libwebp',
'utils.gyp:utils',
]

然后后面又分平台又一次设置了依赖条件和源文件。我发如今Windows下,运行“python bin/sync-and-gyp”生成的skia\out\Release\obj\gyp\images.ninja中,就没有SkImageDecoder_libpng.cpp哦。

编译选项

在运行“python bin/sync-and-gyp”之前。能够设置一些环境变量来控制Skia的编译。最常见的使用方法有两种:

  1. 控制某个模块的编译开关
  2. 改动编译选项

模块编译开关

https://skia.org/user/tips,这里说能够通过GYP_DEFINES来控制某个功能,举的样例例如以下:

GYP_DEFINES='skia_gpu=0 skia_pdf=0' python bin/sync-and-gyp
ninja -C out/Debug

在Windows下,这样设置GYP_DEFINES:

set "GYP_DEFINES=skia_gpu=0 skia_pdf=0"

注意,假设你真的设置了skia_gpu=0,默认编译过程会出错。这是由于bench工具要求定义skia_gpu。只是假设你不须要这个工具倒没关系,出错时各种lib已经正常生成了。

skia\gyp\common_variables.gypi这个文件中有提到了能够使用的开关(应该有个文档说明吧,我没找到,Skia的资料还是太少),比方skia_gpu、skia_pdf、skia_egl、skia_angle等。以下的语句可供參考:

set "GYP_DEFINES=skia_gpu=0 skia_pdf=0 skia_egl=0 skia_angle=0"

改动编译选项

编译选项有两种改法:

  1. 改动ninja中的conditions(skia\gyp\common_conditions.gypi)
  2. 通过环境变量传递

一个一个说吧。

  • 1) conditions

打开skia\gyp\common_conditions.gypi看看就知道有哪些条件了。比方Windows的Release版本号,编译器选项设置例如以下:

        'msvs_settings': {
'VCCLCompilerTool': {
'DebugInformationFormat': '3', # programDatabase (/Zi)
'Optimization': '<(skia_release_optimization_level)',
# Changing the floating point model requires rebaseling gm images
#'FloatingPointModel': '2', # fast (/fp:fast)
'FavorSizeOrSpeed': '1', # speed (/Ot)
'PreprocessorDefinitions': ['NDEBUG'],
'RuntimeLibrary': '2', # rtMultiThreadedDLL (/MD)
'EnableEnhancedInstructionSet': '2',# /arch:SSE2
'RuntimeTypeInfo': 'false', # /GR-
},
'VCLinkerTool': {
'GenerateDebugInformation': 'true', # /DEBUG
},
}

能够看到,设置了RuntimeLibrary为 /MD(多线程动态库)。假设要改动,直接改这个文件,整个编译时就都变了(我没试哈,仅仅是分析)。其他的选项相似。

  • 2) 通过环境变量传递

https://skia.org/user/tips,这里说能够通过在命令行环境设置CC、CXX、CFLAGS、CPPFLAGS、CXXFLAGS来传递一些编译选项。

“python bin/sync-and-gyp”语句运行过程中会分析环境变量。整合到输出的构建脚本中。

https://skia.org/user/tips。这里给的示比例如以下:

CXXFLAGS='-Wunused-parameter' \
CC='clang' CXX='clang++' python bin/sync-and-gyp
ninja -C out/Debug

在Windows下,应该这样设置:

set "CFLAGS=-DYOURMACRO=1 -DXXX=16"
set "CXXFLAGS=-DYOURMACRO=1 -DXXX=16"

我前面给出的images.ninja演示样例,我设置了CFLAGS、CXXFLAGS、CPPFLAGS。所以你会看到该ninja脚本中cflags_c、cflags_cc都添加了“-DSK_A32_SHIFT=24”之类的选项。


就这样吧。

其他參考文章详见我的专栏:【CEF与PPAPI开发】。

Skia构建系统与编译脚本分析的更多相关文章

  1. xmake v2.3.1 发布, 无缝对接其他构建系统

    最近对xmake内部做了不少的重构来改进,并且新增了不少实用的新特性,欢迎来体验. 项目源码 官方文档 一些新特性: 一键编译其他构建系统维护的项目,实现无缝对接,并且支持交叉编译(比如autotoo ...

  2. ESP32构建系统 (传统 GNU Make)

    概述: 一个 ESP-IDF 项目可以看作是多个不同组件的集合,ESP-IDF 可以显式地指定和配置每个组件.在构建项目的时候,构建系统会前往 ESP-IDF 目录.项目目录和用户自定义目录(可选)中 ...

  3. ESP32构建系统(CMake版)

    ESP32 芯片是一款 2.4 GHz Wi-Fi 和蓝牙双模芯片,内置 1 或 2 个 32 位处理器,运算能力最高可达 600 DMIPS. ESP-IDF 即乐鑫物联网开发框架,可为在 Wind ...

  4. nixyx —— 一个小巧的项目工程/编译文件生成器(构建系统?)

    恩..nixyx确实算不上是一个构建系统. 所谓构建系统,比如GNU的Autotools,那是一套很完整的构建体系,包括了程序的配置,编译和安装三大部分. 类似的软件还有:google的gyp.腾讯的 ...

  5. Android系统编译脚本理解

    android源码编译步骤: 1. repo sync 代码(下载代码) 2.start branch(用哪个分支,git相关) 3. 到根目录(android目录) $cd android/ 4. ...

  6. Spark配置&启动脚本分析

    本文档基于Spark2.0,对spark启动脚本进行分析. date:2016/8/3 author:wangxl Spark配置&启动脚本分析 我们主要关注3类文件,配置文件,启动脚本文件以 ...

  7. Android Studio的构建系统:Gradle

    原文作者:youxiachai <用Gradle 构建你的android程序> 前言 android gradle 的插件终于把混淆代码的task集成进去了,加上最近,android st ...

  8. Android NDK学习(二):编译脚本语法Android.mk和Application.mk

    一.Android.mk Android.mk分为一下几部分: LOCAL_PATH:= $(call my-dir), 返回当前文件在系统中的路径,Android.mk文件开始时必须定义该变量. i ...

  9. 基于Jenkins自动构建系统开发

    1  绪论 1.1 课题的研究背景 随着IT行业的不断发展,软件开发的复杂度也随着不断提高.与此同时,软件的开发团队也越来越庞大,而如何更好地协同整个团队进行高效准确的工作,从而确保软件开发的质量已经 ...

随机推荐

  1. Prime Gift(prime)

    Prime Gift(prime) 题目描述 Jyt有nn个质数,分别为p1,p2,p3-,pnp1,p2,p3-,pn. 她认为一个数xx是优秀的,当且仅当xx的所有质因子都在这nn个质数中. 她想 ...

  2. 转JSON提示No serializer found for class

    在调用Json串生成方法时,提示: No serializer found for class com.jeremxy.domain.EpgDetail and no propertiesdiscov ...

  3. 分布式文件系统FastDFS集群部署

    1.源码开放下载地址:https://github.com/happyfish100 早期源码开放下载地址:https://sourceforge.net/projects/fastdfs/files ...

  4. jmeter作接口测试入门的简单使用说明

    一.添加接口信息 1.添加线程组 (1)路径如下图: (2)部分内容解释 a.  Number of Threads(users):线程数 b.  Ramp-Up Period(in seconds) ...

  5. vim 编辑器的使用

    相信一个linux运维人员不可能不知道vim ,下面我们一起来学习vim的日常操作吧.(不要追求多,工作中用到了再去学也不迟.) 1.vim 的几种模式 *正常模式:快捷键or命令行操作 *插入模式: ...

  6. cxGrid让指定的某行自动呈选选中的状态

    cxView.ViewData.Rows[cxView.DataController.DataSource.DataSet.RecNo-1].Selected := True;//将当前的行呈选中的状 ...

  7. 如何在win2003下安装sql2008[多次安装sql2008失败者必看]

    原文发布时间为:2010-11-02 -- 来源于本人的百度文章 [由搬家工具导入] 如何在win2003下安装sql2008[多次安装sql2008失败者必看] 1. 安装win2003,升级全部补 ...

  8. poj 2796 Feel Good dp || 单调栈

    题目链接 题意 对于一个长度为\(n\)的非负整数数列\(a_1,a_2,-,a_n\),求\(max_{1≤l≤r≤n}f(l,r)\), 其中 \[f(l,r)=min(a_l,a_{l+1},- ...

  9. 小甲鱼PE详解之资源(PE详解11)

    原文出自:www.fishc.com 最近一直在安排第一届鱼C 学习班的事情,忙活了好一阵子,真是对不住大家,还大家久等了,这里要跟大家说声不好意思 ^_^ 今天我们来谈谈资源部分,资源部分可以说是 ...

  10. mysql5.7 mysql库下面的user表没有password字段无法修改密码

    如题所述,mysql5.7  mysql库下面的user表没有password字段无法修改密码, 5.7版本已经不再使用password来作为密码的字段了  而改成了authentication_st ...