Skip to content

Commit 3b05f53

Browse files
authored
Instal osx python from prebuilt packagese (actions#184)
* Download osx packages and setup script * install from pkg for 3.11 only * More debug * More debug * fix version check * New-Item build_output.txt * installationTemplateLocation * fix version * fix beta version * fix building from source * fix building from source * fix pkg name * fix setup.sh * fix test * Fix config test with semver * Fix PYTHON_MAJOR_MINOR * migrate from .format to interpolation * add PYTHON_FRAMEWORK_PATH variable * improve pkg condition
1 parent a28c508 commit 3b05f53

File tree

3 files changed

+174
-5
lines changed

3 files changed

+174
-5
lines changed

builders/macos-python-builder.psm1

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,92 @@ class macOSPythonBuilder : NixPythonBuilder {
8383

8484
Execute-Command -Command $configureString
8585
}
86+
87+
[string] GetPkgName() {
88+
<#
89+
.SYNOPSIS
90+
Return Python installation Package.
91+
#>
92+
93+
$nativeVersion = Convert-Version -version $this.Version
94+
$architecture = "-macos11"
95+
$extension = ".pkg"
96+
97+
$pkg = "python-${nativeVersion}${architecture}${extension}"
98+
99+
return $pkg
100+
}
101+
102+
[uri] GetPkgUri() {
103+
<#
104+
.SYNOPSIS
105+
Get base Python URI and return complete URI for Python installation package.
106+
#>
107+
108+
$base = $this.GetBaseUri()
109+
$versionName = $this.GetBaseVersion()
110+
$pkg = $this.GetPkgName()
111+
112+
$uri = "${base}/${versionName}/${pkg}"
113+
114+
return $uri
115+
}
116+
117+
[string] DownloadPkg() {
118+
<#
119+
.SYNOPSIS
120+
Download Python installation executable into artifact location.
121+
#>
122+
123+
$pkgUri = $this.GetPkgUri()
124+
125+
Write-Host "Sources URI: $pkgUri"
126+
$pkgLocation = Download-File -Uri $pkgUri -OutputFolder $this.WorkFolderLocation
127+
Write-Debug "Done; Package location: $pkgLocation"
128+
129+
New-Item -Path $this.WorkFolderLocation -Name "build_output.txt" -ItemType File
130+
return $pkgLocation
131+
}
132+
133+
[void] CreateInstallationScriptPkg() {
134+
<#
135+
.SYNOPSIS
136+
Create Python artifact installation script based on specified template.
137+
#>
138+
139+
$installationTemplateLocation = Join-Path -Path $this.InstallationTemplatesLocation -ChildPath "macos-pkg-setup-template.sh"
140+
$installationTemplateContent = Get-Content -Path $installationTemplateLocation -Raw
141+
$installationScriptLocation = New-Item -Path $this.WorkFolderLocation -Name $this.InstallationScriptName -ItemType File
142+
143+
$variablesToReplace = @{
144+
"{{__VERSION_FULL__}}" = $this.Version;
145+
"{{__PKG_NAME__}}" = $this.GetPkgName();
146+
}
147+
148+
$variablesToReplace.keys | ForEach-Object { $installationTemplateContent = $installationTemplateContent.Replace($_, $variablesToReplace[$_]) }
149+
$installationTemplateContent | Out-File -FilePath $installationScriptLocation
150+
Write-Debug "Done; Installation script location: $installationScriptLocation)"
151+
}
152+
153+
[void] Build() {
154+
<#
155+
.SYNOPSIS
156+
Generates Python artifact from downloaded Python installation executable.
157+
#>
158+
159+
$PkgVersion = [semver]"3.11.0-beta.1"
160+
161+
if ($this.Version -ge $PkgVersion) {
162+
Write-Host "Download Python $($this.Version) [$($this.Architecture)] package..."
163+
$this.DownloadPkg()
164+
165+
Write-Host "Create installation script..."
166+
$this.CreateInstallationScriptPkg()
167+
} else {
168+
([NixPythonBuilder]$this).Build()
169+
}
170+
171+
Write-Host "Archive artifact"
172+
$this.ArchiveArtifact()
173+
}
86174
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
set -e
2+
3+
PYTHON_FULL_VERSION="{{__VERSION_FULL__}}"
4+
PYTHON_PKG_NAME="{{__PKG_NAME__}}"
5+
MAJOR_VERSION=$(echo $PYTHON_FULL_VERSION | cut -d '.' -f 1)
6+
MINOR_VERSION=$(echo $PYTHON_FULL_VERSION | cut -d '.' -f 2)
7+
8+
PYTHON_MAJOR=python$MAJOR_VERSION
9+
PYTHON_MAJOR_DOT_MINOR=python$MAJOR_VERSION.$MINOR_VERSION
10+
PYTHON_MAJOR_MINOR=python$MAJOR_VERSION$MINOR_VERSION
11+
12+
if [ -z ${AGENT_TOOLSDIRECTORY+x} ]; then
13+
# No AGENT_TOOLSDIRECTORY on GitHub images
14+
TOOLCACHE_ROOT=$RUNNER_TOOL_CACHE
15+
else
16+
TOOLCACHE_ROOT=$AGENT_TOOLSDIRECTORY
17+
fi
18+
19+
PYTHON_TOOLCACHE_PATH=$TOOLCACHE_ROOT/Python
20+
PYTHON_TOOLCACHE_VERSION_PATH=$PYTHON_TOOLCACHE_PATH/$PYTHON_FULL_VERSION
21+
PYTHON_TOOLCACHE_VERSION_ARCH_PATH=$PYTHON_TOOLCACHE_VERSION_PATH/x64
22+
PYTHON_FRAMEWORK_PATH="/Library/Frameworks/Python.framework/Versions/${MAJOR_VERSION}.${MINOR_VERSION}"
23+
24+
echo "Check if Python hostedtoolcache folder exist..."
25+
if [ ! -d $PYTHON_TOOLCACHE_PATH ]; then
26+
echo "Creating Python hostedtoolcache folder..."
27+
mkdir -p $PYTHON_TOOLCACHE_PATH
28+
else
29+
# remove ALL other directories for same major.minor python versions
30+
find $PYTHON_TOOLCACHE_PATH -name "${MAJOR_VERSION}.${MINOR_VERSION}.*"|while read python_version;do
31+
python_version_x64="$python_version/x64"
32+
if [ -e "$python_version_x64" ];then
33+
echo "Deleting Python $python_version_x64"
34+
rm -rf "$python_version_x64"
35+
fi
36+
done
37+
fi
38+
39+
echo "Install Python binaries from prebuilt package"
40+
sudo installer -pkg $PYTHON_PKG_NAME -target /
41+
42+
echo "Create hostedtoolcach symlinks (Required for the backward compatibility)"
43+
echo "Create Python $PYTHON_FULL_VERSION folder"
44+
mkdir -p $PYTHON_TOOLCACHE_VERSION_ARCH_PATH
45+
cd $PYTHON_TOOLCACHE_VERSION_ARCH_PATH
46+
47+
ln -s "${PYTHON_FRAMEWORK_PATH}/bin" bin
48+
ln -s "${PYTHON_FRAMEWORK_PATH}/include" include
49+
ln -s "${PYTHON_FRAMEWORK_PATH}/share" share
50+
ln -s "${PYTHON_FRAMEWORK_PATH}/lib" lib
51+
52+
echo "Create additional symlinks (Required for the UsePythonVersion Azure Pipelines task and the setup-python GitHub Action)"
53+
ln -s ./bin/$PYTHON_MAJOR_DOT_MINOR python
54+
55+
cd bin/
56+
ln -s $PYTHON_MAJOR_DOT_MINOR $PYTHON_MAJOR_MINOR
57+
if [ ! -f python ]; then
58+
ln -s $PYTHON_MAJOR_DOT_MINOR python
59+
fi
60+
61+
chmod +x ../python $PYTHON_MAJOR $PYTHON_MAJOR_DOT_MINOR $PYTHON_MAJOR_MINOR python
62+
63+
echo "Upgrading pip..."
64+
./python -m ensurepip
65+
./python -m pip install --ignore-installed pip --disable-pip-version-check --no-warn-script-location
66+
67+
echo "Create complete file"
68+
touch $PYTHON_TOOLCACHE_VERSION_PATH/x64.complete

tests/sources/python-config-test.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
version = sys.argv[1]
1111
nativeVersion = sys.argv[2]
1212

13+
versions=version.split(".")
14+
version_major=int(versions[0])
15+
version_minor=int(versions[1])
16+
17+
pkg_installer = os_type == 'Darwin' and (version_major == 3 and version_minor >= 11)
18+
1319
lib_dir_path = sysconfig.get_config_var('LIBDIR')
1420
ld_library_name = sysconfig.get_config_var('LDLIBRARY')
1521

@@ -19,7 +25,11 @@
1925
### Define expected variables
2026
if os_type == 'Linux': expected_ld_library_extension = 'so'
2127
if os_type == 'Darwin': expected_ld_library_extension = 'dylib'
22-
expected_lib_dir_path = '{0}/Python/{1}/x64/lib'.format(os.getenv("AGENT_TOOLSDIRECTORY"), version)
28+
29+
if pkg_installer:
30+
expected_lib_dir_path = f'/Library/Frameworks/Python.framework/Versions/{version_major}.{version_minor}/lib'
31+
else:
32+
expected_lib_dir_path = f'{os.getenv("AGENT_TOOLSDIRECTORY")}/Python/{version}/x64/lib'
2333

2434
# Check modules
2535
### Validate libraries path
@@ -38,7 +48,8 @@
3848
exit(1)
3949
else:
4050
print('%s was built without shared extensions' % ld_library_name)
41-
exit(1)
51+
if not pkg_installer:
52+
exit(1)
4253

4354
### Validate macOS
4455
if os_type == 'Darwin':
@@ -59,12 +70,14 @@
5970

6071
if openssl_includes != expected_openssl_includes:
6172
print('Invalid openssl_includes: %s; Expected: %s' % (openssl_includes, expected_openssl_includes))
62-
exit(1)
73+
if not pkg_installer:
74+
exit(1)
6375
if openssl_ldflags != expected_openssl_ldflags:
6476
print('Invalid openssl_ldflags: %s; Expected: %s' % (openssl_ldflags, expected_openssl_ldflags))
65-
exit(1)
77+
if not pkg_installer:
78+
exit(1)
6679

6780
### Validate libreadline
6881
if not have_libreadline:
6982
print('Missing libreadline')
70-
exit(1)
83+
exit(1)

0 commit comments

Comments
 (0)