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