Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor static / dynamic linking into build options #546

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions ci-targets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,9 @@ linux:
- "3.12"
- "3.13"
build_options:
- debug
- noopt
- lto
- debug+static
- noopt+static
- lto+static
run: true

x86_64_v2-unknown-linux-musl:
Expand All @@ -273,9 +273,9 @@ linux:
- "3.12"
- "3.13"
build_options:
- debug
- noopt
- lto
- debug+static
- noopt+static
- lto+static
run: true

x86_64_v3-unknown-linux-musl:
Expand All @@ -289,9 +289,9 @@ linux:
- "3.12"
- "3.13"
build_options:
- debug
- noopt
- lto
- debug+static
- noopt+static
- lto+static
run: true

x86_64_v4-unknown-linux-musl:
Expand All @@ -305,9 +305,9 @@ linux:
- "3.12"
- "3.13"
build_options:
- debug
- noopt
- lto
- debug+static
- noopt+static
- lto+static
run: true

windows:
Expand Down
2 changes: 1 addition & 1 deletion cpython-unix/build-cpython.sh
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ CONFIGURE_FLAGS="
--without-ensurepip
${EXTRA_CONFIGURE_FLAGS}"

if [ "${CC}" = "musl-clang" ]; then
if [ -n "${CPYTHON_STATIC}" ]; then
CFLAGS="${CFLAGS} -static"
CPPFLAGS="${CPPFLAGS} -static"
LDFLAGS="${LDFLAGS} -static"
Expand Down
9 changes: 7 additions & 2 deletions cpython-unix/build-main.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def main():
print("Unsupported build platform: %s" % sys.platform)
return 1

# Note these arguments must be synced with `build.py`
parser = argparse.ArgumentParser()

parser.add_argument(
Expand All @@ -54,10 +55,14 @@ def main():
help="Target host triple to build for",
)

optimizations = {"debug", "noopt", "pgo", "lto", "pgo+lto"}
# Construct possible options, we use a set here for canonical ordering
options = set()
options.update({"debug", "noopt", "pgo", "lto", "pgo+lto"})
options.update({f"freethreaded+{option}" for option in options})
options.update({f"{option}+static" for option in options})
parser.add_argument(
"--options",
choices=optimizations.union({f"freethreaded+{o}" for o in optimizations}),
choices=options,
default="noopt",
help="Build options to apply when compiling Python",
)
Expand Down
45 changes: 33 additions & 12 deletions cpython-unix/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ def python_build_info(
target_triple,
musl,
lto,
static,
extensions,
extra_metadata,
):
Expand All @@ -506,7 +507,7 @@ def python_build_info(
)
)

