def main(args): if iswindows: run(*('cscript.exe configure.js include={0}/include' ' include={0}/include/libxml2 lib={0}/lib prefix={0}' ' zlib=yes iconv=no'.format(PREFIX.replace(os.sep, '/')).split()), cwd='win32') for f in walk('.'): bname = os.path.basename(f) if bname.startswith('Makefile'): replace_in_file(f, '/OPT:NOWIN98', '', missing_ok=True) elif bname == 'xsltconfig.h': replace_in_file(f, '@WITH_PROFILER@', '1') run(f'"{NMAKE}" /f Makefile.msvc', cwd='win32') install_tree('libxslt', 'include') install_tree('libexslt', 'include') for f in walk('.'): if f.endswith('.dll'): install_binaries(f, 'bin') elif f.endswith('.lib'): install_binaries(f) else: env = {} if ismacos: env['PATH'] = BIN + os.pathsep + os.environ['PATH'] with ModifiedEnv(**env): simple_build('--disable-dependency-tracking --disable-static' ' --enable-shared --without-python --without-debug')
def main(args): simple_build() for path in walk(os.path.join(build_dir(), 'bin')): replace_in_file(path, build_dir(), PREFIX) for path in walk(build_dir()): if path.endswith('/autom4te.cfg'): replace_in_file(path, build_dir(), PREFIX)
def main(args): # various cherry picks from HEAD that fix regression in the latest release apply_patches('libxml2' + os.sep) if iswindows: run(*('cscript.exe configure.js include={0}/include' ' lib={0}/lib prefix={0} zlib=yes iconv=yes'.format( PREFIX.replace(os.sep, '/')).split()), cwd='win32') replace_in_file('win32/Makefile.msvc', 'iconv.lib', 'libiconv.lib') run(f'"{NMAKE}" /f Makefile.msvc', cwd='win32') install_tree('include/libxml', 'include/libxml2') for f in walk('.'): if f.endswith('.dll'): install_binaries(f, 'bin') elif f.endswith('.lib'): install_binaries(f) else: # https://gitlab.gnome.org/GNOME/libxml2/-/issues/204 replace_in_file('encoding.c', re.compile(r'\bTRUE\b'), '1') # ICU is needed to use libxml2 in qt-webengine simple_build( '--disable-dependency-tracking --disable-static --enable-shared' ' --without-python --without-debug --with-iconv={0}' ' --with-zlib={0} --with-icu'.format(PREFIX)) for path in walk(build_dir()): if path.endswith('/xml2-config'): replace_in_file(path, re.compile(b'(?m)^prefix=.+'), f'prefix={PREFIX}')
def main(args): with ModifiedEnv(PATH=BIN + os.pathsep + os.environ['PATH']): simple_build() files = set() for path in walk(os.path.join(build_dir(), 'bin')): files.add(os.path.abspath(os.path.realpath(path))) for path in walk(build_dir()): if path.endswith('/Config.pm'): files.add(os.path.abspath(os.path.realpath(path))) for path in files: replace_in_file(path, build_dir(), PREFIX, missing_ok=True)
def main(args): os.chdir('source') if iswindows: solution_build() elif ismacos: run('./runConfigureICU MacOSX --disable-samples --prefix=' + build_dir()) run('make ' + MAKEOPTS) run('make install') else: simple_build( '--prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man' ' --sbindir=/usr/bin', install_args='DESTDIR=' + build_dir(), relocate_pkgconfig=False) usr = os.path.join(build_dir(), 'usr') os.rename(os.path.join(usr, 'include'), os.path.join(build_dir(), 'include')) os.rename(os.path.join(usr, 'lib'), os.path.join(build_dir(), 'lib')) for path in walk(build_dir()): if path.endswith('.pc'): replace_in_file(path, re.compile(br'^prefix\s*=\s*/usr', flags=re.M), f'prefix={PREFIX}') shutil.rmtree(usr)
def sign_executables(env): files_to_sign = [] for path in walk(env.base): if path.lower().endswith('.exe'): files_to_sign.append(path) printf('Signing {} exe files'.format(len(files_to_sign))) sign_files(env, files_to_sign)
def freeze_python(self): print('\nFreezing python') kitty_dir = join(self.resources_dir, 'kitty') bases = ('kitty', 'kittens', 'kitty_tests') for x in bases: dest = os.path.join(self.python_stdlib, x) os.rename(os.path.join(kitty_dir, x), dest) if x == 'kitty': shutil.rmtree(os.path.join(dest, 'launcher')) os.rename(os.path.join(kitty_dir, '__main__.py'), os.path.join(self.python_stdlib, 'kitty_main.py')) shutil.rmtree(os.path.join(kitty_dir, '__pycache__')) pdir = os.path.join(dirname(self.python_stdlib), 'kitty-extensions') os.mkdir(pdir) print('Extracting extension modules from', self.python_stdlib, 'to', pdir) ext_map = extract_extension_modules(self.python_stdlib, pdir) shutil.copy(os.path.join(os.path.dirname(self_dir), 'site.py'), os.path.join(self.python_stdlib, 'site.py')) for x in bases: iv['sanitize_source_folder'](os.path.join(self.python_stdlib, x)) self.compile_py_modules() freeze_python(self.python_stdlib, pdir, self.obj_dir, ext_map, develop_mode_env_var='KITTY_DEVELOP_FROM') iv['build_frozen_launcher']([path_to_freeze_dir(), self.obj_dir]) os.rename(join(dirname(self.contents_dir), 'bin', 'kitty'), join(self.contents_dir, 'MacOS', 'kitty')) shutil.rmtree(join(dirname(self.contents_dir), 'bin')) self.fix_dependencies_in_lib(join(self.contents_dir, 'MacOS', 'kitty')) for f in walk(pdir): if f.endswith('.so') or f.endswith('.dylib'): self.fix_dependencies_in_lib(f)
def add_stdlib(self): print('\nAdding python stdlib') src = PREFIX + '/python/Python.framework/Versions/Current/lib/python' src += py_ver dest = join(self.resources_dir, 'Python', 'lib', 'python') dest += py_ver os.makedirs(dest) for x in os.listdir(src): if x in ('site-packages', 'config', 'test', 'lib2to3', 'lib-tk', 'lib-old', 'idlelib', 'plat-mac', 'plat-darwin', 'site.py'): continue x = join(src, x) if os.path.isdir(x): self.add_package_dir(x, dest) elif os.path.splitext(x)[1] in ('.so', '.py'): shutil.copy2(x, dest) dest2 = join(dest, basename(x)) if dest2.endswith('.so'): self.fix_dependencies_in_lib(dest2) target = join(self.resources_dir, 'Python', 'lib') self.remove_bytecode(target) for path in walk(target): if path.endswith('.so'): self.fix_dependencies_in_lib(path)
def main(args): os.chdir('source') if iswindows: solution_build() else: build_loc = os.getcwd() conf = ('--prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man' ' --sbindir=/usr/bin') if 'first_build_dir' in lipo_data: conf += ' --with-cross-build=' + lipo_data['first_build_dir'] simple_build(conf, install_args='DESTDIR=' + build_dir(), relocate_pkgconfig=False) usr = os.path.join(build_dir(), 'usr') os.rename(os.path.join(usr, 'include'), os.path.join(build_dir(), 'include')) os.rename(os.path.join(usr, 'lib'), os.path.join(build_dir(), 'lib')) for path in walk(build_dir()): if path.endswith('.pc'): replace_in_file(path, re.compile(br'^prefix\s*=\s*/usr', flags=re.M), f'prefix={PREFIX}') shutil.rmtree(usr) if 'first_build_dir' not in lipo_data: lipo_data['first_build_dir'] = build_loc
def main(args): # Control font hinting apply_patch('webkit_control_hinting.patch') if iswindows: return windows_build() # fix detection of python2 if islinux: replace_in_file( 'Source/cmake/WebKitCommon.cmake', 'find_package(PythonInterp 2.7.0 REQUIRED)', 'set(PYTHONINTERP_FOUND "ON")\n' 'set(PYTHON_EXECUTABLE /usr/bin/python2)' ) cmake_build( PORT='Qt', CMAKE_PREFIX_PATH='{0};{0}/qt'.format(PREFIX), override_prefix=os.path.join(build_dir(), 'qt'), library_path=True, **DISABLE_DIRECTIVES ) for path in walk(build_dir()): if path.endswith('.pri'): replace_in_file(path, build_dir(), PREFIX)
def main(args): if iswindows: with current_dir('msvc'): msbuild('Hunspell.sln', configuration='Release_dll') dll = lib = False for f in walk('.'): if os.path.basename(f) == 'libhunspell.dll': install_binaries(f, 'bin') dll = True elif os.path.basename(f) == 'libhunspell.lib': install_binaries(f, 'lib') lib = True if not dll or not lib: raise Exception('Failed to find the hunspell dlls') # from bypy.utils import run_shell # run_shell() copy_headers('src/hunspell/*.hxx', destdir='include/hunspell') copy_headers('src/hunspell/*.h', destdir='include/hunspell') copy_headers('msvc/*.h', destdir='include/hunspell') else: env = {} if ismacos: env['PATH'] = BIN + os.pathsep + os.environ['PATH'] env['LIBTOOLIZE'] = 'glibtoolize' env['LIBTOOL'] = 'glibtool' with ModifiedEnv(**env): run('autoreconf -fiv') conf = '--disable-dependency-tracking' env = {} if ismacos: conf += ' --host x86_64-apple-darwin' simple_build(conf)
def windows_python(args): with open('PCbuild/msbuild.rsp', 'w') as f: print(f'/p:PlatformToolset={get_platform_toolset()}', file=f) print(f'/p:WindowsTargetPlatformVersion={get_windows_sdk()}', file=f) # dont need python 3 to get externals, use git instead replace_in_file('PCbuild\\get_externals.bat', re.compile(br'^call.+find_python.bat.+$', re.MULTILINE), '') env = {} if is64bit: env['PROCESSOR_ARCHITECTURE'] = env['PROCESSOR_ARCHITEW6432'] = 'AMD64' try: run( 'PCbuild\\build.bat', '-e', '--no-tkinter', '-c', 'Release', '-m', '-p', ('x64' if is64bit else 'Win32'), '-v', '-t', 'Build', '--pgo', env=env ) # Run the tests # run('PCbuild\\amd64\\python.exe', 'Lib/test/regrtest.py', '-u', # 'network,cpu,subprocess,urlfetch') # Do not read mimetypes from the registry replace_in_file( 'Lib\\mimetypes.py', re.compile(br'try:.*?import\s+winreg.*?None', re.DOTALL), r'_winreg = None') bindir = 'PCbuild\\amd64' if is64bit else 'PCbuild\\win32' install_binaries(bindir + os.sep + '*.exe', 'private\\python') install_binaries(bindir + os.sep + 'python*.dll', 'private\\python') install_binaries(bindir + os.sep + '*.pyd', 'private\\python\\DLLs') install_binaries(bindir + os.sep + '*.dll', 'private\\python\\DLLs') for x in glob.glob( os.path.join(build_dir(), 'private\\python\\DLLs\\python*.dll')): os.remove(x) install_binaries(bindir + os.sep + '*.lib', 'private\\python\\libs') copy_headers('PC\\pyconfig.h', 'private\\python\\include') copy_headers('Include\\*.h', 'private\\python\\include') copy_headers('Include\\cpython', 'private\\python\\include') with open('Lib/sitecustomize.py', 'w') as f: f.write(''' import os for path in ('{p}/bin', '{p}/qt/bin'): if os.path.exists(path): os.add_dll_directory(path) '''.format(p=PREFIX.replace('\\', '/'))) shutil.copytree('Lib', os.path.join(build_dir(), 'private\\python\\Lib')) finally: # bloody git creates files with no write permission import stat for path in walk('externals'): os.chmod(path, stat.S_IWRITE) os.remove(path)
def main(args): python_build() for f in walk(build_dir()): if os.path.basename(f) == 'c_ppmd.py': q = os.path.join(os.path.dirname(f), '__init__.py') if not os.path.exists(q): open(q, 'w').close() break python_install()
def find_binaries(env): files = {j(env.bin_dir, x) for x in os.listdir(env.bin_dir)} | { x for x in { j(os.path.dirname(env.bin_dir), x) for x in os.listdir(env.bin_dir)} if os.path.exists(x)} for x in walk(env.lib_dir): x = os.path.realpath(x) if x not in files and is_elf(x): files.add(x) return files
def main(args): run_sip_install() if iswindows: for x in walk(build_dir()): parts = x.replace(os.sep, '/').split('/') if parts[-2:] == ['PyQt6', '__init__.py']: replace_in_file(x, re.compile(r'^find_qt\(\)', re.M), '') break else: raise ValueError( f'Failed to find PyQt6 __init__.py to patch in {build_dir()}')
def main(args): with ModifiedEnv(FREETYPE_CFLAGS='-I%s/include/freetype2' % PREFIX, FREETYPE_LIBS='-L%s/lib -lfreetype -lz -lbz2' % PREFIX): simple_build( '--disable-dependency-tracking --disable-static --disable-docs' f' --with-expat={PREFIX} --with-add-fonts=/usr/share/fonts', library_path=True) for f in walk(os.path.join(build_dir(), 'etc')): if os.path.islink(f): x = os.path.realpath(f) os.unlink(f) shutil.copy2(x, f)
def embed_manifests(env): printf('Embedding remaining manifests...') for manifest in walk(env.base): dll, ext = os.path.splitext(manifest) if ext != '.manifest': continue res = 2 if os.path.splitext(dll)[1] == '.exe': res = 1 if os.path.exists(dll) and open(manifest, 'rb').read().strip(): run('mt.exe', '-manifest', manifest, '-outputresource:%s;%d' % (dll, res)) os.remove(manifest)
def windows_python2(args): replace_in_file( 'PCbuild\\build.bat', re.compile(r'^\s*%1\s+%2', re.MULTILINE), f'"/p:PlatformToolset={get_platform_toolset()}" ' f'"/p:WindowsTargetPlatformVersion={get_windows_sdk()}"') # We create externals/nasm-2.11.06 below so that the # python build script does not try to download its own nasm instead # using the one we built instead (the python build script fails to # mark its nasm as executable, and therefore errors out) os.makedirs('externals/nasm-2.11.06') # os.makedirs('externals/openssl-1.0.2h') # os.makedirs('externals/sqlite-3.8.11.0') # os.makedirs('externals/bzip2-1.0.6') # dont need python 3 to get externals, use git instead replace_in_file('PCbuild\\get_externals.bat', re.compile(br'^call.+find_python.bat.+$', re.MULTILINE), '') try: run('PCbuild\\build.bat', '-e', '--no-tkinter', '--no-bsddb', '-c', 'Release', '-m', '-p', ('x64' if is64bit else 'Win32'), '-v', '-t', 'Build') # Run the tests # run('PCbuild\\amd64\\python.exe', 'Lib/test/regrtest.py', '-u', # 'network,cpu,subprocess,urlfetch') # Do not read mimetypes from the registry replace_in_file( 'Lib\\mimetypes.py', re.compile(br'try:.*?import\s+_winreg.*?None', re.DOTALL), r'_winreg = None') bindir = 'PCbuild\\amd64' if is64bit else 'PCbuild' install_binaries(bindir + os.sep + '*.exe', 'private\\python') install_binaries(bindir + os.sep + 'python*.dll', 'private\\python') install_binaries(bindir + os.sep + '*.pyd', 'private\\python\\DLLs') install_binaries(bindir + os.sep + '*.dll', 'private\\python\\DLLs') for x in glob.glob( os.path.join(build_dir(), 'private\\python\\DLLs\\python*.dll')): os.remove(x) install_binaries(bindir + os.sep + '*.lib', 'private\\python\\libs') copy_headers('PC\\pyconfig.h', 'private\\python\\include') copy_headers('Include\\*.h', 'private\\python\\include') shutil.copytree('Lib', os.path.join(build_dir(), 'private\\python\\Lib')) finally: # bloody git creates files with no write permission import stat for path in walk('externals'): os.chmod(path, stat.S_IWRITE) os.remove(path)
def strip_binaries(env): files = {j(env.bin_dir, x) for x in os.listdir(env.bin_dir)} | { x for x in { j(os.path.dirname(env.bin_dir), x) for x in os.listdir(env.bin_dir)} if os.path.exists(x)} for x in walk(env.lib_dir): x = os.path.realpath(x) if x not in files and is_elf(x): files.add(x) print('Stripping %d files...' % len(files)) before = sum(os.path.getsize(x) for x in files) strip_files(files) after = sum(os.path.getsize(x) for x in files) print('Stripped %.1f MB' % ((before - after) / (1024 * 1024.)))
def main(args): if iswindows: sln = r'jxrencoderdecoder\JXRDecApp_vc14.vcxproj' msbuild(sln) def fname_map(x): return os.path.basename(x).rpartition('.')[0] + '-calibre.exe' for f in walk(): if f.endswith('.exe'): install_binaries(f, 'bin', fname_map=fname_map) else: run('make', os.path.join(os.getcwd(), 'build/JxrDecApp')) install_binaries('build/JxrDecApp', 'bin')
def main(args): if iswindows: run(*('cscript.exe configure.js include={0}/include' ' lib={0}/lib prefix={0} zlib=yes iconv=no'.format( PREFIX.replace(os.sep, '/')).split()), cwd='win32') run(f'"{NMAKE}" /f Makefile.msvc', cwd='win32') install_tree('include/libxml', 'include/libxml2') for f in walk('.'): if f.endswith('.dll'): install_binaries(f, 'bin') elif f.endswith('.lib'): install_binaries(f) else: # ICU is needed to use libxml2 in qt-webengine simple_build( '--disable-dependency-tracking --disable-static --enable-shared' ' --without-python --without-debug --with-iconv={0}' ' --with-zlib={0} --with-icu'.format(PREFIX)) for path in walk(build_dir()): if path.endswith('/xml2-config'): replace_in_file(path, re.compile(b'(?m)^prefix=.+'), f'prefix={PREFIX}')
def strip_binaries(env): files = {j(env.bin_dir, x) for x in os.listdir(env.bin_dir)} | { x for x in { j(os.path.dirname(env.bin_dir), x) for x in os.listdir(env.bin_dir)} if os.path.exists(x)} for x in walk(env.lib_dir): x = os.path.realpath(x) if x not in files and is_elf(x): files.add(x) files.add(j(env.lib_dir, '..', 'libexec', 'QtWebEngineProcess')) print('Stripping %d files...' % len(files)) before = sum(os.path.getsize(x) for x in files) strip_files(files) after = sum(os.path.getsize(x) for x in files) print('Stripped %.1f MB' % ((before - after) / (1024 * 1024.)))
def main(args): # dbus chooses where to look for config files based on values fed to # ./configure, so we cannot configure to install it to prefix run('./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var' ' --disable-dependency-tracking --disable-static' ' --disable-doxygen-docs --disable-xml-docs --disable-systemd' ' --without-systemdsystemunitdir' ' --with-console-auth-dir=/run/console/ --disable-tests --without-x') run('make ' + MAKEOPTS) run(f'make install', env={'DESTDIR': build_dir()}) for x in ('include', 'lib'): os.rename(os.path.join(build_dir(), 'usr', x), os.path.join(build_dir(), x)) shutil.rmtree(os.path.join(build_dir(), 'usr')) for path in walk(build_dir()): if path.endswith('.pc'): replace_in_file(path, 'prefix=/usr', f'prefix={PREFIX}')
def main(args): # the makefile stupidly uses a comma as a separator for sed which breaks when there # are multiple entries being substituted replace_in_file('Makefile.am', re.compile(rb"'s,.+?'"), lambda m: m.group().replace(b',', b'`')) replace_in_file('Makefile.in', re.compile(rb"'s,.+?'"), lambda m: m.group().replace(b',', b'`')) with ModifiedEnv(FREETYPE_CFLAGS='-I%s/include/freetype2' % PREFIX, FREETYPE_LIBS='-L%s/lib -lfreetype -lz -lbz2' % PREFIX): simple_build( '--disable-dependency-tracking --disable-static --disable-docs' f' --with-expat={PREFIX} --with-add-fonts=/usr/share/fonts', library_path=True) for f in walk(os.path.join(build_dir(), 'etc')): if os.path.islink(f): x = os.path.realpath(f) os.unlink(f) shutil.copy2(x, f)
def add_package_dir(self, x, dest=None): def ignore(root, files): ans = [] for y in files: ext = os.path.splitext(y)[1] if ext not in ('', '.py', '.so') or \ (not ext and not os.path.isdir(join(root, y))): ans.append(y) return ans if dest is None: dest = self.site_packages dest = join(dest, basename(x)) shutil.copytree(x, dest, symlinks=True, ignore=ignore) for f in walk(dest): if f.endswith('.so'): self.fix_dependencies_in_lib(f)
def main(args): if iswindows: sln = r'jxrencoderdecoder\JXRDecApp_vc14.vcxproj' msbuild(sln) def fname_map(x): return os.path.basename(x).rpartition('.')[0] + '-calibre.exe' for f in walk(): if f.endswith('.exe'): install_binaries(f, 'bin', fname_map=fname_map) else: if ismacos: flags = '' if current_build_arch(): flags += f'-arch {current_build_arch()} ' replace_in_file('Makefile', 'CFLAGS=', f'CFLAGS={flags}') replace_in_file('Makefile', 'CXXFLAGS=', f'CXXFLAGS={flags}') run('make', os.path.join(os.getcwd(), 'build/JxrDecApp')) install_binaries('build/JxrDecApp', 'bin')
def add_misc_libraries(self): for x in ( 'sqlite3.0', 'z.1', 'harfbuzz.0', 'png16.16', 'lcms2.2', 'crypto.1.0.0', 'ssl.1.0.0', ): print('\nAdding', x) x = 'lib%s.dylib' % x src = join(PREFIX, 'lib', x) shutil.copy2(src, self.frameworks_dir) dest = join(self.frameworks_dir, x) self.set_id(dest, self.FID + '/' + x) self.fix_dependencies_in_lib(dest) base = join(self.frameworks_dir, 'kitty') for lib in walk(base): if lib.endswith('.so'): self.set_id(lib, self.FID + '/' + os.path.relpath(lib, self.frameworks_dir)) self.fix_dependencies_in_lib(lib)
def main(args): if iswindows: # cmake cannot find openssl replace_in_file('CMakeLists.txt', 'FIND_PACKAGE(LIBCRYPTO)', ('SET(LIBCRYPTO_FOUND "1")\n' 'SET(LIBCRYPTO_INCLUDE_DIR "{0}/include")\n' 'SET(LIBCRYPTO_LIBRARIES "{0}/lib/libcrypto.lib")\n' 'SET(PODOFO_HAVE_OPENSSL_1_1 "1")\n').format( PREFIX.replace(os.sep, '/'))) windows_cmake_build(WANT_LIB64='FALSE', PODOFO_BUILD_SHARED='TRUE', PODOFO_BUILD_STATIC='False', FREETYPE_INCLUDE_DIR=f"{PREFIX}/include/freetype2", nmake_target='podofo_shared') copy_headers('build/podofo_config.h', 'include/podofo') copy_headers('src/podofo/*', 'include/podofo') for f in walk(): if f.endswith('.dll'): install_binaries(f, 'bin') elif f.endswith('.lib'): install_binaries(f, 'lib') else: if ismacos: replace_in_file( 'CMakeLists.txt', 'FIND_PACKAGE(FREETYPE REQUIRED)', ('SET(FREETYPE_FOUND "1")\n' 'SET(FREETYPE_INCLUDE_DIR "{0}/include/freetype2")\n' 'SET(FREETYPE_LIBRARIES "{0}/lib/libfreetype.dylib")' ).format(PREFIX)) replace_in_file('src/podofo/base/PdfDate.cpp', 'struct tm _tm{}', 'struct tm _tm = {0}') cmake_build( make_args='podofo_shared', PODOFO_BUILD_LIB_ONLY='TRUE', PODOFO_BUILD_SHARED='TRUE', PODOFO_BUILD_STATIC='FALSE', )
def freeze(env, ext_dir): shutil.copy2(j(env.src_root, 'LICENSE'), env.base) printf('Adding resources...') tgt = j(env.app_base, 'resources') if os.path.exists(tgt): shutil.rmtree(tgt) shutil.copytree(j(env.src_root, 'resources'), tgt) printf('\tAdding misc binary deps') def copybin(x): shutil.copy2(x, env.dll_dir) try: shutil.copy2(x + '.manifest', env.dll_dir) except EnvironmentError as err: if err.errno != errno.ENOENT: raise bindir = os.path.join(PREFIX, 'bin') for x in ('pdftohtml', 'pdfinfo', 'pdftoppm', 'jpegtran-calibre', 'cjpeg-calibre', 'optipng-calibre', 'JXRDecApp-calibre'): copybin(os.path.join(bindir, x + '.exe')) for f in glob.glob(os.path.join(bindir, '*.dll')): if re.search(r'(easylzma|icutest)', f.lower()) is None: copybin(f) copybin( os.path.join(env.python_base, 'python%s.dll' % env.py_ver.replace('.', ''))) for x in glob.glob(os.path.join(env.python_base, 'DLLs', '*')): # python pyd modules copybin(x) for f in walk(os.path.join(env.python_base, 'Lib')): if f.lower().endswith('.dll') and 'scintilla' not in f.lower(): copybin(f) add_plugins(env, ext_dir) printf('Adding Qt...') for x in QT_DLLS: copybin(os.path.join(QT_PREFIX, 'bin', x + '.dll')) copybin(os.path.join(QT_PREFIX, 'bin', 'QtWebEngineProcess.exe')) for x in 'libGLESv2 libEGL'.split(): copybin(os.path.join(QT_PREFIX, 'bin', x + '.dll')) plugdir = j(QT_PREFIX, 'plugins') tdir = j(env.app_base, 'plugins') for d in QT_PLUGINS: imfd = os.path.join(plugdir, d) tg = os.path.join(tdir, d) if os.path.exists(tg): shutil.rmtree(tg) shutil.copytree(imfd, tg) for f in walk(tdir): if not f.lower().endswith('.dll'): os.remove(f) for data_file in os.listdir(j(QT_PREFIX, 'resources')): shutil.copy2(j(QT_PREFIX, 'resources', data_file), j(env.app_base, 'resources')) shutil.copytree(j(QT_PREFIX, 'translations'), j(env.app_base, 'translations')) printf('Adding python...') def ignore_lib(root, items): ans = [] for x in items: ext = os.path.splitext(x)[1].lower() if ext in ('.dll', '.chm', '.htm', '.txt'): ans.append(x) return ans shutil.copytree(r'%s\Lib' % env.python_base, env.lib_dir, ignore=ignore_lib) install_site_py(env) # Fix win32com sp_dir = j(env.lib_dir, 'site-packages') comext = j(sp_dir, 'win32comext') shutil.copytree(j(comext, 'shell'), j(sp_dir, 'win32com', 'shell')) shutil.rmtree(comext) for pat in ('PyQt5\\uic\\port_v3', ): x = glob.glob(j(env.lib_dir, 'site-packages', pat))[0] shutil.rmtree(x) pyqt = j(env.lib_dir, 'site-packages', 'PyQt5') for x in {x for x in os.listdir(pyqt) if x.endswith('.pyd')}: if x.partition('.')[0] not in PYQT_MODULES and x != 'sip.pyd': os.remove(j(pyqt, x)) with open(j(pyqt, '__init__.py'), 'r+b') as f: raw = f.read() nraw = raw.replace( b'def find_qt():', b'def find_qt():\n return # disabled for calibre') if nraw == raw: raise Exception( 'Failed to patch PyQt to disable dll directory manipulation') f.seek(0), f.truncate(), f.write(nraw) printf('Adding calibre sources...') for x in glob.glob(j(CALIBRE_DIR, 'src', '*')): if os.path.isdir(x): if os.path.exists(os.path.join(x, '__init__.py')): shutil.copytree(x, j(sp_dir, b(x)), ignore=shutil.ignore_patterns( '*.pyc', '*.pyo')) else: shutil.copy(x, j(sp_dir, b(x))) for x in (r'calibre\manual', r'calibre\plugins', 'pythonwin'): deld = j(sp_dir, x) if os.path.exists(deld): shutil.rmtree(deld) for x in os.walk(j(sp_dir, 'calibre')): for f in x[-1]: if not f.endswith('.py'): os.remove(j(x[0], f)) extract_pyd_modules(env, sp_dir) printf('Byte-compiling all python modules...') for x in ('test', 'lib2to3'): x = j(env.lib_dir, x) if os.path.exists(x): shutil.rmtree(x) py_compile(env.lib_dir.replace(os.sep, '/'))
def sanitize_source_folder(path: str) -> None: for q in walk(path): if os.path.splitext(q)[1] not in ('.py', '.glsl', '.ttf', '.otf'): os.unlink(q)
def freeze(env, ext_dir, incdir): shutil.copy2(j(env.src_root, 'LICENSE'), env.base) printf('Adding resources...') tgt = j(env.app_base, 'resources') if os.path.exists(tgt): shutil.rmtree(tgt) shutil.copytree(j(env.src_root, 'resources'), tgt) printf('\tAdding misc binary deps') def copybin(x): shutil.copy2(x, env.dll_dir) with contextlib.suppress(FileNotFoundError): shutil.copy2(x + '.manifest', env.dll_dir) bindir = os.path.join(PREFIX, 'bin') for x in ('pdftohtml', 'pdfinfo', 'pdftoppm', 'jpegtran-calibre', 'cjpeg-calibre', 'optipng-calibre', 'JXRDecApp-calibre'): copybin(os.path.join(bindir, x + '.exe')) for f in glob.glob(os.path.join(bindir, '*.dll')): if re.search(r'(easylzma|icutest)', f.lower()) is None: copybin(f) copybin( os.path.join(env.python_base, 'python%s.dll' % env.py_ver.replace('.', ''))) copybin(os.path.join(env.python_base, 'python%s.dll' % env.py_ver[0])) for x in glob.glob(os.path.join(env.python_base, 'DLLs', '*.dll')): # dlls needed by python copybin(x) for f in walk(os.path.join(env.python_base, 'Lib')): q = f.lower() if q.endswith( '.dll') and 'scintilla' not in q and 'pyqtbuild' not in q: copybin(f) ext_map = extract_extension_modules(ext_dir, env.dll_dir) ext_map.update( extract_extension_modules(j(env.python_base, 'DLLs'), env.dll_dir, move=False)) printf('Adding Qt...') for x in QT_DLLS: copybin(os.path.join(QT_PREFIX, 'bin', x + '.dll')) copybin(os.path.join(QT_PREFIX, 'bin', 'QtWebEngineProcess.exe')) for x in 'libGLESv2 libEGL'.split(): copybin(os.path.join(QT_PREFIX, 'bin', x + '.dll')) plugdir = j(QT_PREFIX, 'plugins') tdir = j(env.app_base, 'plugins') for d in QT_PLUGINS: imfd = os.path.join(plugdir, d) tg = os.path.join(tdir, d) if os.path.exists(tg): shutil.rmtree(tg) shutil.copytree(imfd, tg) for f in walk(tdir): if not f.lower().endswith('.dll'): os.remove(f) for data_file in os.listdir(j(QT_PREFIX, 'resources')): shutil.copy2(j(QT_PREFIX, 'resources', data_file), j(env.app_base, 'resources')) shutil.copytree(j(QT_PREFIX, 'translations'), j(env.app_base, 'translations')) printf('Adding python...') def ignore_lib(root, items): ans = [] for x in items: ext = os.path.splitext(x)[1].lower() if ext in ('.dll', '.chm', '.htm', '.txt'): ans.append(x) return ans shutil.copytree(r'%s\Lib' % env.python_base, env.lib_dir, ignore=ignore_lib) install_site_py(env) sp_dir = j(env.lib_dir, 'site-packages') printf('Adding calibre sources...') for x in glob.glob(j(CALIBRE_DIR, 'src', '*')): if os.path.isdir(x): if os.path.exists(os.path.join(x, '__init__.py')): shutil.copytree(x, j(sp_dir, b(x)), ignore=shutil.ignore_patterns( '*.pyc', '*.pyo')) else: shutil.copy(x, j(sp_dir, b(x))) ext_map.update(cleanup_site_packages(sp_dir)) for x in os.listdir(sp_dir): os.rename(j(sp_dir, x), j(env.lib_dir, x)) os.rmdir(sp_dir) printf('Extracting extension modules from', env.lib_dir, 'to', env.dll_dir) ext_map.update(extract_extension_modules(env.lib_dir, env.dll_dir)) printf('Byte-compiling all python modules...') py_compile(env.lib_dir.replace(os.sep, '/')) # from bypy.utils import run_shell # run_shell(cwd=env.lib_dir) freeze_python(env.lib_dir, env.dll_dir, incdir, ext_map, develop_mode_env_var='CALIBRE_DEVELOP_FROM') shutil.rmtree(env.lib_dir)