1#!/usr/bin/env python3
2# Copyright (c) 2016-2019 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
6import os
7import re
8import argparse
9from shutil import copyfile
10
11SOURCE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src'))
12DEFAULT_PLATFORM_TOOLSET = R'v141'
13
14libs = [
15    'libbitcoin_cli',
16    'libbitcoin_common',
17    'libbitcoin_crypto',
18    'libbitcoin_server',
19    'libbitcoin_util',
20    'libbitcoin_wallet_tool',
21    'libbitcoin_wallet',
22    'libbitcoin_zmq',
23    'bench_bitcoin',
24    'libtest_util',
25]
26
27ignore_list = [
28]
29
30lib_sources = {}
31
32
33def 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
53def set_common_properties(toolset):
54    with open(os.path.join(SOURCE_DIR, '../build_msvc/common.init.vcxproj'), 'r', encoding='utf-8') as rfile:
55        s = rfile.read()
56        s = re.sub('<PlatformToolset>.*?</PlatformToolset>', '<PlatformToolset>'+toolset+'</PlatformToolset>', s)
57    with open(os.path.join(SOURCE_DIR, '../build_msvc/common.init.vcxproj'), 'w', encoding='utf-8',newline='\n') as wfile:
58        wfile.write(s)
59
60def main():
61    parser = argparse.ArgumentParser(description='Bitcoin-core msbuild configuration initialiser.')
62    parser.add_argument('-toolset', nargs='?',help='Optionally sets the msbuild platform toolset, e.g. v142 for Visual Studio 2019.'
63         ' default is %s.'%DEFAULT_PLATFORM_TOOLSET)
64    args = parser.parse_args()
65    if args.toolset:
66        set_common_properties(args.toolset)
67
68    for makefile_name in os.listdir(SOURCE_DIR):
69        if 'Makefile' in makefile_name:
70            parse_makefile(os.path.join(SOURCE_DIR, makefile_name))
71    for key, value in lib_sources.items():
72        vcxproj_filename = os.path.abspath(os.path.join(os.path.dirname(__file__), key, key + '.vcxproj'))
73        content = ''
74        for source_filename, object_filename in value:
75            content += '    <ClCompile Include="..\\..\\src\\' + source_filename + '">\n'
76            content += '      <ObjectFileName>$(IntDir)' + object_filename + '</ObjectFileName>\n'
77            content += '    </ClCompile>\n'
78        with open(vcxproj_filename + '.in', 'r', encoding='utf-8') as vcxproj_in_file:
79            with open(vcxproj_filename, 'w', encoding='utf-8') as vcxproj_file:
80                vcxproj_file.write(vcxproj_in_file.read().replace(
81                    '@SOURCE_FILES@\n', content))
82    copyfile(os.path.join(SOURCE_DIR,'../build_msvc/bitcoin_config.h'), os.path.join(SOURCE_DIR, 'config/bitcoin-config.h'))
83    copyfile(os.path.join(SOURCE_DIR,'../build_msvc/libsecp256k1_config.h'), os.path.join(SOURCE_DIR, 'secp256k1/src/libsecp256k1-config.h'))
84
85if __name__ == '__main__':
86    main()
87