#!/usr/bin/python2 # Copyright 2019 The ANGLE Project Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # # Code generation for: # - src/tests/deqp_support/BUILD.gn # - src/tests/deqp_data.gni # NOTE: don't run this script directly. Run scripts/run_code_generation.py. import errno import os import sys import shutil def initDataDirectories(dataDirectories): dataDirectories.append(os.path.join("data", "gles2")) dataDirectories.append(os.path.join("data", "gles3")) dataDirectories.append(os.path.join("data", "gles31")) dataDirectories.append(os.path.join("external", "graphicsfuzz", "data", "gles3")) dataDirectories.append(os.path.join("external", "openglcts", "data", "gles3")) def initPathReplacements(pathReplacements): # The GraphicsFuzz data files need the 'external/graphicsfuzz/' prefix removed pathToReplace = os.path.join("external", "graphicsfuzz", "") # Include trailing slash pathReplacements[pathToReplace] = "" # The KHR dEQP tests expect a root prefix of "gl_cts" for some reason. pathToReplace = os.path.join("external", "openglcts", "") # Include trailing slash pathReplacements[pathToReplace] = os.path.join("data", "gl_cts", "") def createBuildGnFile(buildGnPath): # Cleanup the old file if os.path.exists(buildGnPath): os.remove(buildGnPath) # Make the new one return open(buildGnPath, "w+") def createGniFile(gniFilename): # Cleanup the old file if os.path.exists(gniFilename): os.remove(gniFilename) # Make the new one return open(gniFilename, "w+") def writeFileHeader(fileIn): templateFileHeader = """# GENERATED FILE - DO NOT EDIT. # Generated by: {script_name} # # Copyright 2019 The ANGLE Project Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """ fileHeader = templateFileHeader.format(script_name=os.path.basename(__file__)) fileIn.write(fileHeader) def fixDestinationDirectory(pathReplacements, relativeDirectory): for pathReplacement in pathReplacements: if pathReplacement in relativeDirectory: return relativeDirectory.replace(pathReplacement, pathReplacements[pathReplacement]) return relativeDirectory def convertPathToVarName(path): return path.replace(os.sep, "_") def getCMakeLists(deqpSrcDir): cmakeLists = [] for root, directories, filenames in os.walk(deqpSrcDir): for filename in filenames: relativeDirectory = os.path.relpath(root, deqpSrcDir) if filename == "CMakeLists.txt": cmakeLists.append(os.path.join(relativeDirectory, filename)) return cmakeLists def main(): # List of directories containing data files dataDirectories = [] # List of directories to exclude from the copy excludedDirectories = [ ".git", ] # List of files to exclude from the copy excludedFilenames = [ "LICENSE", ] # Dictionary of parts of paths that need to be replaced # Key: Part of path to be replaced # Value: What to replace it with pathReplacements = {} # List of unique relative directories for the copy() command outputs relativeDirectories = [] # VK-GL-CTS source directory deqpSourceDirectory = os.path.join("..", "third_party", "VK-GL-CTS", "src") # Tests Directory testsDirectory = os.path.join("..", "src", "tests") # dEQP Support Directory deqpSupportDirectory = "deqp_support" # BUILD.gn file to write to buildGnFilename = "BUILD.gn" # Path to BUILD.gn buildGnPath = os.path.join(testsDirectory, deqpSupportDirectory, buildGnFilename) # dEQP data GNI File to write to dataGniFilename = os.path.join(testsDirectory, deqpSupportDirectory, "deqp_data_autogen.gni") # run_code_generation.py parameters. if len(sys.argv) > 1: # All CMakeLists.txt in the dEQP source tree (at the time) cmakeDirs = getCMakeLists(deqpSourceDirectory) inputs = [os.path.join(deqpSourceDirectory, "%s" % dir) for dir in cmakeDirs] outputs = [dataGniFilename, buildGnPath] if sys.argv[1] == 'inputs': print(','.join(inputs)) elif sys.argv[1] == 'outputs': print(','.join(outputs)) else: print('Invalid script parameters') return 1 return 0 deqpSrcDir = os.path.abspath(os.path.join(sys.path[0], deqpSourceDirectory)) initDataDirectories(dataDirectories) initPathReplacements(pathReplacements) dataFiles = [] for dataDir in dataDirectories: dataPath = os.path.join(deqpSrcDir, dataDir) for root, directories, filenames in os.walk(dataPath): for filename in filenames: relativeDirectory = os.path.relpath(root, deqpSrcDir) # Skip any excluded directories if any(directory in relativeDirectory for directory in excludedDirectories): continue # Skip any excluded files if any(excludedFilename in filename for excludedFilename in excludedFilenames): continue # Record the relative directories and full paths to each data file if relativeDirectory not in relativeDirectories: relativeDirectories.append(relativeDirectory) dataFiles.append(os.path.join(relativeDirectory, filename)) dataFiles.sort() relativeDirectories.sort(key=convertPathToVarName) # # BUILD.gn # buildGnFile = createBuildGnFile(buildGnPath) writeFileHeader(buildGnFile) # Definitions buildGnFile.write("deqp_path = \"../../../third_party/VK-GL-CTS/src\"\n") # Create the copy() commands templateFilesToCopy = """ "$deqp_path/{dataFile}", """ templateCopyCommand = """ copy("vk_gl_cts_data_{relDir}") {{ sources = [ {filesToCopy} ] outputs = [ "$root_gen_dir/vk_gl_cts_data/{destDir}/{{{{source_file_part}}}}" ] }} """ for relativeDirectory in relativeDirectories: filesToCopy = "" for dataFile in dataFiles: path, filename = os.path.split(dataFile) if relativeDirectory == path: filesToCopy += templateFilesToCopy.format(dataFile=dataFile.replace(os.sep, '/')) copyCommand = "" destDir = fixDestinationDirectory(pathReplacements, relativeDirectory) copyCommand += templateCopyCommand.format( relDir=convertPathToVarName(relativeDirectory), filesToCopy=filesToCopy, destDir=destDir.replace(os.sep, '/')) buildGnFile.write(copyCommand) # # .gni # gniFile = createGniFile(dataGniFilename) writeFileHeader(gniFile) # Imports templateImports = """import("deqp.gni") """ gniFile.write(templateImports) # Write the lists of data file dependencies templateDataFiles = """ "$root_gen_dir/vk_gl_cts_data/{dataFile}", """ templateDataFileDeps = """ {dataDepName} = [ {files}] """ for dataDirectory in dataDirectories: files = "" for dataFile in dataFiles: if dataDirectory + os.sep in dataFile: files += templateDataFiles.format( dataFile=fixDestinationDirectory(pathReplacements, dataFile).replace( os.sep, '/')) dataDepName = "angle_deqp_" + convertPathToVarName(dataDirectory) fileDeps = templateDataFileDeps.format(dataDepName=dataDepName, files=files) gniFile.write(fileDeps) templateCopyTarget = """ "{deqpSupportDirectory}:vk_gl_cts_data_{relDir}", """ templateCopyTargets = """ angle_deqp_data_copy_targets = [ {targets}] """ targets = "" for relativeDirectory in relativeDirectories: targets += templateCopyTarget.format( deqpSupportDirectory=deqpSupportDirectory, relDir=convertPathToVarName(relativeDirectory)) gniFile.write(templateCopyTargets.format(targets=targets)) if __name__ == '__main__': sys.exit(main())