imporve nuitka and options

This commit is contained in:
shenjack 2023-06-11 15:19:23 +08:00
parent b6f1fcad3c
commit 341ca29b00
3 changed files with 68 additions and 31 deletions

View File

@ -7,7 +7,7 @@
import traceback import traceback
from io import StringIO from io import StringIO
from dataclasses import dataclass from dataclasses import dataclass
from typing import get_type_hints, Type, List, Union, Dict, Any, Callable, Tuple, Optional, TYPE_CHECKING from typing import get_type_hints, Type, List, Union, Dict, Any, Callable, Tuple, Optional, TYPE_CHECKING, Iterable
__all__ = ['get_type_hints_', __all__ = ['get_type_hints_',
'Options', 'Options',
@ -25,6 +25,18 @@ def get_type_hints_(cls: Type):
return get_type_hints(cls, globalns={}) return get_type_hints(cls, globalns={})
def to_str_value_(value: Any) -> Any:
"""递归的将输入值的每一个非 builtin type 转换成 str"""
if isinstance(value, (str, bytes, bytearray, int, float, bool, type(None))):
return value
elif isinstance(value, dict):
return {k: to_str_value_(v) for k, v in value.items()}
elif isinstance(value, (list, Iterable)):
return [to_str_value_(v) for v in value]
else:
return str(value)
class OptionsError(Exception): class OptionsError(Exception):
""" option 的错误基类""" """ option 的错误基类"""
@ -57,7 +69,7 @@ class Options:
""" """
创建一个新的 Options 的时候的配置 创建一个新的 Options 的时候的配置
如果存在 init 方法 会在设置完 kwargs 之后运行子类的 init 方法 如果存在 init 方法 会在设置完 kwargs 之后运行子类的 init 方法
:param kwargs: :param kwargs: 需要设置的选项
""" """
if TYPE_CHECKING: if TYPE_CHECKING:
self._options: Dict[str, Union[Callable, object]] = {} self._options: Dict[str, Union[Callable, object]] = {}
@ -90,6 +102,7 @@ class Options:
""" 如果子类定义了这个函数,则会在 __init__ 之后调用这个函数 """ 如果子类定义了这个函数,则会在 __init__ 之后调用这个函数
返回值为 True 则不会调用 load_file 函数 返回值为 True 则不会调用 load_file 函数
""" """
#
def load_file(self) -> bool: def load_file(self) -> bool:
"""如果子类定义了这个函数,则会在 __init__ 和 init 之后再调用这个函数 """如果子类定义了这个函数,则会在 __init__ 和 init 之后再调用这个函数
@ -124,6 +137,14 @@ class Options:
raise OptionNotFound(f'Option {option} is not found in {self.name}') from None raise OptionNotFound(f'Option {option} is not found in {self.name}') from None
return values return values
def str_option(self) -> Dict[str, Union[str, Any]]:
"""
获取配置类的所有配置 并将所有非 BuiltInType 的值转换为 str
:return:
"""
raw_option = self.option()
return to_str_value_(raw_option)
def format(self, text: str) -> str: def format(self, text: str) -> str:
""" """
使用自己的选项给输入的字符串替换内容 使用自己的选项给输入的字符串替换内容
@ -154,7 +175,7 @@ class Options:
max_len_value_t = 1 max_len_value_t = 1
option_list = [] option_list = []
for key, value in options.items(): for key, value in options.items():
value_t = value if isinstance(value, Type) else type(value) # 判定这个类型 是不是 基本类型 value_t = type(value) if isinstance(value, type(value)) else type(value) # 判定这个类型 是不是 基本类型
max_len_key = max(max_len_key, len(key)) max_len_key = max(max_len_key, len(key))
max_len_value = max(max_len_value, len(str(value))) max_len_value = max(max_len_value, len(str(value)))
max_len_value_t = max(max_len_value_t, len(str(value_t))) max_len_value_t = max(max_len_value_t, len(str(value_t)))
@ -171,12 +192,13 @@ class Options:
option_len = max(value[1], len('Option')) option_len = max(value[1], len('Option'))
value_len = max(value[2], len('Value')) value_len = max(value[2], len('Value'))
value_type_len = max(value[3], len('Value Type')) value_type_len = max(value[3], len('Value Type'))
cache.write(f"| Option{' '*(option_len-3)}| Value{' '*(value_len-2)}| Value Type{' '*(value_type_len-7)}|\n") cache.write(
cache.write(f'|:{"-" * (option_len+3)}|:{"-" * (value_len+3)}|:{"-" * (value_type_len + 3)}|\n') f"| Option{' ' * (option_len - 3)}| Value{' ' * (value_len - 2)}| Value Type{' ' * (value_type_len - 7)}|\n")
cache.write(f'|:{"-" * (option_len + 3)}|:{"-" * (value_len + 3)}|:{"-" * (value_type_len + 3)}|\n')
for option, value, value_t in value[0]: for option, value, value_t in value[0]:
cache.write(f"| `{option}`{' '* (option_len - len(option))} " cache.write(f"| `{option}`{' ' * (option_len - len(option))} "
f"| `{value}`{' '* (value_len - len(str(value)))} " f"| `{value}`{' ' * (value_len - len(str(value)))} "
f"| `{value_t}`{' '* (value_type_len - len(str(value_t)))} |\n") f"| `{value_t}`{' ' * (value_type_len - len(str(value_t)))} |\n")
result = cache.getvalue() result = cache.getvalue()
cache.close() cache.close()
return result return result

View File

@ -15,6 +15,10 @@
- `api.types` - `api.types`
- 添加 `Version` (`libs.MCDR.version.Version`) - 添加 `Version` (`libs.MCDR.version.Version`)
- `Difficult_Rocket.api.types.Options`
- `str_option`
- 获取一个所有键、值都是 builtin 类型的字典
- 可以用于写入文件
### 修复 Bug ### 修复 Bug

View File

@ -14,10 +14,12 @@ import platform
import traceback import traceback
import subprocess import subprocess
from typing import Tuple, Dict
from pathlib import Path from pathlib import Path
from libs.utils import nuitka from libs.utils import nuitka
if __name__ == '__main__': if __name__ == '__main__':
compiler = nuitka.CompilerHelper() compiler = nuitka.CompilerHelper()
@ -41,26 +43,32 @@ if __name__ == '__main__':
sys.argv.remove('--output') sys.argv.remove('--output')
sys.argv.remove(compiler.output_path) sys.argv.remove(compiler.output_path)
# 检测 --no-pyglet-opt 参数
pyglet_optimizations = True pyglet_optimizations = True
if pyglet_optimizations: if pyglet_optimizations and '--no-pyglet-opt' not in sys.argv:
compiler.no_follow_import += [f'pyglet.app.{x}' for x in ['win32', 'xlib', 'cocoa']]
compiler.no_follow_import += [f'pyglet.input.{x}' for x in ['win32', 'linux', 'macos']]
compiler.no_follow_import += [f'pyglet.libs.{x}' for x in ['win32', 'x11', 'wayland', 'darwin', 'egl', 'headless']]
compiler.no_follow_import += [f'pyglet.window.{x}' for x in ['win32', 'xlib', 'cocoa', 'headless']]
compiler.no_follow_import += [f'pyglet.canvas.{x}' for x in ['win32', 'xlib', 'xlib_vidmoderstore', 'cocoa', 'headless']]
compiler.no_follow_import += [f'pyglet.gl.{x}' for x in ['win32', 'xlib', 'cocoa', 'headless']]
mult_plat_libs = ['app', 'input', 'libs', 'window', 'canvas', 'gl']
if platform.system() == "Windows": if platform.system() == "Windows":
compiler.no_follow_import.append('pyglet.libs.darwin') for lib in mult_plat_libs:
compiler.no_follow_import.append('pyglet.libs.x11') compiler.no_follow_import.remove(f'pyglet.{lib}.win32')
compiler.no_follow_import.append('pyglet.window.xlib')
compiler.no_follow_import.append('pyglet.window.cocoa')
compiler.no_follow_import.append('pyglet.window.headless')
elif platform.system() == "Darwin":
compiler.no_follow_import.append('pyglet.libs.win32')
compiler.no_follow_import.append('pyglet.libs.x11')
compiler.no_follow_import.append('pyglet.window.win32')
compiler.no_follow_import.append('pyglet.window.xlib')
compiler.no_follow_import.append('pyglet.window.headless')
elif platform.system() == "Linux": elif platform.system() == "Linux":
compiler.no_follow_import.append('pyglet.libs.win32') for lib in mult_plat_libs:
compiler.no_follow_import.append('pyglet.libs.darwin') for name in ('xlib', 'x11', 'wayland', 'egl'):
compiler.no_follow_import.append('pyglet.window.win32') if f'pyglet.{lib}.{name}' in compiler.no_follow_import:
compiler.no_follow_import.append('pyglet.window.cocoa') compiler.no_follow_import.remove(f'pyglet.{lib}.{name}')
compiler.no_follow_import.append('pyglet.window.headless') compiler.no_follow_import.remove('pyglet.canvas.xlib_vidmoderstore')
elif platform.system() == "Darwin":
for lib in mult_plat_libs:
for name in ('cocoa', 'darwin', 'macos'):
if f'pyglet.{lib}.{name}' in compiler.no_follow_import:
compiler.no_follow_import.remove(f'pyglet.{lib}.{name}')
print(compiler.output_path) print(compiler.output_path)
@ -88,7 +96,7 @@ if __name__ == '__main__':
print('Compile Done!') print('Compile Done!')
print(f'Compile Time: {time.time_ns() - start_time} ns ({(time.time_ns() - start_time) / 1000_000_000} s)') print(f'Compile Time: {time.time_ns() - start_time} ns ({(time.time_ns() - start_time) / 1000_000_000} s)')
if is_github: if is_github:
# 去除无用字体文件 # 去除无用字体文件 (其实现在也不会打包字体文件了 因为 git lfs 没宽带了)
try: try:
shutil.rmtree(compiler.output_path / 'DR.dist/libs/fonts' / 'Fira_Code', ignore_errors=True) shutil.rmtree(compiler.output_path / 'DR.dist/libs/fonts' / 'Fira_Code', ignore_errors=True)
shutil.rmtree(compiler.output_path / 'DR.dist/libs/fonts' / 'scientifica', ignore_errors=True) shutil.rmtree(compiler.output_path / 'DR.dist/libs/fonts' / 'scientifica', ignore_errors=True)
@ -107,21 +115,24 @@ if __name__ == '__main__':
file_path = os.path.join(path, file) file_path = os.path.join(path, file)
dist_zip.write(file_path) dist_zip.write(file_path)
print('Zip Done!') print('Zip Done!')
elif platform.system() == 'Windows': else:
dist_dir_size = 0 dist_dir_size = 0
dist_file_size: Dict[str, Tuple[int, float]] = {}
for path, sub_paths, sub_files in os.walk(compiler.output_path / 'DR.dist'): for path, sub_paths, sub_files in os.walk(compiler.output_path / 'DR.dist'):
for file in sub_files: for file in sub_files:
file_path = os.path.join(path, file) file_path = os.path.join(path, file)
dist_dir_size += os.path.getsize(file_path) dist_dir_size += os.path.getsize(file_path)
exec_size = os.path.getsize(compiler.output_path / 'DR.dist' / 'DR.exe') # 排除不需要记录的文件
if any(x in file_path for x in ('configs', 'libs', 'textures')):
continue
dist_file_size[file_path] = (os.path.getsize(file_path), os.path.getsize(file_path) / 1024 / 1024)
compile_data = {'compile_time_ns': time.time_ns() - start_time, compile_data = {'compile_time_ns': time.time_ns() - start_time,
'compile_time_s': (time.time_ns() - start_time) / 1000_000_000, 'compile_time_s': (time.time_ns() - start_time) / 1000_000_000,
'dist_size': dist_dir_size, 'dist_size': dist_dir_size,
'dist_size_mb': dist_dir_size / 1024 / 1024, 'dist_size_mb': dist_dir_size / 1024 / 1024,
'exec_size': exec_size, 'compiler_data': compiler.str_option(),
'exec_size_mb': exec_size / 1024 / 1024} 'dist_file_size': dist_file_size}
with open(compiler.output_path / f'../compile_data-{time.time()}.toml', 'w') as compile_data_file: with open(compiler.output_path / f'../compile_data-{time.time()}.toml', 'w') as compile_data_file:
tomlkit.dump(compile_data, compile_data_file) tomlkit.dump(compile_data, compile_data_file)
sys.exit(0) sys.exit(0)