Sandbox soong_build by changing to root directory
This relands I12a0f907753fefd1997ab8b4ea2ac331234093cf along with a fix to blueprint for absolute paths. Store the current working directory and then change to the root directory so that all file accesses must go through helpers in the android package that properly track dependencies. Change-Id: I24ac485677aa102eec1a2521d16820da6ee1ae77 Fixes: 146437378 Test: m checkbuild Test: m OUT_DIR=/tmp/out nothing
This commit is contained in:
parent
47e4f9e1e8
commit
988414c2cf
|
@ -69,6 +69,7 @@ bootstrap_go_package {
|
|||
"android/proto.go",
|
||||
"android/register.go",
|
||||
"android/rule_builder.go",
|
||||
"android/sandbox.go",
|
||||
"android/sdk.go",
|
||||
"android/sh_binary.go",
|
||||
"android/singleton.go",
|
||||
|
|
|
@ -323,7 +323,7 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
return
|
||||
}
|
||||
|
||||
err := translateAndroidMk(ctx, transMk.String(), androidMkModulesList)
|
||||
err := translateAndroidMk(ctx, absolutePath(transMk.String()), androidMkModulesList)
|
||||
if err != nil {
|
||||
ctx.Errorf(err.Error())
|
||||
}
|
||||
|
@ -364,8 +364,8 @@ func translateAndroidMk(ctx SingletonContext, mkFile string, mods []blueprint.Mo
|
|||
}
|
||||
|
||||
// Don't write to the file if it hasn't changed
|
||||
if _, err := os.Stat(mkFile); !os.IsNotExist(err) {
|
||||
if data, err := ioutil.ReadFile(mkFile); err == nil {
|
||||
if _, err := os.Stat(absolutePath(mkFile)); !os.IsNotExist(err) {
|
||||
if data, err := ioutil.ReadFile(absolutePath(mkFile)); err == nil {
|
||||
matches := buf.Len() == len(data)
|
||||
|
||||
if matches {
|
||||
|
@ -383,7 +383,7 @@ func translateAndroidMk(ctx SingletonContext, mkFile string, mods []blueprint.Mo
|
|||
}
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(mkFile, buf.Bytes(), 0666)
|
||||
return ioutil.WriteFile(absolutePath(mkFile), buf.Bytes(), 0666)
|
||||
}
|
||||
|
||||
func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.Module) error {
|
||||
|
|
|
@ -135,12 +135,12 @@ type jsonConfigurable interface {
|
|||
}
|
||||
|
||||
func loadConfig(config *config) error {
|
||||
err := loadFromConfigFile(&config.FileConfigurableOptions, config.ConfigFileName)
|
||||
err := loadFromConfigFile(&config.FileConfigurableOptions, absolutePath(config.ConfigFileName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return loadFromConfigFile(&config.productVariables, config.ProductVariablesFileName)
|
||||
return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName))
|
||||
}
|
||||
|
||||
// loads configuration options from a JSON file in the cwd.
|
||||
|
@ -204,6 +204,17 @@ func saveToConfigFile(config jsonConfigurable, filename string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that
|
||||
// use the android package.
|
||||
func NullConfig(buildDir string) Config {
|
||||
return Config{
|
||||
config: &config{
|
||||
buildDir: buildDir,
|
||||
fs: pathtools.OsFs,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// TestConfig returns a Config object suitable for using for tests
|
||||
func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
|
||||
envCopy := make(map[string]string)
|
||||
|
@ -320,7 +331,7 @@ func NewConfig(srcDir, buildDir string) (Config, error) {
|
|||
buildDir: buildDir,
|
||||
multilibConflicts: make(map[ArchType]bool),
|
||||
|
||||
fs: pathtools.OsFs,
|
||||
fs: pathtools.NewOsFs(absSrcDir),
|
||||
}
|
||||
|
||||
config.deviceConfig = &deviceConfig{
|
||||
|
@ -350,7 +361,7 @@ func NewConfig(srcDir, buildDir string) (Config, error) {
|
|||
}
|
||||
|
||||
inMakeFile := filepath.Join(buildDir, ".soong.in_make")
|
||||
if _, err := os.Stat(inMakeFile); err == nil {
|
||||
if _, err := os.Stat(absolutePath(inMakeFile)); err == nil {
|
||||
config.inMake = true
|
||||
}
|
||||
|
||||
|
@ -398,6 +409,8 @@ func NewConfig(srcDir, buildDir string) (Config, error) {
|
|||
return Config{config}, nil
|
||||
}
|
||||
|
||||
var TestConfigOsFs = map[string][]byte{}
|
||||
|
||||
// mockFileSystem replaces all reads with accesses to the provided map of
|
||||
// filenames to contents stored as a byte slice.
|
||||
func (c *config) mockFileSystem(bp string, fs map[string][]byte) {
|
||||
|
@ -901,8 +914,13 @@ func (c *config) BootJars() []string {
|
|||
return c.productVariables.BootJars
|
||||
}
|
||||
|
||||
func (c *config) DexpreoptGlobalConfig() string {
|
||||
return String(c.productVariables.DexpreoptGlobalConfig)
|
||||
func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) {
|
||||
if c.productVariables.DexpreoptGlobalConfig == nil {
|
||||
return nil, nil
|
||||
}
|
||||
path := absolutePath(*c.productVariables.DexpreoptGlobalConfig)
|
||||
ctx.AddNinjaFileDeps(path)
|
||||
return ioutil.ReadFile(path)
|
||||
}
|
||||
|
||||
func (c *config) FrameworksBaseDirExists(ctx PathContext) bool {
|
||||
|
|
|
@ -52,6 +52,17 @@ func init() {
|
|||
os.Clearenv()
|
||||
}
|
||||
|
||||
// getenv checks either os.Getenv or originalEnv so that it works before or after the init()
|
||||
// function above. It doesn't add any dependencies on the environment variable, so it should
|
||||
// only be used for values that won't change. For values that might change use ctx.Config().Getenv.
|
||||
func getenv(key string) string {
|
||||
if originalEnv == nil {
|
||||
return os.Getenv(key)
|
||||
} else {
|
||||
return originalEnv[key]
|
||||
}
|
||||
}
|
||||
|
||||
func EnvSingleton() Singleton {
|
||||
return &envSingleton{}
|
||||
}
|
||||
|
@ -66,7 +77,12 @@ func (c *envSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
return
|
||||
}
|
||||
|
||||
err := env.WriteEnvFile(envFile.String(), envDeps)
|
||||
data, err := env.EnvFileContents(envDeps)
|
||||
if err != nil {
|
||||
ctx.Errorf(err.Error())
|
||||
}
|
||||
|
||||
err = WriteFileToOutputDir(envFile, data, 0666)
|
||||
if err != nil {
|
||||
ctx.Errorf(err.Error())
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
"github.com/google/blueprint/proptools"
|
||||
)
|
||||
|
||||
|
@ -41,7 +40,6 @@ type MakeVarsContext interface {
|
|||
Config() Config
|
||||
DeviceConfig() DeviceConfig
|
||||
AddNinjaFileDeps(deps ...string)
|
||||
Fs() pathtools.FileSystem
|
||||
|
||||
ModuleName(module blueprint.Module) string
|
||||
ModuleDir(module blueprint.Module) string
|
||||
|
@ -151,7 +149,8 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
return
|
||||
}
|
||||
|
||||
outFile := PathForOutput(ctx, "make_vars"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String()
|
||||
outFile := absolutePath(PathForOutput(ctx,
|
||||
"make_vars"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
|
||||
|
||||
if ctx.Failed() {
|
||||
return
|
||||
|
@ -175,15 +174,15 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
|
||||
outBytes := s.writeVars(vars)
|
||||
|
||||
if _, err := os.Stat(outFile); err == nil {
|
||||
if data, err := ioutil.ReadFile(outFile); err == nil {
|
||||
if _, err := os.Stat(absolutePath(outFile)); err == nil {
|
||||
if data, err := ioutil.ReadFile(absolutePath(outFile)); err == nil {
|
||||
if bytes.Equal(data, outBytes) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(outFile, outBytes, 0666); err != nil {
|
||||
if err := ioutil.WriteFile(absolutePath(outFile), outBytes, 0666); err != nil {
|
||||
ctx.Errorf(err.Error())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,13 +16,13 @@ package android
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/scanner"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
"github.com/google/blueprint/proptools"
|
||||
)
|
||||
|
||||
|
@ -91,7 +91,8 @@ type EarlyModuleContext interface {
|
|||
|
||||
Glob(globPattern string, excludes []string) Paths
|
||||
GlobFiles(globPattern string, excludes []string) Paths
|
||||
Fs() pathtools.FileSystem
|
||||
IsSymlink(path Path) bool
|
||||
Readlink(path Path) string
|
||||
}
|
||||
|
||||
// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
|
||||
|
@ -1172,6 +1173,22 @@ func (e *earlyModuleContext) GlobFiles(globPattern string, excludes []string) Pa
|
|||
return pathsForModuleSrcFromFullPath(e, ret, false)
|
||||
}
|
||||
|
||||
func (b *earlyModuleContext) IsSymlink(path Path) bool {
|
||||
fileInfo, err := b.config.fs.Lstat(path.String())
|
||||
if err != nil {
|
||||
b.ModuleErrorf("os.Lstat(%q) failed: %s", path.String(), err)
|
||||
}
|
||||
return fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink
|
||||
}
|
||||
|
||||
func (b *earlyModuleContext) Readlink(path Path) string {
|
||||
dest, err := b.config.fs.Readlink(path.String())
|
||||
if err != nil {
|
||||
b.ModuleErrorf("os.Readlink(%q) failed: %s", path.String(), err)
|
||||
}
|
||||
return dest
|
||||
}
|
||||
|
||||
func (e *earlyModuleContext) Module() Module {
|
||||
module, _ := e.EarlyModuleContext.Module().(Module)
|
||||
return module
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
)
|
||||
|
||||
// PackageContext is a wrapper for blueprint.PackageContext that adds
|
||||
|
@ -60,10 +59,6 @@ func (e *configErrorWrapper) AddNinjaFileDeps(deps ...string) {
|
|||
e.pctx.AddNinjaFileDeps(deps...)
|
||||
}
|
||||
|
||||
func (e *configErrorWrapper) Fs() pathtools.FileSystem {
|
||||
return nil
|
||||
}
|
||||
|
||||
type PackageVarContext interface {
|
||||
PathContext
|
||||
errorfContext
|
||||
|
|
|
@ -16,6 +16,8 @@ package android
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
@ -25,10 +27,11 @@ import (
|
|||
"github.com/google/blueprint/pathtools"
|
||||
)
|
||||
|
||||
var absSrcDir string
|
||||
|
||||
// PathContext is the subset of a (Module|Singleton)Context required by the
|
||||
// Path methods.
|
||||
type PathContext interface {
|
||||
Fs() pathtools.FileSystem
|
||||
Config() Config
|
||||
AddNinjaFileDeps(deps ...string)
|
||||
}
|
||||
|
@ -390,7 +393,7 @@ func expandOneSrcPath(ctx ModuleContext, s string, expandedExcludes []string) (P
|
|||
return PathsWithModuleSrcSubDir(ctx, paths, ""), nil
|
||||
} else {
|
||||
p := pathForModuleSrc(ctx, s)
|
||||
if exists, _, err := ctx.Fs().Exists(p.String()); err != nil {
|
||||
if exists, _, err := ctx.Config().fs.Exists(p.String()); err != nil {
|
||||
reportPathErrorf(ctx, "%s: %s", p, err.Error())
|
||||
} else if !exists {
|
||||
reportPathErrorf(ctx, "module source path %q does not exist", p)
|
||||
|
@ -720,7 +723,7 @@ func existsWithDependencies(ctx PathContext, path SourcePath) (exists bool, err
|
|||
var deps []string
|
||||
// We cannot add build statements in this context, so we fall back to
|
||||
// AddNinjaFileDeps
|
||||
files, deps, err = pathtools.Glob(path.String(), nil, pathtools.FollowSymlinks)
|
||||
files, deps, err = ctx.Config().fs.Glob(path.String(), nil, pathtools.FollowSymlinks)
|
||||
ctx.AddNinjaFileDeps(deps...)
|
||||
}
|
||||
|
||||
|
@ -752,7 +755,7 @@ func PathForSource(ctx PathContext, pathComponents ...string) SourcePath {
|
|||
if !exists {
|
||||
modCtx.AddMissingDependencies([]string{path.String()})
|
||||
}
|
||||
} else if exists, _, err := ctx.Fs().Exists(path.String()); err != nil {
|
||||
} else if exists, _, err := ctx.Config().fs.Exists(path.String()); err != nil {
|
||||
reportPathErrorf(ctx, "%s: %s", path, err.Error())
|
||||
} else if !exists {
|
||||
reportPathErrorf(ctx, "source path %q does not exist", path)
|
||||
|
@ -1356,7 +1359,6 @@ type testPathContext struct {
|
|||
config Config
|
||||
}
|
||||
|
||||
func (x *testPathContext) Fs() pathtools.FileSystem { return x.config.fs }
|
||||
func (x *testPathContext) Config() Config { return x.config }
|
||||
func (x *testPathContext) AddNinjaFileDeps(...string) {}
|
||||
|
||||
|
@ -1402,3 +1404,16 @@ func maybeRelErr(basePath string, targetPath string) (string, bool, error) {
|
|||
}
|
||||
return rel, true, nil
|
||||
}
|
||||
|
||||
// Writes a file to the output directory. Attempting to write directly to the output directory
|
||||
// will fail due to the sandbox of the soong_build process.
|
||||
func WriteFileToOutputDir(path WritablePath, data []byte, perm os.FileMode) error {
|
||||
return ioutil.WriteFile(absolutePath(path.String()), data, perm)
|
||||
}
|
||||
|
||||
func absolutePath(path string) string {
|
||||
if filepath.IsAbs(path) {
|
||||
return path
|
||||
}
|
||||
return filepath.Join(absSrcDir, path)
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/blueprint/pathtools"
|
||||
"github.com/google/blueprint/proptools"
|
||||
)
|
||||
|
||||
|
@ -207,10 +206,6 @@ type moduleInstallPathContextImpl struct {
|
|||
inRoot bool
|
||||
}
|
||||
|
||||
func (moduleInstallPathContextImpl) Fs() pathtools.FileSystem {
|
||||
return pathtools.MockFs(nil)
|
||||
}
|
||||
|
||||
func (m moduleInstallPathContextImpl) Config() Config {
|
||||
return m.baseModuleContext.config
|
||||
}
|
||||
|
|
|
@ -84,7 +84,9 @@ type Context struct {
|
|||
}
|
||||
|
||||
func NewContext() *Context {
|
||||
return &Context{blueprint.NewContext()}
|
||||
ctx := &Context{blueprint.NewContext()}
|
||||
ctx.SetSrcDir(absSrcDir)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (ctx *Context) Register() {
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2020 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.
|
||||
|
||||
package android
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Stash the working directory in a private variable and then change the working directory
|
||||
// to "/", which will prevent untracked accesses to files by Go Soong plugins. The
|
||||
// SOONG_SANDBOX_SOONG_BUILD environment variable is set by soong_ui, and is not
|
||||
// overrideable on the command line.
|
||||
|
||||
orig, err := os.Getwd()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to get working directory: %s", err))
|
||||
}
|
||||
absSrcDir = orig
|
||||
|
||||
if getenv("SOONG_SANDBOX_SOONG_BUILD") == "true" {
|
||||
err = os.Chdir("/")
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to change working directory to '/': %s", err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DO NOT USE THIS FUNCTION IN NEW CODE.
|
||||
// Deprecated: This function will be removed as soon as the existing use cases that use it have been
|
||||
// replaced.
|
||||
func AbsSrcDirForExistingUseCases() string {
|
||||
return absSrcDir
|
||||
}
|
|
@ -16,7 +16,6 @@ package android
|
|||
|
||||
import (
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
)
|
||||
|
||||
// SingletonContext
|
||||
|
@ -74,8 +73,6 @@ type SingletonContext interface {
|
|||
// builder whenever a file matching the pattern as added or removed, without rerunning if a
|
||||
// file that does not match the pattern is added to a searched directory.
|
||||
GlobWithDeps(pattern string, excludes []string) ([]string, error)
|
||||
|
||||
Fs() pathtools.FileSystem
|
||||
}
|
||||
|
||||
type singletonAdaptor struct {
|
||||
|
|
|
@ -41,7 +41,6 @@ bootstrap_go_package {
|
|||
"androidmk-parser",
|
||||
"blueprint-parser",
|
||||
"bpfix-lib",
|
||||
"soong-android",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
package androidmk
|
||||
|
||||
import (
|
||||
"android/soong/android"
|
||||
mkparser "android/soong/androidmk/parser"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
bpparser "github.com/google/blueprint/parser"
|
||||
|
@ -350,7 +350,13 @@ func splitAndAssign(ctx variableAssignmentContext, splitFunc listSplitFunc, name
|
|||
return err
|
||||
}
|
||||
|
||||
for _, nameClassification := range android.SortedStringKeys(namesByClassification) {
|
||||
var classifications []string
|
||||
for classification := range namesByClassification {
|
||||
classifications = append(classifications, classification)
|
||||
}
|
||||
sort.Strings(classifications)
|
||||
|
||||
for _, nameClassification := range classifications {
|
||||
name := namesByClassification[nameClassification]
|
||||
if component, ok := lists[nameClassification]; ok && !emptyList(component) {
|
||||
err = setVariable(ctx.file, ctx.append, ctx.prefix, name, component, true)
|
||||
|
|
|
@ -76,7 +76,7 @@ func (c *cmakelistsGeneratorSingleton) GenerateBuildActions(ctx android.Singleto
|
|||
// Link all handmade CMakeLists.txt aggregate from
|
||||
// BASE/development/ide/clion to
|
||||
// BASE/out/development/ide/clion.
|
||||
dir := filepath.Join(getAndroidSrcRootDirectory(ctx), cLionAggregateProjectsDirectory)
|
||||
dir := filepath.Join(android.AbsSrcDirForExistingUseCases(), cLionAggregateProjectsDirectory)
|
||||
filepath.Walk(dir, linkAggregateCMakeListsFiles)
|
||||
|
||||
return
|
||||
|
@ -147,7 +147,7 @@ func generateCLionProject(compiledModule CompiledInterface, ctx android.Singleto
|
|||
f.WriteString("# Tools > CMake > Change Project Root \n\n")
|
||||
f.WriteString(fmt.Sprintf("cmake_minimum_required(VERSION %s)\n", minimumCMakeVersionSupported))
|
||||
f.WriteString(fmt.Sprintf("project(%s)\n", ccModule.ModuleBase.Name()))
|
||||
f.WriteString(fmt.Sprintf("set(ANDROID_ROOT %s)\n\n", getAndroidSrcRootDirectory(ctx)))
|
||||
f.WriteString(fmt.Sprintf("set(ANDROID_ROOT %s)\n\n", android.AbsSrcDirForExistingUseCases()))
|
||||
|
||||
pathToCC, _ := evalVariable(ctx, "${config.ClangBin}/")
|
||||
f.WriteString(fmt.Sprintf("set(CMAKE_C_COMPILER \"%s%s\")\n", buildCMakePath(pathToCC), "clang"))
|
||||
|
@ -465,7 +465,7 @@ func evalVariable(ctx android.SingletonContext, str string) (string, error) {
|
|||
}
|
||||
|
||||
func getCMakeListsForModule(module *Module, ctx android.SingletonContext) string {
|
||||
return filepath.Join(getAndroidSrcRootDirectory(ctx),
|
||||
return filepath.Join(android.AbsSrcDirForExistingUseCases(),
|
||||
cLionOutputProjectsDirectory,
|
||||
path.Dir(ctx.BlueprintFile(module)),
|
||||
module.ModuleBase.Name()+"-"+
|
||||
|
@ -473,8 +473,3 @@ func getCMakeListsForModule(module *Module, ctx android.SingletonContext) string
|
|||
module.ModuleBase.Os().Name,
|
||||
cMakeListsFilename)
|
||||
}
|
||||
|
||||
func getAndroidSrcRootDirectory(ctx android.SingletonContext) string {
|
||||
srcPath, _ := filepath.Abs(android.PathForSource(ctx).String())
|
||||
return srcPath
|
||||
}
|
||||
|
|
22
cc/compdb.go
22
cc/compdb.go
|
@ -79,9 +79,9 @@ func (c *compdbGeneratorSingleton) GenerateBuildActions(ctx android.SingletonCon
|
|||
|
||||
// Create the output file.
|
||||
dir := android.PathForOutput(ctx, compdbOutputProjectsDirectory)
|
||||
os.MkdirAll(dir.String(), 0777)
|
||||
os.MkdirAll(filepath.Join(android.AbsSrcDirForExistingUseCases(), dir.String()), 0777)
|
||||
compDBFile := dir.Join(ctx, compdbFilename)
|
||||
f, err := os.Create(compDBFile.String())
|
||||
f, err := os.Create(filepath.Join(android.AbsSrcDirForExistingUseCases(), compDBFile.String()))
|
||||
if err != nil {
|
||||
log.Fatalf("Could not create file %s: %s", compDBFile, err)
|
||||
}
|
||||
|
@ -103,8 +103,8 @@ func (c *compdbGeneratorSingleton) GenerateBuildActions(ctx android.SingletonCon
|
|||
}
|
||||
f.Write(dat)
|
||||
|
||||
finalLinkPath := filepath.Join(ctx.Config().Getenv(envVariableCompdbLink), compdbFilename)
|
||||
if finalLinkPath != "" {
|
||||
if finalLinkDir := ctx.Config().Getenv(envVariableCompdbLink); finalLinkDir != "" {
|
||||
finalLinkPath := filepath.Join(finalLinkDir, compdbFilename)
|
||||
os.Remove(finalLinkPath)
|
||||
if err := os.Symlink(compDBFile.String(), finalLinkPath); err != nil {
|
||||
log.Fatalf("Unable to symlink %s to %s: %s", compDBFile, finalLinkPath, err)
|
||||
|
@ -174,18 +174,17 @@ func generateCompdbProject(compiledModule CompiledInterface, ctx android.Singlet
|
|||
return
|
||||
}
|
||||
|
||||
rootDir := getCompdbAndroidSrcRootDirectory(ctx)
|
||||
pathToCC, err := ctx.Eval(pctx, rootDir+"/${config.ClangBin}/")
|
||||
pathToCC, err := ctx.Eval(pctx, "${config.ClangBin}")
|
||||
ccPath := "/bin/false"
|
||||
cxxPath := "/bin/false"
|
||||
if err == nil {
|
||||
ccPath = pathToCC + "clang"
|
||||
cxxPath = pathToCC + "clang++"
|
||||
ccPath = filepath.Join(pathToCC, "clang")
|
||||
cxxPath = filepath.Join(pathToCC, "clang++")
|
||||
}
|
||||
for _, src := range srcs {
|
||||
if _, ok := builds[src.String()]; !ok {
|
||||
builds[src.String()] = compDbEntry{
|
||||
Directory: rootDir,
|
||||
Directory: android.AbsSrcDirForExistingUseCases(),
|
||||
Arguments: getArguments(src, ctx, ccModule, ccPath, cxxPath),
|
||||
File: src.String(),
|
||||
}
|
||||
|
@ -200,8 +199,3 @@ func evalAndSplitVariable(ctx android.SingletonContext, str string) ([]string, e
|
|||
}
|
||||
return []string{""}, err
|
||||
}
|
||||
|
||||
func getCompdbAndroidSrcRootDirectory(ctx android.SingletonContext) string {
|
||||
srcPath, _ := filepath.Abs(android.PathForSource(ctx).String())
|
||||
return srcPath
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ package cc
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
|
@ -255,16 +254,8 @@ func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir andro
|
|||
depsPath := android.PathForSource(ctx, "bionic/libc/versioner-dependencies")
|
||||
depsGlob := ctx.Glob(filepath.Join(depsPath.String(), "**/*"), nil)
|
||||
for i, path := range depsGlob {
|
||||
fileInfo, err := os.Lstat(path.String())
|
||||
if err != nil {
|
||||
ctx.ModuleErrorf("os.Lstat(%q) failed: %s", path.String, err)
|
||||
}
|
||||
if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||
dest, err := os.Readlink(path.String())
|
||||
if err != nil {
|
||||
ctx.ModuleErrorf("os.Readlink(%q) failed: %s",
|
||||
path.String, err)
|
||||
}
|
||||
if ctx.IsSymlink(path) {
|
||||
dest := ctx.Readlink(path)
|
||||
// Additional .. to account for the symlink itself.
|
||||
depsGlob[i] = android.PathForSource(
|
||||
ctx, filepath.Clean(filepath.Join(path.String(), "..", dest)))
|
||||
|
|
|
@ -16,7 +16,6 @@ package dexpreopt
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"android/soong/android"
|
||||
|
@ -185,7 +184,7 @@ func constructWritablePath(ctx android.PathContext, path string) android.Writabl
|
|||
// soongConfig argument. LoadGlobalConfig is used directly in Soong and in
|
||||
// dexpreopt_gen called from Make to read the $OUT/dexpreopt.config written by
|
||||
// Make.
|
||||
func LoadGlobalConfig(ctx android.PathContext, path string, soongConfig GlobalSoongConfig) (GlobalConfig, []byte, error) {
|
||||
func LoadGlobalConfig(ctx android.PathContext, data []byte, soongConfig GlobalSoongConfig) (GlobalConfig, error) {
|
||||
type GlobalJSONConfig struct {
|
||||
GlobalConfig
|
||||
|
||||
|
@ -196,9 +195,9 @@ func LoadGlobalConfig(ctx android.PathContext, path string, soongConfig GlobalSo
|
|||
}
|
||||
|
||||
config := GlobalJSONConfig{}
|
||||
data, err := loadConfig(ctx, path, &config)
|
||||
err := json.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
return config.GlobalConfig, nil, err
|
||||
return config.GlobalConfig, err
|
||||
}
|
||||
|
||||
// Construct paths that require a PathContext.
|
||||
|
@ -209,13 +208,13 @@ func LoadGlobalConfig(ctx android.PathContext, path string, soongConfig GlobalSo
|
|||
// either CreateGlobalSoongConfig or LoadGlobalSoongConfig).
|
||||
config.GlobalConfig.SoongConfig = soongConfig
|
||||
|
||||
return config.GlobalConfig, data, nil
|
||||
return config.GlobalConfig, nil
|
||||
}
|
||||
|
||||
// LoadModuleConfig reads a per-module dexpreopt.config file into a ModuleConfig struct. It is not used in Soong, which
|
||||
// receives a ModuleConfig struct directly from java/dexpreopt.go. It is used in dexpreopt_gen called from oMake to
|
||||
// read the module dexpreopt.config written by Make.
|
||||
func LoadModuleConfig(ctx android.PathContext, path string) (ModuleConfig, error) {
|
||||
func LoadModuleConfig(ctx android.PathContext, data []byte) (ModuleConfig, error) {
|
||||
type ModuleJSONConfig struct {
|
||||
ModuleConfig
|
||||
|
||||
|
@ -233,7 +232,7 @@ func LoadModuleConfig(ctx android.PathContext, path string) (ModuleConfig, error
|
|||
|
||||
config := ModuleJSONConfig{}
|
||||
|
||||
_, err := loadConfig(ctx, path, &config)
|
||||
err := json.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
return config.ModuleConfig, err
|
||||
}
|
||||
|
@ -289,10 +288,10 @@ type globalJsonSoongConfig struct {
|
|||
|
||||
// LoadGlobalSoongConfig reads the dexpreopt_soong.config file into a
|
||||
// GlobalSoongConfig struct. It is only used in dexpreopt_gen.
|
||||
func LoadGlobalSoongConfig(ctx android.PathContext, path string) (GlobalSoongConfig, error) {
|
||||
func LoadGlobalSoongConfig(ctx android.PathContext, data []byte) (GlobalSoongConfig, error) {
|
||||
var jc globalJsonSoongConfig
|
||||
|
||||
_, err := loadConfig(ctx, path, &jc)
|
||||
err := json.Unmarshal(data, &jc)
|
||||
if err != nil {
|
||||
return GlobalSoongConfig{}, err
|
||||
}
|
||||
|
@ -352,26 +351,6 @@ func (s *globalSoongConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
|
|||
}, " "))
|
||||
}
|
||||
|
||||
func loadConfig(ctx android.PathContext, path string, config interface{}) ([]byte, error) {
|
||||
r, err := ctx.Fs().Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func GlobalConfigForTests(ctx android.PathContext) GlobalConfig {
|
||||
return GlobalConfig{
|
||||
DisablePreopt: false,
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
@ -41,7 +42,6 @@ type pathContext struct {
|
|||
config android.Config
|
||||
}
|
||||
|
||||
func (x *pathContext) Fs() pathtools.FileSystem { return pathtools.OsFs }
|
||||
func (x *pathContext) Config() android.Config { return x.config }
|
||||
func (x *pathContext) AddNinjaFileDeps(...string) {}
|
||||
|
||||
|
@ -76,21 +76,39 @@ func main() {
|
|||
usage("--module configuration file is required")
|
||||
}
|
||||
|
||||
ctx := &pathContext{android.TestConfig(*outDir, nil, "", nil)}
|
||||
ctx := &pathContext{android.NullConfig(*outDir)}
|
||||
|
||||
globalSoongConfig, err := dexpreopt.LoadGlobalSoongConfig(ctx, *globalSoongConfigPath)
|
||||
globalSoongConfigData, err := ioutil.ReadFile(*globalSoongConfigPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error reading global config %q: %s\n", *globalSoongConfigPath, err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
globalSoongConfig, err := dexpreopt.LoadGlobalSoongConfig(ctx, globalSoongConfigData)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalSoongConfigPath, err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
globalConfig, _, err := dexpreopt.LoadGlobalConfig(ctx, *globalConfigPath, globalSoongConfig)
|
||||
globalConfigData, err := ioutil.ReadFile(*globalConfigPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalConfigPath, err)
|
||||
fmt.Fprintf(os.Stderr, "error reading global config %q: %s\n", *globalConfigPath, err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
moduleConfig, err := dexpreopt.LoadModuleConfig(ctx, *moduleConfigPath)
|
||||
globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, globalConfigData, globalSoongConfig)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error parse global config %q: %s\n", *globalConfigPath, err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
moduleConfigData, err := ioutil.ReadFile(*moduleConfigPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error reading module config %q: %s\n", *moduleConfigPath, err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
moduleConfig, err := dexpreopt.LoadModuleConfig(ctx, moduleConfigData)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading module config %q: %s\n", *moduleConfigPath, err)
|
||||
os.Exit(2)
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
type envFileEntry struct{ Key, Value string }
|
||||
type envFileData []envFileEntry
|
||||
|
||||
func WriteEnvFile(filename string, envDeps map[string]string) error {
|
||||
func EnvFileContents(envDeps map[string]string) ([]byte, error) {
|
||||
contents := make(envFileData, 0, len(envDeps))
|
||||
for key, value := range envDeps {
|
||||
contents = append(contents, envFileEntry{key, value})
|
||||
|
@ -37,17 +37,12 @@ func WriteEnvFile(filename string, envDeps map[string]string) error {
|
|||
|
||||
data, err := json.MarshalIndent(contents, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data = append(data, '\n')
|
||||
|
||||
err = ioutil.WriteFile(filename, data, 0664)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func StaleEnvFile(filename string) (bool, error) {
|
||||
|
|
|
@ -36,10 +36,11 @@ type globalConfigAndRaw struct {
|
|||
|
||||
func dexpreoptGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
|
||||
return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
|
||||
if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
|
||||
if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil {
|
||||
panic(err)
|
||||
} else if data != nil {
|
||||
soongConfig := dexpreopt.CreateGlobalSoongConfig(ctx)
|
||||
ctx.AddNinjaFileDeps(f)
|
||||
globalConfig, data, err := dexpreopt.LoadGlobalConfig(ctx, f, soongConfig)
|
||||
globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, data, soongConfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ package java
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"android/soong/android"
|
||||
)
|
||||
|
@ -92,23 +91,21 @@ func (j *jdepsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonCont
|
|||
moduleInfos[name] = dpInfo
|
||||
})
|
||||
|
||||
jfpath := android.PathForOutput(ctx, jdepsJsonFileName).String()
|
||||
jfpath := android.PathForOutput(ctx, jdepsJsonFileName)
|
||||
err := createJsonFile(moduleInfos, jfpath)
|
||||
if err != nil {
|
||||
ctx.Errorf(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath string) error {
|
||||
file, err := os.Create(jfpath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to create file: %s, relative: %v", jdepsJsonFileName, err)
|
||||
}
|
||||
defer file.Close()
|
||||
func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath android.WritablePath) error {
|
||||
buf, err := json.MarshalIndent(moduleInfos, "", "\t")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Write file failed: %s, relative: %v", jdepsJsonFileName, err)
|
||||
return fmt.Errorf("JSON marshal of java deps failed: %s", err)
|
||||
}
|
||||
err = android.WriteFileToOutputDir(jfpath, buf, 0666)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Writing java deps to %s failed: %s", jfpath.String(), err)
|
||||
}
|
||||
fmt.Fprintf(file, string(buf))
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -119,6 +119,7 @@ func runSoong(ctx Context, config Config) {
|
|||
"-j", strconv.Itoa(config.Parallel()),
|
||||
"--frontend_file", fifo,
|
||||
"-f", filepath.Join(config.SoongOutDir(), file))
|
||||
cmd.Environment.Set("SOONG_SANDBOX_SOONG_BUILD", "true")
|
||||
cmd.Sandbox = soongSandbox
|
||||
cmd.RunAndStreamOrFatal()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue