xref: /aosp_15_r20/build/soong/rust/toolchain_library.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1//
2// Copyright (C) 2021 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17package rust
18
19import (
20	"path"
21	"path/filepath"
22
23	"android/soong/android"
24	"android/soong/rust/config"
25
26	"github.com/google/blueprint/proptools"
27)
28
29// This module is used to compile the rust toolchain libraries
30// When RUST_PREBUILTS_VERSION is set, the library will generated
31// from the given Rust version.
32func init() {
33	android.RegisterModuleType("rust_toolchain_library",
34		rustToolchainLibraryFactory)
35	android.RegisterModuleType("rust_toolchain_library_rlib",
36		rustToolchainLibraryRlibFactory)
37	android.RegisterModuleType("rust_toolchain_library_dylib",
38		rustToolchainLibraryDylibFactory)
39	android.RegisterModuleType("rust_toolchain_rustc_prebuilt",
40		rustToolchainRustcPrebuiltFactory)
41}
42
43type toolchainLibraryProperties struct {
44	// path to the toolchain crate root, relative to the top of the toolchain source
45	Toolchain_crate_root *string `android:"arch_variant"`
46	// path to the rest of the toolchain srcs, relative to the top of the toolchain source
47	Toolchain_srcs []string `android:"arch_variant"`
48}
49
50type toolchainLibraryDecorator struct {
51	*libraryDecorator
52	Properties toolchainLibraryProperties
53}
54
55// rust_toolchain_library produces all rust variants.
56func rustToolchainLibraryFactory() android.Module {
57	module, library := NewRustLibrary(android.HostAndDeviceSupported)
58	library.BuildOnlyRust()
59
60	return initToolchainLibrary(module, library)
61}
62
63// rust_toolchain_library_dylib produces a dylib.
64func rustToolchainLibraryDylibFactory() android.Module {
65	module, library := NewRustLibrary(android.HostAndDeviceSupported)
66	library.BuildOnlyDylib()
67
68	return initToolchainLibrary(module, library)
69}
70
71// rust_toolchain_library_rlib produces an rlib.
72func rustToolchainLibraryRlibFactory() android.Module {
73	module, library := NewRustLibrary(android.HostAndDeviceSupported)
74	library.BuildOnlyRlib()
75
76	return initToolchainLibrary(module, library)
77}
78
79func initToolchainLibrary(module *Module, library *libraryDecorator) android.Module {
80	toolchainLibrary := &toolchainLibraryDecorator{
81		libraryDecorator: library,
82	}
83	module.compiler = toolchainLibrary
84	module.AddProperties(&toolchainLibrary.Properties)
85	android.AddLoadHook(module, rustSetToolchainSource)
86
87	return module.Init()
88}
89
90func rustSetToolchainSource(ctx android.LoadHookContext) {
91	if toolchainLib, ok := ctx.Module().(*Module).compiler.(*toolchainLibraryDecorator); ok {
92		prefix := filepath.Join("linux-x86", GetRustPrebuiltVersion(ctx))
93		versionedCrateRoot := path.Join(prefix, android.String(toolchainLib.Properties.Toolchain_crate_root))
94		versionedSrcs := make([]string, len(toolchainLib.Properties.Toolchain_srcs))
95		for i, src := range toolchainLib.Properties.Toolchain_srcs {
96			versionedSrcs[i] = path.Join(prefix, src)
97		}
98
99		type props struct {
100			Crate_root *string
101			Srcs       []string
102		}
103		p := &props{}
104		p.Crate_root = &versionedCrateRoot
105		p.Srcs = versionedSrcs
106		ctx.AppendProperties(p)
107	} else {
108		ctx.ModuleErrorf("Called rustSetToolchainSource on a non-Rust Module.")
109	}
110}
111
112// GetRustPrebuiltVersion returns the RUST_PREBUILTS_VERSION env var, or the default version if it is not defined.
113func GetRustPrebuiltVersion(ctx android.LoadHookContext) string {
114	return ctx.AConfig().GetenvWithDefault("RUST_PREBUILTS_VERSION", config.RustDefaultVersion)
115}
116
117type toolchainRustcPrebuiltProperties struct {
118	// path to rustc prebuilt, relative to the top of the toolchain source
119	Toolchain_prebuilt_src *string
120	// path to deps, relative to the top of the toolchain source
121	Toolchain_deps []string
122	// path to deps, relative to module directory
123	Deps []string
124}
125
126func rustToolchainRustcPrebuiltFactory() android.Module {
127	module := android.NewPrebuiltBuildTool()
128	module.AddProperties(&toolchainRustcPrebuiltProperties{})
129	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
130		var toolchainProps *toolchainRustcPrebuiltProperties
131		for _, p := range ctx.Module().GetProperties() {
132			toolchainProperties, ok := p.(*toolchainRustcPrebuiltProperties)
133			if ok {
134				toolchainProps = toolchainProperties
135			}
136		}
137
138		if toolchainProps.Toolchain_prebuilt_src == nil {
139			ctx.PropertyErrorf("toolchain_prebuilt_src", "must set path to rustc prebuilt")
140		}
141
142		prefix := filepath.Join(config.HostPrebuiltTag(ctx.Config()), GetRustPrebuiltVersion(ctx))
143		deps := make([]string, 0, len(toolchainProps.Toolchain_deps)+len(toolchainProps.Deps))
144		for _, d := range toolchainProps.Toolchain_deps {
145			deps = append(deps, path.Join(prefix, d))
146		}
147		deps = append(deps, toolchainProps.Deps...)
148
149		props := struct {
150			Src  *string
151			Deps []string
152		}{
153			Src:  proptools.StringPtr(path.Join(prefix, *toolchainProps.Toolchain_prebuilt_src)),
154			Deps: deps,
155		}
156		ctx.AppendProperties(&props)
157	})
158	return module
159}
160