diff --git a/Android.bp b/Android.bp index 0382ee2ed..9403b26f8 100644 --- a/Android.bp +++ b/Android.bp @@ -69,7 +69,6 @@ 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", diff --git a/android/androidmk.go b/android/androidmk.go index dbf3aa884..f3c15e471 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -323,7 +323,7 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) { return } - err := translateAndroidMk(ctx, absolutePath(transMk.String()), androidMkModulesList) + err := translateAndroidMk(ctx, 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(absolutePath(mkFile)); !os.IsNotExist(err) { - if data, err := ioutil.ReadFile(absolutePath(mkFile)); err == nil { + if _, err := os.Stat(mkFile); !os.IsNotExist(err) { + if data, err := ioutil.ReadFile(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(absolutePath(mkFile), buf.Bytes(), 0666) + return ioutil.WriteFile(mkFile, buf.Bytes(), 0666) } func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.Module) error { diff --git a/android/config.go b/android/config.go index 3c49c1a6a..101f45728 100644 --- a/android/config.go +++ b/android/config.go @@ -135,12 +135,12 @@ type jsonConfigurable interface { } func loadConfig(config *config) error { - err := loadFromConfigFile(&config.FileConfigurableOptions, absolutePath(config.ConfigFileName)) + err := loadFromConfigFile(&config.FileConfigurableOptions, config.ConfigFileName) if err != nil { return err } - return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName)) + return loadFromConfigFile(&config.productVariables, config.ProductVariablesFileName) } // loads configuration options from a JSON file in the cwd. @@ -204,17 +204,6 @@ 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) @@ -331,7 +320,7 @@ func NewConfig(srcDir, buildDir string) (Config, error) { buildDir: buildDir, multilibConflicts: make(map[ArchType]bool), - fs: pathtools.NewOsFs(absSrcDir), + fs: pathtools.OsFs, } config.deviceConfig = &deviceConfig{ @@ -361,7 +350,7 @@ func NewConfig(srcDir, buildDir string) (Config, error) { } inMakeFile := filepath.Join(buildDir, ".soong.in_make") - if _, err := os.Stat(absolutePath(inMakeFile)); err == nil { + if _, err := os.Stat(inMakeFile); err == nil { config.inMake = true } @@ -409,8 +398,6 @@ 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) { @@ -914,13 +901,8 @@ func (c *config) BootJars() []string { return c.productVariables.BootJars } -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) DexpreoptGlobalConfig() string { + return String(c.productVariables.DexpreoptGlobalConfig) } func (c *config) FrameworksBaseDirExists(ctx PathContext) bool { diff --git a/android/env.go b/android/env.go index 46bd3d6c5..d9f2db2f3 100644 --- a/android/env.go +++ b/android/env.go @@ -52,17 +52,6 @@ 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{} } @@ -77,12 +66,7 @@ func (c *envSingleton) GenerateBuildActions(ctx SingletonContext) { return } - data, err := env.EnvFileContents(envDeps) - if err != nil { - ctx.Errorf(err.Error()) - } - - err = WriteFileToOutputDir(envFile, data, 0666) + err := env.WriteEnvFile(envFile.String(), envDeps) if err != nil { ctx.Errorf(err.Error()) } diff --git a/android/makevars.go b/android/makevars.go index aba4ccec3..38a028caf 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -23,6 +23,7 @@ import ( "strings" "github.com/google/blueprint" + "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" ) @@ -40,6 +41,7 @@ type MakeVarsContext interface { Config() Config DeviceConfig() DeviceConfig AddNinjaFileDeps(deps ...string) + Fs() pathtools.FileSystem ModuleName(module blueprint.Module) string ModuleDir(module blueprint.Module) string @@ -149,8 +151,7 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { return } - outFile := absolutePath(PathForOutput(ctx, - "make_vars"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String()) + outFile := PathForOutput(ctx, "make_vars"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String() if ctx.Failed() { return @@ -174,15 +175,15 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { outBytes := s.writeVars(vars) - if _, err := os.Stat(absolutePath(outFile)); err == nil { - if data, err := ioutil.ReadFile(absolutePath(outFile)); err == nil { + if _, err := os.Stat(outFile); err == nil { + if data, err := ioutil.ReadFile(outFile); err == nil { if bytes.Equal(data, outBytes) { return } } } - if err := ioutil.WriteFile(absolutePath(outFile), outBytes, 0666); err != nil { + if err := ioutil.WriteFile(outFile, outBytes, 0666); err != nil { ctx.Errorf(err.Error()) } } diff --git a/android/module.go b/android/module.go index 67d1f129e..c99800727 100644 --- a/android/module.go +++ b/android/module.go @@ -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,8 +91,7 @@ type EarlyModuleContext interface { Glob(globPattern string, excludes []string) Paths GlobFiles(globPattern string, excludes []string) Paths - IsSymlink(path Path) bool - Readlink(path Path) string + Fs() pathtools.FileSystem } // BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns @@ -1173,22 +1172,6 @@ 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 diff --git a/android/package_ctx.go b/android/package_ctx.go index a22891081..d3527fa20 100644 --- a/android/package_ctx.go +++ b/android/package_ctx.go @@ -19,6 +19,7 @@ import ( "strings" "github.com/google/blueprint" + "github.com/google/blueprint/pathtools" ) // PackageContext is a wrapper for blueprint.PackageContext that adds @@ -59,6 +60,10 @@ func (e *configErrorWrapper) AddNinjaFileDeps(deps ...string) { e.pctx.AddNinjaFileDeps(deps...) } +func (e *configErrorWrapper) Fs() pathtools.FileSystem { + return nil +} + type PackageVarContext interface { PathContext errorfContext diff --git a/android/paths.go b/android/paths.go index 02f56d095..a03fe17e5 100644 --- a/android/paths.go +++ b/android/paths.go @@ -16,8 +16,6 @@ package android import ( "fmt" - "io/ioutil" - "os" "path/filepath" "reflect" "sort" @@ -27,11 +25,10 @@ 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) } @@ -393,7 +390,7 @@ func expandOneSrcPath(ctx ModuleContext, s string, expandedExcludes []string) (P return PathsWithModuleSrcSubDir(ctx, paths, ""), nil } else { p := pathForModuleSrc(ctx, s) - if exists, _, err := ctx.Config().fs.Exists(p.String()); err != nil { + if exists, _, err := ctx.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) @@ -723,7 +720,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 = ctx.Config().fs.Glob(path.String(), nil, pathtools.FollowSymlinks) + files, deps, err = pathtools.Glob(path.String(), nil, pathtools.FollowSymlinks) ctx.AddNinjaFileDeps(deps...) } @@ -755,7 +752,7 @@ func PathForSource(ctx PathContext, pathComponents ...string) SourcePath { if !exists { modCtx.AddMissingDependencies([]string{path.String()}) } - } else if exists, _, err := ctx.Config().fs.Exists(path.String()); err != nil { + } else if exists, _, err := ctx.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) @@ -1359,6 +1356,7 @@ 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) {} @@ -1404,16 +1402,3 @@ 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) -} diff --git a/android/paths_test.go b/android/paths_test.go index 46e3e1fa6..ec5e59820 100644 --- a/android/paths_test.go +++ b/android/paths_test.go @@ -21,6 +21,7 @@ import ( "strings" "testing" + "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" ) @@ -206,6 +207,10 @@ type moduleInstallPathContextImpl struct { inRoot bool } +func (moduleInstallPathContextImpl) Fs() pathtools.FileSystem { + return pathtools.MockFs(nil) +} + func (m moduleInstallPathContextImpl) Config() Config { return m.baseModuleContext.config } diff --git a/android/register.go b/android/register.go index b48d3d1bc..b5defecad 100644 --- a/android/register.go +++ b/android/register.go @@ -84,9 +84,7 @@ type Context struct { } func NewContext() *Context { - ctx := &Context{blueprint.NewContext()} - ctx.SetSrcDir(absSrcDir) - return ctx + return &Context{blueprint.NewContext()} } func (ctx *Context) Register() { diff --git a/android/sandbox.go b/android/sandbox.go deleted file mode 100644 index ed022fb87..000000000 --- a/android/sandbox.go +++ /dev/null @@ -1,47 +0,0 @@ -// 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 -} diff --git a/android/singleton.go b/android/singleton.go index 91268ad1c..5519ca019 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -16,6 +16,7 @@ package android import ( "github.com/google/blueprint" + "github.com/google/blueprint/pathtools" ) // SingletonContext @@ -73,6 +74,8 @@ 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 { diff --git a/androidmk/Android.bp b/androidmk/Android.bp index 70fc1f75c..41100738c 100644 --- a/androidmk/Android.bp +++ b/androidmk/Android.bp @@ -41,6 +41,7 @@ bootstrap_go_package { "androidmk-parser", "blueprint-parser", "bpfix-lib", + "soong-android", ], } diff --git a/androidmk/androidmk/android.go b/androidmk/androidmk/android.go index 88609849d..0082d8b0b 100644 --- a/androidmk/androidmk/android.go +++ b/androidmk/androidmk/android.go @@ -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,13 +350,7 @@ func splitAndAssign(ctx variableAssignmentContext, splitFunc listSplitFunc, name return err } - var classifications []string - for classification := range namesByClassification { - classifications = append(classifications, classification) - } - sort.Strings(classifications) - - for _, nameClassification := range classifications { + for _, nameClassification := range android.SortedStringKeys(namesByClassification) { name := namesByClassification[nameClassification] if component, ok := lists[nameClassification]; ok && !emptyList(component) { err = setVariable(ctx.file, ctx.append, ctx.prefix, name, component, true) diff --git a/cc/cmakelists.go b/cc/cmakelists.go index f7d9081db..97d21f444 100644 --- a/cc/cmakelists.go +++ b/cc/cmakelists.go @@ -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(android.AbsSrcDirForExistingUseCases(), cLionAggregateProjectsDirectory) + dir := filepath.Join(getAndroidSrcRootDirectory(ctx), 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", android.AbsSrcDirForExistingUseCases())) + f.WriteString(fmt.Sprintf("set(ANDROID_ROOT %s)\n\n", getAndroidSrcRootDirectory(ctx))) 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(android.AbsSrcDirForExistingUseCases(), + return filepath.Join(getAndroidSrcRootDirectory(ctx), cLionOutputProjectsDirectory, path.Dir(ctx.BlueprintFile(module)), module.ModuleBase.Name()+"-"+ @@ -473,3 +473,8 @@ 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 +} diff --git a/cc/compdb.go b/cc/compdb.go index ea124438e..dff14dbeb 100644 --- a/cc/compdb.go +++ b/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(filepath.Join(android.AbsSrcDirForExistingUseCases(), dir.String()), 0777) + os.MkdirAll(dir.String(), 0777) compDBFile := dir.Join(ctx, compdbFilename) - f, err := os.Create(filepath.Join(android.AbsSrcDirForExistingUseCases(), compDBFile.String())) + f, err := os.Create(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) - if finalLinkDir := ctx.Config().Getenv(envVariableCompdbLink); finalLinkDir != "" { - finalLinkPath := filepath.Join(finalLinkDir, compdbFilename) + finalLinkPath := filepath.Join(ctx.Config().Getenv(envVariableCompdbLink), compdbFilename) + if finalLinkPath != "" { 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,17 +174,18 @@ func generateCompdbProject(compiledModule CompiledInterface, ctx android.Singlet return } - pathToCC, err := ctx.Eval(pctx, "${config.ClangBin}") + rootDir := getCompdbAndroidSrcRootDirectory(ctx) + pathToCC, err := ctx.Eval(pctx, rootDir+"/${config.ClangBin}/") ccPath := "/bin/false" cxxPath := "/bin/false" if err == nil { - ccPath = filepath.Join(pathToCC, "clang") - cxxPath = filepath.Join(pathToCC, "clang++") + ccPath = pathToCC + "clang" + cxxPath = pathToCC + "clang++" } for _, src := range srcs { if _, ok := builds[src.String()]; !ok { builds[src.String()] = compDbEntry{ - Directory: android.AbsSrcDirForExistingUseCases(), + Directory: rootDir, Arguments: getArguments(src, ctx, ccModule, ccPath, cxxPath), File: src.String(), } @@ -199,3 +200,8 @@ 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 +} diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go index 5744bb285..b8423be1f 100644 --- a/cc/ndk_headers.go +++ b/cc/ndk_headers.go @@ -16,6 +16,7 @@ package cc import ( "fmt" + "os" "path/filepath" "strings" @@ -254,8 +255,16 @@ 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 { - if ctx.IsSymlink(path) { - dest := ctx.Readlink(path) + 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) + } // Additional .. to account for the symlink itself. depsGlob[i] = android.PathForSource( ctx, filepath.Clean(filepath.Join(path.String(), "..", dest))) diff --git a/dexpreopt/config.go b/dexpreopt/config.go index 2a929c536..0c79ccc73 100644 --- a/dexpreopt/config.go +++ b/dexpreopt/config.go @@ -16,6 +16,7 @@ package dexpreopt import ( "encoding/json" + "io/ioutil" "strings" "android/soong/android" @@ -184,7 +185,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, data []byte, soongConfig GlobalSoongConfig) (GlobalConfig, error) { +func LoadGlobalConfig(ctx android.PathContext, path string, soongConfig GlobalSoongConfig) (GlobalConfig, []byte, error) { type GlobalJSONConfig struct { GlobalConfig @@ -195,9 +196,9 @@ func LoadGlobalConfig(ctx android.PathContext, data []byte, soongConfig GlobalSo } config := GlobalJSONConfig{} - err := json.Unmarshal(data, &config) + data, err := loadConfig(ctx, path, &config) if err != nil { - return config.GlobalConfig, err + return config.GlobalConfig, nil, err } // Construct paths that require a PathContext. @@ -208,13 +209,13 @@ func LoadGlobalConfig(ctx android.PathContext, data []byte, soongConfig GlobalSo // either CreateGlobalSoongConfig or LoadGlobalSoongConfig). config.GlobalConfig.SoongConfig = soongConfig - return config.GlobalConfig, nil + return config.GlobalConfig, data, 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, data []byte) (ModuleConfig, error) { +func LoadModuleConfig(ctx android.PathContext, path string) (ModuleConfig, error) { type ModuleJSONConfig struct { ModuleConfig @@ -232,7 +233,7 @@ func LoadModuleConfig(ctx android.PathContext, data []byte) (ModuleConfig, error config := ModuleJSONConfig{} - err := json.Unmarshal(data, &config) + _, err := loadConfig(ctx, path, &config) if err != nil { return config.ModuleConfig, err } @@ -288,10 +289,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, data []byte) (GlobalSoongConfig, error) { +func LoadGlobalSoongConfig(ctx android.PathContext, path string) (GlobalSoongConfig, error) { var jc globalJsonSoongConfig - err := json.Unmarshal(data, &jc) + _, err := loadConfig(ctx, path, &jc) if err != nil { return GlobalSoongConfig{}, err } @@ -351,6 +352,26 @@ 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, diff --git a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go index e2818bb61..d2faa00de 100644 --- a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go +++ b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go @@ -18,7 +18,6 @@ import ( "bytes" "flag" "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -42,6 +41,7 @@ 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,39 +76,21 @@ func main() { usage("--module configuration file is required") } - ctx := &pathContext{android.NullConfig(*outDir)} + ctx := &pathContext{android.TestConfig(*outDir, nil, "", nil)} - 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) + globalSoongConfig, err := dexpreopt.LoadGlobalSoongConfig(ctx, *globalSoongConfigPath) if err != nil { fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalSoongConfigPath, err) os.Exit(2) } - globalConfigData, err := ioutil.ReadFile(*globalConfigPath) + globalConfig, _, err := dexpreopt.LoadGlobalConfig(ctx, *globalConfigPath, globalSoongConfig) if err != nil { - fmt.Fprintf(os.Stderr, "error reading global config %q: %s\n", *globalConfigPath, err) + fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalConfigPath, err) os.Exit(2) } - 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) + moduleConfig, err := dexpreopt.LoadModuleConfig(ctx, *moduleConfigPath) if err != nil { fmt.Fprintf(os.Stderr, "error loading module config %q: %s\n", *moduleConfigPath, err) os.Exit(2) diff --git a/env/env.go b/env/env.go index a98e1f6a8..bf58a9914 100644 --- a/env/env.go +++ b/env/env.go @@ -27,7 +27,7 @@ import ( type envFileEntry struct{ Key, Value string } type envFileData []envFileEntry -func EnvFileContents(envDeps map[string]string) ([]byte, error) { +func WriteEnvFile(filename string, envDeps map[string]string) error { contents := make(envFileData, 0, len(envDeps)) for key, value := range envDeps { contents = append(contents, envFileEntry{key, value}) @@ -37,12 +37,17 @@ func EnvFileContents(envDeps map[string]string) ([]byte, error) { data, err := json.MarshalIndent(contents, "", " ") if err != nil { - return nil, err + return err } data = append(data, '\n') - return data, nil + err = ioutil.WriteFile(filename, data, 0664) + if err != nil { + return err + } + + return nil } func StaleEnvFile(filename string) (bool, error) { diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go index a0fcba755..8749a7d57 100644 --- a/java/dexpreopt_config.go +++ b/java/dexpreopt_config.go @@ -36,11 +36,10 @@ type globalConfigAndRaw struct { func dexpreoptGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw { return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} { - if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil { - panic(err) - } else if data != nil { + if f := ctx.Config().DexpreoptGlobalConfig(); f != "" { soongConfig := dexpreopt.CreateGlobalSoongConfig(ctx) - globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, data, soongConfig) + ctx.AddNinjaFileDeps(f) + globalConfig, data, err := dexpreopt.LoadGlobalConfig(ctx, f, soongConfig) if err != nil { panic(err) } diff --git a/java/jdeps.go b/java/jdeps.go index 49e3de3cc..fccc40fa8 100644 --- a/java/jdeps.go +++ b/java/jdeps.go @@ -17,6 +17,7 @@ package java import ( "encoding/json" "fmt" + "os" "android/soong/android" ) @@ -91,21 +92,23 @@ func (j *jdepsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonCont moduleInfos[name] = dpInfo }) - jfpath := android.PathForOutput(ctx, jdepsJsonFileName) + jfpath := android.PathForOutput(ctx, jdepsJsonFileName).String() err := createJsonFile(moduleInfos, jfpath) if err != nil { ctx.Errorf(err.Error()) } } -func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath android.WritablePath) 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() buf, err := json.MarshalIndent(moduleInfos, "", "\t") if err != nil { - 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) + return fmt.Errorf("Write file failed: %s, relative: %v", jdepsJsonFileName, err) } + fmt.Fprintf(file, string(buf)) return nil } diff --git a/ui/build/soong.go b/ui/build/soong.go index afbc0734b..338841702 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -119,7 +119,6 @@ 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() }