]>
Commit | Line | Data |
---|---|---|
1 | #!/usr/bin/env python3 | |
2 | ||
3 | # Allow direct execution | |
4 | import os | |
5 | import sys | |
6 | ||
7 | sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) | |
8 | ||
9 | import platform | |
10 | ||
11 | from PyInstaller.__main__ import run as run_pyinstaller | |
12 | ||
13 | from devscripts.utils import read_version | |
14 | ||
15 | OS_NAME, MACHINE, ARCH = sys.platform, platform.machine().lower(), platform.architecture()[0][:2] | |
16 | if MACHINE in ('x86', 'x86_64', 'amd64', 'i386', 'i686'): | |
17 | MACHINE = 'x86' if ARCH == '32' else '' | |
18 | ||
19 | ||
20 | def main(): | |
21 | opts, version = parse_options(), read_version() | |
22 | ||
23 | onedir = '--onedir' in opts or '-D' in opts | |
24 | if not onedir and '-F' not in opts and '--onefile' not in opts: | |
25 | opts.append('--onefile') | |
26 | ||
27 | name, final_file = exe(onedir) | |
28 | print(f'Building yt-dlp v{version} for {OS_NAME} {platform.machine()} with options {opts}') | |
29 | print('Remember to update the version using "devscripts/update-version.py"') | |
30 | if not os.path.isfile('yt_dlp/extractor/lazy_extractors.py'): | |
31 | print('WARNING: Building without lazy_extractors. Run ' | |
32 | '"devscripts/make_lazy_extractors.py" to build lazy extractors', file=sys.stderr) | |
33 | print(f'Destination: {final_file}\n') | |
34 | ||
35 | opts = [ | |
36 | f'--name={name}', | |
37 | '--icon=devscripts/logo.ico', | |
38 | '--upx-exclude=vcruntime140.dll', | |
39 | '--noconfirm', | |
40 | '--additional-hooks-dir=yt_dlp/__pyinstaller', | |
41 | *opts, | |
42 | 'yt_dlp/__main__.py', | |
43 | ] | |
44 | ||
45 | print(f'Running PyInstaller with {opts}') | |
46 | run_pyinstaller(opts) | |
47 | set_version_info(final_file, version) | |
48 | ||
49 | ||
50 | def parse_options(): | |
51 | # Compatibility with older arguments | |
52 | opts = sys.argv[1:] | |
53 | if opts[0:1] in (['32'], ['64']): | |
54 | if ARCH != opts[0]: | |
55 | raise Exception(f'{opts[0]}bit executable cannot be built on a {ARCH}bit system') | |
56 | opts = opts[1:] | |
57 | return opts | |
58 | ||
59 | ||
60 | def exe(onedir): | |
61 | """@returns (name, path)""" | |
62 | name = '_'.join(filter(None, ( | |
63 | 'yt-dlp', | |
64 | {'win32': '', 'darwin': 'macos'}.get(OS_NAME, OS_NAME), | |
65 | MACHINE, | |
66 | ))) | |
67 | return name, ''.join(filter(None, ( | |
68 | 'dist/', | |
69 | onedir and f'{name}/', | |
70 | name, | |
71 | OS_NAME == 'win32' and '.exe' | |
72 | ))) | |
73 | ||
74 | ||
75 | def version_to_list(version): | |
76 | version_list = version.split('.') | |
77 | return list(map(int, version_list)) + [0] * (4 - len(version_list)) | |
78 | ||
79 | ||
80 | def set_version_info(exe, version): | |
81 | if OS_NAME == 'win32': | |
82 | windows_set_version(exe, version) | |
83 | ||
84 | ||
85 | def windows_set_version(exe, version): | |
86 | from PyInstaller.utils.win32.versioninfo import ( | |
87 | FixedFileInfo, | |
88 | StringFileInfo, | |
89 | StringStruct, | |
90 | StringTable, | |
91 | VarFileInfo, | |
92 | VarStruct, | |
93 | VSVersionInfo, | |
94 | ) | |
95 | ||
96 | try: | |
97 | from PyInstaller.utils.win32.versioninfo import SetVersion | |
98 | except ImportError: # Pyinstaller >= 5.8 | |
99 | from PyInstaller.utils.win32.versioninfo import write_version_info_to_executable as SetVersion | |
100 | ||
101 | version_list = version_to_list(version) | |
102 | suffix = MACHINE and f'_{MACHINE}' | |
103 | SetVersion(exe, VSVersionInfo( | |
104 | ffi=FixedFileInfo( | |
105 | filevers=version_list, | |
106 | prodvers=version_list, | |
107 | mask=0x3F, | |
108 | flags=0x0, | |
109 | OS=0x4, | |
110 | fileType=0x1, | |
111 | subtype=0x0, | |
112 | date=(0, 0), | |
113 | ), | |
114 | kids=[ | |
115 | StringFileInfo([StringTable('040904B0', [ | |
116 | StringStruct('Comments', 'yt-dlp%s Command Line Interface' % suffix), | |
117 | StringStruct('CompanyName', 'https://github.com/yt-dlp'), | |
118 | StringStruct('FileDescription', 'yt-dlp%s' % (MACHINE and f' ({MACHINE})')), | |
119 | StringStruct('FileVersion', version), | |
120 | StringStruct('InternalName', f'yt-dlp{suffix}'), | |
121 | StringStruct('LegalCopyright', 'pukkandan.ytdlp@gmail.com | UNLICENSE'), | |
122 | StringStruct('OriginalFilename', f'yt-dlp{suffix}.exe'), | |
123 | StringStruct('ProductName', f'yt-dlp{suffix}'), | |
124 | StringStruct( | |
125 | 'ProductVersion', f'{version}{suffix} on Python {platform.python_version()}'), | |
126 | ])]), VarFileInfo([VarStruct('Translation', [0, 1200])]) | |
127 | ] | |
128 | )) | |
129 | ||
130 | ||
131 | if __name__ == '__main__': | |
132 | main() |