332 lines
13 KiB
Python
332 lines
13 KiB
Python
import vs_props_writer, vs_vcxproj_modifier
|
|
import os, enum, sys, argparse
|
|
|
|
#region Constant Declarations
|
|
|
|
class BuildType(enum.Enum):
|
|
Standalone: str = "standalone"
|
|
Plugin: str = "plugin"
|
|
|
|
class VirtoolsVersion(enum.Enum):
|
|
V21 = '21'
|
|
V25 = '25'
|
|
V30 = '30'
|
|
V35 = '35'
|
|
V40 = '40'
|
|
V50 = '50'
|
|
|
|
VT_HEADER_PATH: dict[VirtoolsVersion, str] = {
|
|
VirtoolsVersion.V21: 'Include',
|
|
VirtoolsVersion.V25: 'Virtools_SDK\\Includes',
|
|
VirtoolsVersion.V30: 'Sdk\\Includes',
|
|
VirtoolsVersion.V35: 'Sdk\\Includes',
|
|
VirtoolsVersion.V40: 'Sdk\\Includes',
|
|
VirtoolsVersion.V50: 'Sdk\\Includes'
|
|
}
|
|
|
|
VT_LIB_PATH: dict[VirtoolsVersion, str] = {
|
|
VirtoolsVersion.V21: 'Lib',
|
|
VirtoolsVersion.V25: 'Virtools_SDK\\Lib',
|
|
VirtoolsVersion.V30: 'Sdk\\Lib',
|
|
VirtoolsVersion.V35: 'Sdk\\Lib\\Win32\\Release',
|
|
VirtoolsVersion.V40: 'Sdk\\Lib\\Win32\\Release',
|
|
VirtoolsVersion.V50: 'Sdk\\Lib\\Win32\\Release'
|
|
}
|
|
|
|
VT_STANDALONE_ATTACHED_LIBS: dict[VirtoolsVersion, str] = {
|
|
VirtoolsVersion.V21: "VxMath.lib;CK2.lib",
|
|
VirtoolsVersion.V25: "VxMath.lib;CK2.lib",
|
|
VirtoolsVersion.V30: "VxMath.lib;CK2.lib",
|
|
VirtoolsVersion.V35: "VxMath.lib;CK2.lib",
|
|
VirtoolsVersion.V40: "VxMath.lib;CK2.lib",
|
|
VirtoolsVersion.V50: "VxMath.lib;CK2.lib"
|
|
}
|
|
VT_PLUGIN_ATTACHED_LIBS: dict[VirtoolsVersion, str] = {
|
|
VirtoolsVersion.V21: "",
|
|
VirtoolsVersion.V25: "",
|
|
VirtoolsVersion.V30: "VxMath.lib;DllEditor.lib;CK2.lib;InterfaceControls.lib;CKControls.lib",
|
|
VirtoolsVersion.V35: "VxMath.lib;DllEditor.lib;CK2.lib;InterfaceControls.lib;CKControls.lib",
|
|
VirtoolsVersion.V40: "VxMath.lib;DllEditor.lib;CK2.lib;InterfaceControls.lib;CKControls.lib",
|
|
VirtoolsVersion.V50: "VxMath.lib;DllEditor.lib;CK2.lib;InterfaceControls.lib;CKControls.lib"
|
|
}
|
|
|
|
VT_PLUGIN_MACROS: dict[VirtoolsVersion, str] = {
|
|
VirtoolsVersion.V21: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE",
|
|
VirtoolsVersion.V25: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE",
|
|
VirtoolsVersion.V30: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE",
|
|
VirtoolsVersion.V35: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE",
|
|
VirtoolsVersion.V40: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE",
|
|
VirtoolsVersion.V50: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE"
|
|
}
|
|
VT_STANDALONE_MACROS: dict[VirtoolsVersion, str] = {
|
|
VirtoolsVersion.V21: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG",
|
|
VirtoolsVersion.V25: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG",
|
|
VirtoolsVersion.V30: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG",
|
|
VirtoolsVersion.V35: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG",
|
|
VirtoolsVersion.V40: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG",
|
|
VirtoolsVersion.V50: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;VIRTOOLS_USER_SDK"
|
|
}
|
|
|
|
VT_PLUGIN_SUPPORTED_VER: set[VirtoolsVersion] = set((
|
|
VirtoolsVersion.V30,
|
|
VirtoolsVersion.V35,
|
|
VirtoolsVersion.V40,
|
|
VirtoolsVersion.V50,
|
|
))
|
|
VT_STANDALONE_SUPPORTED_VER: set[VirtoolsVersion] = set((
|
|
VirtoolsVersion.V21,
|
|
VirtoolsVersion.V25,
|
|
VirtoolsVersion.V30,
|
|
VirtoolsVersion.V35,
|
|
VirtoolsVersion.V40,
|
|
VirtoolsVersion.V50,
|
|
))
|
|
|
|
VT_EXECUTABLE_DEV: dict[VirtoolsVersion, str] = {
|
|
VirtoolsVersion.V25: "Dev.exe",
|
|
VirtoolsVersion.V30: "devr.exe",
|
|
VirtoolsVersion.V35: "devr.exe",
|
|
VirtoolsVersion.V40: "devr.exe",
|
|
VirtoolsVersion.V50: "devr.exe"
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Assist Functions
|
|
|
|
def get_project_root() -> str:
|
|
# build project root path and return
|
|
return os.path.dirname(os.path.dirname(__file__))
|
|
|
|
def check_project_root() -> None:
|
|
"""
|
|
Check whether this script is executed in correct folder.
|
|
|
|
If check failed, this function will exit script, otherwise, return directly.
|
|
"""
|
|
project_root: str = get_project_root()
|
|
# check whether have readme file
|
|
if not os.path.isfile(os.path.join(project_root, 'README.md')):
|
|
print('Fail to get project root folder. This script may be placed at wrong location.')
|
|
sys.exit(1)
|
|
|
|
def validate_combination(build_type: BuildType, vt_version: VirtoolsVersion) -> None:
|
|
"""
|
|
Check whether the given combination of build type and Virtools version is OK.
|
|
|
|
Some combination of build type and Virtools version is invalid.
|
|
For example, because Virtools 2.5 do not have UI register so plugin build type is not available in Virtools 2.1
|
|
|
|
If validation failed, this function will exit script, otherwise, return directly.
|
|
"""
|
|
# fetch result
|
|
is_okey: bool
|
|
match(build_type):
|
|
case BuildType.Standalone:
|
|
is_okey = vt_version in VT_STANDALONE_SUPPORTED_VER
|
|
case BuildType.Plugin:
|
|
is_okey = vt_version in VT_PLUGIN_SUPPORTED_VER
|
|
# output result
|
|
if not is_okey:
|
|
print(f'The combination of "{build_type.value}" and "{vt_version.value}" is not compatible currently.')
|
|
sys.exit(1)
|
|
|
|
def ensure_trailing_slash(given_path: str) -> str:
|
|
"""
|
|
Ensure given path is end with slash or backslash.
|
|
|
|
@param given_path The path for checking.
|
|
@return The path with trailing slash or backslash,
|
|
or the given path self if it already has.
|
|
"""
|
|
# make sure return value is end with slash or backslash
|
|
if given_path[-1] != '\\' or given_path[-1] != '/':
|
|
return given_path + '\\'
|
|
else:
|
|
return given_path
|
|
|
|
def get_header_path(vt_version: VirtoolsVersion, vt_root: str) -> str:
|
|
return os.path.join(vt_root, VT_HEADER_PATH[vt_version])
|
|
|
|
def get_lib_path(vt_version: VirtoolsVersion, vt_root: str) -> str:
|
|
return os.path.join(vt_root, VT_LIB_PATH[vt_version])
|
|
|
|
def get_attached_libs(build_type: BuildType, vt_version: VirtoolsVersion) -> str:
|
|
match(build_type):
|
|
case BuildType.Standalone:
|
|
return VT_STANDALONE_ATTACHED_LIBS[vt_version]
|
|
case BuildType.Plugin:
|
|
return VT_PLUGIN_ATTACHED_LIBS[vt_version]
|
|
|
|
def get_macros(build_type: BuildType, vt_version: VirtoolsVersion) -> str:
|
|
match(build_type):
|
|
case BuildType.Standalone:
|
|
return VT_STANDALONE_MACROS[vt_version]
|
|
case BuildType.Plugin:
|
|
return VT_PLUGIN_MACROS[vt_version]
|
|
|
|
def get_executable_dev(vt_version: VirtoolsVersion, vt_root: str) -> str:
|
|
"""
|
|
Return the path to executable Virtools Dev according to given Virtools version.
|
|
|
|
Usually it is `Dev.exe` or `devr.exe`.
|
|
|
|
@param vt_version The version of Virtools.
|
|
@param vt_root The path to Virtools root folder.
|
|
@return The path to executable Virtools Dev.
|
|
"""
|
|
return os.path.join(vt_root, VT_EXECUTABLE_DEV[vt_version])
|
|
|
|
def get_output_path(build_type: BuildType, vt_root: str) -> str:
|
|
"""
|
|
Get the output path for plugin.
|
|
|
|
For plugin build type, script will try output binary into `InterfacePlugins` folder in Virtools environment.
|
|
For standalone build type, script will try output binary in the root path of Virtools.
|
|
|
|
@param vt_version The version of Virtools.
|
|
@param vt_root The path to Virtools root folder.
|
|
@return The path where the compiled project binary will be placed.
|
|
"""
|
|
# fetch output path by build type
|
|
ret: str
|
|
match(build_type):
|
|
case BuildType.Standalone:
|
|
ret = vt_root
|
|
case BuildType.Plugin:
|
|
ret = os.path.join(vt_root, 'InterfacePlugins')
|
|
# make sure return value is end with slash or backslash
|
|
return ensure_trailing_slash(ret)
|
|
|
|
def get_binary_suffix(build_type: BuildType) -> str:
|
|
match(build_type):
|
|
case BuildType.Standalone:
|
|
return 'exe'
|
|
case BuildType.Plugin:
|
|
return 'dll'
|
|
|
|
def get_module_define(build_type: BuildType) -> str:
|
|
match(build_type):
|
|
case BuildType.Standalone:
|
|
return ''
|
|
case BuildType.Plugin:
|
|
return 'SuperScriptMaterializer.def'
|
|
|
|
#endregion
|
|
|
|
def main() -> None:
|
|
# ========== Check Environment ==========
|
|
check_project_root()
|
|
|
|
# ========== Accept User Input ==========
|
|
# build args parser
|
|
parser = argparse.ArgumentParser(description='Project Configuration Maker')
|
|
parser.add_argument(
|
|
'-b', '--build-type', required=True, action='store', dest='build_type', choices=tuple(item.value for item in BuildType),
|
|
help='The build type of project.'
|
|
)
|
|
parser.add_argument(
|
|
'-t', '--virtools-version', required=True, action='store', dest='virtools_version', choices=tuple(item.value for item in VirtoolsVersion),
|
|
help='The Virtools version you picked.'
|
|
)
|
|
parser.add_argument(
|
|
'-p', '--virtools-path', required=True, action='store', dest='virtools_path',
|
|
help='''
|
|
The path to the root folder of you picked Virtools version where you can find "Dev.exe".
|
|
If you select Virtools 2.1, this path should be the root folder of GitHub project "doyaGu/Virtools-SDK-2.1".
|
|
'''
|
|
)
|
|
parser.add_argument(
|
|
'-a', '--sqlite-amalgamation-path', required=True, action='store', dest='sqlite_amalgamation_path',
|
|
help='The path to downloaded sqlite amalgamation folder where you can find "sqlite3.h"'
|
|
)
|
|
parser.add_argument(
|
|
'-d', '--sqlite-dll-path', required=True, action='store', dest='sqlite_dll_path',
|
|
help='The path to downloaded sqlite dll folder where you can find "sqlite3.dll" and "sqlite3.lib" you just built a few minutes ago.'
|
|
)
|
|
# parse arguments
|
|
args = parser.parse_args()
|
|
|
|
# ========== Analyse Arguments ==========
|
|
# extract arguments
|
|
arg_virtools_version: VirtoolsVersion = VirtoolsVersion(args.virtools_version)
|
|
arg_build_type: BuildType = BuildType(args.build_type)
|
|
arg_virtools_path: str = args.virtools_path
|
|
arg_sqlite_amalgamation_path: str = args.sqlite_amalgamation_path
|
|
arg_sqlite_dll_path: str = args.sqlite_dll_path
|
|
|
|
# validate the combination
|
|
validate_combination(arg_build_type, arg_virtools_version)
|
|
|
|
# build macros values
|
|
# virtools version and build type macro
|
|
macro_virtools_ver: str = f'VIRTOOLS_{arg_virtools_version.value}'
|
|
macro_virtools_build_type: str = f'VIRTOOLS_{arg_build_type.value.upper()}'
|
|
# virtools header and lib
|
|
macro_virtools_header_path: str = get_header_path(arg_virtools_version, arg_virtools_path)
|
|
macro_virtools_lib_path: str = get_lib_path(arg_virtools_version, arg_virtools_path)
|
|
macro_virtools_attcahed_libs: str = get_attached_libs(arg_build_type, arg_virtools_version)
|
|
# sqlite header and lib
|
|
macro_sqlite_header_path: str = arg_sqlite_amalgamation_path
|
|
macro_sqlite_lib_path: str = arg_sqlite_dll_path
|
|
# output path macro
|
|
macro_virtools_output_path: str = get_output_path(arg_build_type, arg_virtools_path)
|
|
# virtools used macros
|
|
macro_virtools_macros: str = get_macros(arg_build_type, arg_virtools_version)
|
|
# misc
|
|
macro_virtools_binary_suffix: str = get_binary_suffix(arg_build_type)
|
|
macro_virtools_module_define: str = get_module_define(arg_build_type)
|
|
|
|
# ========== Create Property File ==========
|
|
|
|
props = vs_props_writer.VsPropsWriter()
|
|
|
|
# write subsystem
|
|
match(arg_build_type):
|
|
case BuildType.Standalone:
|
|
props.SetSubSystem(vs_props_writer.VsSubSystem.Console)
|
|
case BuildType.Plugin:
|
|
props.SetSubSystem(vs_props_writer.VsSubSystem.Windows)
|
|
|
|
# write macro and misc
|
|
# build type distinguish macro
|
|
props.AddMacro('VIRTOOLS_VER', macro_virtools_ver)
|
|
props.AddMacro('VIRTOOLS_BUILD_TYPE', macro_virtools_build_type)
|
|
# header and libs
|
|
props.AddMacro('VIRTOOLS_HEADER_PATH', macro_virtools_header_path)
|
|
props.AddMacro('VIRTOOLS_LIB_PATH', macro_virtools_lib_path)
|
|
props.AddMacro('VIRTOOLS_ATTACHED_LIBS', macro_virtools_attcahed_libs)
|
|
props.AddMacro('SQLITE_HEADER_PATH', macro_sqlite_header_path)
|
|
props.AddMacro('SQLITE_LIB_PATH', macro_sqlite_lib_path)
|
|
# output
|
|
props.AddMacro('VIRTOOLS_OUTPUT_PATH', macro_virtools_output_path)
|
|
# essential build macro
|
|
props.AddMacro('VIRTOOLS_MACROS', macro_virtools_macros)
|
|
# misc macro
|
|
props.AddMacro('VIRTOOLS_BINARY_SUFFIX', macro_virtools_binary_suffix)
|
|
props.AddMacro('VIRTOOLS_MODULE_DEFINE', macro_virtools_module_define)
|
|
|
|
# output
|
|
props.Generate(os.path.join(get_project_root(), 'Virtools.props'))
|
|
|
|
# ========== Modify ==========
|
|
vcxproj = vs_vcxproj_modifier.VsVcxprojModifier(
|
|
os.path.join(get_project_root(), 'SuperScriptMaterializer/SuperScriptMaterializer.vcxproj')
|
|
)
|
|
|
|
# write build type
|
|
match(arg_build_type):
|
|
case BuildType.Standalone:
|
|
vcxproj.SetBuildType(vcxproj.BUILDTYPE_EXE)
|
|
case BuildType.Plugin:
|
|
vcxproj.SetBuildType(vcxproj.BUILDTYPE_DLL)
|
|
|
|
# output
|
|
vcxproj.Modify()
|
|
|
|
# ========== Done ==========
|
|
print("Configuration OK!")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|