Export OUT_DIR variable to rust-project.json

This variable is required by rust-analyzer to correctly process crates
that uses the include!(concat!(env!("OUT_DIR"), ...)) pattern.

Adds an initialize method to baseCompiler to save the computed path for
this directory. It is not possible to use the BeginMutator as the
BaseModuleContext does not contain enough information to use
PathForModuleOut.

Bug: 175004835
Test: SOONG_GEN_RUST_PROJECT=1 m nothing; inspect rust-project.json
Change-Id: If47b3832d3cca5712ae87773c174a61f5ee27bf8
This commit is contained in:
Thiébaud Weksteen 2021-02-25 16:30:57 +01:00
parent aa52d66cd5
commit ee6a89ba44
5 changed files with 44 additions and 12 deletions

View File

@ -194,8 +194,7 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl
}
if len(deps.SrcDeps) > 0 {
genSubDir := "out/"
moduleGenDir := android.PathForModuleOut(ctx, genSubDir)
moduleGenDir := ctx.RustModule().compiler.CargoOutDir()
var outputs android.WritablePaths
for _, genSrc := range deps.SrcDeps {
@ -208,7 +207,7 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl
ctx.Build(pctx, android.BuildParams{
Rule: cp,
Description: "cp " + moduleGenDir.Rel(),
Description: "cp " + moduleGenDir.Path().Rel(),
Outputs: outputs,
Inputs: deps.SrcDeps,
Args: map[string]string{

View File

@ -60,6 +60,7 @@ const (
InstallInData = iota
incorrectSourcesError = "srcs can only contain one path for a rust file and source providers prefixed by \":\""
genSubDir = "out/"
)
type BaseCompilerProperties struct {
@ -154,6 +155,10 @@ type baseCompiler struct {
distFile android.OptionalPath
// Stripped output file. If Valid(), this file will be installed instead of outputFile.
strippedOutputFile android.OptionalPath
// If a crate has a source-generated dependency, a copy of the source file
// will be available in cargoOutDir (equivalent to Cargo OUT_DIR).
cargoOutDir android.ModuleOutPath
}
func (compiler *baseCompiler) Disabled() bool {
@ -243,6 +248,14 @@ func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathD
panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
}
func (compiler *baseCompiler) initialize(ctx ModuleContext) {
compiler.cargoOutDir = android.PathForModuleOut(ctx, genSubDir)
}
func (compiler *baseCompiler) CargoOutDir() android.OptionalPath {
return android.OptionalPathForPath(compiler.cargoOutDir)
}
func (compiler *baseCompiler) isDependencyRoot() bool {
return false
}

View File

@ -45,11 +45,12 @@ type rustProjectDep struct {
}
type rustProjectCrate struct {
DisplayName string `json:"display_name"`
RootModule string `json:"root_module"`
Edition string `json:"edition,omitempty"`
Deps []rustProjectDep `json:"deps"`
Cfgs []string `json:"cfgs"`
DisplayName string `json:"display_name"`
RootModule string `json:"root_module"`
Edition string `json:"edition,omitempty"`
Deps []rustProjectDep `json:"deps"`
Cfgs []string `json:"cfgs"`
Env map[string]string `json:"env"`
}
type rustProjectJson struct {
@ -136,7 +137,7 @@ func sourceProviderSource(ctx android.SingletonContext, rModule *Module) (string
}
})
if !foundSource {
fmt.Errorf("No valid source for source provider found: %v\n", rModule)
ctx.Errorf("No valid source for source provider found: %v\n", rModule)
}
return sourceSrc, foundSource
}
@ -220,7 +221,7 @@ func isModuleSupported(ctx android.SingletonContext, module android.Module) (*Mo
func (singleton *projectGeneratorSingleton) addCrate(ctx android.SingletonContext, rModule *Module, comp *baseCompiler) (int, bool) {
rootModule, ok := crateSource(ctx, rModule, comp)
if !ok {
fmt.Errorf("Unable to find source for valid module: %v", rModule)
ctx.Errorf("Unable to find source for valid module: %v", rModule)
return 0, false
}
@ -230,6 +231,11 @@ func (singleton *projectGeneratorSingleton) addCrate(ctx android.SingletonContex
Edition: comp.edition(),
Deps: make([]rustProjectDep, 0),
Cfgs: make([]string, 0),
Env: make(map[string]string),
}
if comp.CargoOutDir().Valid() {
crate.Env["OUT_DIR"] = comp.CargoOutDir().String()
}
deps := make(map[string]int)

View File

@ -190,8 +190,8 @@ func TestProjectJsonBindGen(t *testing.T) {
}
}
}
// Check that liba depends on libbindings1
if strings.Contains(rootModule, "d/src/lib.rs") {
// Check that libd depends on libbindings1
found := false
for _, depName := range validateDependencies(t, crate) {
if depName == "bindings1" {
@ -200,8 +200,17 @@ func TestProjectJsonBindGen(t *testing.T) {
}
}
if !found {
t.Errorf("liba does not depend on libbindings1: %v", crate)
t.Errorf("libd does not depend on libbindings1: %v", crate)
}
// Check that OUT_DIR is populated.
env, ok := crate["env"].(map[string]interface{})
if !ok {
t.Errorf("libd does not have its environment variables set: %v", crate)
}
if _, ok = env["OUT_DIR"]; !ok {
t.Errorf("libd does not have its OUT_DIR set: %v", env)
}
}
}
}

View File

@ -320,12 +320,16 @@ type RustLibrary struct {
}
type compiler interface {
initialize(ctx ModuleContext)
compilerFlags(ctx ModuleContext, flags Flags) Flags
compilerProps() []interface{}
compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path
compilerDeps(ctx DepsContext, deps Deps) Deps
crateName() string
// Output directory in which source-generated code from dependencies is
// copied. This is equivalent to Cargo's OUT_DIR variable.
CargoOutDir() android.OptionalPath
inData() bool
install(ctx ModuleContext)
relativeInstallPath() string
@ -711,6 +715,7 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
}
if mod.compiler != nil && !mod.compiler.Disabled() {
mod.compiler.initialize(ctx)
outputFile := mod.compiler.compile(ctx, flags, deps)
mod.outputFile = android.OptionalPathForPath(outputFile)