blob: 2efec1417ce22e5744181df6f068c62abc02bfa3 [file] [log] [blame]
John Stilesd836f842020-09-14 10:21:44 -04001#!/usr/bin/env python
2#
3# Copyright 2020 Google LLC
4#
5# Use of this source code is governed by a BSD-style license that can be
6# found in the LICENSE file.
7
8import os
John Stilesb7f5e1b2021-01-27 14:05:15 -05009import shlex
John Stilesd836f842020-09-14 10:21:44 -040010import subprocess
11import sys
Brian Osman7b239052020-11-18 17:04:33 +000012import tempfile
John Stilesd836f842020-09-14 10:21:44 -040013
John Stilesb7f5e1b2021-01-27 14:05:15 -050014batchCompile = True
15
John Stiles0ed9f312020-09-16 17:46:37 -040016skslc = sys.argv[1]
John Stiles7e248712020-09-24 16:42:09 -040017lang = sys.argv[2]
18settings = sys.argv[3]
John Stilesb7f5e1b2021-01-27 14:05:15 -050019with open(sys.argv[4], 'r') as reader:
20 inputs = shlex.split(reader.read())
John Stilesf92f89b2021-01-12 14:05:05 -050021
John Stilesda57fc02021-01-22 11:54:30 -050022def pairwise(iterable):
23 # Iterate over an array pairwise (two elements at a time).
24 a = iter(iterable)
25 return zip(a, a)
26
John Stilesf92f89b2021-01-12 14:05:05 -050027def executeWorklist(input, worklist):
28 # Invoke skslc, passing in the worklist.
29 worklist.close()
30 try:
31 output = subprocess.check_output([skslc, worklist.name], stderr=subprocess.STDOUT)
32 except subprocess.CalledProcessError as err:
33 if err.returncode != 1:
34 print("### " + input + " skslc error:\n")
35 print("\n".join(err.output.splitlines()))
36 sys.exit(err.returncode)
37 pass # Compile errors (exit code 1) are expected and normal in test code
38
39 # Delete the worklist file now that execution is complete.
40 os.remove(worklist.name)
John Stiles0ed9f312020-09-16 17:46:37 -040041
John Stiles886b9d42020-09-15 11:16:10 -040042def makeEmptyFile(path):
John Stilesea9e7ca2020-09-14 16:46:40 -040043 try:
John Stiles886b9d42020-09-15 11:16:10 -040044 open(path, 'wb').close()
John Stilesea9e7ca2020-09-14 16:46:40 -040045 except OSError:
46 pass
47
John Stilesdda1d312020-11-20 16:28:50 -050048def extensionForSpirvAsm(ext):
John Stiles92072a32020-11-23 15:14:35 -050049 return ext if (ext == '.frag' or ext == '.vert' or ext == '.geom') else '.frag'
John Stilesdda1d312020-11-20 16:28:50 -050050
John Stiles0ed9f312020-09-16 17:46:37 -040051if settings != "--settings" and settings != "--nosettings":
John Stiles7e248712020-09-24 16:42:09 -040052 sys.exit("### Expected --settings or --nosettings, got " + settings)
John Stilesd836f842020-09-14 10:21:44 -040053
John Stilesa1e8fe32020-11-11 17:29:28 -050054targets = []
John Stiles57adba02020-11-18 13:58:19 -050055worklist = tempfile.NamedTemporaryFile(suffix='.worklist', delete=False)
John Stilesa1e8fe32020-11-11 17:29:28 -050056
John Stilesda57fc02021-01-22 11:54:30 -050057# The `inputs` array pairs off input files with their matching output directory, e.g.:
58# //skia/tests/sksl/shared/test.sksl
59# //skia/tests/sksl/shared/golden/
60# //skia/tests/sksl/intrinsics/abs.sksl
61# //skia/tests/sksl/intrinsics/golden/
62# ... (etc) ...
63# Here we loop over these inputs and convert them into a worklist file for skslc.
64for input, targetDir in pairwise(inputs):
John Stilesdda1d312020-11-20 16:28:50 -050065 noExt, ext = os.path.splitext(input)
John Stilesea9e7ca2020-09-14 16:46:40 -040066 head, tail = os.path.split(noExt)
John Stilesea9e7ca2020-09-14 16:46:40 -040067 if not os.path.isdir(targetDir):
68 os.mkdir(targetDir)
John Stiles0ed9f312020-09-16 17:46:37 -040069
John Stilesea9e7ca2020-09-14 16:46:40 -040070 target = os.path.join(targetDir, tail)
John Stiles0ed9f312020-09-16 17:46:37 -040071 if settings == "--nosettings":
John Stiles371fde52020-09-21 17:09:52 -040072 target += "StandaloneSettings"
John Stiles0ed9f312020-09-16 17:46:37 -040073
John Stilesa1e8fe32020-11-11 17:29:28 -050074 targets.append(target)
75
John Stiles7e248712020-09-24 16:42:09 -040076 if lang == "--fp":
Brian Osman7b239052020-11-18 17:04:33 +000077 worklist.write(input + "\n")
78 worklist.write(target + ".cpp\n")
79 worklist.write(settings + "\n\n")
80 worklist.write(input + "\n")
81 worklist.write(target + ".h\n")
82 worklist.write(settings + "\n\n")
John Stiles82ab3402021-04-13 17:13:03 -040083 elif lang == "--dslfp":
84 worklist.write(input + "\n")
John Stiles0a0a50a2021-04-14 09:35:24 -040085 worklist.write(target + ".dsl.cpp\n")
John Stiles82ab3402021-04-13 17:13:03 -040086 worklist.write(settings + "\n\n")
87 worklist.write(input + "\n")
88 worklist.write(target + ".h\n")
89 worklist.write(settings + "\n\n")
John Stiles7e248712020-09-24 16:42:09 -040090 elif lang == "--glsl":
Brian Osman7b239052020-11-18 17:04:33 +000091 worklist.write(input + "\n")
92 worklist.write(target + ".glsl\n")
93 worklist.write(settings + "\n\n")
John Stilesaeae3a52020-09-25 13:35:58 -040094 elif lang == "--metal":
Brian Osman7b239052020-11-18 17:04:33 +000095 worklist.write(input + "\n")
96 worklist.write(target + ".metal\n")
97 worklist.write(settings + "\n\n")
John Stilesdda1d312020-11-20 16:28:50 -050098 elif lang == "--spirv":
99 worklist.write(input + "\n")
John Stiles92072a32020-11-23 15:14:35 -0500100 worklist.write(target + ".asm" + extensionForSpirvAsm(ext) + "\n")
John Stilesdda1d312020-11-20 16:28:50 -0500101 worklist.write(settings + "\n\n")
Brian Osman977feec2020-12-22 11:28:59 -0500102 elif lang == "--skvm":
103 worklist.write(input + "\n")
104 worklist.write(target + ".skvm\n")
105 worklist.write(settings + "\n\n")
Brian Osman62b039b2021-02-08 13:49:53 -0500106 elif lang == "--stage":
107 worklist.write(input + "\n")
108 worklist.write(target + ".stage\n")
109 worklist.write(settings + "\n\n")
John Stilesea9e7ca2020-09-14 16:46:40 -0400110 else:
John Stiles82ab3402021-04-13 17:13:03 -0400111 sys.exit("### Expected one of: --fp --dslfp --glsl --metal --spirv --skvm --stage, got " +
112 lang)
John Stilesa1e8fe32020-11-11 17:29:28 -0500113
John Stilesf92f89b2021-01-12 14:05:05 -0500114 # Compile items one at a time.
115 if not batchCompile:
116 executeWorklist(input, worklist)
117 worklist = tempfile.NamedTemporaryFile(suffix='.worklist', delete=False)
John Stilesa1e8fe32020-11-11 17:29:28 -0500118
John Stilesf92f89b2021-01-12 14:05:05 -0500119# Compile everything all in one go.
120if batchCompile:
121 executeWorklist("", worklist)
122else:
123 worklist.close()
124 os.remove(worklist.name)
John Stiles57adba02020-11-18 13:58:19 -0500125
John Stilesa1e8fe32020-11-11 17:29:28 -0500126# A special case cleanup pass, just for CPP and H files: if either one of these files starts with
127# `### Compilation failed`, its sibling should be replaced by an empty file. This improves clarity
128# during code review; a failure on either file means that success on the sibling is irrelevant.
John Stiles82ab3402021-04-13 17:13:03 -0400129if lang == "--fp" or lang == "--dslfp":
John Stiles0a0a50a2021-04-14 09:35:24 -0400130 cppExtension = (".dsl.cpp" if lang == "--dslfp" else ".cpp")
John Stiles82ab3402021-04-13 17:13:03 -0400131 hExtension = ".h"
132
John Stilesa1e8fe32020-11-11 17:29:28 -0500133 for target in targets:
John Stiles82ab3402021-04-13 17:13:03 -0400134 cppFile = open(target + cppExtension, 'r')
135 hFile = open(target + hExtension, 'r')
John Stilesa1e8fe32020-11-11 17:29:28 -0500136 if cppFile.readline().startswith("### Compilation failed"):
137 # The CPP had a compilation failure. Clear the header file.
138 hFile.close()
John Stiles82ab3402021-04-13 17:13:03 -0400139 makeEmptyFile(target + hExtension)
John Stilesa1e8fe32020-11-11 17:29:28 -0500140 elif hFile.readline().startswith("### Compilation failed"):
141 # The header had a compilation failure. Clear the CPP file.
142 cppFile.close()
John Stiles82ab3402021-04-13 17:13:03 -0400143 makeEmptyFile(target + cppExtension)