glmark2代码分析1(构建方式)

您所在的位置:网站首页 waf编译器 glmark2代码分析1(构建方式)

glmark2代码分析1(构建方式)

2023-08-26 01:05| 来源: 网络整理| 查看: 265

glmark2代码分析

glmark2是一个GPU测试bench,来自glcompbench,早前的版本glmark1是用makefile构建的。

构建方式

glmark2的构建使用的是waf

waf介绍

Waf的构建文件是wscript。wscript中一个project一般包含6个步骤构成: configure: build: transform the source files into build files install uninstall dist: 源文件打包 clean: remove the build files 每一个步骤在wscript文件中定义成一个python函数,后台会把这几个函数作为参数实例化一个 waflib.Context.Context。每个步骤的定义模板如下:

def configure(conf): print("configure!") def build(bld): print("build!")

使用的时候要下载waf,放到根目录下,按照过程执行:

$ cd /tmp/myproject $ wget https://waf.io/waf-2.0.0 $ python ./waf-2.0.0 configure build configure! build!

waf编译中主要是def build(bld),调用bld函数创建一个task generator对象,创建tasks。waf先读取所有的bld,判断文件和target的依赖顺序,然后再按照bld的顺序执行其中的rule。rule是生成target时需要执行的命令。

def build(bld): tg = bld(rule='cp ${SRC} ${TGT}', source='wscript', target='foo.txt') bld(rule='cp ${SRC} ${TGT}', source='foo.txt', target='bar.txt')

默认的一些语言不用指定rule,指定编译器,waf tool会调用对应的方法,同时可以为指定相关的编译参数。

def options(opt): opt.load('compiler_c compiler_cxx') def configure(cnf): cnf.load('compiler_c compiler_cxx') cnf.check(features='cxx cxxprogram', lib=['m'], cflags=['-Wall'], defines=['var=foo'], uselib_store='M') def build(bld): bld(features='c cshlib', source='b.c', target='mylib') bld(features='c cxx cxxprogram', source='a.c main.cpp', target='app', use=['M','mylib'], lib=['dl'])

相当于定义了下面的三个变量:

conf.env.LIB_M = ['m'] conf.env.CFLAGS_M = ['-Wall'] conf.env.DEFINES_M = ['var=foo']

内置变量的引用用“${}”

def build(bld): bld.env.MESSAGE = 'Hello, world!' bld(rule='echo ${MESSAGE}', always=True)

调用子目录的waf脚本:

def build(bld): bld.recurse('src')

Waf的核心是13个module构成,其流程图如下:

Scripting Configure Build Options Context Node Utils Runner Task TaskGen ConfigSet Logs Errors

使用waf的主要函数和特性有: feature: 指定编译器 configure:包含一些method设置功用参数和配置的方法 build:bld方法中一些参数配置的方法

glmark2 waf 编译方法: $ ./waf configure --with-flavors= [--data-path=DATA_PATH --prefix=PREFIX] $ ./waf $ ./waf install --destdir=DESTDIR 顶层wscript文件

编译文件为顶层wscript文件,流程如下:

def options(opt): 配置编译器: opt.load('gnu_dirs') 使用标准的gnu库路径 opt.load('compiler_c') opt.load('compiler_cxx') add_option添加编译配置参数,包括: –with-flavors:配置编译的操作系统平台 + api版本gl/es2 + 窗口系统drm/wayland/dispmanx/mir –version-suffix:添加版本后缀 –no-debug:disable compiler debug information’ –no-opt:disable compiler optimizations –data-path:path to main data (also see --data(root)dir) –extras-path:path to additional data (models, shaders, textures) def configure(ctx): 解析flavors参数,区分linux和win,两者只能一个不同能同时存在。 flavors用键值对保存, FLAVORS = { 'dispmanx-glesv2' : 'glmark2-es2-dispmanx', 'drm-gl' : 'glmark2-drm', 'drm-glesv2' : 'glmark2-es2-drm', 'mir-gl' : 'glmark2-mir', 'mir-glesv2' : 'glmark2-es2-mir', 'wayland-gl' : 'glmark2-wayland', 'wayland-glesv2' : 'glmark2-es2-wayland', 'win32-gl': 'glmark2-win32', 'win32-glesv2': 'glmark2-es2', 'x11-gl' : 'glmark2', 'x11-glesv2' : 'glmark2-es2', }

生成FLAVOR_%s的环境变量参数,后面的build中根据这个flavor取对应的库、源文件、头文件、defines、依赖等配置。这些配置也是用键值对定义好数组。

