xref: /aosp_15_r20/build/soong/rust/bindgen.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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