From 8c04d6c967b33a311fe17e69e9c5e2289a2fcd14 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 13 Feb 2019 00:15:15 +0100 Subject: [PATCH] CMake: pro2cmake.py: Improve condition simplification code Improve the code that simplifies conditions to take "OS families" into account. E.g. if a system must be ANDROID, then it is redundant to express that it is NOT APPLE_OSX. Change-Id: Ib7e62726c309bf84b9e5e0d6a6e3465511db0ead Reviewed-by: Albert Astals Cid --- util/cmake/pro2cmake.py | 37 +++++++++++++++++++------ util/cmake/tests/test_logic_mapping.py | 21 ++++++++++++++ util/cmake/tests/test_scope_handling.py | 4 +-- 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/util/cmake/pro2cmake.py b/util/cmake/pro2cmake.py index 63938d75c8..60e7f433bf 100755 --- a/util/cmake/pro2cmake.py +++ b/util/cmake/pro2cmake.py @@ -875,12 +875,11 @@ def _iterate_expr_tree(expr, op, matches): keepers = (*keepers, *extra_keepers) else: keepers = (*keepers, arg) - return (matches, keepers) + return matches, keepers def _simplify_expressions(expr, op, matches, replacement): - args = expr.args - for arg in args: + for arg in expr.args: expr = expr.subs(arg, _simplify_expressions(arg, op, matches, replacement)) @@ -920,17 +919,34 @@ def _simplify_flavors_in_condition(base: str, flavors, expr): return expr +def _simplify_os_families(expr, family_members, other_family_members): + for family in family_members: + for other in other_family_members: + if other in family_members: + continue # skip those in the sub-family + + f_expr = simplify_logic(family) + o_expr = simplify_logic(other) + + expr = _simplify_expressions(expr, And, (f_expr, Not(o_expr)), f_expr) + expr = _simplify_expressions(expr, And, (Not(f_expr), o_expr), o_expr) + expr = _simplify_expressions(expr, And, (f_expr, o_expr), simplify_logic('false')) + return expr + + def _recursive_simplify(expr): ''' Simplify the expression as much as possible based on domain knowledge. ''' input_expr = expr # Simplify even further, based on domain knowledge: + windowses = ('WIN32', 'WINRT') apples = ('APPLE_OSX', 'APPLE_UIKIT', 'APPLE_IOS', 'APPLE_TVOS', 'APPLE_WATCHOS',) bsds = ('APPLE', 'FREEBSD', 'OPENBSD', 'NETBSD',) + androids = ('ANDROID', 'ANDROID_EMBEDDED') unixes = ('APPLE', *apples, 'BSD', *bsds, 'LINUX', - 'ANDROID', 'ANDROID_EMBEDDED', + *androids, 'HAIKU', 'INTEGRITY', 'VXWORKS', 'QNX', 'WASM') unix_expr = simplify_logic('UNIX') @@ -945,11 +961,6 @@ def _recursive_simplify(expr): expr = _simplify_expressions(expr, Or, (unix_expr, win_expr,), true_expr) # UNIX [AND foo ]AND WIN32 -> OFF [AND foo] expr = _simplify_expressions(expr, And, (unix_expr, win_expr,), false_expr) - for unix_flavor in unixes: - # unix_flavor [AND foo ] AND WIN32 -> FALSE [AND foo] - flavor_expr = simplify_logic(unix_flavor) - expr = _simplify_expressions(expr, And, (win_expr, flavor_expr,), - false_expr) expr = _simplify_flavors_in_condition('WIN32', ('WINRT',), expr) expr = _simplify_flavors_in_condition('APPLE', apples, expr) @@ -957,6 +968,14 @@ def _recursive_simplify(expr): expr = _simplify_flavors_in_condition('UNIX', unixes, expr) expr = _simplify_flavors_in_condition('ANDROID', ('ANDROID_EMBEDDED',), expr) + # Simplify families of OSes against other families: + expr = _simplify_os_families(expr, ('WIN32', 'WINRT'), unixes) + expr = _simplify_os_families(expr, androids, unixes) + expr = _simplify_os_families(expr, ('BSD', *bsds), unixes) + + for family in ('HAIKU', 'QNX', 'INTEGRITY', 'LINUX', 'VXWORKS'): + expr = _simplify_os_families(expr, (family,), unixes) + # Now simplify further: expr = simplify_logic(expr) diff --git a/util/cmake/tests/test_logic_mapping.py b/util/cmake/tests/test_logic_mapping.py index cf7913a6e4..c477aa8351 100755 --- a/util/cmake/tests/test_logic_mapping.py +++ b/util/cmake/tests/test_logic_mapping.py @@ -47,6 +47,14 @@ def test_simplify_off(): validate_simplify_unchanged('OFF') +def test_simplify_not_on(): + validate_simplify('NOT ON', 'OFF') + + +def test_simplify_not_off(): + validate_simplify('NOT OFF', 'ON') + + def test_simplify_isEmpty(): validate_simplify_unchanged('isEmpty(foo)') @@ -99,11 +107,19 @@ def test_simplify_unix_and_win32(): validate_simplify('WIN32 AND UNIX', 'OFF') +def test_simplify_unix_or_win32(): + validate_simplify('WIN32 OR UNIX', 'ON') + + def test_simplify_unix_and_win32_or_foobar_or_barfoo(): validate_simplify('WIN32 AND foobar AND UNIX AND barfoo', 'OFF') def test_simplify_watchos_and_win32(): + validate_simplify('APPLE_WATCHOS AND WIN32', 'OFF') + + +def test_simplify_win32_and_watchos(): validate_simplify('WIN32 AND APPLE_WATCHOS', 'OFF') @@ -163,3 +179,8 @@ def test_simplify_complex_false(): validate_simplify('WIN32 AND foobar AND ( ' 'APPLE OR ( UNIX OR FREEBSD ))', 'OFF') + + +def test_simplify_android_not_apple(): + validate_simplify('ANDROID AND NOT ANDROID_EMBEDDED AND NOT APPLE_OSX', + 'ANDROID AND NOT ANDROID_EMBEDDED') diff --git a/util/cmake/tests/test_scope_handling.py b/util/cmake/tests/test_scope_handling.py index 1c3406bac8..8bca8c8ec5 100755 --- a/util/cmake/tests/test_scope_handling.py +++ b/util/cmake/tests/test_scope_handling.py @@ -332,7 +332,7 @@ def test_qstandardpaths_scopes(): assert scope6.total_condition == 'UNIX' assert scope7.total_condition == 'APPLE_OSX' assert scope8.total_condition == 'UNIX AND NOT APPLE_OSX' - assert scope9.total_condition == 'ANDROID AND NOT ANDROID_EMBEDDED AND NOT APPLE_OSX' + assert scope9.total_condition == 'ANDROID AND NOT ANDROID_EMBEDDED' assert scope10.total_condition == 'UNIX AND NOT APPLE_OSX AND (ANDROID_EMBEDDED OR NOT ANDROID)' - assert scope11.total_condition == 'HAIKU AND UNIX AND NOT APPLE_OSX AND (ANDROID_EMBEDDED OR NOT ANDROID)' + assert scope11.total_condition == 'HAIKU AND (ANDROID_EMBEDDED OR NOT ANDROID)' assert scope12.total_condition == 'UNIX AND NOT APPLE_OSX AND NOT HAIKU AND (ANDROID_EMBEDDED OR NOT ANDROID)'