build.py (10843B)
1 #!/usr/bin/env python2 2 3 # Copyright (c) 2019 The Khronos Group Inc. 4 # Use of this source code is governed by an MIT-style license that can be 5 # found in the LICENSE.txt file. 6 7 # Author: Mobica LTD 8 9 import sys 10 import re 11 import os 12 import subprocess 13 import threading 14 from sys import stdout, stderr, argv 15 16 # Running this script 17 # 1. To rebuild all dependencies: 18 # $ build.py deps 19 # 2. To build all targets without rebuilding dependencies 20 # $ build.py build 21 # 3. To build a single target without rebuilding dependencies 22 # $ build.py build <target> 23 # See the table below for available targets 24 # 4. To rebuild all dependencies and targets 25 # $ build.py 26 # 5. To build dependencies for a single target 27 # $ build.py deps <target> 28 # 6. To build dependencies for and compile a single target 29 # $ build.py <target> 30 31 # List of targets (short target name, closure namespace) 32 targets = { 33 'textureformat': 'functional.gles3.es3fTextureFormatTests', 34 'fboCompletenessTests': 'functional.gles3.es3fFboCompletenessTests', 35 'fbomultisampletests': 'functional.gles3.es3fFboMultisampleTests', 36 'fbostencilbuffertests': 'functional.gles3.es3fFboStencilbufferTests', 37 'fragmentoutput': 'functional.gles3.es3fFragmentOutputTests', 38 'framebufferblittests': 'functional.gles3.es3fFramebufferBlitTests', 39 'instancedrenderingtests': 'functional.gles3.es3fInstancedRenderingTests', 40 'pixelBufferObjectTest': 'functional.gles3.es3fPixelBufferObjectTest', 41 'primitiverestarttests': 'functional.gles3.es3fPrimitiveRestartTests', 42 'samplerobjecttests': 'functional.gles3.es3fSamplerObjectTests', 43 'transformFeedbackTests': 'functional.gles3.es3fTransformFeedbackTests', 44 'uniformapi': 'functional.gles3.es3fUniformApiTests', 45 'uniformbuffers': 'functional.gles3.es3fUniformBlockTests', 46 'vertexarrays': 'functional.gles3.es3fVertexArrayTests', 47 'shaderlibrary': 'modules.shared.glsShaderLibrary', 48 'negativebuffer': 'functional.gles3.es3fNegativeBufferApiTests', 49 'sglrReferenceContextTest': 'framework.opengl.simplereference.sglrReferenceContextTest', 50 'lifetime': 'functional.gles3.es3fLifetimeTests', 51 'draw': 'functional.gles3.es3fDrawTests', 52 'attriblocation': 'functional.gles3.es3fAttribLocationTests', 53 'textureShadowTests': 'functional.gles3.es3fTextureShadowTests', 54 'texturewrap': 'functional.gles3.es3fTextureWrapTests', 55 'negativetextureapi': 'functional.gles3.es3fNegativeTextureApiTests', 56 'multisample': 'functional.gles3.es3fMultisampleTests', 57 'negativefragmentapi': 'functional.gles3.es3fNegativeFragmentApiTests', 58 'negativevertexarrayapi': 'functional.gles3.es3fNegativeVertexArrayApiTests', 59 'negativestateapi' : 'functional.gles3.es3fNegativeStateApiTests', 60 'negativeshaderapi' : 'functional.gles3.es3fNegativeShaderApiTests', 61 'rasterizerdiscard' : 'functional.gles3.es3fRasterizerDiscardTests', 62 'buffercopy' : 'functional.gles3.es3fBufferCopyTests', 63 'shaderindexing' : 'functional.gles3.es3fShaderIndexingTests', 64 'shaderloop' : 'functional.gles3.es3fShaderLoopTests', 65 'shaderstruct' : 'functional.gles3.es3fShaderStructTests', 66 'shaderswitch' : 'functional.gles3.es3fShaderSwitchTests', 67 'fborender' : 'functional.gles3.es3fFboRenderTest', 68 'shaderderivate' : 'functional.gles3.es3fShaderDerivateTests', 69 'builtinprecision' : 'functional.gles3.es3fBuiltinPrecisionTests', 70 'shaderbuiltinvar' : 'functional.gles3.es3fShaderBuiltinVarTests', 71 'texturefiltering' : 'functional.gles3.es3fTextureFilteringTests', 72 'fbocolor' : 'functional.gles3.es3fFboColorbufferTests', 73 'fragdepth' : 'functional.gles3.es3fFragDepthTests', 74 'shaderop' : 'functional.gles3.es3fShaderOperatorTests', 75 'vao' : 'functional.gles3.es3fVertexArrayObjectTests', 76 'clip' : 'functional.gles3.es3fClippingTests', 77 'inv' : 'functional.gles3.es3fFboInvalidateTests', 78 'defvertattr' : 'functional.gles3.es3fDefaultVertexAttributeTests', 79 'occlusion' : 'functional.gles3.es3fOcclusionQueryTests', 80 'shaderapi' : 'functional.gles3.es3fShaderApiTests', 81 'shaderpackingfunction' : 'functional.gles3.es3fShaderPackingFunctionTests', 82 'shadercommonfunction' : 'functional.gles3.es3fShaderCommonFunctionTests', 83 'shadermatrix' : 'functional.gles3.es3fShaderMatrixTest', 84 'shaderprecision' : 'functional.gles3.es3fShaderPrecisionTests', 85 'bstate': 'functional.gles3.es3fBooleanStateQuery', 86 'shaderstate': 'functional.gles3.es3fShaderStateQueryTests', 87 'fbostate' : 'functional.gles3.es3fFboStateQueryTests', 88 'rbostate' : 'functional.gles3.es3fRboStateQueryTests', 89 'bufferstate' : 'functional.gles3.es3fBufferObjectQueryTests', 90 'samplerstate' : 'functional.gles3.es3fSamplerStateQueryTests', 91 'texstate' : 'functional.gles3.es3fTextureStateQuery', 92 'internalformatstate' : 'functional.gles3.es3fInternalFormatQueryTests', 93 'texturespecification' : 'functional.gles3.es3fTextureSpecificationTests', 94 'shadertexturefunction' : 'functional.gles3.es3fShaderTextureFunctionTests', 95 'sync' : 'functional.gles3.es3fSyncTests', 96 'readpixel' : 'functional.gles3.es3fReadPixelTests', 97 'stringquery' : 'functional.gles3.es3fStringQueryTests', 98 'indexedstate' : 'functional.gles3.es3fIndexedStateQueryTests', 99 'integerstate' : 'functional.gles3.es3fIntegerStateQueryTests', 100 'floatstate' : 'functional.gles3.es3fFloatStateQueryTests' 101 } 102 103 total_errors = 0 104 total_warnings = 0 105 106 results = dict() 107 108 def dep_filename(target): 109 return target + '.dep' 110 111 def compiled_filename(target): 112 return target + '.compiled' 113 114 def write_to_file(outfile, cmdLine, redirect_stderr): 115 stderr = None 116 if redirect_stderr: 117 stderr = subprocess.STDOUT 118 119 with open(outfile, "w") as out_file: 120 proc = subprocess.Popen(cmdLine, shell=True, stdout=subprocess.PIPE, stderr=stderr) 121 while proc.poll() is None: 122 line = proc.stdout.readline() 123 out_file.write(line) 124 125 out_file.flush() 126 proc.wait() 127 128 def read_file(file_path): 129 #File exist 130 if not file_exists(file_path): 131 sys.exit(2) 132 133 fo = open(file_path) 134 lines = fo.read() 135 fo.close() 136 return lines 137 138 def file_exists(file_path): 139 if not os.path.exists: 140 print "The file " + file_name + " doesn't exists" 141 return False 142 return True 143 144 def build_deps(target, namespace): 145 cmdLine = 'python ../closure-library/closure/bin/build/closurebuilder.py --root=../closure-library --root=. --namespace=' + namespace 146 print cmdLine 147 write_to_file(dep_filename(target), cmdLine, False) 148 149 def build_all_deps(): 150 for target in targets.keys(): 151 build_deps(target, targets[target]) 152 153 def buildDepsFile(): 154 # the parameter "--root_with_prefix" is the relative path from the file goog/base.js to the root of the .js files we 155 # are working on. 156 cmdBuildDeps = 'python ../closure-library/closure/bin/build/depswriter.py --root_with_prefix=". ../../../deqp" > deqp-deps.js' 157 158 # Calls the python program that generates the google closure dependencies 159 # write_to_file('deqp-deps.js', cmdBuildDeps, False) 160 proc = subprocess.Popen(cmdBuildDeps, shell=True, stdout=subprocess.PIPE, stderr=None) 161 proc.wait() 162 163 def build_target(target, namespace): 164 global total_errors 165 global total_warnings 166 deps = read_file(dep_filename(target)) 167 cmdLine = 'java -jar compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --warning_level VERBOSE --jscomp_warning undefinedVars --externs compiler_additional_extern.js' 168 for dep in deps.split('\n'): 169 dep = dep.strip() 170 if len(dep) > 0: 171 cmdLine += ' --js ' + dep 172 cmdLine += ' --closure_entry_point=' + namespace 173 print cmdLine 174 filename = compiled_filename(target) 175 write_to_file(filename, cmdLine, True) 176 compiled = read_file(filename) 177 result = re.search(r'(\d*)\s*error\(s\),\s*(\d*)\s*warning\(s\)', compiled) 178 errors = 0 179 warnings = 0 180 if result: 181 print target + ': ' + result.group(0) 182 errors = int(result.group(1)) 183 warnings = int(result.group(2)) 184 total_errors += errors 185 total_warnings += warnings 186 results[target] = [errors, warnings] 187 188 def build_all_targets(): 189 for target in targets.keys(): 190 build_target(target, targets[target]) 191 192 def format_target(target): 193 deps = read_file(dep_filename(target)) 194 fixjsstyle = 'fixjsstyle.py' 195 reformat = 'reformatting_tool.py' 196 for dep in deps.split('\n'): 197 dep = dep.strip() 198 if len(dep) > 0 and not re.search('closure-library.*base\.js', dep): 199 print fixjsstyle + ' ' + dep 200 subprocess.call(['python', fixjsstyle, dep]) 201 print reformat + ' -f ' + dep 202 subprocess.call(['python', reformat, '-f', dep]) 203 204 def format_all_targets(): 205 for target in targets.keys(): 206 format_target(target) 207 208 def pass_or_fail(): 209 if total_errors + total_warnings == 0: 210 print "Passed" 211 elif len(results) > 1: #display the summary only when building more than one target 212 passed = [k for k, v in results.iteritems() if v[0] + v[1] == 0] 213 failed = dict((k, v) for k, v in results.iteritems() if v[0] + v[1] != 0) 214 print "\nBuild Summary:" 215 # Print first the tests that passed 216 for target in passed: 217 print "{0:>30}\tPassed".format(target+":") 218 219 # Print tests that failed. Fixed-width to improve readability 220 for target in failed: 221 errors = failed[target][0] 222 warnings = failed[target][1] 223 print "{0:>30}\tErrors: {1:4}\tWarnings: {2:4}".format(target+":", errors, warnings) 224 print "Compilation failed: {} error(s), {} warning(s).".format(total_errors, total_warnings) 225 226 def main(argv): 227 if len(argv) == 0: 228 build_all_deps() 229 build_all_targets() 230 buildDepsFile() 231 pass_or_fail() 232 elif (argv[0] == 'deps'): 233 if len(argv) == 2: 234 target = argv[1] 235 build_deps(target, targets[target]) 236 else: 237 build_all_deps() 238 elif (argv[0] == 'format'): 239 if len(argv) == 2: 240 target = argv[1] 241 format_target(target) 242 else: 243 format_all_targets() 244 elif (argv[0] == 'build'): 245 if len(argv) == 2: 246 target = argv[1] 247 build_target(target, targets[target]) 248 else: 249 build_all_targets() 250 pass_or_fail() 251 elif (argv[0] == 'depfile'): 252 buildDepsFile() 253 elif (argv[0] == 'list'): 254 print "List of available targets:" 255 for target in targets.keys(): 256 print "\t{}".format(target) 257 else: 258 target = argv[0] 259 build_deps(target, targets[target]) 260 build_target(target, targets[target]) 261 pass_or_fail() 262 263 if __name__ == '__main__': 264 main(sys.argv[1:])