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