zmc
2023-08-08 e792e9a60d958b93aef96050644f369feb25d61b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
U
X±d:ã@sdZddlZddlZddlZddlZddlmZmZmZm    Z    m
Z
ddl m Z ddl mZddlmZe e¡Zdd„Zdd    „Zd
d „Zd d „Zdd„Zdd„Zdd„Zeedœdd„Zdd„Zdd„Z dd„Z!Gdd„de"ƒZ#Gdd „d e"ƒZ$d!d"„Z%d#d$„Z&d,d%d&„Z'd'd(„Z(d-d*d+„Z)dS).z
Utils for Mac OS platform.
éN)ÚLC_BUILD_VERSIONÚLC_CODE_SIGNATUREÚ LC_SEGMENT_64Ú    LC_SYMTABÚLC_VERSION_MIN_MACOSX)ÚMachO)Ú base_prefixcCstƒ}|rt |¡rdSdS)z
    Check if Python interpreter was installed via Homebrew command 'brew'.
 
    :return: True if Homebrew else otherwise.
    TF)Úget_homebrew_prefixrÚ
startswith©Z
env_prefix©r úLd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\PyInstaller/utils/osx.pyÚis_homebrew_envsrcCstƒ}|rt |¡rdSdS)z
    Check if Python interpreter was installed via Macports command 'port'.
 
    :return: True if Macports else otherwise.
    TF)Úget_macports_prefixrr
r r r r Úis_macports_env*srcCs"t d¡}tj tj |¡¡}|S)z9
    :return: Root path of the Homebrew environment.
    Zbrew©ÚshutilÚwhichÚosÚpathÚdirname©Úprefixr r r r    7s
r    cCs"t d¡}tj tj |¡¡}|S)z9
    :return: Root path of the Macports environment.
    Úportrrr r r rAs
rcCs,dd„|jDƒ}t|ƒdks$tdƒ‚|dS)zJ
    Helper that finds the version command in the given MachO header.
    cSs"g|]}|djtthkr|‘qS©r)Úcmdrr©Ú.0rr r r Ú
<listcomp>Qsz%_find_version_cmd.<locals>.<listcomp>ézGExpected exactly one LC_BUILD_VERSION or LC_VERSION_MIN_MACOSX command!r)ÚcommandsÚlenÚAssertionError)ÚheaderÚ version_cmdr r r Ú_find_version_cmdKsr%cCs(t|ƒ}|jd}t|ƒ}t|djƒS)zÙ
    Obtain the version of macOS SDK against which the given binary was built.
 
    NOTE: currently, version is retrieved only from the first arch slice in the binary.
 
    :return: (major, minor, revision) tuple
    rr)rÚheadersr%Ú _hex_tripletÚsdk)ÚfilenameÚbinaryr#r$r r r Úget_macos_sdk_versionVs
r+cCs*|d@d?}|d@d?}|d@}|||fS)Niÿéiÿééÿr )ÚversionÚmajorÚminorÚrevisionr r r r'es  r')r)ÚreturncCsZg}t|ƒjD]<}t|ƒ}|djtkr:| |dj¡q| |dj¡qtt    t
|ƒƒS)z}
    Get the -macosx-version-min used to compile a macOS binary.
 
    For fat binaries, the minimum version is selected.
    rr) rr&r%rrÚappendr/ZminosÚminÚmapr')r)Úversionsr#rr r r Úmacosx_version_minmsr8c    Cs´d|krdksntdƒ‚d|kr2dks<ntdƒ‚d|krPdksZntdƒ‚t|ƒ}|jd}t|ƒ}|d>|d>B|B|d_t|jd    ƒ}| |¡W5QRXd
S) zª
    Overwrite the macOS SDK version declared in the given binary with the specified version.
 
    NOTE: currently, only version in the first arch slice is modified.
    rr.zInvalid major version value!zInvalid minor version value!zInvalid revision value!r,r-rúrb+N)r"rr&r%r(Úopenr)Úwrite)r)r0r1r2r*r#r$Úfpr r r Úset_macos_sdk_versions
r=c    sðtj |¡}t|ƒ}|jd}dd„|jDƒ}t|ƒdksBtdƒ‚d‰‡fdd„|jDƒ}t|ƒdksntd    ƒ‚|dd}d
d„|jDƒ}t|ƒdksžtd ƒ‚|dd}||j|j    |_
||j|j |_ t |jƒ d ¡râd nd}t |j |¡||_t|dƒ‰| ˆ¡W5QRX|jrìddlm}m}    m‰m‰m}
t|dƒœ‰|
 ˆ¡} | j|kr~‡‡fdd„t| jƒDƒ} n&| j|    kr¤‡‡fdd„t| jƒDƒ} | d} || j| _ ˆ !d¡|  "ˆ¡| D]} |  "ˆ¡qÐW5QRXdS)a
    Fixes the Mach-O headers to make code signing possible.
 
    Code signing on Mac OS does not work out of the box with embedding .pkg archive into the executable.
 
    The fix is done this way:
    - Make the embedded .pkg archive part of the Mach-O 'String Table'. 'String Table' is at end of the Mac OS exe file,
      so just change the size of the table to cover the end of the file.
    - Fix the size of the __LINKEDIT segment.
 
    Note: the above fix works only if the single-arch thin executable or the last arch slice in a multi-arch fat
    executable is not signed, because LC_CODE_SIGNATURE comes after LC_SYMTAB, and because modification of headers
    invalidates the code signature. On modern arm64 macOS, code signature is mandatory, and therefore compilers
    create a dummy signature when executable is built. In such cases, that signature needs to be removed before this
    function is called.
 
    Mach-O format specification: http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/Mach-O.5.html
    éÿÿÿÿcSsg|]}|djtkr|‘qSr)rrrr r r r²sz,fix_exe_for_code_signing.<locals>.<listcomp>rz#Executable contains code signature!s__LINKEDITcs,g|]$}|djtkr|djˆkr|‘qS)rr)rrZsegnamer)Ú__LINKEDIT_NAMEr r r·srz(Expected exactly one __LINKEDIT segment!cSsg|]}|djtkr|‘qSr)rrrr r r r»sz$Expected exactly one SYMTAB section!Úarm64i@ir9)Ú    FAT_MAGICÚ FAT_MAGIC_64Úfat_archÚ
