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