OPENGL,GPU图形库Skia在Windows下编译多种VS版本的DLL

news2025/5/25 9:16:57

   这几天刚改了改Duilib,之前为了让Duilib更好的支持透明异形窗体所以把Duilib改为Gdi和Gdi+的双渲染引擎。于是想到了有时间就把渲染引擎完全独立为渲染接口,可以增加更多的渲染引擎。现在来说Skia是个很不错的渲染,之前我只是单独编译了VS2013的Skia做来简单的测试使用,要想把它加到Duilib就得完全编译好Skia并且支持各个版本的VS。

        为了搞好各个版本的Skia,花了一天时间才弄得差不多,之间出现不少问题。在网上的Skia编译教程都太老了,不适用于当下的Skia版本了,所以专门把编译过程记录在这里方便以后查看。

       要编译Skia会用到谷歌的gyp工具,这个工具可以构建出我们需要的sln等项目文件。使用这个工具前,需要先设置两个环境变量。

      一、增加GYP_GENERATORS环境变量。1、可以设置为ninja,这样的话最后不会生成VS项目文件,而是让我们自己用depot_tools工具包中的ninja来手工编译(没啥特别需求就别用这个了)。2、设置为msvs-ninja,这样的话会生成VS项目文件,但是编译的时候还是依靠ninja来让VS自动编译。3、设置为msvs,这样子的话会直接生成VS项目文件,不依赖ninja。我只需要Windows的Skia,所以毫不犹豫的设置为msvs。

      二、增加GYP_MSVS_VERSION环境变量。这个环境变量用来指定生成的VS的版本(可以设置为2013,表示VS2013;还能设置2012、2008等等),对于新版本的Skia,只能用2013,所以这个变量不设置也可以。

VS2013版本:

        Skia的官网为:https://skia.org/。网站里面有Skia在各个系统的编译教程。我按照Windows的编译教程搞了挺长时间。按照官网的方法,需要的编译环境为:

        VS2013

        depot_tools

        Git(用于检出depot_tools和Skia)

        Python2.7版本(一定要2.7这个版本的,安装完后设置好python的环境变量)

        Cygwin(这个很必要,直接用Windows命令行会出问题)

            但是有个很尴尬的问题,那就是翻墙。如果按照教程来编译的话,首先是要检出depot_tools和Skia,然后就发现无法连接到服务器,好在有Github,在上面也有最新版本对应的代码,所以我转到Github去检出depot_tools和Skia。

      在按照教程编译时,执行命令:

cd %SKIA_CHECKOUT_DIR%
SET "GYP_GENERATORS=ninja,msvs"
python bin/sync-and-gyp
SET "GYP_GENERATORS="

      然后同样很悲剧,sync-and-gyp脚本会自动下载编译Skia所需的所有第三方库和环境,但是由于无法翻墙,大多数第三方库都没法下载,自然也无法编译!很尴尬的搞了半天都没成功。

      当最后觉得没法办的时候。突然发现当下新版本的Skia源码里面有个cmake目录,里面居然有CMakeLists.txt文件。眼前一亮,我用cmake。执行命令:

cd %SKIA_CHECKOUT_DIR%
cd cmake
cmake .

       直接生成了VS2013的工程文件!然后打开工程直接编译,没出现任何问题就生成了Skia.dll和一个demo程序,运行时一切正常!不需要depot_tools、python、cygwin、gyp,也不需要任何第三方库(实际上所需的很多第三方库都是给linux、mac等环境用的,比如jepg、png解析库,Windows并不需要,Skia在Windows中直接用WIC解析图片)。只需要Skia源码和cmake,三句代码指定搞定!而且生成的是一个单独的Skia.dll动态链接库,不像原来的Skia会生成一堆静态库文件。Skia要是早点附加个CMakeLists.txt就不需要那么麻烦了。

        我又换命令去尝试生成VS2008、2010、2012等版本的Skia

