14 from string
import Template
17 def __init__(self
, fileName
):
19 self
.fileName
= os
.path
.abspath(fileName
)
22 def __exit__(self
, type, value
, traceback
):
23 if os
.path
.exists(self
.fileName
):
24 with open(self
.fileName
, "r") as file:
25 fileData
= file.read()
26 if fileData
== self
.data
: return
28 dir = os
.path
.dirname(self
.fileName
)
29 if not os
.path
.exists(dir):
31 with open(self
.fileName
, "w") as file:
38 def __init__(self
, name
, value
):
41 def __lt__(self
, other
):
42 return self
.name
.__lt
__(other
.name
)
44 return NinjaFile
.lineWrap("{} = {}".format(self
.name
, self
.value
))
47 def __init__(self
, name
, command
, depfile
):
49 self
.command
= command
50 self
.depfile
= depfile
51 def __lt__(self
, other
):
52 return self
.name
.__lt
__(other
.name
)
54 result
= NinjaFile
.lineWrap("rule {}".format(self
.name
))
55 if self
.command
: result
+= ("\n"+ NinjaFile
.lineWrap(" command = {}".format(self
.command
)))
57 result
+= ("\n" + NinjaFile
.lineWrap(" deps = gcc"))
58 result
+= ("\n" + NinjaFile
.lineWrap(" depfile = {}".format(self
.depfile
)))
61 def __init__(self
, rule
):
66 self
.dependencies
= []
67 def __lt__(self
, other
):
68 return self
.output
.__lt
__(other
.output
)
72 self
.dependencies
.sort()
73 buildLine
= "build {}: {}".format(self
.output
, self
.rule
)
74 if self
.inputs
: buildLine
+= " {}".format(" ".join(self
.inputs
))
75 if self
.dependencies
: buildLine
+= " | {}".format(" ".join(self
.dependencies
))
76 result
= NinjaFile
.lineWrap(buildLine
)
77 for variable
in self
.variables
: result
+= ("\n" + NinjaFile
.lineWrap(" " + str(variable
)))
79 def addVariable(self
, name
, value
): self
.variables
.append(NinjaFile
.Variable(name
, value
))
80 def addDependency(self
, dependency
):
81 if isinstance(dependency
, str):
82 self
.dependencies
.append(dependency
)
83 elif isinstance(dependency
, NinjaFile
.Target
):
84 self
.dependencies
.append(dependency
.output
)
86 raise ValueError("dependency must be a string or NinjaFile.Target")
87 def addInput(self
, input):
88 if isinstance(input, str):
89 self
.inputs
.append(input)
90 elif isinstance(input, NinjaFile
.Target
):
91 self
.inputs
.append(input.output
)
93 raise ValueError("input must be a string or NinjaFile.Target")
95 def __init__(self
, file):
97 def __lt__(self
, other
):
98 return self
.file.__lt
__(other
.file)
100 return NinjaFile
.lineWrap("include {}".format(self
.file))
102 def __init__(self
, fileName
):
103 self
.fileName
= os
.path
.abspath(fileName
)
110 def __exit__(self
, type, value
, traceback
):
111 with BufferedFile(self
.fileName
) as file:
112 file.write(str(self
))
113 def addRule(self
, name
, command
, deps
): self
.rules
.append(NinjaFile
.Rule(name
, command
, deps
))
114 def addVariable(self
, name
, value
): self
.variables
.append(NinjaFile
.Variable(name
, value
))
115 def addInclude(self
, file): self
.includes
.append(NinjaFile
.Include(file))
116 def newTarget(self
, type, name
):
117 target
= NinjaFile
.Target(type)
119 self
.targets
.append(target
)
121 def findTarget(self
, name
):
122 #PERF If this gets to be significant we can sort the array and binary search it
123 for target
in self
.targets
:
124 if target
.output
== name
: return target
125 raise ValueError("Target \"{}\" not found".format(name
))
126 def deleteTarget(self
, name
): self
.targets
.remove(self
.findTarget(name
))
128 self
.variables
.sort()
133 "VARIABLES": "\n".join(map(str, self
.variables
)),
134 "RULES": "\n\n".join(map(str, self
.rules
)),
135 "TARGETS": "\n\n".join(map(str, self
.targets
)),
136 "INCLUDES": "\n\n".join(map(str, self
.includes
))
138 return string
.Template(
139 """ninja_required_version = 1.6
149 """).safe_substitute(subs
)
150 # wrapper = textwrap.TextWrapper(width = 130, subsequent_indent = " ", break_long_words = False)
152 def lineWrap(cls
, line
):
153 if len(line
) <= 132: return line
156 wrappedLineLeadingSpace
= " "
158 if line
[0].isspace():
161 wrappedLineLeadingSpace
= " "
163 wrappedLineLeadingSpaceLen
= len(wrappedLineLeadingSpace
)
164 lineSpaceAvailable
= 132-(firstLineIndent
+wrappedLineLeadingSpaceLen
)
166 wordsCount
= len(words
)-1
167 for idx
, word
in enumerate(words
):
169 if (wordLen
<= lineSpaceAvailable
and idx
== wordsCount
):
171 elif wordLen
<= lineSpaceAvailable
+2:
172 result
+= "{} ".format(word
)
173 lineSpaceAvailable
-= (wordLen
)
175 result
+= "$\n{}{} ".format(wrappedLineLeadingSpace
, word
)
176 lineSpaceAvailable
= 132-(wrappedLineLeadingSpaceLen
+wordLen
)
179 def processBuildLines(ninja
, buildLines
, testName
, platform
, osFlag
, forceArchs
, testDstDir
, testSrcDir
):
180 testInstallTarget
= ninja
.newTarget("phony", "install-{}".format(testName
))
181 testTarget
= ninja
.newTarget("phony", testName
)
182 ninja
.findTarget("all").addInput(testTarget
)
183 ninja
.findTarget("install").addInput(testInstallTarget
)
184 for buildLine
in buildLines
:
186 args
= buildLine
.split()
187 if args
[0] == "$DTRACE":
189 for idx
, arg
in enumerate(args
):
190 if arg
== "-o": target
= ninja
.newTarget("dtrace", args
[idx
+1])
191 for idx
, arg
in enumerate(args
):
192 if arg
== "-s": target
.addInput(testSrcDir
+ "/" + args
[idx
+1])
193 elif args
[0] == "$CP":
194 target
= ninja
.newTarget("cp", args
[2])
195 target
.addInput(testSrcDir
+ "/" + args
[1])
196 testTarget
.addInput(target
)
197 installTarget
= ninja
.newTarget("install", "$INSTALL_DIR/AppleInternal/CoreOS/tests/dyld/{}".format(args
[2][9:]))
198 installTarget
.addInput(target
.output
)
199 installTarget
.addVariable("mode", "0644")
200 testInstallTarget
.addInput(installTarget
)
201 elif args
[0] == "$SYMLINK":
202 target
= ninja
.newTarget("symlink", args
[2])
203 target
.addVariable("source", args
[1])
204 testTarget
.addInput(target
)
205 installTarget
= ninja
.newTarget("symlink", "$INSTALL_DIR/AppleInternal/CoreOS/tests/dyld/{}".format(args
[2][9:]))
206 installTarget
.addVariable("source", args
[1])
207 testInstallTarget
.addInput(installTarget
)
208 elif args
[0] == "$STRIP":
209 target
= ninja
.findTarget(args
[1])
210 target
.addVariable("extraCmds", "&& strip {}".format(target
.output
))
211 elif args
[0] == "$SKIP_INSTALL":
212 target
= "$INSTALL_DIR/AppleInternal/CoreOS/tests/dyld/{}".format(args
[1][9:])
213 ninja
.deleteTarget(target
)
214 testInstallTarget
.inputs
.remove(target
)
215 elif args
[0] == "$DYLD_ENV_VARS_ENABLE":
216 if platform
!= "macos":
217 target
= ninja
.findTarget(args
[1])
218 target
.addVariable("entitlements", "--entitlements $SRCROOT/testing/get_task_allow_entitlement.plist")
219 elif args
[0] == "$TASK_FOR_PID_ENABLE":
220 target
= ninja
.findTarget(args
[1])
221 target
.addVariable("entitlements", "--entitlements $SRCROOT/testing/task_read_for_pid_entitlement.plist")
222 elif args
[0] in ["$CC", "$CXX"]:
223 tool
= args
[0][1:].lower()
230 linkTestSupport
= True
231 platformVersion
= None
232 targetNames
= [target
.output
for target
in ninja
.targets
]
233 args
= [escapedArg
.replace("\"", "\\\"") for escapedArg
in args
[1:]]
234 #First find the target
235 for idx
, arg
in enumerate(args
):
237 linkTarget
= ninja
.newTarget("{}-link".format(tool
), args
[idx
+1])
238 linkTarget
.addDependency("$BUILT_PRODUCTS_DIR/libtest_support.a")
239 testTarget
.addInput(linkTarget
);
242 for idx
, arg
in enumerate(args
):
243 if skipCount
: skipCount
-= 1
246 elif arg
== "$DEPENDS_ON":
248 dependencies
.append(args
[idx
+1])
249 elif arg
in ["-arch"]:
251 nextArg
= args
[idx
+1]
253 ldflags
.append(nextArg
)
255 cflags
.append(nextArg
)
256 elif arg
in ["-target"]:
258 nextArg
= args
[idx
+1]
260 ldflags
.append(nextArg
)
262 cflags
.append(nextArg
)
263 elif arg
in ["-install_name","-framework", "-rpath","-compatibility_version","-sub_library", "-undefined", "-current_version"]:
265 nextArg
= args
[idx
+1]
267 ldflags
.append(nextArg
)
268 elif arg
== "-sectcreate":
271 ldflags
.append(args
[idx
+1])
272 ldflags
.append(args
[idx
+2])
273 ldflags
.append(args
[idx
+3])
274 elif arg
[:2] == "-L": ldflags
.append(arg
)
275 elif arg
[:2] == "-F": ldflags
.append(arg
)
276 elif arg
== "-nostdlib":
278 # Kernel tests pass -nostdlib so don't link test support
279 linkTestSupport
= False
280 elif arg
== "-flat_namespace":
282 elif arg
in ["-dynamiclib","-bundle"]:
284 linkTestSupport
= False
285 elif arg
.endswith((".s", ".c", ".cpp", ".cxx", ".m", ".mm")):
286 if not arg
.startswith("$SRCROOT"): sources
.append(testSrcDir
+ "/" + arg
)
287 else: sources
.append(arg
)
288 elif arg
in targetNames
:
289 linkTarget
.addInput(arg
)
291 minOS
= arg
[arg
.find('=')+1:]
292 elif arg
[:4] == "-Wl,":
293 linkerArgs
= arg
.split(",")
294 if linkerArgs
[1] == "-platform_version":
295 minOS
= linkerArgs
[3]
296 platformVersion
= arg
298 for linkerArg
in linkerArgs
[1:]:
299 if linkerArg
in targetNames
: linkTarget
.addDependency(linkerArg
)
301 elif arg
[:2] == "-l":
302 candidate
= "{}/lib{}.dylib".format(testDstDir
, arg
[2:])
303 if candidate
in targetNames
: linkTarget
.addDependency(candidate
)
305 elif arg
[:7] == "-weak-l":
306 candidate
= "{}/lib{}.dylib".format(testDstDir
, arg
[7:])
307 if candidate
in targetNames
: linkTarget
.addDependency(candidate
)
309 elif arg
[:9] == "-upward-l":
310 candidate
= "{}/lib{}.dylib".format(testDstDir
, arg
[9:])
311 if candidate
in targetNames
: linkTarget
.addDependency(candidate
)
313 elif arg
[:8] == "-fuse-ld":
314 # This is not typically used, but if we ever wanted to try a new ld64, it can be useful
319 ldflags
.append("-force_load $BUILT_PRODUCTS_DIR/libtest_support.a")
320 for source
in sources
:
321 objectHash
= hashlib
.sha1(linkTarget
.output
+source
+tool
+"".join(cflags
)).hexdigest()
322 target
= ninja
.newTarget(tool
, "$OBJROOT/dyld_tests.build/Objects-normal/" + objectHash
+ ".o")
323 target
.addInput(source
)
324 target
.dependencies
= dependencies
325 if cflags
: target
.addVariable("cflags", " ".join(cflags
))
326 if minOS
: target
.addVariable("minOS", "-" + osFlag
+ "=" + minOS
)
327 if forceArchs
: target
.addVariable("archs", " ".join(["-arch {}".format(arch
) for arch
in forceArchs
]))
328 linkTarget
.addInput(target
)
329 if ldflags
: linkTarget
.addVariable("ldflags", " ".join(ldflags
))
330 if platformVersion
: linkTarget
.addVariable("minOS", platformVersion
)
331 elif minOS
: linkTarget
.addVariable("minOS", "-" + osFlag
+ "=" + minOS
)
332 if forceArchs
: linkTarget
.addVariable("archs", " ".join(["-arch {}".format(arch
) for arch
in forceArchs
]))
333 installTarget
= ninja
.newTarget("install", "$INSTALL_DIR/AppleInternal/CoreOS/tests/dyld/{}".format(linkTarget
.output
[9:]))
334 installTarget
.addInput(linkTarget
)
335 testTarget
.addInput(linkTarget
)
336 testInstallTarget
.addInput(installTarget
)
337 elif args
[0] == "$APP_CACHE_UTIL":
338 tool
= args
[0][1:].lower()
344 args
= [escapedArg
.replace("\"", "\\\"") for escapedArg
in args
[1:]]
346 for idx
, arg
in enumerate(args
):
347 if skipCount
: skipCount
-= 1
348 elif arg
== "$DEPENDS_ON":
350 dependencies
.append(args
[idx
+1])
351 elif arg
== "-create-kernel-collection":
353 linkTarget
= ninja
.newTarget("app-cache-util", args
[idx
+1])
354 linkTarget
.addVariable("create_kind", arg
)
355 testTarget
.addInput(linkTarget
)
356 dependencies
.append("$BUILT_PRODUCTS_DIR/host_tools/dyld_app_cache_util")
357 elif arg
== "-kernel":
359 linkTarget
.addInput(args
[idx
+1])
361 flags
.append(args
[idx
+1])
362 elif arg
== "-create-aux-kernel-collection":
364 linkTarget
= ninja
.newTarget("app-cache-util", args
[idx
+1])
365 linkTarget
.addVariable("create_kind", arg
)
366 testTarget
.addInput(linkTarget
)
367 dependencies
.append("$BUILT_PRODUCTS_DIR/host_tools/dyld_app_cache_util")
368 elif arg
== "-create-pageable-kernel-collection":
370 linkTarget
= ninja
.newTarget("app-cache-util", args
[idx
+1])
371 linkTarget
.addVariable("create_kind", arg
)
372 testTarget
.addInput(linkTarget
)
373 dependencies
.append("$BUILT_PRODUCTS_DIR/host_tools/dyld_app_cache_util")
374 elif arg
== "-kernel-collection":
376 linkTarget
.addInput(args
[idx
+1])
378 flags
.append(args
[idx
+1])
379 elif arg
== "-pageable-collection":
381 linkTarget
.addInput(args
[idx
+1])
383 flags
.append(args
[idx
+1])
386 linkTarget
.dependencies
= dependencies
387 if flags
: linkTarget
.addVariable("flags", " ".join(flags
))
388 if forceArchs
: linkTarget
.addVariable("archs", " ".join(["-arch {}".format(arch
) for arch
in forceArchs
]))
389 installTarget
= ninja
.newTarget("install", "$INSTALL_DIR/AppleInternal/CoreOS/tests/dyld/{}".format(linkTarget
.output
[9:]))
390 installTarget
.addInput(linkTarget
)
391 testTarget
.addInput(linkTarget
)
392 testInstallTarget
.addInput(installTarget
)
393 else: raise ValueError("Unknown Command: {}".format(args
[0]))
396 def processRunLine(runFile
, runLine
, environment
):
397 if runLine
.startswith("sudo "):
398 runFile
.write("sudo {} {}\n".format(environment
, runLine
[5:]))
400 runFile
.write("{} {}\n".format(environment
, runLine
))
402 def processRunLines(ninja
, runLines
, testName
, platform
, runStatic
, symRoot
, xcTestInvocations
):
403 runFilePath
= "{}/{}/run.sh".format(symRoot
, testName
)
404 for runLine
in runLines
:
405 xcTestInvocations
.append("{{ \"{}\", \"{}\" }}".format(testName
, runLine
.replace("\"","\\\"").replace("sudo","")))
406 with BufferedFile(runFilePath
) as runFile
:
407 runFile
.write("#!/bin/sh\n")
408 runFile
.write("cd {}\n".format(testRunDir
))
411 runFile
.write("echo \"run static\" \n");
412 for runLine
in runLines
:
413 processRunLine(runFile
, runLine
, "TEST_OUTPUT=BATS")
415 runFile
.write("echo \"run in dyld2 mode\" \n");
416 for runLine
in runLines
:
417 processRunLine(runFile
, runLine
, "TEST_OUTPUT=BATS DYLD_USE_CLOSURES=0")
419 runFile
.write("echo \"run in dyld3 mode\" \n");
420 for runLine
in runLines
:
421 processRunLine(runFile
, runLine
, "TEST_OUTPUT=BATS DYLD_USE_CLOSURES=1")
423 runFile
.write("echo \"run in dyld3s mode\" \n");
424 for runLine
in runLines
:
425 if runLine
.startswith("sudo "):
426 runFile
.write("sudo TEST_OUTPUT=BATS DYLD_USE_CLOSURES=2 {}\n".format(runLine
[5:]))
428 runFile
.write("TEST_OUTPUT=BATS DYLD_USE_CLOSURES=2 {}\n".format(runLine
))
429 os
.chmod(runFilePath
, 0755)
430 installPath
= "$INSTALL_DIR/AppleInternal/CoreOS/tests/dyld/{}/run.sh".format(testName
)
431 target
= ninja
.newTarget("install", installPath
)
432 target
.addInput(runFilePath
)
433 ninja
.findTarget("install-{}".format(testName
)).addInput(installPath
)
435 # returns a tuple of:
436 # 1. Idx after end of directive
437 # 2. Set of platforms directive is restricted to
438 # 3. Bool indicatin if the directive has a platform specifier
439 def parseDirective(line
, directive
, platform
, archs
):
440 idx
= string
.find(line
, directive
)
441 if idx
== -1: return -1, archs
, False
442 if line
[idx
+ len(directive
)] == ':': return idx
+len(directive
)+1, archs
, False
443 match
= re
.match("\((.*?)\)?(?:\|(.*?))?\:", line
[idx
+ len(directive
):]);
445 foundPlatform
= False
450 platforms
= match
.group(1).split(",");
451 if match
.group(2): restrictedArchs
= match
.group(2).split(",");
452 if platforms
and platform
not in platforms
: return -1, archs
, foundPlatform
453 effectiveArchs
= list(set(archs
) & set(restrictedArchs
))
454 if effectiveArchs
: return idx
+ len(directive
) + len(match
.group()), effectiveArchs
, foundPlatform
455 return line
.find(':')+1, archs
, foundPlatform
456 return -1, archs
, False
458 if __name__
== "__main__":
459 configPath
= sys
.argv
[1]
461 with open(configPath
) as configFile
:
462 for line
in configFile
.read().splitlines():
464 configMap
[args
[0]] = args
[2:]
465 sys
.stderr
.write("CONFIG: {}\n".format(configMap
))
466 srcRoot
= configMap
["SRCROOT"][0]
467 symRoot
= configMap
["SYMROOT"][0]
468 sdkRoot
= configMap
["SDKROOT"][0]
469 objRoot
= configMap
["OBJROOT"][0]
470 osFlag
= configMap
["OSFLAG"][0]
471 osVers
= configMap
["OSVERSION"][0]
472 linkerFlags
= configMap
["LDFLAGS"][0];
473 installOwner
= configMap
["INSTALL_OWNER"][0];
474 installGroup
= configMap
["INSTALL_GROUP"][0];
475 installMode
= configMap
["INSTALL_MODE_FLAG"][0];
476 installDir
= configMap
["INSTALL_DIR"][0];
477 userHeaderSearchPaths
= configMap
["USER_HEADER_SEARCH_PATHS"]
478 systemHeaderSearchPaths
= configMap
["SYSTEM_HEADER_SEARCH_PATHS"]
480 derivedFilesDir
= configMap
["DERIVED_FILES_DIR"][0]
481 archs
= configMap
["ARCHS"]
483 if not os
.path
.exists(derivedFilesDir
): os
.makedirs(derivedFilesDir
)
484 if not os
.path
.exists(objRoot
): os
.makedirs(objRoot
)
486 sys
.stderr
.write("srcRoot = {}\n".format(srcRoot
))
487 sys
.stderr
.write("sdkRoot = {}\n".format(sdkRoot
))
488 sys
.stderr
.write("objRoot = {}\n".format(objRoot
))
489 sys
.stderr
.write("osFlag = {}\n".format(osFlag
))
490 sys
.stderr
.write("osVers = {}\n".format(osVers
))
491 sys
.stderr
.write("archs = {}\n".format(archs
))
492 sys
.stderr
.write("derivedFilesDir = {}\n".format(derivedFilesDir
))
494 testSrcRoot
= os
.path
.abspath(srcRoot
+ "/testing/test-cases")
495 ccTool
= os
.popen("xcrun --sdk " + sdkRoot
+ " --find clang").read().rstrip()
496 cxxTool
= os
.popen("xcrun --sdk " + sdkRoot
+ " --find clang++").read().rstrip()
497 headerPaths
= " -isysroot " + sdkRoot
498 for headerPath
in userHeaderSearchPaths
: headerPaths
+= " -I{}".format(headerPath
)
499 for headerPath
in systemHeaderSearchPaths
: headerPaths
+= " -I{}".format(headerPath
)
502 if osFlag
== "mmacosx-version-min":
505 elif osFlag
== "miphoneos-version-min": platform
= "ios"
506 elif osFlag
== "mtvos-version-min": platform
= "tvos"
507 elif osFlag
== "mwatchos-version-min": platform
= "watchos"
508 elif osFlag
== "mbridgeos-version-min": platform
= "bridgeos"
510 sys
.stderr
.write("Unknown platform\n")
513 with NinjaFile(derivedFilesDir
+ "/build.ninja") as ninja
:
514 extraCmds
= "$extraCmds"
515 if "RC_XBS" in os
.environ
and os
.environ
["RC_XBS"] == "YES":
516 extraCmds
= "&& dsymutil -o $out.dSYM $out $extraCmds"
517 ninja
.addInclude("config.ninja")
518 ninja
.addVariable("minOS", "-" + osFlag
+ "=" + osVers
)
519 ninja
.addVariable("archs", " ".join(["-arch {}".format(arch
) for arch
in archs
]))
520 ninja
.addVariable("mode", "0755")
521 ninja
.addVariable("headerpaths", headerPaths
)
523 ninja
.addRule("cc", "{} -g -MMD -MF $out.d $archs -o $out -c $in $minOS $headerpaths $cflags".format(ccTool
), "$out.d")
524 ninja
.addRule("cxx", "{} -g -MMD -MF $out.d $archs -o $out -c $in $minOS $headerpaths $cflags".format(cxxTool
), "$out.d")
525 ninja
.addRule("cc-link", "{} -g $archs -o $out -ltest_support $in $minOS -isysroot {} {} $ldflags {} && codesign --force --sign - $entitlements $out".format(ccTool
, sdkRoot
, linkerFlags
, extraCmds
), False)
526 ninja
.addRule("cxx-link", "{} -g $archs -o $out -ltest_support $in $minOS -isysroot {} {} $ldflags {} && codesign --force --sign - $entitlements $out".format(cxxTool
, sdkRoot
, linkerFlags
, extraCmds
), False)
527 ninja
.addRule("app-cache-util", "$BUILT_PRODUCTS_DIR/host_tools/dyld_app_cache_util $archs $create_kind $out $flags", False)
528 ninja
.addRule("dtrace", "/usr/sbin/dtrace -h -s $in -o $out", False)
529 ninja
.addRule("cp", "/bin/cp -p $in $out", False)
530 ninja
.addRule("install", "/usr/bin/install -m $mode -o {} -g {} $install_flags $in $out".format(installOwner
, installGroup
), False)
531 ninja
.addRule("symlink", "ln -sfh $source $out", False)
533 allTarget
= ninja
.newTarget("phony", "all")
534 masterInstallTarget
= ninja
.newTarget("phony", "install")
536 runAllScriptPath
= "{}/run_all_dyld_tests.sh".format(derivedFilesDir
)
537 xctestPath
= "{}/dyld_xctest.h".format(derivedFilesDir
)
538 if "XCTestGenPath" in os
.environ
: xctestPath
= os
.environ
["XCTestGenPath"]
540 batsSuppressedCrashes
= []
541 xctestInvocations
= []
542 with BufferedFile(runAllScriptPath
) as runAllScript
:
543 missingPlatformDirectives
= False
544 runAllScript
.write("#!/bin/sh\n")
545 for entry
in os
.listdir(testSrcRoot
):
546 if entry
.endswith((".dtest")):
547 testName
= entry
[:-6]
548 sys
.stdout
.write("Processing " + testName
+ "\n")
553 testSrcDir
= "$SRCROOT/testing/test-cases/{}.dtest".format(testName
)
554 testDstDir
= "$SYMROOT/{}".format(testName
)
555 testRunDir
= "/AppleInternal/CoreOS/tests/dyld/{}".format(testName
)
558 batsTest
["TestName"] = testName
559 batsTest
["Arch"] = "platform-native"
560 batsTest
["WorkingDirectory"] = testRunDir
561 batsTest
["ShowSubtestResults"] = True
562 batsTest
["Command"] = []
563 batsTest
["Command"].append("./run.sh")
564 for file in os
.listdir(testSrcRoot
+ "/" + entry
):
566 "BUILD_DIR": testDstDir
,
567 "RUN_DIR": testRunDir
,
568 "SRC_DIR": testSrcDir
571 "RUN_DIR": testRunDir
,
573 "RUN_STATIC": "/AppleInternal/CoreOS/tests/dyld/run-static",
575 if file.endswith((".c", ".cpp", ".cxx", ".m", ".mm")):
576 with open(testSrcRoot
+ "/" + entry
+ "/" + file) as f
:
577 requiresPlatformDirective
= False
578 foundPlatformDirective
= False
579 for line
in f
.read().splitlines():
580 idx
, forceArchs
, foundPlatform
= parseDirective(line
, "BUILD", platform
, archs
);
581 if foundPlatform
: requiresPlatformDirective
= True
583 foundPlatformDirective
= True
584 if line
[idx
:]: buildLines
.append(string
.Template(line
[idx
:]).safe_substitute(buildSubs
))
586 idx
, _
, _
= parseDirective(line
, "RUN", platform
, archs
);
588 if "$SUDO" in line
: batsTest
["AsRoot"] = True
589 runLines
.append(string
.Template(line
[idx
:]).safe_substitute(runSubs
).lstrip())
591 idx
, _
, _
= parseDirective(line
,"RUN_STATIC", platform
, archs
)
593 runStaticLines
.append(string
.Template(line
[idx
:]).safe_substitute(runSubs
).lstrip())
595 idx
, _
, _
= parseDirective(line
,"RUN_TIMEOUT", platform
, archs
)
597 batsTest
["Timeout"] = line
[idx
:].lstrip()
599 idx
, _
, _
= parseDirective(line
,"BOOT_ARGS", platform
, archs
)
601 batsTest
["BootArgsSet"] = ",".join(line
[idx
:].split())
603 idx
, _
, _
= parseDirective(line
,"NO_CRASH_LOG", platform
, archs
)
605 batsSuppressedCrashes
.append(line
[idx
:].lstrip())
607 if requiresPlatformDirective
and not foundPlatformDirective
:
608 missingPlatformDirectives
= True
609 sys
.stderr
.write("Did not find platform({}) BUILD directive for {}\n".format(platform
, testName
))
610 if buildLines
and (runLines
or runStaticLines
):
611 processBuildLines(ninja
, buildLines
, testName
, platform
, osFlag
, forceArchs
, testDstDir
, testSrcDir
)
613 processRunLines(ninja
, runLines
, testName
, platform
, False, symRoot
, xctestInvocations
)
615 processRunLines(ninja
, runStaticLines
, testName
, platform
, True, symRoot
, xctestInvocations
)
616 runAllScript
.write("/AppleInternal/CoreOS/tests/dyld/{}/run.sh\n".format(testName
))
617 batsTests
.append(batsTest
)
618 if missingPlatformDirectives
: sys
.exit(-1)
619 sys
.stderr
.write("Wrote test config to: {}\n".format(xctestPath
))
620 with BufferedFile(xctestPath
) as xcTestFile
:
621 xcTestFile
.write("static const TestInfo sTests[] = {\n")
622 xcTestFile
.write(",\n".join(xctestInvocations
))
623 xcTestFile
.write("\n};")
624 os
.chmod(runAllScriptPath
, 0755)
625 runAllFilesInstallTarget
= ninja
.newTarget("install", "$INSTALL_DIR/AppleInternal/CoreOS/tests/dyld/run_all_dyld_tests.sh")
626 runAllFilesInstallTarget
.addInput("$DERIVED_FILES_DIR/run_all_dyld_tests.sh")
627 masterInstallTarget
.addInput(runAllFilesInstallTarget
)
628 batsFilePath
= derivedFilesDir
+ "/dyld.plist"
629 batsTests
.sort(key
=lambda test
: test
["TestName"])
630 with BufferedFile(batsFilePath
) as batsFile
:
631 batsConfig
= { "BATSConfigVersion": "0.1.0",
632 "Project": "dyld_tests",
634 if batsSuppressedCrashes
: batsConfig
["IgnoreCrashes"] = batsSuppressedCrashes
635 batsFile
.write(plistlib
.writePlistToString(batsConfig
))
636 os
.system('plutil -convert binary1 ' + batsFilePath
) # convert the plist in place to binary
637 batsConfigInstallTarget
= ninja
.newTarget("install", "$INSTALL_DIR/AppleInternal/CoreOS/BATS/unit_tests/dyld.plist")
638 batsConfigInstallTarget
.addInput(batsFilePath
)
639 batsConfigInstallTarget
.addVariable("mode", "0644")
640 masterInstallTarget
.addInput(batsConfigInstallTarget
)
641 sys
.stdout
.write("DONE\n")