1
+ from __future__ import annotations
2
+
1
3
import argparse
2
4
import os
3
5
import platform
7
9
import subprocess
8
10
9
11
10
- def cmd_cd (path ) :
12
+ def cmd_cd (path : str ) -> str :
11
13
return f"cd /D { path } "
12
14
13
15
14
- def cmd_set (name , value ) :
16
+ def cmd_set (name : str , value : str ) -> str :
15
17
return f"set { name } ={ value } "
16
18
17
19
18
- def cmd_append (name , value ) :
20
+ def cmd_append (name : str , value : str ) -> str :
19
21
op = "path " if name == "PATH" else f"set { name } ="
20
22
return op + f"%{ name } %;{ value } "
21
23
22
24
23
- def cmd_copy (src , tgt ) :
25
+ def cmd_copy (src : str , tgt : str ) -> str :
24
26
return f'copy /Y /B "{ src } " "{ tgt } "'
25
27
26
28
27
- def cmd_xcopy (src , tgt ) :
29
+ def cmd_xcopy (src : str , tgt : str ) -> str :
28
30
return f'xcopy /Y /E "{ src } " "{ tgt } "'
29
31
30
32
31
- def cmd_mkdir (path ) :
33
+ def cmd_mkdir (path : str ) -> str :
32
34
return f'mkdir "{ path } "'
33
35
34
36
35
- def cmd_rmdir (path ) :
37
+ def cmd_rmdir (path : str ) -> str :
36
38
return f'rmdir /S /Q "{ path } "'
37
39
38
40
39
- def cmd_nmake (makefile = None , target = "" , params = None ):
40
- if params is None :
41
- params = ""
42
- elif isinstance (params , (list , tuple )):
43
- params = " " .join (params )
44
- else :
45
- params = str (params )
41
+ def cmd_nmake (
42
+ makefile : str | None = None ,
43
+ target : str = "" ,
44
+ params : list [str ] | None = None ,
45
+ ) -> str :
46
+ params = "" if params is None else " " .join (params )
46
47
47
48
return " " .join (
48
49
[
@@ -55,7 +56,7 @@ def cmd_nmake(makefile=None, target="", params=None):
55
56
)
56
57
57
58
58
- def cmds_cmake (target , * params ):
59
+ def cmds_cmake (target : str | tuple [ str , ...] | list [ str ], * params ) -> list [ str ] :
59
60
if not isinstance (target , str ):
60
61
target = " " .join (target )
61
62
@@ -80,8 +81,11 @@ def cmds_cmake(target, *params):
80
81
81
82
82
83
def cmd_msbuild (
83
- file , configuration = "Release" , target = "Build" , platform = "{msbuild_arch}"
84
- ):
84
+ file : str ,
85
+ configuration : str = "Release" ,
86
+ target : str = "Build" ,
87
+ platform : str = "{msbuild_arch}" ,
88
+ ) -> str :
85
89
return " " .join (
86
90
[
87
91
"{msbuild}" ,
@@ -96,14 +100,14 @@ def cmd_msbuild(
96
100
97
101
SF_PROJECTS = "https://sourceforge.net/projects"
98
102
99
- architectures = {
103
+ ARCHITECTURES = {
100
104
"x86" : {"vcvars_arch" : "x86" , "msbuild_arch" : "Win32" },
101
105
"x64" : {"vcvars_arch" : "x86_amd64" , "msbuild_arch" : "x64" },
102
106
"ARM64" : {"vcvars_arch" : "x86_arm64" , "msbuild_arch" : "ARM64" },
103
107
}
104
108
105
109
# dependencies, listed in order of compilation
106
- deps = {
110
+ DEPS = {
107
111
"libjpeg" : {
108
112
"url" : SF_PROJECTS
109
113
+ "/libjpeg-turbo/files/3.0.0/libjpeg-turbo-3.0.0.tar.gz/download" ,
@@ -365,7 +369,7 @@ def cmd_msbuild(
365
369
366
370
367
371
# based on distutils._msvccompiler from CPython 3.7.4
368
- def find_msvs ():
372
+ def find_msvs () -> dict [ str , str ] | None :
369
373
root = os .environ .get ("ProgramFiles(x86)" ) or os .environ .get ("ProgramFiles" )
370
374
if not root :
371
375
print ("Program Files not found" )
@@ -421,25 +425,40 @@ def find_msvs():
421
425
}
422
426
423
427
424
- def extract_dep (url , filename ):
425
- import tarfile
428
+ def download_dep (url : str , file : str ) -> None :
426
429
import urllib .request
430
+
431
+ ex = None
432
+ for i in range (3 ):
433
+ try :
434
+ print (f"Fetching { url } (attempt { i + 1 } )..." )
435
+ content = urllib .request .urlopen (url ).read ()
436
+ with open (file , "wb" ) as f :
437
+ f .write (content )
438
+ break
439
+ except urllib .error .URLError as e :
440
+ ex = e
441
+ else :
442
+ raise RuntimeError (ex )
443
+
444
+
445
+ def extract_dep (url : str , filename : str ) -> None :
446
+ import tarfile
427
447
import zipfile
428
448
429
449
file = os .path .join (args .depends_dir , filename )
430
450
if not os .path .exists (file ):
431
- ex = None
432
- for i in range (3 ):
433
- try :
434
- print ("Fetching %s (attempt %d)..." % (url , i + 1 ))
435
- content = urllib .request .urlopen (url ).read ()
436
- with open (file , "wb" ) as f :
437
- f .write (content )
438
- break
439
- except urllib .error .URLError as e :
440
- ex = e
441
- else :
442
- raise RuntimeError (ex )
451
+ # First try our mirror
452
+ mirror_url = (
453
+ f"https://raw.githubusercontent.com/"
454
+ f"python-pillow/pillow-depends/main/{ filename } "
455
+ )
456
+ try :
457
+ download_dep (mirror_url , file )
458
+ except RuntimeError as exc :
459
+ # Otherwise try upstream
460
+ print (exc )
461
+ download_dep (url , file )
443
462
444
463
print ("Extracting " + filename )
445
464
sources_dir_abs = os .path .abspath (sources_dir )
@@ -466,7 +485,7 @@ def extract_dep(url, filename):
466
485
raise RuntimeError (msg )
467
486
468
487
469
- def write_script (name , lines ) :
488
+ def write_script (name : str , lines : list [ str ]) -> None :
470
489
name = os .path .join (args .build_dir , name )
471
490
lines = [line .format (** prefs ) for line in lines ]
472
491
print ("Writing " + name )
@@ -477,7 +496,7 @@ def write_script(name, lines):
477
496
print (" " + line )
478
497
479
498
480
- def get_footer (dep ) :
499
+ def get_footer (dep : dict ) -> list [ str ] :
481
500
lines = []
482
501
for out in dep .get ("headers" , []):
483
502
lines .append (cmd_copy (out , "{inc_dir}" ))
@@ -488,7 +507,7 @@ def get_footer(dep):
488
507
return lines
489
508
490
509
491
- def build_env ():
510
+ def build_env () -> None :
492
511
lines = [
493
512
"if defined DISTUTILS_USE_SDK goto end" ,
494
513
cmd_set ("INCLUDE" , "{inc_dir}" ),
@@ -504,8 +523,8 @@ def build_env():
504
523
write_script ("build_env.cmd" , lines )
505
524
506
525
507
- def build_dep (name ) :
508
- dep = deps [name ]
526
+ def build_dep (name : str ) -> str :
527
+ dep = DEPS [name ]
509
528
dir = dep ["dir" ]
510
529
file = f"build_dep_{ name } .cmd"
511
530
@@ -554,9 +573,9 @@ def build_dep(name):
554
573
return file
555
574
556
575
557
- def build_dep_all ():
576
+ def build_dep_all () -> None :
558
577
lines = [r'call "{build_dir}\build_env.cmd"' ]
559
- for dep_name in deps :
578
+ for dep_name in DEPS :
560
579
print ()
561
580
if dep_name in disabled :
562
581
print (f"Skipping disabled dependency { dep_name } " )
@@ -602,7 +621,7 @@ def build_dep_all():
602
621
)
603
622
parser .add_argument (
604
623
"--architecture" ,
605
- choices = architectures ,
624
+ choices = ARCHITECTURES ,
606
625
default = os .environ .get (
607
626
"ARCHITECTURE" ,
608
627
(
@@ -634,7 +653,7 @@ def build_dep_all():
634
653
)
635
654
args = parser .parse_args ()
636
655
637
- arch_prefs = architectures [args .architecture ]
656
+ arch_prefs = ARCHITECTURES [args .architecture ]
638
657
print ("Target architecture:" , args .architecture )
639
658
640
659
msvs = find_msvs ()
@@ -693,7 +712,7 @@ def build_dep_all():
693
712
# TODO find NASM automatically
694
713
}
695
714
696
- for k , v in deps .items ():
715
+ for k , v in DEPS .items ():
697
716
prefs [f"dir_{ k } " ] = os .path .join (sources_dir , v ["dir" ])
698
717
699
718
print ()
0 commit comments