cd %SKIA_CHECKOUT_DIR%
cd cmake
cmake . -G "Visual Studio 9 2008"

       不过很遗憾,虽然最新版本的Skia虽然生成VS工程文件很简单了,但是由于新代码用到很多C++11的特性,所以只支持VS2013版本,其他VS编译时都会报错,更别说VS2008了。

      如果要让生成Skia.dll支持xp sp3系统,需要对项目属性做如下修改:

     1. 项目菜单->项目属性->配置属性->常规->平台工具集,选择“VS2013WindowsXP(v120_xp)”
  2. 项目菜单->项目属性->链接器->系统->所需的最低版本,设置为5.01

     3.打开sln后,找到ports项目,找到里面的”SkFontMgr_win_dw_factory.cpp“源文件并且移出,把“src/ports/SkFontMgr_win_gdi_factory.cpp”,再添加到ports项目(这是把DWrite渲染方式改为GDI渲染,原因我在后面说)

       如果要支持到xp sp2系统,还需要另外设置:

       C/C++->代码生成->运行库,选择“多线程(/MT)";

       这样做完,就算是圆满的编译好了Skia最新版本,但是这个并不能满足我的需求。因为最新版本的Skia必须要用VS2013编译,意味着最终程序必须附带VS2013的运行时库,而很多时候项目用的Duilib版本不是VS2013,这样会增加程序体积,也可能导致其他兼容性问题。所以还是需要编译出其他版本的Skia,既然最新版本Skia不支持,那就只能试试老版本的了

VS2010和VS2012版本:

        从Github检出Skia后,我浏览Skia版本库历史,尝试了编译很多个时间段的Skia,最终选择了一个2014年的Skia,这个版本的相对来说比较新,可以满足需求,同时也可以做出VS2008到VS2013版本的所有项目文件。我检出的版本为2014.4.11日的:

       编译VS2010版本的Skia也比较简单(2010直接升级就能用于2012和2013)。需要的环境如下:

       VS2010

       设置环境变量GYP_MSVS_VERSION为2010

       Python2.7(安装完后设置好python的环境变量)

       Cygwin(安装过程中提示安装package时找到python,把这个package装上)

       Skia依赖的第三方库

       其中Cygwin很重要,我一开始没用Cygwin而是直接用cmd,去编译的时候,python总会执行错误,需要在Cygwin环境下执行命令。

      在最新版本的Skia中,原本的syna-and-gyp脚本会自动下载所需的第三方库和各种环境,但是老版本的Skia没有这种脚本,就需要我们自己下载了。我会把我下载好的Skia依赖第三方库文件上传到我的Github上。在Skia的third_party目录新建externals目录,把第三方库文件放到externals目录就可以了,其中包括gyp(用来生成sln,这个很重要)。

     这些准备好后,启动Cygwin,执行命令:

cd d:/skia/skia #这里替换为你的Skia检出目录,用英文目录
python gyp_skia

    执行完毕后,如果一些顺利,就会生成out目录,里面有生成好的VS2010工程文件,把它可以升级为2012或者2013的。然后打开工程直接编译就OK了,编译时会出现错误:“警告视被为错误”,修改对应项目的属性:“C/C++->常规->将错误视为警告:否”就可以了。

     但是有的版本的Skia编译时会提供一些文件缺失的错误,这时就要看错误原因,如果是缺少第三方库那就需要我们自己再去下载对应的第三方库补充到externals目录。如果是缺失Skia本身的文件,就可以从Git中找到缺失的文件补充好(理论上不应该出现这个问题,但是我的确遇到了,不过重新检出了一下就没问题了)。不过经过我的测试,我检出的这个2014.4.11版本的Skia配合我的第三方库,编译时一切正常。

      至此,VS2010到VS2013的所有版本都可以编译出来了。但是最麻烦的是VS2008,我单独搞了挺长时间才搞出来2008版本的Skia。

