Skip to content

Commit d9cf62b

Browse files
committed
Allow configurations to be reconfigured for pulling in source list changes after initial config pass
After building from a full swift project build a configuration file is emitted to store the settings used for this build pass. When iterating with adding files or changing flags the ninja target `reconfigure` should be run to re-invoke the configure script to pick up on new changes to build.py
1 parent 34a0910 commit d9cf62b

File tree

4 files changed

+156
-34
lines changed

4 files changed

+156
-34
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ project.xcworkspace
1515

1616
Build
1717
.build
18+
.configuration
1819

configure

Lines changed: 101 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,68 @@ from lib.workspace import Workspace
4444

4545
import sys
4646

47+
def reconfigure(config, path):
48+
with open(path, 'r') as infile:
49+
info = json.load(infile)
50+
if 'version' in info and info['version'] == config.version:
51+
if 'command' in info:
52+
config.command = info['command']
53+
if 'project' in info:
54+
config.command = info['project']
55+
if 'script_path' in info:
56+
config.script_path = Path(info['script_path'])
57+
if 'build_script_path' in info:
58+
config.build_script_path = Path(info['build_script_path'])
59+
if 'source_root' in info:
60+
config.source_root = Path(info['source_root'])
61+
if 'target' in info:
62+
config.target = Target(info['target'])
63+
if 'system_root' in info:
64+
config.system_root = Path(info['system_root'])
65+
if 'toolchain' in info:
66+
config.toolchain = info['toolchain']
67+
if 'build_directory' in info:
68+
config.build_directory = Path(info['build_directory'])
69+
if 'intermediate_directory' in info:
70+
config.intermediate_directory = Path(info['intermediate_directory'])
71+
if 'module_cache_directory' in info:
72+
config.module_cache_directory = Path(info['module_cache_directory'])
73+
if 'install_directory' in info:
74+
config.install_directory = Path(info['install_directory'])
75+
if 'prefix' in info:
76+
config.prefix = info['prefix']
77+
if 'swift_install' in info:
78+
config.swift_install = info['swift_install']
79+
if 'clang' in info:
80+
config.clang = info['clang']
81+
if 'clangxx' in info:
82+
config.clangxx = info['clangxx']
83+
if 'swift' in info:
84+
config.swift = info['swift']
85+
if 'swiftc' in info:
86+
config.swiftc = info['swiftc']
87+
if 'ar' in info:
88+
config.ar = info['ar']
89+
if 'swift_sdk' in info:
90+
config.swift_sdk = info['swift_sdk']
91+
if 'bootstrap_directory' in info:
92+
config.bootstrap_directory = Path(info['bootstrap_directory'])
93+
if 'verbose' in info:
94+
config.verbose = info['verbose']
95+
if 'extra_c_flags' in info:
96+
config.extra_c_flags = info['extra_c_flags']
97+
if 'extra_swift_flags' in info:
98+
config.extra_swift_flags = info['extra_swift_flags']
99+
if 'extra_ld_flags' in info:
100+
config.extra_ld_flags = info['extra_ld_flags']
101+
if 'build_mode' in info:
102+
config.build_mode = info['build_mode']
103+
if 'variables' in info:
104+
config.variables = info['variables']
105+
else:
106+
sys.exit("invalid version")
107+
108+
47109
def main():
48110
config = Configuration()
49111
CWD = Path.path(os.getcwd())
@@ -64,49 +126,56 @@ def main():
64126
config.swift_sdk = os.getenv("SDKROOT", None)
65127
config.script_path = config.source_root.path_by_appending("build.py")
66128
config.build_script_path = config.source_root.path_by_appending("build.ninja")
129+
config.config_path = config.source_root.path_by_appending(".configuration")
67130