ctx.env["FLAVOR_%s" % flavor.upper().replace('-','_')] = FLAVORS[flavor] for name in bld.env.keys(): if name.startswith('FLAVOR_') and bld.env[name]: flavor = name.replace('FLAVOR_', '').lower().replace('_', '-') egl_platform = flavor.split('-')[0] target = bld.env[name] node = bld( features = ['cxx', 'cprogram'], source = flavor_sources[flavor], target = target, use = platform_uselibs + flavor_uselibs[flavor], lib = platform_libs + flavor_libs[flavor], includes = ['.'] + platform_includes, defines = common_defines + flavor_defines[flavor] + egl_platform_defines[egl_platform], depends_on = flavor_depends_on[flavor] ) if flavor_sources_gen[flavor]: node.source.extend(flavor_sources_gen[flavor]) all_uselibs |= set(flavor_uselibs[flavor] + platform_uselibs) load前面的配置: ctx.load('gnu_dirs') ctx.load('compiler_c') ctx.load('compiler_cxx')

根据是win还是linux进行配置

if is_win: configure_win32(ctx) else: configure_linux(ctx) 添加定义versionsuffix和信息打印,这些打印在运行 waf configure 时打印出来。

def configure_linux(ctx): 用 check_cc 和 check_cfg 查找依赖库和头文件和编译参数CXXFLAGS和资源路径宏,包含标准头文件和库、gl相关库、flovar中指定的驱动库、libjpeg和libpng。

def build(ctx): 调用子目录的wscript_build

ctx.recurse('src') ctx.recurse('data') ctx.recurse('doc') class Glmark2Dist(Context.Context): 定义 waf dist 命令,将根目录下的源文件和资源文件打包成一个压缩包,名为glmark2-2020.04.tar.gz。不包含的文件: excludes = [’.bzr’, '.git’, ‘~’, ‘./.waf’, './build’, ‘.swp’, '.pyc’, ‘glmark2-.tar.gz’] 压缩方法,使用python tarfile def archive(self): import tarfile tar = tarfile.open(APPNAME + '-' + VERSION + '.tar.gz', 'w:gz') for f in self.get_files(): tar.add(f, arcname = APPNAME + '-' + VERSION + '/' + f, recursive = False) tar.close() src下wscript_build

src下wscript_build的流程如下:

获取所有源文件all_sources,对源文件进行分类: common_sources:非平台相关的代码,src目录下的cpp,scene-ideas下的cc文件 和 scene-terrain下的cc文件。不包含以下前缀的文件:canvas-、android、native-state-、gl-state-、main.cpp。 libmatrix_sources:libmatrix/*.cc不含test目录下文件 common_flavor_sources:‘main.cpp’, ‘canvas-generic.cpp’ libpng_local_sources:libpng目录下的c文件 zlib_local_sources = zlib目录下的c文件 libjpeg_turbo_local_sources:libjpeg-turbo目录下的c文件判断是不是win32和msvc环境,win32使用的platform_uselibs和platform_libs为local的,主要是png、jpeg和z库。如果是WAYLAND_SCANNER_wayland_scanner,要在系统指定pkg目录下扫描生成xdg-shell-client-protocol.h和xdg-shell-protocol.c文件按照flavor参数设置flavor_sources、flavor_uselibs、flavor_defines、flavor_libs、flavor_depends_on、flavor_sources_gen、egl_platform_defines,都是定义成list组根据flavor名称,创建bld,生成target for name in bld.env.keys(): if name.startswith('FLAVOR_') and bld.env[name]: flavor = name.replace('FLAVOR_', '').lower().replace('_', '-') egl_platform = flavor.split('-')[0] target = bld.env[name] node = bld( features = ['cxx', 'cprogram'], source = flavor_sources[flavor], target = target, use = platform_uselibs + flavor_uselibs[flavor], lib = platform_libs + flavor_libs[flavor], includes = ['.'] + platform_includes, defines = common_defines + flavor_defines[flavor] + egl_platform_defines[egl_platform], depends_on = flavor_depends_on[flavor] ) if flavor_sources_gen[flavor]: node.source.extend(flavor_sources_gen[flavor]) all_uselibs |= set(flavor_uselibs[flavor] + platform_uselibs) for egl_target in (v for v in all_uselibs if v.startswith('glad-egl')): egl_platform = egl_target.split('-')[2] bld( features = ['c'], source = ['glad/src/egl.c'], target = egl_target, includes = ['glad/include'], export_includes = 'glad/include', defines = egl_platform_defines[egl_platform] ) 后面判断all_uselibs里如果包含下面的库,创建相关的依赖库的生成命令bld: glad-glx/gl/wgl/glesv2 matrix-gl/glesv2 libpng-local zlib-local libjpeg-turbo-local common-gl common-glesv2


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3