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

Commit 225a37a7 authored by Colin Cross's avatar Colin Cross
Browse files

Use the same rpaths for tests and binaries and cc and rust

Rust and cc binaries currently use $ORIGIN/lib64:$ORIGIN/../lib64 as the
rpath, and cc tests add $ORIGIN/../../lib64:$ORIGIN/../../../$ORIGIN:$ORIGIN.
This causes problems when a binary is included as test data in
out/host/linux-x86/testcases/<test dir>/<CPU>/<test>, as the
binaries can't find the libraries in out/host/linux-x86/lib64.

Use the same rpath for test and binaries, and for cc and rust.

Bug: 264604160
Test: m USE_HOST_MUSL=true out/host/linux-x86/testcases/acpi_tables_test_src_lib/x86_64/acpi_tables_test_src_lib && out/host/linux-x86/testcases/acpi_tables_test_src_lib/x86_64/acpi_tables_test_src_lib
Test: m USE_HOST_MUSL=true out/host/linux-x86/testcases/gen_sdk_test/x86_64/gen_sdk_test && out/host/linux-x86/testcases/gen_sdk_test/x86_64/toybox
Change-Id: I10fe5dc0de01d1f3c6aea8dbabbf60edab5989c3
parent 57b1e406
Loading
Loading
Loading
Loading
+45 −21
Original line number Diff line number Diff line
@@ -15,10 +15,10 @@
package cc

