Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce2cffd5 authored by Ivan Lozano's avatar Ivan Lozano Committed by Gerrit Code Review
Browse files

Merge "rust: Add rust_bindgen std version w/ cc defaults."

parents 6a94390d 3d94752b
Loading
Loading
Loading
Loading
+72 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import (
	"github.com/google/blueprint/proptools"

	"android/soong/android"
	cc_config "android/soong/cc/config"
)

var (
@@ -56,7 +57,11 @@ 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
@@ -81,6 +86,22 @@ type BindgenProperties struct {
	// "my_bindgen [flags] wrapper_header.h -o [output_path] -- [clang flags]"
	Custom_bindgen string `android:"path"`

	// C standard version to use. Can be a specific version (such as "gnu11"),
	// "experimental" (which will use draft versions like C1x when available),
	// or the empty string (which will use the default).
	//
	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
	// to "default" will use the build system default version. This cannot be set at the same time as cpp_std.
	C_std *string

	// C++ standard version to use. Can be a specific version (such as
	// "gnu++11"), "experimental" (which will use draft versions like C++1z when
	// available), or the empty string (which will use the default).
	//
	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
	// to "default" will use the build system default version. This cannot be set at the same time as c_std.
	Cpp_std *string

	//TODO(b/161141999) Add support for headers from cc_library_header modules.
}

@@ -90,6 +111,45 @@ type bindgenDecorator struct {
	Properties BindgenProperties
}

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.Properties.Cpp_std) != "" && String(b.Properties.C_std) != "" {
		ctx.PropertyErrorf("c_std", "c_std and cpp_std cannot both be defined at the same time.")
	}

	if String(b.Properties.Cpp_std) != "" {
		if String(b.Properties.Cpp_std) == "experimental" {
			stdVersion = cc_config.ExperimentalCppStdVersion
		} else if String(b.Properties.Cpp_std) == "default" {
			stdVersion = cc_config.CppStdVersion
		} else {
			stdVersion = String(b.Properties.Cpp_std)
		}
	} else if b.Properties.C_std != nil {
		if String(b.Properties.C_std) == "experimental" {
			stdVersion = cc_config.ExperimentalCStdVersion
		} else if String(b.Properties.C_std) == "default" {
			stdVersion = cc_config.CStdVersion
		} else {
			stdVersion = String(b.Properties.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 {
	ccToolchain := ctx.RustModule().ccToolchain(ctx)

@@ -134,6 +194,17 @@ 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++")
	} else {
		cflags = append(cflags, "-x c")
	}

	outputFile := android.PathForModuleOut(ctx, b.BaseSourceProvider.getStem(ctx)+".rs")

	var cmd, cmdDesc string
+44 −0
Original line number Diff line number Diff line
@@ -82,3 +82,47 @@ func TestRustBindgenCustomBindgen(t *testing.T) {
			libbindgen.Description)
	}
}

func TestRustBindgenStdVersions(t *testing.T) {
	testRustError(t, "c_std and cpp_std cannot both be defined at the same time.", `
		rust_bindgen {
			name: "libbindgen",
			wrapper_src: "src/any.h",
			crate_name: "bindgen",
			stem: "libbindgen",
			source_stem: "bindings",
			c_std: "somevalue",
			cpp_std: "somevalue",
		}
	`)

	ctx := testRust(t, `
		rust_bindgen {
			name: "libbindgen_cstd",
			wrapper_src: "src/any.h",
			crate_name: "bindgen",
			stem: "libbindgen",
			source_stem: "bindings",
			c_std: "foo"
		}
		rust_bindgen {
			name: "libbindgen_cppstd",
			wrapper_src: "src/any.h",
			crate_name: "bindgen",
			stem: "libbindgen",
			source_stem: "bindings",
			cpp_std: "foo"
		}
	`)

	libbindgen_cstd := ctx.ModuleForTests("libbindgen_cstd", "android_arm64_armv8-a").Output("bindings.rs")
	libbindgen_cppstd := ctx.ModuleForTests("libbindgen_cppstd", "android_arm64_armv8-a").Output("bindings.rs")

	if !strings.Contains(libbindgen_cstd.Args["cflags"], "-std=foo") {
		t.Errorf("c_std value not passed in to rust_bindgen as a clang flag")
	}

	if !strings.Contains(libbindgen_cppstd.Args["cflags"], "-std=foo") {
		t.Errorf("cpp_std value not passed in to rust_bindgen as a clang flag")
	}
}