D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
proc
/
thread-self
/
root
/
opt
/
saltstack
/
salt
/
lib
/
python3.10
/
site-packages
/
relenv
/
build
/
Filename :
linux.py
back
Copy
# Copyright 2025-2026 Broadcom. # SPDX-License-Identifier: Apache-2 # mypy: ignore-errors """ The linux build process. """ from __future__ import annotations import glob import io import os import pathlib import shutil import tarfile import tempfile import time import urllib.request from typing import IO, MutableMapping from .common import ( Dirs, build_openssl, build_openssl_fips, build_sqlite, builds, finalize, get_dependency_version, update_sbom_checksums, ) from ..common import LINUX, Version, arches, runcmd ARCHES = arches[LINUX] EnvMapping = MutableMapping[str, str] # Patch for Python's setup.py PATCH = """--- ./setup.py +++ ./setup.py @@ -664,6 +664,7 @@ self.failed.append(ext.name) def add_multiarch_paths(self): + return # Debian/Ubuntu multiarch support. # https://wiki.ubuntu.com/MultiarchSpec tmpfile = os.path.join(self.build_temp, 'multiarch') """ def populate_env(env: EnvMapping, dirs: Dirs) -> None: """ Make sure we have the correct environment variables set. :param env: The environment dictionary :type env: dict :param dirs: The working directories :type dirs: ``relenv.build.common.Dirs`` """ # CC and CXX need to be to have the full path to the executable env["CC"] = f"{dirs.toolchain}/bin/{env['RELENV_HOST']}-gcc" env["CXX"] = f"{dirs.toolchain}/bin/{env['RELENV_HOST']}-g++" # Add our toolchain binaries to the path. We also add the bin directory of # our prefix so that libtirpc can find krb5-config env["PATH"] = f"{dirs.toolchain}/bin/:{dirs.prefix}/bin/:{env['PATH']}" ldflags = [ "-Wl,--build-id=sha1", f"-Wl,--rpath={dirs.prefix}/lib", f"-L{dirs.prefix}/lib", f"-L{dirs.toolchain}/{env['RELENV_HOST']}/sysroot/lib", ] env["LDFLAGS"] = " ".join(ldflags) cflags = [ "-g", f"-I{dirs.prefix}/include", f"-I{dirs.prefix}/include/readline", f"-I{dirs.prefix}/include/ncursesw", f"-I{dirs.toolchain}/{env['RELENV_HOST']}/sysroot/usr/include", ] env["CFLAGS"] = " ".join(cflags) # CPPFLAGS are needed for Python's setup.py to find the 'nessicery bits' # for things like zlib and sqlite. cpplags = [ f"-I{dirs.prefix}/include", f"-I{dirs.prefix}/include/readline", f"-I{dirs.prefix}/include/ncursesw", f"-I{dirs.toolchain}/{env['RELENV_HOST']}/sysroot/usr/include", ] # env["CXXFLAGS"] = " ".join(cpplags) env["CPPFLAGS"] = " ".join(cpplags) env["PKG_CONFIG_PATH"] = f"{dirs.prefix}/lib/pkgconfig" def build_bzip2(env: EnvMapping, dirs: Dirs, logfp: IO[str]) -> None: """ Build bzip2. :param env: The environment dictionary :type env: dict :param dirs: The working directories :type dirs: ``relenv.build.common.Dirs`` :param logfp: A handle for the log file :type logfp: file """ runcmd( [ "make", "-j8", f"PREFIX={dirs.prefix}", f"LDFLAGS={env['LDFLAGS']}", "CFLAGS=-fPIC", f"CC={env['CC']}", "BUILD=x86_64-linux-gnu", f"HOST={env['RELENV_HOST']}", "install", ], env=env, stderr=logfp, stdout=logfp, ) runcmd( [ "make", "-f", "Makefile-libbz2_so", f"CC={env['CC']}", f"LDFLAGS={env['LDFLAGS']}", "BUILD=x86_64-linux-gnu", f"HOST={env['RELENV_HOST']}", ], env=env, stderr=logfp, stdout=logfp, ) shutil.copy2("libbz2.so.1.0.8", os.path.join(dirs.prefix, "lib")) def build_libxcrypt(env: EnvMapping, dirs: Dirs, logfp: IO[str]) -> None: """ Build libxcrypt. :param env: The environment dictionary :type env: dict :param dirs: The working directories :type dirs: ``relenv.build.common.Dirs`` :param logfp: A handle for the log file :type logfp: file """ runcmd( [ "./configure", f"--prefix={dirs.prefix}", # "--enable-libgdbm-compat", f"--build={env['RELENV_BUILD']}", f"--host={env['RELENV_HOST']}", ], env=env, stderr=logfp, stdout=logfp, ) runcmd(["make", "-j8"], env=env, stderr=logfp, stdout=logfp) runcmd(["make", "install"], env=env, stderr=logfp, stdout=logfp) def build_gdbm(env: EnvMapping, dirs: Dirs, logfp: IO[str]) -> None: """ Build gdbm. :param env: The environment dictionary :type env: dict :param dirs: The working directories :type dirs: ``relenv.build.common.Dirs`` :param logfp: A handle for the log file :type logfp: file """ runcmd( [ "./configure", f"--prefix={dirs.prefix}", "--enable-libgdbm-compat", f"--build={env['RELENV_BUILD']}", f"--host={env['RELENV_HOST']}", ], env=env, stderr=logfp, stdout=logfp, ) runcmd(["make", "-j8"], env=env, stderr=logfp, stdout=logfp) runcmd(["make", "install"], env=env, stderr=logfp, stdout=logfp) def build_ncurses(env: EnvMapping, dirs: Dirs, logfp: IO[str]) -> None: """ Build ncurses. :param env: The environment dictionary :type env: dict :param dirs: The working directories :type dirs: ``relenv.build.common.Dirs`` :param logfp: A handle for the log file :type logfp: file """ configure = pathlib.Path(dirs.source) / "configure" if env["RELENV_BUILD_ARCH"] == "aarch64" or env["RELENV_HOST_ARCH"] == "aarch64": os.chdir(dirs.tmpbuild) runcmd([str(configure)], stderr=logfp, stdout=logfp) runcmd(["make", "-C", "include"], stderr=logfp, stdout=logfp) runcmd(["make", "-C", "progs", "tic"], stderr=logfp, stdout=logfp) os.chdir(dirs.source) # Configure with a prefix of '/' so things will be installed to '/lib' # instead of '/usr/local/lib'. The root of the install will be specified # via the DESTDIR make argument. runcmd( [ str(configure), "--prefix=/", "--with-shared", "--enable-termcap", "--with-termlib", "--without-cxx-shared", "--without-static", "--without-cxx", "--enable-widec", "--without-normal", "--disable-stripping", f"--with-pkg-config={dirs.prefix}/lib/pkgconfig", "--enable-pc-files", f"--build={env['RELENV_BUILD']}", f"--host={env['RELENV_HOST']}", ], env=env, stderr=logfp, stdout=logfp, ) runcmd(["make", "-j8"], env=env, stderr=logfp, stdout=logfp) ticdir = str(pathlib.Path(dirs.tmpbuild) / "progs" / "tic") runcmd( [ "make", f"DESTDIR={dirs.prefix}", f"TIC_PATH={ticdir}", "install", ], env=env, stderr=logfp, stdout=logfp, ) def build_readline(env: EnvMapping, dirs: Dirs, logfp: IO[str]) -> None: """ Build readline library. :param env: The environment dictionary :type env: dict :param dirs: The working directories :type dirs: ``relenv.build.common.Dirs`` :param logfp: A handle for the log file :type logfp: file """ env["LDFLAGS"] = f"{env['LDFLAGS']} -ltinfow" cmd = [ "./configure", f"--prefix={dirs.prefix}", ] if env["RELENV_HOST"].find("linux") > -1: cmd += [ f"--build={env['RELENV_BUILD']}", f"--host={env['RELENV_HOST']}", ] runcmd(cmd, env=env, stderr=logfp, stdout=logfp) runcmd(["make", "-j8"], env=env, stderr=logfp, stdout=logfp) runcmd(["make", "install"], env=env, stderr=logfp, stdout=logfp) def build_libffi(env: EnvMapping, dirs: Dirs, logfp: IO[str]) -> None: """ Build libffi. :param env: The environment dictionary :type env: dict :param dirs: The working directories :type dirs: ``relenv.build.common.Dirs`` :param logfp: A handle for the log file :type logfp: file """ runcmd( [ "./configure", f"--prefix={dirs.prefix}", "--disable-multi-os-directory", f"--build={env['RELENV_BUILD']}", f"--host={env['RELENV_HOST']}", ], env=env, stderr=logfp, stdout=logfp, ) # libffi doens't want to honor libdir, force install to lib instead of lib64 runcmd( ["sed", "-i", "s/lib64/lib/g", "Makefile"], env=env, stderr=logfp, stdout=logfp ) runcmd(["make", "-j8"], env=env, stderr=logfp, stdout=logfp) runcmd(["make", "install"], env=env, stderr=logfp, stdout=logfp) def build_zlib(env: EnvMapping, dirs: Dirs, logfp: IO[str]) -> None: """ Build zlib. :param env: The environment dictionary :type env: dict :param dirs: The working directories :type dirs: ``relenv.build.common.Dirs`` :param logfp: A handle for the log file :type logfp: file """ env["CFLAGS"] = f"-fPIC {env['CFLAGS']}" runcmd( [ "./configure", f"--prefix={dirs.prefix}", f"--libdir={dirs.prefix}/lib", "--shared", ], env=env, stderr=logfp, stdout=logfp, ) runcmd(["make", "-no-pie", "-j8"], env=env, stderr=logfp, stdout=logfp) runcmd(["make", "install"], env=env, stderr=logfp, stdout=logfp) def build_krb(env: EnvMapping, dirs: Dirs, logfp: IO[str]) -> None: """ Build kerberos. :param env: The environment dictionary :type env: dict :param dirs: The working directories :type dirs: ``relenv.build.common.Dirs`` :param logfp: A handle for the log file :type logfp: file """ if env["RELENV_BUILD_ARCH"] != env["RELENV_HOST_ARCH"]: env["krb5_cv_attr_constructor_destructor"] = "yes,yes" env["ac_cv_func_regcomp"] = "yes" env["ac_cv_printf_positional"] = "yes" os.chdir(dirs.source / "src") runcmd( [ "./configure", f"--prefix={dirs.prefix}", "--without-system-verto", "--without-libedit", f"--build={env['RELENV_BUILD']}", f"--host={env['RELENV_HOST']}", ], env=env, stderr=logfp, stdout=logfp, ) runcmd(["make", "-j8"], env=env, stderr=logfp, stdout=logfp) runcmd(["make", "install"], env=env, stderr=logfp, stdout=logfp) def update_expat(dirs: Dirs, env: EnvMapping) -> None: """ Update the bundled expat library to the latest version. Python ships with an older bundled expat. This function updates it to the latest version for security and bug fixes. """ # Get version from JSON expat_info = get_dependency_version("expat", "linux") if not expat_info: # No update needed, use bundled version return version = expat_info["version"] version_tag = version.replace(".", "_") url = f"https://github.com/libexpat/libexpat/releases/download/R_{version_tag}/expat-{version}.tar.xz" expat_dir = pathlib.Path(dirs.source) / "Modules" / "expat" if not expat_dir.exists(): # No expat directory, skip return # Download expat tarball tmpbuild = pathlib.Path(dirs.tmpbuild) tarball_path = tmpbuild / f"expat-{version}.tar.xz" urllib.request.urlretrieve(url, str(tarball_path)) # Extract tarball with tarfile.open(tarball_path) as tar: tar.extractall(path=str(tmpbuild)) # Copy source files to Modules/expat/ expat_source_dir = tmpbuild / f"expat-{version}" / "lib" updated_files = [] for source_file in ["*.h", "*.c"]: for file_path in glob.glob(str(expat_source_dir / source_file)): target_file = expat_dir / pathlib.Path(file_path).name # Remove old file if it exists if target_file.exists(): target_file.unlink() shutil.copy2(file_path, str(expat_dir)) updated_files.append(target_file) # Touch all updated files to ensure make rebuilds them # (The tarball may contain files with newer timestamps) now = time.time() for target_file in updated_files: os.utime(target_file, (now, now)) # Update SBOM with correct checksums for updated expat files files_to_update = {} for target_file in updated_files: # SBOM uses relative paths from Python source root relative_path = f"Modules/expat/{target_file.name}" files_to_update[relative_path] = target_file update_sbom_checksums(dirs.source, files_to_update) def build_python(env: EnvMapping, dirs: Dirs, logfp: IO[str]) -> None: """ Run the commands to build Python. :param env: The environment dictionary :type env: dict :param dirs: The working directories :type dirs: ``relenv.build.common.Dirs`` :param logfp: A handle for the log file :type logfp: file """ # Update bundled expat to latest version update_expat(dirs, env) ldflagopt = f"-Wl,--rpath={dirs.prefix}/lib" if ldflagopt not in env["LDFLAGS"]: env["LDFLAGS"] = f"{ldflagopt} {env['LDFLAGS']}" # Needed when using a toolchain even if build and host match. runcmd( [ "sed", "-i", "s/ac_cv_buggy_getaddrinfo=yes/ac_cv_buggy_getaddrinfo=no/g", "configure", ] ) runcmd( [ "sed", "-i", ( "s/ac_cv_enable_implicit_function_declaration_error=yes/" "ac_cv_enable_implicit_function_declaration_error=no/g" ), "configure", ] ) if pathlib.Path("setup.py").exists(): with tempfile.NamedTemporaryFile(mode="w", suffix="_patch") as p_file: p_file.write(PATCH) p_file.flush() runcmd( ["patch", "-p0", "-i", p_file.name], env=env, stderr=logfp, stdout=logfp, ) env["OPENSSL_CFLAGS"] = f"-I{dirs.prefix}/include -Wno-coverage-mismatch" env["OPENSSL_LDFLAGS"] = f"-L{dirs.prefix}/lib" env["CFLAGS"] = f"-Wno-coverage-mismatch {env['CFLAGS']}" runcmd( [ "sed", "-i", "s/#readline readline.c -lreadline -ltermcap/readline readline.c -lreadline -ltinfow/g", "Modules/Setup", ] ) if Version.parse_string(env["RELENV_PY_MAJOR_VERSION"]) <= Version.parse_string( "3.10" ): runcmd( [ "sed", "-i", ( "s/#_curses -lncurses -lncursesw -ltermcap _cursesmodule.c" "/_curses -lncursesw -ltinfow _cursesmodule.c/g" ), "Modules/Setup", ] ) runcmd( [ "sed", "-i", ( "s/#_curses_panel _curses_panel.c -lpanel -lncurses" "/_curses_panel _curses_panel.c -lpanelw -lncursesw/g" ), "Modules/Setup", ] ) else: env["CURSES_LIBS"] = "-lncursesw -ltinfow" env["PANEL_LIBS"] = "-lpanelw" cmd = [ "./configure", "-v", f"--prefix={dirs.prefix}", f"--with-openssl={dirs.prefix}", "--enable-optimizations", "--with-ensurepip=no", f"--build={env['RELENV_BUILD']}", f"--host={env['RELENV_HOST']}", "--disable-test-modules", "--with-ssl-default-suites=openssl", "--with-builtin-hashlib-hashes=blake2,md5,sha1,sha2,sha3", "--with-readline=readline", "--with-pkg-config=yes", ] if env["RELENV_HOST_ARCH"] != env["RELENV_BUILD_ARCH"]: # env["RELENV_CROSS"] = dirs.prefix cmd += [ f"--with-build-python={env['RELENV_NATIVE_PY']}", ] # Needed when using a toolchain even if build and host match. cmd += [ "ac_cv_file__dev_ptmx=yes", "ac_cv_file__dev_ptc=no", ] runcmd(cmd, env=env, stderr=logfp, stdout=logfp) with io.open("Modules/Setup", "a+") as fp: fp.seek(0, io.SEEK_END) fp.write("*disabled*\n" "_tkinter\n" "nsl\n" "nis\n") for _ in ["LDFLAGS", "CFLAGS", "CPPFLAGS", "CXX", "CC"]: env.pop(_) runcmd(["make", "-j8"], env=env, stderr=logfp, stdout=logfp) runcmd(["make", "install"], env=env, stderr=logfp, stdout=logfp) # RELENVCROSS=relenv/_build/aarch64-linux-gnu relenv/_build/x86_64-linux-gnu/bin/python3 -m ensurepip # python = dirs.prefix / "bin" / "python3" # if env["RELENV_BUILD_ARCH"] == "aarch64": # python = env["RELENV_NATIVE_PY"] # env["PYTHONUSERBASE"] = dirs.prefix # runcmd([str(python), "-m", "ensurepip", "-U"], env=env, stderr=logfp, stdout=logfp) build = builds.add("linux", populate_env=populate_env) # Get dependency versions from JSON (with fallback to hardcoded values) openssl_info = get_dependency_version("openssl", "linux") if openssl_info: openssl_version = openssl_info["version"] openssl_url = openssl_info["url"] openssl_checksum = openssl_info["sha256"] else: # Fallback to hardcoded values openssl_version = "3.5.4" openssl_url = "https://github.com/openssl/openssl/releases/download/openssl-{version}/openssl-{version}.tar.gz" openssl_checksum = "b75daac8e10f189abe28a076ba5905d363e4801f" build.add( "openssl", build_func=build_openssl, download={ "url": openssl_url, "version": openssl_version, "checksum": openssl_checksum, }, ) # If openssl-fips-module runs before openssl we get an error installing openssl # becuase <prefix>/lib/ossl-modules exists. build.add( "openssl-fips-module", wait_on=["openssl"], build_func=build_openssl_fips, download={ "url": "https://www.openssl.org/source/openssl-{version}.tar.gz", "version": "3.1.2", "checksum": "206036c21264e53f0196f715d81d905742e6245b", }, ) # Get libxcrypt version from JSON libxcrypt_info = get_dependency_version("libxcrypt", "linux") if libxcrypt_info: libxcrypt_version = libxcrypt_info["version"] libxcrypt_url = libxcrypt_info["url"] libxcrypt_checksum = libxcrypt_info["sha256"] else: libxcrypt_version = "4.4.38" libxcrypt_url = "https://github.com/besser82/libxcrypt/releases/download/v{version}/libxcrypt-{version}.tar.xz" libxcrypt_checksum = "9aa2fa261be6144af492e9b6bfd03bfaa47f7159" build.add( "libxcrypt", download={ "url": libxcrypt_url, "version": libxcrypt_version, "checksum": libxcrypt_checksum, }, ) # Get XZ version from JSON xz_info = get_dependency_version("xz", "linux") if xz_info: xz_version = xz_info["version"] xz_url = xz_info["url"] xz_checksum = xz_info["sha256"] else: # Fallback to hardcoded values xz_version = "5.8.1" xz_url = "http://tukaani.org/xz/xz-{version}.tar.gz" xz_checksum = "ed4d5589c4cfe84e1697bd02a9954b76af336931" build.add( "XZ", download={ "url": xz_url, "version": xz_version, "checksum": xz_checksum, }, ) # Get SQLite version from JSON sqlite_info = get_dependency_version("sqlite", "linux") if sqlite_info: sqlite_url = sqlite_info["url"] sqlite_checksum = sqlite_info["sha256"] # SQLite uses a special 7-digit version number sqlite_version_num = sqlite_info.get("sqliteversion", "3500400") else: # Fallback to hardcoded values sqlite_version_num = "3500400" sqlite_url = "https://sqlite.org/2025/sqlite-autoconf-{version}.tar.gz" sqlite_checksum = "145048005c777796dd8494aa1cfed304e8c34283" build.add( name="SQLite", build_func=build_sqlite, download={ "url": sqlite_url, "version": sqlite_version_num, "checksum": sqlite_checksum, }, ) # Get bzip2 version from JSON bzip2_info = get_dependency_version("bzip2", "linux") if bzip2_info: bzip2_version = bzip2_info["version"] bzip2_url = bzip2_info["url"] bzip2_checksum = bzip2_info["sha256"] else: bzip2_version = "1.0.8" bzip2_url = "https://sourceware.org/pub/bzip2/bzip2-{version}.tar.gz" bzip2_checksum = "bf7badf7e248e0ecf465d33c2f5aeec774209227" build.add( name="bzip2", build_func=build_bzip2, download={ "url": bzip2_url, "version": bzip2_version, "checksum": bzip2_checksum, }, ) # Get gdbm version from JSON gdbm_info = get_dependency_version("gdbm", "linux") if gdbm_info: gdbm_version = gdbm_info["version"] gdbm_url = gdbm_info["url"] gdbm_checksum = gdbm_info["sha256"] else: gdbm_version = "1.26" gdbm_url = "https://mirrors.ocf.berkeley.edu/gnu/gdbm/gdbm-{version}.tar.gz" gdbm_checksum = "6cee3657de948e691e8df26509157be950cef4d4" build.add( name="gdbm", build_func=build_gdbm, download={ "url": gdbm_url, "version": gdbm_version, "checksum": gdbm_checksum, }, ) # Get ncurses version from JSON ncurses_info = get_dependency_version("ncurses", "linux") if ncurses_info: ncurses_version = ncurses_info["version"] ncurses_url = ncurses_info["url"] ncurses_checksum = ncurses_info["sha256"] else: ncurses_version = "6.5" ncurses_url = ( "https://mirrors.ocf.berkeley.edu/gnu/ncurses/ncurses-{version}.tar.gz" ) ncurses_checksum = "cde3024ac3f9ef21eaed6f001476ea8fffcaa381" build.add( name="ncurses", build_func=build_ncurses, download={ "url": ncurses_url, "version": ncurses_version, "checksum": ncurses_checksum, }, ) # Get libffi version from JSON libffi_info = get_dependency_version("libffi", "linux") if libffi_info: libffi_version = libffi_info["version"] libffi_url = libffi_info["url"] libffi_checksum = libffi_info["sha256"] else: libffi_version = "3.5.2" libffi_url = "https://github.com/libffi/libffi/releases/download/v{version}/libffi-{version}.tar.gz" libffi_checksum = "2bd35b135b0eeb5c631e02422c9dbe786ddb626a" build.add( "libffi", build_libffi, download={ "url": libffi_url, "version": libffi_version, "checksum": libffi_checksum, }, ) # Get zlib version from JSON zlib_info = get_dependency_version("zlib", "linux") if zlib_info: zlib_version = zlib_info["version"] zlib_url = zlib_info["url"] zlib_checksum = zlib_info["sha256"] else: zlib_version = "1.3.1" zlib_url = "https://zlib.net/fossils/zlib-{version}.tar.gz" zlib_checksum = "f535367b1a11e2f9ac3bec723fb007fbc0d189e5" build.add( "zlib", build_zlib, download={ "url": zlib_url, "version": zlib_version, "checksum": zlib_checksum, }, ) # Get uuid version from JSON uuid_info = get_dependency_version("uuid", "linux") if uuid_info: uuid_ver = uuid_info["version"] uuid_url = uuid_info["url"] uuid_checksum = uuid_info["sha256"] else: uuid_ver = "1.0.3" uuid_url = "https://sourceforge.net/projects/libuuid/files/libuuid-{version}.tar.gz" uuid_checksum = "46eaedb875ae6e63677b51ec583656199241d597" build.add( "uuid", download={ "url": uuid_url, "version": uuid_ver, "checksum": uuid_checksum, }, ) # Get krb5 version from JSON krb5_info = get_dependency_version("krb5", "linux") if krb5_info: krb5_version = krb5_info["version"] krb5_url = krb5_info["url"] krb5_checksum = krb5_info["sha256"] else: krb5_version = "1.22" krb5_url = "https://kerberos.org/dist/krb5/{version}/krb5-{version}.tar.gz" krb5_checksum = "3ad930ab036a8dc3678356fbb9de9246567e7984" build.add( "krb5", build_func=build_krb, wait_on=["openssl"], download={ "url": krb5_url, "version": krb5_version, "checksum": krb5_checksum, }, ) # Get readline version from JSON readline_info = get_dependency_version("readline", "linux") if readline_info: readline_version = readline_info["version"] readline_url = readline_info["url"] readline_checksum = readline_info["sha256"] else: readline_version = "8.3" readline_url = ( "https://mirrors.ocf.berkeley.edu/gnu/readline/readline-{version}.tar.gz" ) readline_checksum = "2c05ae9350b695f69d70b47f17f092611de2081f" build.add( "readline", build_func=build_readline, wait_on=["ncurses"], download={ "url": readline_url, "version": readline_version, "checksum": readline_checksum, }, ) # Get tirpc version from JSON tirpc_info = get_dependency_version("tirpc", "linux") if tirpc_info: tirpc_version = tirpc_info["version"] tirpc_url = tirpc_info["url"] tirpc_checksum = tirpc_info["sha256"] else: tirpc_version = "1.3.4" tirpc_url = ( "https://sourceforge.net/projects/libtirpc/files/libtirpc-{version}.tar.bz2" ) tirpc_checksum = "63c800f81f823254d2706637bab551dec176b99b" build.add( "tirpc", wait_on=[ "krb5", ], download={ "url": tirpc_url, # "url": "https://downloads.sourceforge.net/projects/libtirpc/files/libtirpc-{version}.tar.bz2", "version": tirpc_version, "checksum": tirpc_checksum, }, ) build.add( "python", build_func=build_python, wait_on=[ "openssl", "libxcrypt", "XZ", "SQLite", "bzip2", "gdbm", "ncurses", "libffi", "zlib", "uuid", "krb5", "readline", "tirpc", ], download={ "url": "https://www.python.org/ftp/python/{version}/Python-{version}.tar.xz", "version": build.version, "checksum": "d31d548cd2c5ca2ae713bebe346ba15e8406633a", }, ) build.add( "relenv-finalize", build_func=finalize, wait_on=[ "python", "openssl-fips-module", ], )