This is an automated email from the ASF dual-hosted git repository. szaszm pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git
commit 435b5e016de9cae654c3e054e1a566c11f54d788 Author: Gabor Gyimesi <gamezb...@gmail.com> AuthorDate: Mon May 6 20:38:38 2024 +0200 MINIFICPP-2336 Python bootstrap part 2 Closes #1773 Signed-off-by: Marton Szasz <sza...@apache.org> --- bootstrap/.gitignore | 2 +- bootstrap/cli.py | 56 ++++++++++++++++++++++++++++++++---------- bootstrap/main.py | 1 + bootstrap/minifi_option.py | 43 +++++++++++++++++++++++++++++++- bootstrap/system_dependency.py | 2 +- 5 files changed, 88 insertions(+), 16 deletions(-) diff --git a/bootstrap/.gitignore b/bootstrap/.gitignore index 13166f334..51c5d7c74 100644 --- a/bootstrap/.gitignore +++ b/bootstrap/.gitignore @@ -1,3 +1,3 @@ venv build_environment.bat - +option_state.json diff --git a/bootstrap/cli.py b/bootstrap/cli.py index e383771c8..e8bdc5ec8 100644 --- a/bootstrap/cli.py +++ b/bootstrap/cli.py @@ -15,7 +15,6 @@ import os - import inquirer from minifi_option import MinifiOptions @@ -32,21 +31,26 @@ def install_dependencies(minifi_options: MinifiOptions, package_manager: Package def run_cmake(minifi_options: MinifiOptions, package_manager: PackageManager): if not os.path.exists(minifi_options.build_dir): os.mkdir(minifi_options.build_dir) - cmake_cmd = f"cmake -G Ninja {minifi_options.create_cmake_options_str()} {minifi_options.source_dir} -B {minifi_options.build_dir}" + cmake_cmd = f"cmake {minifi_options.create_cmake_generator_str()} {minifi_options.create_cmake_options_str()} {minifi_options.source_dir} -B {minifi_options.build_dir}" res = package_manager.run_cmd(cmake_cmd) print("CMake command run successfully" if res else "CMake command run unsuccessfully") return res def do_build(minifi_options: MinifiOptions, package_manager: PackageManager): - build_cmd = f"cmake --build {str(minifi_options.build_dir)}" + build_cmd = f"cmake --build {str(minifi_options.build_dir)} {minifi_options.create_cmake_build_flags_str()}" res = package_manager.run_cmd(build_cmd) print("Build was successful" if res else "Build was unsuccessful") return res def do_package(minifi_options: MinifiOptions, package_manager: PackageManager): - build_cmd = f"cmake --build {str(minifi_options.build_dir)} --target package" + build_cmd = f"cmake --build {str(minifi_options.build_dir)} --target package {minifi_options.create_cmake_build_flags_str()}" + return package_manager.run_cmd(build_cmd) + + +def do_docker_build(minifi_options: MinifiOptions, package_manager: PackageManager): + build_cmd = f"cmake --build {str(minifi_options.build_dir)} --target docker" return package_manager.run_cmd(build_cmd) @@ -64,7 +68,8 @@ def main_menu(minifi_options: MinifiOptions, package_manager: PackageManager): main_menu_options = { f"Build dir: {minifi_options.build_dir}": build_dir_menu, f"Build type: {minifi_options.build_type.value}": build_type_menu, - "Build options": bool_menu, + "Build options": build_options_menu, + "Extension options": extension_options_menu, "One click build": do_one_click_build, "Step by step build": step_by_step_menu, "Exit": lambda _options, _manager: True, @@ -107,25 +112,49 @@ def build_dir_menu(minifi_options: MinifiOptions, _package_manager: PackageManag return False -def bool_menu(minifi_options: MinifiOptions, _package_manager: PackageManager) -> bool: - possible_values = [option_name for option_name in minifi_options.bool_options] - selected_values = [option.name for option in minifi_options.bool_options.values() if option.value == "ON"] +def extension_options_menu(minifi_options: MinifiOptions, _package_manager: PackageManager) -> bool: + possible_values = [option_name for option_name in minifi_options.extension_options] + selected_values = [option.name for option in minifi_options.extension_options.values() if option.value == "ON"] + questions = [ + inquirer.Checkbox( + "options", + message="MiNiFi C++ Extension Options (space to select, enter to confirm)", + choices=possible_values, + default=selected_values + ), + ] + + answers = inquirer.prompt(questions) + for extension_option in minifi_options.extension_options.values(): + if extension_option.name in answers["options"]: + extension_option.value = "ON" + else: + extension_option.value = "OFF" + + minifi_options.save_option_state() + return False + + +def build_options_menu(minifi_options: MinifiOptions, _package_manager: PackageManager) -> bool: + possible_values = [option_name for option_name in minifi_options.build_options] + selected_values = [option.name for option in minifi_options.build_options.values() if option.value == "ON"] questions = [ inquirer.Checkbox( "options", - message="MiNiFi C++ Options (space to select, enter to confirm)", + message="MiNiFi C++ Build Options (space to select, enter to confirm)", choices=possible_values, default=selected_values ), ] answers = inquirer.prompt(questions) - for bool_option in minifi_options.bool_options.values(): - if bool_option.name in answers["options"]: - bool_option.value = "ON" + for build_option in minifi_options.build_options.values(): + if build_option.name in answers["options"]: + build_option.value = "ON" else: - bool_option.value = "OFF" + build_option.value = "OFF" + minifi_options.save_option_state() return False @@ -138,6 +167,7 @@ def step_by_step_menu(minifi_options: MinifiOptions, package_manager: PackageMan "Run cmake": run_cmake, "Build": do_build, "Package": do_package, + "Docker build": do_docker_build, "Back": lambda _options, _manager: True, } questions = [ diff --git a/bootstrap/main.py b/bootstrap/main.py index 9fd92ebcb..5985c3eb9 100644 --- a/bootstrap/main.py +++ b/bootstrap/main.py @@ -52,6 +52,7 @@ if __name__ == '__main__': cmake_options_for_parsing, package_manager, cmake_cache_dir) + minifi_options.load_option_state() minifi_options.no_confirm = no_confirm minifi_options.set_cmake_override(cmake_options_for_cmake) diff --git a/bootstrap/minifi_option.py b/bootstrap/minifi_option.py index 0c659eba9..7e4974fcb 100644 --- a/bootstrap/minifi_option.py +++ b/bootstrap/minifi_option.py @@ -16,6 +16,9 @@ from typing import Dict import pathlib +import json +import platform +import os import cmake_parser from cmake_parser import CMakeCacheValue @@ -28,8 +31,13 @@ class MinifiOptions: self.build_type = CMakeCacheValue("Specifies the build type on single-configuration generators", "CMAKE_BUILD_TYPE", "STRING", "Release") self.build_type.possible_values = ["Release", "Debug", "RelWithDebInfo", "MinSizeRel"] + additional_build_options = ["DOCKER_BUILD_ONLY", "DOCKER_SKIP_TESTS", "SKIP_TESTS"] + self.use_ninja = CMakeCacheValue("Specifies if CMake should use the Ninja generator or the system default", "USE_NINJA", "BOOL", "ON") self.bool_options = {name: cache_value for name, cache_value in cache_values.items() if - cache_value.value_type == "BOOL" and ("ENABLE" in name or "MINIFI" in name)} + cache_value.value_type == "BOOL" and ("ENABLE" in name or "MINIFI" in name or name in additional_build_options)} + self.build_options = {name: cache_value for name, cache_value in self.bool_options.items() if "MINIFI" in name or name in additional_build_options} + self.build_options["USE_NINJA"] = self.use_ninja + self.extension_options = {name: cache_value for name, cache_value in self.bool_options.items() if "ENABLE" in name} self.multi_choice_options = [cache_value for name, cache_value in cache_values.items() if cache_value.value_type == "STRING" and cache_value.possible_values is not None] self.build_dir = pathlib.Path(__file__).parent.parent.resolve() / "build" @@ -44,6 +52,17 @@ class MinifiOptions: cmake_options_str = " ".join(filter(None, cmake_options)) return cmake_options_str + def create_cmake_generator_str(self) -> str: + return "-G Ninja" if self.use_ninja.value == "ON" else "" + + def create_cmake_build_flags_str(self) -> str: + additional_flags = "" + if self.use_ninja.value != "ON": + additional_flags = f"-j {os.cpu_count()}" + if platform.system() == "Windows": + additional_flags += f" --config {self.build_type.value}" + return additional_flags + def is_enabled(self, option_name: str) -> bool: if option_name not in self.bool_options: raise ValueError(f"Expected {option_name} to be a minifi option") @@ -54,6 +73,28 @@ class MinifiOptions: def set_cmake_override(self, cmake_override: str): self.cmake_override = cmake_override + def save_option_state(self): + options_dict = dict() + for option_name in self.bool_options: + options_dict[option_name] = self.bool_options[option_name].value + options_dict[self.use_ninja.name] = self.use_ninja.value + + with open(pathlib.Path(__file__).parent / "option_state.json", "w") as f: + json.dump(options_dict, f) + + def load_option_state(self): + state_path = pathlib.Path(__file__).parent / "option_state.json" + if not pathlib.Path.exists(state_path): + return + with open(state_path, "r") as f: + options_dict = json.load(f) + for option_name in options_dict: + if option_name not in self.bool_options: + continue + self.bool_options[option_name].value = options_dict[option_name] + if self.use_ninja.name in options_dict: + self.use_ninja.value = options_dict[self.use_ninja.name] + def parse_minifi_options(path: str, cmake_options: str, package_manager: PackageManager, cmake_cache_dir: str): cmake_cache_path = cmake_parser.create_cmake_cache(path, cmake_options, cmake_cache_dir, package_manager) diff --git a/bootstrap/system_dependency.py b/bootstrap/system_dependency.py index 9e91b6bd3..74a864f74 100644 --- a/bootstrap/system_dependency.py +++ b/bootstrap/system_dependency.py @@ -36,7 +36,7 @@ def _create_system_dependencies(minifi_options: MinifiOptions) -> Dict[str, Set[ system_dependencies['libpng'] = {'libpng'} if minifi_options.is_enabled("ENABLE_GPS"): system_dependencies['gpsd'] = {'gpsd'} - if minifi_options.is_enabled("ENABLE_COAP"): + if minifi_options.is_enabled("ENABLE_COAP") or minifi_options.is_enabled("ENABLE_SQL"): system_dependencies['automake'] = {'automake'} system_dependencies['autoconf'] = {'autoconf'} system_dependencies['libtool'] = {'libtool'}