VS2008版本:

        所需的环境和Skia版本与VS2010的完全一样,就不再赘述了。为什么编译VS2008的最麻烦?原因如下:

       1、Skia的源码原本最低就是支持VS2010的,没有考虑VS2008,用gyp工具生成的默认也是VS2010(当然也可以修改环境变量生成出VS2008版本)。

       2、在Windows中,Skia渲染字体有两种方式:GDI或者DWrite,而Skia默认的渲染方法是用DWrite,但是VS2008不支持没有DWrite的头文件(VS2010开始支持),所以会出现编译错误。另外XP系统不支持DWrite,所以如果想让编译出来的Skia支持XP系统,就需要把DWrite渲染方式改为GDI(这也是在编译VS2013那一节中我提到要替换文件的原因)

     由于这两个原因,所以需要修改一些项目和源代码,才能顺利编译出支持xp和VS2008的Skia。

     首先说一下生成2008工程文件的方法。

    正常情况下,设置环境变量GYP_MSVS_VERSION为2008,然后按照VS2010的生成方法,就能生成出VS2008的项目文件。

    但是在我尝试生成了很多个版本的Skia后发现,很多情况下,可能是gyp脚本编写有问题,会生成出默认的VS2010项目文件而无法生成VS2008的。如果按照上面的方法没有出现VS2008的项目文件,就需要强行修改一点gyp脚本了。找到"skia\third_party\externals\gyp\pylib\gyp\MSVSVersion.py"文件,这个文件负责gyp生成的VS版本,找到如下代码:

  # In auto mode, check environment variable for override.if version == 'auto':version = os.environ.get('GYP_MSVS_VERSION', 'auto')version_map = {'auto': ('10.0', '12.0', '9.0', '8.0', '11.0'),'2005': ('8.0',),'2005e': ('8.0',),'2008': ('9.0',),'2008e': ('9.0',),'2010': ('10.0',),'2010e': ('10.0',),'2012': ('11.0',),'2012e': ('11.0',),'2013': ('12.0',),'2013e': ('12.0',),}

      把其中几个数字做出修改,这些数字代码VS的版本,我把默认的生成版本从VS2010改成了VS2008

  # In auto mode, check environment variable for override.if version == 'auto':version = os.environ.get('GYP_MSVS_VERSION', 'auto')version_map = {'auto': ('9.0', '12.0', '9.0', '8.0', '11.0'),'2005': ('8.0',),'2005e': ('8.0',),'2008': ('9.0',),'2008e': ('9.0',),'2010': ('9.0',),'2010e': ('9.0',),'2012': ('11.0',),'2012e': ('11.0',),'2013': ('12.0',),'2013e': ('12.0',),}

         改完后保存,然后打开cygwin执行命令:

cd d:/skia/skia #这里替换为你的Skia检出目录,用英文目录
python gyp_skia

      这样就会生成VS2008的项目文件。但是只生成了项目文件还是不行,编译时会出现很多错误。

      首先把最常见的”警告视为错误“的问题改掉。

      然后还会提示缺少"stdint.h",这是C++标准头文件,但是VS2010才开始提供,所以我从VS2010找到这个头文件,并且把他放到了"skia/src/core”目录中(这个文件我也会提交到Github)。

      最后我们打开Skia解决方案,依次把工程里的DWrite相关代码修改,替换为GDI的:

      1、找到“Util”项目,把其中“SkDwrite.cpp/.h”、”SkDwriteFontFileSteam.cpp/.h“、”SkDwriteGeometrySink.cpp/.h“这几个用到dwrite的文件移除掉:

      2、找到“Ports”项目,把SkRemotableFontMgr_win_dw.cpp和SkFontHost_win_dw.cpp文件移除。

        3、如果上图的位置中,包含的是”SkFontMgr_default_dw.cpp“文件而不是”SkFontMgr_default_gdi.cpp“,那就用”SkFontMgr_default_gdi.cpp“替换”SkFontMgr_default_dw.cpp“

      4、打开”src\core\skadvancedtypefacemetrics.cpp“文件,把开头的#include "dwrite.h"头文件的语句注释掉;然后在文件中搜索如下代码并且注释掉:

template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(IDWriteFontFace* fontFace,int num_glyphs,const uint32_t* subsetGlyphIDs,uint32_t subsetGlyphIDsLength,bool (*getAdvance)(IDWriteFontFace* fontFace, int gId, int16_t* data));

      如果有其他的关于dwrite.h的错误,也类似的修改一下就可以了。做完这些后,就可以用VS2008编译生成Skia了。当然,由于可能其他人用其他版本的Skia,所以我说的步骤里面的文件和一些具体的代码可能会有差别,但是照猫画虎类似的改改就可以了。

用cmake生成VS2008版本的单一文件skia:

       在生成好上面说的VS2008版本的Skia后,我又想到了既然最新版本的Skia支持用cmake生成解决方案,那我应该也能自己为老版本的Skia写个CMakeLists.txt来各种版本的Skia。倒腾了一上午,还真搞出来了···,gyp生成的解决方案最麻烦的就是他会把skia拆分为很多个静态库文件,我们要用的话还得依次链接多个静态库文件,用起来很不爽。而用cmake可以生成一个单一的解决方案,编出来就是一个单独的skia,用起来方便多了。

      我把最新版的Skia的cmake目录的CMakeLists.txt文件拷贝到前面说的老版本的Skia目录。当然了,这个CMakeLists.txt肯定没法直接用,我对照着新版和老版的Skia的文件差异,修改了CMakeLists.txt,最终使用命令:

