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