import (
	"fmt"

	"android/soong/android"
	"android/soong/cc/config"
	"fmt"
	"path/filepath"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"
@@ -270,7 +270,6 @@ func NewBaseLinker(sanitize *sanitize) *baseLinker {
type baseLinker struct {
	Properties        BaseLinkerProperties
	dynamicProperties struct {
		RunPaths   []string `blueprint:"mutated"`
		BuildStubs bool `blueprint:"mutated"`
	}

@@ -281,13 +280,8 @@ func (linker *baseLinker) appendLdflags(flags []string) {
	linker.Properties.Ldflags = append(linker.Properties.Ldflags, flags...)
}

// linkerInit initializes dynamic properties of the linker (such as runpath).
// linkerInit initializes dynamic properties of the linker.
func (linker *baseLinker) linkerInit(ctx BaseModuleContext) {
	if ctx.toolchain().Is64Bit() {
		linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, "../lib64", "lib64")
	} else {
		linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, "../lib", "lib")
	}
}

func (linker *baseLinker) linkerProps() []interface{} {
@@ -529,17 +523,8 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {

	flags.Local.LdFlags = append(flags.Local.LdFlags, proptools.NinjaAndShellEscapeList(linker.Properties.Ldflags)...)

	if ctx.Host() && !ctx.Windows() {
		rpathPrefix := `\$$ORIGIN/`
		if ctx.Darwin() {
			rpathPrefix = "@loader_path/"
		}

		if !ctx.static() {
			for _, rpath := range linker.dynamicProperties.RunPaths {
				flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-rpath,"+rpathPrefix+rpath)
			}
		}
	if ctx.Host() && !ctx.Windows() && !ctx.static() {
		flags.Global.LdFlags = append(flags.Global.LdFlags, RpathFlags(ctx)...)
	}

	if ctx.useSdk() {
@@ -610,6 +595,45 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
	return flags
}

// RpathFlags returns the rpath linker flags for current target to search the following directories relative
// to the binary:
//
//   - "." to find libraries alongside tests
//   - "lib[64]" to find libraries in a subdirectory of the binaries' directory
//   - "../lib[64]" to find libraries when the binaries are in a bin directory
//   - "../../lib[64]" to find libraries in out/host/linux-x86/lib64 when the test or binary is in
//     out/host/linux-x86/nativetest/<test dir>/<test>
//   - "../../../lib[[64] to find libraries in out/host/linux-x86/lib64 when the test or binary is in
//     out/host/linux-x86/testcases/<test dir>/<CPU>/<test>
func RpathFlags(ctx android.ModuleContext) []string {
	key := struct {
		os   android.OsType
		arch android.ArchType
	}{ctx.Target().Os, ctx.Target().Arch.ArchType}

	return ctx.Config().OnceStringSlice(android.NewCustomOnceKey(key), func() []string {
		rpathPrefix := `\$$ORIGIN/`
		if key.os == android.Darwin {
			rpathPrefix = "@loader_path/"
		}

		var libDir string
		if key.arch.Multilib == "lib64" {
			libDir = "lib64"
		} else {
			libDir = "lib"
		}

		return []string{
			"-Wl,-rpath," + rpathPrefix,
			"-Wl,-rpath," + rpathPrefix + libDir,
			"-Wl,-rpath," + rpathPrefix + filepath.Join("..", libDir),
			"-Wl,-rpath," + rpathPrefix + filepath.Join("../..", libDir),
			"-Wl,-rpath," + rpathPrefix + filepath.Join("../../..", libDir),
		}
	})
}

func (linker *baseLinker) link(ctx ModuleContext,
	flags Flags, deps PathDeps, objs Objects) android.Path {
	panic(fmt.Errorf("baseLinker doesn't know how to link"))
+0 −36
Original line number Diff line number Diff line
@@ -311,23 +311,6 @@ func (test *testDecorator) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
	return deps
}

func (test *testDecorator) linkerInit(ctx BaseModuleContext, linker *baseLinker) {
	// 1. Add ../../lib[64] to rpath so that out/host/linux-x86/nativetest/<test dir>/<test> can
	// find out/host/linux-x86/lib[64]/library.so
	// 2. Add ../../../lib[64] to rpath so that out/host/linux-x86/testcases/<test dir>/<CPU>/<test> can
	// also find out/host/linux-x86/lib[64]/library.so
	runpaths := []string{"../../lib", "../../../lib"}
	for _, runpath := range runpaths {
		if ctx.toolchain().Is64Bit() {
			runpath += "64"
		}
		linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, runpath)
	}

	// add "" to rpath so that test binaries can find libraries in their own test directory
	linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, "")
}

func (test *testDecorator) linkerProps() []interface{} {
	return []interface{}{&test.LinkerProperties}
}
@@ -356,11 +339,6 @@ func (test *testBinary) linkerProps() []interface{} {
	return props
}

func (test *testBinary) linkerInit(ctx BaseModuleContext) {
	test.testDecorator.linkerInit(ctx, test.binaryDecorator.baseLinker)
	test.binaryDecorator.linkerInit(ctx)
}

func (test *testBinary) linkerDeps(ctx DepsContext, deps Deps) Deps {
	deps = test.testDecorator.linkerDeps(ctx, deps)
	deps = test.binaryDecorator.linkerDeps(ctx, deps)
@@ -535,11 +513,6 @@ func (test *testLibrary) linkerProps() []interface{} {
	return append(props, test.libraryDecorator.linkerProps()...)
}

func (test *testLibrary) linkerInit(ctx BaseModuleContext) {
	test.testDecorator.linkerInit(ctx, test.libraryDecorator.baseLinker)
	test.libraryDecorator.linkerInit(ctx)
}

func (test *testLibrary) linkerDeps(ctx DepsContext, deps Deps) Deps {
	deps = test.testDecorator.linkerDeps(ctx, deps)
	deps = test.libraryDecorator.linkerDeps(ctx, deps)
@@ -610,15 +583,6 @@ func (benchmark *benchmarkDecorator) benchmarkBinary() bool {
	return true
}

func (benchmark *benchmarkDecorator) linkerInit(ctx BaseModuleContext) {
	runpath := "../../lib"
	if ctx.toolchain().Is64Bit() {
		runpath += "64"
	}
	benchmark.baseLinker.dynamicProperties.RunPaths = append(benchmark.baseLinker.dynamicProperties.RunPaths, runpath)
	benchmark.binaryDecorator.linkerInit(ctx)
}

func (benchmark *benchmarkDecorator) linkerProps() []interface{} {
	props := benchmark.binaryDecorator.linkerProps()
	props = append(props, &benchmark.Properties)
+2 −13
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
package rust

import (
	"android/soong/cc"
	"fmt"
	"path/filepath"
	"strings"
@@ -307,19 +308,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flag
	flags.EmitXrefs = ctx.Config().EmitXrefRules()

	if ctx.Host() && !ctx.Windows() {
		rpathPrefix := `\$$ORIGIN/`
		if ctx.Darwin() {
			rpathPrefix = "@loader_path/"
		}

		var rpath string
		if ctx.toolchain().Is64Bit() {
			rpath = "lib64"
		} else {
			rpath = "lib"
		}
		flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpathPrefix+rpath)
		flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpathPrefix+"../"+rpath)
		flags.LinkFlags = append(flags.LinkFlags, cc.RpathFlags(ctx)...)
	}

	return flags
+1 −0
Original line number Diff line number Diff line
@@ -200,6 +200,7 @@ func (test *testDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
	if ctx.Device() {
		flags.RustFlags = append(flags.RustFlags, "-Z panic_abort_tests")
	}

	return flags
}