1// Copyright 2019 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package rust
16
17import (
18	"fmt"
19	"regexp"
20	"strings"
21
22	"android/soong/android"
23	"android/soong/cc"
24)
25
26var (
27	DylibStdlibSuffix = ".dylib-std"
28	RlibStdlibSuffix  = ".rlib-std"
29)
30
31func init() {
32	android.RegisterModuleType("rust_library", RustLibraryFactory)
33	android.RegisterModuleType("rust_library_dylib", RustLibraryDylibFactory)
34	android.RegisterModuleType("rust_library_rlib", RustLibraryRlibFactory)
35	android.RegisterModuleType("rust_library_host", RustLibraryHostFactory)
36	android.RegisterModuleType("rust_library_host_dylib", RustLibraryDylibHostFactory)
37	android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory)
38	android.RegisterModuleType("rust_ffi", RustFFIFactory)
39	android.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory)
40	android.RegisterModuleType("rust_ffi_static", RustFFIStaticFactory)
41	android.RegisterModuleType("rust_ffi_host", RustFFIHostFactory)
42	android.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory)
43	android.RegisterModuleType("rust_ffi_host_static", RustFFIStaticHostFactory)
44}
45
46type VariantLibraryProperties struct {
47	Enabled *bool    `android:"arch_variant"`
48	Srcs    []string `android:"path,arch_variant"`
49}
50
51type LibraryCompilerProperties struct {
52	Rlib   VariantLibraryProperties `android:"arch_variant"`
53	Dylib  VariantLibraryProperties `android:"arch_variant"`
54	Shared VariantLibraryProperties `android:"arch_variant"`
55	Static VariantLibraryProperties `android:"arch_variant"`
56
57	// path to include directories to pass to cc_* modules, only relevant for static/shared variants.
58	Include_dirs []string `android:"path,arch_variant"`
59
60	// Whether this library is part of the Rust toolchain sysroot.
61	Sysroot *bool
62}
63
64type LibraryMutatedProperties struct {
65	// Build a dylib variant
66	BuildDylib bool `blueprint:"mutated"`
67	// Build an rlib variant
68	BuildRlib bool `blueprint:"mutated"`
69	// Build a shared library variant
70	BuildShared bool `blueprint:"mutated"`
71	// Build a static library variant
72	BuildStatic bool `blueprint:"mutated"`
73
74	// This variant is a dylib
75	VariantIsDylib bool `blueprint:"mutated"`
76	// This variant is an rlib
77	VariantIsRlib bool `blueprint:"mutated"`
78	// This variant is a shared library
79	VariantIsShared bool `blueprint:"mutated"`
80	// This variant is a static library
81	VariantIsStatic bool `blueprint:"mutated"`
82	// This variant is a source provider
83	VariantIsSource bool `blueprint:"mutated"`
84
85	// This variant is disabled and should not be compiled
86	// (used for SourceProvider variants that produce only source)
87	VariantIsDisabled bool `blueprint:"mutated"`
88
89	// Whether this library variant should be link libstd via rlibs
90	VariantIsStaticStd bool `blueprint:"mutated"`
91}
92
93type libraryDecorator struct {
94	*baseCompiler
95	*flagExporter
96	stripper Stripper
97
98	Properties        LibraryCompilerProperties
99	MutatedProperties LibraryMutatedProperties
100	includeDirs       android.Paths
101	sourceProvider    SourceProvider
102}
103
104type libraryInterface interface {
105	rlib() bool
106	dylib() bool
107	static() bool
108	shared() bool
109	sysroot() bool
110	source() bool
111
112	// Returns true if the build options for the module have selected a particular build type
113	buildRlib() bool
114	buildDylib() bool
115	buildShared() bool
116	buildStatic() bool
117
118	// Sets a particular variant type
119	setRlib()
120	setDylib()
121	setShared()
122	setStatic()
123	setSource()
124
125	// Set libstd linkage
126	setRlibStd()
127	setDylibStd()
128
129	// Build a specific library variant
130	BuildOnlyFFI()
131	BuildOnlyRust()
132	BuildOnlyRlib()
133	BuildOnlyDylib()
134	BuildOnlyStatic()
135	BuildOnlyShared()
136}
137
138func (library *libraryDecorator) nativeCoverage() bool {
139	return true
140}
141
142func (library *libraryDecorator) rlib() bool {
143	return library.MutatedProperties.VariantIsRlib
144}
145
146func (library *libraryDecorator) sysroot() bool {
147	return Bool(library.Properties.Sysroot)
148}
149
150func (library *libraryDecorator) dylib() bool {
151	return library.MutatedProperties.VariantIsDylib
152}
153
154func (library *libraryDecorator) shared() bool {
155	return library.MutatedProperties.VariantIsShared
156}
157
158func (library *libraryDecorator) static() bool {
159	return library.MutatedProperties.VariantIsStatic
160}
161
162func (library *libraryDecorator) source() bool {
163	return library.MutatedProperties.VariantIsSource
164}
165
166func (library *libraryDecorator) buildRlib() bool {
167	return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true)
168}
169
170func (library *libraryDecorator) buildDylib() bool {
171	return library.MutatedProperties.BuildDylib && BoolDefault(library.Properties.Dylib.Enabled, true)
172}
173
174func (library *libraryDecorator) buildShared() bool {
175	return library.MutatedProperties.BuildShared && BoolDefault(library.Properties.Shared.Enabled, true)
176}
177
178func (library *libraryDecorator) buildStatic() bool {
179	return library.MutatedProperties.BuildStatic && BoolDefault(library.Properties.Static.Enabled, true)
180}
181
182func (library *libraryDecorator) setRlib() {
183	library.MutatedProperties.VariantIsRlib = true
184	library.MutatedProperties.VariantIsDylib = false
185	library.MutatedProperties.VariantIsStatic = false
186	library.MutatedProperties.VariantIsShared = false
187}
188
189func (library *libraryDecorator) setDylib() {
190	library.MutatedProperties.VariantIsRlib = false
191	library.MutatedProperties.VariantIsDylib = true
192	library.MutatedProperties.VariantIsStatic = false
193	library.MutatedProperties.VariantIsShared = false
194}
195
196func (library *libraryDecorator) setRlibStd() {
197	library.MutatedProperties.VariantIsStaticStd = true
198}
199
200func (library *libraryDecorator) setDylibStd() {
201	library.MutatedProperties.VariantIsStaticStd = false
202}
203
204func (library *libraryDecorator) setShared() {
205	library.MutatedProperties.VariantIsStatic = false
206	library.MutatedProperties.VariantIsShared = true
207	library.MutatedProperties.VariantIsRlib = false
208	library.MutatedProperties.VariantIsDylib = false
209}
210
211func (library *libraryDecorator) setStatic() {
212	library.MutatedProperties.VariantIsStatic = true
213	library.MutatedProperties.VariantIsShared = false
214	library.MutatedProperties.VariantIsRlib = false
215	library.MutatedProperties.VariantIsDylib = false
216}
217
218func (library *libraryDecorator) setSource() {
219	library.MutatedProperties.VariantIsSource = true
220}
221
222func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
223	if library.preferRlib() {
224		return rlibAutoDep
225	} else if library.rlib() || library.static() {
226		return rlibAutoDep
227	} else if library.dylib() || library.shared() {
228		return dylibAutoDep
229	} else if ctx.BazelConversionMode() {
230		// In Bazel conversion mode, we are currently ignoring the deptag, so we just need to supply a
231		// compatible tag in order to add the dependency.
232		return rlibAutoDep
233	} else {
234		panic(fmt.Errorf("autoDep called on library %q that has no enabled variants.", ctx.ModuleName()))
235	}
236}
237
238func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
239	if library.static() || library.MutatedProperties.VariantIsStaticStd {
240		return RlibLinkage
241	} else if library.baseCompiler.preferRlib() {
242		return RlibLinkage
243	}
244	return DefaultLinkage
245}
246
247var _ compiler = (*libraryDecorator)(nil)
248var _ libraryInterface = (*libraryDecorator)(nil)
249var _ exportedFlagsProducer = (*libraryDecorator)(nil)
250
251// rust_library produces all rust variants.
252func RustLibraryFactory() android.Module {
253	module, library := NewRustLibrary(android.HostAndDeviceSupported)
254	library.BuildOnlyRust()
255	return module.Init()
256}
257
258// rust_ffi produces all ffi variants.
259func RustFFIFactory() android.Module {
260	module, library := NewRustLibrary(android.HostAndDeviceSupported)
261	library.BuildOnlyFFI()
262	return module.Init()
263}
264
265// rust_library_dylib produces a dylib.
266func RustLibraryDylibFactory() android.Module {
267	module, library := NewRustLibrary(android.HostAndDeviceSupported)
268	library.BuildOnlyDylib()
269	return module.Init()
270}
271
272// rust_library_rlib produces an rlib.
273func RustLibraryRlibFactory() android.Module {
274	module, library := NewRustLibrary(android.HostAndDeviceSupported)
275	library.BuildOnlyRlib()
276	return module.Init()
277}
278
279// rust_ffi_shared produces a shared library.
280func RustFFISharedFactory() android.Module {
281	module, library := NewRustLibrary(android.HostAndDeviceSupported)
282	library.BuildOnlyShared()
283	return module.Init()
284}
285
286// rust_ffi_static produces a static library.
287func RustFFIStaticFactory() android.Module {
288	module, library := NewRustLibrary(android.HostAndDeviceSupported)
289	library.BuildOnlyStatic()
290	return module.Init()
291}
292
293// rust_library_host produces all rust variants.
294func RustLibraryHostFactory() android.Module {
295	module, library := NewRustLibrary(android.HostSupported)
296	library.BuildOnlyRust()
297	return module.Init()
298}
299
300// rust_ffi_host produces all FFI variants.
301func RustFFIHostFactory() android.Module {
302	module, library := NewRustLibrary(android.HostSupported)
303	library.BuildOnlyFFI()
304	return module.Init()
305}
306
307// rust_library_dylib_host produces a dylib.
308func RustLibraryDylibHostFactory() android.Module {
309	module, library := NewRustLibrary(android.HostSupported)
310	library.BuildOnlyDylib()
311	return module.Init()
312}
313
314// rust_library_rlib_host produces an rlib.
315func RustLibraryRlibHostFactory() android.Module {
316	module, library := NewRustLibrary(android.HostSupported)
317	library.BuildOnlyRlib()
318	return module.Init()
319}
320
321// rust_ffi_static_host produces a static library.
322func RustFFIStaticHostFactory() android.Module {
323	module, library := NewRustLibrary(android.HostSupported)
324	library.BuildOnlyStatic()
325	return module.Init()
326}
327
328// rust_ffi_shared_host produces an shared library.
329func RustFFISharedHostFactory() android.Module {
330	module, library := NewRustLibrary(android.HostSupported)
331	library.BuildOnlyShared()
332	return module.Init()
333}
334
335func (library *libraryDecorator) BuildOnlyFFI() {
336	library.MutatedProperties.BuildDylib = false
337	library.MutatedProperties.BuildRlib = false
338	library.MutatedProperties.BuildShared = true
339	library.MutatedProperties.BuildStatic = true
340}
341
342func (library *libraryDecorator) BuildOnlyRust() {
343	library.MutatedProperties.BuildDylib = true
344	library.MutatedProperties.BuildRlib = true
345	library.MutatedProperties.BuildShared = false
346	library.MutatedProperties.BuildStatic = false
347}
348
349func (library *libraryDecorator) BuildOnlyDylib() {
350	library.MutatedProperties.BuildDylib = true
351	library.MutatedProperties.BuildRlib = false
352	library.MutatedProperties.BuildShared = false
353	library.MutatedProperties.BuildStatic = false
354}
355
356func (library *libraryDecorator) BuildOnlyRlib() {
357	library.MutatedProperties.BuildDylib = false
358	library.MutatedProperties.BuildRlib = true
359	library.MutatedProperties.BuildShared = false
360	library.MutatedProperties.BuildStatic = false
361}
362
363func (library *libraryDecorator) BuildOnlyStatic() {
364	library.MutatedProperties.BuildRlib = false
365	library.MutatedProperties.BuildDylib = false
366	library.MutatedProperties.BuildShared = false
367	library.MutatedProperties.BuildStatic = true
368}
369
370func (library *libraryDecorator) BuildOnlyShared() {
371	library.MutatedProperties.BuildRlib = false
372	library.MutatedProperties.BuildDylib = false
373	library.MutatedProperties.BuildStatic = false
374	library.MutatedProperties.BuildShared = true
375}
376
377func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
378	module := newModule(hod, android.MultilibBoth)
379
380	library := &libraryDecorator{
381		MutatedProperties: LibraryMutatedProperties{
382			BuildDylib:  false,
383			BuildRlib:   false,
384			BuildShared: false,
385			BuildStatic: false,
386		},
387		baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem),
388		flagExporter: NewFlagExporter(),
389	}
390
391	module.compiler = library
392
393	return module, library
394}
395
396func (library *libraryDecorator) compilerProps() []interface{} {
397	return append(library.baseCompiler.compilerProps(),
398		&library.Properties,
399		&library.MutatedProperties,
400		&library.stripper.StripProperties)
401}
402
403func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
404	deps = library.baseCompiler.compilerDeps(ctx, deps)
405
406	if ctx.toolchain().Bionic() && (library.dylib() || library.shared()) {
407		deps = bionicDeps(ctx, deps, false)
408		deps.CrtBegin = "crtbegin_so"
409		deps.CrtEnd = "crtend_so"
410	}
411
412	return deps
413}
414
415func (library *libraryDecorator) sharedLibFilename(ctx ModuleContext) string {
416	return library.getStem(ctx) + ctx.toolchain().SharedLibSuffix()
417}
418
419func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
420	flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName())
421	flags = library.baseCompiler.compilerFlags(ctx, flags)
422	if library.shared() || library.static() {
423		library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
424	}
425	if library.shared() {
426		flags.LinkFlags = append(flags.LinkFlags, "-Wl,-soname="+library.sharedLibFilename(ctx))
427	}
428
429	return flags
430}
431
432func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
433	var outputFile android.ModuleOutPath
434	var fileName string
435	srcPath := library.srcPath(ctx, deps)
436
437	if library.sourceProvider != nil {
438		deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
439	}
440
441	flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
442	flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
443	flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
444
445	if library.dylib() {
446		// We need prefer-dynamic for now to avoid linking in the static stdlib. See:
447		// https://github.com/rust-lang/rust/issues/19680
448		// https://github.com/rust-lang/rust/issues/34909
449		flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
450	}
451
452	if library.rlib() {
453		fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
454		outputFile = android.PathForModuleOut(ctx, fileName)
455
456		TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile)
457	} else if library.dylib() {
458		fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix()
459		outputFile = android.PathForModuleOut(ctx, fileName)
460
461		TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile)
462	} else if library.static() {
463		fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
464		outputFile = android.PathForModuleOut(ctx, fileName)
465
466		TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile)
467	} else if library.shared() {
468		fileName = library.sharedLibFilename(ctx)
469		outputFile = android.PathForModuleOut(ctx, fileName)
470
471		TransformSrctoShared(ctx, srcPath, deps, flags, outputFile)
472	}
473
474	if !library.rlib() && !library.static() && library.stripper.NeedsStrip(ctx) {
475		strippedOutputFile := android.PathForModuleOut(ctx, "stripped", fileName)
476		library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)
477		library.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
478	}
479
480	if library.rlib() || library.dylib() {
481		library.flagExporter.exportLinkDirs(deps.linkDirs...)
482		library.flagExporter.exportLinkObjects(deps.linkObjects...)
483	}
484
485	if library.static() || library.shared() {
486		ctx.SetProvider(cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
487			IncludeDirs: library.includeDirs,
488		})
489	}
490
491	if library.shared() {
492		ctx.SetProvider(cc.SharedLibraryInfoProvider, cc.SharedLibraryInfo{
493			SharedLibrary:           outputFile,
494			UnstrippedSharedLibrary: outputFile,
495			Target:                  ctx.Target(),
496		})
497	}
498
499	if library.static() {
500		depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(outputFile).Build()
501		ctx.SetProvider(cc.StaticLibraryInfoProvider, cc.StaticLibraryInfo{
502			StaticLibrary: outputFile,
503
504			TransitiveStaticLibrariesForOrdering: depSet,
505		})
506	}
507
508	library.flagExporter.setProvider(ctx)
509
510	return outputFile
511}
512
513func (library *libraryDecorator) srcPath(ctx ModuleContext, deps PathDeps) android.Path {
514	if library.sourceProvider != nil {
515		// Assume the first source from the source provider is the library entry point.
516		return library.sourceProvider.Srcs()[0]
517	} else {
518		path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
519		return path
520	}
521}
522
523func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags,
524	deps PathDeps) android.OptionalPath {
525	// rustdoc has builtin support for documenting config specific information
526	// regardless of the actual config it was given
527	// (https://doc.rust-lang.org/rustdoc/advanced-features.html#cfgdoc-documenting-platform-specific-or-feature-specific-information),
528	// so we generate the rustdoc for only the primary module so that we have a
529	// single set of docs to refer to.
530	if ctx.Module() != ctx.PrimaryModule() {
531		return android.OptionalPath{}
532	}
533
534	return android.OptionalPathForPath(Rustdoc(ctx, library.srcPath(ctx, deps),
535		deps, flags))
536}
537
538func (library *libraryDecorator) getStem(ctx ModuleContext) string {
539	stem := library.baseCompiler.getStemWithoutSuffix(ctx)
540	validateLibraryStem(ctx, stem, library.crateName())
541
542	return stem + String(library.baseCompiler.Properties.Suffix)
543}
544
545func (library *libraryDecorator) install(ctx ModuleContext) {
546	// Only shared and dylib variants make sense to install.
547	if library.shared() || library.dylib() {
548		library.baseCompiler.install(ctx)
549	}
550}
551
552func (library *libraryDecorator) Disabled() bool {
553	return library.MutatedProperties.VariantIsDisabled
554}
555
556func (library *libraryDecorator) SetDisabled() {
557	library.MutatedProperties.VariantIsDisabled = true
558}
559
560var validCrateName = regexp.MustCompile("[^a-zA-Z0-9_]+")
561
562func validateLibraryStem(ctx BaseModuleContext, filename string, crate_name string) {
563	if crate_name == "" {
564		ctx.PropertyErrorf("crate_name", "crate_name must be defined.")
565	}
566
567	// crate_names are used for the library output file, and rustc expects these
568	// to be alphanumeric with underscores allowed.
569	if validCrateName.MatchString(crate_name) {
570		ctx.PropertyErrorf("crate_name",
571			"library crate_names must be alphanumeric with underscores allowed")
572	}
573
574	// Libraries are expected to begin with "lib" followed by the crate_name
575	if !strings.HasPrefix(filename, "lib"+crate_name) {
576		ctx.ModuleErrorf("Invalid name or stem property; library filenames must start with lib<crate_name>")
577	}
578}
579
580// LibraryMutator mutates the libraries into variants according to the
581// build{Rlib,Dylib} attributes.
582func LibraryMutator(mctx android.BottomUpMutatorContext) {
583	// Only mutate on Rust libraries.
584	m, ok := mctx.Module().(*Module)
585	if !ok || m.compiler == nil {
586		return
587	}
588	library, ok := m.compiler.(libraryInterface)
589	if !ok {
590		return
591	}
592
593	var variants []string
594	// The source variant is used for SourceProvider modules. The other variants (i.e. rlib and dylib)
595	// depend on this variant. It must be the first variant to be declared.
596	sourceVariant := false
597	if m.sourceProvider != nil {
598		variants = append(variants, "source")
599		sourceVariant = true
600	}
601	if library.buildRlib() {
602		variants = append(variants, rlibVariation)
603	}
604	if library.buildDylib() {
605		variants = append(variants, dylibVariation)
606	}
607
608	if len(variants) == 0 {
609		return
610	}
611	modules := mctx.CreateLocalVariations(variants...)
612
613	// The order of the variations (modules) matches the variant names provided. Iterate
614	// through the new variation modules and set their mutated properties.
615	for i, v := range modules {
616		switch variants[i] {
617		case rlibVariation:
618			v.(*Module).compiler.(libraryInterface).setRlib()
619		case dylibVariation:
620			v.(*Module).compiler.(libraryInterface).setDylib()
621			if v.(*Module).ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
622				// TODO(b/165791368)
623				// Disable dylib Vendor Ramdisk variations until we support these.
624				v.(*Module).Disable()
625			}
626		case "source":
627			v.(*Module).compiler.(libraryInterface).setSource()
628			// The source variant does not produce any library.
629			// Disable the compilation steps.
630			v.(*Module).compiler.SetDisabled()
631		}
632	}
633
634	// If a source variant is created, add an inter-variant dependency
635	// between the other variants and the source variant.
636	if sourceVariant {
637		sv := modules[0]
638		for _, v := range modules[1:] {
639			if !v.Enabled() {
640				continue
641			}
642			mctx.AddInterVariantDependency(sourceDepTag, v, sv)
643		}
644		// Alias the source variation so it can be named directly in "srcs" properties.
645		mctx.AliasVariation("source")
646	}
647}
648
649func LibstdMutator(mctx android.BottomUpMutatorContext) {
650	if m, ok := mctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() {
651		switch library := m.compiler.(type) {
652		case libraryInterface:
653			// Only create a variant if a library is actually being built.
654			if library.rlib() && !library.sysroot() {
655				variants := []string{"rlib-std", "dylib-std"}
656				modules := mctx.CreateLocalVariations(variants...)
657
658				rlib := modules[0].(*Module)
659				dylib := modules[1].(*Module)
660				rlib.compiler.(libraryInterface).setRlibStd()
661				dylib.compiler.(libraryInterface).setDylibStd()
662				if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
663					// TODO(b/165791368)
664					// Disable rlibs that link against dylib-std on vendor ramdisk variations until those dylib
665					// variants are properly supported.
666					dylib.Disable()
667				}
668				rlib.Properties.RustSubName += RlibStdlibSuffix
669				dylib.Properties.RustSubName += DylibStdlibSuffix
670			}
671		}
672	}
673}
674