Skip to content

Commit 6bf0826

Browse files
committed
[build-script] Improvements to CMakeOptions.
CMakeOptions was briefly used in the cmake module, but mostly unused in the rest of the modules, however, several products were dealing with what eventually will end as CMake options, but not using the already existing code, and duplicating it. The changes tries to unify all usage around CMakeOptions which avoids code duplication. Additionally, it provides some more API surface in CMakeOptions to make it more useful. - The initializer can be passed a list of tuples or another CMakeOptions to copy into the newly created options. - Boolean Python values are treated automatically as boolean CMake options and transformed into `TRUE` and `FALSE` automatically. - Provides `extend`, which will add all the tuples from a list or all the options from another `CMakeOptions` into the receiving `CMakeOptions`. - Provides `__contains__`, which makes checking for existing options a little easier (however, being `CMakeOptions` basically a list, the checking has to include also the value, which is not that helpful). - Modify LLVM and Swift products to use `CMakeOptions`. It makes the boolean values clearer and avoid a lot of repetitive string formatting. - Modify the tests to make them pass and provide new test for newly introduced features.
1 parent 05808b9 commit 6bf0826

File tree

7 files changed

+98
-49
lines changed

7 files changed

+98
-49
lines changed

utils/swift_build_support/swift_build_support/cmake.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,33 @@ class CMakeOptions(object):
2525
"""List like object used to define cmake options
2626
"""
2727

28-
def __init__(self):
28+
def __init__(self, initial_options=None):
2929
self._options = []
30+
if initial_options is not None:
31+
self.extend(initial_options)
3032

3133
def define(self, var, value):
3234
"""Utility to define cmake options in this object.
3335
3436
opts.define("FOO", "BAR") # -> -DFOO=BAR
3537
opts.define("FLAG:BOOL", True) # -> -FLAG:BOOL=TRUE
3638
"""
37-
if var.endswith(':BOOL'):
39+
if var.endswith(':BOOL') or isinstance(value, bool):
3840
value = self.true_false(value)
3941
if value is None:
4042
value = ""
4143
elif not isinstance(value, (str, Number)):
42-
raise ValueError('define: invalid value: %s' % value)
44+
raise ValueError('define: invalid value for key %s: %s (%s)' %
45+
(var, value, type(value)))
4346
self._options.append('-D%s=%s' % (var, value))
4447

48+
def extend(self, tuples_or_options):
49+
if isinstance(tuples_or_options, CMakeOptions):
50+
self += tuples_or_options
51+
else:
52+
for (variable, value) in tuples_or_options:
53+
self.define(variable, value)
54+
4555
@staticmethod
4656
def true_false(value):
4757
if hasattr(value, 'lower'):
@@ -58,6 +68,9 @@ def __len__(self):
5868
def __iter__(self):
5969
return self._options.__iter__()
6070

71+
def __contains__(self, item):
72+
return self._options.__contains__(item)
73+
6174
def __add__(self, other):
6275
ret = CMakeOptions()
6376
ret._options += self._options

utils/swift_build_support/swift_build_support/products/llvm.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# ----------------------------------------------------------------------------
1212

1313
from . import product
14+
from ..cmake import CMakeOptions
1415

1516

1617
class LLVM(product.Product):
@@ -20,14 +21,12 @@ def __init__(self, args, toolchain, source_dir, build_dir):
2021
build_dir)
2122

2223
# Add the cmake option for enabling or disabling assertions.
23-
self.cmake_options.extend([
24-
'-DLLVM_ENABLE_ASSERTIONS=%s' % str(args.llvm_assertions).upper()
25-
])
24+
self.cmake_options.define(
25+
'LLVM_ENABLE_ASSERTIONS:BOOL', args.llvm_assertions)
2626

2727
# Add the cmake option for LLVM_TARGETS_TO_BUILD.
28-
self.cmake_options.extend([
29-
'-DLLVM_TARGETS_TO_BUILD=%s' % args.llvm_targets_to_build
30-
])
28+
self.cmake_options.define(
29+
'LLVM_TARGETS_TO_BUILD', args.llvm_targets_to_build)
3130

3231
# Add the cmake options for vendors
3332
self.cmake_options.extend(self._compiler_vendor_flags)
@@ -44,17 +43,17 @@ def _compiler_vendor_flags(self):
4443
raise RuntimeError("Unknown compiler vendor?!")
4544

4645
return [
47-
"-DCLANG_VENDOR=Apple",
48-
"-DCLANG_VENDOR_UTI=com.apple.compilers.llvm.clang",
46+
('CLANG_VENDOR', 'Apple'),
47+
('CLANG_VENDOR_UTI', 'com.apple.compilers.llvm.clang'),
4948
# This is safe since we always provide a default.
50-
"-DPACKAGE_VERSION={}".format(self.args.clang_user_visible_version)
49+
('PACKAGE_VERSION', str(self.args.clang_user_visible_version))
5150
]
5251

