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'}

Reply via email to