@@ -39,6 +39,7 @@ def rust_crate(
3939 build_script_tools ,
4040 build_script_tags ,
4141 is_proc_macro ,
42+ has_lib ,
4243 binaries ,
4344 use_legacy_rules_rust_platforms ,
4445 extra_compile_data = [],
@@ -139,43 +140,68 @@ def rust_crate(
139140
140141 deps = deps + maybe_build_script
141142
142- kwargs = dict (
143- name = name ,
144- crate_name = crate_name ,
145- version = version ,
146- srcs = srcs ,
147- compile_data = compile_data ,
148- aliases = aliases ,
149- deps = deps ,
150- data = data ,
151- crate_features = crate_features + select (
152- {_platform (k , use_legacy_rules_rust_platforms ): v for k , v in conditional_crate_features .items ()} |
153- {"//conditions:default" : []},
154- ),
155- crate_root = crate_root ,
156- edition = edition ,
157- rustc_env = rustc_env ,
158- rustc_env_files = ["cargo_toml_env_vars.env" ],
159- rustc_flags = rustc_flags + ["--cap-lints=allow" ],
160- tags = crate_tags ,
161- target_compatible_with = target_compatible_with ,
162- package_metadata = [name + "_package_metadata" ],
163- skip_deps_verification = skip_deps_verification ,
164- visibility = ["//visibility:public" ],
165- skip_per_crate_rustc_flags = True ,
166- )
143+ if not has_lib :
144+ # HACK: create a stub target so the hub's `<crate>-<version>` alias
145+ # (emitted unconditionally in rs/extensions.bzl) still resolves for
146+ # binary-only crates. Marked as incompatible so that library use
147+ # fails at analysis time. The descriptive stub name & alias make the
148+ # error self-explanatory.
149+ #
150+ # A cleaner fix would be to make the hub skip the library alias when
151+ # the crate has no library, but that is non-trivial.
152+ stub_name = name + "_no_library_only_binary"
153+ native .filegroup (
154+ name = stub_name ,
155+ tags = crate_tags ,
156+ target_compatible_with = ["@platforms//:incompatible" ],
157+ visibility = ["//visibility:public" ],
158+ )
159+ native .alias (
160+ name = name ,
161+ actual = ":" + stub_name ,
162+ tags = crate_tags ,
163+ visibility = ["//visibility:public" ],
164+ )
167165
168- if is_proc_macro :
169- (_rust_proc_macro if skip_deps_verification else rust_proc_macro )(** kwargs )
170- else :
171- (_rust_library if skip_deps_verification else rust_library )(** kwargs )
166+ if has_lib :
167+ kwargs = dict (
168+ name = name ,
169+ crate_name = crate_name ,
170+ version = version ,
171+ srcs = srcs ,
172+ compile_data = compile_data ,
173+ aliases = aliases ,
174+ deps = deps ,
175+ data = data ,
176+ crate_features = crate_features + select (
177+ {_platform (k , use_legacy_rules_rust_platforms ): v for k , v in conditional_crate_features .items ()} |
178+ {"//conditions:default" : []},
179+ ),
180+ crate_root = crate_root ,
181+ edition = edition ,
182+ rustc_env = rustc_env ,
183+ rustc_env_files = ["cargo_toml_env_vars.env" ],
184+ rustc_flags = rustc_flags + ["--cap-lints=allow" ],
185+ tags = crate_tags ,
186+ target_compatible_with = target_compatible_with ,
187+ package_metadata = [name + "_package_metadata" ],
188+ skip_deps_verification = skip_deps_verification ,
189+ visibility = ["//visibility:public" ],
190+ skip_per_crate_rustc_flags = True ,
191+ )
192+
193+ if is_proc_macro :
194+ (_rust_proc_macro if skip_deps_verification else rust_proc_macro )(** kwargs )
195+ else :
196+ (_rust_library if skip_deps_verification else rust_library )(** kwargs )
172197
198+ binary_lib_dep = [name ] if has_lib else []
173199 for binary , crate_root in binaries .items ():
174200 rust_binary (
175201 name = binary + "__bin" ,
176202 compile_data = compile_data ,
177203 aliases = aliases ,
178- deps = [ name ] + deps ,
204+ deps = binary_lib_dep + deps ,
179205 data = data ,
180206 crate_features = crate_features ,
181207 crate_root = crate_root ,
0 commit comments