Skip to content

Commit 502cfbd

Browse files
committed
build: bootstrap generates debug configurations
1 parent 77cea7c commit 502cfbd

File tree

2 files changed

+154
-2
lines changed

2 files changed

+154
-2
lines changed

CMakeUserPresets.json.example

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,6 @@
210210
"Clang_ROOT": "$env{HOME}/Developer/cpp-libs/llvm-project/install/debwithopt",
211211
"duktape_ROOT": "$env{HOME}/Developer/cpp-libs/duktape/install/debwithopt",
212212
"Duktape_ROOT": "$env{HOME}/Developer/cpp-libs/duktape/install/debwithopt",
213-
"fmt_ROOT": "$env{HOME}/Developer/cpp-libs/fmt/install/debwithopt",
214213
"libxml2_ROOT": "$env{HOME}/Developer/cpp-libs/libxml2/install/release",
215214
"LibXml2_ROOT": "$env{HOME}/Developer/cpp-libs/libxml2/install/release",
216215
"MRDOCS_BUILD_TESTS": true,

bootstrap.py

Lines changed: 154 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ class InstallOptions:
8989
llvm_repo: str = "https://github.com/llvm/llvm-project.git"
9090
llvm_commit: str = "dd7a3d4d798e30dfe53b5bbbbcd9a23c24ea1af9"
9191

92+
# Information to create run configurations
93+
generate_run_configs: bool = field(default_factory=lambda: running_from_mrdocs_source_dir())
94+
jetbrains_run_config_dir: str = "<mrdocs-src-dir>/.run"
95+
boost_src_dir: str = "<mrdocs-src-dir>/../boost"
96+
9297
# Meta
9398
non_interactive: bool = False
9499

@@ -125,6 +130,9 @@ class InstallOptions:
125130
"llvm_install_dir": "Directory where LLVM will be installed.",
126131
"llvm_repo": "URL of the LLVM project repository to clone.",
127132
"llvm_commit": "Specific commit hash of LLVM to checkout.",
133+
"generate_run_configs": "Whether to generate run configurations for IDEs.",
134+
"jetbrains_run_config_dir": "Directory where JetBrains run configurations will be stored.",
135+
"boost_src_dir": "Directory where the source files of the Boost libraries are located.",
128136
"non_interactive": "Whether to use all default options without interactive prompts."
129137
}
130138

@@ -797,16 +805,161 @@ def install_mrdocs(self):
797805
else:
798806
print(f"\nMrDocs has been successfully installed in {self.options.mrdocs_install_dir}.\n")
799807

