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