zoukankan      html  css  js  c++  java
  • Skia构建系统与编译脚本分析

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

    SET "GYP_GENERATORS=ninja"
    python bin/sync-and-gyp 
    ninja -C outRelease
    

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

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

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

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

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

    most相应的ninja脚本是outReleaseobjgypmost.ninja。

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

    详细到某个模块的编译脚本,都在outReleaseobjgyp文件夹下。某个模块的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 objgypimages.actions_depends.stamp: stamp objgyplibjpeg-turbo.lib $
        objgyplibwebp.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....includeimages -I....includeprivate -I....srclazy $
        -I....srccore -I....srcimage -I....includec $
        -I....includeconfig -I....includecore -I....includepathops $
        -I....gypconfigwin -I....	hird_partyexternalslibjpeg-turbo $
        -I....	hird_partyexternalslibpng -I....	hird_partylibpng $
        -I....	hird_partyexternalsgiflib -I....	hird_partygiflib $
        -I....	hird_partyetc1 -I....	hird_partyktx $
        -I....	hird_partyexternalslibwebpsrc -I....includeutils $
        -I....srcutils -I....includeutilswin
    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 objsrcimagesimages.bmpdecoderhelper.obj: cxx $
        ....srcimagesmpdecoderhelper.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkDecodingImageGenerator.obj: cxx $
        ....srcimagesSkDecodingImageGenerator.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkForceLinking.obj: cxx $
        ....srcimagesSkForceLinking.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageDecoder.obj: cxx $
        ....srcimagesSkImageDecoder.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageDecoder_FactoryRegistrar.obj: cxx $
        ....srcimagesSkImageDecoder_FactoryRegistrar.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageDecoder_wbmp.obj: cxx $
        ....srcimagesSkImageDecoder_wbmp.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageDecoder_pkm.obj: cxx $
        ....srcimagesSkImageDecoder_pkm.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageDecoder_ktx.obj: cxx $
        ....srcimagesSkImageDecoder_ktx.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageDecoder_astc.obj: cxx $
        ....srcimagesSkImageDecoder_astc.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageDecoder_libbmp.obj: cxx $
        ....srcimagesSkImageDecoder_libbmp.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageDecoder_libico.obj: cxx $
        ....srcimagesSkImageDecoder_libico.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageDecoder_libwebp.obj: cxx $
        ....srcimagesSkImageDecoder_libwebp.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageDecoder_libjpeg.obj: cxx $
        ....srcimagesSkImageDecoder_libjpeg.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageDecoder_libpng.obj: cxx $
        ....srcimagesSkImageDecoder_libpng.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageDecoder_libgif.obj: cxx $
        ....srcimagesSkImageDecoder_libgif.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageEncoder.obj: cxx $
        ....srcimagesSkImageEncoder.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageEncoder_Factory.obj: cxx $
        ....srcimagesSkImageEncoder_Factory.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkImageEncoder_argb.obj: cxx $
        ....srcimagesSkImageEncoder_argb.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkJpegUtility.obj: cxx $
        ....srcimagesSkJpegUtility.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkMovie.obj: cxx ....srcimagesSkMovie.cpp $
        || objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkPageFlipper.obj: cxx $
        ....srcimagesSkPageFlipper.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcimagesimages.SkScaledBitmapSampler.obj: cxx $
        ....srcimagesSkScaledBitmapSampler.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcportsimages.SkImageGenerator_skia.obj: cxx $
        ....srcportsSkImageGenerator_skia.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    build objsrcportsimages.SkImageDecoder_WIC.obj: cxx $
        ....srcportsSkImageDecoder_WIC.cpp || $
        objgyplibjpeg-turbo.actions_rules_copies.stamp
    
    build skia_images.lib: alink objsrcimagesimages.bmpdecoderhelper.obj $
        objsrcimagesimages.SkDecodingImageGenerator.obj $
        objsrcimagesimages.SkForceLinking.obj $
        objsrcimagesimages.SkImageDecoder.obj $
        objsrcimagesimages.SkImageDecoder_FactoryRegistrar.obj $
        objsrcimagesimages.SkImageDecoder_wbmp.obj $
        objsrcimagesimages.SkImageDecoder_pkm.obj $
        objsrcimagesimages.SkImageDecoder_ktx.obj $
        objsrcimagesimages.SkImageDecoder_astc.obj $
        objsrcimagesimages.SkImageDecoder_libbmp.obj $
        objsrcimagesimages.SkImageDecoder_libico.obj $
        objsrcimagesimages.SkImageDecoder_libgif.obj $
        objsrcimagesimages.SkImageDecoder_libwebp.obj $
        objsrcimagesimages.SkImageDecoder_libjpeg.obj $
        objsrcimagesimages.SkImageDecoder_libpng.obj $
        objsrcimagesimages.SkImageEncoder.obj $
        objsrcimagesimages.SkImageEncoder_Factory.obj $
        objsrcimagesimages.SkImageEncoder_argb.obj $
        objsrcimagesimages.SkJpegUtility.obj $
        objsrcimagesimages.SkMovie.obj $
        objsrcimagesimages.SkPageFlipper.obj $
        objsrcimagesimages.SkScaledBitmapSampler.obj $
        objsrcportsimages.SkImageGenerator_skia.obj $
        objsrcportsimages.SkImageDecoder_WIC.obj || $
        objgypimages.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
    

    模块间的依赖

    skiagyp以下的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”生成的skiaoutReleaseobjgypimages.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已经正常生成了。

    skiagypcommon_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(skiagypcommon_conditions.gypi)
    2. 通过环境变量传递

    一个一个说吧。

    • 1) conditions

    打开skiagypcommon_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开发】。

  • 相关阅读:
    Bootstrap学习js插件篇之提示框
    动态装载外部JavaScript脚本文件
    Bootstrap学习js插件篇之滚动监听
    ASP.NET 仿腾讯微博提示“还能输入*个字符”的实现
    Javascript 操作 Sql中的Xml 字段
    Bootstrap学习js插件篇之标签页
    CSS垂直水平完全居中手册
    Bootstrap学习js插件篇之下拉菜单
    国庆大礼包:2014年最全的ANDROID GUI模板和线框图免费下载
    网上收集:跟着 8 张思维导图学习 Javascript【转】
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7243434.html
Copyright © 2011-2022 走看看