Skip to content

Commit 1fe7638

Browse files
committed
Merge pull request #187 from mxcl/parse_deps_in_bootstrap
[bootstrap] Extract dependency graph from manifest
2 parents bac34ec + 9bd0ed6 commit 1fe7638

File tree

2 files changed

+53
-19
lines changed

2 files changed

+53
-19
lines changed

Package.swift

+11-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ import PackageDescription
1212

1313
let package = Package(
1414
name: "SwiftPM",
15+
16+
/**
17+
The following is parsed by our bootstrap script, so
18+
if you make changes here please check the boostrap still
19+
succeeds! Thanks.
20+
*/
1521
targets: [
1622
Target(
1723
/** “Swifty” POSIX functions from libc */
@@ -24,8 +30,8 @@ let package = Package(
2430
Target(
2531
/** Base types for the package-engine */
2632
name: "PackageType",
27-
dependencies: ["PackageDescription", "Utility"]), //FIXME dependency on PackageDescription sucks
28-
Target( //FIXME Utility is too general, we only need `Path`
33+
dependencies: ["PackageDescription", "Utility"]),
34+
Target(
2935
name: "ManifestParser",
3036
dependencies: ["PackageDescription", "PackageType"]),
3137
Target(
@@ -45,12 +51,15 @@ let package = Package(
4551
name: "Multitool",
4652
dependencies: ["PackageType"]),
4753
Target(
54+
/** Generates Xcode projects */
4855
name: "Xcodeproj",
4956
dependencies: ["PackageType"]),
5057
Target(
58+
/** The main executable provided by SwiftPM */
5159
name: "swift-build",
5260
dependencies: ["ManifestParser", "Get", "Transmute", "Build", "Multitool", "Xcodeproj"]),
5361
Target(
62+
/** Runs package tests */
5463
name: "swift-test",
5564
dependencies: ["Multitool"]),
5665
])

Utilities/bootstrap

+42-17
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@ import argparse
3333
import errno
3434
import json
3535
import os
36+
import pipes
3637
import platform
38+
import re
3739
import shlex
40+
import shutil
3841
import subprocess
3942
import sys
4043
import tempfile
41-
import pipes
42-
import shutil
4344

4445
###
4546

@@ -179,24 +180,48 @@ class Target(object):
179180
str(bool(self.is_library)).lower()), file=output)
180181
print(file=output)
181182

183+
# currently only returns the targets parsed from the manifest
184+
def parse_manifest():
185+
# we have a *very* strict format for our manifest to make parsing more robust
186+
pattern = re.compile(r'Target\(.*?name: "(.*?)",\n *dependencies: (\[.*?\])\)', re.DOTALL|re.MULTILINE)
187+
manifest_data = open(os.path.join(g_project_root, "Package.swift")).read()
188+
189+
def convert(match):
190+
name = match.group(1)
191+
deps = eval(match.group(2))
192+
return Target(name, deps)
193+
targets = map(convert, pattern.finditer(manifest_data))
194+
195+
# substitute strings for Target objects
196+
for target in targets:
197+
def convert(targetName):
198+
try:
199+
return next(a for a in targets if a.name == targetName)
200+
except StopIteration:
201+
# this target is not explicit in the manifest: it is an implicit target
202+
b = Target(targetName)
203+
targets.append(b)
204+
return b
205+
target.dependencies = map(convert, target.dependencies)
206+
207+
# fill dependency graph and set dependencies back to strings
208+
def convert(target):
209+
myset = set()
210+
def recurse(root):
211+
deps = []
212+
for dep in root.dependencies:
213+
if dep.name not in myset:
214+
myset.add(dep.name)
215+
deps += recurse(dep) + [dep.name]
216+
return deps
217+
# `reversed` because Linux link order must be reverse-topological
218+
return Target(target.name, reversed(recurse(target)))
219+
return map(convert, targets)
220+
182221
# Hard-coded target definition.
183222
g_project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
184223
g_source_root = os.path.join(g_project_root, "Sources")
185-
targets = [
186-
Target('libc'),
187-
Target('POSIX', dependencies=["libc"]),
188-
Target('Utility', dependencies=["POSIX", "libc"]),
189-
Target('PackageDescription'),
190-
Target('Xcodeproj', dependencies=["PackageType", "Utility", "POSIX", "libc"]),
191-
Target('Multitool', dependencies=["PackageType", "Utility", "POSIX", "libc"]),
192-
Target('PackageType', dependencies=["PackageDescription", "Utility", "POSIX", "libc"]),
193-
Target('Transmute', dependencies=["PackageType", "PackageDescription", "Utility", "POSIX", "libc"]),
194-
Target('ManifestParser', dependencies=["PackageType", "Utility", "PackageDescription", "POSIX", "libc"]),
195-
Target('Get', dependencies=["ManifestParser", "PackageDescription", "PackageType", "Utility", "POSIX", "libc"]),
196-
Target('Build', dependencies=["PackageType", "Utility", "PackageDescription", "POSIX", "libc"]),
197-
Target('swift-build', dependencies=["Xcodeproj", "Transmute", "Multitool", "Build", "Get", "ManifestParser", "PackageDescription", "PackageType", "Utility", "POSIX", "libc"]),
198-
Target('swift-test', dependencies=["Multitool", "PackageType", "PackageDescription", "Utility", "POSIX", "libc"]),
199-
]
224+
targets = parse_manifest()
200225
target_map = dict((t.name, t) for t in targets)
201226

202227
def create_bootstrap_files(sandbox_path, args):

0 commit comments

Comments
 (0)