5352
@property
5453
def _version_flags(self):
55-
result = []
54+
result = CMakeOptions()
5655
if self.args.clang_compiler_version is not None:
57-
result.append("-DCLANG_REPOSITORY_STRING=clang-{}".format(
58-
self.args.clang_compiler_version
59-
))
56+
result.define(
57+
'CLANG_REPOSITORY_STRING',
58+
"clang-{}".format(self.args.clang_compiler_version))
6059
return result

utils/swift_build_support/swift_build_support/products/product.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
import abc
1414

15+
from .. import cmake
16+
1517

1618
class Product(object):
1719
@classmethod
@@ -59,7 +61,7 @@ def __init__(self, args, toolchain, source_dir, build_dir):
5961
self.toolchain = toolchain
6062
self.source_dir = source_dir
6163
self.build_dir = build_dir
62-
self.cmake_options = []
64+
self.cmake_options = cmake.CMakeOptions()
6365

6466

6567
class ProductBuilder(object):

utils/swift_build_support/swift_build_support/products/swift.py

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# ----------------------------------------------------------------------------
1212

1313
from . import product
14+
from ..cmake import CMakeOptions
1415

1516

1617
class Swift(product.Product):
@@ -47,8 +48,7 @@ def _runtime_sanitizer_flags(self):
4748
sanitizer_list += ['Thread']
4849
if len(sanitizer_list) == 0:
4950
return []
50-
return ["-DSWIFT_RUNTIME_USE_SANITIZERS=%s" %
51-
";".join(sanitizer_list)]
51+
return [('SWIFT_RUNTIME_USE_SANITIZERS', ';'.join(sanitizer_list))]
5252

5353
@property
5454
def _compiler_vendor_flags(self):
@@ -64,31 +64,27 @@ def _compiler_vendor_flags(self):
6464
swift_compiler_version = self.args.swift_compiler_version
6565

6666
return [
67-
"-DSWIFT_VENDOR=Apple",
68-
"-DSWIFT_VENDOR_UTI=com.apple.compilers.llvm.swift",
67+
('SWIFT_VENDOR', 'Apple'),
68+
('SWIFT_VENDOR_UTI', 'com.apple.compilers.llvm.swift'),
6969

7070
# This has a default of 3.0, so it should be safe to use here.
71-
"-DSWIFT_VERSION={}".format(self.args.swift_user_visible_version),
71+
('SWIFT_VERSION', str(self.args.swift_user_visible_version)),
7272

7373
# FIXME: We are matching build-script-impl here. But it seems like
7474
# bit rot since this flag is specified in another place with the
7575
# exact same value in build-script-impl.
76-
"-DSWIFT_COMPILER_VERSION={}".format(swift_compiler_version),
76+
('SWIFT_COMPILER_VERSION', str(swift_compiler_version)),
7777
]
7878

7979
@property
8080
def _version_flags(self):
81-
r = []
81+
r = CMakeOptions()
8282
if self.args.swift_compiler_version is not None:
8383
swift_compiler_version = self.args.swift_compiler_version
84-
r.append(
85-
"-DSWIFT_COMPILER_VERSION={}".format(swift_compiler_version)
86-
)
84+
r.define('SWIFT_COMPILER_VERSION', str(swift_compiler_version))
8785
if self.args.clang_compiler_version is not None:
8886
clang_compiler_version = self.args.clang_compiler_version
89-
r.append(
90-
"-DCLANG_COMPILER_VERSION={}".format(clang_compiler_version)
91-
)
87+
r.define('CLANG_COMPILER_VERSION', str(clang_compiler_version))
9288
return r
9389

9490
@property
@@ -99,24 +95,20 @@ def _benchmark_flags(self):
9995
onone_iters = self.args.benchmark_num_onone_iterations
10096
o_iters = self.args.benchmark_num_o_iterations
10197
return [
102-
"-DSWIFT_BENCHMARK_NUM_ONONE_ITERATIONS={}".format(onone_iters),
103-
"-DSWIFT_BENCHMARK_NUM_O_ITERATIONS={}".format(o_iters)
98+
('SWIFT_BENCHMARK_NUM_ONONE_ITERATIONS', onone_iters),
99+
('SWIFT_BENCHMARK_NUM_O_ITERATIONS', o_iters)
104100
]
105101

106102
@property
107103
def _compile_db_flags(self):
108-
return ['-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE']
104+
return [('CMAKE_EXPORT_COMPILE_COMMANDS', True)]
109105

110106
@property
111107
def _force_optimized_typechecker_flags(self):
112-
if not self.args.force_optimized_typechecker:
113-
return ['-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=FALSE']
114-
return ['-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=TRUE']
108+
return [('SWIFT_FORCE_OPTIMIZED_TYPECHECKER:BOOL',
109+
self.args.force_optimized_typechecker)]
115110

116111
@property
117112
def _stdlibcore_exclusivity_checking_flags(self):
118-
# This is just to get around 80 column limitations.
119-
result = '-DSWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING={}'
120-
if not self.args.enable_stdlibcore_exclusivity_checking:
121-
return [result.format("FALSE")]
122-
return [result.format("TRUE")]
113+
return [('SWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING:BOOL',
114+
self.args.enable_stdlibcore_exclusivity_checking)]

