14
14
"""Common functionality between test/binary executables."""
15
15
16
16
load ("@bazel_skylib//lib:dicts.bzl" , "dicts" )
17
+ load ("@bazel_skylib//lib:structs.bzl" , "structs" )
17
18
load ("@bazel_skylib//rules:common_settings.bzl" , "BuildSettingInfo" )
18
19
load ("@rules_cc//cc:defs.bzl" , "cc_common" )
19
20
load ("//python/private:flags.bzl" , "PrecompileAddToRunfilesFlag" )
21
+ load ("//python/private:py_executable_info.bzl" , "PyExecutableInfo" )
20
22
load ("//python/private:reexports.bzl" , "BuiltinPyRuntimeInfo" )
21
23
load (
22
24
"//python/private:toolchain_types.bzl" ,
@@ -221,10 +223,14 @@ def py_executable_base_impl(ctx, *, semantics, is_test, inherited_environment =
221
223
extra_exec_runfiles = exec_result .extra_runfiles .merge (
222
224
ctx .runfiles (transitive_files = exec_result .extra_files_to_build ),
223
225
)
224
- runfiles_details = struct (
225
- default_runfiles = runfiles_details .default_runfiles .merge (extra_exec_runfiles ),
226
- data_runfiles = runfiles_details .data_runfiles .merge (extra_exec_runfiles ),
227
- )
226
+
227
+ # Copy any existing fields in case of company patches.
228
+ runfiles_details = struct (** (
229
+ structs .to_dict (runfiles_details ) | dict (
230
+ default_runfiles = runfiles_details .default_runfiles .merge (extra_exec_runfiles ),
231
+ data_runfiles = runfiles_details .data_runfiles .merge (extra_exec_runfiles ),
232
+ )
233
+ ))
228
234
229
235
return _create_providers (
230
236
ctx = ctx ,
@@ -400,8 +406,8 @@ def _get_base_runfiles_for_binary(
400
406
semantics ):
401
407
"""Returns the set of runfiles necessary prior to executable creation.
402
408
403
- NOTE: The term "common runfiles" refers to the runfiles that both the
404
- default and data runfiles have in common .
409
+ NOTE: The term "common runfiles" refers to the runfiles that are common to
410
+ runfiles_without_exe, default_runfiles, and data_runfiles .
405
411
406
412
Args:
407
413
ctx: The rule ctx.
@@ -418,6 +424,8 @@ def _get_base_runfiles_for_binary(
418
424
struct with attributes:
419
425
* default_runfiles: The default runfiles
420
426
* data_runfiles: The data runfiles
427
+ * runfiles_without_exe: The default runfiles, but without the executable
428
+ or files specific to the original program/executable.
421
429
"""
422
430
common_runfiles_depsets = [main_py_files ]
423
431
@@ -431,7 +439,6 @@ def _get_base_runfiles_for_binary(
431
439
common_runfiles_depsets .append (dep [PyInfo ].transitive_pyc_files )
432
440
433
441
common_runfiles = collect_runfiles (ctx , depset (
434
- direct = [executable ],
435
442
transitive = common_runfiles_depsets ,
436
443
))
437
444
if extra_deps :
@@ -447,22 +454,27 @@ def _get_base_runfiles_for_binary(
447
454
runfiles = common_runfiles ,
448
455
)
449
456
457
+ # Don't include build_data.txt in the non-exe runfiles. The build data
458
+ # may contain program-specific content (e.g. target name).
459
+ runfiles_with_exe = common_runfiles .merge (ctx .runfiles ([executable ]))
460
+
450
461
# Don't include build_data.txt in data runfiles. This allows binaries to
451
462
# contain other binaries while still using the same fixed location symlink
452
463
# for the build_data.txt file. Really, the fixed location symlink should be
453
464
# removed and another way found to locate the underlying build data file.
454
- data_runfiles = common_runfiles
465
+ data_runfiles = runfiles_with_exe
455
466
456
467
if is_stamping_enabled (ctx , semantics ) and semantics .should_include_build_data (ctx ):
457
- default_runfiles = common_runfiles .merge (_create_runfiles_with_build_data (
468
+ default_runfiles = runfiles_with_exe .merge (_create_runfiles_with_build_data (
458
469
ctx ,
459
470
semantics .get_central_uncachable_version_file (ctx ),
460
471
semantics .get_extra_write_build_data_env (ctx ),
461
472
))
462
473
else :
463
- default_runfiles = common_runfiles
474
+ default_runfiles = runfiles_with_exe
464
475
465
476
return struct (
477
+ runfiles_without_exe = common_runfiles ,
466
478
default_runfiles = default_runfiles ,
467
479
data_runfiles = data_runfiles ,
468
480
)
@@ -814,6 +826,11 @@ def _create_providers(
814
826
),
815
827
create_instrumented_files_info (ctx ),
816
828
_create_run_environment_info (ctx , inherited_environment ),
829
+ PyExecutableInfo (
830
+ main = main_py ,
831
+ runfiles_without_exe = runfiles_details .runfiles_without_exe ,
832
+ interpreter_path = runtime_details .executable_interpreter_path ,
833
+ ),
817
834
]
818
835
819
836
# TODO(b/265840007): Make this non-conditional once Google enables
@@ -904,6 +921,7 @@ def create_base_executable_rule(*, attrs, fragments = [], **kwargs):
904
921
if "py" not in fragments :
905
922
# The list might be frozen, so use concatentation
906
923
fragments = fragments + ["py" ]
924
+ kwargs .setdefault ("provides" , []).append (PyExecutableInfo )
907
925
return rule (
908
926
# TODO: add ability to remove attrs, i.e. for imports attr
909
927
attrs = dicts .add (EXECUTABLE_ATTRS , attrs ),
0 commit comments