68131
parser = argparse.ArgumentParser(description='Configure and emit ninja build scripts for building.')
69132
parser.add_argument('--target', dest='target', type=str, default=Target.default())
70133
parser.add_argument('--sysroot', dest='sysroot', type=str, default=None)
71134
parser.add_argument('--toolchain', dest='toolchain', type=str, default=None)
72135
parser.add_argument('--bootstrap', dest='bootstrap', type=str, default=os.path.join(os.path.dirname(os.path.abspath(__file__)), "bootstrap"))
136+
parser.add_argument('--reconfigure', dest='reconfigure', action="store_true")
73137
parser.add_argument('-v', '--verbose', dest='verbose', action="store_true")
74138
args, extras = parser.parse_known_args()
75-
76-
config.build_mode = Configuration.Debug # by default build in debug mode
77-
78-
for arg in extras:
79-
if arg.lower() == 'debug':
80-
config.build_mode = Configuration.Debug
81-
elif arg.lower() == 'release':
82-
config.build_mode = Configuration.Release
83-
elif arg.startswith('-D'): # accept -DNAME=value as extra parameters to the configuration of the build.ninja
84-
key, val = arg[2:].split("=", 1)
85-
config.variables[key] = val
86-
87-
config.command = [os.path.abspath(__file__)] + sys.argv[1:]
88-
89-
config.target = Target(args.target)
90-
91-
config.system_root = Path.path(args.sysroot)
92-
if config.target.sdk == OSType.MacOSX and config.system_root is None and Target(Target.default()).sdk == OSType.MacOSX:
93-
import subprocess
94-
config.system_root = Path.path(subprocess.Popen(['xcrun', '--show-sdk-path'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate()[0])
95-
swift_path = Path.path(subprocess.Popen(['xcrun', '--find', 'swift'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate()[0]).parent().parent()
96-
config.swift_sdk = swift_path.absolute()
97-
elif config.swift_sdk is None:
98-
config.swift_sdk = "/usr"
99-
config.toolchain = Path.path(args.toolchain)
100-
config.bootstrap_directory = Path.path(args.bootstrap)
101-
config.verbose = args.verbose
102-
if config.toolchain is not None:
103-
config.ar = os.path.join(config.toolchain.relative(), "bin", "ar")
104-
elif config.ar is None:
105-
config.ar = "ar"
106-
139+
140+
if args.reconfigure:
141+
reconfigure(config, config.config_path.absolute())
142+
else:
143+
config.build_mode = Configuration.Debug # by default build in debug mode
144+
145+
for arg in extras:
146+
if arg.lower() == 'debug':
147+
config.build_mode = Configuration.Debug
148+
elif arg.lower() == 'release':
149+
config.build_mode = Configuration.Release
150+
elif arg.startswith('-D'): # accept -DNAME=value as extra parameters to the configuration of the build.ninja
151+
key, val = arg[2:].split("=", 1)
152+
config.variables[key] = val
153+
154+
config.command = [os.path.abspath(__file__)] + sys.argv[1:]
155+
156+
config.target = Target(args.target)
157+
158+
config.system_root = Path.path(args.sysroot)
159+
if config.target.sdk == OSType.MacOSX and config.system_root is None and Target(Target.default()).sdk == OSType.MacOSX:
160+
import subprocess
161+
config.system_root = Path.path(subprocess.Popen(['xcrun', '--show-sdk-path'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate()[0])
162+
swift_path = Path.path(subprocess.Popen(['xcrun', '--find', 'swift'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate()[0]).parent().parent()
163+
config.swift_sdk = swift_path.absolute()
164+
elif config.swift_sdk is None:
165+
config.swift_sdk = "/usr"
166+
config.toolchain = Path.path(args.toolchain)
167+
config.bootstrap_directory = Path.path(args.bootstrap)
168+
config.verbose = args.verbose
169+
if config.toolchain is not None:
170+
config.ar = os.path.join(config.toolchain.relative(), "bin", "ar")
171+
elif config.ar is None:
172+
config.ar = "ar"
173+
174+
config.write(config.config_path.absolute())
107175
Configuration.current = config
108176

109177
execfile(config.script_path.absolute())
110178

179+
111180
if __name__ == "__main__":
112181
main()

lib/config.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@
77
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
88
#
99

10+
import json
11+
12+
from path import Path
13+
1014
class Configuration:
1115
Debug = "debug"
1216
Release = "release"
17+
version = 1
1318

1419
command = None
1520
current = None
@@ -30,13 +35,50 @@ class Configuration:
3035
clangxx = None
3136
swift = None
3237
swiftc = None
38+
ar = None
3339
swift_sdk = None
3440
bootstrap_directory = None
3541
verbose = False
3642
extra_c_flags = None
3743
extra_swift_flags = None
3844
extra_ld_flags = None
3945
build_mode = None
46+
config_path = None # dont save this; else it would be recursive
4047
variables = {}
4148
def __init__(self):
42-
pass
49+
pass
50+
51+
def write(self, path):
52+
info = {
53+
'version' : self.version,
54+
'command' : self.command,
55+
'project' : self.project,
56+
'script_path' : self.script_path.absolute(),
57+
'build_script_path' : self.build_script_path.absolute(),
58+
'source_root' : self.source_root.absolute(),
59+
'target' : self.target.triple,
60+
'system_root' : self.system_root.absolute(),
61+
'toolchain' : self.toolchain,
62+
'build_directory' : self.build_directory.absolute(),
63+
'intermediate_directory' : self.intermediate_directory.absolute(),
64+
'module_cache_directory' : self.module_cache_directory.absolute(),
65+
'install_directory' : self.install_directory.absolute(),
66+
'prefix' : self.prefix,
67+
'swift_install' : self.swift_install,
68+
'clang' : self.clang,
69+
'clangxx' : self.clangxx,
70+
'swift' : self.swift,
71+
'swiftc' : self.swiftc,
72+
'ar' : self.ar,
73+
'swift_sdk' : self.swift_sdk,
74+
'bootstrap_directory' : self.bootstrap_directory.absolute(),
75+
'verbose' : self.verbose,
76+
'extra_c_flags' : self.extra_c_flags,
77+
'extra_swift_flags' : self.extra_swift_flags,
78+
'extra_ld_flags' : self.extra_ld_flags,
79+
'build_mode' : self.build_mode,
80+
'variables' : self.variables,
81+
}
82+
with open(path, 'w+') as outfile:
83+
json.dump(info, outfile)
84+

lib/script.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,17 @@ def generate_products(self):
213213
for product in self.products:
214214
script += product.generate()
215215

216-
script += "\n\n"
216+
script += """
217+
218+
rule RunReconfigure
219+
command = ./configure --reconfigure
220+
description = Reconfiguring build script.
221+
222+
build ${BUILD_DIR}/.reconfigure: RunReconfigure
223+
224+
build reconfigure: phony | ${BUILD_DIR}/.reconfigure
225+
226+
"""
217227
script += self.extra
218228
script += "\n\n"
219229

0 commit comments

Comments
 (0)