From cd9813d2763adb715d1cf1a37b86439fea255172 Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Mon, 28 Oct 2019 15:35:47 +0100 Subject: Add support for benchmark conversion Convert benchmark executables to add_qt_benchmark(). Currently add_qt_benchmark just calls add_qt_executable() and ensures that it they build under CMAKE_CURRENT_BUILD_DIR and do not install. Add QT_BUILD_BENCHMARKS option to enable/disable building of benchmarks. Change-Id: Id0bc676698d21d50048d97d9abef51d92ccb6638 Reviewed-by: Alexandru Croitor --- cmake/QtBuild.cmake | 32 +++++++++++++++++++++ .../QtBuildInternals/QtBuildInternalsConfig.cmake | 2 +- cmake/QtSetup.cmake | 11 ++++++++ util/cmake/pro2cmake.py | 33 ++++++++++++++++------ 4 files changed, 69 insertions(+), 9 deletions(-) diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake index c47271f9de..1c46b09eb3 100644 --- a/cmake/QtBuild.cmake +++ b/cmake/QtBuild.cmake @@ -2351,6 +2351,38 @@ function(add_qt_executable name) endif() endfunction() +# Simple wrapper around add_qt_executable for benchmarks which insure that +# the binary is built under ${CMAKE_CURRENT_BINARY_DIR} and never installed. +# See add_qt_executable() for more details. +function(add_qt_benchmark target) + + qt_parse_all_arguments(arg "add_qt_benchmark" + "${__add_qt_executable_optional_args}" + "${__add_qt_executable_single_args}" + "${__add_qt_executable_multi_args}" + ${ARGN} + ) + + qt_remove_args(exec_args + ARGS_TO_REMOVE + ${target} + OUTPUT_DIRECTORY + INSTALL_DIRECTORY + ALL_ARGS + "${__add_qt_executable_optional_args}" + "${__add_qt_executable_single_args}" + "${__add_qt_executable_multi_args}" + ARGS + ${ARGV} + ) + + add_qt_executable(${target} + NO_INSTALL # we don't install benchmarks + OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" # avoid polluting bin directory + ${exec_args} + ) + +endfunction() # This function creates a CMake test target with the specified name for use with CTest. function(add_qt_test name) diff --git a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake index 4bf09e5b15..cb2070f773 100644 --- a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake +++ b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake @@ -159,7 +159,7 @@ macro(qt_build_tests) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/auto/CMakeLists.txt") add_subdirectory(auto) endif() - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/CMakeLists.txt") + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/CMakeLists.txt" AND QT_BUILD_BENCHMARKS) add_subdirectory(benchmarks) endif() endmacro() diff --git a/cmake/QtSetup.cmake b/cmake/QtSetup.cmake index 6f42e337da..837b81db4d 100644 --- a/cmake/QtSetup.cmake +++ b/cmake/QtSetup.cmake @@ -73,8 +73,16 @@ if(FEATURE_developer_build) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) endif() set(QT_BUILD_TESTING ON) + set(__build_benchmarks ON) + + # Disable benchmarks for single configuration generators which do not build + # with release configuration. + if (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE STREQUAL Release) + set(__build_benchmarks OFF) + endif() else() set(QT_BUILD_TESTING OFF) + set(__build_benchmarks OFF) endif() ## Set up testing @@ -85,6 +93,9 @@ enable_testing() # Set up building of examples. option(BUILD_EXAMPLES "Build Qt examples" ON) +# Build Benchmarks +option(QT_BUILD_BENCHMARKS "Build Qt Benchmarks" ${__build_benchmarks}) + ## Android platform settings if(ANDROID) include(QtPlatformAndroid) diff --git a/util/cmake/pro2cmake.py b/util/cmake/pro2cmake.py index c16864d474..89e3e6441a 100755 --- a/util/cmake/pro2cmake.py +++ b/util/cmake/pro2cmake.py @@ -233,6 +233,16 @@ def is_config_test_project(project_file_path: str = "") -> bool: ) +def is_benchmark_project(project_file_path: str = "") -> bool: + qmake_conf_path = find_qmake_conf(project_file_path) + qmake_conf_dir_path = os.path.dirname(qmake_conf_path) + + project_relative_path = os.path.relpath(project_file_path, qmake_conf_dir_path) + # If the project file is found in a subdir called 'tests/benchmarks' + # relative to the repo source dir, then it must be benchmark + return project_relative_path.startswith("tests/benchmarks") + + @lru_cache(maxsize=None) def find_qmake_conf(project_file_path: str = "") -> str: if not os.path.isabs(project_file_path): @@ -2661,22 +2671,29 @@ def write_binary(cm_fh: IO[str], scope: Scope, gui: bool = False, *, indent: int binary_name = scope.TARGET assert binary_name + is_benchmark = is_benchmark_project(scope.file_absolute_path) + is_qt_test_helper = "qt_test_helper" in scope.get("_LOADED") extra = ["GUI"] if gui and not is_qt_test_helper else [] cmake_function_call = "add_qt_executable" + extra_keys = [] if is_qt_test_helper: binary_name += "_helper" cmake_function_call = "add_qt_test_helper" - target_path = scope.get_string("target.path") - if target_path: - target_path = replace_path_constants(target_path, scope) - if not scope.get("DESTDIR"): - extra.append(f'OUTPUT_DIRECTORY "{target_path}"') - if "target" in scope.get("INSTALLS"): - extra.append(f'INSTALL_DIRECTORY "{target_path}"') + if is_benchmark: + cmake_function_call = "add_qt_benchmark" + else: + extra_keys = ["target.path", "INSTALLS"] + target_path = scope.get_string("target.path") + if target_path: + target_path = replace_path_constants(target_path, scope) + if not scope.get("DESTDIR"): + extra.append(f'OUTPUT_DIRECTORY "{target_path}"') + if "target" in scope.get("INSTALLS"): + extra.append(f'INSTALL_DIRECTORY "{target_path}"') write_main_part( cm_fh, @@ -2687,7 +2704,7 @@ def write_binary(cm_fh: IO[str], scope: Scope, gui: bool = False, *, indent: int extra_lines=extra, indent=indent, known_libraries={"Qt::Core"}, - extra_keys=["target.path", "INSTALLS"], + extra_keys=extra_keys, ) return binary_name -- cgit v1.2.3