Skip to content

Commit 2ab127e

Browse files
committed
[build_script.py] Add "install" subcommand
This builds upon the subcommand system added in swiftlang#57, to add an install command. As that pull request describes, because there is no way to test or install XCTest without also building the project, the current Swift build script ends up building XCTest three times. This adds an "install" subcommand that allows an already built XCTest to be installed.
1 parent 1f719f3 commit 2ab127e

File tree

1 file changed

+68
-27
lines changed

1 file changed

+68
-27
lines changed

build_script.py

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,22 @@ def run(command):
2525
subprocess.check_call(command, shell=True)
2626

2727

28+
def _mkdirp(path):
29+
"""
30+
Creates a directory at the given path if it doesn't already exist.
31+
"""
32+
if not os.path.exists(path):
33+
run("mkdir -p {}".format(path))
34+
35+
2836
def _build(args):
2937
"""
3038
Build XCTest and place the built products in the given 'build_dir'.
3139
If 'test' is specified, also executes the 'test' subcommand.
3240
"""
3341
swiftc = os.path.abspath(args.swiftc)
3442
build_dir = os.path.abspath(args.build_dir)
35-
36-
if not os.path.exists(build_dir):
37-
run("mkdir -p {}".format(build_dir))
43+
_mkdirp(build_dir)
3844

3945
sourceFiles = [
4046
"XCTAssert.swift",
@@ -59,32 +65,18 @@ def _build(args):
5965
"-module-link-name XCTest".format(swiftc, style_options, " ".join(sourcePaths), build_dir))
6066
run("{0} -emit-library {1}/XCTest.o -o {1}/libXCTest.so -lswiftGlibc -lswiftCore -lm".format(swiftc, build_dir))
6167

62-
# If we were given an install directive, perform installation
63-
if args.module_path is not None and args.lib_path is not None:
64-
module_path = os.path.abspath(args.module_path)
65-
lib_path = os.path.abspath(args.lib_path)
66-
run("mkdir -p {}".format(module_path))
67-
run("mkdir -p {}".format(lib_path))
68-
69-
note("Performing installation into {} and {}".format(module_path, lib_path))
70-
71-
install_lib = "libXCTest.so"
72-
install_mod_doc = "XCTest.swiftdoc"
73-
install_mod = "XCTest.swiftmodule"
74-
75-
# These paths should have been created for us, unless we need to create new substructure.
76-
cmd = ['cp', os.path.join(build_dir, install_lib), os.path.join(lib_path, install_lib)]
77-
subprocess.check_call(cmd)
78-
79-
cmd = ['cp', os.path.join(build_dir, install_mod), os.path.join(module_path, install_mod)]
80-
subprocess.check_call(cmd)
81-
cmd = ['cp', os.path.join(build_dir, install_mod_doc), os.path.join(module_path, install_mod_doc)]
82-
subprocess.check_call(cmd)
83-
8468
if args.test:
8569
# Execute main() using the arguments necessary to run the tests.
8670
main(args=["test", "--swiftc", swiftc, build_dir])
8771

72+
# If --module-install-path and --library-install-path were specified,
73+
# we also install the built XCTest products.
74+
if args.module_path is not None and args.lib_path is not None:
75+
# Execute main() using the arguments necessary for installation.
76+
main(args=["install", build_dir,
77+
"--module-install-path", args.module_path,
78+
"--library-install-path", args.lib_path])
79+
8880
note('Done.')
8981

9082

@@ -110,6 +102,34 @@ def _test(args):
110102
tests_path=tests_path))
111103

112104

105+
def _install(args):
106+
"""
107+
Install the XCTest.so, XCTest.swiftmodule, and XCTest.swiftdoc build
108+
products into the given module and library paths.
109+
"""
110+
build_dir = os.path.abspath(args.build_dir)
111+
module_install_path = os.path.abspath(args.module_install_path)
112+
library_install_path = os.path.abspath(args.library_install_path)
113+
114+
_mkdirp(module_install_path)
115+
_mkdirp(library_install_path)
116+
117+
xctest_so = "libXCTest.so"
118+
run("cp {} {}".format(
119+
os.path.join(build_dir, xctest_so),
120+
os.path.join(library_install_path, xctest_so)))
121+
122+
xctest_swiftmodule = "XCTest.swiftmodule"
123+
run("cp {} {}".format(
124+
os.path.join(build_dir, xctest_swiftmodule),
125+
os.path.join(module_install_path, xctest_swiftmodule)))
126+
127+
xctest_swiftdoc = "XCTest.swiftdoc"
128+
run("cp {} {}".format(
129+
os.path.join(build_dir, xctest_swiftdoc),
130+
os.path.join(module_install_path, xctest_swiftdoc)))
131+
132+
113133
def main(args=sys.argv[1:]):
114134
"""
115135
The main entry point for this script. Based on the subcommand given,
@@ -196,11 +216,32 @@ def main(args=sys.argv[1:]):
196216
help="Path to the 'swiftc' compiler used to build and run the tests.",
197217
required=True)
198218

219+
install_parser = subparsers.add_parser(
220+
"install",
221+
description="Installs a built XCTest framework.")
222+
install_parser.set_defaults(func=_install)
223+
install_parser.add_argument(
224+
"build_dir",
225+
help="An absolute path to a directory containing a built XCTest.so, "
226+
"XCTest.swiftmodule, and XCTest.swiftdoc.",
227+
metavar="PATH")
228+
install_parser.add_argument(
229+
"-m", "--module-install-path",
230+
help="Location at which to install XCTest.swiftmodule and "
231+
"XCTest.swiftdoc. This directory will be created if it doesn't "
232+
"already exist.",
233+
metavar="PATH")
234+
install_parser.add_argument(
235+
"-l", "--library-install-path",
236+
help="Location at which to install XCTest.so. This directory will be "
237+
"created if it doesn't already exist.",
238+
metavar="PATH")
239+
199240
# Many versions of Python require a subcommand must be specified.
200241
# We handle this here: if no known subcommand (or none of the help options)
201242
# is included in the arguments, then insert the default subcommand
202-
# argument.
203-
if any([a in ["build", "test", "-h", "--help"] for a in args]):
243+
# argument: 'build'.
244+
if any([a in ["build", "test", "install", "-h", "--help"] for a in args]):
204245
parsed_args = parser.parse_args(args=args)
205246
else:
206247
parsed_args = parser.parse_args(args=["build"] + args)

0 commit comments

Comments
 (0)