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 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): if iswindows: windows_cmake_build() install_binaries('build/jpegtran-static.exe', 'bin', fname_map=lambda x: 'jpegtran-calibre.exe') install_binaries('build/cjpeg-static.exe', 'bin', fname_map=lambda x: 'cjpeg-calibre.exe') 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 --disable-shared --with-jpeg8' ' --without-turbojpeg') env = {} if ismacos: conf += f' --host x86_64-apple-darwin NASM={BIN}/nasm' replace_in_file( 'configure', re.compile(br'^PKG_CHECK_MODULES.libpng.+?\bfi\b', re.M | re.DOTALL), 'HAVE_LIBPNG=1\nHAVE_LIBPNG_TRUE="#"\n') simple_build(conf, override_prefix=os.path.join(build_dir(), 'private', 'mozjpeg'))
def main(args): apply_patch('chmlib-empty-file-not-dir.patch', level=1) # needed for aarch64 if iswindows: os.chdir('src') for f in 'chm_lib.c lzx.c'.split(): copy_headers(f, 'src') run(f'"{CL}" /c /nologo /MD /W3 /DWIN32 -c ' + f) run(f'"{LIB}" -nologo chm_lib.obj lzx.obj -OUT:chmlib.lib') install_binaries('chmlib.lib') copy_headers('chm_lib.h') copy_headers('lzx.h', 'src') else: # test for malloc breaks on macos universal. # All system we care about have malloc anyway replace_in_file('configure', 'if test $ac_cv_func_malloc_0_nonnull = yes; then', 'if test 1; then') replace_in_file('src/chm_lib.c', 'pread64', 'pread') apply_patch('chmlib-integer-types.patch', level=1) # needed for aarch64 # updated config.guess is needed for aarch64 with open('config.guess', 'wb') as dest, open(os.path.join(PATCHES, 'config.guess'), 'rb') as src: dest.write(src.read()) if ismacos and is_arm_half_of_lipo_build(): with open('config.sub', 'w') as dest: dest.write('echo arm-apple-darwin') conf = '--disable-dependency-tracking' if ismacos: conf += ' --disable-pread --disable-io64' simple_build(conf)
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 run_sip_install(for_webengine=False): qt_bin = f'{PREFIX}/qt/bin' qmake = 'qmake' + ('.exe' if iswindows else '') args = ('--no-docstrings --no-make' f' --qmake={qt_bin}/{qmake} --concatenate=5 --verbose').split() if iswindows: args.append('--link-full-dll') if for_webengine: args.extend('--disable QtWebEngineQuick'.split()) else: args.extend('--qt-shared --confirm-license --no-designer-plugin' ' --no-qml-plugin'.split()) run(f'{PREFIX}/bin/sip-build', *args, library_path=True) if iswindows: # disable distinfo as installing it fails when using INSTALL_ROOT replace_in_file('build/Makefile', 'install_distinfo ', ' ') run(NMAKE, cwd='build') run(NMAKE, 'install', cwd='build', env={'INSTALL_ROOT': build_dir()[2:]}) else: run('make ' + MAKEOPTS, cwd='build') run(f'make INSTALL_ROOT="{build_dir()}" install', cwd='build', library_path=True) python_install()
def create_installer(env): if os.path.exists(env.installer_dir): shutil.rmtree(env.installer_dir) os.makedirs(env.installer_dir) template = open(j(d(__file__), 'wix-template.xml'), 'rb').read().decode('utf-8') components, smap = get_components_from_files(env) wxs = template.format( app=calibre_constants['appname'], appfolder='Calibre2' if is64bit else 'Calibre', version=calibre_constants['version'], upgrade_code=UPGRADE_CODE, ProgramFilesFolder='ProgramFiles64Folder' if is64bit else 'ProgramFilesFolder', x64=' 64bit' if is64bit else '', minverhuman=MINVERHUMAN, minver='601', fix_wix='<Custom Action="OverwriteWixSetDefaultPerMachineFolder" After="WixSetDefaultPerMachineFolder" />' if is64bit else '', compression='high', app_components=components, exe_map=smap, main_icon=j(env.src_root, 'icons', 'library.ico'), viewer_icon=j(env.src_root, 'icons', 'viewer.ico'), editor_icon=j(env.src_root, 'icons', 'ebook-edit.ico'), web_icon=j(env.src_root, 'icons', 'web.ico'), ) template = open(j(d(__file__), 'en-us.xml'), 'rb').read().decode('utf-8') enus = template.format(app=calibre_constants['appname']) enusf = j(env.installer_dir, 'en-us.wxl') wxsf = j(env.installer_dir, calibre_constants['appname'] + '.wxs') with open(wxsf, 'wb') as f: f.write(wxs.encode('utf-8')) with open(enusf, 'wb') as f: f.write(enus.encode('utf-8')) wixobj = j(env.installer_dir, calibre_constants['appname'] + '.wixobj') arch = 'x64' if is64bit else 'x86' cmd = [CANDLE, '-nologo', '-arch', arch, '-ext', 'WiXUtilExtension', '-o', wixobj, wxsf] run(*cmd) installer = j(env.dist, '%s%s-%s.msi' % ( calibre_constants['appname'], ('-64bit' if is64bit else ''), calibre_constants['version'])) license = j(env.src_root, 'LICENSE.rtf') banner = j(env.src_root, 'icons', 'wix-banner.bmp') dialog = j(env.src_root, 'icons', 'wix-dialog.bmp') cmd = [LIGHT, '-nologo', '-ext', 'WixUIExtension', '-cultures:en-us', '-loc', enusf, wixobj, '-ext', 'WixUtilExtension', '-o', installer, '-dWixUILicenseRtf=' + license, '-dWixUIBannerBmp=' + banner, '-dWixUIDialogBmp=' + dialog] cmd.extend([ '-sice:ICE60', # No language in dlls warning '-sice:ICE61', # Allow upgrading with same version number '-sice:ICE40', # Re-install mode overriden '-sice:ICE69', # Shortcut components are part of a different feature than the files they point to ]) cmd.append('-sval') # Disable all checks since they fail when running under ssh run(*cmd)
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): if iswindows: run(f'"{NMAKE}" -f build\\visualc.mk') install_binaries('src\\optipng\\optipng.exe', 'bin', fname_map=lambda x: 'optipng-calibre.exe') else: simple_build('-with-system-libs', use_envvars_for_lipo=True)
def build_launchers(env, debug=False): if not os.path.exists(env.obj_dir): os.makedirs(env.obj_dir) dflags = (['/Zi'] if debug else []) dlflags = (['/DEBUG'] if debug else ['/INCREMENTAL:NO']) base = d(a(__file__)) sources = [j(base, x) for x in ['util.c', ]] objects = [j(env.obj_dir, b(x) + '.obj') for x in sources] cflags = '/c /EHsc /W3 /Ox /nologo /D_UNICODE'.split() cflags += ['/DPYDLL="python%s.dll"' % env.py_ver.replace('.', ''), '/I%s/include' % env.python_base] for src, obj in zip(sources, objects): cmd = [CL] + cflags + dflags + ['/MD', '/Fo' + obj, '/Tc' + src] run_compiler(env, *cmd) dll = j(env.obj_dir, 'calibre-launcher.dll') ver = '.'.join(VERSION.split('.')[:2]) cmd = [LINK, '/DLL', '/VERSION:' + ver, '/LTCG', '/OUT:' + dll, '/nologo', '/MACHINE:' + machine] + dlflags + objects + \ [embed_resources(env, dll), '/LIBPATH:%s/libs' % env.python_base, 'delayimp.lib', 'user32.lib', 'shell32.lib', 'python%s.lib' % env.py_ver.replace('.', ''), '/delayload:python%s.dll' % env.py_ver.replace('.', '')] printf('Linking calibre-launcher.dll') run(*cmd) src = j(base, 'main.c') shutil.copy2(dll, env.dll_dir) basenames, modules, functions = calibre_constants['basenames'], calibre_constants['modules'], calibre_constants['functions'] for typ in ('console', 'gui', ): printf('Processing %s launchers' % typ) subsys = 'WINDOWS' if typ == 'gui' else 'CONSOLE' for mod, bname, func in zip(modules[typ], basenames[typ], functions[typ]): cflags = '/c /EHsc /MT /W3 /O1 /nologo /D_UNICODE /DUNICODE /GS-'.split() if typ == 'gui': cflags += ['/DGUI_APP='] cflags += ['/DMODULE="%s"' % mod, '/DBASENAME="%s"' % bname, '/DFUNCTION="%s"' % func] dest = j(env.obj_dir, bname + '.obj') printf('Compiling', bname) cmd = [CL] + cflags + dflags + ['/Tc' + src, '/Fo' + dest] run_compiler(env, *cmd) exe = j(env.base, bname + '.exe') lib = dll.replace('.dll', '.lib') u32 = ['user32.lib'] printf('Linking', bname) mf = dest + '.manifest' with open(mf, 'wb') as f: f.write(EXE_MANIFEST.encode('utf-8')) cmd = [LINK] + [ '/MACHINE:' + machine, '/NODEFAULTLIB', '/ENTRY:start_here', '/LIBPATH:' + env.obj_dir, '/SUBSYSTEM:' + subsys, '/LIBPATH:%s/libs' % env.python_base, '/RELEASE', '/MANIFEST:EMBED', '/MANIFESTINPUT:' + mf, 'user32.lib', 'kernel32.lib', '/OUT:' + exe] + u32 + dlflags + [embed_resources(env, exe), dest, lib] run(*cmd)
def main(args): replace_in_file('setup.py', 'self._want_assembly_kept = sys', 'self._want_assembly_kept = False and sys') # the exports in this file lead to linker errors with invalid export # specification replace_in_file('setup.py', "export_symbol_file = 'com/win32com/src/PythonCOM.def',", '') # get rid of some not needed modules and modules that dont build replace_in_file( 'setup.py', 'def _why_cant_build_extension(self, ext):', '''def _why_cant_build_extension(self, ext): if ext.name in ('exchdapi', 'exchange', 'mapi', 'pythonservice', 'win32ui', 'win32uiole', 'dde', 'Pythonwin'): return 'disabled by Kovid' ''') # dont copy the MFC Dlls since we have disabled the modules # that use them replace_in_file( 'setup.py', re.compile(r'^\s+# The MFC DLLs.+?^\s+def ', re.DOTALL | re.MULTILINE), ' def ') # dont build scintilla (used by the disabled pythonwin) replace_in_file('setup.py', 'self._build_scintilla()', '') # CLSID_PropertyChangeArray is not useable replace_in_file('com/win32comext/propsys/src/propsys.cpp', '#ifndef CLSID_PropertyChangeArray', '#if 0') replace_in_file( 'com/win32comext/propsys/src/propsys.cpp', re.compile(r'PYCOM_INTERFACE_CLSID_ONLY\s*\(PropertyChangeArray\),'), '') # Undefined symbol replace_in_file( 'win32/src/win32job.i', '#define JOB_OBJECT_RESERVED_LIMIT_VALID_FLAGS JOB_OBJECT_RESERVED_LIMIT_VALID_FLAGS', # noqa '') # fix win32com trying to write to paths inside the installation folder replace_in_file( 'com/win32com/__init__.py', "__gen_path__ = ''", 'import tempfile; __gen_path__ = os.path.join(tempfile.gettempdir(), "gen_py", "%d.%d" % (sys.version_info[0], sys.version_info[1]))' ) # noqa replace_in_file('com/win32com/client/gencache.py', 'except IOError:', 'except Exception:') p = windows_sdk_paths() with ModifiedEnv(MSSDK_INCLUDE=p['include'], MSSDK_LIB=p['lib']): run(PYTHON, 'setup.py', 'build', '--plat-name=' + ('win-amd64' if is64bit else 'win32')) run(PYTHON, 'setup.py', '-q', 'install', '--root', build_dir()) base = os.path.relpath(PREFIX, '/') q = os.listdir(build_dir())[0] os.rename(os.path.join(build_dir(), base, 'private'), os.path.join(build_dir(), 'private')) rmtree(os.path.join(build_dir(), q)) rmtree( os.path.join(build_dir(), 'private/python/Lib/site-packages/pythonwin'))
def post_install_check(): mods = '_ssl zlib bz2 ctypes sqlite3 lzma'.split() if not iswindows: mods.extend('readline _curses'.split()) run(PYTHON, '-c', 'import ' + ','.join(mods), library_path=True) run(PYTHON, '-c', 'import sqlite3; c = sqlite3.Connection(":memory:");' 'c.enable_load_extension(True)', library_path=True)
def embed_resources(env, module, desc=None, extra_data=None, product_description=None): icon_base = j(env.src_root, 'icons') icon_map = { 'calibre': 'library', 'ebook-viewer': 'viewer', 'ebook-edit': 'ebook-edit', 'lrfviewer': 'viewer', 'calibre-portable': 'library' } file_type = 'DLL' if module.endswith('.dll') else 'APP' with open(env.rc_template, 'rb') as f: template = f.read().decode('utf-8') bname = b(module) internal_name = os.path.splitext(bname)[0] icon = icon_map.get(internal_name, 'command-prompt') if internal_name.startswith('calibre-portable-'): icon = 'install' icon = j(icon_base, icon + '.ico') if desc is None: defdesc = 'A dynamic link library' if file_type == 'DLL' else \ 'An executable program' desc = DESCRIPTIONS.get(internal_name, defdesc) license = 'GNU GPL v3.0' def e(val): return val.replace('"', r'\"') if product_description is None: product_description = APPNAME + ' - E-book management' rc = template.format( icon=icon.replace('\\', '/'), file_type=e(file_type), file_version=e(WINVER.replace('.', ',')), file_version_str=e(WINVER), file_description=e(desc), internal_name=e(internal_name), original_filename=e(bname), product_version=e(WINVER.replace('.', ',')), product_version_str=e(VERSION), product_name=e(APPNAME), product_description=e(product_description), legal_copyright=e(license), legal_trademarks=e(APPNAME + ' is a registered U.S. trademark number 3,666,525')) if extra_data: rc += '\nextra extra "%s"' % extra_data tdir = env.obj_dir rcf = j(tdir, bname + '.rc') with open(rcf, 'w') as f: f.write(rc) res = j(tdir, bname + '.res') run(RC, '/n', '/fo' + res, rcf) return res
def main(args): pyver = python_major_minor_version() b = build_dir() if ismacos: b = os.path.join( b, 'python/Python.framework/Versions/{}.{}'.format(*pyver)) elif iswindows: b = os.path.join(b, 'private', 'python') cmd = [ PYTHON, 'configure.py', '--no-pyi', '--sip-module=PyQt5.sip', '--bindir=%s/bin' % build_dir() ] sp = 'Lib' if iswindows else 'lib/python{}.{}'.format(*pyver) inc = 'include' if iswindows else 'include/python{}.{}'.format(*pyver) cmd += [ '--destdir=%s/%s/site-packages' % (b, sp), '--sipdir=%s/share/sip' % b, '--incdir=%s/%s' % (b, inc) ] run(*cmd, library_path=True) if iswindows: run(f'"{NMAKE}"'), run(f'"{NMAKE}" install') else: run('make ' + MAKEOPTS) run('make install', library_path=True) q, r = build_dir(), PREFIX if iswindows: q = q.replace(os.sep, os.sep + os.sep) r = r.replace(os.sep, os.sep + os.sep) p = 'Lib' if iswindows else 'lib/python{}.{}'.format(*pyver) replace_in_file(os.path.join(b, p, 'site-packages/sipconfig.py'), q, r)
def main(args): if iswindows: for f in 'hnjalloc.c hyphen.c'.split(): run(f'"{CL}" /c /nologo /MD /W3 /DWIN32 -c ' + f) run(f'"{LIB}" -nologo hnjalloc.obj hyphen.obj -OUT:hyphen.lib') install_binaries('hyphen.lib') copy_headers('hyphen.h') return run('./configure', f'--prefix={build_dir()}', '--disable-static') run('make', 'install-libLTLIBRARIES') run('make', 'install-includeHEADERS')
def post_install_check(): if iswindows: # Ensure the system python27.dll is not being loaded run(PYTHON, '-c', "import sys; 'MSC v.1916' not in sys.version and sys.exit(1)") mods = '_ssl zlib bz2 ctypes sqlite3'.split() if python_major_minor_version()[0] > 2: mods.append('lzma') if not iswindows: mods.extend('readline _curses'.split()) run(PYTHON, '-c', 'import ' + ','.join(mods), library_path=True)
def main(args): if iswindows: run(f'"{NMAKE}" /f Makefile.vc CFG=release-dynamic' ' RTLIBCFG=dynamic OBJDIR=output') install_binaries('output/release-dynamic/*/bin/*.dll', 'bin') install_binaries('output/release-dynamic/*/lib/*.lib', 'lib') copy_headers('src/webp') else: # mux/demux are needed for webengine simple_build('--disable-dependency-tracking --disable-static' ' --enable-libwebpmux --enable-libwebpdemux')
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 main(args): if iswindows: for f in 'hnjalloc.c hyphen.c'.split(): run(f'"{CL}" /c /nologo /MD /W3 /DWIN32 -c ' + f) run(f'"{LIB}" -nologo hnjalloc.obj hyphen.obj -OUT:hyphen.lib') install_binaries('hyphen.lib') copy_headers('hyphen.h') return simple_build( ('--disable-static', ), make_args=('install-libLTLIBRARIES', 'install-includeHEADERS'), do_install=False, )
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(PYTHON, 'setup.py', 'fetch', '--all', '--missing-checksum-ok', 'build', '--enable-all-extensions', 'install', '--root', build_dir()) else: run(PYTHON, 'setup.py', 'build', 'install', '--root', build_dir(), library_path=True) python_install()
def main(args): if iswindows: # libxml2 does not depend on iconv in our windows build replace_in_file('setupinfo.py', ", 'iconv'", '') run( PYTHON, *('setup.py build_ext -I {0}/include;{0}/include/libxml2 -L {0}/lib' .format(PREFIX.replace(os.sep, '/')).split())) else: run(PYTHON, *('setup.py build_ext -I {0}/include/libxml2 -L {0}/lib'.format( PREFIX).split()), library_path=True) python_build() python_install()
def main(args): if iswindows: os.chdir('src') for f in 'chm_lib.c lzx.c'.split(): copy_headers(f, 'src') run(f'"{CL}" /c /nologo /MD /W3 /DWIN32 -c ' + f) run(f'"{LIB}" -nologo chm_lib.obj lzx.obj -OUT:chmlib.lib') install_binaries('chmlib.lib') copy_headers('chm_lib.h') copy_headers('lzx.h', 'src') else: conf = '--disable-dependency-tracking' if ismacos: conf += ' --disable-pread --disable-io64' simple_build(conf)
def main(args): # the Makefile has a circular dependency that breaks building under VS # 2019, see # https://webcache.googleusercontent.com/search?q=cache:s-p9ts472EoJ:https://forum.nasm.us/index.php%3Ftopic%3D2746.0+&cd=6&hl=en&ct=clnk&gl=in replace_in_file( 'Mkfiles/msvc.mak', re.compile(rb'\s+\$\(MAKE\) asm\\warnings.time.+?WARNFILES\)', re.DOTALL), '') open('asm/warnings.time', 'w').close() run(NMAKE, '/f', 'Mkfiles/msvc.mak', append_to_path=os.path.dirname(PERL)) install_binaries('./nasm.exe', 'bin')
def run_build(): if iswindows: run(f'"{NMAKE}"') run(f'"{NMAKE}" install') else: lp = os.path.join(PREFIX, 'qt', 'lib') run('make ' + MAKEOPTS, library_path=lp) run('make install', library_path=True)
def build(src, name, subsys='CONSOLE', libs='setupapi.lib'.split()): printf('Building ' + name) obj = j(env.obj_dir, os.path.basename(src) + '.obj') cflags = '/c /EHsc /MD /W3 /Ox /nologo /D_UNICODE'.split() ftype = '/T' + ('c' if src.endswith('.c') else 'p') cmd = [CL] + cflags + ['/Fo' + obj, ftype + src] run_compiler(env, *cmd) exe = j(env.dll_dir, name) mf = exe + '.manifest' with open(mf, 'wb') as f: f.write(EXE_MANIFEST.encode('utf-8')) cmd = [LINK] + [ '/MACHINE:' + machine, '/SUBSYSTEM:' + subsys, '/RELEASE', '/MANIFEST:EMBED', '/MANIFESTINPUT:' + mf, '/OUT:' + exe ] + [embed_resources(env, exe), obj] + libs run(*cmd)
def run_configure(for_webengine=False): pyver = python_major_minor_version() b = build_dir() if ismacos: b = os.path.join( b, 'python/Python.framework/Versions/{}.{}'.format(*pyver)) elif iswindows: b = os.path.join(b, 'private', 'python') lp = os.path.join(PREFIX, 'qt', 'lib') sip, qmake = 'sip', 'qmake' if iswindows: sip += '.exe' qmake += '.exe' sp = 'Lib' if iswindows else 'lib/python{}.{}'.format(*pyver) sip_dir = f'{b}/share/sip/PyQt5' dest_dir = f'{b}/{sp}/site-packages' if for_webengine: pyqt_options = [] os.makedirs(sip_dir) dest_dir += '/PyQt5' else: pyqt_options = [ '--confirm-license', '--assume-shared', f'--bindir={b}/bin', '--no-designer-plugin', '--no-qml-plugin', ] cmd = [PYTHON, 'configure.py'] + pyqt_options + [ '--sip=%s/bin/%s' % (PREFIX, sip), '--qmake=%s/qt/bin/%s' % (PREFIX, qmake), f'--destdir={dest_dir}', '--verbose', f'--sipdir={sip_dir}', '--no-stubs', '-c', '-j5', '--no-docstrings', ] if iswindows: cmd.append('--spec=win32-msvc') cmd.append('--sip-incdir=%s/private/python/include' % PREFIX) if for_webengine: cmd.append( f'--pyqt-sipdir={PREFIX}/private/python/share/sip/PyQt5') run(*cmd, library_path=lp) return dest_dir
def main(args): replace_in_file('dll.cpp', 'WideToChar', 'WideToUtf') if iswindows: # see https://github.com/microsoft/vcpkg/pull/8053 replace_in_file( 'UnRARDll.vcxproj', '<StructMemberAlignment>4Bytes</StructMemberAlignment>', '') msbuild('UnRARDll.vcxproj') install_binaries('./build/*/Release/unrar.dll', 'bin') install_binaries('./build/*/Release/UnRAR.lib', 'lib') # from bypy.utils import run_shell # run_shell() else: if ismacos: replace_in_file('makefile', 'libunrar.so', 'libunrar.dylib') run('make -j4 lib CXXFLAGS=-fPIC') install_binaries('libunrar.' + ('dylib' if ismacos else 'so'), 'lib') copy_headers('*.hpp', destdir='include/unrar')
def build_portable(env): base = env.portable_base if os.path.exists(base): shutil.rmtree(base) os.makedirs(base) root = d(a(__file__)) src = j(root, 'portable.c') obj = j(env.obj_dir, b(src) + '.obj') cflags = '/c /EHsc /MT /W3 /Ox /nologo /D_UNICODE /DUNICODE'.split() for exe_name in ('calibre.exe', 'ebook-viewer.exe', 'ebook-edit.exe'): exe = j(base, exe_name.replace('.exe', '-portable.exe')) printf('Compiling', exe) cmd = [CL] + cflags + [ '/DEXE_NAME="%s"' % exe_name, '/Fo' + obj, '/Tc' + src ] run_compiler(env, *cmd) printf('Linking', exe) desc = { 'calibre.exe': 'Calibre Portable', 'ebook-viewer.exe': 'Calibre Portable Viewer', 'ebook-edit.exe': 'Calibre Portable Editor' }[exe_name] cmd = [LINK] + [ '/INCREMENTAL:NO', '/MACHINE:' + machine, '/LIBPATH:' + env.obj_dir, '/SUBSYSTEM:WINDOWS', '/RELEASE', '/ENTRY:wWinMainCRTStartup', '/OUT:' + exe, embed_resources(env, exe, desc=desc, product_description=desc), obj, 'User32.lib' ] run(*cmd) printf('Creating portable installer') shutil.copytree(env.base, j(base, 'Calibre')) os.mkdir(j(base, 'Calibre Library')) os.mkdir(j(base, 'Calibre Settings')) name = '%s-portable-%s.zip' % (APPNAME, VERSION) name = j(env.dist, name) with zipfile.ZipFile(name, 'w', zipfile.ZIP_STORED) as zf: add_dir_to_zip(zf, base, 'Calibre Portable') env.portable_uncompressed_size = os.path.getsize(name) subprocess.check_call([PREFIX + r'\bin\elzma.exe', '-9', '--lzip', name])
def build_launchers(env): base = self_dir sources = [j(base, x) for x in ['util.c']] objects = [j(env.obj_dir, os.path.basename(x) + '.o') for x in sources] cflags = '-fno-strict-aliasing -W -Wall -c -O2 -pipe -DPYTHON_VER="python%s"' % py_ver cflags = cflags.split() + ['-I%s/include/python%s' % (PREFIX, py_ver)] for src, obj in zip(sources, objects): cmd = ['gcc'] + cflags + ['-fPIC', '-o', obj, src] run(*cmd) dll = j(env.lib_dir, 'libcalibre-launcher.so') cmd = ['gcc', '-O2', '-Wl,--rpath=$ORIGIN/../lib', '-fPIC', '-o', dll, '-shared'] + objects + \ ['-L%s/lib' % PREFIX, '-lpython' + py_ver] run(*cmd) src = j(base, 'main.c') modules, basenames, functions = calibre_constants['modules'].copy(), calibre_constants['basenames'].copy(), calibre_constants['functions'].copy() modules['console'].append('calibre.linux') basenames['console'].append('calibre_postinstall') functions['console'].append('main') c_launcher = '/tmp/calibre-c-launcher' lsrc = os.path.join(base, 'launcher.c') cmd = ['gcc', '-O2', '-o', c_launcher, lsrc, ] run(*cmd) jobs = [] for typ in ('console', 'gui', ): for mod, bname, func in zip(modules[typ], basenames[typ], functions[typ]): xflags = list(cflags) xflags.remove('-c') xflags += ['-DGUI_APP=' + ('1' if typ == 'gui' else '0')] xflags += ['-DMODULE="%s"' % mod, '-DBASENAME="%s"' % bname, '-DFUNCTION="%s"' % func] exe = j(env.bin_dir, bname) cmd = ['gcc'] + xflags + [src, '-o', exe, '-L' + env.lib_dir, '-lcalibre-launcher'] jobs.append(create_job(cmd)) sh = j(env.base, bname) shutil.copy2(c_launcher, sh) os.chmod(sh, stat.S_IREAD | stat.S_IEXEC | stat.S_IWRITE | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) if jobs: if not parallel_build(jobs, verbose=False): raise SystemExit(1)