Merge changes Iae2bda98,I68e64888,I75af16e7
* changes:
Remove gcc-specific optimizations
Move some flags to affect all devices
Move -fvisibility-inlines-hidden to global device cppflags
diff --git a/android/paths.go b/android/paths.go
index d6a1c66..4adaa2d 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -18,6 +18,7 @@
"fmt"
"path/filepath"
"reflect"
+ "sort"
"strings"
"github.com/google/blueprint"
@@ -380,6 +381,38 @@
return ret
}
+// DirectorySortedPaths is a slice of paths that are sorted such that all files in a directory
+// (including subdirectories) are in a contiguous subslice of the list, and can be found in
+// O(log(N)) time using a binary search on the directory prefix.
+type DirectorySortedPaths Paths
+
+func PathsToDirectorySortedPaths(paths Paths) DirectorySortedPaths {
+ ret := append(DirectorySortedPaths(nil), paths...)
+ sort.Slice(ret, func(i, j int) bool {
+ return ret[i].String() < ret[j].String()
+ })
+ return ret
+}
+
+// PathsInDirectory returns a subslice of the DirectorySortedPaths as a Paths that contains all entries
+// that are in the specified directory and its subdirectories.
+func (p DirectorySortedPaths) PathsInDirectory(dir string) Paths {
+ prefix := filepath.Clean(dir) + "/"
+ start := sort.Search(len(p), func(i int) bool {
+ return prefix < p[i].String()
+ })
+
+ ret := p[start:]
+
+ end := sort.Search(len(ret), func(i int) bool {
+ return !strings.HasPrefix(ret[i].String(), prefix)
+ })
+
+ ret = ret[:end]
+
+ return Paths(ret)
+}
+
// WritablePaths is a slice of WritablePaths, used for multiple outputs.
type WritablePaths []WritablePath
diff --git a/android/paths_test.go b/android/paths_test.go
index 248f4d4..82ae4dc 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -340,3 +340,75 @@
})
}
}
+
+func TestDirectorySortedPaths(t *testing.T) {
+ makePaths := func() Paths {
+ return Paths{
+ PathForTesting("a.txt"),
+ PathForTesting("a/txt"),
+ PathForTesting("a/b/c"),
+ PathForTesting("a/b/d"),
+ PathForTesting("b"),
+ PathForTesting("b/b.txt"),
+ PathForTesting("a/a.txt"),
+ }
+ }
+
+ expected := []string{
+ "a.txt",
+ "a/a.txt",
+ "a/b/c",
+ "a/b/d",
+ "a/txt",
+ "b",
+ "b/b.txt",
+ }
+
+ paths := makePaths()
+ reversePaths := make(Paths, len(paths))
+ for i, v := range paths {
+ reversePaths[len(paths)-i-1] = v
+ }
+
+ sortedPaths := PathsToDirectorySortedPaths(paths)
+ reverseSortedPaths := PathsToDirectorySortedPaths(reversePaths)
+
+ if !reflect.DeepEqual(Paths(sortedPaths).Strings(), expected) {
+ t.Fatalf("sorted paths:\n %#v\n != \n %#v", paths.Strings(), expected)
+ }
+
+ if !reflect.DeepEqual(Paths(reverseSortedPaths).Strings(), expected) {
+ t.Fatalf("sorted reversed paths:\n %#v\n !=\n %#v", reversePaths.Strings(), expected)
+ }
+
+ expectedA := []string{
+ "a/a.txt",
+ "a/b/c",
+ "a/b/d",
+ "a/txt",
+ }
+
+ inA := sortedPaths.PathsInDirectory("a")
+ if !reflect.DeepEqual(inA.Strings(), expectedA) {
+ t.Errorf("FilesInDirectory(a):\n %#v\n != \n %#v", inA.Strings(), expectedA)
+ }
+
+ expectedA_B := []string{
+ "a/b/c",
+ "a/b/d",
+ }
+
+ inA_B := sortedPaths.PathsInDirectory("a/b")
+ if !reflect.DeepEqual(inA_B.Strings(), expectedA_B) {
+ t.Errorf("FilesInDirectory(a/b):\n %#v\n != \n %#v", inA_B.Strings(), expectedA_B)
+ }
+
+ expectedB := []string{
+ "b/b.txt",
+ }
+
+ inB := sortedPaths.PathsInDirectory("b")
+ if !reflect.DeepEqual(inB.Strings(), expectedB) {
+ t.Errorf("FilesInDirectory(b):\n %#v\n != \n %#v", inA.Strings(), expectedA)
+ }
+}
diff --git a/android/variable.go b/android/variable.go
index d89c146..4272817 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -205,26 +205,29 @@
func (v *productVariables) SetDefaultConfig() {
*v = productVariables{
- Platform_sdk_version: intPtr(24),
+ Platform_sdk_version: intPtr(26),
+ Platform_version_active_codenames: []string{"P"},
+ Platform_version_future_codenames: []string{"P"},
+
HostArch: stringPtr("x86_64"),
HostSecondaryArch: stringPtr("x86"),
- DeviceName: stringPtr("flounder"),
+ DeviceName: stringPtr("generic_arm64"),
DeviceArch: stringPtr("arm64"),
DeviceArchVariant: stringPtr("armv8-a"),
- DeviceCpuVariant: stringPtr("denver64"),
+ DeviceCpuVariant: stringPtr("generic"),
DeviceAbi: &[]string{"arm64-v8a"},
DeviceUsesClang: boolPtr(true),
DeviceSecondaryArch: stringPtr("arm"),
- DeviceSecondaryArchVariant: stringPtr("armv7-a-neon"),
- DeviceSecondaryCpuVariant: stringPtr("denver"),
- DeviceSecondaryAbi: &[]string{"armeabi-v7a"},
+ DeviceSecondaryArchVariant: stringPtr("armv8-a"),
+ DeviceSecondaryCpuVariant: stringPtr("generic"),
+ DeviceSecondaryAbi: &[]string{"armeabi-v7a", "armeabi"},
AAPTConfig: &[]string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
AAPTPreferredConfig: stringPtr("xhdpi"),
AAPTCharacteristics: stringPtr("nosdcard"),
AAPTPrebuiltDPI: &[]string{"xhdpi", "xxhdpi"},
- Malloc_not_svelte: boolPtr(false),
+ Malloc_not_svelte: boolPtr(true),
Safestack: boolPtr(false),
}
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 40373cc..154b3f4 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -151,7 +151,7 @@
return stub.libraryDecorator.link(ctx, flags, deps, objs)
}
-func newLLndkStubLibrary() *Module {
+func NewLLndkStubLibrary() *Module {
module, library := NewLibrary(android.DeviceSupported)
library.BuildOnlyShared()
module.stl = nil
@@ -175,7 +175,7 @@
}
func llndkLibraryFactory() android.Module {
- module := newLLndkStubLibrary()
+ module := NewLLndkStubLibrary()
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
return module
}
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 2ca7ebf..0619b5c 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -114,11 +114,7 @@
} else if os.Args[1] == "--dumpvars-mode" {
dumpVars(buildCtx, config, os.Args[2:])
} else {
- toBuild := build.BuildAll
- if config.Checkbuild() {
- toBuild |= build.RunBuildTests
- }
- build.Build(buildCtx, config, toBuild)
+ build.Build(buildCtx, config, build.BuildAll)
}
}
diff --git a/ui/build/Android.bp b/ui/build/Android.bp
index 5809894..d1b4943 100644
--- a/ui/build/Android.bp
+++ b/ui/build/Android.bp
@@ -36,7 +36,6 @@
"proc_sync.go",
"signal.go",
"soong.go",
- "test_build.go",
"util.go",
],
testSrcs: [
diff --git a/ui/build/build.go b/ui/build/build.go
index 78eb6a3..0df22b3 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -68,7 +68,6 @@
BuildSoong = 1 << iota
BuildKati = 1 << iota
BuildNinja = 1 << iota
- RunBuildTests = 1 << iota
BuildAll = BuildProductConfig | BuildSoong | BuildKati | BuildNinja
)
@@ -173,18 +172,14 @@
}
}
- // Write combined ninja file
- createCombinedBuildNinjaFile(ctx, config)
-
- if what&RunBuildTests != 0 {
- testForDanglingRules(ctx, config)
- }
-
if what&BuildNinja != 0 {
if !config.SkipMake() {
installCleanIfNecessary(ctx, config)
}
+ // Write combined ninja file
+ createCombinedBuildNinjaFile(ctx, config)
+
// Run ninja
runNinja(ctx, config)
}
diff --git a/ui/build/config.go b/ui/build/config.go
index 99ae2da..940bb2f 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -34,12 +34,11 @@
environ *Environment
// From the arguments
- parallel int
- keepGoing int
- verbose bool
- checkbuild bool
- dist bool
- skipMake bool
+ parallel int
+ keepGoing int
+ verbose bool
+ dist bool
+ skipMake bool
// From the product config
katiArgs []string
@@ -207,8 +206,6 @@
} else {
if arg == "dist" {
c.dist = true
- } else if arg == "checkbuild" {
- c.checkbuild = true
}
c.arguments = append(c.arguments, arg)
}
@@ -316,12 +313,6 @@
panic("SetKatiSuffix has not been called")
}
-// Checkbuild returns true if "checkbuild" was one of the build goals, which means that the
-// user is interested in additional checks at the expense of build time.
-func (c *configImpl) Checkbuild() bool {
- return c.checkbuild
-}
-
func (c *configImpl) Dist() bool {
return c.dist
}
diff --git a/ui/build/test_build.go b/ui/build/test_build.go
deleted file mode 100644
index d5e244c..0000000
--- a/ui/build/test_build.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2017 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 build
-
-import (
- "bufio"
- "path/filepath"
- "strings"
-)
-
-// Checks for files in the out directory that have a rule that depends on them but no rule to
-// create them. This catches a common set of build failures where a rule to generate a file is
-// deleted (either by deleting a module in an Android.mk file, or by modifying the build system
-// incorrectly). These failures are often not caught by a local incremental build because the
-// previously built files are still present in the output directory.
-func testForDanglingRules(ctx Context, config Config) {
- ctx.BeginTrace("test for dangling rules")
- defer ctx.EndTrace()
-
- // Get a list of leaf nodes in the dependency graph from ninja
- executable := config.PrebuiltBuildTool("ninja")
-
- args := []string{}
- args = append(args, config.NinjaArgs()...)
- args = append(args, "-f", config.CombinedNinjaFile())
- args = append(args, "-t", "targets", "rule")
-
- cmd := Command(ctx, config, "ninja", executable, args...)
- stdout, err := cmd.StdoutPipe()
- if err != nil {
- ctx.Fatal(err)
- }
-
- cmd.StartOrFatal()
-
- outDir := config.OutDir()
- bootstrapDir := filepath.Join(outDir, "soong", ".bootstrap")
- miniBootstrapDir := filepath.Join(outDir, "soong", ".minibootstrap")
-
- var danglingRules []string
-
- scanner := bufio.NewScanner(stdout)
- for scanner.Scan() {
- line := scanner.Text()
- if !strings.HasPrefix(line, outDir) {
- // Leaf node is not in the out directory.
- continue
- }
- if strings.HasPrefix(line, bootstrapDir) || strings.HasPrefix(line, miniBootstrapDir) {
- // Leaf node is in one of Soong's bootstrap directories, which do not have
- // full build rules in the primary build.ninja file.
- continue
- }
- danglingRules = append(danglingRules, line)
- }
-
- cmd.WaitOrFatal()
-
- if len(danglingRules) > 0 {
- ctx.Println("Dependencies in out found with no rule to create them:")
- for _, dep := range danglingRules {
- ctx.Println(dep)
- }
- ctx.Fatal("")
- }
-}
diff --git a/zip/Android.bp b/zip/Android.bp
index d708089..3bb4f25 100644
--- a/zip/Android.bp
+++ b/zip/Android.bp
@@ -19,6 +19,7 @@
pkgPath: "android/soong/zip",
deps: [
"android-archive-zip",
+ "blueprint-pathtools",
"soong-jar",
],
srcs: [
diff --git a/zip/cmd/main.go b/zip/cmd/main.go
index 348728c..c0418f7 100644
--- a/zip/cmd/main.go
+++ b/zip/cmd/main.go
@@ -120,14 +120,15 @@
}
var (
- out = flag.String("o", "", "file to write zip file to")
- manifest = flag.String("m", "", "input jar manifest file name")
- directories = flag.Bool("d", false, "include directories in zip")
- rootPrefix = flag.String("P", "", "path prefix within the zip at which to place files")
- relativeRoot = flag.String("C", "", "path to use as relative root of files in following -f, -l, or -D arguments")
- parallelJobs = flag.Int("j", runtime.NumCPU(), "number of parallel threads to use")
- compLevel = flag.Int("L", 5, "deflate compression level (0-9)")
- emulateJar = flag.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'")
+ out = flag.String("o", "", "file to write zip file to")
+ manifest = flag.String("m", "", "input jar manifest file name")
+ directories = flag.Bool("d", false, "include directories in zip")
+ rootPrefix = flag.String("P", "", "path prefix within the zip at which to place files")
+ relativeRoot = flag.String("C", "", "path to use as relative root of files in following -f, -l, or -D arguments")
+ parallelJobs = flag.Int("j", runtime.NumCPU(), "number of parallel threads to use")
+ compLevel = flag.Int("L", 5, "deflate compression level (0-9)")
+ emulateJar = flag.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'")
+ writeIfChanged = flag.Bool("write_if_changed", false, "only update resultant .zip if it has changed")
fArgs zip.FileArgs
nonDeflatedFiles = make(uniqueSet)
@@ -163,6 +164,7 @@
ManifestSourcePath: *manifest,
NumParallelJobs: *parallelJobs,
NonDeflatedFiles: nonDeflatedFiles,
+ WriteIfChanged: *writeIfChanged,
})
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
diff --git a/zip/zip.go b/zip/zip.go
index 95520fe..c878a0c 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -32,6 +32,8 @@
"sync"
"time"
+ "github.com/google/blueprint/pathtools"
+
"android/soong/jar"
"android/soong/third_party/zip"
)
@@ -127,6 +129,7 @@
ManifestSourcePath string
NumParallelJobs int
NonDeflatedFiles map[string]bool
+ WriteIfChanged bool
}
func Run(args ZipArgs) (err error) {
@@ -186,8 +189,38 @@
}
}
- return w.write(args.OutputFilePath, pathMappings, args.ManifestSourcePath, args.EmulateJar, args.NumParallelJobs)
+ buf := &bytes.Buffer{}
+ var out io.Writer = buf
+ if !args.WriteIfChanged {
+ f, err := os.Create(args.OutputFilePath)
+ if err != nil {
+ return err
+ }
+
+ defer f.Close()
+ defer func() {
+ if err != nil {
+ os.Remove(args.OutputFilePath)
+ }
+ }()
+
+ out = f
+ }
+
+ err = w.write(out, pathMappings, args.ManifestSourcePath, args.EmulateJar, args.NumParallelJobs)
+ if err != nil {
+ return err
+ }
+
+ if args.WriteIfChanged {
+ err := pathtools.WriteFileIfChanged(args.OutputFilePath, buf.Bytes(), 0666)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
}
func fillPathPairs(prefix, rel, src string, pathMappings *[]pathMapping, nonDeflatedFiles map[string]bool) error {
@@ -226,19 +259,7 @@
io.Seeker
}
-func (z *ZipWriter) write(out string, pathMappings []pathMapping, manifest string, emulateJar bool, parallelJobs int) error {
- f, err := os.Create(out)
- if err != nil {
- return err
- }
-
- defer f.Close()
- defer func() {
- if err != nil {
- os.Remove(out)
- }
- }()
-
+func (z *ZipWriter) write(f io.Writer, pathMappings []pathMapping, manifest string, emulateJar bool, parallelJobs int) error {
z.errors = make(chan error)
defer close(z.errors)
@@ -324,6 +345,7 @@
case op := <-writeOpChan:
currentWriteOpChan = nil
+ var err error
if op.fh.Method == zip.Deflate {
currentWriter, err = zipw.CreateCompressedHeader(op.fh)
} else {
@@ -356,21 +378,21 @@
currentReader = futureReader
case reader := <-currentReader:
- _, err = io.Copy(currentWriter, reader)
+ _, err := io.Copy(currentWriter, reader)
if err != nil {
return err
}
currentReader = nil
- case err = <-z.errors:
+ case err := <-z.errors:
return err
}
}
// One last chance to catch an error
select {
- case err = <-z.errors:
+ case err := <-z.errors:
return err
default:
zipw.Close()