Skip to content

Commit 2421823

Browse files
committed
Add sanitize_pwd feature for PWD overwriting
This logic around overwriting PWD for non-macOS builds doesn't work correctly for cross compilation. Setting this value ends up breaking `-ffile-compilation-dir`. Now if the toolchain defines the `sanitize_pwd` feature this `execution_info` logic is skipped (even if this feature does nothing). This also defines this features for all toolchains that use legacy features.
1 parent 8a95356 commit 2421823

8 files changed

Lines changed: 206 additions & 14 deletions

File tree

cc/private/link/finalize_link_action.bzl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,11 @@ def _create_action(
360360
action_name = action_name,
361361
variables = build_variables,
362362
)
363-
if "requires_darwin" not in execution_info:
364-
# This prevents gcc from writing the unpredictable (and often irrelevant)
365-
# value of getcwd() into the debug info.
363+
if not feature_configuration.is_enabled("sanitize_pwd") and "requires_darwin" not in execution_info:
364+
# Legacy behavior: prevents gcc from writing the unpredictable (and often
365+
# irrelevant) value of getcwd() into the debug info.
366+
# New toolchains should use the sanitize_pwd feature instead.
367+
# This is mostly solved with -fdebug-prefix-map, and similar flags now.
366368
env = env | {"PWD": "/proc/self/cwd"}
367369
exec_group = None
368370
toolchain = None