808+
809+
def generate_clion_run_configs(self, configs):
810+
import xml.etree.ElementTree as ET
811+
812+
# Generate CLion run configurations for MrDocs
813+
# For each configuration, we create an XML file in <mrdocs-src-dir>/.run
814+
# named <config-name>.run.xml
815+
run_dir = os.path.join(self.options.mrdocs_src_dir, ".run")
816+
os.makedirs(run_dir, exist_ok=True)
817+
for config in configs:
818+
config_name = config["name"]
819+
run_config_path = os.path.join(run_dir, f"{config_name}.run.xml")
820+
root = ET.Element("component", name="ProjectRunConfigurationManager")
821+
config = ET.SubElement(root, "configuration", {
822+
"default": "false",
823+
"name": config["name"],
824+
"type": "CMakeRunConfiguration",
825+
"factoryName": "Application",
826+
"PROGRAM_PARAMS": " ".join(config["args"]),
827+
"REDIRECT_INPUT": "false",
828+
"ELEVATE": "false",
829+
"USE_EXTERNAL_CONSOLE": "false",
830+
"EMULATE_TERMINAL": "false",
831+
"PASS_PARENT_ENVS_2": "true",
832+
"PROJECT_NAME": "MrDocs",
833+
"TARGET_NAME": config["target"],
834+
"CONFIG_NAME": self.options.mrdocs_preset_name or "debug",
835+
"RUN_TARGET_PROJECT_NAME": "MrDocs",
836+
"RUN_TARGET_NAME": config["target"]
837+
})
838+
method = ET.SubElement(config, "method", v="2")
839+
ET.SubElement(method, "option", name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask", enabled="true")
840+
tree = ET.ElementTree(root)
841+
tree.write(run_config_path, encoding="utf-8", xml_declaration=False)
842+
843+
def generate_visual_studio_run_configs(self, configs):
844+
# Visual Studio launch configs are stored in .vs/launch.vs.json
845+
vs_dir = os.path.join(self.options.mrdocs_src_dir, ".vs")
846+
os.makedirs(vs_dir, exist_ok=True)
847+
launch_path = os.path.join(vs_dir, "launch.vs.json")
848+
849+
# Load existing configs if present
850+
if os.path.exists(launch_path):
851+
with open(launch_path, "r") as f:
852+
launch_data = json.load(f)
853+
else:
854+
launch_data = {"version": "0.2.1", "configurations": []}
855+
856+
# Build a dict for quick lookup by name
857+
configs_by_name = {cfg.get("name"): cfg for cfg in launch_data.get("configurations", [])}
858+
859+
for config in configs:
860+
new_cfg = {
861+
"name": config["name"],
862+
"type": "default",
863+
"project": "MrDocs",
864+
"projectTarget": config["target"],
865+
"args": config["args"],
866+
"cwd": self.options.mrdocs_build_dir,
867+
"env": {},
868+
"stopAtEntry": False
869+
}
870+
# Replace or add
871+
configs_by_name[config["name"]] = new_cfg
872+
873+
# Write back all configs
874+
launch_data["configurations"] = list(configs_by_name.values())
875+
with open(launch_path, "w") as f:
876+
json.dump(launch_data, f, indent=4)
877+
878+
def generate_run_configs(self):
879+
# Configurations using MrDocs executable
880+
configs = [{
881+
"name": "MrDocs Version",
882+
"target": "mrdocs",
883+
"args": ["--version"]
884+
}, {
885+
"name": "MrDocs Help",
886+
"target": "mrdocs",
887+
"args": ["--help"]
888+
}]
889+
890+
# Configuration to run unit tests
891+
if self.options.mrdocs_build_tests:
892+
configs.append({
893+
"name": "MrDocs Unit Tests",
894+
"target": "mrdocs-test",
895+
"args": [
896+
'--unit=true'
897+
]
898+
})
899+
900+
# Configurations to Update/Test/Create test fixtures
901+
for verb in ["update", "test", "create"]:
902+
for generator in ["adoc", "html", "xml"]:
903+
configs.append({
904+
"name": f"MrDocs {verb.title()} Test Fixtures ({generator.upper()})",
905+
"target": "mrdocs-test",
906+
"args": [
907+
f'"{self.options.mrdocs_src_dir}/test-files/golden-tests"',
908+
'--unit=false',
909+
f'--action={verb}',
910+
f'--generator={generator}',
911+
f'--addons="{self.options.mrdocs_src_dir}/share/mrdocs/addons"',
912+
f'--stdlib-includes="{self.options.llvm_install_dir}/include/c++/v1"',
913+
f'--stdlib-includes="{self.options.llvm_install_dir}/lib/clang/20/include"',
914+
f'--libc-includes="{self.options.mrdocs_src_dir}/share/mrdocs/headers/libc-stubs"',
915+
'--log-level=warn'
916+
]
917+
})
918+
919+
self.prompt_option("boost_src_dir")
920+
if self.options.boost_src_dir and os.path.exists(self.options.boost_src_dir):
921+
boost_libs = os.path.join(self.options.boost_src_dir, 'libs')
922+
if os.path.exists(boost_libs):
923+
for lib in os.listdir(boost_libs):
924+
mrdocs_config = os.path.join(boost_libs, lib, 'doc', 'mrdocs.yml')
925+
if os.path.exists(mrdocs_config):
926+
print(f"Generating run configuration for Boost library '{lib}'")
927+
configs.append({
928+
"name": f"Boost.{lib.title()} Documentation",
929+
"target": "mrdocs",
930+
"args": [
931+
'"../CMakeLists.txt"',
932+
f'--config="{self.options.boost_src_dir}/libs/{lib}/doc/mrdocs.yml"',
933+
f'--output="{self.options.boost_src_dir}/libs/{lib}/doc/modules/reference/pages"',
934+
f'--generator=adoc',
935+
f'--addons="{self.options.mrdocs_src_dir}/share/mrdocs/addons"',
936+
f'--stdlib-includes="{self.options.llvm_install_dir}/include/c++/v1"',
937+
f'--stdlib-includes="{self.options.llvm_install_dir}/lib/clang/20/include"',
938+
f'--libc-includes="{self.options.mrdocs_src_dir}/share/mrdocs/headers/libc-stubs"',
939+
f'--tagfile=reference.tag.xml',
940+
'--multipage=true',
941+
'--concurrency=32',
942+
'--log-level=debug'
943+
]
944+
})
945+
else:
946+
print(f"Warning: Boost source directory '{self.options.boost_src_dir}' does not contain 'libs' directory. Skipping Boost documentation target generation.")
947+
948+
self.generate_clion_run_configs(configs)
949+
self.generate_visual_studio_run_configs(configs)
950+
800951
def install_all(self):
801952
self.check_tools()
802953
self.setup_mrdocs_dir()
803954
self.setup_third_party_dir()
804955
self.install_duktape()
805-
if self.options.mrdocs_build_tests:
956+
if self.prompt_option("mrdocs_build_tests"):
806957
self.install_libxml2()
807958
self.install_llvm()
808959
self.create_cmake_presets()
809960
self.install_mrdocs()
961+
if self.prompt_option("generate_run_configs"):
962+
self.generate_run_configs()
810963

811964
def get_command_line_args():
812965
"""

0 commit comments

Comments
 (0)