if not musl:
if not static:
bi["core"]["shared_lib"] = "install/lib/libpython%s%s.so.1.0" % (
version,
binary_suffix,
Expand Down Expand Up @@ -735,6 +736,7 @@ def build_cpython(
python_archive,
python_version=python_version,
target_triple=target_triple,
build_options=parsed_build_options,
extension_modules=ems,
)

Expand Down Expand Up @@ -825,6 +827,8 @@ def build_cpython(
env["CPYTHON_OPTIMIZED"] = "1"
if "lto" in parsed_build_options:
env["CPYTHON_LTO"] = "1"
if "static" in parsed_build_options:
env["CPYTHON_STATIC"] = "1"

add_target_env(env, host_platform, target_triple, build_env)

Expand All @@ -834,19 +838,26 @@ def build_cpython(
crt_features = []

if host_platform == "linux64":
if "musl" in target_triple:
if "static" in parsed_build_options:
crt_features.append("static")
else:
extension_module_loading.append("shared-library")
crt_features.append("glibc-dynamic")

glibc_max_version = build_env.get_file("glibc_version.txt").strip()
if not glibc_max_version:
raise Exception("failed to retrieve glibc max symbol version")
if "musl" in target_triple:
crt_features.append("musl-dynamic")
# TODO: Determine the dynamic musl libc version

crt_features.append(
"glibc-max-symbol-version:%s" % glibc_max_version.decode("ascii")
)
else:
crt_features.append("glibc-dynamic")

glibc_max_version = build_env.get_file("glibc_version.txt").strip()
if not glibc_max_version:
raise Exception("failed to retrieve glibc max symbol version")

crt_features.append(
"glibc-max-symbol-version:%s"
% glibc_max_version.decode("ascii")
)

python_symbol_visibility = "global-default"

Expand Down Expand Up @@ -874,7 +885,9 @@ def build_cpython(
"python_stdlib_test_packages": sorted(STDLIB_TEST_PACKAGES),
"python_symbol_visibility": python_symbol_visibility,
"python_extension_module_loading": extension_module_loading,
"libpython_link_mode": "static" if "musl" in target_triple else "shared",
"libpython_link_mode": (
"static" if "static" in parsed_build_options else "shared"
),
"crt_features": crt_features,
"run_tests": "build/run_tests.py",
"build_info": python_build_info(
Expand All @@ -884,6 +897,7 @@ def build_cpython(
target_triple,
"musl" in target_triple,
"lto" in parsed_build_options,
"static" in parsed_build_options,
enabled_extensions,
extra_metadata,
),
Expand Down Expand Up @@ -946,6 +960,7 @@ def main():
print("unable to connect to Docker: %s" % e, file=sys.stderr)
return 1

# Note these arguments must be synced with `build-main.py`
parser = argparse.ArgumentParser()
parser.add_argument(
"--host-platform", required=True, help="Platform we are building from"
Expand All @@ -955,13 +970,19 @@ def main():
required=True,
help="Host triple that we are building Python for",
)
optimizations = {"debug", "noopt", "pgo", "lto", "pgo+lto"}

# Construct possible options
options = set()
options.update({"debug", "noopt", "pgo", "lto", "pgo+lto"})
options.update({f"freethreaded+{option}" for option in options})
options.update({f"{option}+static" for option in options})
parser.add_argument(
"--options",
choices=optimizations.union({f"freethreaded+{o}" for o in optimizations}),
choices=options,
default="noopt",
help="Build options to apply when compiling Python",
)

parser.add_argument(
"--toolchain",
action="store_true",
Expand Down
12 changes: 6 additions & 6 deletions pythonbuild/cpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ def derive_setup_local(
cpython_source_archive,
python_version,
target_triple,
build_options,
extension_modules,
):
"""Derive the content of the Modules/Setup.local file."""
Expand Down Expand Up @@ -466,12 +467,11 @@ def derive_setup_local(
enabled_extensions[name]["setup_line"] = name.encode("ascii")
continue

# musl is static only. Ignore build-mode override.
if "musl" in target_triple:
section = "static"
else:
section = info.get("build-mode", "static")

# Force static linking if we're doing a fully static build, otherwise,
# respect the `build-mode` falling back to `static` if not defined.
section = (
"static" if "static" in build_options else info.get("build-mode", "static")
)
enabled_extensions[name]["build-mode"] = section

# Presumably this means the extension comes from the distribution's
Expand Down
17 changes: 9 additions & 8 deletions src/release.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ pub static RELEASE_TRIPLES: Lazy<BTreeMap<&'static str, TripleRelease>> = Lazy::
"freethreaded+lto",
"freethreaded+noopt",
];
let linux_suffixes_nopgo_static = vec!["debug+static", "lto+static", "noopt+static"];

h.insert(
"aarch64-unknown-linux-gnu",
Expand Down Expand Up @@ -297,35 +298,35 @@ pub static RELEASE_TRIPLES: Lazy<BTreeMap<&'static str, TripleRelease>> = Lazy::
h.insert(
"x86_64-unknown-linux-musl",
TripleRelease {
suffixes: linux_suffixes_nopgo.clone(),
install_only_suffix: "lto",
suffixes: linux_suffixes_nopgo_static.clone(),
install_only_suffix: "lto+static",
python_version_requirement: Some(VersionSpecifier::from_str("<3.14").unwrap()),
conditional_suffixes: vec![],
},
);
h.insert(
"x86_64_v2-unknown-linux-musl",
TripleRelease {
suffixes: linux_suffixes_nopgo.clone(),
install_only_suffix: "lto",
suffixes: linux_suffixes_nopgo_static.clone(),
install_only_suffix: "lto+static",
python_version_requirement: Some(VersionSpecifier::from_str("<3.14").unwrap()),
conditional_suffixes: vec![],
},
);
h.insert(
"x86_64_v3-unknown-linux-musl",
TripleRelease {
suffixes: linux_suffixes_nopgo.clone(),
install_only_suffix: "lto",
suffixes: linux_suffixes_nopgo_static.clone(),
install_only_suffix: "lto+static",
python_version_requirement: Some(VersionSpecifier::from_str("<3.14").unwrap()),
conditional_suffixes: vec![],
},
);
h.insert(
"x86_64_v4-unknown-linux-musl",
TripleRelease {
suffixes: linux_suffixes_nopgo.clone(),
install_only_suffix: "lto",
suffixes: linux_suffixes_nopgo_static.clone(),
install_only_suffix: "lto+static",
python_version_requirement: Some(VersionSpecifier::from_str("<3.14").unwrap()),
conditional_suffixes: vec![],
},
Expand Down