Skip to content

Default link mode to PIE on supported platforms#4481

Merged
fmeum merged 3 commits intobazel-contrib:masterfrom
alextercete:linkmode-pie-on-android
Nov 18, 2025
Merged

Default link mode to PIE on supported platforms#4481
fmeum merged 3 commits intobazel-contrib:masterfrom
alextercete:linkmode-pie-on-android

Conversation

@alextercete
Copy link
Copy Markdown
Contributor

@alextercete alextercete commented Oct 21, 2025

What type of PR is this?
Feature

What does this PR do? Why is it needed?

We now choose pie over normal when linkmode is omitted (or explicitly set to auto) and target supports it. This mirrors the behaviour of go build.

Which issues(s) does this PR fix?

Fixes #4478

Copy link
Copy Markdown
Member

@fmeum fmeum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can disable the failing test in the Bazel 6 config in the .bazelci config directory.

@fmeum fmeum requested review from Copilot and jayconrod and removed request for Copilot October 21, 2025 08:37
@alextercete alextercete force-pushed the linkmode-pie-on-android branch from 8156045 to 96f76de Compare October 21, 2025 08:55
@alextercete
Copy link
Copy Markdown
Contributor Author

@fmeum I've managed to fix the tests by adding pure = "on" to my go_binary test target.

@dzbarsky
Copy link
Copy Markdown
Contributor

Doesn't have to be in this PR, but should we try to flip the default to PIE globally? I think that would match the vanilla go toolchain?

@fmeum
Copy link
Copy Markdown
Member

fmeum commented Oct 21, 2025

Doesn't have to be in this PR, but should we try to flip the default to PIE globally? I think that would match the vanilla go toolchain?

If that's actually the case then let's do it here so that we don't have to introduce the Android special case at all.

@dzbarsky
Copy link
Copy Markdown
Contributor

If that's actually the case then let's do it here so that we don't have to introduce the Android special case at all.

Looks like it's on by default in androis/ios/macos and windows without race, but not linux/bsds.

See https://github.com/golang/go/blob/694182d77b1a0e3676214ad0e361bdbdafde33a1/src/internal/platform/supported.go#L235-L253

@fmeum
Copy link
Copy Markdown
Member

fmeum commented Oct 23, 2025

@alextercete Could you update the condition to match what native Go does?

@alextercete alextercete force-pushed the linkmode-pie-on-android branch from 96f76de to 7668b29 Compare October 23, 2025 20:05
@alextercete alextercete changed the title Default link mode to PIE on Android Default link mode to PIE on supported platforms Oct 23, 2025
@alextercete alextercete requested a review from fmeum October 23, 2025 20:31
@fmeum
Copy link
Copy Markdown
Member

fmeum commented Oct 23, 2025

@dzbarsky The failures look like cmd/internal/cov isn't available for all platforms - we may have to limit where we request it.

@dzbarsky
Copy link
Copy Markdown
Contributor

dzbarsky commented Oct 24, 2025

@dzbarsky The failures look like cmd/internal/cov isn't available for all platforms - we may have to limit where we request it.

So there's a few things going on here:

  1. cmd/internal/cov only exists in go 1.20+, but some of our tests indicate go 1.16 in their go.mod. I'm not sure if we have an actual minimum version here, but we might as well condition the inclusion of those packages on 1.20+

This patch can do it:

--- a/go/private/actions/stdlib.bzl
+++ b/go/private/actions/stdlib.bzl
@@ -143,9 +143,11 @@ def _build_stdlib(go):
     if not go.mode.pure:
         args.add("-package", "runtime/cgo")
 
-    # For bzltestutil's coverage support.
-    args.add("-package", "cmd/internal/cov")
-    args.add("-package", "cmd/internal/bio")
+    version = parse_version(go.sdk.version)
+    if version and version[0] >= 1 and version[1] >= 20:
+        # For bzltestutil's coverage support.
+        args.add("-package", "cmd/internal/cov")
+        args.add("-package", "cmd/internal/bio")

(Pulled this out into #4489)

  1. The reason this PR triggers this at all is because of the following check, which make us think we can't use the prebuilt SDK and need to build from source instead:
    go.mode.linkmode == LINKMODE_NORMAL)

    I think that line should be changed to go.mode.linkmode in (LINKMODE_NORMAL, LINKMODE_PIE) since the prebuilt SDK should be fine to use for PIE linking.

Hope that helps!

@alextercete alextercete force-pushed the linkmode-pie-on-android branch 2 times, most recently from 3fe0c0a to c5c2e60 Compare October 27, 2025 22:34
@alextercete alextercete requested a review from dzbarsky October 27, 2025 22:37
@alextercete
Copy link
Copy Markdown
Contributor Author

@dzbarsky I tried your suggestion to fix the CI failures on Windows, but they didn't work. Any other ideas?

@fmeum
Copy link
Copy Markdown
Member

fmeum commented Oct 28, 2025

cc @linzhp for mocks

@linzhp
Copy link
Copy Markdown
Contributor

linzhp commented Oct 28, 2025

We can disable that target on Windows if it's failing. We are moving the mock support to https://github.com/uber-go/mock

@alextercete alextercete force-pushed the linkmode-pie-on-android branch 3 times, most recently from 18183c8 to e0f1670 Compare October 28, 2025 14:43
@alextercete
Copy link
Copy Markdown
Contributor Author

alextercete commented Oct 28, 2025

I'm not sure if there are any targets I can disable. The new ones I've added are all tagged as manual, so shouldn't affect the build.

I've rebased onto the latest master and tried a few different ideas, but I still can't make CI pass on Windows.

@alextercete
Copy link
Copy Markdown
Contributor Author

@fmeum @dzbarsky Any advice on how to proceed?

@dzbarsky
Copy link
Copy Markdown
Contributor

@alextercete can you try marking these targets as

target_compatible_with = select({
    "@platforms//os:windows": ["@platforms//:incompatible"],
    "//conditions:default": [],
})

@alextercete alextercete force-pushed the linkmode-pie-on-android branch from b823df2 to ac416dd Compare November 3, 2025 09:28
@alextercete alextercete force-pushed the linkmode-pie-on-android branch 2 times, most recently from 65741c8 to 3dd6c63 Compare November 10, 2025 11:33
@alextercete alextercete requested a review from fmeum November 10, 2025 12:19
@alextercete
Copy link
Copy Markdown
Contributor Author

It turns out there was a legitimate failure on Windows related to testing for stripped portable executables. I've adjusted the test and now CI is green.

@alextercete alextercete force-pushed the linkmode-pie-on-android branch from 3dd6c63 to 229c608 Compare November 18, 2025 15:19
We now choose `pie` over `normal` when `linkmode` is omitted (or
explicitly set to `auto`) and target supports it. This mirrors the
behaviour of `go build`.
Go's PIE builds for Windows clear the COFF symbol table by zeroing the
header fields, so the old .symtab lookup hit a panic on every run.
Instead, the test now checks those header indicators (and falls back to
the parsed symbol list) to decide whether the binary was stripped.
@alextercete alextercete force-pushed the linkmode-pie-on-android branch from 229c608 to 80e1901 Compare November 18, 2025 15:46
@alextercete alextercete requested a review from fmeum November 18, 2025 16:26
@fmeum fmeum merged commit 2c43998 into bazel-contrib:master Nov 18, 2025
1 check passed
@dzbarsky
Copy link
Copy Markdown
Contributor

@alextercete thanks for powering through this one!

@alextercete alextercete deleted the linkmode-pie-on-android branch November 18, 2025 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Automatically select PIE when building for Android

5 participants