xref: /aosp_15_r20/prebuilts/rust/soong/rustprebuilts.go (revision b40554a23088fb75aa6945dfe8e65169c8484da3)
1*b40554a2SAndroid Build Coastguard Worker//
2*b40554a2SAndroid Build Coastguard Worker// Copyright (C) 2021 The Android Open Source Project
3*b40554a2SAndroid Build Coastguard Worker//
4*b40554a2SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
5*b40554a2SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
6*b40554a2SAndroid Build Coastguard Worker// You may obtain a copy of the License at
7*b40554a2SAndroid Build Coastguard Worker//
8*b40554a2SAndroid Build Coastguard Worker//      http://www.apache.org/licenses/LICENSE-2.0
9*b40554a2SAndroid Build Coastguard Worker//
10*b40554a2SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
11*b40554a2SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
12*b40554a2SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*b40554a2SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
14*b40554a2SAndroid Build Coastguard Worker// limitations under the License.
15*b40554a2SAndroid Build Coastguard Worker//
16*b40554a2SAndroid Build Coastguard Worker
17*b40554a2SAndroid Build Coastguard Workerpackage rustprebuilts
18*b40554a2SAndroid Build Coastguard Worker
19*b40554a2SAndroid Build Coastguard Workerimport (
20*b40554a2SAndroid Build Coastguard Worker	"path"
21*b40554a2SAndroid Build Coastguard Worker	"path/filepath"
22*b40554a2SAndroid Build Coastguard Worker	"strings"
23*b40554a2SAndroid Build Coastguard Worker
24*b40554a2SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
25*b40554a2SAndroid Build Coastguard Worker
26*b40554a2SAndroid Build Coastguard Worker	"android/soong/android"
27*b40554a2SAndroid Build Coastguard Worker	"android/soong/rust"
28*b40554a2SAndroid Build Coastguard Worker	"android/soong/rust/config"
29*b40554a2SAndroid Build Coastguard Worker)
30*b40554a2SAndroid Build Coastguard Worker
31*b40554a2SAndroid Build Coastguard Worker// This module is used to generate the rust host stdlib prebuilts
32*b40554a2SAndroid Build Coastguard Worker// When RUST_PREBUILTS_VERSION is set, the library will generated
33*b40554a2SAndroid Build Coastguard Worker// from the given Rust version.
34*b40554a2SAndroid Build Coastguard Workerfunc init() {
35*b40554a2SAndroid Build Coastguard Worker	android.RegisterModuleType("rust_stdlib_prebuilt_host",
36*b40554a2SAndroid Build Coastguard Worker		rustHostPrebuiltSysrootLibraryFactory)
37*b40554a2SAndroid Build Coastguard Worker	android.RegisterModuleType("rust_stdlib_prebuilt_filegroup_host",
38*b40554a2SAndroid Build Coastguard Worker		rustToolchainFilegroupFactory)
39*b40554a2SAndroid Build Coastguard Worker}
40*b40554a2SAndroid Build Coastguard Worker
41*b40554a2SAndroid Build Coastguard Workerfunc getRustPrebuiltVersion(ctx android.LoadHookContext) string {
42*b40554a2SAndroid Build Coastguard Worker	return ctx.Config().GetenvWithDefault("RUST_PREBUILTS_VERSION", config.RustDefaultVersion)
43*b40554a2SAndroid Build Coastguard Worker}
44*b40554a2SAndroid Build Coastguard Worker
45*b40554a2SAndroid Build Coastguard Workerfunc getRustLibDir(ctx android.LoadHookContext) string {
46*b40554a2SAndroid Build Coastguard Worker	rustDir := getRustPrebuiltVersion(ctx)
47*b40554a2SAndroid Build Coastguard Worker	return path.Join(rustDir, "lib", "rustlib")
48*b40554a2SAndroid Build Coastguard Worker}
49*b40554a2SAndroid Build Coastguard Worker
50*b40554a2SAndroid Build Coastguard Worker// getPrebuilt returns the module relative Rust library path and the suffix hash.
51*b40554a2SAndroid Build Coastguard Workerfunc getPrebuilt(ctx android.LoadHookContext, dir, lib, extension string) (string, string) {
52*b40554a2SAndroid Build Coastguard Worker	globPath := path.Join(ctx.ModuleDir(), dir, lib) + "-*" + extension
53*b40554a2SAndroid Build Coastguard Worker	libMatches := ctx.Glob(globPath, nil)
54*b40554a2SAndroid Build Coastguard Worker
55*b40554a2SAndroid Build Coastguard Worker	if len(libMatches) != 1 {
56*b40554a2SAndroid Build Coastguard Worker		ctx.ModuleErrorf("Unexpected number of matches for prebuilt libraries at path %q, found %d matches", globPath, len(libMatches))
57*b40554a2SAndroid Build Coastguard Worker		return "", ""
58*b40554a2SAndroid Build Coastguard Worker	}
59*b40554a2SAndroid Build Coastguard Worker
60*b40554a2SAndroid Build Coastguard Worker	// Collect the suffix by trimming the extension from the Base, then removing the library name and hyphen.
61*b40554a2SAndroid Build Coastguard Worker	suffix := strings.TrimSuffix(libMatches[0].Base(), extension)[len(lib)+1:]
62*b40554a2SAndroid Build Coastguard Worker
63*b40554a2SAndroid Build Coastguard Worker	// Get the relative path from the match by trimming out the module directory.
64*b40554a2SAndroid Build Coastguard Worker	relPath := strings.TrimPrefix(libMatches[0].String(), ctx.ModuleDir()+"/")
65*b40554a2SAndroid Build Coastguard Worker
66*b40554a2SAndroid Build Coastguard Worker	return relPath, suffix
67*b40554a2SAndroid Build Coastguard Worker}
68*b40554a2SAndroid Build Coastguard Worker
69*b40554a2SAndroid Build Coastguard Workertype targetProps struct {
70*b40554a2SAndroid Build Coastguard Worker	Suffix *string
71*b40554a2SAndroid Build Coastguard Worker	Dylib  struct {
72*b40554a2SAndroid Build Coastguard Worker		Srcs []string
73*b40554a2SAndroid Build Coastguard Worker	}
74*b40554a2SAndroid Build Coastguard Worker	Rlib struct {
75*b40554a2SAndroid Build Coastguard Worker		Srcs []string
76*b40554a2SAndroid Build Coastguard Worker	}
77*b40554a2SAndroid Build Coastguard Worker	Link_dirs []string
78*b40554a2SAndroid Build Coastguard Worker	Enabled   *bool
79*b40554a2SAndroid Build Coastguard Worker}
80*b40554a2SAndroid Build Coastguard Worker
81*b40554a2SAndroid Build Coastguard Workertype props struct {
82*b40554a2SAndroid Build Coastguard Worker	Enabled *bool
83*b40554a2SAndroid Build Coastguard Worker	Target  struct {
84*b40554a2SAndroid Build Coastguard Worker		Linux_glibc_x86_64 targetProps
85*b40554a2SAndroid Build Coastguard Worker		Linux_glibc_x86    targetProps
86*b40554a2SAndroid Build Coastguard Worker		Linux_musl_x86_64  targetProps
87*b40554a2SAndroid Build Coastguard Worker		Linux_musl_x86     targetProps
88*b40554a2SAndroid Build Coastguard Worker		Darwin_x86_64      targetProps
89*b40554a2SAndroid Build Coastguard Worker	}
90*b40554a2SAndroid Build Coastguard Worker}
91*b40554a2SAndroid Build Coastguard Worker
92*b40554a2SAndroid Build Coastguard Workerfunc (target *targetProps) addPrebuiltToTarget(ctx android.LoadHookContext, libName, rustDir, platform, arch string, rlib, solib bool) {
93*b40554a2SAndroid Build Coastguard Worker	dir := path.Join(platform, rustDir, arch, "lib")
94*b40554a2SAndroid Build Coastguard Worker	target.Link_dirs = []string{dir}
95*b40554a2SAndroid Build Coastguard Worker	target.Enabled = proptools.BoolPtr(true)
96*b40554a2SAndroid Build Coastguard Worker	if rlib {
97*b40554a2SAndroid Build Coastguard Worker		rlib, suffix := getPrebuilt(ctx, dir, libName, ".rlib")
98*b40554a2SAndroid Build Coastguard Worker		target.Rlib.Srcs = []string{rlib}
99*b40554a2SAndroid Build Coastguard Worker		target.Suffix = proptools.StringPtr(suffix)
100*b40554a2SAndroid Build Coastguard Worker	}
101*b40554a2SAndroid Build Coastguard Worker	if solib {
102*b40554a2SAndroid Build Coastguard Worker		// The suffixes are the same between the dylib and the rlib,
103*b40554a2SAndroid Build Coastguard Worker		// so it's okay if we overwrite the rlib suffix
104*b40554a2SAndroid Build Coastguard Worker		var soSuffix string
105*b40554a2SAndroid Build Coastguard Worker		if strings.Contains(platform, "darwin") {
106*b40554a2SAndroid Build Coastguard Worker			soSuffix = ".dylib"
107*b40554a2SAndroid Build Coastguard Worker		} else {
108*b40554a2SAndroid Build Coastguard Worker			soSuffix = ".so"
109*b40554a2SAndroid Build Coastguard Worker		}
110*b40554a2SAndroid Build Coastguard Worker		dylib, suffix := getPrebuilt(ctx, dir, libName, soSuffix)
111*b40554a2SAndroid Build Coastguard Worker		target.Dylib.Srcs = []string{dylib}
112*b40554a2SAndroid Build Coastguard Worker		target.Suffix = proptools.StringPtr(suffix)
113*b40554a2SAndroid Build Coastguard Worker	}
114*b40554a2SAndroid Build Coastguard Worker}
115*b40554a2SAndroid Build Coastguard Worker
116*b40554a2SAndroid Build Coastguard Workerfunc constructLibProps(rlib, solib bool) func(ctx android.LoadHookContext) {
117*b40554a2SAndroid Build Coastguard Worker	return func(ctx android.LoadHookContext) {
118*b40554a2SAndroid Build Coastguard Worker		rustDir := getRustLibDir(ctx)
119*b40554a2SAndroid Build Coastguard Worker		name := android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())
120*b40554a2SAndroid Build Coastguard Worker		name = strings.Replace(name, ".rust_sysroot", "", -1)
121*b40554a2SAndroid Build Coastguard Worker
122*b40554a2SAndroid Build Coastguard Worker		p := props{}
123*b40554a2SAndroid Build Coastguard Worker		p.Enabled = proptools.BoolPtr(false)
124*b40554a2SAndroid Build Coastguard Worker
125*b40554a2SAndroid Build Coastguard Worker		if ctx.Config().BuildOS == android.Linux {
126*b40554a2SAndroid Build Coastguard Worker			p.Target.Linux_glibc_x86_64.addPrebuiltToTarget(ctx, name, rustDir, "linux-x86", "x86_64-unknown-linux-gnu", rlib, solib)
127*b40554a2SAndroid Build Coastguard Worker			p.Target.Linux_glibc_x86.addPrebuiltToTarget(ctx, name, rustDir, "linux-x86", "i686-unknown-linux-gnu", rlib, solib)
128*b40554a2SAndroid Build Coastguard Worker		} else if ctx.Config().BuildOS == android.LinuxMusl {
129*b40554a2SAndroid Build Coastguard Worker			p.Target.Linux_musl_x86_64.addPrebuiltToTarget(ctx, name, rustDir, "linux-musl-x86", "x86_64-unknown-linux-musl", rlib, solib)
130*b40554a2SAndroid Build Coastguard Worker			p.Target.Linux_musl_x86.addPrebuiltToTarget(ctx, name, rustDir, "linux-musl-x86", "i686-unknown-linux-musl", rlib, solib)
131*b40554a2SAndroid Build Coastguard Worker		} else if ctx.Config().BuildOS == android.Darwin {
132*b40554a2SAndroid Build Coastguard Worker			p.Target.Darwin_x86_64.addPrebuiltToTarget(ctx, name, rustDir, "darwin-x86", "x86_64-apple-darwin", rlib, solib)
133*b40554a2SAndroid Build Coastguard Worker		}
134*b40554a2SAndroid Build Coastguard Worker
135*b40554a2SAndroid Build Coastguard Worker		ctx.AppendProperties(&p)
136*b40554a2SAndroid Build Coastguard Worker	}
137*b40554a2SAndroid Build Coastguard Worker}
138*b40554a2SAndroid Build Coastguard Worker
139*b40554a2SAndroid Build Coastguard Workerfunc rustHostPrebuiltSysrootLibraryFactory() android.Module {
140*b40554a2SAndroid Build Coastguard Worker	module, _ := rust.NewPrebuiltLibrary(android.HostSupportedNoCross)
141*b40554a2SAndroid Build Coastguard Worker	android.AddLoadHook(module, constructLibProps( /*rlib=*/ true /*solib=*/, true))
142*b40554a2SAndroid Build Coastguard Worker	return module.Init()
143*b40554a2SAndroid Build Coastguard Worker}
144*b40554a2SAndroid Build Coastguard Worker
145*b40554a2SAndroid Build Coastguard Workertype toolchainFilegroupProperties struct {
146*b40554a2SAndroid Build Coastguard Worker	// path to toolchain files, relative to the top of the toolchain source
147*b40554a2SAndroid Build Coastguard Worker	Toolchain_srcs []string
148*b40554a2SAndroid Build Coastguard Worker}
149*b40554a2SAndroid Build Coastguard Worker
150*b40554a2SAndroid Build Coastguard Workerfunc rustToolchainFilegroupFactory() android.Module {
151*b40554a2SAndroid Build Coastguard Worker	module := android.FileGroupFactory()
152*b40554a2SAndroid Build Coastguard Worker	module.AddProperties(&toolchainFilegroupProperties{})
153*b40554a2SAndroid Build Coastguard Worker	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
154*b40554a2SAndroid Build Coastguard Worker		var toolchainProps *toolchainFilegroupProperties
155*b40554a2SAndroid Build Coastguard Worker		for _, p := range ctx.Module().GetProperties() {
156*b40554a2SAndroid Build Coastguard Worker			toolchainProperties, ok := p.(*toolchainFilegroupProperties)
157*b40554a2SAndroid Build Coastguard Worker			if ok {
158*b40554a2SAndroid Build Coastguard Worker				toolchainProps = toolchainProperties
159*b40554a2SAndroid Build Coastguard Worker			}
160*b40554a2SAndroid Build Coastguard Worker		}
161*b40554a2SAndroid Build Coastguard Worker
162*b40554a2SAndroid Build Coastguard Worker		var archTriple string
163*b40554a2SAndroid Build Coastguard Worker		if ctx.Config().BuildOS == android.Linux {
164*b40554a2SAndroid Build Coastguard Worker			if ctx.Config().BuildArch == android.X86_64 {
165*b40554a2SAndroid Build Coastguard Worker				archTriple = "x86_64-unknown-linux-gnu"
166*b40554a2SAndroid Build Coastguard Worker			} else {
167*b40554a2SAndroid Build Coastguard Worker				archTriple = "i686-unknown-linux-gnu"
168*b40554a2SAndroid Build Coastguard Worker			}
169*b40554a2SAndroid Build Coastguard Worker		} else if ctx.Config().BuildOS == android.LinuxMusl {
170*b40554a2SAndroid Build Coastguard Worker			if ctx.Config().BuildArch == android.X86_64 {
171*b40554a2SAndroid Build Coastguard Worker				archTriple = "x86_64-unknown-linux-musl"
172*b40554a2SAndroid Build Coastguard Worker			} else {
173*b40554a2SAndroid Build Coastguard Worker				archTriple = "i686-unknown-linux-musl"
174*b40554a2SAndroid Build Coastguard Worker			}
175*b40554a2SAndroid Build Coastguard Worker
176*b40554a2SAndroid Build Coastguard Worker		} else if ctx.Config().BuildOS == android.Darwin {
177*b40554a2SAndroid Build Coastguard Worker			if ctx.Config().BuildArch == android.X86_64 {
178*b40554a2SAndroid Build Coastguard Worker				archTriple = "x86_64-apple-darwin"
179*b40554a2SAndroid Build Coastguard Worker			}
180*b40554a2SAndroid Build Coastguard Worker		}
181*b40554a2SAndroid Build Coastguard Worker
182*b40554a2SAndroid Build Coastguard Worker		prefix := filepath.Join(config.HostPrebuiltTag(ctx.Config()), rust.GetRustPrebuiltVersion(ctx), "lib", "rustlib", archTriple)
183*b40554a2SAndroid Build Coastguard Worker		srcs := make([]string, 0, len(toolchainProps.Toolchain_srcs))
184*b40554a2SAndroid Build Coastguard Worker		for _, s := range toolchainProps.Toolchain_srcs {
185*b40554a2SAndroid Build Coastguard Worker			srcs = append(srcs, path.Join(prefix, s))
186*b40554a2SAndroid Build Coastguard Worker		}
187*b40554a2SAndroid Build Coastguard Worker
188*b40554a2SAndroid Build Coastguard Worker		props := struct {
189*b40554a2SAndroid Build Coastguard Worker			Srcs []string
190*b40554a2SAndroid Build Coastguard Worker		}{
191*b40554a2SAndroid Build Coastguard Worker			Srcs: srcs,
192*b40554a2SAndroid Build Coastguard Worker		}
193*b40554a2SAndroid Build Coastguard Worker		ctx.AppendProperties(&props)
194*b40554a2SAndroid Build Coastguard Worker	})
195*b40554a2SAndroid Build Coastguard Worker	return module
196*b40554a2SAndroid Build Coastguard Worker}
197