Skip to content

Commit 9502b80

Browse files
committed
[build_script.py] Add "install" subcommand
This builds upon the subcommand system added in #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 e072d55 commit 9502b80

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
@@ -26,16 +26,22 @@ def run(command):
2626
subprocess.check_call(command, shell=True)
2727

2828

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

4046
sourcePaths = glob.glob(os.path.join(
4147
SOURCE_DIR, 'Sources', 'XCTest', '*.swift'))
@@ -52,32 +58,18 @@ def _build(args):
5258
"-module-link-name XCTest".format(swiftc, style_options, " ".join(sourcePaths), build_dir))
5359
run("{0} -emit-library {1}/XCTest.o -o {1}/libXCTest.so -lswiftGlibc -lswiftCore -lm".format(swiftc, build_dir))
5460

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

65+
# If --module-install-path and --library-install-path were specified,
66+
# we also install the built XCTest products.
67+
if args.module_path is not None and args.lib_path is not None:
68+
# Execute main() using the arguments necessary for installation.
69+
main(args=["install", build_dir,
70+
"--module-install-path", args.module_path,
71+
"--library-install-path", args.lib_path])
72+
8173
note('Done.')
8274

8375

@@ -103,6 +95,34 @@ def _test(args):
10395
tests_path=tests_path))
10496

10597

98+
def _install(args):
99+
"""
100+
Install the XCTest.so, XCTest.swiftmodule, and XCTest.swiftdoc build
101+
products into the given module and library paths.
102+
"""
103+
build_dir = os.path.abspath(args.build_dir)
104+
module_install_path = os.path.abspath(args.module_install_path)
105+
library_install_path = os.path.abspath(args.library_install_path)
106+
107+
_mkdirp(module_install_path)
108+
_mkdirp(library_install_path)
109+
110+
xctest_so = "libXCTest.so"
111+
run("cp {} {}".format(
112+
os.path.join(build_dir, xctest_so),
113+
os.path.join(library_install_path, xctest_so)))
114+
115+
xctest_swiftmodule = "XCTest.swiftmodule"
116+
run("cp {} {}".format(
117+
os.path.join(build_dir, xctest_swiftmodule),
118+
os.path.join(module_install_path, xctest_swiftmodule)))
119+
120+
xctest_swiftdoc = "XCTest.swiftdoc"
121+
run("cp {} {}".format(
122+
os.path.join(build_dir, xctest_swiftdoc),
123+
os.path.join(module_install_path, xctest_swiftdoc)))
124+
125+
106126
def main(args=sys.argv[1:]):
107127
"""
108128
The main entry point for this script. Based on the subcommand given,
@@ -189,11 +209,32 @@ def main(args=sys.argv[1:]):
189209
help="Path to the 'swiftc' compiler used to build and run the tests.",
190210
required=True)
191211

212+
install_parser = subparsers.add_parser(
213+
"install",
214+
description="Installs a built XCTest framework.")
215+
install_parser.set_defaults(func=_install)
216+
install_parser.add_argument(
217+
"build_dir",
218+
help="An absolute path to a directory containing a built XCTest.so, "
219+
"XCTest.swiftmodule, and XCTest.swiftdoc.",
220+
metavar="PATH")
221+
install_parser.add_argument(
222+
"-m", "--module-install-path",
223+
help="Location at which to install XCTest.swiftmodule and "
224+
"XCTest.swiftdoc. This directory will be created if it doesn't "
225+
"already exist.",
226+
metavar="PATH")
227+
install_parser.add_argument(
228+
"-l", "--library-install-path",
229+
help="Location at which to install XCTest.so. This directory will be "
230+
"created if it doesn't already exist.",
231+
metavar="PATH")
232+
192233
# Many versions of Python require a subcommand must be specified.
193234
# We handle this here: if no known subcommand (or none of the help options)
194235
# is included in the arguments, then insert the default subcommand
195-
# argument.
196-
if any([a in ["build", "test", "-h", "--help"] for a in args]):
236+
# argument: 'build'.
237+
if any([a in ["build", "test", "install", "-h", "--help"] for a in args]):
197238
parsed_args = parser.parse_args(args=args)
198239
else:
199240
parsed_args = parser.parse_args(args=["build"] + args)

0 commit comments

Comments
 (0)