• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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