cd %SKIA_CHECKOUT_DIR%
cd cmake
cmake . -G "Visual Studio 9 2008"

      生成了VS2008的解决方案,但是这个解决方案是没法直接编译的,因为skia涉及的文件有点多,我改的CMakeLists.txt不够完善。所以我编译解决方案,根据提示的错误,移出多余的源文件,修改了不少地方,终于是编译陈功了。但是由于改的步骤不较多,也比较乱,所以我就不专门说明修改步骤了。我把最终生成的VS2008解决方案上传到Github。

      这个VS2008的Skia是我想要的最理想的版本。首先由于这是VS2008版本,所以可以很容易升级到VS2013等高版本的VS,而且直接编译,这就满足了实际开发对多种VS版本的需求。其次修改后完全支持xp系统。最后生成的是一个单独的Skia.dll文件,使用简单方便。

      生成的release版本的skia.dll大小是1.82M。不过我是用dll版本的Skia发现由于源文件中由于Skia有一些类没有导出,所以有一些功能没法使用。所以建议还是修改工程属性,生成skia的静态库,就可以使用完整的skia功能。如果使用静态库的skia,最终的exe大概会增加1.5M的体积,我感觉是可以接受的大小。

     最后,我再附加一个使用这个skia静态库的demo。简单做了个半透明的窗体,附加了文字特效。代码比较简略,凑活着看吧,主要就是测试功能是否正常。这里提示一下,使用skia静态库时记得链接这几个库文件:OpenGL32.lib、usp10.lib、DelayImp.lib、windowscodecs.lib

总结:

        也类似的这次编译Skia真是比较麻烦,gyp和depot_tools的确是厉害,不过对于我这样只需要Windows环境的来说用起来就不如CMake那么简单了。我把编译VS2010和VS2008所需要第三方库、生成好的Skia VS2008解决方案、单独skia版本的VS2008解决方案上传到我的Github。其中单独skia版本的VS2008解决方案可以直接编译出skia。地址:点击打开链接

转于:在Windows下编译多种VS版本的Skia

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1355835.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文查重降重写成大白话可以吗

大家好,今天来聊聊论文查重降重写成大白话可以吗,希望能给大家提供一点参考。 以下是针对论文重复率高的情况,提供一些修改建议和技巧,可以借助此类工具: 论文查重降重:用大白话解析 一、引言 写论文是每个…

软件测试基础理论学习-常见软件开发模型

瀑布模型 背景 瀑布模型的概念最早在1970年由软件工程师Winston W. Royce在其论文《Managing the Development of Large Software Systems》中提出。Royce虽然没有明确提出“瀑布模型”这个术语,但他描述了一种线性的、阶段性的开发流程,各个阶段之间具…

小迪安全第一天

一、常用的专业术语 参考: https://www.cnblogs.com/sunny11/p/13583083.html POC(proof of concept)验证漏洞的代码EXP(exploit) 利用对一段漏洞代码的利用Playload:有效载荷,当利用exploit成功后如何通过一个管道把这个权限给…

集群渲染是?渲染农场是?两者与云渲染关联是什么

在数字化浪潮不断推进的当下,渲染技术在多个行业中发挥着至关重要的作用,尤其体现在电影制作、建筑可视化以及电子游戏开发等领域。在众多渲染技术中,集群渲染、渲染农场以及云渲染特别受到业界的重视。本文旨在阐述这些概念的含义以及它们之…

蛇目标检测数据集VOC格式750张

蛇,一种令人着迷而又神秘的爬行动物,以其独特的外貌和习性,成为了自然界中的一道独特风景。 蛇的外观光滑细长,身体呈流线型,鳞片覆盖全身,使得它们能够在地面上或树枝间快速移动。大多数蛇拥有尖锐的毒牙…

小目标识别任务算法

小目标识别是计算机视觉领域中的一个挑战性任务,主要是指在图像或视频中检测和识别尺寸相对较小的目标。 以下是一些常见的小目标识别算法: Faster R-CNN: Faster R-CNN是一种基于深度学习的目标检测算法,通过引入区域建议网络&am…

算法导论复习——CHP22 基本图算法

图的表示 邻接矩阵和邻接表 稀疏图一般用邻接表表示(稀疏图:边数|E|远小于的图 ) 稠密图更倾向于用邻接矩阵表示 (稠密图:边数|E|接近的图) 邻接矩阵可用于需要快速判断任意两个结点之间是否有边相连的应用场景。 如果用邻…

