summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2019-09-30 18:16:20 +0200
committerTobias Hunger <tobias.hunger@qt.io>2019-10-01 14:14:16 +0000
commitf23b7e1476ded2be43d5e3f03195f522d307b163 (patch)
tree76c5fa3d2de29fbbedc01a6647198b6f123fbaa6 /util
parent590213e531f3a14f9b5365a10122f815d5fd6e8f (diff)
Implement persistent caching for simplify_condition
Store the results of simplify_condition in a json cache file, next to the pro2cmake.py script. Dramatically speeds up re-conversion of projects. The cache is cleared whenever the content of the condition_simplifier.py file changes, effectively presuming that the condition computing code has changed. Sample times. Initial corelib.pro conversion - 142.13 seconds. Next re-conversion with hot cache - 1.17 seconds. Change-Id: I8790b2736358236e4b23bcb5f10f45a36fdfa426 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io> Reviewed-by: Qt CMake Build Bot
Diffstat (limited to 'util')
-rw-r--r--util/cmake/condition_simplifier.py3
-rw-r--r--util/cmake/condition_simplifier_cache.py113
2 files changed, 115 insertions, 1 deletions
diff --git a/util/cmake/condition_simplifier.py b/util/cmake/condition_simplifier.py
index c67b78ffad..de329be1d4 100644
--- a/util/cmake/condition_simplifier.py
+++ b/util/cmake/condition_simplifier.py
@@ -29,8 +29,8 @@
import re
-
from sympy import simplify_logic, And, Or, Not, SympifyError
+from condition_simplifier_cache import simplify_condition_memoize
def _iterate_expr_tree(expr, op, matches):
@@ -160,6 +160,7 @@ def _recursive_simplify(expr):
return expr
+@simplify_condition_memoize
def simplify_condition(condition: str) -> str:
input_condition = condition.strip()
diff --git a/util/cmake/condition_simplifier_cache.py b/util/cmake/condition_simplifier_cache.py
new file mode 100644
index 0000000000..b405ef23f8
--- /dev/null
+++ b/util/cmake/condition_simplifier_cache.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python3
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the plugins of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+
+import atexit
+import hashlib
+import json
+import os
+import sys
+import time
+
+from typing import Callable
+
+
+def get_current_file_path() -> str:
+ try:
+ this_file = __file__
+ except NameError:
+ this_file = sys.argv[0]
+ this_file = os.path.abspath(this_file)
+ return this_file
+
+
+def get_cache_location() -> str:
+ this_file = get_current_file_path()
+ dir_path = os.path.dirname(this_file)
+ cache_path = os.path.join(dir_path, ".pro2cmake_cache", "cache.json")
+ return cache_path
+
+
+def get_file_checksum(file_path: str) -> str:
+ try:
+ with open(file_path, "r") as content_file:
+ content = content_file.read()
+ except IOError:
+ content = time.time()
+ checksum = hashlib.md5(content.encode("utf-8")).hexdigest()
+ return checksum
+
+
+def get_condition_simplifier_checksum() -> str:
+ current_file_path = get_current_file_path()
+ dir_name = os.path.dirname(current_file_path)
+ condition_simplifier_path = os.path.join(dir_name, "condition_simplifier.py")
+ return get_file_checksum(condition_simplifier_path)
+
+
+def init_cache_dict():
+ return {
+ "checksum": get_condition_simplifier_checksum(),
+ "schema_version": "1",
+ "cache": {"conditions": {}},
+ }
+
+
+def simplify_condition_memoize(f: Callable[[str], str]):
+ cache_path = get_cache_location()
+ cache_file_content = None
+
+ if os.path.exists(cache_path):
+ try:
+ with open(cache_path, "r") as cache_file:
+ cache_file_content = json.load(cache_file)
+ except (IOError, ValueError):
+ pass
+
+ if not cache_file_content:
+ cache_file_content = init_cache_dict()
+
+ current_checksum = get_condition_simplifier_checksum()
+ if cache_file_content["checksum"] != current_checksum:
+ cache_file_content = init_cache_dict()
+
+ def update_cache_file():
+ if not os.path.exists(cache_path):
+ os.makedirs(os.path.dirname(cache_path), exist_ok=True)
+ with open(cache_path, "w") as cache_file_write_handle:
+ json.dump(cache_file_content, cache_file_write_handle, indent=4)
+
+ atexit.register(update_cache_file)
+
+ def helper(condition: str) -> str:
+ if condition not in cache_file_content["cache"]["conditions"]:
+ cache_file_content["cache"]["conditions"][condition] = f(condition)
+ return cache_file_content["cache"]["conditions"][condition]
+
+ return helper