diff options
Diffstat (limited to 'rust/bindgen.go')
-rw-r--r-- | rust/bindgen.go | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/rust/bindgen.go b/rust/bindgen.go index cafdb8bfa..ac33ff7ef 100644 --- a/rust/bindgen.go +++ b/rust/bindgen.go @@ -21,6 +21,8 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/cc" + cc_config "android/soong/cc/config" ) var ( @@ -56,38 +58,67 @@ func init() { var _ SourceProvider = (*bindgenDecorator)(nil) type BindgenProperties struct { - // The wrapper header file + // The wrapper header file. By default this is assumed to be a C header unless the extension is ".hh" or ".hpp". + // This is used to specify how to interpret the header and determines which '-std' flag to use by default. + // + // If your C++ header must have some other extension, then the default behavior can be overridden by setting the + // cpp_std property. Wrapper_src *string `android:"path,arch_variant"` // list of bindgen-specific flags and options Bindgen_flags []string `android:"arch_variant"` - // list of clang flags required to correctly interpret the headers. - Cflags []string `android:"arch_variant"` - - // list of directories relative to the Blueprints file that will - // be added to the include path using -I - Local_include_dirs []string `android:"arch_variant,variant_prepend"` - - // list of static libraries that provide headers for this binding. - Static_libs []string `android:"arch_variant,variant_prepend"` - - // list of shared libraries that provide headers for this binding. - Shared_libs []string `android:"arch_variant"` - // module name of a custom binary/script which should be used instead of the 'bindgen' binary. This custom // binary must expect arguments in a similar fashion to bindgen, e.g. // // "my_bindgen [flags] wrapper_header.h -o [output_path] -- [clang flags]" Custom_bindgen string `android:"path"` - - //TODO(b/161141999) Add support for headers from cc_library_header modules. } type bindgenDecorator struct { *BaseSourceProvider - Properties BindgenProperties + Properties BindgenProperties + ClangProperties cc.RustBindgenClangProperties +} + +func (b *bindgenDecorator) getStdVersion(ctx ModuleContext, src android.Path) (string, bool) { + // Assume headers are C headers + isCpp := false + stdVersion := "" + + switch src.Ext() { + case ".hpp", ".hh": + isCpp = true + } + + if String(b.ClangProperties.Cpp_std) != "" && String(b.ClangProperties.C_std) != "" { + ctx.PropertyErrorf("c_std", "c_std and cpp_std cannot both be defined at the same time.") + } + + if String(b.ClangProperties.Cpp_std) != "" { + if String(b.ClangProperties.Cpp_std) == "experimental" { + stdVersion = cc_config.ExperimentalCppStdVersion + } else if String(b.ClangProperties.Cpp_std) == "default" { + stdVersion = cc_config.CppStdVersion + } else { + stdVersion = String(b.ClangProperties.Cpp_std) + } + } else if b.ClangProperties.C_std != nil { + if String(b.ClangProperties.C_std) == "experimental" { + stdVersion = cc_config.ExperimentalCStdVersion + } else if String(b.ClangProperties.C_std) == "default" { + stdVersion = cc_config.CStdVersion + } else { + stdVersion = String(b.ClangProperties.C_std) + } + } else if isCpp { + stdVersion = cc_config.CppStdVersion + } else { + stdVersion = cc_config.CStdVersion + } + + return stdVersion, isCpp } func (b *bindgenDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) android.Path { @@ -120,8 +151,8 @@ func (b *bindgenDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) andr esc := proptools.NinjaAndShellEscapeList // Module defined clang flags and include paths - cflags = append(cflags, esc(b.Properties.Cflags)...) - for _, include := range b.Properties.Local_include_dirs { + cflags = append(cflags, esc(b.ClangProperties.Cflags)...) + for _, include := range b.ClangProperties.Local_include_dirs { cflags = append(cflags, "-I"+android.PathForModuleSrc(ctx, include).String()) implicits = append(implicits, android.PathForModuleSrc(ctx, include)) } @@ -134,6 +165,19 @@ func (b *bindgenDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) andr ctx.PropertyErrorf("wrapper_src", "invalid path to wrapper source") } + // Add C std version flag + stdVersion, isCpp := b.getStdVersion(ctx, wrapperFile.Path()) + cflags = append(cflags, "-std="+stdVersion) + + // Specify the header source language to avoid ambiguity. + if isCpp { + cflags = append(cflags, "-x c++") + // Add any C++ only flags. + cflags = append(cflags, esc(b.ClangProperties.Cppflags)...) + } else { + cflags = append(cflags, "-x c") + } + outputFile := android.PathForModuleOut(ctx, b.BaseSourceProvider.getStem(ctx)+".rs") var cmd, cmdDesc string @@ -164,12 +208,14 @@ func (b *bindgenDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) andr func (b *bindgenDecorator) SourceProviderProps() []interface{} { return append(b.BaseSourceProvider.SourceProviderProps(), - &b.Properties) + &b.Properties, &b.ClangProperties) } // rust_bindgen generates Rust FFI bindings to C libraries using bindgen given a wrapper header as the primary input. // Bindgen has a number of flags to control the generated source, and additional flags can be passed to clang to ensure -// the header and generated source is appropriately handled. +// the header and generated source is appropriately handled. It is recommended to add it as a dependency in the +// rlibs, dylibs or rustlibs property. It may also be added in the srcs property for external crates, using the ":" +// prefix. func RustBindgenFactory() android.Module { module, _ := NewRustBindgen(android.HostAndDeviceSupported) return module.Init() @@ -184,6 +230,7 @@ func NewRustBindgen(hod android.HostOrDeviceSupported) (*Module, *bindgenDecorat bindgen := &bindgenDecorator{ BaseSourceProvider: NewSourceProvider(), Properties: BindgenProperties{}, + ClangProperties: cc.RustBindgenClangProperties{}, } module := NewSourceProviderModule(hod, bindgen, false) @@ -194,10 +241,10 @@ func NewRustBindgen(hod android.HostOrDeviceSupported) (*Module, *bindgenDecorat func (b *bindgenDecorator) SourceProviderDeps(ctx DepsContext, deps Deps) Deps { deps = b.BaseSourceProvider.SourceProviderDeps(ctx, deps) if ctx.toolchain().Bionic() { - deps = bionicDeps(deps) + deps = bionicDeps(deps, false) } - deps.SharedLibs = append(deps.SharedLibs, b.Properties.Shared_libs...) - deps.StaticLibs = append(deps.StaticLibs, b.Properties.Static_libs...) + deps.SharedLibs = append(deps.SharedLibs, b.ClangProperties.Shared_libs...) + deps.StaticLibs = append(deps.StaticLibs, b.ClangProperties.Static_libs...) return deps } |