utils/swift_build_support/tests/products/test_llvm.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,16 @@ def test_llvm_enable_assertions(self):
8989
toolchain=self.toolchain,
9090
source_dir='/path/to/src',
9191
build_dir='/path/to/build')
92-
self.assertIn('-DLLVM_ENABLE_ASSERTIONS=TRUE', llvm.cmake_options)
92+
self.assertIn('-DLLVM_ENABLE_ASSERTIONS:BOOL=TRUE', llvm.cmake_options)
9393

9494
self.args.llvm_assertions = False
9595
llvm = LLVM(
9696
args=self.args,
9797
toolchain=self.toolchain,
9898
source_dir='/path/to/src',
9999
build_dir='/path/to/build')
100-
self.assertIn('-DLLVM_ENABLE_ASSERTIONS=FALSE', llvm.cmake_options)
100+
self.assertIn('-DLLVM_ENABLE_ASSERTIONS:BOOL=FALSE',
101+
llvm.cmake_options)
101102

102103
def test_compiler_vendor_flags(self):
103104
self.args.compiler_vendor = "none"

utils/swift_build_support/tests/products/test_swift.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ def test_by_default_no_cmake_options(self):
8686
build_dir='/path/to/build')
8787
expected = [
8888
'-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE',
89-
'-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=FALSE',
90-
'-DSWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING=FALSE'
89+
'-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER:BOOL=FALSE',
90+
'-DSWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING:BOOL=FALSE'
9191
]
9292
self.assertEqual(set(swift.cmake_options), set(expected))
9393

@@ -101,8 +101,8 @@ def test_swift_runtime_tsan(self):
101101
flags_set = [
102102
'-DSWIFT_RUNTIME_USE_SANITIZERS=Thread',
103103
'-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE',
104-
'-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=FALSE',
105-
'-DSWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING=FALSE'
104+
'-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER:BOOL=FALSE',
105+
'-DSWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING:BOOL=FALSE'
106106
]
107107
self.assertEqual(set(swift.cmake_options), set(flags_set))
108108

@@ -286,7 +286,7 @@ def test_force_optimized_typechecker_flags(self):
286286
source_dir='/path/to/src',
287287
build_dir='/path/to/build')
288288
self.assertEqual(
289-
['-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=TRUE'],
289+
['-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER:BOOL=TRUE'],
290290
[x for x in swift.cmake_options
291291
if 'SWIFT_FORCE_OPTIMIZED_TYPECHECKER' in x])
292292

@@ -298,6 +298,7 @@ def test_exclusivity_checking_flags(self):
298298
source_dir='/path/to/src',
299299
build_dir='/path/to/build')
300300
self.assertEqual(
301-
['-DSWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING=TRUE'],
301+
['-DSWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING:BOOL='
302+
'TRUE'],
302303
[x for x in swift.cmake_options
303304
if 'SWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING' in x])

utils/swift_build_support/tests/test_cmake.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,47 @@ def test_operations(self):
496496
"-DOPT1_1=VAL1",
497497
"-DOPT1_2=VAL2"])
498498

499+
def test_initial_options_with_tuples(self):
500+
options = CMakeOptions([('FOO', 'foo'), ('BAR', True)])
501+
self.assertIn('-DFOO=foo', options)
502+
self.assertIn('-DBAR=TRUE', options)
503+
504+
def test_initial_options_with_other_options(self):
505+
options = CMakeOptions()
506+
options.define('FOO', 'foo')
507+
options.define('BAR', True)
508+
derived = CMakeOptions(options)
509+
self.assertIn('-DFOO=foo', derived)
510+
self.assertIn('-DBAR=TRUE', derived)
511+
512+
def test_booleans_are_translated(self):
513+
options = CMakeOptions()
514+
options.define('A_BOOLEAN_OPTION', True)
515+
options.define('ANOTHER_BOOLEAN_OPTION', False)
516+
self.assertIn('-DA_BOOLEAN_OPTION=TRUE', options)
517+
self.assertIn('-DANOTHER_BOOLEAN_OPTION=FALSE', options)
518+
519+
def test_extend_with_other_options(self):
520+
options = CMakeOptions()
521+
options.define('FOO', 'foo')
522+
options.define('BAR', True)
523+
derived = CMakeOptions()
524+
derived.extend(options)
525+
self.assertIn('-DFOO=foo', derived)
526+
self.assertIn('-DBAR=TRUE', derived)
527+
528+
def test_extend_with_tuples(self):
529+
options = CMakeOptions()
530+
options.extend([('FOO', 'foo'), ('BAR', True)])
531+
self.assertIn('-DFOO=foo', options)
532+
self.assertIn('-DBAR=TRUE', options)
533+
534+
def test_contains(self):
535+
options = CMakeOptions()
536+
self.assertTrue('-DFOO=foo' not in options)
537+
options.define('FOO', 'foo')
538+
self.assertTrue('-DFOO=foo' in options)
539+
499540

500541
if __name__ == '__main__':
501542
unittest.main()

0 commit comments

Comments
 (0)