VSCode远程连接centos

1 下载remote -ssh插件 2 在上方打开命令面板,输入>,再输入ssh,选择设置 Remote-SSH:Settings 那行 3 勾选下面这个选项 4 点击加号旁边的那个齿轮,选择.ssh\config ,配置连接信息,保存好后,刷新。 4 连接centos,然…

springBoot2.3-简单了解依赖管理、自动配置

一、自动依赖管理 基本介绍:springBoot提前帮我们写好了极多的依赖及版本号,当然我们也可以自定义依赖项与版本号。 1.1 简单介绍 1、在入门案例中,springBoot的maven中引入了parent父工程 2、ctrl 左键 parent, 发现里边还有…

图像融合算法

图像融合是将两个或多个图像或图像的特定部分合并在一起的过程。这可以通过各种图像融合算法来实现,这些算法可以用于不同的应用,如图像编辑、计算机视觉和医学图像处理。以下是一些常见的图像融合算法: 透明度融合(Alpha Blendi…

智能洗地机哪款最好用?智能洗地机推荐

洗地机是一种非常实用的家居清洁设备,可以有效地清理地面上的污垢和灰尘,给人们的生活带来了极大的便利性。那么洗地机哪个牌子最好用呢?市场上出现了越来越多的洗地机品牌,究竟哪一款智能洗地机更好用呢?本文将为大家简单介绍一下! 在选择…

这份江苏“最牛”医院和科室名单,我们核实过了

这份榜单不仅评出了全国100家最具科技影响力医院 还公布了25个医院学科影响力排行 那么,江苏哪些医院和科室入榜了呢? ▲戳大图更清晰 具体到学科排名 是这样的 心血管病 ▲戳大图更清晰 呼吸病学 ▲戳大图更清晰 消化病学 ▲戳大图更清晰 血液病…

接口和抽象类有什么共同点和区别?

共同点: 都不能被实例化。都可以包含抽象方法。都可以有默认实现的方法(Java 8 可以用 default 关键字在接口中定义默认方法)。 区别: 接口主要用于对类的行为进行约束,你实现了某个接口就具有了对应的行为。抽象类…

halcon 缺陷检测--形状匹配+差分

一、前言 本篇主要总结使用halcon 做缺陷检测的一个常用思路,当一张图片拍摄多个待检测工件,常用方法是由预先建立好的模版图像,采用 形状匹配查分方法抠下每个工件,逐个检测。 形状匹配比灰度值匹配要更为可靠 二、代码 代码是对…

目标管理(案例)

介绍 本篇Codelab将介绍如何使用State、Prop、Link、Watch、Provide、Consume管理页面级变量的状态,实现对页面数据的增加、删除、修改。要求完成以下功能: 实现一个自定义弹窗,完成添加子目标的功能。实现一个可编辑列表,可点击指…

JUC AQS(AbstractQueuedSynchronizer)

文章目录 AQS (AbstractQueuedSynchronizer^1.5^)CLH 锁队列AbstractQueuedSynchronizer 成员变量说明AbstractQueuedSynchronizer.Node 源码CLH 队列原理图入队逻辑方法出队逻辑方法 继承 AQS 需要实现的几个方法AQS 对象序列化ReentrantLock 源码解析R…

Day7 vitest 之 vitest配置第三版

项目目录 runner Type: VitestRunnerConstructor Default: node, 当运行test的时候 benchmark,当运行bench测试的时候 功能 自定义测试运行程序的路径。 要求 应与自定义库运行程序一起使用。 如果您只是运行测试,则可能不需要这个。它主要由library作者使用 …

kubernetes(K8s)的使用和常用命令

K8S kubernetes,由于k和s之间有8个字符,所以简称k8s,是一个全新的基于容器技术的分布式架构领先方案,是谷歌严格保密十几年的秘密武器----Borg系统的一个开源版本,于2015年7月发布第一个正式版本,它的本质…

HTML如何设置多图片上传,并限制格式类型

在HTML如何设置多图片上传&#xff0c;并限制格式类型为jpg和png格式。 <input type"file" name"fileInput" id"fileInput"> 上面这行代码&#xff0c;只支持单个文件上传&#xff0c;且不支持文件类型过滤&#xff0c;在实际开发过程中&…

HTML5+CSS3+Vue小实例:彩色圆环溶解加载动画

实例:彩色圆环溶解加载动画 技术栈:HTML+CSS+Vue.js 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge&…