modify_vcxprojs.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #!/usr/bin/env python
  2. """
  3. Rewrite libmupdf.vcxproj:
  4. 1. insert reference to mupdf_load_system_font.c,
  5. 2. add preprocessor TOFU;TOFU_CJK_EXT
  6. Rewrite other vcxproj files to place output files into the proper directory.
  7. Run this script before compiling libmupdf.vcxproj
  8. """
  9. import os
  10. import pathlib
  11. import xml.etree.ElementTree as ET
  12. import shutil
  13. def main():
  14. os.chdir(os.path.dirname(__file__))
  15. os.chdir("..\\mupdf\\platform\\win32\\")
  16. modified_files = []
  17. default_namespace = "http://schemas.microsoft.com/developer/msbuild/2003"
  18. for filename in ["bin2coff.vcxproj", "libextract.vcxproj", "libharfbuzz.vcxproj", "libleptonica.vcxproj", "libluratech.vcxproj", "libmupdf.vcxproj", "libpkcs7.vcxproj", "libresources.vcxproj", "libtesseract.vcxproj", "libthirdparty.vcxproj"]:
  19. print(f'Processing {filename}...')
  20. tree = ET.parse(filename)
  21. ET.register_namespace("", default_namespace)
  22. ns = {'ms': default_namespace}
  23. root = tree.getroot()
  24. any_modification = False
  25. for pg in root.findall("ms:PropertyGroup", ns):
  26. condition = pg.get('Condition')
  27. if condition is not None:
  28. if condition.endswith("|Win32'"):
  29. any_modification |= update_property_group(pg, ns, 'Win32')
  30. elif condition.endswith("|x64'"):
  31. any_modification |= update_property_group(pg, ns, 'x64')
  32. if filename.endswith("libmupdf.vcxproj"):
  33. any_modification |= modify_libmupdf(root, ns)
  34. if any_modification:
  35. # backup original file
  36. backup_filename = filename + '.bak'
  37. shutil.copy(filename, backup_filename)
  38. print(f'Backup created for {filename}.')
  39. # save modified file
  40. tree.write(filename, encoding='utf-8', xml_declaration=True)
  41. print(f'Processed {filename}.')
  42. modified_files.append(filename)
  43. else:
  44. print(f'No modifications needed for {filename}.')
  45. print(f'Files modified: {modified_files}')
  46. def modify_libmupdf(root, ns):
  47. # find all ItemGroup/ClCompile
  48. modified = False
  49. cl_compile_elements = root.findall("ms:ItemGroup/ms:ClCompile", ns)
  50. # check if included Include='..\..\..\MuPDFLib\Document\mupdf_load_system_font.c'
  51. target_include = "..\\..\\..\\MuPDFLib\\Document\\mupdf_load_system_font.c"
  52. if not any(elem.get('Include') == target_include for elem in cl_compile_elements):
  53. # get first ItemGroup element
  54. first_item_group = root.find("ms:ItemGroup[ms:ClCompile]", ns)
  55. if first_item_group is not None:
  56. new_cl_compile = ET.SubElement(first_item_group, "ClCompile")
  57. new_cl_compile.set('Include', target_include)
  58. modified = True
  59. # modify ItemDefinitionGroup/ClCompile/PreprocessorDefinitions elements
  60. preprocessor_elements = root.findall("ms:ItemDefinitionGroup/ms:ClCompile/ms:PreprocessorDefinitions", ns)
  61. for elem in preprocessor_elements:
  62. # check if contains "TOFU;TOFU_CJK_EXT;"
  63. if "TOFU;TOFU_CJK_EXT;" not in elem.text:
  64. # prepend "TOFU;TOFU_CJK_EXT;"
  65. elem.text = "TOFU;TOFU_CJK_EXT;" + elem.text
  66. modified = True
  67. return modified
  68. def update_property_group(pg, ns, platform):
  69. """Update PropertyGroup / OutDir or IntDir when needed."""
  70. modified = False
  71. if platform == 'Win32':
  72. out_dir = pg.find('ms:OutDir', ns)
  73. if out_dir is not None and out_dir.text != '$(Configuration)\\':
  74. out_dir.text = '$(Configuration)\\'
  75. modified = True
  76. elif out_dir is None:
  77. ET.SubElement(pg, "OutDir").text = '$(Configuration)\\'
  78. modified = True
  79. int_dir = pg.find('ms:IntDir', ns)
  80. if int_dir is not None and int_dir.text != '$(Configuration)\\$(ProjectName)\\':
  81. int_dir.text = '$(Configuration)\\$(ProjectName)\\'
  82. modified = True
  83. elif platform == 'x64':
  84. out_dir = pg.find('ms:OutDir', ns)
  85. if out_dir is not None and out_dir.text != '$(Platform)\\$(Configuration)\\':
  86. out_dir.text = '$(Platform)\\$(Configuration)\\'
  87. modified = True
  88. elif out_dir is None:
  89. ET.SubElement(pg, "OutDir").text = '$(Platform)\\$(Configuration)\\'
  90. modified = True
  91. int_dir = pg.find('ms:IntDir', ns)
  92. if int_dir is not None and int_dir.text != '$(Platform)\\$(Configuration)\\$(ProjectName)\\':
  93. int_dir.text = '$(Platform)\\$(Configuration)\\$(ProjectName)\\'
  94. modified = True
  95. return modified
  96. if __name__ == "__main__":
  97. main()