From d6f2bec890db6f798824e30eb337fbe1df48c00d Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Thu, 15 Feb 2024 13:06:34 +0100 Subject: [PATCH] VS: Improve performance of parsing project file VS doesn't handle string parsing very well, so having all the files in one property slows down VS a lot when loading the projects. Splitting the files up into per-directory properties brings down project processing times from 20 seconds to 1 second (on my machine). --- methods.py | 63 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/methods.py b/methods.py index 69d8df1d72f..4bb82637a19 100644 --- a/methods.py +++ b/methods.py @@ -1142,6 +1142,11 @@ def generate_vs_project(env, original_args, project_name="godot"): # This lets projects be regenerated even if there are build errors. filtered_args.pop("vsproj_gen_only", None) + # This flag allows users to regenerate only the props file without touching the sln or vcxproj files. + # This preserves any customizations users have done to the solution, while still updating the file list + # and build commands. + filtered_args.pop("vsproj_props_only", None) + # The "progress" option is ignored as the current compilation progress indication doesn't work in VS filtered_args.pop("progress", None) @@ -1334,27 +1339,30 @@ def generate_vs_project(env, original_args, project_name="godot"): set_sources = set(sources_active) set_others = set(others_active) for file in headers: + base_path = os.path.dirname(file).replace("\\", "_") all_items.append(f'') all_items.append( - f" true" + f" true" ) all_items.append("") if file in set_headers: activeItems.append(file) for file in sources: + base_path = os.path.dirname(file).replace("\\", "_") all_items.append(f'') all_items.append( - f" true" + f" true" ) all_items.append("") if file in set_sources: activeItems.append(file) for file in others: + base_path = os.path.dirname(file).replace("\\", "_") all_items.append(f'') all_items.append( - f" true" + f" true" ) all_items.append("") if file in set_others: @@ -1368,7 +1376,18 @@ def generate_vs_project(env, original_args, project_name="godot"): break condition = "'$(GodotConfiguration)|$(GodotPlatform)'=='" + vsconf + "'" - properties.append(";" + ";".join(activeItems) + ";") + itemlist = {} + for item in activeItems: + key = os.path.dirname(item).replace("\\", "_") + if not key in itemlist: + itemlist[key] = [item] + else: + itemlist[key] += [item] + + for x in itemlist.keys(): + properties.append( + ";%s;" % (x, ";".join(itemlist[x]), x) + ) output = f'bin\\godot{env["PROGSUFFIX"]}' props_template = open("misc/msvs/props.template", "r").read() @@ -1406,6 +1425,8 @@ def generate_vs_project(env, original_args, project_name="godot"): cmd_rebuild = [ "vsproj=yes", + "vsproj_props_only=yes", + "vsproj_gen_only=no", f"vsproj_name={project_name}", ] + common_build_postfix @@ -1523,25 +1544,27 @@ def generate_vs_project(env, original_args, project_name="godot"): section1 = sorted(section1) section2 = sorted(section2) - proj_template = open("misc/msvs/vcxproj.template", "r").read() + if not get_bool(original_args, "vsproj_props_only", False): + proj_template = open("misc/msvs/vcxproj.template", "r").read() + proj_template = proj_template.replace("%%UUID%%", proj_uuid) + proj_template = proj_template.replace("%%CONFS%%", "\n ".join(configurations)) + proj_template = proj_template.replace("%%IMPORTS%%", "\n ".join(imports)) + proj_template = proj_template.replace("%%DEFAULT_ITEMS%%", "\n ".join(all_items)) + proj_template = proj_template.replace("%%PROPERTIES%%", "\n ".join(properties)) - proj_template = proj_template.replace("%%UUID%%", proj_uuid) - proj_template = proj_template.replace("%%CONFS%%", "\n ".join(configurations)) - proj_template = proj_template.replace("%%IMPORTS%%", "\n ".join(imports)) - proj_template = proj_template.replace("%%DEFAULT_ITEMS%%", "\n ".join(all_items)) - proj_template = proj_template.replace("%%PROPERTIES%%", "\n ".join(properties)) + with open(f"{project_name}.vcxproj", "w") as f: + f.write(proj_template) - with open(f"{project_name}.vcxproj", "w") as f: - f.write(proj_template) + if not get_bool(original_args, "vsproj_props_only", False): + sln_template = open("misc/msvs/sln.template", "r").read() + sln_template = sln_template.replace("%%NAME%%", project_name) + sln_template = sln_template.replace("%%UUID%%", proj_uuid) + sln_template = sln_template.replace("%%SLNUUID%%", sln_uuid) + sln_template = sln_template.replace("%%SECTION1%%", "\n ".join(section1)) + sln_template = sln_template.replace("%%SECTION2%%", "\n ".join(section2)) - sln_template = open("misc/msvs/sln.template", "r").read() - sln_template = sln_template.replace("%%NAME%%", project_name) - sln_template = sln_template.replace("%%UUID%%", proj_uuid) - sln_template = sln_template.replace("%%SLNUUID%%", sln_uuid) - sln_template = sln_template.replace("%%SECTION1%%", "\n ".join(section1)) - sln_template = sln_template.replace("%%SECTION2%%", "\n ".join(section2)) - with open(f"{project_name}.sln", "w") as f: - f.write(sln_template) + with open(f"{project_name}.sln", "w") as f: + f.write(sln_template) if get_bool(original_args, "vsproj_gen_only", True): sys.exit()