1#!/usr/bin/python3 2# Copyright 2019 The ANGLE Project Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5# 6# Code generation for: 7# - src/tests/deqp_support/BUILD.gn 8# - src/tests/deqp_data.gni 9# NOTE: don't run this script directly. Run scripts/run_code_generation.py. 10 11import errno 12import os 13import sys 14import shutil 15 16 17def initDataDirectories(dataDirectories): 18 dataDirectories.append(os.path.join("data", "gles2")) 19 dataDirectories.append(os.path.join("data", "gles3")) 20 dataDirectories.append(os.path.join("data", "gles31")) 21 dataDirectories.append(os.path.join("external", "graphicsfuzz", "data", "gles3")) 22 dataDirectories.append( 23 os.path.join("external", "openglcts", "data", "gl_cts", "data", "gles3")) 24 dataDirectories.append( 25 os.path.join("external", "openglcts", "data", "gl_cts", "data", "gles31")) 26 dataDirectories.append( 27 os.path.join("external", "openglcts", "data", "gl_cts", "data", "gles32")) 28 29 30def initPathReplacements(pathReplacements): 31 # The GraphicsFuzz data files need the 'external/graphicsfuzz/' prefix removed 32 pathToReplace = os.path.join("external", "graphicsfuzz", "") # Include trailing slash 33 pathReplacements[pathToReplace] = "" 34 # The KHR dEQP tests expect a root prefix of "gl_cts" for some reason. 35 pathToReplace = os.path.join("external", "openglcts", "") # Include trailing slash 36 pathReplacements[pathToReplace] = "" 37 38 39def createBuildGnFile(buildGnPath): 40 # Cleanup the old file 41 if os.path.exists(buildGnPath): 42 os.remove(buildGnPath) 43 # Make the new one 44 return open(buildGnPath, "w+") 45 46 47def createGniFile(gniFilename): 48 # Cleanup the old file 49 if os.path.exists(gniFilename): 50 os.remove(gniFilename) 51 # Make the new one 52 return open(gniFilename, "w+") 53 54 55def writeFileHeader(fileIn): 56 templateFileHeader = """# GENERATED FILE - DO NOT EDIT. 57# Generated by: {script_name} 58# 59# Copyright 2019 The ANGLE Project Authors. All rights reserved. 60# Use of this source code is governed by a BSD-style license that can be 61# found in the LICENSE file. 62 63""" 64 65 fileHeader = templateFileHeader.format(script_name=os.path.basename(__file__)) 66 fileIn.write(fileHeader) 67 68 69def fixDestinationDirectory(pathReplacements, relativeDirectory): 70 for pathReplacement in pathReplacements: 71 if pathReplacement in relativeDirectory: 72 return relativeDirectory.replace(pathReplacement, pathReplacements[pathReplacement]) 73 return relativeDirectory 74 75 76def convertPathToVarName(path): 77 return path.replace(os.sep, "_") 78 79 80def getCMakeLists(deqpSrcDir): 81 cmakeLists = [] 82 for root, directories, filenames in os.walk(deqpSrcDir): 83 for filename in filenames: 84 relativeDirectory = os.path.relpath(root, deqpSrcDir) 85 if filename == "CMakeLists.txt": 86 cmakeLists.append(os.path.join(relativeDirectory, filename)) 87 return cmakeLists 88 89 90def main(): 91 # List of directories containing data files 92 dataDirectories = [] 93 # List of directories to exclude from the copy 94 excludedDirectories = [ 95 ".git", 96 ] 97 # List of files to exclude from the copy 98 excludedFilenames = [ 99 "LICENSE", 100 ] 101 # Dictionary of parts of paths that need to be replaced 102 # Key: Part of path to be replaced 103 # Value: What to replace it with 104 pathReplacements = {} 105 # List of unique relative directories for the copy() command outputs 106 relativeDirectories = [] 107 # VK-GL-CTS source directory 108 deqpSourceDirectory = os.path.join("..", "third_party", "VK-GL-CTS", "src") 109 # Tests Directory 110 testsDirectory = os.path.join("..", "src", "tests") 111 # dEQP Support Directory 112 deqpSupportDirectory = "deqp_support" 113 # BUILD.gn file to write to 114 buildGnFilename = "BUILD.gn" 115 # Path to BUILD.gn 116 buildGnPath = os.path.join(testsDirectory, deqpSupportDirectory, buildGnFilename) 117 # dEQP data GNI File to write to 118 dataGniFilename = os.path.join(testsDirectory, deqpSupportDirectory, "deqp_data_autogen.gni") 119 120 # run_code_generation.py parameters. 121 if len(sys.argv) > 1: 122 # All CMakeLists.txt in the dEQP source tree (at the time) 123 cmakeDirs = getCMakeLists(deqpSourceDirectory) 124 inputs = [os.path.join(deqpSourceDirectory, "%s" % dir) for dir in cmakeDirs] 125 outputs = [dataGniFilename, buildGnPath] 126 127 if sys.argv[1] == 'inputs': 128 print(','.join(inputs)) 129 elif sys.argv[1] == 'outputs': 130 print(','.join(outputs)) 131 else: 132 print('Invalid script parameters') 133 return 1 134 return 0 135 136 deqpSrcDir = os.path.abspath(os.path.join(sys.path[0], deqpSourceDirectory)) 137 138 initDataDirectories(dataDirectories) 139 initPathReplacements(pathReplacements) 140 141 dataFiles = [] 142 for dataDir in dataDirectories: 143 dataPath = os.path.join(deqpSrcDir, dataDir) 144 for root, directories, filenames in os.walk(dataPath): 145 for filename in filenames: 146 relativeDirectory = os.path.relpath(root, deqpSrcDir) 147 # Skip any excluded directories 148 if any(directory in relativeDirectory for directory in excludedDirectories): 149 continue 150 # Skip any excluded files 151 if any(excludedFilename in filename for excludedFilename in excludedFilenames): 152 continue 153 # Record the relative directories and full paths to each data file 154 if relativeDirectory not in relativeDirectories: 155 relativeDirectories.append(relativeDirectory) 156 dataFiles.append(os.path.join(relativeDirectory, filename)) 157 158 dataFiles.sort() 159 relativeDirectories.sort(key=convertPathToVarName) 160 161 # 162 # BUILD.gn 163 # 164 buildGnFile = createBuildGnFile(buildGnPath) 165 writeFileHeader(buildGnFile) 166 # Definitions 167 buildGnFile.write("deqp_path = \"../../../third_party/VK-GL-CTS/src\"\n") 168 # Create the copy() commands 169 templateFilesToCopy = """ "$deqp_path/{dataFile}", 170""" 171 templateCopyCommand = """ 172copy("vk_gl_cts_data_{relDir}") {{ 173 sources = [ 174 {filesToCopy} 175 ] 176 outputs = [ "$root_gen_dir/vk_gl_cts_data/{destDir}/{{{{source_file_part}}}}" ] 177}} 178""" 179 for relativeDirectory in relativeDirectories: 180 filesToCopy = "" 181 for dataFile in dataFiles: 182 path, filename = os.path.split(dataFile) 183 if relativeDirectory == path: 184 filesToCopy += templateFilesToCopy.format(dataFile=dataFile.replace(os.sep, '/')) 185 copyCommand = "" 186 destDir = fixDestinationDirectory(pathReplacements, relativeDirectory) 187 copyCommand += templateCopyCommand.format( 188 relDir=convertPathToVarName(relativeDirectory), 189 filesToCopy=filesToCopy, 190 destDir=destDir.replace(os.sep, '/')) 191 buildGnFile.write(copyCommand) 192 193 # 194 # .gni 195 # 196 gniFile = createGniFile(dataGniFilename) 197 writeFileHeader(gniFile) 198 # Imports 199 templateImports = """import("deqp.gni") 200""" 201 gniFile.write(templateImports) 202 # Write the lists of data file dependencies 203 templateDataFiles = """ "$root_gen_dir/vk_gl_cts_data/{dataFile}", 204""" 205 templateDataFileDeps = """ 206{dataDepName} = [ 207{files}] 208""" 209 for dataDirectory in dataDirectories: 210 files = "" 211 for dataFile in dataFiles: 212 if dataDirectory + os.sep in dataFile: 213 files += templateDataFiles.format( 214 dataFile=fixDestinationDirectory(pathReplacements, dataFile).replace( 215 os.sep, '/')) 216 dataDepName = "angle_deqp_" + convertPathToVarName(dataDirectory) 217 fileDeps = templateDataFileDeps.format(dataDepName=dataDepName, files=files) 218 gniFile.write(fileDeps) 219 220 templateCopyTarget = """ "{deqpSupportDirectory}:vk_gl_cts_data_{relDir}", 221""" 222 templateCopyTargets = """ 223angle_deqp_data_copy_targets = [ 224{targets}] 225""" 226 targets = "" 227 for relativeDirectory in relativeDirectories: 228 targets += templateCopyTarget.format( 229 deqpSupportDirectory=deqpSupportDirectory, 230 relDir=convertPathToVarName(relativeDirectory)) 231 gniFile.write(templateCopyTargets.format(targets=targets)) 232 233 234if __name__ == '__main__': 235 sys.exit(main()) 236