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