1*333d2b36SAndroid Build Coastguard Worker// Copyright 2020 The Android Open Source Project 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Workerpackage rust 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "strings" 19*333d2b36SAndroid Build Coastguard Worker 20*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 21*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 22*333d2b36SAndroid Build Coastguard Worker 23*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 24*333d2b36SAndroid Build Coastguard Worker "android/soong/cc" 25*333d2b36SAndroid Build Coastguard Worker cc_config "android/soong/cc/config" 26*333d2b36SAndroid Build Coastguard Worker) 27*333d2b36SAndroid Build Coastguard Worker 28*333d2b36SAndroid Build Coastguard Workervar ( 29*333d2b36SAndroid Build Coastguard Worker defaultBindgenFlags = []string{""} 30*333d2b36SAndroid Build Coastguard Worker 31*333d2b36SAndroid Build Coastguard Worker // bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures. 32*333d2b36SAndroid Build Coastguard Worker bindgenClangVersion = "clang-r530567" 33*333d2b36SAndroid Build Coastguard Worker 34*333d2b36SAndroid Build Coastguard Worker _ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string { 35*333d2b36SAndroid Build Coastguard Worker if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" { 36*333d2b36SAndroid Build Coastguard Worker return override 37*333d2b36SAndroid Build Coastguard Worker } 38*333d2b36SAndroid Build Coastguard Worker return bindgenClangVersion 39*333d2b36SAndroid Build Coastguard Worker }) 40*333d2b36SAndroid Build Coastguard Worker 41*333d2b36SAndroid Build Coastguard Worker //TODO(b/160803703) Use a prebuilt bindgen instead of the built bindgen. 42*333d2b36SAndroid Build Coastguard Worker _ = pctx.HostBinToolVariable("bindgenCmd", "bindgen") 43*333d2b36SAndroid Build Coastguard Worker _ = pctx.VariableFunc("bindgenHostPrebuiltTag", func(ctx android.PackageVarContext) string { 44*333d2b36SAndroid Build Coastguard Worker if ctx.Config().UseHostMusl() { 45*333d2b36SAndroid Build Coastguard Worker // This is a hack to use the glibc bindgen binary until we have a musl version checked in. 46*333d2b36SAndroid Build Coastguard Worker return "linux-x86" 47*333d2b36SAndroid Build Coastguard Worker } else { 48*333d2b36SAndroid Build Coastguard Worker return "${config.HostPrebuiltTag}" 49*333d2b36SAndroid Build Coastguard Worker } 50*333d2b36SAndroid Build Coastguard Worker }) 51*333d2b36SAndroid Build Coastguard Worker _ = pctx.VariableFunc("bindgenClangLibdir", func(ctx android.PackageVarContext) string { 52*333d2b36SAndroid Build Coastguard Worker if ctx.Config().UseHostMusl() { 53*333d2b36SAndroid Build Coastguard Worker return "musl/lib/" 54*333d2b36SAndroid Build Coastguard Worker } else { 55*333d2b36SAndroid Build Coastguard Worker return "lib/" 56*333d2b36SAndroid Build Coastguard Worker } 57*333d2b36SAndroid Build Coastguard Worker }) 58*333d2b36SAndroid Build Coastguard Worker _ = pctx.SourcePathVariable("bindgenClang", 59*333d2b36SAndroid Build Coastguard Worker "${cc_config.ClangBase}/${bindgenHostPrebuiltTag}/${bindgenClangVersion}/bin/clang") 60*333d2b36SAndroid Build Coastguard Worker _ = pctx.SourcePathVariable("bindgenLibClang", 61*333d2b36SAndroid Build Coastguard Worker "${cc_config.ClangBase}/${bindgenHostPrebuiltTag}/${bindgenClangVersion}/${bindgenClangLibdir}") 62*333d2b36SAndroid Build Coastguard Worker 63*333d2b36SAndroid Build Coastguard Worker //TODO(ivanlozano) Switch this to RuleBuilder 64*333d2b36SAndroid Build Coastguard Worker // 65*333d2b36SAndroid Build Coastguard Worker //TODO Pass the flag files directly to bindgen e.g. with @file when it supports that. 66*333d2b36SAndroid Build Coastguard Worker //See https://github.com/rust-lang/rust-bindgen/issues/2508. 67*333d2b36SAndroid Build Coastguard Worker bindgen = pctx.AndroidStaticRule("bindgen", 68*333d2b36SAndroid Build Coastguard Worker blueprint.RuleParams{ 69*333d2b36SAndroid Build Coastguard Worker Command: "CLANG_PATH=$bindgenClang LIBCLANG_PATH=$bindgenLibClang RUSTFMT=${config.RustBin}/rustfmt " + 70*333d2b36SAndroid Build Coastguard Worker "$cmd $flags $$(cat $flagfiles) $in -o $out -- -MD -MF $out.d $cflags", 71*333d2b36SAndroid Build Coastguard Worker CommandDeps: []string{"$cmd"}, 72*333d2b36SAndroid Build Coastguard Worker Deps: blueprint.DepsGCC, 73*333d2b36SAndroid Build Coastguard Worker Depfile: "$out.d", 74*333d2b36SAndroid Build Coastguard Worker }, 75*333d2b36SAndroid Build Coastguard Worker "cmd", "flags", "flagfiles", "cflags") 76*333d2b36SAndroid Build Coastguard Worker) 77*333d2b36SAndroid Build Coastguard Worker 78*333d2b36SAndroid Build Coastguard Workerfunc init() { 79*333d2b36SAndroid Build Coastguard Worker android.RegisterModuleType("rust_bindgen", RustBindgenFactory) 80*333d2b36SAndroid Build Coastguard Worker android.RegisterModuleType("rust_bindgen_host", RustBindgenHostFactory) 81*333d2b36SAndroid Build Coastguard Worker} 82*333d2b36SAndroid Build Coastguard Worker 83*333d2b36SAndroid Build Coastguard Workervar _ SourceProvider = (*bindgenDecorator)(nil) 84*333d2b36SAndroid Build Coastguard Worker 85*333d2b36SAndroid Build Coastguard Workertype BindgenProperties struct { 86*333d2b36SAndroid Build Coastguard Worker // The wrapper header file. By default this is assumed to be a C header unless the extension is ".hh" or ".hpp". 87*333d2b36SAndroid Build Coastguard Worker // This is used to specify how to interpret the header and determines which '-std' flag to use by default. 88*333d2b36SAndroid Build Coastguard Worker // 89*333d2b36SAndroid Build Coastguard Worker // If your C++ header must have some other extension, then the default behavior can be overridden by setting the 90*333d2b36SAndroid Build Coastguard Worker // cpp_std property. 91*333d2b36SAndroid Build Coastguard Worker Wrapper_src *string `android:"path,arch_variant"` 92*333d2b36SAndroid Build Coastguard Worker 93*333d2b36SAndroid Build Coastguard Worker // list of bindgen-specific flags and options 94*333d2b36SAndroid Build Coastguard Worker Bindgen_flags []string `android:"arch_variant"` 95*333d2b36SAndroid Build Coastguard Worker 96*333d2b36SAndroid Build Coastguard Worker // list of files containing extra bindgen flags 97*333d2b36SAndroid Build Coastguard Worker Bindgen_flag_files []string `android:"arch_variant"` 98*333d2b36SAndroid Build Coastguard Worker 99*333d2b36SAndroid Build Coastguard Worker // module name of a custom binary/script which should be used instead of the 'bindgen' binary. This custom 100*333d2b36SAndroid Build Coastguard Worker // binary must expect arguments in a similar fashion to bindgen, e.g. 101*333d2b36SAndroid Build Coastguard Worker // 102*333d2b36SAndroid Build Coastguard Worker // "my_bindgen [flags] wrapper_header.h -o [output_path] -- [clang flags]" 103*333d2b36SAndroid Build Coastguard Worker Custom_bindgen string 104*333d2b36SAndroid Build Coastguard Worker 105*333d2b36SAndroid Build Coastguard Worker // flag to indicate if bindgen should handle `static inline` functions (default is false). 106*333d2b36SAndroid Build Coastguard Worker // If true, Static_inline_library must be set. 107*333d2b36SAndroid Build Coastguard Worker Handle_static_inline *bool 108*333d2b36SAndroid Build Coastguard Worker 109*333d2b36SAndroid Build Coastguard Worker // module name of the corresponding cc_library_static which includes the static_inline wrapper 110*333d2b36SAndroid Build Coastguard Worker // generated functions from bindgen. Must be used together with handle_static_inline. 111*333d2b36SAndroid Build Coastguard Worker // 112*333d2b36SAndroid Build Coastguard Worker // If there are no static inline functions provided through the header file, 113*333d2b36SAndroid Build Coastguard Worker // then bindgen (as of 0.69.2) will silently fail to output a .c file, and 114*333d2b36SAndroid Build Coastguard Worker // the cc_library_static depending on this module will fail compilation. 115*333d2b36SAndroid Build Coastguard Worker Static_inline_library *string 116*333d2b36SAndroid Build Coastguard Worker} 117*333d2b36SAndroid Build Coastguard Worker 118*333d2b36SAndroid Build Coastguard Workertype bindgenDecorator struct { 119*333d2b36SAndroid Build Coastguard Worker *BaseSourceProvider 120*333d2b36SAndroid Build Coastguard Worker 121*333d2b36SAndroid Build Coastguard Worker Properties BindgenProperties 122*333d2b36SAndroid Build Coastguard Worker ClangProperties cc.RustBindgenClangProperties 123*333d2b36SAndroid Build Coastguard Worker} 124*333d2b36SAndroid Build Coastguard Worker 125*333d2b36SAndroid Build Coastguard Workerfunc (b *bindgenDecorator) getStdVersion(ctx ModuleContext, src android.Path) (string, bool) { 126*333d2b36SAndroid Build Coastguard Worker // Assume headers are C headers 127*333d2b36SAndroid Build Coastguard Worker isCpp := false 128*333d2b36SAndroid Build Coastguard Worker stdVersion := "" 129*333d2b36SAndroid Build Coastguard Worker 130*333d2b36SAndroid Build Coastguard Worker switch src.Ext() { 131*333d2b36SAndroid Build Coastguard Worker case ".hpp", ".hh": 132*333d2b36SAndroid Build Coastguard Worker isCpp = true 133*333d2b36SAndroid Build Coastguard Worker } 134*333d2b36SAndroid Build Coastguard Worker 135*333d2b36SAndroid Build Coastguard Worker if String(b.ClangProperties.Cpp_std) != "" && String(b.ClangProperties.C_std) != "" { 136*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("c_std", "c_std and cpp_std cannot both be defined at the same time.") 137*333d2b36SAndroid Build Coastguard Worker } 138*333d2b36SAndroid Build Coastguard Worker 139*333d2b36SAndroid Build Coastguard Worker if b.ClangProperties.Cpp_std != nil { 140*333d2b36SAndroid Build Coastguard Worker isCpp = true 141*333d2b36SAndroid Build Coastguard Worker if String(b.ClangProperties.Cpp_std) == "experimental" { 142*333d2b36SAndroid Build Coastguard Worker stdVersion = cc_config.ExperimentalCppStdVersion 143*333d2b36SAndroid Build Coastguard Worker } else if String(b.ClangProperties.Cpp_std) == "default" || String(b.ClangProperties.Cpp_std) == "" { 144*333d2b36SAndroid Build Coastguard Worker stdVersion = cc_config.CppStdVersion 145*333d2b36SAndroid Build Coastguard Worker } else { 146*333d2b36SAndroid Build Coastguard Worker stdVersion = String(b.ClangProperties.Cpp_std) 147*333d2b36SAndroid Build Coastguard Worker } 148*333d2b36SAndroid Build Coastguard Worker } else if b.ClangProperties.C_std != nil { 149*333d2b36SAndroid Build Coastguard Worker isCpp = false 150*333d2b36SAndroid Build Coastguard Worker if String(b.ClangProperties.C_std) == "experimental" { 151*333d2b36SAndroid Build Coastguard Worker stdVersion = cc_config.ExperimentalCStdVersion 152*333d2b36SAndroid Build Coastguard Worker } else if String(b.ClangProperties.C_std) == "default" || String(b.ClangProperties.C_std) == "" { 153*333d2b36SAndroid Build Coastguard Worker stdVersion = cc_config.CStdVersion 154*333d2b36SAndroid Build Coastguard Worker } else { 155*333d2b36SAndroid Build Coastguard Worker stdVersion = String(b.ClangProperties.C_std) 156*333d2b36SAndroid Build Coastguard Worker } 157*333d2b36SAndroid Build Coastguard Worker } else if isCpp { 158*333d2b36SAndroid Build Coastguard Worker stdVersion = cc_config.CppStdVersion 159*333d2b36SAndroid Build Coastguard Worker } else { 160*333d2b36SAndroid Build Coastguard Worker stdVersion = cc_config.CStdVersion 161*333d2b36SAndroid Build Coastguard Worker } 162*333d2b36SAndroid Build Coastguard Worker 163*333d2b36SAndroid Build Coastguard Worker return stdVersion, isCpp 164*333d2b36SAndroid Build Coastguard Worker} 165*333d2b36SAndroid Build Coastguard Worker 166*333d2b36SAndroid Build Coastguard Workerfunc (b *bindgenDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) android.Path { 167*333d2b36SAndroid Build Coastguard Worker ccToolchain := ctx.RustModule().ccToolchain(ctx) 168*333d2b36SAndroid Build Coastguard Worker 169*333d2b36SAndroid Build Coastguard Worker var cflags []string 170*333d2b36SAndroid Build Coastguard Worker var implicits android.Paths 171*333d2b36SAndroid Build Coastguard Worker var implicitOutputs android.WritablePaths 172*333d2b36SAndroid Build Coastguard Worker var validations android.Paths 173*333d2b36SAndroid Build Coastguard Worker 174*333d2b36SAndroid Build Coastguard Worker if Bool(b.Properties.Handle_static_inline) && b.Properties.Static_inline_library == nil { 175*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("handle_static_inline", 176*333d2b36SAndroid Build Coastguard Worker "requires declaring static_inline_library to the corresponding cc_library module that includes the generated C source from bindgen.") 177*333d2b36SAndroid Build Coastguard Worker } 178*333d2b36SAndroid Build Coastguard Worker 179*333d2b36SAndroid Build Coastguard Worker if b.Properties.Static_inline_library != nil && !Bool(b.Properties.Handle_static_inline) { 180*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("static_inline_library", 181*333d2b36SAndroid Build Coastguard Worker "requires declaring handle_static_inline.") 182*333d2b36SAndroid Build Coastguard Worker } 183*333d2b36SAndroid Build Coastguard Worker 184*333d2b36SAndroid Build Coastguard Worker implicits = append(implicits, deps.depGeneratedHeaders...) 185*333d2b36SAndroid Build Coastguard Worker 186*333d2b36SAndroid Build Coastguard Worker // Default clang flags 187*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "${cc_config.CommonGlobalCflags}") 188*333d2b36SAndroid Build Coastguard Worker if ctx.Device() { 189*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "${cc_config.DeviceGlobalCflags}", "-nostdlibinc") 190*333d2b36SAndroid Build Coastguard Worker } 191*333d2b36SAndroid Build Coastguard Worker 192*333d2b36SAndroid Build Coastguard Worker // Toolchain clang flags 193*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-target "+ccToolchain.ClangTriple()) 194*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, strings.ReplaceAll(ccToolchain.Cflags(), "${config.", "${cc_config.")) 195*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, strings.ReplaceAll(ccToolchain.ToolchainCflags(), "${config.", "${cc_config.")) 196*333d2b36SAndroid Build Coastguard Worker 197*333d2b36SAndroid Build Coastguard Worker if ctx.RustModule().InVendorOrProduct() { 198*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-D__ANDROID_VNDK__") 199*333d2b36SAndroid Build Coastguard Worker if ctx.RustModule().InVendor() { 200*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-D__ANDROID_VENDOR__") 201*333d2b36SAndroid Build Coastguard Worker } else if ctx.RustModule().InProduct() { 202*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-D__ANDROID_PRODUCT__") 203*333d2b36SAndroid Build Coastguard Worker } 204*333d2b36SAndroid Build Coastguard Worker 205*333d2b36SAndroid Build Coastguard Worker // Define __ANDROID_VENDOR_API__ for both product and vendor variants 206*333d2b36SAndroid Build Coastguard Worker // because they both use the same LLNDK libraries. 207*333d2b36SAndroid Build Coastguard Worker vendorApiLevel := ctx.Config().VendorApiLevel() 208*333d2b36SAndroid Build Coastguard Worker if vendorApiLevel == "" { 209*333d2b36SAndroid Build Coastguard Worker // TODO(b/314036847): This is a fallback for UDC targets. 210*333d2b36SAndroid Build Coastguard Worker // This must be a build failure when UDC is no longer built 211*333d2b36SAndroid Build Coastguard Worker // from this source tree. 212*333d2b36SAndroid Build Coastguard Worker vendorApiLevel = ctx.Config().PlatformSdkVersion().String() 213*333d2b36SAndroid Build Coastguard Worker } 214*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-D__ANDROID_VENDOR_API__="+vendorApiLevel) 215*333d2b36SAndroid Build Coastguard Worker } 216*333d2b36SAndroid Build Coastguard Worker 217*333d2b36SAndroid Build Coastguard Worker if ctx.RustModule().InRecovery() { 218*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-D__ANDROID_RECOVERY__") 219*333d2b36SAndroid Build Coastguard Worker } 220*333d2b36SAndroid Build Coastguard Worker 221*333d2b36SAndroid Build Coastguard Worker if mctx, ok := ctx.(*moduleContext); ok && mctx.apexVariationName() != "" { 222*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-D__ANDROID_APEX__") 223*333d2b36SAndroid Build Coastguard Worker } 224*333d2b36SAndroid Build Coastguard Worker 225*333d2b36SAndroid Build Coastguard Worker if ctx.Target().NativeBridge == android.NativeBridgeEnabled { 226*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-D__ANDROID_NATIVE_BRIDGE__") 227*333d2b36SAndroid Build Coastguard Worker } 228*333d2b36SAndroid Build Coastguard Worker 229*333d2b36SAndroid Build Coastguard Worker // Dependency clang flags and include paths 230*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, deps.depClangFlags...) 231*333d2b36SAndroid Build Coastguard Worker for _, include := range deps.depIncludePaths { 232*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-I"+include.String()) 233*333d2b36SAndroid Build Coastguard Worker } 234*333d2b36SAndroid Build Coastguard Worker for _, include := range deps.depSystemIncludePaths { 235*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-isystem "+include.String()) 236*333d2b36SAndroid Build Coastguard Worker } 237*333d2b36SAndroid Build Coastguard Worker 238*333d2b36SAndroid Build Coastguard Worker esc := proptools.NinjaAndShellEscapeList 239*333d2b36SAndroid Build Coastguard Worker 240*333d2b36SAndroid Build Coastguard Worker // Filter out invalid cflags 241*333d2b36SAndroid Build Coastguard Worker cflagsProp := b.ClangProperties.Cflags.GetOrDefault(ctx, nil) 242*333d2b36SAndroid Build Coastguard Worker for _, flag := range cflagsProp { 243*333d2b36SAndroid Build Coastguard Worker if flag == "-x c++" || flag == "-xc++" { 244*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("cflags", 245*333d2b36SAndroid Build Coastguard Worker "-x c++ should not be specified in cflags; setting cpp_std specifies this is a C++ header, or change the file extension to '.hpp' or '.hh'") 246*333d2b36SAndroid Build Coastguard Worker } 247*333d2b36SAndroid Build Coastguard Worker if strings.HasPrefix(flag, "-std=") { 248*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("cflags", 249*333d2b36SAndroid Build Coastguard Worker "-std should not be specified in cflags; instead use c_std or cpp_std") 250*333d2b36SAndroid Build Coastguard Worker } 251*333d2b36SAndroid Build Coastguard Worker } 252*333d2b36SAndroid Build Coastguard Worker 253*333d2b36SAndroid Build Coastguard Worker // Module defined clang flags and include paths 254*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, esc(cflagsProp)...) 255*333d2b36SAndroid Build Coastguard Worker for _, include := range b.ClangProperties.Local_include_dirs.GetOrDefault(ctx, nil) { 256*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-I"+android.PathForModuleSrc(ctx, include).String()) 257*333d2b36SAndroid Build Coastguard Worker implicits = append(implicits, android.PathForModuleSrc(ctx, include)) 258*333d2b36SAndroid Build Coastguard Worker } 259*333d2b36SAndroid Build Coastguard Worker 260*333d2b36SAndroid Build Coastguard Worker bindgenFlags := defaultBindgenFlags 261*333d2b36SAndroid Build Coastguard Worker bindgenFlags = append(bindgenFlags, esc(b.Properties.Bindgen_flags)...) 262*333d2b36SAndroid Build Coastguard Worker if Bool(b.Properties.Handle_static_inline) { 263*333d2b36SAndroid Build Coastguard Worker outputStaticFnsFile := android.PathForModuleOut(ctx, b.BaseSourceProvider.getStem(ctx)+".c") 264*333d2b36SAndroid Build Coastguard Worker implicitOutputs = append(implicitOutputs, outputStaticFnsFile) 265*333d2b36SAndroid Build Coastguard Worker validations = append(validations, outputStaticFnsFile) 266*333d2b36SAndroid Build Coastguard Worker bindgenFlags = append(bindgenFlags, []string{"--experimental", "--wrap-static-fns", "--wrap-static-fns-path=" + outputStaticFnsFile.String()}...) 267*333d2b36SAndroid Build Coastguard Worker } 268*333d2b36SAndroid Build Coastguard Worker 269*333d2b36SAndroid Build Coastguard Worker // cat reads from stdin if its command line is empty, 270*333d2b36SAndroid Build Coastguard Worker // so we pass in /dev/null if there are no other flag files 271*333d2b36SAndroid Build Coastguard Worker bindgenFlagFiles := []string{"/dev/null"} 272*333d2b36SAndroid Build Coastguard Worker for _, flagFile := range b.Properties.Bindgen_flag_files { 273*333d2b36SAndroid Build Coastguard Worker bindgenFlagFiles = append(bindgenFlagFiles, android.PathForModuleSrc(ctx, flagFile).String()) 274*333d2b36SAndroid Build Coastguard Worker implicits = append(implicits, android.PathForModuleSrc(ctx, flagFile)) 275*333d2b36SAndroid Build Coastguard Worker } 276*333d2b36SAndroid Build Coastguard Worker 277*333d2b36SAndroid Build Coastguard Worker wrapperFile := android.OptionalPathForModuleSrc(ctx, b.Properties.Wrapper_src) 278*333d2b36SAndroid Build Coastguard Worker if !wrapperFile.Valid() { 279*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("wrapper_src", "invalid path to wrapper source") 280*333d2b36SAndroid Build Coastguard Worker } 281*333d2b36SAndroid Build Coastguard Worker 282*333d2b36SAndroid Build Coastguard Worker // Add C std version flag 283*333d2b36SAndroid Build Coastguard Worker stdVersion, isCpp := b.getStdVersion(ctx, wrapperFile.Path()) 284*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-std="+stdVersion) 285*333d2b36SAndroid Build Coastguard Worker 286*333d2b36SAndroid Build Coastguard Worker // Specify the header source language to avoid ambiguity. 287*333d2b36SAndroid Build Coastguard Worker if isCpp { 288*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-x c++") 289*333d2b36SAndroid Build Coastguard Worker // Add any C++ only flags. 290*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, esc(b.ClangProperties.Cppflags.GetOrDefault(ctx, nil))...) 291*333d2b36SAndroid Build Coastguard Worker } else { 292*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-x c") 293*333d2b36SAndroid Build Coastguard Worker } 294*333d2b36SAndroid Build Coastguard Worker 295*333d2b36SAndroid Build Coastguard Worker // clang-r468909b complains about the -x c in the flags in clang-sys parse_search_paths: 296*333d2b36SAndroid Build Coastguard Worker // clang: error: '-x c' after last input file has no effect [-Werror,-Wunused-command-line-argument] 297*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-Wno-unused-command-line-argument") 298*333d2b36SAndroid Build Coastguard Worker 299*333d2b36SAndroid Build Coastguard Worker // The Clang version used by CXX can be newer than the one used by Bindgen, and uses warning related flags that 300*333d2b36SAndroid Build Coastguard Worker // it cannot recognize. Turn off unknown warning flags warning. 301*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-Wno-unknown-warning-option") 302*333d2b36SAndroid Build Coastguard Worker 303*333d2b36SAndroid Build Coastguard Worker // Suppress warnings while testing a new compiler. 304*333d2b36SAndroid Build Coastguard Worker if ctx.Config().IsEnvTrue("LLVM_NEXT") { 305*333d2b36SAndroid Build Coastguard Worker cflags = append(cflags, "-Wno-everything") 306*333d2b36SAndroid Build Coastguard Worker } 307*333d2b36SAndroid Build Coastguard Worker 308*333d2b36SAndroid Build Coastguard Worker outputFile := android.PathForModuleOut(ctx, b.BaseSourceProvider.getStem(ctx)+".rs") 309*333d2b36SAndroid Build Coastguard Worker 310*333d2b36SAndroid Build Coastguard Worker var cmd, cmdDesc string 311*333d2b36SAndroid Build Coastguard Worker if b.Properties.Custom_bindgen != "" { 312*333d2b36SAndroid Build Coastguard Worker cmd = ctx.GetDirectDepWithTag(b.Properties.Custom_bindgen, customBindgenDepTag).(android.HostToolProvider).HostToolPath().String() 313*333d2b36SAndroid Build Coastguard Worker cmdDesc = b.Properties.Custom_bindgen 314*333d2b36SAndroid Build Coastguard Worker } else { 315*333d2b36SAndroid Build Coastguard Worker cmd = "$bindgenCmd" 316*333d2b36SAndroid Build Coastguard Worker cmdDesc = "bindgen" 317*333d2b36SAndroid Build Coastguard Worker } 318*333d2b36SAndroid Build Coastguard Worker 319*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 320*333d2b36SAndroid Build Coastguard Worker Rule: bindgen, 321*333d2b36SAndroid Build Coastguard Worker Description: strings.Join([]string{cmdDesc, wrapperFile.Path().Rel()}, " "), 322*333d2b36SAndroid Build Coastguard Worker Output: outputFile, 323*333d2b36SAndroid Build Coastguard Worker Input: wrapperFile.Path(), 324*333d2b36SAndroid Build Coastguard Worker Implicits: implicits, 325*333d2b36SAndroid Build Coastguard Worker ImplicitOutputs: implicitOutputs, 326*333d2b36SAndroid Build Coastguard Worker Validations: validations, 327*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 328*333d2b36SAndroid Build Coastguard Worker "cmd": cmd, 329*333d2b36SAndroid Build Coastguard Worker "flags": strings.Join(bindgenFlags, " "), 330*333d2b36SAndroid Build Coastguard Worker "flagfiles": strings.Join(bindgenFlagFiles, " "), 331*333d2b36SAndroid Build Coastguard Worker "cflags": strings.Join(cflags, " "), 332*333d2b36SAndroid Build Coastguard Worker }, 333*333d2b36SAndroid Build Coastguard Worker }) 334*333d2b36SAndroid Build Coastguard Worker 335*333d2b36SAndroid Build Coastguard Worker b.BaseSourceProvider.OutputFiles = android.Paths{outputFile} 336*333d2b36SAndroid Build Coastguard Worker 337*333d2b36SAndroid Build Coastguard Worker // Append any additional implicit outputs after the entry point source. 338*333d2b36SAndroid Build Coastguard Worker // We append any generated .c file here so it can picked up by cc_library_static modules. 339*333d2b36SAndroid Build Coastguard Worker // Those CC modules need to be sure not to pass any included .rs files to Clang. 340*333d2b36SAndroid Build Coastguard Worker // We don't have to worry about the additional .c files for Rust modules as only the entry point 341*333d2b36SAndroid Build Coastguard Worker // is passed to rustc. 342*333d2b36SAndroid Build Coastguard Worker b.BaseSourceProvider.OutputFiles = append(b.BaseSourceProvider.OutputFiles, implicitOutputs.Paths()...) 343*333d2b36SAndroid Build Coastguard Worker 344*333d2b36SAndroid Build Coastguard Worker return outputFile 345*333d2b36SAndroid Build Coastguard Worker} 346*333d2b36SAndroid Build Coastguard Worker 347*333d2b36SAndroid Build Coastguard Workerfunc (b *bindgenDecorator) SourceProviderProps() []interface{} { 348*333d2b36SAndroid Build Coastguard Worker return append(b.BaseSourceProvider.SourceProviderProps(), 349*333d2b36SAndroid Build Coastguard Worker &b.Properties, &b.ClangProperties) 350*333d2b36SAndroid Build Coastguard Worker} 351*333d2b36SAndroid Build Coastguard Worker 352*333d2b36SAndroid Build Coastguard Worker// rust_bindgen generates Rust FFI bindings to C libraries using bindgen given a wrapper header as the primary input. 353*333d2b36SAndroid Build Coastguard Worker// Bindgen has a number of flags to control the generated source, and additional flags can be passed to clang to ensure 354*333d2b36SAndroid Build Coastguard Worker// the header and generated source is appropriately handled. It is recommended to add it as a dependency in the 355*333d2b36SAndroid Build Coastguard Worker// rlibs or rustlibs property. It may also be added in the srcs property for external crates, using the ":" 356*333d2b36SAndroid Build Coastguard Worker// prefix. 357*333d2b36SAndroid Build Coastguard Workerfunc RustBindgenFactory() android.Module { 358*333d2b36SAndroid Build Coastguard Worker module, _ := NewRustBindgen(android.HostAndDeviceSupported) 359*333d2b36SAndroid Build Coastguard Worker return module.Init() 360*333d2b36SAndroid Build Coastguard Worker} 361*333d2b36SAndroid Build Coastguard Worker 362*333d2b36SAndroid Build Coastguard Workerfunc RustBindgenHostFactory() android.Module { 363*333d2b36SAndroid Build Coastguard Worker module, _ := NewRustBindgen(android.HostSupported) 364*333d2b36SAndroid Build Coastguard Worker return module.Init() 365*333d2b36SAndroid Build Coastguard Worker} 366*333d2b36SAndroid Build Coastguard Worker 367*333d2b36SAndroid Build Coastguard Workerfunc NewRustBindgen(hod android.HostOrDeviceSupported) (*Module, *bindgenDecorator) { 368*333d2b36SAndroid Build Coastguard Worker bindgen := &bindgenDecorator{ 369*333d2b36SAndroid Build Coastguard Worker BaseSourceProvider: NewSourceProvider(), 370*333d2b36SAndroid Build Coastguard Worker Properties: BindgenProperties{}, 371*333d2b36SAndroid Build Coastguard Worker ClangProperties: cc.RustBindgenClangProperties{}, 372*333d2b36SAndroid Build Coastguard Worker } 373*333d2b36SAndroid Build Coastguard Worker 374*333d2b36SAndroid Build Coastguard Worker module := NewSourceProviderModule(hod, bindgen, false, false) 375*333d2b36SAndroid Build Coastguard Worker 376*333d2b36SAndroid Build Coastguard Worker android.AddLoadHook(module, func(ctx android.LoadHookContext) { 377*333d2b36SAndroid Build Coastguard Worker type stub_props struct { 378*333d2b36SAndroid Build Coastguard Worker Visibility []string 379*333d2b36SAndroid Build Coastguard Worker } 380*333d2b36SAndroid Build Coastguard Worker props := &stub_props{[]string{":__subpackages__"}} 381*333d2b36SAndroid Build Coastguard Worker ctx.PrependProperties(props) 382*333d2b36SAndroid Build Coastguard Worker }) 383*333d2b36SAndroid Build Coastguard Worker 384*333d2b36SAndroid Build Coastguard Worker return module, bindgen 385*333d2b36SAndroid Build Coastguard Worker} 386*333d2b36SAndroid Build Coastguard Worker 387*333d2b36SAndroid Build Coastguard Workerfunc (b *bindgenDecorator) SourceProviderDeps(ctx DepsContext, deps Deps) Deps { 388*333d2b36SAndroid Build Coastguard Worker deps = b.BaseSourceProvider.SourceProviderDeps(ctx, deps) 389*333d2b36SAndroid Build Coastguard Worker if ctx.toolchain().Bionic() && !ctx.RustModule().compiler.noStdlibs() { 390*333d2b36SAndroid Build Coastguard Worker deps = bionicDeps(ctx, deps, false) 391*333d2b36SAndroid Build Coastguard Worker } else if ctx.Os() == android.LinuxMusl { 392*333d2b36SAndroid Build Coastguard Worker deps = muslDeps(ctx, deps, false) 393*333d2b36SAndroid Build Coastguard Worker } 394*333d2b36SAndroid Build Coastguard Worker 395*333d2b36SAndroid Build Coastguard Worker if !ctx.RustModule().Source() && b.Properties.Static_inline_library != nil { 396*333d2b36SAndroid Build Coastguard Worker // This is not the source variant, so add the static inline library as a dependency. 397*333d2b36SAndroid Build Coastguard Worker // 398*333d2b36SAndroid Build Coastguard Worker // This is necessary to avoid a circular dependency between the source variant and the 399*333d2b36SAndroid Build Coastguard Worker // dependent cc module. 400*333d2b36SAndroid Build Coastguard Worker deps.StaticLibs = append(deps.StaticLibs, String(b.Properties.Static_inline_library)) 401*333d2b36SAndroid Build Coastguard Worker } 402*333d2b36SAndroid Build Coastguard Worker 403*333d2b36SAndroid Build Coastguard Worker deps.SharedLibs = append(deps.SharedLibs, b.ClangProperties.Shared_libs.GetOrDefault(ctx, nil)...) 404*333d2b36SAndroid Build Coastguard Worker deps.StaticLibs = append(deps.StaticLibs, b.ClangProperties.Static_libs.GetOrDefault(ctx, nil)...) 405*333d2b36SAndroid Build Coastguard Worker deps.HeaderLibs = append(deps.HeaderLibs, b.ClangProperties.Header_libs.GetOrDefault(ctx, nil)...) 406*333d2b36SAndroid Build Coastguard Worker return deps 407*333d2b36SAndroid Build Coastguard Worker} 408