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 if platform
!= "macos":
221 target
= ninja
.findTarget(args
[1])
222 target
.addVariable("entitlements", "--entitlements $SRCROOT/testing/task_for_pid_entitlement.plist")
223 elif args
[0] in ["$CC", "$CXX"]:
224 tool
= args
[0][1:].lower()
231 linkTestSupport
= True
232 platformVersion
= None
233 targetNames
= [target
.output
for target
in ninja
.targets
]
234 args
= [escapedArg
.replace("\"", "\\\"") for escapedArg
in args
[1:]]
235 #First find the target
236 for idx
, arg
in enumerate(args
):
238 linkTarget
= ninja
.newTarget("{}-link".format(tool
), args
[idx
+1])
239 linkTarget
.addDependency("$BUILT_PRODUCTS_DIR/libtest_support.a")
240 testTarget
.addInput(linkTarget
);
243 for idx
, arg
in enumerate(args
):
244 if skipCount
: skipCount
-= 1
247 elif arg
== "$DEPENDS_ON":
249 dependencies
.append(args
[idx
+1])
250 elif arg
in ["-arch"]:
252 nextArg
= args
[idx
+1]
254 ldflags
.append(nextArg
)
256 cflags
.append(nextArg
)
257 elif arg
in ["-target"]:
259 nextArg
= args
[idx
+1]
261 ldflags
.append(nextArg
)
263 cflags
.append(nextArg
)
264 elif arg
in ["-install_name","-framework", "-rpath","-compatibility_version","-sub_library", "-undefined", "-current_version"]:
266 nextArg
= args
[idx
+1]
268 ldflags
.append(nextArg
)
269 elif arg
== "-sectcreate":
272 ldflags
.append(args
[idx
+1])
273 ldflags
.append(args
[idx
+2])
274 ldflags
.append(args
[idx
+3])
275 elif arg
[:2] == "-L": ldflags
.append(arg
)
276 elif arg
[:2] == "-F": ldflags
.append(arg
)
277 elif arg
== "-nostdlib":
279 # Kernel tests pass -nostdlib so don't link test support
280 linkTestSupport
= False
281 elif arg
== "-flat_namespace":
283 elif arg
in ["-dynamiclib","-bundle"]:
285 linkTestSupport
= False
286 elif arg
.endswith((".s", ".c", ".cpp", ".cxx", ".m", ".mm")):
287 if not arg
.startswith("$SRCROOT"): sources
.append(testSrcDir
+ "/" + arg
)
288 else: sources
.append(arg
)
289 elif arg
in targetNames
:
290 linkTarget
.addInput(arg
)
292 minOS
= arg
[arg
.find('=')+1:]
293 elif arg
[:4] == "-Wl,":
294 linkerArgs
= arg
.split(",")
295 if linkerArgs
[1] == "-platform_version":
296 minOS
= linkerArgs
[3]
297 platformVersion
= arg
299 for linkerArg
in linkerArgs
[1:]:
300 if linkerArg
in targetNames
: linkTarget
.addDependency(linkerArg
)
302 elif arg
[:2] == "-l":
303 candidate
= "{}/lib{}.dylib".format(testDstDir
, arg
[2:])
304 if candidate
in targetNames
: linkTarget
.addDependency(candidate
)
306 elif arg
[:7] == "-weak-l":
307 candidate
= "{}/lib{}.dylib".format(testDstDir
, arg
[7:])
308 if candidate
in targetNames
: linkTarget
.addDependency(candidate
)
310 elif arg
[:9] == "-upward-l":
311 candidate
= "{}/lib{}.dylib".format(testDstDir
, arg
[9:])
312 if candidate
in targetNames
: linkTarget
.addDependency(candidate
)
314 elif arg
[:8] == "-fuse-ld":
315 # This is not typically used, but if we ever wanted to try a new ld64, it can be useful
320 ldflags
.append("-force_load $BUILT_PRODUCTS_DIR/libtest_support.a")
321 for source
in sources
:
322 objectHash
= hashlib
.sha1(linkTarget
.output
+source
+tool
+"".join(cflags
)).hexdigest()
323 target
= ninja
.newTarget(tool
, "$OBJROOT/dyld_tests.build/Objects-normal/" + objectHash
+ ".o")
324 target
.addInput(source
)
325 target
.dependencies
= dependencies
326 if cflags
: target
.addVariable("cflags", " ".join(cflags
))
327 if minOS
: target
.addVariable("minOS", "-" + osFlag
+ "=" + minOS
)
328 if forceArchs
: target
.addVariable("archs", " ".join(["-arch {}".format(arch
) for arch
in forceArchs
]))
329 linkTarget
.addInput(target
)
330 if ldflags
: linkTarget
.addVariable("ldflags", " ".join(ldflags
))
331 if platformVersion
: linkTarget
.addVariable("minOS", platformVersion
)
332 elif minOS
: linkTarget
.addVariable("minOS", "-" + osFlag
+ "=" + minOS
)
333 if forceArchs
: linkTarget
.addVariable("archs", " ".join(["-arch {}".format(arch
) for arch
in forceArchs
]))
334 installTarget
= ninja
.newTarget("install", "$INSTALL_DIR/AppleInternal/CoreOS/tests/dyld/{}".format(linkTarget
.output
[9:]))
335 installTarget
.addInput(linkTarget
)
336 testTarget
.addInput(linkTarget
)
337 testInstallTarget
.addInput(installTarget
)
338 elif args
[0] == "$APP_CACHE_UTIL":
339 tool
= args
[0][1:].lower()
345 args
= [escapedArg
.replace("\"", "\\\"") for escapedArg
in args
[1:]]
347 for idx
, arg
in enumerate(args
):
348 if skipCount
: skipCount
-= 1
349 elif arg
== "$DEPENDS_ON":
351 dependencies
.append(args
[idx
+1])
352 elif arg
== "-create-kernel-collection":
354 linkTarget
= ninja
.newTarget("app-cache-util", args
[idx
+1])
355 linkTarget
.addVariable("create_kind", arg
)
356 testTarget
.addInput(linkTarget
)
357 dependencies
.append("$BUILT_PRODUCTS_DIR/host_tools/dyld_app_cache_util")
358 elif arg
== "-kernel":
360 linkTarget
.addInput(args
[idx
+1])
362 flags
.append(args
[idx
+1])
363 elif arg
== "-create-aux-kernel-collection":
365 linkTarget
= ninja
.newTarget("app-cache-util", args
[idx
+1])
366 linkTarget
.addVariable("create_kind", arg
)
367 testTarget
.addInput(linkTarget
)
368 dependencies
.append("$BUILT_PRODUCTS_DIR/host_tools/dyld_app_cache_util")
369 elif arg
== "-create-pageable-kernel-collection":
371 linkTarget
= ninja
.newTarget("app-cache-util", args
[idx
+1])
372 linkTarget
.addVariable("create_kind", arg
)
373 testTarget
.addInput(linkTarget
)
374 dependencies
.append("$BUILT_PRODUCTS_DIR/host_tools/dyld_app_cache_util")
375 elif arg
== "-kernel-collection":
377 linkTarget
.addInput(args
[idx
+1])
379 flags
.append(args
[idx
+1])
380 elif arg
== "-pageable-collection":
382 linkTarget
.addInput(args
[idx
+1])
384 flags
.append(args
[idx
+1])
387 linkTarget
.dependencies
= dependencies
388 if flags
: linkTarget
.addVariable("flags", " ".join(flags
))
389 if forceArchs
: linkTarget
.addVariable("archs", " ".join(["-arch {}".format(arch
) for arch
in forceArchs
]))
390 installTarget
= ninja
.newTarget("install", "$INSTALL_DIR/AppleInternal/CoreOS/tests/dyld/{}".format(linkTarget
.output
[9:]))
391 installTarget
.addInput(linkTarget
)
392 testTarget
.addInput(linkTarget
)
393 testInstallTarget
.addInput(installTarget
)
394 else: raise ValueError("Unknown Command: {}".format(args
[0]))
397 def processRunLine(runFile
, runLine
, environment
):
398 if runLine
.startswith("sudo "):
399 runFile
.write("sudo {} {}\n".format(environment
, runLine
[5:]))
401 runFile
.write("{} {}\n".format(environment
, runLine
))
403 def processRunLines(ninja
, runLines
, testName
, platform
, runStatic
, symRoot
, xcTestInvocations
):
404 runFilePath
= "{}/{}/run.sh".format(symRoot
, testName
)
405 for runLine
in runLines
:
406 xcTestInvocations
.append("{{ \"{}\", \"{}\" }}".format(testName
, runLine
.replace("\"","\\\"").replace("sudo","")))
407 with BufferedFile(runFilePath
) as runFile
:
408 runFile
.write("#!/bin/sh\n")
409 runFile
.write("cd {}\n".format(testRunDir
))
412 runFile
.write("echo \"run static\" \n");
413 for runLine
in runLines
:
414 processRunLine(runFile
, runLine
, "TEST_OUTPUT=BATS")
416 runFile
.write("echo \"run in dyld2 mode\" \n");
417 for runLine
in runLines
:
418 processRunLine(runFile
, runLine
, "TEST_OUTPUT=BATS DYLD_USE_CLOSURES=0")
420 runFile
.write("echo \"run in dyld3 mode\" \n");
421 for runLine
in runLines
:
422 processRunLine(runFile
, runLine
, "TEST_OUTPUT=BATS DYLD_USE_CLOSURES=1")
424 runFile
.write("echo \"run in dyld3s mode\" \n");
425 for runLine
in runLines
:
426 if runLine
.startswith("sudo "):
427 runFile
.write("sudo TEST_OUTPUT=BATS DYLD_USE_CLOSURES=2 {}\n".format(runLine
[5:]))
429 runFile
.write("TEST_OUTPUT=BATS DYLD_USE_CLOSURES=2 {}\n".format(runLine
))
430 os
.chmod(runFilePath
, 0755)
431 installPath
= "$INSTALL_DIR/AppleInternal/CoreOS/tests/dyld/{}/run.sh".format(testName
)
432 target
= ninja
.newTarget("install", installPath
)
433 target
.addInput(runFilePath
)
434 ninja
.findTarget("install-{}".format(testName
)).addInput(installPath
)
436 # returns a tuple of:
437 # 1. Idx after end of directive
438 # 2. Set of platforms directive is restricted to
439 # 3. Bool indicatin if the directive has a platform specifier
440 def parseDirective(line
, directive
, platform
, archs
):
441 idx
= string
.find(line
, directive
)
442 if idx
== -1: return -1, archs
, False
443 if line
[idx
+ len(directive
)] == ':': return idx
+len(directive
)+1, archs
, False
444 match
= re
.match("\((.*?)\)?(?:\|(.*?))?\:", line
[idx
+ len(directive
):]);
446 foundPlatform
= False
451 platforms
= match
.group(1).split(",");
452 if match
.group(2): restrictedArchs
= match
.group(2).split(",");
453 if platforms
and platform
not in platforms
: return -1, archs
, foundPlatform
454 effectiveArchs
= list(set(archs
) & set(restrictedArchs
))
455 if effectiveArchs
: return idx
+ len(directive
) + len(match
.group()), effectiveArchs
, foundPlatform
456 return len(line
), archs
, foundPlatform
457 return -1, archs
, False
459 if __name__
== "__main__":
460 configPath
= sys
.argv
[1]
462 with open(configPath
) as configFile
:
463 for line
in configFile
.read().splitlines():
465 configMap
[args
[0]] = args
[2:]
466 sys
.stderr
.write("CONFIG: {}\n".format(configMap
))
467 srcRoot
= configMap
["SRCROOT"][0]
468 symRoot
= configMap
["SYMROOT"][0]
469 sdkRoot
= configMap
["SDKROOT"][0]
470 objRoot
= configMap
["OBJROOT"][0]
471 osFlag
= configMap
["OSFLAG"][0]
472 osVers
= configMap
["OSVERSION"][0]
473 linkerFlags
= configMap
["LDFLAGS"][0];
474 installOwner
= configMap
["INSTALL_OWNER"][0];
475 installGroup
= configMap
["INSTALL_GROUP"][0];
476 installMode
= configMap
["INSTALL_MODE_FLAG"][0];
477 installDir
= configMap
["INSTALL_DIR"][0];
478 userHeaderSearchPaths
= configMap
["USER_HEADER_SEARCH_PATHS"]
479 systemHeaderSearchPaths
= configMap
["SYSTEM_HEADER_SEARCH_PATHS"]
481 derivedFilesDir
= configMap
["DERIVED_FILES_DIR"][0]
482 archs
= configMap
["ARCHS"]
484 if not os
.path
.exists(derivedFilesDir
): os
.makedirs(derivedFilesDir
)
485 if not os
.path
.exists(objRoot
): os
.makedirs(objRoot
)
487 sys
.stderr
.write("srcRoot = {}\n".format(srcRoot
))
488 sys
.stderr
.write("sdkRoot = {}\n".format(sdkRoot
))
489 sys
.stderr
.write("objRoot = {}\n".format(objRoot
))
490 sys
.stderr
.write("osFlag = {}\n".format(osFlag
))
491 sys
.stderr
.write("osVers = {}\n".format(osVers
))
492 sys
.stderr
.write("archs = {}\n".format(archs
))
493 sys
.stderr
.write("derivedFilesDir = {}\n".format(derivedFilesDir
))
495 testSrcRoot
= os
.path
.abspath(srcRoot
+ "/testing/test-cases")
496 ccTool
= os
.popen("xcrun --sdk " + sdkRoot
+ " --find clang").read().rstrip()
497 cxxTool
= os
.popen("xcrun --sdk " + sdkRoot
+ " --find clang++").read().rstrip()
498 headerPaths
= " -isysroot " + sdkRoot
499 for headerPath
in userHeaderSearchPaths
: headerPaths
+= " -I{}".format(headerPath
)
500 for headerPath
in systemHeaderSearchPaths
: headerPaths
+= " -I{}".format(headerPath
)
503 if osFlag
== "mmacosx-version-min":
506 elif osFlag
== "miphoneos-version-min": platform
= "ios"
507 elif osFlag
== "mtvos-version-min": platform
= "tvos"
508 elif osFlag
== "mwatchos-version-min": platform
= "watchos"
509 elif osFlag
== "mbridgeos-version-min": platform
= "bridgeos"
511 sys
.stderr
.write("Unknown platform\n")
514 with NinjaFile(derivedFilesDir
+ "/build.ninja") as ninja
:
515 extraCmds
= "$extraCmds"
516 if "RC_XBS" in os
.environ
and os
.environ
["RC_XBS"] == "YES":
517 extraCmds
= "&& dsymutil -o $out.dSYM $out $extraCmds"
518 ninja
.addInclude("config.ninja")
519 ninja
.addVariable("minOS", "-" + osFlag
+ "=" + osVers
)
520 ninja
.addVariable("archs", " ".join(["-arch {}".format(arch
) for arch
in archs
]))
521 ninja
.addVariable("mode", "0755")
522 ninja
.addVariable("headerpaths", headerPaths
)
524 ninja
.addRule("cc", "{} -g -MMD -MF $out.d $archs -o $out -c $in $minOS $headerpaths $cflags".format(ccTool
), "$out.d")
525 ninja
.addRule("cxx", "{} -g -MMD -MF $out.d $archs -o $out -c $in $minOS $headerpaths $cflags".format(cxxTool
), "$out.d")
526 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)
527 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)
528 ninja
.addRule("app-cache-util", "$BUILT_PRODUCTS_DIR/host_tools/dyld_app_cache_util $archs $create_kind $out $flags", False)
529 ninja
.addRule("dtrace", "/usr/sbin/dtrace -h -s $in -o $out", False)
530 ninja
.addRule("cp", "/bin/cp -p $in $out", False)
531 ninja
.addRule("install", "/usr/bin/install -m $mode -o {} -g {} $install_flags $in $out".format(installOwner
, installGroup
), False)
532 ninja
.addRule("symlink", "ln -sfh $source $out", False)
534 allTarget
= ninja
.newTarget("phony", "all")
535 masterInstallTarget
= ninja
.newTarget("phony", "install")
537 runAllScriptPath
= "{}/run_all_dyld_tests.sh".format(derivedFilesDir
)
538 xctestPath
= "{}/dyld_xctest.h".format(derivedFilesDir
)
539 if "XCTestGenPath" in os
.environ
: xctestPath
= os
.environ
["XCTestGenPath"]
541 batsSuppressedCrashes
= []
542 xctestInvocations
= []
543 with BufferedFile(runAllScriptPath
) as runAllScript
:
544 missingPlatformDirectives
= False
545 runAllScript
.write("#!/bin/sh\n")
546 for entry
in os
.listdir(testSrcRoot
):
547 if entry
.endswith((".dtest")):
548 testName
= entry
[:-6]
549 sys
.stdout
.write("Processing " + testName
+ "\n")
554 testSrcDir
= "$SRCROOT/testing/test-cases/{}.dtest".format(testName
)
555 testDstDir
= "$SYMROOT/{}".format(testName
)
556 testRunDir
= "/AppleInternal/CoreOS/tests/dyld/{}".format(testName
)
559 batsTest
["TestName"] = testName
560 batsTest
["Arch"] = "platform-native"
561 batsTest
["WorkingDirectory"] = testRunDir
562 batsTest
["ShowSubtestResults"] = True
563 batsTest
["Command"] = []
564 batsTest
["Command"].append("./run.sh")
565 for file in os
.listdir(testSrcRoot
+ "/" + entry
):
567 "BUILD_DIR": testDstDir
,
568 "RUN_DIR": testRunDir
,
569 "SRC_DIR": testSrcDir
572 "RUN_DIR": testRunDir
,
574 "RUN_STATIC": "/AppleInternal/CoreOS/tests/dyld/run-static",
576 if file.endswith((".c", ".cpp", ".cxx", ".m", ".mm")):
577 with open(testSrcRoot
+ "/" + entry
+ "/" + file) as f
:
578 requiresPlatformDirective
= False
579 foundPlatformDirective
= False
580 for line
in f
.read().splitlines():
581 idx
, forceArchs
, foundPlatform
= parseDirective(line
, "BUILD", platform
, archs
);
582 if foundPlatform
: requiresPlatformDirective
= True
584 foundPlatformDirective
= True
585 if line
[idx
:]: buildLines
.append(string
.Template(line
[idx
:]).safe_substitute(buildSubs
))
587 idx
, _
, _
= parseDirective(line
, "RUN", platform
, archs
);
589 if "$SUDO" in line
: batsTest
["AsRoot"] = True
590 runLines
.append(string
.Template(line
[idx
:]).safe_substitute(runSubs
).lstrip())
592 idx
, _
, _
= parseDirective(line
,"RUN_STATIC", platform
, archs
)
594 runStaticLines
.append(string
.Template(line
[idx
:]).safe_substitute(runSubs
).lstrip())
596 idx
, _
, _
= parseDirective(line
,"RUN_TIMEOUT", platform
, archs
)
598 batsTest
["Timeout"] = line
[idx
:].lstrip()
600 idx
, _
, _
= parseDirective(line
,"BOOT_ARGS", platform
, archs
)
602 batsTest
["BootArgsSet"] = ",".join(line
[idx
:].split())
604 idx
, _
, _
= parseDirective(line
,"NO_CRASH_LOG", platform
, archs
)
606 batsSuppressedCrashes
.append(line
[idx
:].lstrip())
608 if requiresPlatformDirective
and not foundPlatformDirective
:
609 missingPlatformDirectives
= True
610 sys
.stderr
.write("Did not find platform({}) BUILD directive for {}\n".format(platform
, testName
))
611 if buildLines
and (runLines
or runStaticLines
):
612 processBuildLines(ninja
, buildLines
, testName
, platform
, osFlag
, forceArchs
, testDstDir
, testSrcDir
)
614 processRunLines(ninja
, runLines
, testName
, platform
, False, symRoot
, xctestInvocations
)
616 processRunLines(ninja
, runStaticLines
, testName
, platform
, True, symRoot
, xctestInvocations
)
617 runAllScript
.write("/AppleInternal/CoreOS/tests/dyld/{}/run.sh\n".format(testName
))
618 batsTests
.append(batsTest
)
619 if missingPlatformDirectives
: sys
.exit(-1)
620 sys
.stderr
.write("Wrote test config to: {}\n".format(xctestPath
))
621 with BufferedFile(xctestPath
) as xcTestFile
:
622 xcTestFile
.write("static const TestInfo sTests[] = {\n")
623 xcTestFile
.write(",\n".join(xctestInvocations
))
624 xcTestFile
.write("\n};")
625 os
.chmod(runAllScriptPath
, 0755)
626 runAllFilesInstallTarget
= ninja
.newTarget("install", "$INSTALL_DIR/AppleInternal/CoreOS/tests/dyld/run_all_dyld_tests.sh")
627 runAllFilesInstallTarget
.addInput("$DERIVED_FILES_DIR/run_all_dyld_tests.sh")
628 masterInstallTarget
.addInput(runAllFilesInstallTarget
)
629 batsFilePath
= derivedFilesDir
+ "/dyld.plist"
630 batsTests
.sort(key
=lambda test
: test
["TestName"])
631 with BufferedFile(batsFilePath
) as batsFile
:
632 batsConfig
= { "BATSConfigVersion": "0.1.0",
633 "Project": "dyld_tests",
635 if batsSuppressedCrashes
: batsConfig
["IgnoreCrashes"] = batsSuppressedCrashes
636 batsFile
.write(plistlib
.writePlistToString(batsConfig
))
637 os
.system('plutil -convert binary1 ' + batsFilePath
) # convert the plist in place to binary
638 batsConfigInstallTarget
= ninja
.newTarget("install", "$INSTALL_DIR/AppleInternal/CoreOS/BATS/unit_tests/dyld.plist")
639 batsConfigInstallTarget
.addInput(batsFilePath
)
640 batsConfigInstallTarget
.addVariable("mode", "0644")
641 masterInstallTarget
.addInput(batsConfigInstallTarget
)
642 sys
.stdout
.write("DONE\n")