cc/toolchains/args/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ cc_feature_set(
1616
name = "experimental_replace_legacy_action_config_features",
1717
all_of = [
1818
":backfill_legacy_args",
19+
"//cc/toolchains/args/sanitize_pwd:feature",
1920
"//cc/toolchains/args/archiver_flags:feature",
2021
"//cc/toolchains/args/pic_flags:feature",
2122
"//cc/toolchains/args/libraries_to_link:feature",
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
load("//cc/toolchains:args.bzl", "cc_args")
2+
load("//cc/toolchains:feature.bzl", "cc_feature")
3+
4+
cc_feature(
5+
name = "feature",
6+
args = [":sanitize_pwd"],
7+
# The feature name matters: finalize_link_action.bzl checks for
8+
# "sanitize_pwd" by name to skip legacy PWD env logic.
9+
feature_name = "sanitize_pwd",
10+
visibility = ["//visibility:public"],
11+
)
12+
13+
cc_args(
14+
name = "sanitize_pwd",
15+
actions = [
16+
"//cc/toolchains/actions:ar_actions",
17+
"//cc/toolchains/actions:link_actions",
18+
"//cc/toolchains/actions:objc_fully_link",
19+
],
20+
env = select({
21+
"@platforms//os:macos": {},
22+
"//conditions:default": {"PWD": "/proc/self/cwd"},
23+
}),
24+
)

tests/cc/common/cc_binary_configured_target_tests.bzl

Lines changed: 84 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""Tests for cc_binary."""
22

3+
load("@bazel_features//:features.bzl", "bazel_features")
34
load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite")
4-
load("@rules_testing//lib:truth.bzl", "matching")
5+
load("@rules_testing//lib:truth.bzl", "matching", "subjects")
56
load("@rules_testing//lib:util.bzl", "TestingAspectInfo", "util")
67
load("//cc:action_names.bzl", "ACTION_NAMES")
78
load("//cc:cc_binary.bzl", _actual_cc_binary = "cc_binary")
@@ -300,16 +301,89 @@ def _test_missing_action_config_for_strip_is_a_rule_error_impl(env, target):
300301
matching.contains("Expected action_config for 'strip' to be configured."),
301302
)
302303

304+
def _test_sanitize_pwd_feature_enabled(name, **kwargs):
305+
"""sanitize_pwd is on by default, PWD should be set via the feature's env_set."""
306+
util.helper_target(
307+
cc_binary,
308+
name = name + "/hello",
309+
srcs = ["hello.cc"],
310+
)
311+
cc_analysis_test(
312+
name = name,
313+
impl = _test_sanitize_pwd_feature_enabled_impl,
314+
target = name + "/hello",
315+
config_settings = {
316+
"//command_line_option:platforms": str(Label("//tests/cc/testutil/toolchains:linux_x86_64")),
317+
},
318+
**kwargs
319+
)
320+
321+
def _test_sanitize_pwd_feature_enabled_impl(env, target):
322+
link_action = link_action_subject.from_target(env, target)
323+
link_action.env().get("PWD", factory = subjects.str).equals("/proc/self/cwd")
324+
325+
def _test_sanitize_pwd_feature_disabled(name, **kwargs):
326+
"""When sanitize_pwd is explicitly disabled, the legacy requires_darwin fallback still applies."""
327+
util.helper_target(
328+
cc_binary,
329+
name = name + "/hello",
330+
srcs = ["hello.cc"],
331+
)
332+
cc_analysis_test(
333+
name = name,
334+
impl = _test_sanitize_pwd_feature_disabled_impl,
335+
target = name + "/hello",
336+
config_settings = {
337+
"//command_line_option:features": ["-sanitize_pwd"],
338+
},
339+
**kwargs
340+
)
341+
342+
def _test_sanitize_pwd_feature_disabled_impl(env, target):
343+
link_action = link_action_subject.from_target(env, target)
344+
link_action.env().get("PWD", factory = subjects.str).equals("/proc/self/cwd")
345+
346+
def _test_sanitize_pwd_macos_no_pwd(name, **kwargs):
347+
"""On macOS, sanitize_pwd is enabled but should not set PWD."""
348+
util.helper_target(
349+
cc_binary,
350+
name = name + "/hello",
351+
srcs = ["hello.cc"],
352+
)
353+
cc_analysis_test(
354+
name = name,
355+
impl = _test_sanitize_pwd_macos_no_pwd_impl,
356+
target = name + "/hello",
357+
config_settings = {
358+
"//command_line_option:platforms": str(Label("//tests/cc/testutil/toolchains:macos_arm64")),
359+
},
360+
**kwargs
361+
)
362+
363+
def _test_sanitize_pwd_macos_no_pwd_impl(env, target):
364+
link_action = link_action_subject.from_target(env, target)
365+
link_action.env().keys().not_contains("PWD")
366+
303367
def cc_binary_configured_target_tests(name):
368+
tests = [
369+
_test_files_to_build,
370+
_test_headers_not_passed_to_linking_action,
371+
_test_no_duplicate_linkopts,
372+
_test_action_graph,
373+
_test_runtime_dynamic_libraries_copy_behavior,
374+
_test_pic,
375+
_test_missing_action_config_for_strip_is_a_rule_error,
376+
]
377+
378+
# sanitize_pwd is implemented in Starlark in rules_cc, requires Bazel 9+.
379+
if bazel_features.cc.cc_common_is_in_rules_cc:
380+
tests.extend([
381+
_test_sanitize_pwd_feature_enabled,
382+
_test_sanitize_pwd_feature_disabled,
383+
_test_sanitize_pwd_macos_no_pwd,
384+
])
385+
304386
test_suite(
305387
name = name,
306-
tests = [
307-
_test_files_to_build,
308-
_test_headers_not_passed_to_linking_action,
309-
_test_no_duplicate_linkopts,
310-
_test_action_graph,
311-
_test_runtime_dynamic_libraries_copy_behavior,
312-
_test_pic,
313-
_test_missing_action_config_for_strip_is_a_rule_error,
314-
],
388+
tests = tests,
315389
)

tests/cc/testutil/cc_analysis_test.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def cc_analysis_test(name, with_features = None, test_features = [], with_action
3535

3636
mock_toolchains = [
3737
"//tests/cc/testutil/toolchains:cc-toolchain-k8-compiler",
38+
"//tests/cc/testutil/toolchains:cc-toolchain-macos-compiler",
3839
] + ADDITIONAL_MOCK_TOOLCHAINS
3940

4041
config_settings = {

tests/cc/testutil/link_action_subject.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ def _link_action_subject_new(actual, meta):
1010
inputs = lambda: subjects.collection([f.short_path for f in actual.inputs.to_list()], meta = meta.derive("inputs")),
1111
outputs = lambda: subjects.collection([f.short_path for f in actual.outputs.to_list()], meta = meta.derive("outputs")),
1212
argv = lambda: subjects.collection(actual.argv, meta = meta.derive("argv")),
13+
env = lambda: subjects.dict(actual.env, meta = meta.derive("env")),
1314
)
1415

1516
def _link_action_subject_from_target(env, target):

tests/cc/testutil/toolchains/BUILD

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@ load(":cc_toolchain_config.bzl", "cc_toolchain_config")
77

88
package(default_visibility = ["//tests:__subpackages__"])
99

10+
platform(
11+
name = "linux_x86_64",
12+
constraint_values = [
13+
"@platforms//os:linux",
14+
"@platforms//cpu:x86_64",
15+
],
16+
)
17+
18+
platform(
19+
name = "macos_arm64",
20+
constraint_values = [
21+
"@platforms//os:macos",
22+
"@platforms//cpu:arm64",
23+
],
24+
)
25+
1026
toolchain_type(name = "toolchain_type")
1127

1228
toolchain_type(name = "test_runner_toolchain_type")
@@ -286,6 +302,52 @@ cc_toolchain_config(
286302
toolchain_identifier = "mock-toolchain-k8",
287303
)
288304

305+
toolchain(
306+
name = "cc-toolchain-macos-compiler",
307+
target_compatible_with = ["@platforms//os:macos"],
308+
toolchain = ":cc-compiler-macos-compiler",
309+
toolchain_type = "//cc:toolchain_type",
310+
)
311+
312+
cc_toolchain_config(
313+
name = "macos-compiler_config",
314+
abi_libc_version = "local",
315+
abi_version = "local",
316+
action_configs = [],
317+
artifact_name_patterns = {},
318+
builtin_sysroot = "/usr/grte/v1",
319+
cc_target_os = "macos",
320+
compiler = "compiler",
321+
cpu = "darwin_arm64",
322+
cxx_builtin_include_directories = [],
323+
feature_names = [],
324+
host_system_name = "local",
325+
make_variables = {},
326+
target_libc = "macosx", # NOTE: This value is read for legacy features
327+
target_system_name = "local",
328+
tool_paths = {},
329+
toolchain_identifier = "mock-toolchain-macos",
330+
)
331+
332+
cc_toolchain(
333+
name = "cc-compiler-macos-compiler",
334+
all_files = ":every-file",
335+
ar_files = "ar-k8",
336+
as_files = "as-k8",
337+
compiler_files = "compile-k8",
338+
coverage_files = "coverage-file",
339+
dwp_files = "dwp-k8",
340+
licenses = ["unencumbered"],
341+
linker_files = "link-k8",
342+
module_map = "crosstool.cppmap",
343+
objcopy_files = "objcopy-k8",
344+
output_licenses = ["unencumbered"],
345+
strip_files = ":every-file",
346+
supports_header_parsing = 1,
347+
toolchain_config = ":macos-compiler_config",
348+
toolchain_identifier = "mock-toolchain-macos",
349+
)
350+
289351
cc_toolchain(
290352
name = "cc-compiler-k8-compiler",
291353
all_files = ":every-file",

tests/cc/testutil/toolchains/cc_toolchain_config.bzl

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1495,7 +1495,34 @@ def _impl(ctx):
14951495
],
14961496
)
14971497

1498-
hard_coded_default_features = [default_compile_flags_feature, default_link_flags_feature]
1498+
sanitize_pwd_feature = feature(
1499+
name = "sanitize_pwd",
1500+
enabled = True,
1501+
env_sets = [env_set(
1502+
actions = [
1503+
ACTION_NAMES.cpp_link_executable,
1504+
ACTION_NAMES.cpp_link_dynamic_library,
1505+
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1506+
ACTION_NAMES.cpp_link_static_library,
1507+
ACTION_NAMES.lto_index_for_executable,
1508+
ACTION_NAMES.lto_index_for_dynamic_library,
1509+
ACTION_NAMES.lto_index_for_nodeps_dynamic_library,
1510+
ACTION_NAMES.objc_executable,
1511+
ACTION_NAMES.objc_fully_link,
1512+
ACTION_NAMES.objcpp_executable,
1513+
],
1514+
env_entries = [env_entry(
1515+
key = "PWD",
1516+
value = "/proc/self/cwd",
1517+
)],
1518+
)] if ctx.attr.target_libc != "macosx" else [],
1519+
)
1520+
1521+
hard_coded_default_features = [
1522+
default_compile_flags_feature,
1523+
default_link_flags_feature,
1524+
sanitize_pwd_feature,
1525+
]
14991526
cmdline_registered_features = [
15001527
_feature_name_to_feature[f]
15011528
for f in ctx.attr._with_features[BuildSettingInfo].value

0 commit comments

Comments
 (0)