comparison setup.py @ 39:a6bc019ac0b2 upstream

ADD: PyMuPDF v1.26.5: the original sdist.
author Franz Glasner <fzglas.hg@dom66.de>
date Sat, 11 Oct 2025 11:19:58 +0200
parents 1d09e1dec1d9
children 71bcc18e306f
comparison
equal deleted inserted replaced
2:b50eed0cc0ef 39:a6bc019ac0b2
86 If unset or '-', use internal hard-coded default MuPDF location. 86 If unset or '-', use internal hard-coded default MuPDF location.
87 Otherwise overrides location of MuPDF when building PyMuPDF: 87 Otherwise overrides location of MuPDF when building PyMuPDF:
88 Empty string: 88 Empty string:
89 Build PyMuPDF with the system MuPDF. 89 Build PyMuPDF with the system MuPDF.
90 A string starting with 'git:': 90 A string starting with 'git:':
91 Use `git clone` to get a MuPDF checkout. We use the 91 We use `git` commands to clone/update a local MuPDF checkout.
92 string in the git clone command; it must contain the git 92 Should match `git:[--branch <branch>][--tag <tag>][<remote>]`.
93 URL from which to clone, and can also contain other `git 93 If <remote> is omitted we use a default.
94 clone` args, for example: 94 For example:
95 PYMUPDF_SETUP_MUPDF_BUILD="git:--branch master https://github.com/ArtifexSoftware/mupdf.git" 95 PYMUPDF_SETUP_MUPDF_BUILD="git:--branch master"
96 Passed as <text> arg to pipcl.git_get().
96 Otherwise: 97 Otherwise:
97 Location of mupdf directory. 98 Location of mupdf directory.
98 99
99 PYMUPDF_SETUP_MUPDF_BSYMBOLIC 100 PYMUPDF_SETUP_MUPDF_BSYMBOLIC
100 If '0' we do not link libmupdf.so with -Bsymbolic. 101 If '0' we do not link libmupdf.so with -Bsymbolic.
423 run(f'cd {directory} && git diff') 424 run(f'cd {directory} && git diff')
424 425
425 426
426 mupdf_tgz = os.path.abspath( f'{__file__}/../mupdf.tgz') 427 mupdf_tgz = os.path.abspath( f'{__file__}/../mupdf.tgz')
427 428
428 def get_mupdf_internal(out, location=None, sha=None, local_tgz=None): 429 def get_mupdf_internal(out, location=None, local_tgz=None):
429 ''' 430 '''
430 Gets MuPDF as either a .tgz or a local directory. 431 Gets MuPDF as either a .tgz or a local directory.
431 432
432 Args: 433 Args:
433 out: 434 out:
436 location: 437 location:
437 First, if None we set to hard-coded default URL or git location. 438 First, if None we set to hard-coded default URL or git location.
438 If starts with 'git:', should be remote git location. 439 If starts with 'git:', should be remote git location.
439 Otherwise if containing '://' should be URL for .tgz. 440 Otherwise if containing '://' should be URL for .tgz.
440 Otherwise should path of local mupdf checkout. 441 Otherwise should path of local mupdf checkout.
441 sha:
442 If not None and we use git clone, we checkout this sha.
443 local_tgz: 442 local_tgz:
444 If not None, must be local .tgz file. 443 If not None, must be local .tgz file.
445 Returns: 444 Returns:
446 (path, location): 445 (path, location):
447 `path` is absolute path of local directory or .tgz containing 446 `path` is absolute path of local directory or .tgz containing
449 448
450 `location_out` is `location` if not None, else the hard-coded 449 `location_out` is `location` if not None, else the hard-coded
451 default location. 450 default location.
452 451
453 ''' 452 '''
454 log(f'get_mupdf_internal(): {out=} {location=} {sha=}') 453 log(f'get_mupdf_internal(): {out=} {location=}')
455 assert out in ('dir', 'tgz') 454 assert out in ('dir', 'tgz')
456 if location is None: 455 if location is None:
457 location = f'https://mupdf.com/downloads/archive/mupdf-{version_mupdf}-source.tar.gz' 456 location = f'https://mupdf.com/downloads/archive/mupdf-{version_mupdf}-source.tar.gz'
458 #location = 'git:--branch master https://github.com/ArtifexSoftware/mupdf.git' 457 #location = 'git:--branch master https://github.com/ArtifexSoftware/mupdf.git'
459 458
463 462
464 local_dir = None 463 local_dir = None
465 if local_tgz: 464 if local_tgz:
466 assert os.path.isfile(local_tgz) 465 assert os.path.isfile(local_tgz)
467 elif location.startswith( 'git:'): 466 elif location.startswith( 'git:'):
468 location_git = location[4:]
469 local_dir = 'mupdf-git' 467 local_dir = 'mupdf-git'
470 468 pipcl.git_get(local_dir, text=location, remote='https://github.com/ArtifexSoftware/mupdf.git')
471 # Try to update existing checkout. 469
472 e = run(f'cd {local_dir} && git pull && git submodule update --init', check=False)
473 if e:
474 # No existing git checkout, so do a fresh clone.
475 _fs_remove(local_dir)
476 gitargs = location[4:]
477 run(f'git clone --recursive --depth 1 --shallow-submodules {gitargs} {local_dir}')
478
479 # Show sha of checkout. 470 # Show sha of checkout.
480 run( f'cd {local_dir} && git show --pretty=oneline|head -n 1', check=False) 471 run(
481 if sha: 472 f'cd {local_dir} && git show --pretty=oneline|head -n 1',
482 run( f'cd {local_dir} && git checkout {sha}') 473 check = False,
474 prefix = 'mupdf git id: ',
475 )
483 elif '://' in location: 476 elif '://' in location:
484 # Download .tgz. 477 # Download .tgz.
485 local_tgz = os.path.basename( location) 478 local_tgz = os.path.basename( location)
486 suffix = '.tar.gz' 479 suffix = '.tar.gz'
487 assert location.endswith(suffix), f'Unrecognised suffix in remote URL {location=}.' 480 assert location.endswith(suffix), f'Unrecognised suffix in remote URL {location=}.'
572 freebsd = sys.platform.startswith( 'freebsd') 565 freebsd = sys.platform.startswith( 'freebsd')
573 darwin = sys.platform.startswith( 'darwin') 566 darwin = sys.platform.startswith( 'darwin')
574 windows = platform.system() == 'Windows' or platform.system().startswith('CYGWIN') 567 windows = platform.system() == 'Windows' or platform.system().startswith('CYGWIN')
575 msys2 = platform.system().startswith('MSYS_NT-') 568 msys2 = platform.system().startswith('MSYS_NT-')
576 569
577 pyodide_flags = '-fwasm-exceptions'
578
579 if os.environ.get('PYODIDE') == '1': 570 if os.environ.get('PYODIDE') == '1':
580 if os.environ.get('OS') != 'pyodide': 571 if os.environ.get('OS') != 'pyodide':
581 log('PYODIDE=1, setting OS=pyodide.') 572 log('PYODIDE=1, setting OS=pyodide.')
582 os.environ['OS'] = 'pyodide' 573 os.environ['OS'] = 'pyodide'
583 os.environ['XCFLAGS'] = pyodide_flags
584 os.environ['XCXXFLAGS'] = pyodide_flags
585 574
586 pyodide = os.environ.get('OS') == 'pyodide' 575 pyodide = os.environ.get('OS') == 'pyodide'
587 576
588 def build(): 577 def build():
589 ''' 578 '''
702 add('b', f'{mupdf_build_dir}/libmupdfcpp.so', to_dir) 691 add('b', f'{mupdf_build_dir}/libmupdfcpp.so', to_dir)
703 add('b', f'{mupdf_build_dir}/libmupdf.dylib', to_dir) 692 add('b', f'{mupdf_build_dir}/libmupdf.dylib', to_dir)
704 add('d', f'{mupdf_build_dir}/libmupdf-threads.a', f'{to_dir_d}/lib/') 693 add('d', f'{mupdf_build_dir}/libmupdf-threads.a', f'{to_dir_d}/lib/')
705 elif pyodide: 694 elif pyodide:
706 add('p', f'{mupdf_build_dir}/_mupdf.so', to_dir) 695 add('p', f'{mupdf_build_dir}/_mupdf.so', to_dir)
707 add('b', f'{mupdf_build_dir}/libmupdfcpp.so', 'PyMuPDF.libs/') 696 add('b', f'{mupdf_build_dir}/libmupdfcpp.so', to_dir)
708 add('b', f'{mupdf_build_dir}/libmupdf.so', 'PyMuPDF.libs/') 697 add('b', f'{mupdf_build_dir}/libmupdf.so', to_dir)
709 else: 698 else:
710 add('p', f'{mupdf_build_dir}/_mupdf.so', to_dir) 699 add('p', f'{mupdf_build_dir}/_mupdf.so', to_dir)
711 add('b', pipcl.get_soname(f'{mupdf_build_dir}/libmupdfcpp.so'), to_dir) 700 add('b', pipcl.get_soname(f'{mupdf_build_dir}/libmupdfcpp.so'), to_dir)
712 add('b', pipcl.get_soname(f'{mupdf_build_dir}/libmupdf.so'), to_dir) 701 add('b', pipcl.get_soname(f'{mupdf_build_dir}/libmupdf.so'), to_dir)
713 add('d', f'{mupdf_build_dir}/libmupdf-threads.a', f'{to_dir_d}/lib/') 702 add('d', f'{mupdf_build_dir}/libmupdf-threads.a', f'{to_dir_d}/lib/')
746 try: 735 try:
747 return int(text) 736 return int(text)
748 except Exception: 737 except Exception:
749 return 0 738 return 0
750 swig_version_tuple = tuple(int_or_0(i) for i in swig_version.split('.')) 739 swig_version_tuple = tuple(int_or_0(i) for i in swig_version.split('.'))
740 version_p_tuple = tuple(int_or_0(i) for i in version_p.split('.'))
751 log(f'{swig_version=}') 741 log(f'{swig_version=}')
752 text = '' 742 text = ''
753 text += f'mupdf_location = {mupdf_location!r}\n' 743 text += f'mupdf_location = {mupdf_location!r}\n'
754 text += f'pymupdf_version = {version_p!r}\n' 744 text += f'pymupdf_version = {version_p!r}\n'
745 text += f'pymupdf_version_tuple = {version_p_tuple!r}\n'
755 text += f'pymupdf_git_sha = {sha!r}\n' 746 text += f'pymupdf_git_sha = {sha!r}\n'
756 text += f'pymupdf_git_diff = {diff!r}\n' 747 text += f'pymupdf_git_diff = {diff!r}\n'
757 text += f'pymupdf_git_branch = {branch!r}\n' 748 text += f'pymupdf_git_branch = {branch!r}\n'
758 text += f'swig_version = {swig_version!r}\n' 749 text += f'swig_version = {swig_version!r}\n'
759 text += f'swig_version_tuple = {swig_version_tuple!r}\n' 750 text += f'swig_version_tuple = {swig_version_tuple!r}\n'
1209 compiler_extra += f' {cflags}' 1200 compiler_extra += f' {cflags}'
1210 cxxflags = os.environ.get('CXXFLAGS') 1201 cxxflags = os.environ.get('CXXFLAGS')
1211 if cxxflags: 1202 if cxxflags:
1212 compiler_extra += f' {cxxflags}' 1203 compiler_extra += f' {cxxflags}'
1213 1204
1214 if pyodide:
1215 compiler_extra += f' {pyodide_flags}'
1216 linker_extra += f' {pyodide_flags}'
1217
1218 return compiler_extra, linker_extra, includes, defines, optimise, debug, libpaths, libs, libraries, 1205 return compiler_extra, linker_extra, includes, defines, optimise, debug, libpaths, libs, libraries,
1219 1206
1220 1207
1221 def sdist(): 1208 def sdist():
1222 ret = list() 1209 ret = list()
1278 1265
1279 # We generate different wheels depending on PYMUPDF_SETUP_FLAVOUR. 1266 # We generate different wheels depending on PYMUPDF_SETUP_FLAVOUR.
1280 # 1267 #
1281 1268
1282 # PyMuPDF version. 1269 # PyMuPDF version.
1283 version_p = '1.26.4' 1270 version_p = '1.26.5'
1284 1271
1285 version_mupdf = '1.26.7' 1272 version_mupdf = '1.26.10'
1286 1273
1287 # PyMuPDFb version. This is the PyMuPDF version whose PyMuPDFb wheels we will 1274 # PyMuPDFb version. This is the PyMuPDF version whose PyMuPDFb wheels we will
1288 # (re)use if generating separate PyMuPDFb wheels. Though as of PyMuPDF-1.24.11 1275 # (re)use if generating separate PyMuPDFb wheels. Though as of PyMuPDF-1.24.11
1289 # (2024-10-03) we no longer use PyMuPDFb wheels so this is actually unused. 1276 # (2024-10-03) we no longer use PyMuPDFb wheels so this is actually unused.
1290 # 1277 #
1411 if libclang: 1398 if libclang:
1412 print(f'Overriding to use {libclang=}.') 1399 print(f'Overriding to use {libclang=}.')
1413 ret.append(libclang) 1400 ret.append(libclang)
1414 elif openbsd: 1401 elif openbsd:
1415 print(f'OpenBSD: libclang not available via pip; assuming `pkg_add py3-llvm`.') 1402 print(f'OpenBSD: libclang not available via pip; assuming `pkg_add py3-llvm`.')
1416 elif darwin and platform.machine() == 'arm64':
1417 print(f'MacOS/arm64: forcing use of libclang 16.0.6 because 18.1.1 known to fail with `clang.cindex.TranslationUnitLoadError: Error parsing translation unit.`')
1418 ret.append('libclang==16.0.6')
1419 elif darwin and platform_release_tuple() < (18,): 1403 elif darwin and platform_release_tuple() < (18,):
1420 # There are still of problems when building on old macos. 1404 # There are still of problems when building on old macos.
1421 ret.append('libclang==14.0.6') 1405 ret.append('libclang==14.0.6')
1422 else: 1406 else:
1423 ret.append('libclang') 1407 ret.append('libclang')