@@ -194,6 +194,10 @@ accepting arbitrary Python versions.
194
194
allow_single_file = True ,
195
195
default = "@bazel_tools//tools/python:python_bootstrap_template.txt" ,
196
196
),
197
+ "_main_module_entrypoint_template" : lambda : attrb .Label (
198
+ allow_single_file = True ,
199
+ default = "//python/private:main_module_entrypoint_template.py" ,
200
+ ),
197
201
"_launcher" : lambda : attrb .Label (
198
202
cfg = "target" ,
199
203
# NOTE: This is an executable, but is only used for Windows. It
@@ -360,9 +364,8 @@ def _create_executable(
360
364
)
361
365
else :
362
366
stage2_bootstrap = None
363
- extra_runfiles = ctx .runfiles ()
364
367
zip_main = ctx .actions .declare_file (base_executable_name + ".temp" , sibling = executable )
365
- _create_stage1_bootstrap (
368
+ extra_runfiles = _create_stage1_bootstrap (
366
369
ctx ,
367
370
output = zip_main ,
368
371
main_py = main_py ,
@@ -426,16 +429,17 @@ def _create_executable(
426
429
if bootstrap_output != None :
427
430
fail ("Should not occur: bootstrap_output should not be used " +
428
431
"when creating an executable zip" )
429
- _create_executable_zip_file (
432
+ more_runfiles = _create_executable_zip_file (
430
433
ctx ,
431
434
output = executable ,
432
435
zip_file = zip_file ,
433
436
stage2_bootstrap = stage2_bootstrap ,
434
437
runtime_details = runtime_details ,
435
438
venv = venv ,
436
439
)
440
+ extra_runfiles = extra_runfiles .merge (more_runfiles )
437
441
elif bootstrap_output :
438
- _create_stage1_bootstrap (
442
+ more_runfiles = _create_stage1_bootstrap (
439
443
ctx ,
440
444
output = bootstrap_output ,
441
445
stage2_bootstrap = stage2_bootstrap ,
@@ -445,6 +449,7 @@ def _create_executable(
445
449
main_py = main_py ,
446
450
venv = venv ,
447
451
)
452
+ extra_runfiles = extra_runfiles .merge (more_runfiles )
448
453
else :
449
454
# Otherwise, this should be the Windows case of launcher + zip.
450
455
# Double check this just to make sure.
@@ -796,6 +801,7 @@ def _create_stage1_bootstrap(
796
801
is_for_zip ,
797
802
runtime_details ,
798
803
venv = None ):
804
+ extra_runfiles = ctx .runfiles ()
799
805
runtime = runtime_details .effective_runtime
800
806
801
807
if venv :
@@ -833,9 +839,10 @@ def _create_stage1_bootstrap(
833
839
)
834
840
template = runtime .bootstrap_template
835
841
subs ["%shebang%" ] = runtime .stub_shebang
836
- elif not ctx .files .srcs :
837
- fail ("mandatory 'srcs' files have not been provided" )
838
842
else :
843
+ if not ctx .files .srcs and not ctx .attr .main_module :
844
+ fail ("mandatory 'srcs' files have not been provided" )
845
+
839
846
if (ctx .configuration .coverage_enabled and
840
847
runtime and
841
848
runtime .coverage_tool ):
@@ -855,6 +862,20 @@ def _create_stage1_bootstrap(
855
862
subs ["%coverage_tool%" ] = coverage_tool_runfiles_path
856
863
subs ["%import_all%" ] = ("True" if ctx .fragments .bazel_py .python_import_all_repositories else "False" )
857
864
subs ["%imports%" ] = ":" .join (imports .to_list ())
865
+
866
+ if ctx .attr .main_module :
867
+ main_module_entrypoint = ctx .actions .declare_file ("main_module_entrypoint.py" )
868
+ ctx .actions .expand_template (
869
+ template = ctx .file ._main_module_entrypoint_template ,
870
+ output = main_module_entrypoint ,
871
+ substitutions = {"%main_module%" : ctx .attr .main_module }
872
+ )
873
+ main_py = main_module_entrypoint
874
+ extra_runfiles = extra_runfiles .merge (ctx .runfiles ([main_module_entrypoint ]))
875
+ else :
876
+ # shouldn't happen
877
+ fail ("Neither main nor main_module was provided" )
878
+
858
879
subs ["%main%" ] = "{}/{}" .format (ctx .workspace_name , main_py .short_path )
859
880
860
881
ctx .actions .expand_template (
@@ -863,6 +884,8 @@ def _create_stage1_bootstrap(
863
884
substitutions = subs ,
864
885
)
865
886
887
+ return extra_runfiles
888
+
866
889
def _create_windows_exe_launcher (
867
890
ctx ,
868
891
* ,
@@ -985,7 +1008,7 @@ def _create_executable_zip_file(
985
1008
sibling = output ,
986
1009
)
987
1010
if stage2_bootstrap :
988
- _create_stage1_bootstrap (
1011
+ extra_runfiles = _create_stage1_bootstrap (
989
1012
ctx ,
990
1013
output = prelude ,
991
1014
stage2_bootstrap = stage2_bootstrap ,
@@ -994,6 +1017,7 @@ def _create_executable_zip_file(
994
1017
venv = venv ,
995
1018
)
996
1019
else :
1020
+ extra_runfiles = ctx .runfiles ()
997
1021
ctx .actions .write (prelude , "#!/usr/bin/env python3\n " )
998
1022
999
1023
ctx .actions .run_shell (
@@ -1009,6 +1033,8 @@ def _create_executable_zip_file(
1009
1033
progress_message = "Build Python zip executable: %{label}" ,
1010
1034
)
1011
1035
1036
+ return extra_runfiles
1037
+
1012
1038
def _get_cc_details_for_binary (ctx , extra_deps ):
1013
1039
cc_info = collect_cc_info (ctx , extra_deps = extra_deps )
1014
1040
return create_cc_details_struct (
0 commit comments