@@ -371,22 +371,40 @@ def update_openssl(dirs: Dirs, env: EnvMapping) -> None:
371371 ref_loc = f"cpe:2.3:a:openssl:openssl:{ version } :*:*:*:*:*:*:*"
372372
373373 is_binary = "cpython-bin-deps" in url
374- target_dir = dirs .source / "externals" / f"openssl-{ version } "
374+ target_dir = dirs .source / "externals" / f"openssl-{ version } - { env [ 'RELENV_HOST_ARCH' ] } "
375375
376- update_props (dirs .source , r"openssl-\d+(\.\d+)*[a-z]*" , f"openssl-{ version } " )
376+ update_props (dirs .source , r"openssl-\d+(\.\d+)*[a-z]*" , f"openssl-{ version } - { env [ 'RELENV_HOST_ARCH' ] } " )
377377 # Binary deps tarball from cpython-bin-deps includes both source and binaries
378378 # We need to ensure openssl-bin-<version> is also pointed to the same place if needed
379379 update_props (
380- dirs .source , r"openssl-bin-\d+(\.\d+)*[a-z]*" , f"openssl-{ version } "
380+ dirs .source , r"openssl-bin-\d+(\.\d+)*[a-z]*" , f"openssl-{ version } - { env [ 'RELENV_HOST_ARCH' ] } "
381381 )
382382
383383 if not target_dir .exists ():
384384 get_externals_source (externals_dir = dirs .source / "externals" , url = url )
385- flatten_externals (dirs , "openssl" , version )
385+ # flatten_externals(dirs, "openssl", version) would move it to openssl-<version>
386+ # but we want openssl-<version>-<arch>.
387+ # We'll find it and move it ourselves.
388+ for d in (dirs .source / "externals" ).iterdir ():
389+ if d .is_dir () and (d .name == f"openssl-{ version } " or d .name .startswith (f"openssl-{ version } " )):
390+ if d != target_dir :
391+ if target_dir .exists ():
392+ shutil .rmtree (str (target_dir ))
393+ shutil .move (str (d ), str (target_dir ))
394+ break
395+
396+ # Now flatten if it's nested
397+ subdirs = [x for x in target_dir .iterdir () if x .is_dir ()]
398+ if len (subdirs ) == 1 and subdirs [0 ].name .startswith ("openssl" ):
399+ log .info ("Flattening nested OpenSSL" )
400+ temp_dir = target_dir .parent / f"openssl-{ version } -tmp"
401+ shutil .move (str (subdirs [0 ]), str (temp_dir ))
402+ shutil .rmtree (str (target_dir ))
403+ shutil .move (str (temp_dir ), str (target_dir ))
386404
387405 if not is_binary :
388406 # Build from source
389- log .info ("Building OpenSSL %s from source" , version )
407+ log .info ("Building OpenSSL %s (%s) from source" , version , env [ "RELENV_HOST_ARCH" ] )
390408 perl_dir = update_perl (dirs , env )
391409 perl_bin = perl_dir / "perl" / "bin" / "perl.exe"
392410
@@ -439,67 +457,67 @@ def update_openssl(dirs: Dirs, env: EnvMapping) -> None:
439457
440458 log .info ("Running OpenSSL build batch file" )
441459 runcmd ([str (build_bat )], env = build_env )
442-
443- # CPython expects binaries in a specific structure
444- # opensslOutDir = $(ExternalsDir)openssl-bin-<version)\$(ArchName)\
445- # We'll move them to match.
446- out_dir = target_dir / env ["RELENV_HOST_ARCH" ]
447- out_dir .mkdir (parents = True , exist_ok = True )
460+
461+ # CPython expects binaries in a specific structure
462+ # opensslOutDir = $(ExternalsDir)openssl-bin-<version)\$(ArchName)\
463+ # We'll move them to match.
464+ out_dir = target_dir / env ["RELENV_HOST_ARCH" ]
465+ out_dir .mkdir (parents = True , exist_ok = True )
466+
467+ prefix = target_dir / "build"
468+ bin_dir = prefix / "bin"
469+ lib_dir = prefix / "lib"
470+ inc_dir = prefix / "include"
471+
472+ if prefix .exists ():
473+ for f in bin_dir .glob ("*.dll" ):
474+ shutil .copy (str (f ), str (out_dir ))
475+ for f in bin_dir .glob ("*.pdb" ):
476+ shutil .copy (str (f ), str (out_dir ))
477+ for f in lib_dir .glob ("*.lib" ):
478+ shutil .copy (str (f ), str (out_dir ))
448479
449- prefix = target_dir / "build"
450- bin_dir = prefix / "bin"
451- lib_dir = prefix / "lib"
452- inc_dir = prefix / "include"
480+ # CPython expects headers in $(opensslOutDir)include
481+ (out_dir / "include" ).mkdir (parents = True , exist_ok = True )
482+ shutil .copytree (str (inc_dir ), str (out_dir / "include" ), dirs_exist_ok = True )
453483
454- if prefix .exists ():
455- for f in bin_dir .glob ("*.dll" ):
456- shutil .copy (str (f ), str (out_dir ))
457- for f in bin_dir .glob ("*.pdb" ):
458- shutil .copy (str (f ), str (out_dir ))
459- for f in lib_dir .glob ("*.lib" ):
460- shutil .copy (str (f ), str (out_dir ))
461-
462- # CPython expects headers in $(opensslOutDir)include
463- (out_dir / "include" ).mkdir (parents = True , exist_ok = True )
464- shutil .copytree (str (inc_dir ), str (out_dir / "include" ), dirs_exist_ok = True )
465-
466- # CPython specifically looks for applink.c in the include directory
467- if (target_dir / "ms" / "applink.c" ).exists ():
468- shutil .copy (
469- target_dir / "ms" / "applink.c" ,
470- out_dir / "include" / "applink.c" ,
471- )
472-
473- # Copy LICENSE file to out_dir to satisfy CPython build
474- for license_file in ["LICENSE" , "LICENSE.txt" , "COPYING" ]:
475- if (target_dir / license_file ).exists ():
476- shutil .copy (str (target_dir / license_file ), str (out_dir / "LICENSE" ))
484+ # CPython specifically looks for applink.c in the include directory
485+ if (target_dir / "ms" / "applink.c" ).exists ():
486+ shutil .copy (
487+ target_dir / "ms" / "applink.c" ,
488+ out_dir / "include" / "applink.c" ,
489+ )
490+
491+ # Copy LICENSE file to out_dir to satisfy CPython build
492+ for license_file in ["LICENSE" , "LICENSE.txt" , "COPYING" ]:
493+ if (target_dir / license_file ).exists ():
494+ shutil .copy (str (target_dir / license_file ), str (out_dir / "LICENSE" ))
495+ break
496+
497+ if is_binary :
498+ # Ensure include/openssl exists
499+ inc_openssl_dir = target_dir / "include" / "openssl"
500+ if not inc_openssl_dir .exists ():
501+ # Try to find headers and move them
502+ for h in target_dir .glob ("**/opensslv.h" ):
503+ if h .parent .name == "openssl" :
504+ # Found it, move its parent to include/
505+ shutil .copytree (str (h .parent ), str (inc_openssl_dir ), dirs_exist_ok = True )
477506 break
478507
479- else :
480- # Ensure include/openssl exists
481- inc_dir = target_dir / "include" / "openssl"
482- if not inc_dir .exists ():
483- # Try to find headers and move them
484- for h in target_dir .glob ("**/opensslv.h" ):
485- if h .parent .name == "openssl" :
486- # Found it, move its parent to include/
487- shutil .copytree (str (h .parent ), str (inc_dir ), dirs_exist_ok = True )
488- break
489-
490- # Ensure applink.c is in include/
491- if not (target_dir / "include" / "applink.c" ).exists ():
492- for a in target_dir .glob ("**/applink.c" ):
493- shutil .copy (str (a ), str (target_dir / "include" / "applink.c" ))
494- break
508+ # Ensure applink.c is in include/
509+ if not (target_dir / "include" / "applink.c" ).exists ():
510+ for a in target_dir .glob ("**/applink.c" ):
511+ shutil .copy (str (a ), str (target_dir / "include" / "applink.c" ))
512+ break
495513
496514 if not is_binary :
497515 # Update props to point to our custom build
498- update_props (dirs .source , r"openssl-bin-\d+(\.\d+)*[a-z]*" , f"openssl-{ version } \\ \\ { env ['RELENV_HOST_ARCH' ]} " )
516+ update_props (dirs .source , r"openssl-bin-\d+(\.\d+)*[a-z]*" , f"openssl-{ version } - { env [ 'RELENV_HOST_ARCH' ] } \\ \\ { env ['RELENV_HOST_ARCH' ]} " )
499517 # And opensslOutDir needs to be just the folder containing include
500518 patch_file (dirs .source / "PCbuild" / "python.props" ,
501- rf"<opensslOutDir Condition=\"\$\(opensslOutDir\) == ''\">\$\(ExternalsDir\)openssl-{ version } \\ \\ { env ['RELENV_HOST_ARCH' ]} \\\$\(ArchName\)\\\</opensslOutDir>" ,
502- f"<opensslOutDir Condition=\" $(opensslOutDir) == ''\" >$(ExternalsDir)openssl-{ version } \\ \\ { env ['RELENV_HOST_ARCH' ]} \\ \\ </opensslOutDir>" )
519+ rf"<opensslOutDir Condition=\"\$\(opensslOutDir\) == ''\">\$\(ExternalsDir\)openssl-{ version } - { env [ 'RELENV_HOST_ARCH' ] } \\ \\ { env ['RELENV_HOST_ARCH' ]} \\\$\(ArchName\)\\\</opensslOutDir>" ,
520+ f"<opensslOutDir Condition=\" $(opensslOutDir) == ''\" >$(ExternalsDir)openssl-{ version } - { env [ 'RELENV_HOST_ARCH' ] } \\ \\ { env ['RELENV_HOST_ARCH' ]} \\ \\ </opensslOutDir>" )
503521
504522 # Patch openssl.props to use correct DLL suffix for OpenSSL 3.x
505523 if version .startswith ("3." ):
0 commit comments