/ build_msvc / msvc-autogen.py
msvc-autogen.py
1 #!/usr/bin/env python3 2 # Copyright (c) 2016-2022 The Bitcoin Core developers 3 # Distributed under the MIT software license, see the accompanying 4 # file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 6 import os 7 import re 8 import argparse 9 from shutil import copyfile 10 11 SOURCE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src')) 12 DEFAULT_PLATFORM_TOOLSET = R'v143' 13 14 libs = [ 15 'libbitcoin_cli', 16 'libbitcoin_common', 17 'libbitcoin_crypto', 18 'libbitcoin_node', 19 'libbitcoin_util', 20 'libbitcoin_wallet_tool', 21 'libbitcoin_wallet', 22 'libbitcoin_zmq', 23 'bench_bitcoin', 24 'libtest_util', 25 ] 26 27 ignore_list = [ 28 ] 29 30 lib_sources = {} 31 32 33 def parse_makefile(makefile): 34 with open(makefile, 'r', encoding='utf-8') as file: 35 current_lib = '' 36 for line in file.read().splitlines(): 37 if current_lib: 38 source = line.split()[0] 39 if source.endswith('.cpp') and not source.startswith('$') and source not in ignore_list: 40 source_filename = source.replace('/', '\\') 41 object_filename = source.replace('/', '_')[:-4] + ".obj" 42 lib_sources[current_lib].append((source_filename, object_filename)) 43 if not line.endswith('\\'): 44 current_lib = '' 45 continue 46 for lib in libs: 47 _lib = lib.replace('-', '_') 48 if re.search(_lib + '.*_SOURCES \\= \\\\', line): 49 current_lib = lib 50 lib_sources[current_lib] = [] 51 break 52 53 def parse_config_into_btc_config(): 54 def find_between( s, first, last ): 55 try: 56 start = s.index( first ) + len( first ) 57 end = s.index( last, start ) 58 return s[start:end] 59 except ValueError: 60 return "" 61 62 config_info = [] 63 with open(os.path.join(SOURCE_DIR,'../configure.ac'), encoding="utf8") as f: 64 for line in f: 65 if line.startswith("define"): 66 config_info.append(find_between(line, "(_", ")")) 67 68 config_info = [c for c in config_info if not c.startswith("COPYRIGHT_HOLDERS")] 69 70 config_dict = dict(item.split(", ") for item in config_info) 71 config_dict["PACKAGE_VERSION"] = f"\"{config_dict['CLIENT_VERSION_MAJOR']}.{config_dict['CLIENT_VERSION_MINOR']}.{config_dict['CLIENT_VERSION_BUILD']}\"" 72 version = config_dict["PACKAGE_VERSION"].strip('"') 73 config_dict["PACKAGE_STRING"] = f"\"Bitcoin Core {version}\"" 74 75 with open(os.path.join(SOURCE_DIR,'../build_msvc/bitcoin_config.h.in'), "r", encoding="utf8") as template_file: 76 template = template_file.readlines() 77 78 for index, line in enumerate(template): 79 header = "" 80 if line.startswith("#define"): 81 header = line.split(" ")[1] 82 if header in config_dict: 83 template[index] = line.replace("$", f"{config_dict[header]}") 84 85 with open(os.path.join(SOURCE_DIR,'../build_msvc/bitcoin_config.h'), "w", encoding="utf8") as btc_config: 86 btc_config.writelines(template) 87 88 def set_properties(vcxproj_filename, placeholder, content): 89 with open(vcxproj_filename + '.in', 'r', encoding='utf-8') as vcxproj_in_file: 90 with open(vcxproj_filename, 'w', encoding='utf-8') as vcxproj_file: 91 vcxproj_file.write(vcxproj_in_file.read().replace(placeholder, content)) 92 93 def main(): 94 parser = argparse.ArgumentParser(description='Bitcoin-core msbuild configuration initialiser.') 95 parser.add_argument('-toolset', nargs='?', default=DEFAULT_PLATFORM_TOOLSET, 96 help='Optionally sets the msbuild platform toolset, e.g. v143 for Visual Studio 2022.' 97 ' default is %s.'%DEFAULT_PLATFORM_TOOLSET) 98 args = parser.parse_args() 99 set_properties(os.path.join(SOURCE_DIR, '../build_msvc/common.init.vcxproj'), '@TOOLSET@', args.toolset) 100 101 for makefile_name in os.listdir(SOURCE_DIR): 102 if 'Makefile' in makefile_name: 103 parse_makefile(os.path.join(SOURCE_DIR, makefile_name)) 104 for key, value in lib_sources.items(): 105 vcxproj_filename = os.path.abspath(os.path.join(os.path.dirname(__file__), key, key + '.vcxproj')) 106 content = '' 107 for source_filename, object_filename in value: 108 content += ' <ClCompile Include="..\\..\\src\\' + source_filename + '">\n' 109 content += ' <ObjectFileName>$(IntDir)' + object_filename + '</ObjectFileName>\n' 110 content += ' </ClCompile>\n' 111 set_properties(vcxproj_filename, '@SOURCE_FILES@\n', content) 112 parse_config_into_btc_config() 113 copyfile(os.path.join(SOURCE_DIR,'../build_msvc/bitcoin_config.h'), os.path.join(SOURCE_DIR, 'config/bitcoin-config.h')) 114 115 if __name__ == '__main__': 116 main()