fat_arch64Ú
fat_headercsg|]}ˆ ˆ¡‘qSr ©Ú from_fileobj©rÚi)rCr<r r råscsg|]}ˆ ˆ¡‘qSr rFrH)rDr<r r rçsN)#rrÚgetsizerr&r r!r"ÚoffsetZstroffZstrsizeZfileoffÚfilesizeÚ_get_arch_stringr#r
ÚmathÚceilZvmsizer:r;ÚfatÚmacholib.mach_orArBrCrDrErGÚmagicÚrangeZ    nfat_archÚsizeÚseekZ
to_fileobj)r)Ú    file_sizeÚ
executabler#Zsign_secZ linkedit_segZ
symtab_secZ    page_sizerArBrErPÚarchsÚarchr )r?rCrDr<r Úfix_exe_for_code_signing•s@ 
 
 
 
rZcCs`|j}|jd@}|dkr*|dkr$dSdSn&|dkrD|dkr>dSd    Sn |d
krPd Sd s\td ƒ‚dS)z¹
    Converts cputype and cpusubtype from mach_o.mach_header_64 into arch string comparible with lipo/codesign.
    The list of supported architectures can be found in man(1) arch.
    iÿÿÿir-Zx86_64hÚx86_64i éZarm64er@éÚi386FzUnhandled architecture!N)ÚcputypeÚ
cpusubtyper")r#r_r`r r r rMòs
rMc@seZdZdZdS)ÚInvalidBinaryErroru_
    Exception raised by Ë™get_binary_architectures˙ when it is passed an invalid binary.
    N©Ú__name__Ú
__module__Ú __qualname__Ú__doc__r r r r ra    srac@seZdZdZdS)ÚIncompatibleBinaryArchErrorzq
    Exception raised by `binary_to_target_arch` when the passed binary fails the strict architecture check.
    Nrbr r r r rgsrgc
CsTz t|ƒ}Wn,tk
r8}ztdƒ|‚W5d}~XYnXt|jƒdd„|jDƒfS)zÅ
    Inspects the given binary and returns tuple (is_fat, archs), where is_fat is boolean indicating fat/thin binary,
    and arch is list of architectures with lipo/codesign compatible names.
    zInvalid Mach-O binary!NcSsg|]}t|jƒ‘qSr )rMr#)rÚhdrr r r r sz,get_binary_architectures.<locals>.<listcomp>)rÚ
ValueErrorraÚboolrPr&)r)rWÚer r r Úget_binary_architecturess
 rlcCsNdd||d|g}tj|tjtjdd}|jrJtd|›d|j›d|j›ƒ‚d    S)
z\
    Convert the given fat binary into thin one with the specified target architecture.
    Zlipoz-thinz-outputT©ÚstdoutÚstderrÚuniversal_newlineszlipo command (ú) failed with error code ú
!
output: N)Ú
subprocessÚrunÚPIPEÚSTDOUTÚ
returncodeÚ SystemErrorrn)r)Z    thin_archÚcmd_argsÚpr r r Úconvert_binary_to_thin_arch#sr{cCs–|s|}t|ƒ\}}|dkr0|s’t|›dƒ‚nb|rl||krPt|›d|›dƒ‚t d|||¡t||ƒn&||kr’t|›d|›d|d›d    ƒ‚d
S) z‰
    Check that the given binary contains required architecture slice(s) and convert the fat binary into thin one,
    if necessary.
    Z
universal2z is not a fat binary!z does not contain slice for ú!z1Converting fat binary %s (%s) to thin binary (%s)z" is incompatible with target arch z  (has arch: rz)!N)rlrgÚloggerÚdebugr{)r)Z target_archZ display_nameZis_fatrXr r r Úbinary_to_target_arch-s  ÿrcCsVt d|¡ddd|g}tj|tjtjdd}|jrRtd|›d|j›d    |j›ƒ‚d
S) zp
    Remove the signature from all architecture slices of the given binary file using the codesign utility.
    zRemoving signature from file %rÚcodesignz--removeú--all-architecturesTrmúcodesign command (rqrrN)    r}r~rsrtrurvrwrxrn)r)ryrzr r r Úremove_signature_from_binaryIs
  rƒFcCs g}|sd}n
| d¡|r0| d¡| |¡|r>| d¡t d|¡dd|dd    d
f||f•}tj|tjtjd d }|jrœtd |›d|j›d|j    ›ƒ‚dS)zj
    Sign the binary using codesign utility. If no identity is provided, ad-hoc signing is performed.
    ú-z--options=runtimez--entitlementsz--deepzSigning file %rr€z-sz--forcerz --timestampTrmr‚rqrrN)
r4r}r~rsrtrurvrwrxrn)r)ÚidentityZentitlements_fileÚdeepÚ
extra_argsryrzr r r Ú sign_binaryTs
 
 
 
 rˆ)N)NNF)*rfrNrrsrrQrrrrrZmacholib.MachOrZPyInstaller.logÚlogÚloggingZPyInstaller.compatrÚ    getLoggerrcr}rrr    rr%r+r'ÚstrÚtupler8r=rZrMÚ    Exceptionrargrlr{rrƒrˆr r r r Ú<module> s6   
 
 
 ]