Skip to content

Commit ec40b90

Browse files
CMAKE generator : allow options other than variables
Prep step for migrating other builders to `master-migration`
1 parent e94265a commit ec40b90

File tree

3 files changed

+135
-4
lines changed

3 files changed

+135
-4
lines changed

configuration/steps/generators/base/generator.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ def generate(self) -> list[str]:
4545
Generates the command as a list of strings.
4646
"""
4747
result = self.base_cmd.copy()
48-
for flag in sorted(self.flags, key=lambda x: x.name):
49-
result.append(flag.as_cmd_arg())
48+
# arg can be "" for False values in CMakeFlagOption so we skip those
49+
# flag options don't have a False counterpart nor can be assigned right-hand side values .e.g --trace, --trace-expand
50+
result += [
51+
arg
52+
for flag in sorted(self.flags, key=lambda x: x.name)
53+
if (arg := flag.as_cmd_arg())
54+
]
5055
return result

configuration/steps/generators/cmake/options.py

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,25 @@ def __str__(self):
3434
return f"CMAKE_{self.value}"
3535

3636

37+
class CMAKEWARN(StrEnum):
38+
DEVELOPER_WARNINGS = "dev"
39+
DEPRECATED_WARNINGS = "deprecated"
40+
WARNINGS_AS_ERRORS = "error"
41+
42+
def __str__(self):
43+
return self.value
44+
45+
46+
class CMAKEDEBUG(StrEnum):
47+
TRACE = "trace"
48+
TRACE_EXPAND = "trace-expand"
49+
DEBUG_OUTPUT = "debug-output"
50+
DEBUG_FIND = "debug-find"
51+
52+
def __str__(self):
53+
return self.value
54+
55+
3756
class PLUGIN(StrEnum):
3857
"""
3958
Enumerates valid plugin options for MariaDB's CMake configuration.
@@ -132,9 +151,9 @@ class BuildConfig(StrEnum):
132151
MYSQL_RELEASE = "mysql_release"
133152

134153

135-
class CMakeOption(Option):
154+
class CMakeVariableOption(Option):
136155
"""
137-
Represents a CMake option in the form `-D<name>=<value>`.
156+
Represents a `-DNAME=VALUE` variable option
138157
"""
139158

140159
def __init__(self, name: StrEnum, value: Union[str, bool]):
@@ -147,3 +166,76 @@ def __init__(self, name: StrEnum, value: Union[str, bool]):
147166

148167
def as_cmd_arg(self) -> str:
149168
return f"-D{self.name}={self.value}"
169+
170+
171+
class CMakeFlagOption(Option):
172+
"""
173+
Represents a flag-like option (e.g., --trace, --trace-expand).
174+
"""
175+
176+
def __init__(self, name: StrEnum, value: bool):
177+
if isinstance(value, bool):
178+
value = f"--{name}" if value else ""
179+
else:
180+
raise ValueError(
181+
f"Flag option '{type(name)}-{name}' must be initialized with a boolean value at creation time. Got {type(value)} instead."
182+
)
183+
super().__init__(name, value)
184+
185+
def as_cmd_arg(self) -> str:
186+
return f"{self.value}"
187+
188+
189+
class CMakeWarnOption(Option):
190+
"""
191+
Represents a -W option (e.g., -Wno-dev, -Wdeprecated).
192+
"""
193+
194+
def __init__(self, name: StrEnum, value: bool):
195+
if isinstance(value, bool):
196+
value = f"-W{'' if value else 'no-'}{name}"
197+
else:
198+
raise ValueError(
199+
f"Flag option '{type(name)}-{name}' must be initialized with a boolean value at creation time. Got {type(value)} instead."
200+
)
201+
super().__init__(name, value)
202+
203+
def as_cmd_arg(self) -> str:
204+
return f"{self.value}"
205+
206+
207+
class CMakeOption:
208+
"""
209+
Factory class to create CMake options based on the type of the input object.
210+
"""
211+
212+
HANDLERS = (
213+
(
214+
(
215+
CMAKE,
216+
PLUGIN,
217+
WITH,
218+
WITHOUT,
219+
OTHER,
220+
BuildType,
221+
BuildConfig,
222+
),
223+
CMakeVariableOption,
224+
),
225+
(
226+
(CMAKEDEBUG,),
227+
CMakeFlagOption,
228+
),
229+
(
230+
(CMAKEWARN,),
231+
CMakeWarnOption,
232+
),
233+
)
234+
235+
def __new__(cls, obj: StrEnum, value: Union[str, bool]) -> Option:
236+
for base_classes, handler_class in cls.HANDLERS:
237+
if isinstance(obj, base_classes):
238+
return handler_class(obj, value)
239+
raise ValueError(
240+
f"No handler found for object of type {type(obj)}. Cannot create a CMake option."
241+
)

configuration/test/unit/test_cmake_generator.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from configuration.steps.generators.cmake.generator import CMakeGenerator
66
from configuration.steps.generators.cmake.options import (
77
CMAKE,
8+
CMAKEDEBUG,
9+
CMAKEWOPT,
810
PLUGIN,
911
WITH,
1012
BuildConfig,
@@ -37,6 +39,38 @@ def test_initialization_with_flags(self):
3739
],
3840
)
3941

42+
def test_all_handlers(self):
43+
"""Test that all CMakeOption handlers work correctly."""
44+
flags = [
45+
CMakeOption(CMAKE.BUILD_TYPE, BuildType.RELWITHDEBUG),
46+
CMakeOption(CMAKE.INSTALL_PREFIX, "/usr/local"),
47+
CMakeOption(PLUGIN.ARCHIVE_STORAGE_ENGINE, True),
48+
CMakeOption(WITH.ASAN, True),
49+
CMakeOption(CMAKEWOPT.DEVELOPER_WARNINGS, False),
50+
CMakeOption(CMAKEDEBUG.TRACE, False),
51+
CMakeOption(CMAKEDEBUG.DEBUG_OUTPUT, True),
52+
CMakeOption(CMAKEWOPT.DEPRECATED_WARNINGS, True),
53+
CMakeOption(CMAKEWOPT.WARNINGS_AS_ERRORS, False),
54+
]
55+
generator = CMakeGenerator(flags=flags)
56+
command = generator.generate()
57+
self.assertEqual(
58+
command,
59+
[
60+
"cmake",
61+
"-S",
62+
".",
63+
"-DCMAKE_BUILD_TYPE=RelWithDebInfo",
64+
"-DCMAKE_INSTALL_PREFIX=/usr/local",
65+
"-DPLUGIN_ARCHIVE=YES",
66+
"-DWITH_ASAN=ON",
67+
"--debug-output",
68+
"-Wdeprecated",
69+
"-Wno-dev",
70+
"-Wno-error",
71+
],
72+
)
73+
4074
def test_append_flags_successful(self):
4175
"""
4276
Test that flags are appended successfully.

0 commit comments

Comments
 (0)