Merge "multiproduct_kati: better directory names."
diff --git a/Android.bp b/Android.bp
index e394892..c87903f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -47,6 +47,7 @@
],
srcs: [
"android/androidmk.go",
+ "android/api_levels.go",
"android/arch.go",
"android/config.go",
"android/defaults.go",
diff --git a/android/androidmk.go b/android/androidmk.go
index d55cdca..f606522 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -175,19 +175,21 @@
if data.Custom != nil {
prefix := ""
- switch amod.Os().Class {
- case Host:
- prefix = "HOST_"
- case HostCross:
- prefix = "HOST_CROSS_"
- case Device:
- prefix = "TARGET_"
+ if amod.ArchSpecific() {
+ switch amod.Os().Class {
+ case Host:
+ prefix = "HOST_"
+ case HostCross:
+ prefix = "HOST_CROSS_"
+ case Device:
+ prefix = "TARGET_"
- }
+ }
- config := ctx.Config().(Config)
- if amod.Arch().ArchType != config.Targets[amod.Os().Class][0].Arch.ArchType {
- prefix = "2ND_" + prefix
+ config := ctx.Config().(Config)
+ if amod.Arch().ArchType != config.Targets[amod.Os().Class][0].Arch.ArchType {
+ prefix = "2ND_" + prefix
+ }
}
return data.Custom(w, name, prefix, filepath.Dir(ctx.BlueprintFile(mod)))
diff --git a/android/api_levels.go b/android/api_levels.go
new file mode 100644
index 0000000..c77ced1
--- /dev/null
+++ b/android/api_levels.go
@@ -0,0 +1,63 @@
+// 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 android
+
+import (
+ "encoding/json"
+
+ "github.com/google/blueprint"
+)
+
+func init() {
+ RegisterSingletonType("api_levels", ApiLevelsSingleton)
+}
+
+func ApiLevelsSingleton() blueprint.Singleton {
+ return &apiLevelsSingleton{}
+}
+
+type apiLevelsSingleton struct{}
+
+func createApiLevelsJson(ctx blueprint.SingletonContext, file string,
+ apiLevelsMap map[string]int) {
+
+ jsonStr, err := json.Marshal(apiLevelsMap)
+ if err != nil {
+ ctx.Errorf(err.Error())
+ }
+
+ ctx.Build(pctx, blueprint.BuildParams{
+ Rule: WriteFile,
+ Outputs: []string{file},
+ Args: map[string]string{
+ "content": string(jsonStr[:]),
+ },
+ })
+}
+
+func GetApiLevelsJson(ctx PathContext) Path {
+ return PathForOutput(ctx, "api_levels.json")
+}
+
+func (a *apiLevelsSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
+ baseApiLevel := 9000
+ apiLevelsMap := map[string]int{}
+ for i, codename := range ctx.Config().(Config).PlatformVersionAllCodenames() {
+ apiLevelsMap[codename] = baseApiLevel + i
+ }
+
+ apiLevelsJson := GetApiLevelsJson(ctx)
+ createApiLevelsJson(ctx, apiLevelsJson.String(), apiLevelsMap)
+}
diff --git a/android/config.go b/android/config.go
index 2361920..3c25485 100644
--- a/android/config.go
+++ b/android/config.go
@@ -353,6 +353,10 @@
return strconv.Itoa(c.PlatformSdkVersionInt())
}
+func (c *config) PlatformVersionAllCodenames() []string {
+ return c.ProductVariables.Platform_version_all_codenames
+}
+
func (c *config) BuildNumber() string {
return "000000"
}
@@ -462,11 +466,11 @@
return "vendor"
}
-func (c *deviceConfig) VndkVersion() string {
+func (c *deviceConfig) CompileVndk() bool {
if c.config.ProductVariables.DeviceVndkVersion == nil {
- return ""
+ return false
}
- return *c.config.ProductVariables.DeviceVndkVersion
+ return *c.config.ProductVariables.DeviceVndkVersion == "current"
}
func (c *deviceConfig) BtConfigIncludeDir() string {
diff --git a/android/defs.go b/android/defs.go
index d7e2a9f..6f46316 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -80,6 +80,13 @@
Description: "concatenate licenses $out",
})
+ WriteFile = pctx.AndroidStaticRule("WriteFile",
+ blueprint.RuleParams{
+ Command: "echo '$content' > $out",
+ Description: "writing file $out",
+ },
+ "content")
+
// Used only when USE_GOMA=true is set, to restrict non-goma jobs to the local parallelism value
localPool = blueprint.NewBuiltinPool("local_pool")
)
diff --git a/android/module.go b/android/module.go
index cc420fb..4fba1cf 100644
--- a/android/module.go
+++ b/android/module.go
@@ -59,6 +59,7 @@
Darwin() bool
Debug() bool
PrimaryArch() bool
+ Proprietary() bool
AConfig() Config
DeviceConfig() DeviceConfig
}
@@ -87,8 +88,8 @@
AddMissingDependencies(deps []string)
- Proprietary() bool
InstallInData() bool
+ InstallInSanitizerDir() bool
RequiredModuleNames() []string
}
@@ -103,6 +104,7 @@
Enabled() bool
Target() Target
InstallInData() bool
+ InstallInSanitizerDir() bool
SkipInstall()
}
@@ -399,6 +401,10 @@
return false
}
+func (p *ModuleBase) InstallInSanitizerDir() bool {
+ return false
+}
+
func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
allInstalledFiles := Paths{}
allCheckbuildFiles := Paths{}
@@ -455,6 +461,7 @@
return androidBaseContextImpl{
target: a.commonProperties.CompileTarget,
targetPrimary: a.commonProperties.CompilePrimary,
+ proprietary: a.commonProperties.Proprietary,
config: ctx.Config().(Config),
}
}
@@ -491,6 +498,7 @@
target Target
targetPrimary bool
debug bool
+ proprietary bool
config Config
}
@@ -619,14 +627,18 @@
return DeviceConfig{a.config.deviceConfig}
}
-func (a *androidModuleContext) Proprietary() bool {
- return a.module.base().commonProperties.Proprietary
+func (a *androidBaseContextImpl) Proprietary() bool {
+ return a.proprietary
}
func (a *androidModuleContext) InstallInData() bool {
return a.module.InstallInData()
}
+func (a *androidModuleContext) InstallInSanitizerDir() bool {
+ return a.module.InstallInSanitizerDir()
+}
+
func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
deps ...Path) OutputPath {
diff --git a/android/paths.go b/android/paths.go
index 037c98d..fe639e6 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -652,7 +652,10 @@
if ctx.Proprietary() {
partition = ctx.DeviceConfig().VendorPath()
}
- if ctx.InstallInData() {
+
+ if ctx.InstallInSanitizerDir() {
+ partition = "data/asan/" + partition
+ } else if ctx.InstallInData() {
partition = "data"
}
outPaths = []string{"target", "product", ctx.AConfig().DeviceName(), partition}
diff --git a/android/variable.go b/android/variable.go
index c5b957b..b0ab2d0 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -82,7 +82,8 @@
// Suffix to add to generated Makefiles
Make_suffix *string `json:",omitempty"`
- Platform_sdk_version *int `json:",omitempty"`
+ Platform_sdk_version *int `json:",omitempty"`
+ Platform_version_all_codenames []string `json:",omitempty"`
DeviceName *string `json:",omitempty"`
DeviceArch *string `json:",omitempty"`
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
index 75c3eec..33e7eb3 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/cmd/androidmk/android.go
@@ -29,6 +29,7 @@
"LOCAL_C_INCLUDES": localIncludeDirs,
"LOCAL_EXPORT_C_INCLUDE_DIRS": exportIncludeDirs,
"LOCAL_LDFLAGS": ldflags,
+ "LOCAL_MODULE_CLASS": prebuiltClass,
"LOCAL_MODULE_STEM": stem,
"LOCAL_MODULE_HOST_OS": hostOs,
"LOCAL_SRC_FILES": srcFiles,
@@ -40,7 +41,9 @@
// skip functions
"LOCAL_ADDITIONAL_DEPENDENCIES": skip, // TODO: check for only .mk files?
"LOCAL_CPP_EXTENSION": skip,
+ "LOCAL_MODULE_SUFFIX": skip, // TODO
"LOCAL_PATH": skip, // Nothing to do, except maybe avoid the "./" in paths?
+ "LOCAL_PRELINK_MODULE": skip, // Already phased out
}
// adds a group of properties all having the same type
@@ -54,7 +57,6 @@
addStandardProperties(bpparser.StringType,
map[string]string{
"LOCAL_MODULE": "name",
- "LOCAL_MODULE_CLASS": "class",
"LOCAL_CXX_STL": "stl",
"LOCAL_STRIP_MODULE": "strip",
"LOCAL_MULTILIB": "compile_multilib",
@@ -103,6 +105,7 @@
"LOCAL_AIDL_INCLUDES": "aidl_includes",
"LOCAL_AAPT_FLAGS": "aaptflags",
"LOCAL_PACKAGE_SPLITS": "package_splits",
+ "LOCAL_COMPATIBILITY_SUITE": "test_suites",
})
addStandardProperties(bpparser.BoolType,
map[string]string{
@@ -117,7 +120,6 @@
"LOCAL_NO_STANDARD_LIBRARIES": "no_standard_libraries",
"LOCAL_PACK_MODULE_RELOCATIONS": "pack_relocations",
"LOCAL_TIDY": "tidy",
- "LOCAL_USE_VNDK": "use_vndk",
"LOCAL_PROPRIETARY_MODULE": "proprietary",
"LOCAL_EXPORT_PACKAGE_RESOURCES": "export_package_resources",
@@ -462,6 +464,17 @@
return err
}
+func prebuiltClass(ctx variableAssignmentContext) error {
+ class := ctx.mkvalue.Value(nil)
+ if v, ok := prebuiltTypes[class]; ok {
+ ctx.file.scope.Set("BUILD_PREBUILT", v)
+ } else {
+ // reset to default
+ ctx.file.scope.Set("BUILD_PREBUILT", "prebuilt")
+ }
+ return nil
+}
+
func ldflags(ctx variableAssignmentContext) error {
val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.ListType)
if err != nil {
@@ -658,8 +671,13 @@
"BUILD_HOST_JAVA_LIBRARY": "java_library_host",
"BUILD_HOST_DALVIK_JAVA_LIBRARY": "java_library_host_dalvik",
"BUILD_PACKAGE": "android_app",
+}
- "BUILD_PREBUILT": "prebuilt",
+var prebuiltTypes = map[string]string{
+ "SHARED_LIBRARIES": "cc_prebuilt_library_shared",
+ "STATIC_LIBRARIES": "cc_prebuilt_library_static",
+ "EXECUTABLES": "cc_prebuilt_binary",
+ "JAVA_LIBRARIES": "prebuilt_java_library",
}
var soongModuleTypes = map[string]bool{}
@@ -675,6 +693,9 @@
globalScope.Set(k, v)
soongModuleTypes[v] = true
}
+ for _, v := range prebuiltTypes {
+ soongModuleTypes[v] = true
+ }
return globalScope
}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index f45fbbe..705ac90 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -59,9 +59,6 @@
if c.Target().Os == android.Android && c.Properties.Sdk_version != "" {
fmt.Fprintln(w, "LOCAL_SDK_VERSION := "+c.Properties.Sdk_version)
fmt.Fprintln(w, "LOCAL_NDK_STL_VARIANT := none")
- } else if c.Target().Os == android.Android && c.Properties.Use_vndk {
- fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
- fmt.Fprintln(w, "LOCAL_NDK_STL_VARIANT := none")
} else {
// These are already included in LOCAL_SHARED_LIBRARIES
fmt.Fprintln(w, "LOCAL_CXX_STL := none")
@@ -200,6 +197,14 @@
ret.SubName = "_" + test.binaryDecorator.Properties.Stem
}
+ ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+ if len(test.Properties.Test_suites) > 0 {
+ fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=",
+ strings.Join(test.Properties.Test_suites, " "))
+ }
+ return nil
+ })
+
var testFiles []string
for _, d := range test.data {
rel := d.Rel()
diff --git a/cc/builder.go b/cc/builder.go
index f3a4bcb..0694cb7 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -109,7 +109,7 @@
},
"objcopyCmd", "prefix")
- stripPath = pctx.SourcePathVariable("stripPath", "build/soong/scripts/strip.sh")
+ _ = pctx.SourcePathVariable("stripPath", "build/soong/scripts/strip.sh")
strip = pctx.AndroidStaticRule("strip",
blueprint.RuleParams{
@@ -127,7 +127,7 @@
Description: "empty file $out",
})
- copyGccLibPath = pctx.SourcePathVariable("copyGccLibPath", "build/soong/scripts/copygcclib.sh")
+ _ = pctx.SourcePathVariable("copyGccLibPath", "build/soong/scripts/copygcclib.sh")
copyGccLib = pctx.AndroidStaticRule("copyGccLib",
blueprint.RuleParams{
@@ -139,7 +139,7 @@
},
"ccCmd", "cFlags", "libName")
- tocPath = pctx.SourcePathVariable("tocPath", "build/soong/scripts/toc.sh")
+ _ = pctx.SourcePathVariable("tocPath", "build/soong/scripts/toc.sh")
toc = pctx.AndroidStaticRule("toc",
blueprint.RuleParams{
@@ -159,7 +159,7 @@
},
"cFlags", "tidyFlags")
- yasmCmd = pctx.SourcePathVariable("yasmCmd", "prebuilts/misc/${config.HostPrebuiltTag}/yasm/yasm")
+ _ = pctx.SourcePathVariable("yasmCmd", "prebuilts/misc/${config.HostPrebuiltTag}/yasm/yasm")
yasm = pctx.AndroidStaticRule("yasm",
blueprint.RuleParams{
@@ -201,6 +201,8 @@
tidy bool
coverage bool
+ systemIncludeFlags string
+
groupStaticLibs bool
stripKeepSymbols bool
@@ -244,9 +246,25 @@
coverageFiles = make(android.Paths, 0, len(srcFiles))
}
- cflags := flags.globalFlags + " " + flags.cFlags + " " + flags.conlyFlags
- cppflags := flags.globalFlags + " " + flags.cFlags + " " + flags.cppFlags
- asflags := flags.globalFlags + " " + flags.asFlags
+ cflags := strings.Join([]string{
+ flags.globalFlags,
+ flags.systemIncludeFlags,
+ flags.cFlags,
+ flags.conlyFlags,
+ }, " ")
+
+ cppflags := strings.Join([]string{
+ flags.globalFlags,
+ flags.systemIncludeFlags,
+ flags.cFlags,
+ flags.cppFlags,
+ }, " ")
+
+ asflags := strings.Join([]string{
+ flags.globalFlags,
+ flags.systemIncludeFlags,
+ flags.asFlags,
+ }, " ")
if flags.clang {
cflags += " ${config.NoOverrideClangGlobalCflags}"
diff --git a/cc/cc.go b/cc/cc.go
index 4c69723..6f5539f 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -109,6 +109,10 @@
TidyFlags []string // Flags that apply to clang-tidy
YasmFlags []string // Flags that apply to yasm assembly source files
+ // Global include flags that apply to C, C++, and assembly source files
+ // These must be after any module include flags, which will be in GlobalFlags.
+ SystemIncludeFlags []string
+
Toolchain config.Toolchain
Clang bool
Tidy bool
@@ -135,9 +139,6 @@
// Minimum sdk version supported when compiling against the ndk
Sdk_version string
- // Whether to compile against the VNDK
- Use_vndk bool
-
// don't insert default compiler flags into asflags, cflags,
// cppflags, conlyflags, ldflags, or include_dirs
No_default_compiler_flags *bool
@@ -145,7 +146,6 @@
AndroidMkSharedLibs []string `blueprint:"mutated"`
HideFromMake bool `blueprint:"mutated"`
PreventInstall bool `blueprint:"mutated"`
- Vndk_version string `blueprint:"mutated"`
}
type UnusedProperties struct {
@@ -212,6 +212,7 @@
installerProps() []interface{}
install(ctx ModuleContext, path android.Path)
inData() bool
+ inSanitizerDir() bool
hostToolPath() android.OptionalPath
}
@@ -378,8 +379,8 @@
func (ctx *moduleContextImpl) sdkVersion() string {
if ctx.ctx.Device() {
- if ctx.mod.Properties.Use_vndk {
- return ctx.mod.Properties.Vndk_version
+ if ctx.vndk() {
+ return "current"
} else {
return ctx.mod.Properties.Sdk_version
}
@@ -388,10 +389,7 @@
}
func (ctx *moduleContextImpl) vndk() bool {
- if ctx.ctx.Device() {
- return ctx.mod.Properties.Use_vndk
- }
- return false
+ return ctx.ctx.Os() == android.Android && ctx.ctx.Proprietary() && ctx.ctx.DeviceConfig().CompileVndk()
}
func (ctx *moduleContextImpl) selectedStl() string {
@@ -544,22 +542,11 @@
feature.begin(ctx)
}
if ctx.sdk() {
- if ctx.vndk() {
- ctx.PropertyErrorf("use_vndk",
- "sdk_version and use_vndk cannot be used at the same time")
- }
-
version, err := normalizeNdkApiLevel(ctx.sdkVersion(), ctx.Arch())
if err != nil {
ctx.PropertyErrorf("sdk_version", err.Error())
}
c.Properties.Sdk_version = version
- } else if ctx.vndk() {
- version, err := normalizeNdkApiLevel(ctx.DeviceConfig().VndkVersion(), ctx.Arch())
- if err != nil {
- ctx.ModuleErrorf("Bad BOARD_VNDK_VERSION: %s", err.Error())
- }
- c.Properties.Vndk_version = version
}
}
@@ -675,7 +662,7 @@
variantLibs = append(variantLibs, entry+ndkLibrarySuffix)
}
} else {
- nonvariantLibs = append(variantLibs, entry)
+ nonvariantLibs = append(nonvariantLibs, entry)
}
}
return nonvariantLibs, variantLibs
@@ -1007,10 +994,17 @@
if c.installer == nil {
return false
}
- if c.sanitize != nil && c.sanitize.inData() {
+ return c.installer.inData()
+}
+
+func (c *Module) InstallInSanitizerDir() bool {
+ if c.installer == nil {
+ return false
+ }
+ if c.sanitize != nil && c.sanitize.inSanitizerDir() {
return true
}
- return c.installer.inData()
+ return c.installer.inSanitizerDir()
}
func (c *Module) HostToolPath() android.OptionalPath {
diff --git a/cc/cmakelists.go b/cc/cmakelists.go
index 1a6eaf2..4df9ece 100644
--- a/cc/cmakelists.go
+++ b/cc/cmakelists.go
@@ -5,11 +5,12 @@
"android/soong/android"
"android/soong/cc/config"
- "github.com/google/blueprint"
"os"
"path"
"path/filepath"
"strings"
+
+ "github.com/google/blueprint"
)
// This singleton generates CMakeLists.txt files. It does so for each blueprint Android.bp resulting in a cc.Module
@@ -162,13 +163,22 @@
cppParameters := parseCompilerParameters(ccModule.flags.CppFlags, ctx, f)
translateToCMake(cppParameters, f, false, true)
+ f.WriteString("\n# SYSTEM INCLUDE FLAGS:\n")
+ includeParameters := parseCompilerParameters(ccModule.flags.SystemIncludeFlags, ctx, f)
+ translateToCMake(includeParameters, f, true, true)
+
// Add project executable.
- f.WriteString(fmt.Sprintf("\nadd_executable(%s ${SOURCE_FILES})\n", ccModule.ModuleBase.Name()))
+ f.WriteString(fmt.Sprintf("\nadd_executable(%s ${SOURCE_FILES})\n",
+ cleanExecutableName(ccModule.ModuleBase.Name())))
+}
+
+func cleanExecutableName(s string) string {
+ return strings.Replace(s, "@", "-", -1)
}
func translateToCMake(c compilerParameters, f *os.File, cflags bool, cppflags bool) {
- writeAllSystemDirectories(c.systemHeaderSearchPath, f)
- writeAllIncludeDirectories(c.headerSearchPath, f)
+ writeAllIncludeDirectories(c.systemHeaderSearchPath, f, true)
+ writeAllIncludeDirectories(c.headerSearchPath, f, false)
if cflags {
writeAllFlags(c.flags, f, "CMAKE_C_FLAGS")
}
@@ -189,26 +199,30 @@
return fmt.Sprintf("${ANDROID_ROOT}/%s", p)
}
-func writeAllIncludeDirectories(includes []string, f *os.File) {
+func writeAllIncludeDirectories(includes []string, f *os.File, isSystem bool) {
if len(includes) == 0 {
return
}
- f.WriteString("include_directories(\n")
- for _, include := range includes {
- f.WriteString(fmt.Sprintf(" \"%s\"\n", buildCMakePath(include)))
- }
- f.WriteString(")\n")
-}
-func writeAllSystemDirectories(includes []string, f *os.File) {
- if len(includes) == 0 {
- return
+ system := ""
+ if isSystem {
+ system = "SYSTEM"
}
- f.WriteString("include_directories(SYSTEM \n")
+
+ f.WriteString(fmt.Sprintf("include_directories(%s \n", system))
+
for _, include := range includes {
- f.WriteString(fmt.Sprintf(" \"%s\"\n", buildCMakePath(include)))
+ f.WriteString(fmt.Sprintf(" \"%s\"\n", buildCMakePath(include)))
+ }
+ f.WriteString(")\n\n")
+
+ // Also add all headers to source files.
+ f.WriteString("file (GLOB_RECURSE TMP_HEADERS\n");
+ for _, include := range includes {
+ f.WriteString(fmt.Sprintf(" \"%s/**/*.h\"\n", buildCMakePath(include)))
}
f.WriteString(")\n")
+ f.WriteString("list (APPEND SOURCE_FILES ${TMP_HEADERS})\n\n");
}
func writeAllFlags(flags []string, f *os.File, tag string) {
diff --git a/cc/compiler.go b/cc/compiler.go
index 84ee652..91eda38 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -194,15 +194,15 @@
}
if !ctx.noDefaultCompilerFlags() {
+ flags.GlobalFlags = append(flags.GlobalFlags, "-I"+android.PathForModuleSrc(ctx).String())
+
if !(ctx.sdk() || ctx.vndk()) || ctx.Host() {
- flags.GlobalFlags = append(flags.GlobalFlags,
+ flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
"${config.CommonGlobalIncludes}",
"${config.CommonGlobalSystemIncludes}",
tc.IncludeFlags(),
"${config.CommonNativehelperInclude}")
}
-
- flags.GlobalFlags = append(flags.GlobalFlags, "-I"+android.PathForModuleSrc(ctx).String())
}
if ctx.sdk() || ctx.vndk() {
@@ -210,7 +210,7 @@
// typical Soong approach would be to only make the headers for the
// library you're using available, we're trying to emulate the NDK
// behavior here, and the NDK always has all the NDK headers available.
- flags.GlobalFlags = append(flags.GlobalFlags,
+ flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
"-isystem "+getCurrentIncludePath(ctx).String(),
"-isystem "+getCurrentIncludePath(ctx).Join(ctx, tc.ClangTriple()).String())
@@ -230,7 +230,7 @@
legacyIncludes := fmt.Sprintf(
"prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/include",
ctx.sdkVersion(), ctx.Arch().ArchType.String())
- flags.GlobalFlags = append(flags.GlobalFlags, "-isystem "+legacyIncludes)
+ flags.SystemIncludeFlags = append(flags.SystemIncludeFlags, "-isystem "+legacyIncludes)
}
instructionSet := compiler.Properties.Instruction_set
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index fe47ddf..23186e7 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -66,9 +66,6 @@
"-fuse-ld=gold",
"-Wl,--icf=safe",
"-Wl,--no-undefined-version",
-
- // Disable transitive dependency library symbol resolving.
- "-Wl,--allow-shlib-undefined",
}
arm64Cppflags = []string{
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 10f4cea..30ab1c6 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -91,6 +91,10 @@
// http://b/29823425 Disable -Wexpansion-to-defined for Clang update to r271374
"-Wno-expansion-to-defined",
+
+ // http://b/36463318 Clang executes with an absolute path, so clang-provided
+ // headers are now absolute.
+ "-fdebug-prefix-map=$$PWD/=",
}, " "))
pctx.StaticVariable("ClangExtraCppflags", strings.Join([]string{
diff --git a/cc/config/global.go b/cc/config/global.go
index 1ce1cce..50c7c98 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -132,7 +132,7 @@
if override := config.(android.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
return override, nil
}
- return "clang-3688880", nil
+ return "clang-3859424", nil
})
pctx.StaticVariable("ClangPath", "${ClangBase}/${HostPrebuiltTag}/${ClangVersion}")
pctx.StaticVariable("ClangBin", "${ClangPath}/bin")
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index 8fc4a21..5270437 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -207,20 +207,24 @@
return indexList(s, list) != -1
}
-func AddressSanitizerRuntimeLibrary(t Toolchain) string {
+func SanitizerRuntimeLibrary(t Toolchain, sanitizer string) string {
arch := t.SanitizerRuntimeLibraryArch()
if arch == "" {
return ""
}
- return "libclang_rt.asan-" + arch + "-android.so"
+ return "libclang_rt." + sanitizer + "-" + arch + "-android.so"
+}
+
+func AddressSanitizerRuntimeLibrary(t Toolchain) string {
+ return SanitizerRuntimeLibrary(t, "asan")
}
func UndefinedBehaviorSanitizerRuntimeLibrary(t Toolchain) string {
- arch := t.SanitizerRuntimeLibraryArch()
- if arch == "" {
- return ""
- }
- return "libclang_rt.ubsan_standalone-" + arch + "-android.so"
+ return SanitizerRuntimeLibrary(t, "ubsan_standalone")
+}
+
+func ThreadSanitizerRuntimeLibrary(t Toolchain) string {
+ return SanitizerRuntimeLibrary(t, "tsan")
}
func ToolPath(t Toolchain) string {
diff --git a/cc/installer.go b/cc/installer.go
index 64f87d9..c4de589 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -30,8 +30,9 @@
type installLocation int
const (
- InstallInSystem installLocation = 0
- InstallInData = iota
+ InstallInSystem installLocation = 0
+ InstallInData = iota
+ InstallInSanitizerDir = iota
)
func NewBaseInstaller(dir, dir64 string, location installLocation) *baseInstaller {
@@ -78,6 +79,10 @@
return installer.location == InstallInData
}
+func (installer *baseInstaller) inSanitizerDir() bool {
+ return installer.location == InstallInSanitizerDir
+}
+
func (installer *baseInstaller) hostToolPath() android.OptionalPath {
return android.OptionalPath{}
}
diff --git a/cc/library.go b/cc/library.go
index 0658fef..953c37a 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -349,8 +349,8 @@
func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) {
location := InstallInSystem
- if library.sanitize.inData() {
- location = InstallInData
+ if library.sanitize.inSanitizerDir() {
+ location = InstallInSanitizerDir
}
library.baseInstaller.location = location
diff --git a/cc/makevars.go b/cc/makevars.go
index 200faff..dcde828 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -209,6 +209,7 @@
if target.Os.Class == android.Device {
ctx.Strict(secondPrefix+"ADDRESS_SANITIZER_RUNTIME_LIBRARY", strings.TrimSuffix(config.AddressSanitizerRuntimeLibrary(toolchain), ".so"))
ctx.Strict(secondPrefix+"UBSAN_RUNTIME_LIBRARY", strings.TrimSuffix(config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain), ".so"))
+ ctx.Strict(secondPrefix+"TSAN_RUNTIME_LIBRARY", strings.TrimSuffix(config.ThreadSanitizerRuntimeLibrary(toolchain), ".so"))
}
// This is used by external/gentoo/...
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index e4a790f..6a083ae 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -27,11 +27,13 @@
var (
preprocessBionicHeaders = pctx.AndroidStaticRule("preprocessBionicHeaders",
blueprint.RuleParams{
- Command: "$versionerCmd $srcDir $depsPath -o $out",
+ // The `&& touch $out` isn't really necessary, but Blueprint won't
+ // let us have only implicit outputs.
+ Command: "$versionerCmd -o $outDir $srcDir $depsPath && touch $out",
CommandDeps: []string{"$versionerCmd"},
Description: "versioner preprocess $in",
},
- "depsPath", "srcDir")
+ "depsPath", "srcDir", "outDir")
)
func init() {
@@ -229,14 +231,16 @@
}
}
+ timestampFile := android.PathForModuleOut(ctx, "versioner.timestamp")
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Rule: preprocessBionicHeaders,
- Output: toOutputPath,
+ Output: timestampFile,
Implicits: append(srcFiles, depsGlob...),
ImplicitOutputs: installPaths,
Args: map[string]string{
"depsPath": depsPath.String(),
"srcDir": fromSrcPath.String(),
+ "outDir": toOutputPath.String(),
},
})
}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 6ebd0c4..c28b411 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -130,6 +130,16 @@
"x86_64": 21,
}
+ archStr := arch.ArchType.String()
+ firstArchVersion, ok := firstArchVersions[archStr]
+ if !ok {
+ panic(fmt.Errorf("Arch %q not found in firstArchVersions", archStr))
+ }
+
+ if apiLevel == "minimum" {
+ return strconv.Itoa(firstArchVersion), nil
+ }
+
// If the NDK drops support for a platform version, we don't want to have to
// fix up every module that was using it as its SDK version. Clip to the
// supported version here instead.
@@ -139,12 +149,6 @@
}
version = intMax(version, minVersion)
- archStr := arch.ArchType.String()
- firstArchVersion, ok := firstArchVersions[archStr]
- if !ok {
- panic(fmt.Errorf("Arch %q not found in firstArchVersions", archStr))
- }
-
return strconv.Itoa(intMax(version, firstArchVersion)), nil
}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index bccd28d..18d6c16 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -97,7 +97,7 @@
SanitizerEnabled bool `blueprint:"mutated"`
SanitizeDep bool `blueprint:"mutated"`
- InData bool `blueprint:"mutated"`
+ InSanitizerDir bool `blueprint:"mutated"`
}
type sanitize struct {
@@ -383,8 +383,8 @@
return flags
}
-func (sanitize *sanitize) inData() bool {
- return sanitize.Properties.InData
+func (sanitize *sanitize) inSanitizerDir() bool {
+ return sanitize.Properties.InSanitizerDir
}
func (sanitize *sanitize) Sanitizer(t sanitizerType) bool {
@@ -447,7 +447,7 @@
modules[0].(*Module).sanitize.Properties.SanitizeDep = false
modules[1].(*Module).sanitize.Properties.SanitizeDep = false
if mctx.Device() {
- modules[1].(*Module).sanitize.Properties.InData = true
+ modules[1].(*Module).sanitize.Properties.InSanitizerDir = true
} else {
modules[0].(*Module).Properties.PreventInstall = true
}
diff --git a/cc/test.go b/cc/test.go
index d3556bf..145b5b0 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -20,6 +20,7 @@
"strings"
"android/soong/android"
+
"github.com/google/blueprint"
)
@@ -41,6 +42,10 @@
// list of files or filegroup modules that provide data that should be installed alongside
// the test
Data []string
+
+ // list of compatibility suites (for example "cts", "vts") that the module should be
+ // installed into.
+ Test_suites []string
}
func init() {
diff --git a/cc/util.go b/cc/util.go
index 919e14c..36d8dd2 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -105,6 +105,8 @@
coverage: in.Coverage,
tidy: in.Tidy,
+ systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "),
+
groupStaticLibs: in.GroupStaticLibs,
}
}
diff --git a/cmd/fileslist/Android.bp b/cmd/fileslist/Android.bp
new file mode 100644
index 0000000..cbf939a
--- /dev/null
+++ b/cmd/fileslist/Android.bp
@@ -0,0 +1,20 @@
+// 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.
+
+blueprint_go_binary {
+ name: "fileslist",
+ srcs: [
+ "fileslist.go",
+ ],
+}
diff --git a/cmd/fileslist/fileslist.go b/cmd/fileslist/fileslist.go
new file mode 100755
index 0000000..56ea66d
--- /dev/null
+++ b/cmd/fileslist/fileslist.go
@@ -0,0 +1,173 @@
+// 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.
+
+// fileslist.py replacement written in GO, which utilizes multi-cores.
+
+package main
+
+import (
+ "crypto/sha256"
+ "encoding/json"
+ "flag"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "runtime"
+ "sort"
+ "strings"
+ "sync"
+)
+
+const (
+ MAX_DEFAULT_PARA = 24
+)
+
+func defaultPara() int {
+ ret := runtime.NumCPU()
+ if ret > MAX_DEFAULT_PARA {
+ return MAX_DEFAULT_PARA
+ }
+ return ret
+}
+
+var (
+ para = flag.Int("para", defaultPara(), "Number of goroutines")
+)
+
+// Represents each file.
+type Node struct {
+ SHA256 string
+ Name string // device side path.
+ Size int64
+ path string // host side path.
+ stat os.FileInfo
+}
+
+func newNode(hostPath string, devicePath string, stat os.FileInfo) Node {
+ return Node{Name: devicePath, path: hostPath, stat: stat}
+}
+
+// Scan a Node and returns true if it should be added to the result.
+func (n *Node) scan() bool {
+ n.Size = n.stat.Size()
+
+ // Calculate SHA256.
+ h := sha256.New()
+ if n.stat.Mode()&os.ModeSymlink == 0 {
+ f, err := os.Open(n.path)
+ if err != nil {
+ panic(err)
+ }
+ defer f.Close()
+
+ if _, err := io.Copy(h, f); err != nil {
+ panic(err)
+ }
+ } else {
+ // Hash the content of symlink, not the file it points to.
+ s, err := os.Readlink(n.path)
+ if err != nil {
+ panic(err)
+ }
+ if _, err := io.WriteString(h, s); err != nil {
+ panic(err)
+ }
+ }
+ n.SHA256 = fmt.Sprintf("%x", h.Sum(nil))
+ return true
+}
+
+func main() {
+ flag.Parse()
+
+ allOutput := make([]Node, 0, 1024) // Store all outputs.
+ mutex := &sync.Mutex{} // Guard allOutput
+
+ ch := make(chan Node) // Pass nodes to goroutines.
+
+ var wg sync.WaitGroup // To wait for all goroutines.
+ wg.Add(*para)
+
+ // Scan files in multiple goroutines.
+ for i := 0; i < *para; i++ {
+ go func() {
+ defer wg.Done()
+
+ output := make([]Node, 0, 1024) // Local output list.
+ for node := range ch {
+ if node.scan() {
+ output = append(output, node)
+ }
+ }
+ // Add to the global output list.
+ mutex.Lock()
+ allOutput = append(allOutput, output...)
+ mutex.Unlock()
+ }()
+ }
+
+ // Walk the directories and find files to scan.
+ for _, dir := range flag.Args() {
+ absDir, err := filepath.Abs(dir)
+ if err != nil {
+ panic(err)
+ }
+ deviceRoot := filepath.Clean(absDir + "/..")
+ err = filepath.Walk(dir, func(path string, stat os.FileInfo, err error) error {
+ if err != nil {
+ panic(err)
+ }
+ if stat.IsDir() {
+ return nil
+ }
+ absPath, err := filepath.Abs(path)
+ if err != nil {
+ panic(err)
+ }
+ devicePath, err := filepath.Rel(deviceRoot, absPath)
+ if err != nil {
+ panic(err)
+ }
+ devicePath = "/" + devicePath
+ ch <- newNode(absPath, devicePath, stat)
+ return nil
+ })
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ // Wait until all the goroutines finish.
+ close(ch)
+ wg.Wait()
+
+ // Sort the entries and dump as json.
+ sort.Slice(allOutput, func(i, j int) bool {
+ if allOutput[i].Size > allOutput[j].Size {
+ return true
+ }
+ if allOutput[i].Size == allOutput[j].Size && strings.Compare(allOutput[i].Name, allOutput[j].Name) > 0 {
+ return true
+ }
+ return false
+ })
+
+ j, err := json.MarshalIndent(allOutput, "", " ")
+ if err != nil {
+ panic(nil)
+ }
+
+ fmt.Printf("%s\n", j)
+}
diff --git a/cmd/microfactory/microfactory.go b/cmd/microfactory/microfactory.go
index d0febe7..6c062e2 100644
--- a/cmd/microfactory/microfactory.go
+++ b/cmd/microfactory/microfactory.go
@@ -87,8 +87,9 @@
Name string
// Inputs
- deps []*GoPackage
- files []string
+ directDeps []*GoPackage // specified directly by the module
+ allDeps []*GoPackage // direct dependencies and transitive dependencies
+ files []string
// Outputs
pkgDir string
@@ -102,17 +103,48 @@
rebuilt bool
}
+// LinkedHashMap<string, GoPackage>
+type linkedDepSet struct {
+ packageSet map[string](*GoPackage)
+ packageList []*GoPackage
+}
+
+func newDepSet() *linkedDepSet {
+ return &linkedDepSet{packageSet: make(map[string]*GoPackage)}
+}
+func (s *linkedDepSet) tryGetByName(name string) (*GoPackage, bool) {
+ pkg, contained := s.packageSet[name]
+ return pkg, contained
+}
+func (s *linkedDepSet) getByName(name string) *GoPackage {
+ pkg, _ := s.tryGetByName(name)
+ return pkg
+}
+func (s *linkedDepSet) add(name string, goPackage *GoPackage) {
+ s.packageSet[name] = goPackage
+ s.packageList = append(s.packageList, goPackage)
+}
+func (s *linkedDepSet) ignore(name string) {
+ s.packageSet[name] = nil
+}
+
// FindDeps searches all applicable go files in `path`, parses all of them
// for import dependencies that exist in pkgMap, then recursively does the
// same for all of those dependencies.
func (p *GoPackage) FindDeps(path string, pkgMap *pkgPathMapping) error {
- return p.findDeps(path, pkgMap, make(map[string]*GoPackage))
+ depSet := newDepSet()
+ err := p.findDeps(path, pkgMap, depSet)
+ if err != nil {
+ return err
+ }
+ p.allDeps = depSet.packageList
+ return nil
}
// findDeps is the recursive version of FindDeps. allPackages is the map of
// all locally defined packages so that the same dependency of two different
// packages is only resolved once.
-func (p *GoPackage) findDeps(path string, pkgMap *pkgPathMapping, allPackages map[string]*GoPackage) error {
+func (p *GoPackage) findDeps(path string, pkgMap *pkgPathMapping, allPackages *linkedDepSet) error {
// If this ever becomes too slow, we can look at reading the files once instead of twice
// But that just complicates things today, and we're already really fast.
foundPkgs, err := parser.ParseDir(token.NewFileSet(), path, func(fi os.FileInfo) bool {
@@ -154,7 +186,7 @@
return fmt.Errorf("%s: invalid quoted string: <%s> %v", filename, importSpec.Path.Value, err)
}
- if pkg, ok := allPackages[name]; ok && pkg != nil {
+ if pkg, ok := allPackages.tryGetByName(name); ok {
if pkg != nil {
if _, ok := localDeps[name]; !ok {
deps = append(deps, name)
@@ -168,9 +200,9 @@
if path, ok, err := pkgMap.Path(name); err != nil {
return err
} else if !ok {
- // Probably in the stdlib, compiler will fail we a reasonable error message otherwise.
+ // Probably in the stdlib, but if not, then the compiler will fail with a reasonable error message
// Mark it as such so that we don't try to decode its path again.
- allPackages[name] = nil
+ allPackages.ignore(name)
continue
} else {
pkgPath = path
@@ -180,7 +212,7 @@
Name: name,
}
deps = append(deps, name)
- allPackages[name] = pkg
+ allPackages.add(name, pkg)
localDeps[name] = true
if err := pkg.findDeps(pkgPath, pkgMap, allPackages); err != nil {
@@ -196,7 +228,7 @@
}
for _, dep := range deps {
- p.deps = append(p.deps, allPackages[dep])
+ p.directDeps = append(p.directDeps, allPackages.getByName(dep))
}
return nil
@@ -212,7 +244,7 @@
// Build all dependencies in parallel, then fail if any of them failed.
var wg sync.WaitGroup
- for _, dep := range p.deps {
+ for _, dep := range p.directDeps {
wg.Add(1)
go func(dep *GoPackage) {
defer wg.Done()
@@ -220,7 +252,7 @@
}(dep)
}
wg.Wait()
- for _, dep := range p.deps {
+ for _, dep := range p.directDeps {
if dep.failed != nil {
p.failed = dep.failed
return p.failed
@@ -246,7 +278,7 @@
cmd.Args = append(cmd.Args, "-trimpath", trimPath)
fmt.Fprintln(hash, trimPath)
}
- for _, dep := range p.deps {
+ for _, dep := range p.directDeps {
cmd.Args = append(cmd.Args, "-I", dep.pkgDir)
hash.Write(dep.hashResult)
}
@@ -361,7 +393,7 @@
if race {
cmd.Args = append(cmd.Args, "-race")
}
- for _, dep := range p.deps {
+ for _, dep := range p.allDeps {
cmd.Args = append(cmd.Args, "-L", dep.pkgDir)
}
cmd.Args = append(cmd.Args, p.output)
@@ -373,7 +405,7 @@
}
err = cmd.Run()
if err != nil {
- return err
+ return fmt.Errorf("command %s failed with error %v", cmd.Args, err)
}
return ioutil.WriteFile(shaFile, p.hashResult, 0666)
@@ -481,7 +513,7 @@
err = mainPackage.Link(output)
if err != nil {
- fmt.Fprintln(os.Stderr, "Failed to link:", err)
+ fmt.Fprintln(os.Stderr, "microfactory.go failed to link:", err)
os.Exit(1)
}
}
diff --git a/cmd/microfactory/microfactory_test.go b/cmd/microfactory/microfactory_test.go
index 296a844..8c02bcf 100644
--- a/cmd/microfactory/microfactory_test.go
+++ b/cmd/microfactory/microfactory_test.go
@@ -236,10 +236,10 @@
t.Fatal("Error writing a/a.go:", err)
}
}, func(pkg *GoPackage) {
- if !pkg.deps[0].rebuilt {
+ if !pkg.directDeps[0].rebuilt {
t.Fatal("android/soong/a should have rebuilt")
}
- if !pkg.deps[1].rebuilt {
+ if !pkg.directDeps[1].rebuilt {
t.Fatal("android/soong/b should have rebuilt")
}
})
@@ -253,10 +253,10 @@
t.Fatal("Error writing main/main.go:", err)
}
}, func(pkg *GoPackage) {
- if pkg.deps[0].rebuilt {
+ if pkg.directDeps[0].rebuilt {
t.Fatal("android/soong/a should not have rebuilt")
}
- if pkg.deps[1].rebuilt {
+ if pkg.directDeps[1].rebuilt {
t.Fatal("android/soong/b should not have rebuilt")
}
})
diff --git a/root.bp b/root.bp
index 219b4e5..f14b047 100644
--- a/root.bp
+++ b/root.bp
@@ -28,6 +28,7 @@
"libcore",
"libnativehelper",
"packages/apps/HTMLViewer",
+ "prebuilts/clang/host/linux-x86",
"prebuilts/ndk",
"prebuilts/sdk",
"system/*",