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

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

Merge "Link device binaries dynamically by default."

parents 6945e9b6 042504f7
Loading
Loading
Loading
Loading
+3 −12
Original line number Diff line number Diff line
@@ -24,9 +24,6 @@ func init() {
}

type BinaryCompilerProperties struct {
	// passes -C prefer-dynamic to rustc, which tells it to dynamically link the stdlib
	// (assuming it has no dylib dependencies already)
	Prefer_dynamic *bool
}

type binaryDecorator struct {
@@ -60,10 +57,6 @@ func NewRustBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator
	return module, binary
}

func (binary *binaryDecorator) preferDynamic() bool {
	return Bool(binary.Properties.Prefer_dynamic)
}

func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
	flags = binary.baseCompiler.compilerFlags(ctx, flags)

@@ -76,9 +69,6 @@ func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Fla
			"-Wl,--no-undefined-version")
	}

	if binary.preferDynamic() {
		flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
	}
	return flags
}

@@ -132,8 +122,9 @@ func (binary *binaryDecorator) coverageOutputZipPath() android.OptionalPath {
	return binary.coverageOutputZipFile
}

func (binary *binaryDecorator) autoDep() autoDep {
	if binary.preferDynamic() {
func (binary *binaryDecorator) autoDep(ctx BaseModuleContext) autoDep {
	// Binaries default to dylib dependencies for device, rlib for host.
	if ctx.Device() {
		return dylibAutoDep
	} else {
		return rlibAutoDep
+40 −20
Original line number Diff line number Diff line
@@ -17,44 +17,64 @@ package rust
import (
	"strings"
	"testing"

	"android/soong/android"
)

// Test that the prefer_dynamic property is handled correctly.
func TestPreferDynamicBinary(t *testing.T) {
// Test that rustlibs default linkage is correct for binaries.
func TestBinaryLinkage(t *testing.T) {
	ctx := testRust(t, `
		rust_binary_host {
			name: "fizz-buzz-dynamic",
		rust_binary {
			name: "fizz-buzz",
			srcs: ["foo.rs"],
			prefer_dynamic: true,
			rustlibs: ["libfoo"],
			host_supported: true,
		}
		rust_library {
			name: "libfoo",
			srcs: ["foo.rs"],
			crate_name: "foo",
			host_supported: true,
		}`)

	fizzBuzzHost := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
	fizzBuzzDevice := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Module().(*Module)

	if !android.InList("libfoo", fizzBuzzHost.Properties.AndroidMkRlibs) {
		t.Errorf("rustlibs dependency libfoo should be an rlib dep for host modules")
	}

	if !android.InList("libfoo", fizzBuzzDevice.Properties.AndroidMkDylibs) {
		t.Errorf("rustlibs dependency libfoo should be an dylib dep for device modules")
	}
}

// Test that the path returned by HostToolPath is correct
func TestHostToolPath(t *testing.T) {
	ctx := testRust(t, `
		rust_binary_host {
			name: "fizz-buzz",
			srcs: ["foo.rs"],
		}`)

	fizzBuzz := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Output("fizz-buzz")
	fizzBuzzDynamic := ctx.ModuleForTests("fizz-buzz-dynamic", "linux_glibc_x86_64").Output("fizz-buzz-dynamic")

	path := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module).HostToolPath()
	if g, w := path.String(), "/host/linux-x86/bin/fizz-buzz"; !strings.Contains(g, w) {
		t.Errorf("wrong host tool path, expected %q got %q", w, g)
	}

	// Do not compile binary modules with the --test flag.
	flags := fizzBuzzDynamic.Args["rustcFlags"]
	if strings.Contains(flags, "--test") {
		t.Errorf("extra --test flag, rustcFlags: %#v", flags)
	}
	if !strings.Contains(flags, "prefer-dynamic") {
		t.Errorf("missing prefer-dynamic flag, rustcFlags: %#v", flags)
}

	flags = fizzBuzz.Args["rustcFlags"]
// Test that the flags being passed to rust_binary modules are as expected
func TestBinaryFlags(t *testing.T) {
	ctx := testRust(t, `
		rust_binary_host {
			name: "fizz-buzz",
			srcs: ["foo.rs"],
		}`)

	fizzBuzz := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Output("fizz-buzz")

	flags := fizzBuzz.Args["rustcFlags"]
	if strings.Contains(flags, "--test") {
		t.Errorf("extra --test flag, rustcFlags: %#v", flags)
	}
	if strings.Contains(flags, "prefer-dynamic") {
		t.Errorf("unexpected prefer-dynamic flag, rustcFlags: %#v", flags)
	}
}
+13 −1
Original line number Diff line number Diff line
@@ -145,6 +145,10 @@ func (compiler *baseCompiler) coverageOutputZipPath() android.OptionalPath {
	panic("baseCompiler does not implement coverageOutputZipPath()")
}

func (compiler *baseCompiler) static() bool {
	return false
}

var _ compiler = (*baseCompiler)(nil)

func (compiler *baseCompiler) inData() bool {
@@ -216,7 +220,15 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
				stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
			}

			// For devices, we always link stdlibs in as dylibs except for ffi static libraries.
			// (rustc does not support linking libstd as a dylib for ffi static libraries)
			if ctx.Host() {
				deps.Rustlibs = append(deps.Rustlibs, stdlib)
			} else if ctx.RustModule().compiler.static() {
				deps.Rlibs = append(deps.Rlibs, stdlib)
			} else {
				deps.Dylibs = append(deps.Dylibs, stdlib)
			}
		}
	}
	return deps
+27 −0
Original line number Diff line number Diff line
@@ -177,3 +177,30 @@ func TestLints(t *testing.T) {
		})
	}
}

// Test that devices are linking the stdlib dynamically
func TestStdDeviceLinkage(t *testing.T) {
	ctx := testRust(t, `
		rust_binary {
			name: "fizz",
			srcs: ["foo.rs"],
		}
		rust_library {
			name: "libfoo",
			srcs: ["foo.rs"],
			crate_name: "foo",
		}`)
	fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module)
	fooRlib := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib").Module().(*Module)
	fooDylib := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").Module().(*Module)

	if !android.InList("libstd", fizz.Properties.AndroidMkDylibs) {
		t.Errorf("libstd is not linked dynamically for device binaries")
	}
	if !android.InList("libstd", fooRlib.Properties.AndroidMkDylibs) {
		t.Errorf("libstd is not linked dynamically for rlibs")
	}
	if !android.InList("libstd", fooDylib.Properties.AndroidMkDylibs) {
		t.Errorf("libstd is not linked dynamically for dylibs")
	}
}
+2 −2
Original line number Diff line number Diff line
@@ -176,13 +176,13 @@ func (library *libraryDecorator) setStatic() {
	library.MutatedProperties.VariantIsDylib = false
}

func (library *libraryDecorator) autoDep() autoDep {
func (library *libraryDecorator) autoDep(ctx BaseModuleContext) autoDep {
	if library.rlib() || library.static() {
		return rlibAutoDep
	} else if library.dylib() || library.shared() {
		return dylibAutoDep
	} else {
		return rlibAutoDep
		panic("autoDep called on library" + ctx.ModuleName() + "that has no enabled variants.")
	}
}

Loading