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