@@ -101,7 +101,7 @@ class InstallOptions:
101101
102102    # Libxml2 
103103    libxml2_src_dir : str  =  "<third-party-src-dir>/libxml2" 
104-     libxml2_build_type : str  =  "Release"  # purposefully does not depend on mrdocs-build-type because we only need the executable 
104+     libxml2_build_type : str  =  "Release"    # purposefully does not depend on mrdocs-build-type because we only need the executable 
105105    libxml2_build_dir : str  =  "<libxml2-src-dir>/build/<libxml2-build-type:lower><\" -\" :if(cc)><cc:basename>" 
106106    libxml2_install_dir : str  =  "<libxml2-src-dir>/install/<libxml2-build-type:lower><\" -\" :if(cc)><cc:basename>" 
107107    libxml2_repo : str  =  "https://github.com/GNOME/libxml2" 
@@ -115,6 +115,9 @@ class InstallOptions:
115115    generate_vscode_run_configs : bool  =  field (default_factory = lambda : os .name  !=  "nt" )
116116    generate_vs_run_configs : bool  =  field (default_factory = lambda : os .name  ==  "nt" )
117117
118+     # Information to create pretty printer configs 
119+     generate_pretty_printer_configs : bool  =  field (default_factory = lambda : running_from_mrdocs_source_dir ())
120+ 
118121    # Command line arguments 
119122    non_interactive : bool  =  False 
120123    refresh_all : bool  =  False 
@@ -167,6 +170,7 @@ class InstallOptions:
167170    "generate_clion_run_configs" : "Whether to generate run configurations for CLion." ,
168171    "generate_vscode_run_configs" : "Whether to generate run configurations for Visual Studio Code." ,
169172    "generate_vs_run_configs" : "Whether to generate run configurations for Visual Studio." ,
173+     "generate_pretty_printer_configs" : "Whether to generate pretty printer configurations for debuggers." ,
170174    "non_interactive" : "Whether to use all default options without interactive prompts." ,
171175    "refresh_all" : "Call the command to refresh dependencies for all configurations" ,
172176    "force_rebuild" : "Whether to force a rebuild of all dependencies, even if they are already built." ,
@@ -514,7 +518,7 @@ def cmake_workflow(self, src_dir, build_type, build_dir, install_dir, extra_args
514518            elif  extra_arg .startswith ('-DCMAKE_CXX_FLAGS=' ):
515519                cxx_flags  +=  ' '  +  extra_arg .split ('=' , 1 )[1 ]
516520                extra_args_remove_idx .append (i )
517-             elif  i  !=  0  and  extra_args [i - 1 ].strip () ==  '-D' :
521+             elif  i  !=  0  and  extra_args [i   -   1 ].strip () ==  '-D' :
518522                if  extra_arg .startswith ('CMAKE_C_FLAGS=' ):
519523                    cc_flags  +=  ' '  +  extra_arg .split ('=' , 1 )[1 ]
520524                    extra_args_remove_idx .append (i  -  1 )
@@ -553,7 +557,8 @@ def cmake_workflow(self, src_dir, build_type, build_dir, install_dir, extra_args
553557
554558        # Maybe adjust build type based on the options for the main project 
555559        if  not  self .is_abi_compatible (self .options .mrdocs_build_type , build_type ):
556-             print (f"Warning: The build type '{ build_type }  ' is not ABI compatible with the MrDocs build type '{ self .options .mrdocs_build_type }  '." )
560+             print (
561+                 f"Warning: The build type '{ build_type }  ' is not ABI compatible with the MrDocs build type '{ self .options .mrdocs_build_type }  '." )
557562            if  self .options .mrdocs_build_type .lower () ==  "debug" :
558563                # User asked for Release dependency, so we do the best we can and change it to 
559564                # an optimized debug build. 
@@ -925,7 +930,8 @@ def probe_compilers(self):
925930        shutil .rmtree (probe_dir )
926931
927932        # Print default C++ compiler path 
928-         print (f"Default C++ compiler: { self .compiler_info .get ('CMAKE_CXX_COMPILER_ID' , 'unknown' )}   ({ self .compiler_info .get ('CMAKE_CXX_COMPILER' , 'unknown' )}  )" )
933+         print (
934+             f"Default C++ compiler: { self .compiler_info .get ('CMAKE_CXX_COMPILER_ID' , 'unknown' )}   ({ self .compiler_info .get ('CMAKE_CXX_COMPILER' , 'unknown' )}  )" )
929935        print (f"Default C++ build system: { self .compiler_info .get ('CMAKE_GENERATOR' , 'unknown' )}  " )
930936
931937    @lru_cache (maxsize = 1 ) 
@@ -983,7 +989,6 @@ def probe_msvc_dev_env(self):
983989            self .env [key ] =  value 
984990        print ("MSVC development environment variables extracted successfully." )
985991
986- 
987992    @lru_cache (maxsize = 1 ) 
988993    def  is_homebrew_clang (self ):
989994        self .probe_compilers ()
@@ -1894,7 +1899,8 @@ def vs_config_type(config):
18941899                return  "default" 
18951900
18961901        def  rel_to_mrdocs_dir (script_path ):
1897-             is_subdir_of_mrdocs_src_dir  =  script_path .replace ('\\ ' , '/' ).rstrip ('/' ).startswith (self .options .mrdocs_src_dir .replace ('\\ ' , '/' ).rstrip ('/' ))
1902+             is_subdir_of_mrdocs_src_dir  =  script_path .replace ('\\ ' , '/' ).rstrip ('/' ).startswith (
1903+                 self .options .mrdocs_src_dir .replace ('\\ ' , '/' ).rstrip ('/' ))
18981904            if  is_subdir_of_mrdocs_src_dir :
18991905                return  os .path .relpath (script_path , self .options .mrdocs_src_dir )
19001906            return  script_path 
@@ -1981,7 +1987,6 @@ def vs_config_project_target(config):
19811987        with  open (tasks_path , "w" ) as  f :
19821988            json .dump (tasks_data , f , indent = 4 )
19831989
1984- 
19851990    def  generate_vscode_run_configs (self , configs ):
19861991        if  not  self .prompt_option ("generate_run_configs" ):
19871992            return 
@@ -2477,6 +2482,56 @@ def generate_run_configs(self):
24772482            print ("Generating Visual Studio run configurations for MrDocs..." )
24782483            self .generate_visual_studio_run_configs (configs )
24792484
2485+     def  generate_pretty_printer_configs (self ):
2486+         # Generate a .lldbinit file (if it doesn't exist) for LLDB pretty printers 
2487+         lldbinit_path  =  os .path .join (self .options .mrdocs_src_dir , ".lldbinit" )
2488+         if  not  os .path .exists (lldbinit_path ):
2489+             home_lldbinit_path  =  os .path .join (os .path .expanduser ("~" ), ".lldbinit" )
2490+             lldbinit_enabled  =  False 
2491+             if  os .path .exists (home_lldbinit_path ):
2492+                 with  open (home_lldbinit_path , "r" ) as  f :
2493+                     home_lldbinit_content  =  f .read ()
2494+                 if  "settings set target.load-cwd-lldbinit true"  in  home_lldbinit_content :
2495+                     lldbinit_enabled  =  True 
2496+             # The content of the file should be: 
2497+             # # echo 'settings set target.load-cwd-lldbinit true' >> ~/.lldbinit 
2498+             # command script import /Users/alandefreitas/Documents/Code/C++/mrdocs/build/third-party/llvm-project/llvm/utils/lldbDataFormatters.py 
2499+             lldbinit_content  =  f"# LLDB pretty printers for MrDocs\n " 
2500+             lldbinit_content  +=  f"# Generated by bootstrap.py\n " 
2501+             lldbinit_content  +=  f"# \n " 
2502+             if  not  lldbinit_enabled :
2503+                 lldbinit_content  +=  f"# To enable this file, also add this to your ~/.lldbinit file:\n " 
2504+                 lldbinit_content  +=  f"# settings set target.load-cwd-lldbinit true\n " 
2505+                 lldbinit_content  +=  f"# \n " 
2506+                 lldbinit_content  +=  f"# Or run the following bash command:\n " 
2507+                 lldbinit_content  +=  f"# echo 'settings set target.load-cwd-lldbinit true' >> ~/.lldbinit\n " 
2508+                 lldbinit_content  +=  f"# \n " 
2509+             lldbinit_content  +=  f"command script import { os .path .join (self .options .llvm_src_dir , 'llvm' , 'utils' , 'lldbDataFormatters.py' ).replace (os .sep , '/' )} \n " 
2510+             with  open (lldbinit_path , "w" ) as  f :
2511+                 f .write (lldbinit_content )
2512+             print (f"Generated LLDB pretty printer configuration at '{ lldbinit_path }  '" )
2513+         else :
2514+             print (f"LLDB pretty printer configuration already exists at '{ lldbinit_path }  ', skipping generation." )
2515+ 
2516+         # Do the same logic for GDB pretty printers, generating a .gdbinit file 
2517+         # The pretty printer is at: .../third-party/llvm-project/llvm/utils/gdb-scripts/prettyprinters.py 
2518+         gdbinit_path  =  os .path .join (self .options .mrdocs_src_dir , ".gdbinit" )
2519+         if  not  os .path .exists (gdbinit_path ):
2520+             gdbinit_content  =  f"# GDB pretty printers for MrDocs\n " 
2521+             gdbinit_content  +=  f"# Generated by bootstrap.py\n " 
2522+             gdbinit_content  +=  f"# \n " 
2523+             gdbinit_content  +=  f"python\n " 
2524+             gdbinit_content  +=  f"import sys\n " 
2525+             gdbinit_content  +=  f"sys.path.insert(0, '{ os .path .join (self .options .llvm_src_dir , 'llvm' , 'utils' , 'gdb-scripts' , 'prettyprinters.py' ).replace (os .sep , '/' )}  ')\n " 
2526+             gdbinit_content  +=  f"from prettyprinters import register_pretty_printers\n " 
2527+             gdbinit_content  +=  f"register_pretty_printers(gdb)\n " 
2528+             gdbinit_content  +=  f"end\n " 
2529+             with  open (gdbinit_path , "w" ) as  f :
2530+                 f .write (gdbinit_content )
2531+             print (f"Generated GDB pretty printer configuration at '{ gdbinit_path }  '" )
2532+         else :
2533+             print (f"GDB pretty printer configuration already exists at '{ gdbinit_path }  ', skipping generation." )
2534+ 
24802535    def  install_all (self ):
24812536        self .check_compilers ()
24822537        self .probe_msvc_dev_env ()
@@ -2493,8 +2548,8 @@ def install_all(self):
24932548        self .install_mrdocs ()
24942549        if  self .prompt_option ("generate_run_configs" ):
24952550            self .generate_run_configs ()
2496-         else :
2497-             print ( "Skipping run configurations generation as per user preference." )
2551+         if   self . prompt_option ( "generate_pretty_printer_configs" ) :
2552+             self . generate_pretty_printer_configs ( )
24982553
24992554    def  refresh_all (self ):
25002555        # 1. Read all configurations in .vscode/launch.json 
@@ -2519,7 +2574,8 @@ def refresh_all(self):
25192574
25202575        # 2. Filter configurations whose name starts with "MrDocs Bootstrap Refresh (" 
25212576        bootstrap_refresh_configs  =  [
2522-             cfg  for  cfg  in  configs  if  cfg .get ("name" , "" ).startswith ("MrDocs Bootstrap Refresh (" ) and  cfg .get ("name" , "" ).endswith (")" )
2577+             cfg  for  cfg  in  configs  if 
2578+             cfg .get ("name" , "" ).startswith ("MrDocs Bootstrap Refresh (" ) and  cfg .get ("name" , "" ).endswith (")" )
25232579        ]
25242580        if  not  bootstrap_refresh_configs :
25252581            print ("No bootstrap refresh configurations found in Visual Studio Code launch configurations." )
0 commit comments