2
2
Installs packages using PIP
3
3
"""
4
4
5
+ import itertools
5
6
import logging
6
7
import re
7
8
import subprocess
8
9
from email .parser import FeedParser
9
- from typing import Tuple
10
+ from typing import List , Tuple
10
11
11
12
from aws_lambda_builders .architecture import ARM64 , X86_64
12
13
from aws_lambda_builders .utils import extract_tarfile
@@ -171,19 +172,25 @@ class DependencyBuilder(object):
171
172
packager.
172
173
"""
173
174
174
- _COMPATIBLE_PLATFORM_ARM64 = {
175
+ _COMPATIBLE_PLATFORM_ARM64 = [
175
176
"any" ,
176
177
"linux_aarch64" ,
177
178
"manylinux2014_aarch64" ,
178
- }
179
+ "manylinux_2_17_aarch64" ,
180
+ "manylinux_2_28_aarch64" ,
181
+ "manylinux_2_34_aarch64" ,
182
+ ]
179
183
180
- _COMPATIBLE_PLATFORM_X86_64 = {
184
+ _COMPATIBLE_PLATFORM_X86_64 = [
181
185
"any" ,
182
186
"linux_x86_64" ,
183
187
"manylinux1_x86_64" ,
184
188
"manylinux2010_x86_64" ,
185
189
"manylinux2014_x86_64" ,
186
- }
190
+ "manylinux_2_17_x86_64" ,
191
+ "manylinux_2_28_x86_64" ,
192
+ "manylinux_2_34_x86_64" ,
193
+ ]
187
194
188
195
_COMPATIBLE_PLATFORMS = {
189
196
ARM64 : _COMPATIBLE_PLATFORM_ARM64 ,
@@ -214,6 +221,14 @@ class DependencyBuilder(object):
214
221
# Unlikely to hit this case.
215
222
_DEFAULT_GLIBC = (2 , 17 )
216
223
224
+ # Mapping of glibc version to the most recent manylinux version compatible.
225
+ # The offically supported manylinux versions are 2_17, 2_28 and 2_34 as per https://github.com/pypa/manylinux
226
+ _GLIBC_TO_LATEST_MANYLINUX = {
227
+ (2 , 17 ): "manylinux_2_17" ,
228
+ (2 , 26 ): "manylinux_2_17" ,
229
+ (2 , 34 ): "manylinux_2_34" ,
230
+ }
231
+
217
232
def __init__ (self , osutils , runtime , python_exe , pip_runner = None , architecture = X86_64 ):
218
233
"""Initialize a DependencyBuilder.
219
234
@@ -379,8 +394,60 @@ def _download_binary_wheels(self, packages, directory):
379
394
# Try to get binary wheels for each package that isn't compatible.
380
395
LOG .debug ("Downloading missing wheels: %s" , packages )
381
396
lambda_abi = get_lambda_abi (self .runtime )
382
- platform = "manylinux2014_aarch64" if self .architecture == ARM64 else "manylinux2014_x86_64"
383
- self ._pip .download_manylinux_wheels ([pkg .identifier for pkg in packages ], directory , lambda_abi , platform )
397
+ self ._pip .download_manylinux_wheels (
398
+ [pkg .identifier for pkg in packages ], directory , lambda_abi , self .compatible_platforms
399
+ )
400
+
401
+ @property
402
+ def compatible_platforms (self ) -> List [str ]:
403
+ """Get the list of all compatible platforms for the current architecture.
404
+
405
+ Examples:
406
+ ```python
407
+ # Return value with python 3.11 on x86_64
408
+ [
409
+ 'any',
410
+ 'linux_x86_64',
411
+ 'manylinux1_x86_64',
412
+ 'manylinux2010_x86_64',
413
+ 'manylinux2014_x86_64',
414
+ 'manylinux_2_17_x86_64'
415
+ ]
416
+
417
+ # Return value with python 3.12 on x86_64
418
+ [
419
+ 'any',
420
+ 'linux_x86_64',
421
+ 'manylinux1_x86_64',
422
+ 'manylinux2010_x86_64',
423
+ 'manylinux2014_x86_64',
424
+ 'manylinux_2_17_x86_64',
425
+ 'manylinux_2_28_x86_64',
426
+ 'manylinux_2_34_x86_64'
427
+ ]
428
+
429
+ # Return value with python 3.13 on ARM64
430
+ [
431
+ 'any',
432
+ 'linux_aarch64',
433
+ 'manylinux2014_aarch64',
434
+ 'manylinux_2_17_aarch64',
435
+ 'manylinux_2_28_aarch64',
436
+ 'manylinux_2_34_aarch64'
437
+ ]
438
+ ```
439
+ """
440
+ lambda_abi = get_lambda_abi (self .runtime )
441
+ manylinux_prefix = self ._GLIBC_TO_LATEST_MANYLINUX .get (self ._RUNTIME_GLIBC .get (lambda_abi , self ._DEFAULT_GLIBC ))
442
+ architecture = "aarch64" if self .architecture == ARM64 else "x86_64"
443
+
444
+ # Get the latest compatible platform tag for the current architecture,
445
+ # all the previous ones are also compatible.
446
+ latest_compatible_platform = f"{ manylinux_prefix } _{ architecture } "
447
+
448
+ all_platforms = self ._COMPATIBLE_PLATFORMS [self .architecture ]
449
+ max_index = all_platforms .index (latest_compatible_platform )
450
+ return all_platforms [: max_index + 1 ]
384
451
385
452
def _build_sdists (self , sdists , directory , compile_c = True ):
386
453
LOG .debug ("Build missing wheels from sdists " "(C compiling %s): %s" , compile_c , sdists )
@@ -432,7 +499,7 @@ def _is_compatible_platform_tag(self, expected_abi, platform):
432
499
433
500
In addition to checking the tag pattern, we also need to verify the glibc version
434
501
"""
435
- if platform in self ._COMPATIBLE_PLATFORMS [ self . architecture ] :
502
+ if platform in self .compatible_platforms :
436
503
return True
437
504
438
505
arch = "aarch64" if self .architecture == ARM64 else "x86_64"
@@ -832,7 +899,7 @@ def download_all_dependencies(self, requirements_filename, directory):
832
899
# complain at deployment time.
833
900
self .build_wheel (wheel_package_path , directory )
834
901
835
- def download_manylinux_wheels (self , packages , directory , lambda_abi , platform = "manylinux2014_x86_64" ):
902
+ def download_manylinux_wheels (self , packages , directory , lambda_abi , platforms ):
836
903
"""Download wheel files for manylinux for all the given packages."""
837
904
# If any one of these dependencies fails pip will bail out. Since we
838
905
# are only interested in all the ones we can download, we need to feed
@@ -846,8 +913,7 @@ def download_manylinux_wheels(self, packages, directory, lambda_abi, platform="m
846
913
arguments = [
847
914
"--only-binary=:all:" ,
848
915
"--no-deps" ,
849
- "--platform" ,
850
- platform ,
916
+ * list (itertools .chain .from_iterable (["--platform" , element ] for element in platforms )),
851
917
"--implementation" ,
852
918
"cp" ,
853
919
"--abi" ,
0 commit comments