Rewrite depfile from sbox to stay reproducible
sbox will generate a random directory for the output root, and most
tools will encode that directory name in the output target of the
depfile.
So embed the library from dep_fixer into sbox so that it can rewrite the
output filename to a static (reproducible) value. Ninja doesn't care
what that value is, so it's just "outputfile".
Also fix up rule_builder to actually tell sbox about the depfile.
Bug: 144948629
Test: mmma system/iorap; check the contents of:
out/soong/.intermediates/system/iorap/libiorap-binder/android_arm_armv7-a-neon_core_static/gen/aidl/system/iorap/binder/com/google/android/startop/iorap/IIorap.cpp.d
Change-Id: I3640a2e8b0c034f143a35e398a8418a6d621b265
Merged-In: I3640a2e8b0c034f143a35e398a8418a6d621b265
(cherry picked from commit c89b6f1981
)
This commit is contained in:
parent
0ce5d05f76
commit
db14db3a06
|
@ -342,10 +342,6 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
|
||||||
sboxOutputs[i] = "__SBOX_OUT_DIR__/" + Rel(ctx, r.sboxOutDir.String(), output.String())
|
sboxOutputs[i] = "__SBOX_OUT_DIR__/" + Rel(ctx, r.sboxOutDir.String(), output.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if depFile != nil {
|
|
||||||
sboxOutputs = append(sboxOutputs, "__SBOX_OUT_DIR__/"+Rel(ctx, r.sboxOutDir.String(), depFile.String()))
|
|
||||||
}
|
|
||||||
|
|
||||||
commandString = proptools.ShellEscape(commandString)
|
commandString = proptools.ShellEscape(commandString)
|
||||||
if !strings.HasPrefix(commandString, `'`) {
|
if !strings.HasPrefix(commandString, `'`) {
|
||||||
commandString = `'` + commandString + `'`
|
commandString = `'` + commandString + `'`
|
||||||
|
@ -355,8 +351,13 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
|
||||||
sboxCmd.Tool(ctx.Config().HostToolPath(ctx, "sbox")).
|
sboxCmd.Tool(ctx.Config().HostToolPath(ctx, "sbox")).
|
||||||
Flag("-c").Text(commandString).
|
Flag("-c").Text(commandString).
|
||||||
Flag("--sandbox-path").Text(shared.TempDirForOutDir(PathForOutput(ctx).String())).
|
Flag("--sandbox-path").Text(shared.TempDirForOutDir(PathForOutput(ctx).String())).
|
||||||
Flag("--output-root").Text(r.sboxOutDir.String()).
|
Flag("--output-root").Text(r.sboxOutDir.String())
|
||||||
Flags(sboxOutputs)
|
|
||||||
|
if depFile != nil {
|
||||||
|
sboxCmd.Flag("--depfile-out").Text(depFile.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
sboxCmd.Flags(sboxOutputs)
|
||||||
|
|
||||||
commandString = string(sboxCmd.buf)
|
commandString = string(sboxCmd.buf)
|
||||||
tools = append(tools, sboxCmd.tools...)
|
tools = append(tools, sboxCmd.tools...)
|
||||||
|
|
|
@ -454,6 +454,7 @@ func TestRuleBuilder_Build(t *testing.T) {
|
||||||
FailIfErrored(t, errs)
|
FailIfErrored(t, errs)
|
||||||
|
|
||||||
check := func(t *testing.T, params TestingBuildParams, wantCommand, wantOutput, wantDepfile string, wantRestat bool, extraCmdDeps []string) {
|
check := func(t *testing.T, params TestingBuildParams, wantCommand, wantOutput, wantDepfile string, wantRestat bool, extraCmdDeps []string) {
|
||||||
|
t.Helper()
|
||||||
if params.RuleParams.Command != wantCommand {
|
if params.RuleParams.Command != wantCommand {
|
||||||
t.Errorf("\nwant RuleParams.Command = %q\n got %q", wantCommand, params.RuleParams.Command)
|
t.Errorf("\nwant RuleParams.Command = %q\n got %q", wantCommand, params.RuleParams.Command)
|
||||||
}
|
}
|
||||||
|
@ -497,13 +498,14 @@ func TestRuleBuilder_Build(t *testing.T) {
|
||||||
t.Run("sbox", func(t *testing.T) {
|
t.Run("sbox", func(t *testing.T) {
|
||||||
outDir := filepath.Join(buildDir, ".intermediates", "foo_sbox")
|
outDir := filepath.Join(buildDir, ".intermediates", "foo_sbox")
|
||||||
outFile := filepath.Join(outDir, "foo_sbox")
|
outFile := filepath.Join(outDir, "foo_sbox")
|
||||||
|
depFile := filepath.Join(outDir, "foo_sbox.d")
|
||||||
sbox := filepath.Join(buildDir, "host", config.PrebuiltOS(), "bin/sbox")
|
sbox := filepath.Join(buildDir, "host", config.PrebuiltOS(), "bin/sbox")
|
||||||
sandboxPath := shared.TempDirForOutDir(buildDir)
|
sandboxPath := shared.TempDirForOutDir(buildDir)
|
||||||
|
|
||||||
cmd := sbox + ` -c 'cp bar __SBOX_OUT_DIR__/foo_sbox' --sandbox-path ` + sandboxPath + " --output-root " + outDir + " __SBOX_OUT_DIR__/foo_sbox __SBOX_OUT_DIR__/foo_sbox.d"
|
cmd := sbox + ` -c 'cp bar __SBOX_OUT_DIR__/foo_sbox' --sandbox-path ` + sandboxPath + " --output-root " + outDir + " --depfile-out " + depFile + " __SBOX_OUT_DIR__/foo_sbox"
|
||||||
|
|
||||||
check(t, ctx.ModuleForTests("foo_sbox", "").Rule("rule"),
|
check(t, ctx.ModuleForTests("foo_sbox", "").Rule("rule"),
|
||||||
cmd, outFile, outFile+".d", false, []string{sbox})
|
cmd, outFile, depFile, false, []string{sbox})
|
||||||
})
|
})
|
||||||
t.Run("singleton", func(t *testing.T) {
|
t.Run("singleton", func(t *testing.T) {
|
||||||
outFile := filepath.Join(buildDir, "baz")
|
outFile := filepath.Join(buildDir, "baz")
|
||||||
|
|
|
@ -14,10 +14,6 @@
|
||||||
|
|
||||||
blueprint_go_binary {
|
blueprint_go_binary {
|
||||||
name: "dep_fixer",
|
name: "dep_fixer",
|
||||||
deps: ["androidmk-parser"],
|
deps: ["soong-makedeps"],
|
||||||
srcs: [
|
srcs: ["main.go"],
|
||||||
"main.go",
|
|
||||||
"deps.go",
|
|
||||||
],
|
|
||||||
testSrcs: ["deps_test.go"],
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"android/soong/makedeps"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -39,7 +41,7 @@ func main() {
|
||||||
log.Fatal("Expected at least one input file as an argument")
|
log.Fatal("Expected at least one input file as an argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
var mergedDeps *Deps
|
var mergedDeps *makedeps.Deps
|
||||||
var firstInput []byte
|
var firstInput []byte
|
||||||
|
|
||||||
for i, arg := range flag.Args() {
|
for i, arg := range flag.Args() {
|
||||||
|
@ -48,7 +50,7 @@ func main() {
|
||||||
log.Fatalf("Error opening %q: %v", arg, err)
|
log.Fatalf("Error opening %q: %v", arg, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
deps, err := Parse(arg, bytes.NewBuffer(append([]byte(nil), input...)))
|
deps, err := makedeps.Parse(arg, bytes.NewBuffer(append([]byte(nil), input...)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to parse: %v", err)
|
log.Fatalf("Failed to parse: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
blueprint_go_binary {
|
blueprint_go_binary {
|
||||||
name: "sbox",
|
name: "sbox",
|
||||||
|
deps: ["soong-makedeps"],
|
||||||
srcs: [
|
srcs: [
|
||||||
"sbox.go",
|
"sbox.go",
|
||||||
],
|
],
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -25,6 +26,8 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"android/soong/makedeps"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -152,9 +155,6 @@ func run() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
allOutputs = append(allOutputs, sandboxedDepfile)
|
allOutputs = append(allOutputs, sandboxedDepfile)
|
||||||
if !strings.Contains(rawCommand, "__SBOX_DEPFILE__") {
|
|
||||||
return fmt.Errorf("the --depfile-out argument only makes sense if the command contains the text __SBOX_DEPFILE__")
|
|
||||||
}
|
|
||||||
rawCommand = strings.Replace(rawCommand, "__SBOX_DEPFILE__", filepath.Join(tempDir, sandboxedDepfile), -1)
|
rawCommand = strings.Replace(rawCommand, "__SBOX_DEPFILE__", filepath.Join(tempDir, sandboxedDepfile), -1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -281,6 +281,26 @@ func run() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rewrite the depfile so that it doesn't include the (randomized) sandbox directory
|
||||||
|
if depfileOut != "" {
|
||||||
|
in, err := ioutil.ReadFile(depfileOut)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
deps, err := makedeps.Parse(depfileOut, bytes.NewBuffer(in))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
deps.Output = "outputfile"
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(depfileOut, deps.Print(), 0666)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(jeffrygaston) if a process creates more output files than it declares, should there be a warning?
|
// TODO(jeffrygaston) if a process creates more output files than it declares, should there be a warning?
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2019 Google Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
bootstrap_go_package {
|
||||||
|
name: "soong-makedeps",
|
||||||
|
pkgPath: "android/soong/makedeps",
|
||||||
|
deps: ["androidmk-parser"],
|
||||||
|
srcs: ["deps.go"],
|
||||||
|
testSrcs: ["deps_test.go"],
|
||||||
|
}
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package main
|
package makedeps
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package main
|
package makedeps
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
Loading…
Reference in New Issue