Use Path
instead of string for file paths
This centralizes verification and common operations, like converting the path to a source file to the path for a built object. It also embeds the configuration knowledge into the path, so that we can remove "${SrcDir}/path" from the ninja file. When SrcDir is '.', that leads to paths like './path' instead of just 'path' like make is doing, causing differences in compiled binaries. Change-Id: Ib4e8910a6e867ce1b7b420d927c04f1142a7589e
This commit is contained in:
@@ -98,10 +98,14 @@ bootstrap_go_package {
|
||||
"common/glob.go",
|
||||
"common/module.go",
|
||||
"common/mutator.go",
|
||||
"common/package_ctx.go",
|
||||
"common/paths.go",
|
||||
"common/util.go",
|
||||
"common/variable.go",
|
||||
],
|
||||
testSrcs: [
|
||||
"common/paths_test.go",
|
||||
],
|
||||
}
|
||||
|
||||
bootstrap_go_package {
|
||||
|
@@ -16,7 +16,6 @@ package cc
|
||||
|
||||
import (
|
||||
"io"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"android/soong/common"
|
||||
@@ -29,7 +28,7 @@ func (c *CCLibrary) AndroidMk() (ret common.AndroidMkData) {
|
||||
ret.Class = "SHARED_LIBRARIES"
|
||||
}
|
||||
ret.OutputFile = c.outputFile()
|
||||
ret.Extra = func(name, prefix, outputFile string, arch common.Arch) (ret []string) {
|
||||
ret.Extra = func(name, prefix string, outputFile common.Path, arch common.Arch) (ret []string) {
|
||||
exportedIncludes := c.exportedFlags()
|
||||
for i := range exportedIncludes {
|
||||
exportedIncludes[i] = strings.TrimPrefix(exportedIncludes[i], "-I")
|
||||
@@ -38,7 +37,7 @@ func (c *CCLibrary) AndroidMk() (ret common.AndroidMkData) {
|
||||
ret = append(ret, "LOCAL_EXPORT_C_INCLUDE_DIRS := "+strings.Join(exportedIncludes, " "))
|
||||
}
|
||||
|
||||
ret = append(ret, "LOCAL_MODULE_SUFFIX := "+filepath.Ext(outputFile))
|
||||
ret = append(ret, "LOCAL_MODULE_SUFFIX := "+outputFile.Ext())
|
||||
ret = append(ret, "LOCAL_SHARED_LIBRARIES_"+arch.ArchType.String()+" := "+strings.Join(c.savedDepNames.SharedLibs, " "))
|
||||
|
||||
if c.Properties.Relative_install_path != "" {
|
||||
@@ -57,9 +56,9 @@ func (c *CCLibrary) AndroidMk() (ret common.AndroidMkData) {
|
||||
func (c *ccObject) AndroidMk() (ret common.AndroidMkData) {
|
||||
ret.OutputFile = c.outputFile()
|
||||
ret.Custom = func(w io.Writer, name, prefix string) {
|
||||
out := c.outputFile()
|
||||
out := c.outputFile().Path()
|
||||
|
||||
io.WriteString(w, "$("+prefix+"TARGET_OUT_INTERMEDIATE_LIBRARIES)/"+name+objectExtension+": "+out+" | $(ACP)\n")
|
||||
io.WriteString(w, "$("+prefix+"TARGET_OUT_INTERMEDIATE_LIBRARIES)/"+name+objectExtension+": "+out.String()+" | $(ACP)\n")
|
||||
io.WriteString(w, "\t$(copy-file-to-target)\n")
|
||||
}
|
||||
return
|
||||
@@ -67,7 +66,7 @@ func (c *ccObject) AndroidMk() (ret common.AndroidMkData) {
|
||||
|
||||
func (c *CCBinary) AndroidMk() (ret common.AndroidMkData) {
|
||||
ret.Class = "EXECUTABLES"
|
||||
ret.Extra = func(name, prefix, outputFile string, arch common.Arch) []string {
|
||||
ret.Extra = func(name, prefix string, outputFile common.Path, arch common.Arch) []string {
|
||||
ret := []string{
|
||||
"LOCAL_CXX_STL := none",
|
||||
"LOCAL_SYSTEM_SHARED_LIBRARIES :=",
|
||||
|
@@ -78,7 +78,7 @@ const (
|
||||
func init() {
|
||||
pctx.StaticVariable("arm64GccVersion", arm64GccVersion)
|
||||
|
||||
pctx.StaticVariable("arm64GccRoot",
|
||||
pctx.SourcePathVariable("arm64GccRoot",
|
||||
"prebuilts/gcc/${HostPrebuiltTag}/aarch64/aarch64-linux-android-${arm64GccVersion}")
|
||||
|
||||
pctx.StaticVariable("arm64GccTriple", "aarch64-linux-android")
|
||||
|
@@ -154,7 +154,7 @@ func init() {
|
||||
|
||||
pctx.StaticVariable("armGccVersion", armGccVersion)
|
||||
|
||||
pctx.StaticVariable("armGccRoot",
|
||||
pctx.SourcePathVariable("armGccRoot",
|
||||
"prebuilts/gcc/${HostPrebuiltTag}/arm/arm-linux-androideabi-${armGccVersion}")
|
||||
|
||||
pctx.StaticVariable("armGccTriple", "arm-linux-androideabi")
|
||||
|
116
cc/builder.go
116
cc/builder.go
@@ -28,7 +28,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -37,7 +36,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
pctx = blueprint.NewPackageContext("android/soong/cc")
|
||||
pctx = common.NewPackageContext("android/soong/cc")
|
||||
|
||||
cc = pctx.StaticRule("cc",
|
||||
blueprint.RuleParams{
|
||||
@@ -102,7 +101,7 @@ var (
|
||||
},
|
||||
"objcopyCmd", "prefix")
|
||||
|
||||
copyGccLibPath = pctx.StaticVariable("copyGccLibPath", "${SrcDir}/build/soong/copygcclib.sh")
|
||||
copyGccLibPath = pctx.SourcePathVariable("copyGccLibPath", "build/soong/copygcclib.sh")
|
||||
|
||||
copyGccLib = pctx.StaticRule("copyGccLib",
|
||||
blueprint.RuleParams{
|
||||
@@ -141,45 +140,24 @@ type builderFlags struct {
|
||||
}
|
||||
|
||||
// Generate rules for compiling multiple .c, .cpp, or .S files to individual .o files
|
||||
func TransformSourceToObj(ctx common.AndroidModuleContext, subdir string, srcFiles []string,
|
||||
flags builderFlags, deps []string) (objFiles []string) {
|
||||
func TransformSourceToObj(ctx common.AndroidModuleContext, subdir string, srcFiles common.Paths,
|
||||
flags builderFlags, deps common.Paths) (objFiles common.Paths) {
|
||||
|
||||
srcRoot := ctx.AConfig().SrcDir()
|
||||
intermediatesRoot := ctx.AConfig().IntermediatesDir()
|
||||
|
||||
objFiles = make([]string, len(srcFiles))
|
||||
objDir := common.ModuleObjDir(ctx)
|
||||
if subdir != "" {
|
||||
objDir = filepath.Join(objDir, subdir)
|
||||
}
|
||||
objFiles = make(common.Paths, len(srcFiles))
|
||||
|
||||
cflags := flags.globalFlags + " " + flags.cFlags + " " + flags.conlyFlags
|
||||
cppflags := flags.globalFlags + " " + flags.cFlags + " " + flags.cppFlags
|
||||
asflags := flags.globalFlags + " " + flags.asFlags
|
||||
|
||||
for i, srcFile := range srcFiles {
|
||||
var objFile string
|
||||
if strings.HasPrefix(srcFile, intermediatesRoot) {
|
||||
objFile = strings.TrimPrefix(srcFile, intermediatesRoot)
|
||||
objFile = filepath.Join(objDir, "gen", objFile)
|
||||
} else if strings.HasPrefix(srcFile, srcRoot) {
|
||||
srcFile, _ = filepath.Rel(srcRoot, srcFile)
|
||||
objFile = filepath.Join(objDir, srcFile)
|
||||
} else if srcRoot == "." && srcFile[0] != '/' {
|
||||
objFile = filepath.Join(objDir, srcFile)
|
||||
} else {
|
||||
ctx.ModuleErrorf("source file %q is not in source directory %q", srcFile, srcRoot)
|
||||
continue
|
||||
}
|
||||
|
||||
objFile = pathtools.ReplaceExtension(objFile, "o")
|
||||
objFile := common.ObjPathWithExt(ctx, srcFile, subdir, "o")
|
||||
|
||||
objFiles[i] = objFile
|
||||
|
||||
var moduleCflags string
|
||||
var ccCmd string
|
||||
|
||||
switch filepath.Ext(srcFile) {
|
||||
switch srcFile.Ext() {
|
||||
case ".S", ".s":
|
||||
ccCmd = "gcc"
|
||||
moduleCflags = asflags
|
||||
@@ -204,15 +182,15 @@ func TransformSourceToObj(ctx common.AndroidModuleContext, subdir string, srcFil
|
||||
panic("unrecoginzied ccCmd")
|
||||
}
|
||||
|
||||
ccCmd = "${clangPath}" + ccCmd
|
||||
ccCmd = "${clangPath}/" + ccCmd
|
||||
} else {
|
||||
ccCmd = gccCmd(flags.toolchain, ccCmd)
|
||||
}
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: cc,
|
||||
Outputs: []string{objFile},
|
||||
Inputs: []string{srcFile},
|
||||
Output: objFile,
|
||||
Input: srcFile,
|
||||
Implicits: deps,
|
||||
Args: map[string]string{
|
||||
"cFlags": moduleCflags,
|
||||
@@ -225,15 +203,15 @@ func TransformSourceToObj(ctx common.AndroidModuleContext, subdir string, srcFil
|
||||
}
|
||||
|
||||
// Generate a rule for compiling multiple .o files to a static library (.a)
|
||||
func TransformObjToStaticLib(ctx common.AndroidModuleContext, objFiles []string,
|
||||
flags builderFlags, outputFile string) {
|
||||
func TransformObjToStaticLib(ctx common.AndroidModuleContext, objFiles common.Paths,
|
||||
flags builderFlags, outputFile common.ModuleOutPath) {
|
||||
|
||||
arCmd := gccCmd(flags.toolchain, "ar")
|
||||
arFlags := "crsPD"
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: ar,
|
||||
Outputs: []string{outputFile},
|
||||
Output: outputFile,
|
||||
Inputs: objFiles,
|
||||
Args: map[string]string{
|
||||
"arFlags": arFlags,
|
||||
@@ -246,18 +224,20 @@ func TransformObjToStaticLib(ctx common.AndroidModuleContext, objFiles []string,
|
||||
// darwin. The darwin ar tool doesn't support @file for list files, and has a
|
||||
// very small command line length limit, so we have to split the ar into multiple
|
||||
// steps, each appending to the previous one.
|
||||
func TransformDarwinObjToStaticLib(ctx common.AndroidModuleContext, objFiles []string,
|
||||
flags builderFlags, outputFile string) {
|
||||
func TransformDarwinObjToStaticLib(ctx common.AndroidModuleContext, objFiles common.Paths,
|
||||
flags builderFlags, outputPath common.ModuleOutPath) {
|
||||
|
||||
arCmd := "ar"
|
||||
arFlags := "cqs"
|
||||
|
||||
// ARG_MAX on darwin is 262144, use half that to be safe
|
||||
objFilesLists, err := splitListForSize(objFiles, 131072)
|
||||
objFilesLists, err := splitListForSize(objFiles.Strings(), 131072)
|
||||
if err != nil {
|
||||
ctx.ModuleErrorf("%s", err.Error())
|
||||
}
|
||||
|
||||
outputFile := outputPath.String()
|
||||
|
||||
var in, out string
|
||||
for i, l := range objFilesLists {
|
||||
in = out
|
||||
@@ -295,12 +275,12 @@ func TransformDarwinObjToStaticLib(ctx common.AndroidModuleContext, objFiles []s
|
||||
// Generate a rule for compiling multiple .o files, plus static libraries, whole static libraries,
|
||||
// and shared libraires, to a shared library (.so) or dynamic executable
|
||||
func TransformObjToDynamicBinary(ctx common.AndroidModuleContext,
|
||||
objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps []string,
|
||||
crtBegin, crtEnd string, groupLate bool, flags builderFlags, outputFile string) {
|
||||
objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps common.Paths,
|
||||
crtBegin, crtEnd common.OptionalPath, groupLate bool, flags builderFlags, outputFile common.WritablePath) {
|
||||
|
||||
var ldCmd string
|
||||
if flags.clang {
|
||||
ldCmd = "${clangPath}clang++"
|
||||
ldCmd = "${clangPath}/clang++"
|
||||
} else {
|
||||
ldCmd = gccCmd(flags.toolchain, "g++")
|
||||
}
|
||||
@@ -310,31 +290,31 @@ func TransformObjToDynamicBinary(ctx common.AndroidModuleContext,
|
||||
|
||||
if len(wholeStaticLibs) > 0 {
|
||||
if ctx.Host() && ctx.Darwin() {
|
||||
libFlagsList = append(libFlagsList, common.JoinWithPrefix(wholeStaticLibs, "-force_load "))
|
||||
libFlagsList = append(libFlagsList, common.JoinWithPrefix(wholeStaticLibs.Strings(), "-force_load "))
|
||||
} else {
|
||||
libFlagsList = append(libFlagsList, "-Wl,--whole-archive ")
|
||||
libFlagsList = append(libFlagsList, wholeStaticLibs...)
|
||||
libFlagsList = append(libFlagsList, wholeStaticLibs.Strings()...)
|
||||
libFlagsList = append(libFlagsList, "-Wl,--no-whole-archive ")
|
||||
}
|
||||
}
|
||||
|
||||
libFlagsList = append(libFlagsList, staticLibs...)
|
||||
libFlagsList = append(libFlagsList, staticLibs.Strings()...)
|
||||
|
||||
if groupLate && len(lateStaticLibs) > 0 {
|
||||
libFlagsList = append(libFlagsList, "-Wl,--start-group")
|
||||
}
|
||||
libFlagsList = append(libFlagsList, lateStaticLibs...)
|
||||
libFlagsList = append(libFlagsList, lateStaticLibs.Strings()...)
|
||||
if groupLate && len(lateStaticLibs) > 0 {
|
||||
libFlagsList = append(libFlagsList, "-Wl,--end-group")
|
||||
}
|
||||
|
||||
for _, lib := range sharedLibs {
|
||||
dir, file := filepath.Split(lib)
|
||||
dir, file := filepath.Split(lib.String())
|
||||
if !strings.HasPrefix(file, "lib") {
|
||||
panic("shared library " + lib + " does not start with lib")
|
||||
panic("shared library " + lib.String() + " does not start with lib")
|
||||
}
|
||||
if !strings.HasSuffix(file, flags.toolchain.ShlibSuffix()) {
|
||||
panic("shared library " + lib + " does not end with " + flags.toolchain.ShlibSuffix())
|
||||
panic("shared library " + lib.String() + " does not end with " + flags.toolchain.ShlibSuffix())
|
||||
}
|
||||
libFlagsList = append(libFlagsList,
|
||||
"-l"+strings.TrimSuffix(strings.TrimPrefix(file, "lib"), flags.toolchain.ShlibSuffix()))
|
||||
@@ -345,29 +325,29 @@ func TransformObjToDynamicBinary(ctx common.AndroidModuleContext,
|
||||
deps = append(deps, staticLibs...)
|
||||
deps = append(deps, lateStaticLibs...)
|
||||
deps = append(deps, wholeStaticLibs...)
|
||||
if crtBegin != "" {
|
||||
deps = append(deps, crtBegin, crtEnd)
|
||||
if crtBegin.Valid() {
|
||||
deps = append(deps, crtBegin.Path(), crtEnd.Path())
|
||||
}
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: ld,
|
||||
Outputs: []string{outputFile},
|
||||
Output: outputFile,
|
||||
Inputs: objFiles,
|
||||
Implicits: deps,
|
||||
Args: map[string]string{
|
||||
"ldCmd": ldCmd,
|
||||
"ldDirFlags": ldDirsToFlags(ldDirs),
|
||||
"crtBegin": crtBegin,
|
||||
"crtBegin": crtBegin.String(),
|
||||
"libFlags": strings.Join(libFlagsList, " "),
|
||||
"ldFlags": flags.ldFlags,
|
||||
"crtEnd": crtEnd,
|
||||
"crtEnd": crtEnd.String(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Generate a rule for compiling multiple .o files to a .o using ld partial linking
|
||||
func TransformObjsToObj(ctx common.AndroidModuleContext, objFiles []string,
|
||||
flags builderFlags, outputFile string) {
|
||||
func TransformObjsToObj(ctx common.AndroidModuleContext, objFiles common.Paths,
|
||||
flags builderFlags, outputFile common.WritablePath) {
|
||||
|
||||
var ldCmd string
|
||||
if flags.clang {
|
||||
@@ -376,9 +356,9 @@ func TransformObjsToObj(ctx common.AndroidModuleContext, objFiles []string,
|
||||
ldCmd = gccCmd(flags.toolchain, "g++")
|
||||
}
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: partialLd,
|
||||
Outputs: []string{outputFile},
|
||||
Output: outputFile,
|
||||
Inputs: objFiles,
|
||||
Args: map[string]string{
|
||||
"ldCmd": ldCmd,
|
||||
@@ -388,15 +368,15 @@ func TransformObjsToObj(ctx common.AndroidModuleContext, objFiles []string,
|
||||
}
|
||||
|
||||
// Generate a rule for runing objcopy --prefix-symbols on a binary
|
||||
func TransformBinaryPrefixSymbols(ctx common.AndroidModuleContext, prefix string, inputFile string,
|
||||
flags builderFlags, outputFile string) {
|
||||
func TransformBinaryPrefixSymbols(ctx common.AndroidModuleContext, prefix string, inputFile common.Path,
|
||||
flags builderFlags, outputFile common.WritablePath) {
|
||||
|
||||
objcopyCmd := gccCmd(flags.toolchain, "objcopy")
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: prefixSymbols,
|
||||
Outputs: []string{outputFile},
|
||||
Inputs: []string{inputFile},
|
||||
Output: outputFile,
|
||||
Input: inputFile,
|
||||
Args: map[string]string{
|
||||
"objcopyCmd": objcopyCmd,
|
||||
"prefix": prefix,
|
||||
@@ -405,11 +385,11 @@ func TransformBinaryPrefixSymbols(ctx common.AndroidModuleContext, prefix string
|
||||
}
|
||||
|
||||
func CopyGccLib(ctx common.AndroidModuleContext, libName string,
|
||||
flags builderFlags, outputFile string) {
|
||||
flags builderFlags, outputFile common.WritablePath) {
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: copyGccLib,
|
||||
Outputs: []string{outputFile},
|
||||
Output: outputFile,
|
||||
Args: map[string]string{
|
||||
"ccCmd": gccCmd(flags.toolchain, "gcc"),
|
||||
"cFlags": flags.globalFlags,
|
||||
|
274
cc/cc.go
274
cc/cc.go
@@ -24,7 +24,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
"github.com/google/blueprint/proptools"
|
||||
|
||||
"android/soong"
|
||||
@@ -64,10 +63,9 @@ func init() {
|
||||
|
||||
var (
|
||||
HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", common.Config.PrebuiltOS)
|
||||
SrcDir = pctx.VariableConfigMethod("SrcDir", common.Config.SrcDir)
|
||||
|
||||
LibcRoot = pctx.StaticVariable("LibcRoot", "bionic/libc")
|
||||
LibmRoot = pctx.StaticVariable("LibmRoot", "bionic/libm")
|
||||
LibcRoot = pctx.SourcePathVariable("LibcRoot", "bionic/libc")
|
||||
LibmRoot = pctx.SourcePathVariable("LibmRoot", "bionic/libm")
|
||||
)
|
||||
|
||||
// Flags used by lots of devices. Putting them in package static variables will save bytes in
|
||||
@@ -127,19 +125,20 @@ func init() {
|
||||
|
||||
// Everything in this list is a crime against abstraction and dependency tracking.
|
||||
// Do not add anything to this list.
|
||||
pctx.StaticVariable("commonGlobalIncludes", strings.Join([]string{
|
||||
"-isystem ${SrcDir}/system/core/include",
|
||||
"-isystem ${SrcDir}/hardware/libhardware/include",
|
||||
"-isystem ${SrcDir}/hardware/libhardware_legacy/include",
|
||||
"-isystem ${SrcDir}/hardware/ril/include",
|
||||
"-isystem ${SrcDir}/libnativehelper/include",
|
||||
"-isystem ${SrcDir}/frameworks/native/include",
|
||||
"-isystem ${SrcDir}/frameworks/native/opengl/include",
|
||||
"-isystem ${SrcDir}/frameworks/av/include",
|
||||
"-isystem ${SrcDir}/frameworks/base/include",
|
||||
}, " "))
|
||||
pctx.PrefixedPathsForSourceVariable("commonGlobalIncludes", "-isystem ",
|
||||
[]string{
|
||||
"system/core/include",
|
||||
"hardware/libhardware/include",
|
||||
"hardware/libhardware_legacy/include",
|
||||
"hardware/ril/include",
|
||||
"libnativehelper/include",
|
||||
"frameworks/native/include",
|
||||
"frameworks/native/opengl/include",
|
||||
"frameworks/av/include",
|
||||
"frameworks/base/include",
|
||||
})
|
||||
|
||||
pctx.StaticVariable("clangPath", "${SrcDir}/prebuilts/clang/host/${HostPrebuiltTag}/3.8/bin/")
|
||||
pctx.SourcePathVariable("clangPath", "prebuilts/clang/host/${HostPrebuiltTag}/3.8/bin")
|
||||
}
|
||||
|
||||
type CCModuleContext common.AndroidBaseContext
|
||||
@@ -162,23 +161,36 @@ type CCModuleType interface {
|
||||
depsMutator(common.AndroidBottomUpMutatorContext)
|
||||
|
||||
// Compile objects into final module
|
||||
compileModule(common.AndroidModuleContext, CCFlags, CCDeps, []string)
|
||||
compileModule(common.AndroidModuleContext, CCFlags, CCPathDeps, common.Paths)
|
||||
|
||||
// Install the built module.
|
||||
installModule(common.AndroidModuleContext, CCFlags)
|
||||
|
||||
// Return the output file (.o, .a or .so) for use by other modules
|
||||
outputFile() string
|
||||
outputFile() common.OptionalPath
|
||||
}
|
||||
|
||||
type CCDeps struct {
|
||||
StaticLibs, SharedLibs, LateStaticLibs, WholeStaticLibs, ObjFiles, Cflags, ReexportedCflags []string
|
||||
StaticLibs, SharedLibs, LateStaticLibs, WholeStaticLibs []string
|
||||
|
||||
WholeStaticLibObjFiles []string
|
||||
ObjFiles common.Paths
|
||||
|
||||
Cflags, ReexportedCflags []string
|
||||
|
||||
CrtBegin, CrtEnd string
|
||||
}
|
||||
|
||||
type CCPathDeps struct {
|
||||
StaticLibs, SharedLibs, LateStaticLibs, WholeStaticLibs common.Paths
|
||||
|
||||
ObjFiles common.Paths
|
||||
WholeStaticLibObjFiles common.Paths
|
||||
|
||||
Cflags, ReexportedCflags []string
|
||||
|
||||
CrtBegin, CrtEnd common.OptionalPath
|
||||
}
|
||||
|
||||
type CCFlags struct {
|
||||
GlobalFlags []string // Flags that apply to C, C++, and assembly source files
|
||||
AsFlags []string // Flags that apply to assembly source files
|
||||
@@ -440,7 +452,7 @@ func (c *CCBase) depsMutator(ctx common.AndroidBottomUpMutatorContext) {
|
||||
|
||||
ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.savedDepNames.SharedLibs...)
|
||||
|
||||
ctx.AddDependency(ctx.Module(), c.savedDepNames.ObjFiles...)
|
||||
ctx.AddDependency(ctx.Module(), c.savedDepNames.ObjFiles.Strings()...)
|
||||
if c.savedDepNames.CrtBegin != "" {
|
||||
ctx.AddDependency(ctx.Module(), c.savedDepNames.CrtBegin)
|
||||
}
|
||||
@@ -472,17 +484,14 @@ func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
|
||||
}
|
||||
|
||||
// Include dir cflags
|
||||
common.CheckSrcDirsExist(ctx, c.Properties.Include_dirs, "include_dirs")
|
||||
common.CheckModuleSrcDirsExist(ctx, c.Properties.Local_include_dirs, "local_include_dirs")
|
||||
|
||||
rootIncludeDirs := pathtools.PrefixPaths(c.Properties.Include_dirs, ctx.AConfig().SrcDir())
|
||||
localIncludeDirs := pathtools.PrefixPaths(c.Properties.Local_include_dirs, common.ModuleSrcDir(ctx))
|
||||
rootIncludeDirs := common.PathsForSource(ctx, c.Properties.Include_dirs)
|
||||
localIncludeDirs := common.PathsForModuleSrc(ctx, c.Properties.Local_include_dirs)
|
||||
flags.GlobalFlags = append(flags.GlobalFlags,
|
||||
includeDirsToFlags(localIncludeDirs),
|
||||
includeDirsToFlags(rootIncludeDirs))
|
||||
|
||||
rootIncludeFiles := pathtools.PrefixPaths(c.Properties.Include_files, ctx.AConfig().SrcDir())
|
||||
localIncludeFiles := pathtools.PrefixPaths(c.Properties.Local_include_files, common.ModuleSrcDir(ctx))
|
||||
rootIncludeFiles := common.PathsForSource(ctx, c.Properties.Include_files)
|
||||
localIncludeFiles := common.PathsForModuleSrc(ctx, c.Properties.Local_include_files)
|
||||
|
||||
flags.GlobalFlags = append(flags.GlobalFlags,
|
||||
includeFilesToFlags(rootIncludeFiles),
|
||||
@@ -493,13 +502,13 @@ func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
|
||||
flags.GlobalFlags = append(flags.GlobalFlags,
|
||||
"${commonGlobalIncludes}",
|
||||
toolchain.IncludeFlags(),
|
||||
"-I${SrcDir}/libnativehelper/include/nativehelper")
|
||||
"-I"+common.PathForSource(ctx, "libnativehelper/include/nativehelper").String())
|
||||
}
|
||||
|
||||
flags.GlobalFlags = append(flags.GlobalFlags, []string{
|
||||
"-I" + common.ModuleSrcDir(ctx),
|
||||
"-I" + common.ModuleOutDir(ctx),
|
||||
"-I" + common.ModuleGenDir(ctx),
|
||||
"-I" + common.PathForModuleSrc(ctx).String(),
|
||||
"-I" + common.PathForModuleOut(ctx).String(),
|
||||
"-I" + common.PathForModuleGen(ctx).String(),
|
||||
}...)
|
||||
}
|
||||
|
||||
@@ -636,18 +645,18 @@ func (c *CCBase) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
|
||||
|
||||
// Compile a list of source files into objects a specified subdirectory
|
||||
func (c *CCBase) customCompileObjs(ctx common.AndroidModuleContext, flags CCFlags,
|
||||
subdir string, srcFiles, excludes []string) []string {
|
||||
subdir string, srcFiles, excludes []string) common.Paths {
|
||||
|
||||
buildFlags := ccFlagsToBuilderFlags(flags)
|
||||
|
||||
srcFiles = ctx.ExpandSources(srcFiles, excludes)
|
||||
srcFiles, deps := genSources(ctx, srcFiles, buildFlags)
|
||||
inputFiles := ctx.ExpandSources(srcFiles, excludes)
|
||||
srcPaths, deps := genSources(ctx, inputFiles, buildFlags)
|
||||
|
||||
return TransformSourceToObj(ctx, subdir, srcFiles, buildFlags, deps)
|
||||
return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps)
|
||||
}
|
||||
|
||||
// Compile files listed in c.Properties.Srcs into objects
|
||||
func (c *CCBase) compileObjs(ctx common.AndroidModuleContext, flags CCFlags) []string {
|
||||
func (c *CCBase) compileObjs(ctx common.AndroidModuleContext, flags CCFlags) common.Paths {
|
||||
|
||||
if c.Properties.SkipCompileObjs {
|
||||
return nil
|
||||
@@ -657,8 +666,8 @@ func (c *CCBase) compileObjs(ctx common.AndroidModuleContext, flags CCFlags) []s
|
||||
}
|
||||
|
||||
// Compile generated source files from dependencies
|
||||
func (c *CCBase) compileGeneratedObjs(ctx common.AndroidModuleContext, flags CCFlags) []string {
|
||||
var srcs []string
|
||||
func (c *CCBase) compileGeneratedObjs(ctx common.AndroidModuleContext, flags CCFlags) common.Paths {
|
||||
var srcs common.Paths
|
||||
|
||||
if c.Properties.SkipCompileObjs {
|
||||
return nil
|
||||
@@ -677,13 +686,13 @@ func (c *CCBase) compileGeneratedObjs(ctx common.AndroidModuleContext, flags CCF
|
||||
return TransformSourceToObj(ctx, "", srcs, ccFlagsToBuilderFlags(flags), nil)
|
||||
}
|
||||
|
||||
func (c *CCBase) outputFile() string {
|
||||
return ""
|
||||
func (c *CCBase) outputFile() common.OptionalPath {
|
||||
return common.OptionalPath{}
|
||||
}
|
||||
|
||||
func (c *CCBase) depsToPathsFromList(ctx common.AndroidModuleContext,
|
||||
names []string) (modules []common.AndroidModule,
|
||||
outputFiles []string, exportedFlags []string) {
|
||||
outputFiles common.Paths, exportedFlags []string) {
|
||||
|
||||
for _, n := range names {
|
||||
found := false
|
||||
@@ -707,12 +716,12 @@ func (c *CCBase) depsToPathsFromList(ctx common.AndroidModuleContext,
|
||||
return
|
||||
}
|
||||
|
||||
if outputFile := a.outputFile(); outputFile != "" {
|
||||
if outputFile := a.outputFile(); outputFile.Valid() {
|
||||
if found {
|
||||
ctx.ModuleErrorf("multiple modules satisified dependency on %q", otherName)
|
||||
return
|
||||
}
|
||||
outputFiles = append(outputFiles, outputFile)
|
||||
outputFiles = append(outputFiles, outputFile.Path())
|
||||
modules = append(modules, a)
|
||||
if i, ok := a.(ccExportedFlagsProducer); ok {
|
||||
exportedFlags = append(exportedFlags, i.exportedFlags()...)
|
||||
@@ -735,10 +744,10 @@ func (c *CCBase) depsToPathsFromList(ctx common.AndroidModuleContext,
|
||||
return modules, outputFiles, exportedFlags
|
||||
}
|
||||
|
||||
// Convert depenedency names to paths. Takes a CCDeps containing names and returns a CCDeps
|
||||
// Convert dependency names to paths. Takes a CCDeps containing names and returns a CCPathDeps
|
||||
// containing paths
|
||||
func (c *CCBase) depsToPaths(ctx common.AndroidModuleContext, depNames CCDeps) CCDeps {
|
||||
var depPaths CCDeps
|
||||
func (c *CCBase) depsToPaths(ctx common.AndroidModuleContext, depNames CCDeps) CCPathDeps {
|
||||
var depPaths CCPathDeps
|
||||
var newCflags []string
|
||||
|
||||
var wholeStaticLibModules []common.AndroidModule
|
||||
@@ -778,7 +787,12 @@ func (c *CCBase) depsToPaths(ctx common.AndroidModuleContext, depNames CCDeps) C
|
||||
depPaths.CrtEnd = obj.object().outputFile()
|
||||
}
|
||||
} else {
|
||||
depPaths.ObjFiles = append(depPaths.ObjFiles, obj.object().outputFile())
|
||||
output := obj.object().outputFile()
|
||||
if output.Valid() {
|
||||
depPaths.ObjFiles = append(depPaths.ObjFiles, output.Path())
|
||||
} else {
|
||||
ctx.ModuleErrorf("module %s did not provide an output file", otherName)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -908,11 +922,11 @@ func (c *CCLinked) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags
|
||||
// tree is in good enough shape to not need it.
|
||||
// Host builds will use GNU libstdc++.
|
||||
if ctx.Device() {
|
||||
flags.CFlags = append(flags.CFlags, "-I${SrcDir}/bionic/libstdc++/include")
|
||||
flags.CFlags = append(flags.CFlags, "-I"+common.PathForSource(ctx, "bionic/libstdc++/include").String())
|
||||
}
|
||||
case "ndk_system":
|
||||
ndkSrcRoot := ctx.AConfig().SrcDir() + "/prebuilts/ndk/current/sources/"
|
||||
flags.CFlags = append(flags.CFlags, "-isystem "+ndkSrcRoot+"cxx-stl/system/include")
|
||||
ndkSrcRoot := common.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include")
|
||||
flags.CFlags = append(flags.CFlags, "-isystem "+ndkSrcRoot.String())
|
||||
case "ndk_libc++_shared", "ndk_libc++_static":
|
||||
// TODO(danalbert): This really shouldn't be here...
|
||||
flags.CppFlags = append(flags.CppFlags, "-std=c++11")
|
||||
@@ -1067,23 +1081,23 @@ type CCLibraryProperties struct {
|
||||
} `android:"arch_variant"`
|
||||
|
||||
// local file name to pass to the linker as --version_script
|
||||
Version_script string `android:"arch_variant"`
|
||||
Version_script *string `android:"arch_variant"`
|
||||
// local file name to pass to the linker as -unexported_symbols_list
|
||||
Unexported_symbols_list string `android:"arch_variant"`
|
||||
Unexported_symbols_list *string `android:"arch_variant"`
|
||||
// local file name to pass to the linker as -force_symbols_not_weak_list
|
||||
Force_symbols_not_weak_list string `android:"arch_variant"`
|
||||
Force_symbols_not_weak_list *string `android:"arch_variant"`
|
||||
// local file name to pass to the linker as -force_symbols_weak_list
|
||||
Force_symbols_weak_list string `android:"arch_variant"`
|
||||
Force_symbols_weak_list *string `android:"arch_variant"`
|
||||
}
|
||||
|
||||
type CCLibrary struct {
|
||||
CCLinked
|
||||
|
||||
reuseFrom ccLibraryInterface
|
||||
reuseObjFiles []string
|
||||
objFiles []string
|
||||
reuseObjFiles common.Paths
|
||||
objFiles common.Paths
|
||||
exportFlags []string
|
||||
out string
|
||||
out common.Path
|
||||
systemLibs []string
|
||||
|
||||
LibraryProperties CCLibraryProperties
|
||||
@@ -1102,8 +1116,8 @@ type ccLibraryInterface interface {
|
||||
ccLibrary() *CCLibrary
|
||||
setReuseFrom(ccLibraryInterface)
|
||||
getReuseFrom() ccLibraryInterface
|
||||
getReuseObjFiles() []string
|
||||
allObjFiles() []string
|
||||
getReuseObjFiles() common.Paths
|
||||
allObjFiles() common.Paths
|
||||
}
|
||||
|
||||
var _ ccLibraryInterface = (*CCLibrary)(nil)
|
||||
@@ -1154,11 +1168,11 @@ func (c *CCLibrary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCD
|
||||
return depNames
|
||||
}
|
||||
|
||||
func (c *CCLibrary) outputFile() string {
|
||||
return c.out
|
||||
func (c *CCLibrary) outputFile() common.OptionalPath {
|
||||
return common.OptionalPathForPath(c.out)
|
||||
}
|
||||
|
||||
func (c *CCLibrary) getReuseObjFiles() []string {
|
||||
func (c *CCLibrary) getReuseObjFiles() common.Paths {
|
||||
return c.reuseObjFiles
|
||||
}
|
||||
|
||||
@@ -1170,7 +1184,7 @@ func (c *CCLibrary) getReuseFrom() ccLibraryInterface {
|
||||
return c.reuseFrom
|
||||
}
|
||||
|
||||
func (c *CCLibrary) allObjFiles() []string {
|
||||
func (c *CCLibrary) allObjFiles() common.Paths {
|
||||
return c.objFiles
|
||||
}
|
||||
|
||||
@@ -1225,7 +1239,7 @@ func (c *CCLibrary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlag
|
||||
}
|
||||
|
||||
func (c *CCLibrary) compileStaticLibrary(ctx common.AndroidModuleContext,
|
||||
flags CCFlags, deps CCDeps, objFiles []string) {
|
||||
flags CCFlags, deps CCPathDeps, objFiles common.Paths) {
|
||||
|
||||
staticFlags := flags
|
||||
objFilesStatic := c.customCompileObjs(ctx, staticFlags, common.DeviceStaticLibrary,
|
||||
@@ -1234,7 +1248,7 @@ func (c *CCLibrary) compileStaticLibrary(ctx common.AndroidModuleContext,
|
||||
objFiles = append(objFiles, objFilesStatic...)
|
||||
objFiles = append(objFiles, deps.WholeStaticLibObjFiles...)
|
||||
|
||||
outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+staticLibraryExtension)
|
||||
outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+staticLibraryExtension)
|
||||
|
||||
if ctx.Darwin() {
|
||||
TransformDarwinObjToStaticLib(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
|
||||
@@ -1245,8 +1259,7 @@ func (c *CCLibrary) compileStaticLibrary(ctx common.AndroidModuleContext,
|
||||
c.objFiles = objFiles
|
||||
c.out = outputFile
|
||||
|
||||
common.CheckModuleSrcDirsExist(ctx, c.Properties.Export_include_dirs, "export_include_dirs")
|
||||
includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
|
||||
includeDirs := common.PathsForModuleSrc(ctx, c.Properties.Export_include_dirs)
|
||||
c.exportFlags = []string{includeDirsToFlags(includeDirs)}
|
||||
c.exportFlags = append(c.exportFlags, deps.ReexportedCflags...)
|
||||
|
||||
@@ -1254,7 +1267,7 @@ func (c *CCLibrary) compileStaticLibrary(ctx common.AndroidModuleContext,
|
||||
}
|
||||
|
||||
func (c *CCLibrary) compileSharedLibrary(ctx common.AndroidModuleContext,
|
||||
flags CCFlags, deps CCDeps, objFiles []string) {
|
||||
flags CCFlags, deps CCPathDeps, objFiles common.Paths) {
|
||||
|
||||
sharedFlags := flags
|
||||
objFilesShared := c.customCompileObjs(ctx, sharedFlags, common.DeviceSharedLibrary,
|
||||
@@ -1262,43 +1275,43 @@ func (c *CCLibrary) compileSharedLibrary(ctx common.AndroidModuleContext,
|
||||
|
||||
objFiles = append(objFiles, objFilesShared...)
|
||||
|
||||
outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+flags.Toolchain.ShlibSuffix())
|
||||
outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+flags.Toolchain.ShlibSuffix())
|
||||
|
||||
var linkerDeps []string
|
||||
var linkerDeps common.Paths
|
||||
|
||||
versionScript := common.OptionalPathForModuleSrc(ctx, c.LibraryProperties.Version_script)
|
||||
unexportedSymbols := common.OptionalPathForModuleSrc(ctx, c.LibraryProperties.Unexported_symbols_list)
|
||||
forceNotWeakSymbols := common.OptionalPathForModuleSrc(ctx, c.LibraryProperties.Force_symbols_not_weak_list)
|
||||
forceWeakSymbols := common.OptionalPathForModuleSrc(ctx, c.LibraryProperties.Force_symbols_weak_list)
|
||||
if !ctx.Darwin() {
|
||||
if c.LibraryProperties.Version_script != "" {
|
||||
versionScript := filepath.Join(common.ModuleSrcDir(ctx), c.LibraryProperties.Version_script)
|
||||
sharedFlags.LdFlags = append(sharedFlags.LdFlags, "-Wl,--version-script,"+versionScript)
|
||||
linkerDeps = append(linkerDeps, versionScript)
|
||||
if versionScript.Valid() {
|
||||
sharedFlags.LdFlags = append(sharedFlags.LdFlags, "-Wl,--version-script,"+versionScript.String())
|
||||
linkerDeps = append(linkerDeps, versionScript.Path())
|
||||
}
|
||||
if c.LibraryProperties.Unexported_symbols_list != "" {
|
||||
if unexportedSymbols.Valid() {
|
||||
ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
|
||||
}
|
||||
if c.LibraryProperties.Force_symbols_not_weak_list != "" {
|
||||
if forceNotWeakSymbols.Valid() {
|
||||
ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
|
||||
}
|
||||
if c.LibraryProperties.Force_symbols_weak_list != "" {
|
||||
if forceWeakSymbols.Valid() {
|
||||
ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
|
||||
}
|
||||
} else {
|
||||
if c.LibraryProperties.Version_script != "" {
|
||||
if versionScript.Valid() {
|
||||
ctx.PropertyErrorf("version_script", "Not supported on Darwin")
|
||||
}
|
||||
if c.LibraryProperties.Unexported_symbols_list != "" {
|
||||
localFile := filepath.Join(common.ModuleSrcDir(ctx), c.LibraryProperties.Unexported_symbols_list)
|
||||
sharedFlags.LdFlags = append(sharedFlags.LdFlags, "-Wl,-unexported_symbols_list,"+localFile)
|
||||
linkerDeps = append(linkerDeps, localFile)
|
||||
if unexportedSymbols.Valid() {
|
||||
sharedFlags.LdFlags = append(sharedFlags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
|
||||
linkerDeps = append(linkerDeps, unexportedSymbols.Path())
|
||||
}
|
||||
if c.LibraryProperties.Force_symbols_not_weak_list != "" {
|
||||
localFile := filepath.Join(common.ModuleSrcDir(ctx), c.LibraryProperties.Force_symbols_not_weak_list)
|
||||
sharedFlags.LdFlags = append(sharedFlags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+localFile)
|
||||
linkerDeps = append(linkerDeps, localFile)
|
||||
if forceNotWeakSymbols.Valid() {
|
||||
sharedFlags.LdFlags = append(sharedFlags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
|
||||
linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
|
||||
}
|
||||
if c.LibraryProperties.Force_symbols_weak_list != "" {
|
||||
localFile := filepath.Join(common.ModuleSrcDir(ctx), c.LibraryProperties.Force_symbols_weak_list)
|
||||
sharedFlags.LdFlags = append(sharedFlags.LdFlags, "-Wl,-force_symbols_weak_list,"+localFile)
|
||||
linkerDeps = append(linkerDeps, localFile)
|
||||
if forceWeakSymbols.Valid() {
|
||||
sharedFlags.LdFlags = append(sharedFlags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
|
||||
linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1307,13 +1320,13 @@ func (c *CCLibrary) compileSharedLibrary(ctx common.AndroidModuleContext,
|
||||
ccFlagsToBuilderFlags(sharedFlags), outputFile)
|
||||
|
||||
c.out = outputFile
|
||||
includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
|
||||
includeDirs := common.PathsForModuleSrc(ctx, c.Properties.Export_include_dirs)
|
||||
c.exportFlags = []string{includeDirsToFlags(includeDirs)}
|
||||
c.exportFlags = append(c.exportFlags, deps.ReexportedCflags...)
|
||||
}
|
||||
|
||||
func (c *CCLibrary) compileModule(ctx common.AndroidModuleContext,
|
||||
flags CCFlags, deps CCDeps, objFiles []string) {
|
||||
flags CCFlags, deps CCPathDeps, objFiles common.Paths) {
|
||||
|
||||
// Reuse the object files from the matching static library if it exists
|
||||
if c.getReuseFrom().ccLibrary() == c {
|
||||
@@ -1321,7 +1334,7 @@ func (c *CCLibrary) compileModule(ctx common.AndroidModuleContext,
|
||||
} else {
|
||||
if c.getReuseFrom().ccLibrary().LibraryProperties.Static.Cflags == nil &&
|
||||
c.LibraryProperties.Shared.Cflags == nil {
|
||||
objFiles = append([]string(nil), c.getReuseFrom().getReuseObjFiles()...)
|
||||
objFiles = append(common.Paths(nil), c.getReuseFrom().getReuseObjFiles()...)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1363,7 +1376,7 @@ type ccObjectProvider interface {
|
||||
|
||||
type ccObject struct {
|
||||
CCBase
|
||||
out string
|
||||
out common.OptionalPath
|
||||
}
|
||||
|
||||
func (c *ccObject) object() *ccObject {
|
||||
@@ -1382,19 +1395,20 @@ func (*ccObject) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps
|
||||
}
|
||||
|
||||
func (c *ccObject) compileModule(ctx common.AndroidModuleContext,
|
||||
flags CCFlags, deps CCDeps, objFiles []string) {
|
||||
flags CCFlags, deps CCPathDeps, objFiles common.Paths) {
|
||||
|
||||
objFiles = append(objFiles, deps.ObjFiles...)
|
||||
|
||||
var outputFile string
|
||||
var outputFile common.Path
|
||||
if len(objFiles) == 1 {
|
||||
outputFile = objFiles[0]
|
||||
} else {
|
||||
outputFile = filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+objectExtension)
|
||||
TransformObjsToObj(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
|
||||
output := common.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension)
|
||||
TransformObjsToObj(ctx, objFiles, ccFlagsToBuilderFlags(flags), output)
|
||||
outputFile = output
|
||||
}
|
||||
|
||||
c.out = outputFile
|
||||
c.out = common.OptionalPathForPath(outputFile)
|
||||
|
||||
ctx.CheckbuildFile(outputFile)
|
||||
}
|
||||
@@ -1403,7 +1417,7 @@ func (c *ccObject) installModule(ctx common.AndroidModuleContext, flags CCFlags)
|
||||
// Object files do not get installed.
|
||||
}
|
||||
|
||||
func (c *ccObject) outputFile() string {
|
||||
func (c *ccObject) outputFile() common.OptionalPath {
|
||||
return c.out
|
||||
}
|
||||
|
||||
@@ -1433,8 +1447,8 @@ type CCBinaryProperties struct {
|
||||
|
||||
type CCBinary struct {
|
||||
CCLinked
|
||||
out string
|
||||
installFile string
|
||||
out common.Path
|
||||
installFile common.Path
|
||||
BinaryProperties CCBinaryProperties
|
||||
}
|
||||
|
||||
@@ -1569,23 +1583,23 @@ func (c *CCBinary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags
|
||||
}
|
||||
|
||||
func (c *CCBinary) compileModule(ctx common.AndroidModuleContext,
|
||||
flags CCFlags, deps CCDeps, objFiles []string) {
|
||||
flags CCFlags, deps CCPathDeps, objFiles common.Paths) {
|
||||
|
||||
if !Bool(c.BinaryProperties.Static_executable) && inList("libc", c.Properties.Static_libs) {
|
||||
ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
|
||||
"from static libs or set static_executable: true")
|
||||
}
|
||||
|
||||
outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx)+flags.Toolchain.ExecutableSuffix())
|
||||
outputFile := common.PathForModuleOut(ctx, c.getStem(ctx)+flags.Toolchain.ExecutableSuffix())
|
||||
c.out = outputFile
|
||||
if c.BinaryProperties.Prefix_symbols != "" {
|
||||
afterPrefixSymbols := outputFile
|
||||
outputFile = outputFile + ".intermediate"
|
||||
outputFile = common.PathForModuleOut(ctx, c.getStem(ctx)+".intermediate")
|
||||
TransformBinaryPrefixSymbols(ctx, c.BinaryProperties.Prefix_symbols, outputFile,
|
||||
ccFlagsToBuilderFlags(flags), afterPrefixSymbols)
|
||||
}
|
||||
|
||||
var linkerDeps []string
|
||||
var linkerDeps common.Paths
|
||||
|
||||
TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
|
||||
deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
|
||||
@@ -1596,11 +1610,11 @@ func (c *CCBinary) installModule(ctx common.AndroidModuleContext, flags CCFlags)
|
||||
c.installFile = ctx.InstallFile(filepath.Join("bin", c.Properties.Relative_install_path), c.out)
|
||||
}
|
||||
|
||||
func (c *CCBinary) HostToolPath() string {
|
||||
func (c *CCBinary) HostToolPath() common.OptionalPath {
|
||||
if c.HostOrDevice().Host() {
|
||||
return c.installFile
|
||||
return common.OptionalPathForPath(c.installFile)
|
||||
}
|
||||
return ""
|
||||
return common.OptionalPath{}
|
||||
}
|
||||
|
||||
func (c *CCBinary) testPerSrc() bool {
|
||||
@@ -1649,7 +1663,7 @@ func (c *CCTest) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
|
||||
|
||||
// TODO(danalbert): Make gtest export its dependencies.
|
||||
flags.CFlags = append(flags.CFlags,
|
||||
"-I"+filepath.Join(ctx.AConfig().SrcDir(), "external/gtest/include"))
|
||||
"-I"+common.PathForSource(ctx, "external/gtest/include").String())
|
||||
|
||||
return flags
|
||||
}
|
||||
@@ -1832,10 +1846,10 @@ func ToolchainLibraryFactory() (blueprint.Module, []interface{}) {
|
||||
}
|
||||
|
||||
func (c *toolchainLibrary) compileModule(ctx common.AndroidModuleContext,
|
||||
flags CCFlags, deps CCDeps, objFiles []string) {
|
||||
flags CCFlags, deps CCPathDeps, objFiles common.Paths) {
|
||||
|
||||
libName := ctx.ModuleName() + staticLibraryExtension
|
||||
outputFile := filepath.Join(common.ModuleOutDir(ctx), libName)
|
||||
outputFile := common.PathForModuleOut(ctx, libName)
|
||||
|
||||
CopyGccLib(ctx, libName, ccFlagsToBuilderFlags(flags), outputFile)
|
||||
|
||||
@@ -1854,19 +1868,19 @@ func (c *toolchainLibrary) installModule(ctx common.AndroidModuleContext, flags
|
||||
// either (with the exception of the shared STLs, which are installed to the app's directory rather
|
||||
// than to the system image).
|
||||
|
||||
func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) string {
|
||||
return fmt.Sprintf("%s/prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
|
||||
ctx.AConfig().SrcDir(), version, toolchain.Name())
|
||||
func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) common.SourcePath {
|
||||
return common.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
|
||||
version, toolchain.Name()))
|
||||
}
|
||||
|
||||
func ndkPrebuiltModuleToPath(ctx common.AndroidModuleContext, toolchain Toolchain,
|
||||
ext string, version string) string {
|
||||
ext string, version string) common.Path {
|
||||
|
||||
// NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
|
||||
// We want to translate to just NAME.EXT
|
||||
name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
|
||||
dir := getNdkLibDir(ctx, toolchain, version)
|
||||
return filepath.Join(dir, name+ext)
|
||||
return dir.Join(ctx, name+ext)
|
||||
}
|
||||
|
||||
type ndkPrebuiltObject struct {
|
||||
@@ -1884,13 +1898,13 @@ func NdkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
|
||||
}
|
||||
|
||||
func (c *ndkPrebuiltObject) compileModule(ctx common.AndroidModuleContext, flags CCFlags,
|
||||
deps CCDeps, objFiles []string) {
|
||||
deps CCPathDeps, objFiles common.Paths) {
|
||||
// A null build step, but it sets up the output path.
|
||||
if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") {
|
||||
ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
|
||||
}
|
||||
|
||||
c.out = ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, c.Properties.Sdk_version)
|
||||
c.out = common.OptionalPathForPath(ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, c.Properties.Sdk_version))
|
||||
}
|
||||
|
||||
func (c *ndkPrebuiltObject) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
|
||||
@@ -1915,14 +1929,14 @@ func NdkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
|
||||
}
|
||||
|
||||
func (c *ndkPrebuiltLibrary) compileModule(ctx common.AndroidModuleContext, flags CCFlags,
|
||||
deps CCDeps, objFiles []string) {
|
||||
deps CCPathDeps, objFiles common.Paths) {
|
||||
// A null build step, but it sets up the output path.
|
||||
if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
|
||||
ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
|
||||
}
|
||||
|
||||
includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
|
||||
c.exportFlags = []string{common.JoinWithPrefix(includeDirs, "-isystem ")}
|
||||
includeDirs := common.PathsForModuleSrc(ctx, c.Properties.Export_include_dirs)
|
||||
c.exportFlags = []string{common.JoinWithPrefix(includeDirs.Strings(), "-isystem ")}
|
||||
|
||||
c.out = ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
|
||||
c.Properties.Sdk_version)
|
||||
@@ -1960,7 +1974,7 @@ func NdkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
|
||||
return NewCCLibrary(&module.CCLibrary, module, common.DeviceSupported)
|
||||
}
|
||||
|
||||
func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) string {
|
||||
func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) common.SourcePath {
|
||||
gccVersion := toolchain.GccVersion()
|
||||
var libDir string
|
||||
switch stl {
|
||||
@@ -1973,22 +1987,22 @@ func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl s
|
||||
}
|
||||
|
||||
if libDir != "" {
|
||||
ndkSrcRoot := ctx.AConfig().SrcDir() + "/prebuilts/ndk/current/sources"
|
||||
return fmt.Sprintf("%s/%s/%s", ndkSrcRoot, libDir, ctx.Arch().Abi)
|
||||
ndkSrcRoot := "prebuilts/ndk/current/sources"
|
||||
return common.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0])
|
||||
}
|
||||
|
||||
ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
|
||||
return ""
|
||||
return common.PathForSource(ctx, "")
|
||||
}
|
||||
|
||||
func (c *ndkPrebuiltStl) compileModule(ctx common.AndroidModuleContext, flags CCFlags,
|
||||
deps CCDeps, objFiles []string) {
|
||||
deps CCPathDeps, objFiles common.Paths) {
|
||||
// A null build step, but it sets up the output path.
|
||||
if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
|
||||
ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
|
||||
}
|
||||
|
||||
includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
|
||||
includeDirs := common.PathsForModuleSrc(ctx, c.Properties.Export_include_dirs)
|
||||
c.exportFlags = []string{includeDirsToFlags(includeDirs)}
|
||||
|
||||
libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
|
||||
@@ -2000,7 +2014,7 @@ func (c *ndkPrebuiltStl) compileModule(ctx common.AndroidModuleContext, flags CC
|
||||
stlName := strings.TrimSuffix(libName, "_shared")
|
||||
stlName = strings.TrimSuffix(stlName, "_static")
|
||||
libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
|
||||
c.out = libDir + "/" + libName + libExt
|
||||
c.out = libDir.Join(ctx, libName+libExt)
|
||||
}
|
||||
|
||||
func linkageMutator(mctx common.AndroidBottomUpMutatorContext) {
|
||||
|
51
cc/gen.go
51
cc/gen.go
@@ -19,18 +19,15 @@ package cc
|
||||
// functions.
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
|
||||
"android/soong/common"
|
||||
)
|
||||
|
||||
func init() {
|
||||
pctx.StaticVariable("lexCmd", "${SrcDir}/prebuilts/misc/${HostPrebuiltTag}/flex/flex-2.5.39")
|
||||
pctx.StaticVariable("yaccCmd", "${SrcDir}/prebuilts/misc/${HostPrebuiltTag}/bison/bison")
|
||||
pctx.StaticVariable("yaccDataDir", "${SrcDir}/external/bison/data")
|
||||
pctx.SourcePathVariable("lexCmd", "prebuilts/misc/${HostPrebuiltTag}/flex/flex-2.5.39")
|
||||
pctx.SourcePathVariable("yaccCmd", "prebuilts/misc/${HostPrebuiltTag}/bison/bison")
|
||||
pctx.SourcePathVariable("yaccDataDir", "external/bison/data")
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -51,49 +48,45 @@ var (
|
||||
})
|
||||
)
|
||||
|
||||
func genYacc(ctx common.AndroidModuleContext, yaccFile, yaccFlags string) (cppFile, headerFile string) {
|
||||
cppFile = common.SrcDirRelPath(ctx, yaccFile)
|
||||
cppFile = filepath.Join(common.ModuleGenDir(ctx), cppFile)
|
||||
cppFile = pathtools.ReplaceExtension(cppFile, "cpp")
|
||||
hppFile := pathtools.ReplaceExtension(cppFile, "hpp")
|
||||
headerFile = pathtools.ReplaceExtension(cppFile, "h")
|
||||
func genYacc(ctx common.AndroidModuleContext, yaccFile common.Path, yaccFlags string) (cppFile, headerFile common.ModuleGenPath) {
|
||||
cppFile = common.GenPathWithExt(ctx, yaccFile, "cpp")
|
||||
hppFile := common.GenPathWithExt(ctx, yaccFile, "hpp")
|
||||
headerFile = common.GenPathWithExt(ctx, yaccFile, "h")
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: yacc,
|
||||
Outputs: []string{cppFile, headerFile},
|
||||
Inputs: []string{yaccFile},
|
||||
Outputs: common.WritablePaths{cppFile, headerFile},
|
||||
Input: yaccFile,
|
||||
Args: map[string]string{
|
||||
"yaccFlags": yaccFlags,
|
||||
"cppFile": cppFile,
|
||||
"hppFile": hppFile,
|
||||
"hFile": headerFile,
|
||||
"cppFile": cppFile.String(),
|
||||
"hppFile": hppFile.String(),
|
||||
"hFile": headerFile.String(),
|
||||
},
|
||||
})
|
||||
|
||||
return cppFile, headerFile
|
||||
}
|
||||
|
||||
func genLex(ctx common.AndroidModuleContext, lexFile string) (cppFile string) {
|
||||
cppFile = common.SrcDirRelPath(ctx, lexFile)
|
||||
cppFile = filepath.Join(common.ModuleGenDir(ctx), cppFile)
|
||||
cppFile = pathtools.ReplaceExtension(cppFile, "cpp")
|
||||
func genLex(ctx common.AndroidModuleContext, lexFile common.Path) (cppFile common.ModuleGenPath) {
|
||||
cppFile = common.GenPathWithExt(ctx, lexFile, "cpp")
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: lex,
|
||||
Outputs: []string{cppFile},
|
||||
Inputs: []string{lexFile},
|
||||
Output: cppFile,
|
||||
Input: lexFile,
|
||||
})
|
||||
|
||||
return cppFile
|
||||
}
|
||||
|
||||
func genSources(ctx common.AndroidModuleContext, srcFiles []string,
|
||||
buildFlags builderFlags) ([]string, []string) {
|
||||
func genSources(ctx common.AndroidModuleContext, srcFiles common.Paths,
|
||||
buildFlags builderFlags) (common.Paths, common.Paths) {
|
||||
|
||||
var deps []string
|
||||
var deps common.Paths
|
||||
|
||||
for i, srcFile := range srcFiles {
|
||||
switch filepath.Ext(srcFile) {
|
||||
switch srcFile.Ext() {
|
||||
case ".y", ".yy":
|
||||
cppFile, headerFile := genYacc(ctx, srcFile, buildFlags.yaccFlags)
|
||||
srcFiles[i] = cppFile
|
||||
|
@@ -90,7 +90,7 @@ func init() {
|
||||
|
||||
pctx.StaticVariable("mips64GccVersion", mips64GccVersion)
|
||||
|
||||
pctx.StaticVariable("mips64GccRoot",
|
||||
pctx.SourcePathVariable("mips64GccRoot",
|
||||
"prebuilts/gcc/${HostPrebuiltTag}/mips/mips64el-linux-android-${mips64GccVersion}")
|
||||
|
||||
pctx.StaticVariable("mips64GccTriple", "mips64el-linux-android")
|
||||
|
@@ -121,7 +121,7 @@ func init() {
|
||||
|
||||
pctx.StaticVariable("mipsGccVersion", mipsGccVersion)
|
||||
|
||||
pctx.StaticVariable("mipsGccRoot",
|
||||
pctx.SourcePathVariable("mipsGccRoot",
|
||||
"prebuilts/gcc/${HostPrebuiltTag}/mips/mips64el-linux-android-${mipsGccVersion}")
|
||||
|
||||
pctx.StaticVariable("mipsGccTriple", "mips64el-linux-android")
|
||||
|
@@ -24,12 +24,12 @@ import (
|
||||
|
||||
// Efficiently converts a list of include directories to a single string
|
||||
// of cflags with -I prepended to each directory.
|
||||
func includeDirsToFlags(dirs []string) string {
|
||||
return common.JoinWithPrefix(dirs, "-I")
|
||||
func includeDirsToFlags(dirs common.Paths) string {
|
||||
return common.JoinWithPrefix(dirs.Strings(), "-I")
|
||||
}
|
||||
|
||||
func includeFilesToFlags(dirs []string) string {
|
||||
return common.JoinWithPrefix(dirs, "-include ")
|
||||
func includeFilesToFlags(files common.Paths) string {
|
||||
return common.JoinWithPrefix(files.Strings(), "-include ")
|
||||
}
|
||||
|
||||
func ldDirsToFlags(dirs []string) string {
|
||||
|
@@ -137,7 +137,7 @@ func init() {
|
||||
|
||||
pctx.StaticVariable("x86_64GccVersion", x86_64GccVersion)
|
||||
|
||||
pctx.StaticVariable("x86_64GccRoot",
|
||||
pctx.SourcePathVariable("x86_64GccRoot",
|
||||
"prebuilts/gcc/${HostPrebuiltTag}/x86/x86_64-linux-android-${x86_64GccVersion}")
|
||||
|
||||
pctx.StaticVariable("x86_64GccTriple", "x86_64-linux-android")
|
||||
|
@@ -83,8 +83,8 @@ func init() {
|
||||
pctx.StaticVariable("macSdkRoot", "${macSdkPath}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk")
|
||||
|
||||
pctx.StaticVariable("darwinGccVersion", darwinGccVersion)
|
||||
pctx.StaticVariable("darwinGccRoot",
|
||||
"${SrcDir}/prebuilts/gcc/${HostPrebuiltTag}/host/i686-apple-darwin-${darwinGccVersion}")
|
||||
pctx.SourcePathVariable("darwinGccRoot",
|
||||
"prebuilts/gcc/${HostPrebuiltTag}/host/i686-apple-darwin-${darwinGccVersion}")
|
||||
|
||||
pctx.StaticVariable("darwinGccTriple", "i686-apple-darwin11")
|
||||
|
||||
|
@@ -139,7 +139,7 @@ func init() {
|
||||
|
||||
pctx.StaticVariable("x86GccVersion", x86GccVersion)
|
||||
|
||||
pctx.StaticVariable("x86GccRoot",
|
||||
pctx.SourcePathVariable("x86GccRoot",
|
||||
"prebuilts/gcc/${HostPrebuiltTag}/x86/x86_64-linux-android-${x86GccVersion}")
|
||||
|
||||
pctx.StaticVariable("x86GccTriple", "x86_64-linux-android")
|
||||
|
@@ -108,8 +108,8 @@ const (
|
||||
func init() {
|
||||
pctx.StaticVariable("linuxGccVersion", linuxGccVersion)
|
||||
|
||||
pctx.StaticVariable("linuxGccRoot",
|
||||
"${SrcDir}/prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-linux-glibc2.15-${linuxGccVersion}")
|
||||
pctx.SourcePathVariable("linuxGccRoot",
|
||||
"prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-linux-glibc2.15-${linuxGccVersion}")
|
||||
|
||||
pctx.StaticVariable("linuxGccTriple", "x86_64-linux")
|
||||
|
||||
|
@@ -68,8 +68,8 @@ const (
|
||||
func init() {
|
||||
pctx.StaticVariable("windowsGccVersion", windowsGccVersion)
|
||||
|
||||
pctx.StaticVariable("windowsGccRoot",
|
||||
"${SrcDir}/prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-w64-mingw32-${windowsGccVersion}")
|
||||
pctx.SourcePathVariable("windowsGccRoot",
|
||||
"prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-w64-mingw32-${windowsGccVersion}")
|
||||
|
||||
pctx.StaticVariable("windowsGccTriple", "x86_64-w64-mingw32")
|
||||
|
||||
|
@@ -37,11 +37,11 @@ type AndroidMkDataProvider interface {
|
||||
|
||||
type AndroidMkData struct {
|
||||
Class string
|
||||
OutputFile string
|
||||
OutputFile OptionalPath
|
||||
|
||||
Custom func(w io.Writer, name, prefix string)
|
||||
|
||||
Extra func(name, prefix, outputFile string, arch Arch) []string
|
||||
Extra func(name, prefix string, outputFile Path, arch Arch) []string
|
||||
}
|
||||
|
||||
func AndroidMkSingleton() blueprint.Singleton {
|
||||
@@ -55,7 +55,7 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext
|
||||
hasBPDir := make(map[string]bool)
|
||||
bpDirs := []string{}
|
||||
|
||||
ctx.SetNinjaBuildDir(pctx, filepath.Join(ctx.Config().(Config).BuildDir(), ".."))
|
||||
ctx.SetNinjaBuildDir(pctx, filepath.Join(ctx.Config().(Config).buildDir, ".."))
|
||||
|
||||
ctx.VisitAllModules(func(module blueprint.Module) {
|
||||
if _, ok := module.(AndroidModule); ok {
|
||||
@@ -72,30 +72,15 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext
|
||||
|
||||
// Gather list of eligible Android modules for translation
|
||||
androidMkModules := make(map[blueprint.Module]bool)
|
||||
srcDir := ctx.Config().(Config).SrcDir()
|
||||
intermediatesDir := filepath.Join(ctx.Config().(Config).IntermediatesDir(), "androidmk")
|
||||
sort.Strings(bpDirs)
|
||||
for _, bpDir := range bpDirs {
|
||||
mkFile := filepath.Join(srcDir, bpDir, "Android.mk")
|
||||
|
||||
files, err := Glob(ctx, intermediatesDir, mkFile, nil)
|
||||
if err != nil {
|
||||
ctx.Errorf("glob: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
// Existing Android.mk file, use that instead
|
||||
if len(files) > 0 {
|
||||
for _, file := range files {
|
||||
ctx.AddNinjaFileDeps(file)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
mkFile := OptionalPathForSource(ctx, "androidmk", bpDir, "Android.mk")
|
||||
if !mkFile.Valid() {
|
||||
for _, mod := range dirModules[bpDir] {
|
||||
androidMkModules[mod] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate that all modules have proper dependencies
|
||||
androidMkModulesList := make([]AndroidModule, 0, len(androidMkModules))
|
||||
@@ -110,16 +95,19 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext
|
||||
}
|
||||
}
|
||||
|
||||
transMk := filepath.Join(ctx.Config().(Config).BuildDir(), "Android.mk")
|
||||
transMk := PathForOutput(ctx, "Android.mk")
|
||||
if ctx.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
err := translateAndroidMk(ctx, transMk, androidMkModulesList)
|
||||
err := translateAndroidMk(ctx, transMk.String(), androidMkModulesList)
|
||||
if err != nil {
|
||||
ctx.Errorf(err.Error())
|
||||
}
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Outputs: []string{transMk},
|
||||
Outputs: []string{transMk.String()},
|
||||
Optional: true,
|
||||
})
|
||||
}
|
||||
@@ -177,7 +165,7 @@ func translateAndroidMkModule(ctx blueprint.SingletonContext, w io.Writer, mod b
|
||||
|
||||
type archSrc struct {
|
||||
arch Arch
|
||||
src string
|
||||
src Path
|
||||
extra []string
|
||||
}
|
||||
|
||||
@@ -211,6 +199,10 @@ func translateAndroidMkModule(ctx blueprint.SingletonContext, w io.Writer, mod b
|
||||
return
|
||||
}
|
||||
|
||||
if !data.OutputFile.Valid() {
|
||||
return
|
||||
}
|
||||
|
||||
hC := hostClass{
|
||||
host: amod.HostOrDevice() == Host,
|
||||
class: data.Class,
|
||||
@@ -219,7 +211,7 @@ func translateAndroidMkModule(ctx blueprint.SingletonContext, w io.Writer, mod b
|
||||
|
||||
src := archSrc{
|
||||
arch: arch,
|
||||
src: data.OutputFile,
|
||||
src: data.OutputFile.Path(),
|
||||
}
|
||||
|
||||
if data.Extra != nil {
|
||||
@@ -242,7 +234,7 @@ func translateAndroidMkModule(ctx blueprint.SingletonContext, w io.Writer, mod b
|
||||
|
||||
printed := make(map[string]bool)
|
||||
for _, src := range archSrcs {
|
||||
io.WriteString(w, "LOCAL_SRC_FILES_"+src.arch.ArchType.String()+" := "+src.src+"\n")
|
||||
io.WriteString(w, "LOCAL_SRC_FILES_"+src.arch.ArchType.String()+" := "+src.src.String()+"\n")
|
||||
|
||||
for _, extra := range src.extra {
|
||||
if !printed[extra] {
|
||||
|
@@ -20,6 +20,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@@ -38,8 +39,6 @@ func (f *FileConfigurableOptions) SetDefaultConfig() {
|
||||
|
||||
type Config struct {
|
||||
*config
|
||||
|
||||
dontCreateNinjaFile bool
|
||||
}
|
||||
|
||||
// A config object represents the entire build configuration for Android.
|
||||
@@ -142,8 +141,24 @@ func NewConfig(srcDir, buildDir string) (Config, error) {
|
||||
},
|
||||
}
|
||||
|
||||
// Sanity check the build and source directories. This won't catch strange
|
||||
// configurations with symlinks, but at least checks the obvious cases.
|
||||
absBuildDir, err := filepath.Abs(buildDir)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
absSrcDir, err := filepath.Abs(srcDir)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
if strings.HasPrefix(absSrcDir, absBuildDir) {
|
||||
return Config{}, fmt.Errorf("Build dir must not contain source directory")
|
||||
}
|
||||
|
||||
// Load any configurable options from the configuration file
|
||||
err := loadConfig(config.config)
|
||||
err = loadConfig(config.config)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
@@ -159,18 +174,6 @@ func NewConfig(srcDir, buildDir string) (Config, error) {
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func (c *config) SrcDir() string {
|
||||
return c.srcDir
|
||||
}
|
||||
|
||||
func (c *config) BuildDir() string {
|
||||
return c.buildDir
|
||||
}
|
||||
|
||||
func (c *config) IntermediatesDir() string {
|
||||
return filepath.Join(c.BuildDir(), ".intermediates")
|
||||
}
|
||||
|
||||
func (c *config) RemoveAbandonedFiles() bool {
|
||||
return false
|
||||
}
|
||||
@@ -238,37 +241,7 @@ func (c *config) DeviceUsesClang() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// DeviceOut returns the path to out directory for device targets
|
||||
func (c *config) DeviceOut() string {
|
||||
return filepath.Join(c.BuildDir(), "target/product", c.DeviceName())
|
||||
}
|
||||
|
||||
// HostOut returns the path to out directory for host targets
|
||||
func (c *config) HostOut() string {
|
||||
return filepath.Join(c.BuildDir(), "host", c.PrebuiltOS())
|
||||
}
|
||||
|
||||
// HostBin returns the path to bin directory for host targets
|
||||
func (c *config) HostBin() string {
|
||||
return filepath.Join(c.HostOut(), "bin")
|
||||
}
|
||||
|
||||
// HostBinTool returns the path to a host tool in the bin directory for host targets
|
||||
func (c *config) HostBinTool(tool string) (string, error) {
|
||||
return filepath.Join(c.HostBin(), tool), nil
|
||||
}
|
||||
|
||||
// HostJavaDir returns the path to framework directory for host targets
|
||||
func (c *config) HostJavaDir() string {
|
||||
return filepath.Join(c.HostOut(), "framework")
|
||||
}
|
||||
|
||||
// HostJavaTool returns the path to a host tool in the frameworks directory for host targets
|
||||
func (c *config) HostJavaTool(tool string) (string, error) {
|
||||
return filepath.Join(c.HostJavaDir(), tool), nil
|
||||
}
|
||||
|
||||
func (c *config) ResourceOverlays() []string {
|
||||
func (c *config) ResourceOverlays() []SourcePath {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -296,10 +269,10 @@ func (c *config) ProductAaptCharacteristics() string {
|
||||
return "nosdcard"
|
||||
}
|
||||
|
||||
func (c *config) DefaultAppCertificateDir() string {
|
||||
return filepath.Join(c.SrcDir(), "build/target/product/security")
|
||||
func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath {
|
||||
return PathForSource(ctx, "build/target/product/security")
|
||||
}
|
||||
|
||||
func (c *config) DefaultAppCertificate() string {
|
||||
return filepath.Join(c.DefaultAppCertificateDir(), "testkey")
|
||||
func (c *config) DefaultAppCertificate(ctx PathContext) SourcePath {
|
||||
return c.DefaultAppCertificateDir(ctx).Join(ctx, "testkey")
|
||||
}
|
||||
|
@@ -20,13 +20,11 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
pctx = blueprint.NewPackageContext("android/soong/common")
|
||||
pctx = NewPackageContext("android/soong/common")
|
||||
|
||||
cpPreserveSymlinks = pctx.VariableConfigMethod("cpPreserveSymlinks",
|
||||
Config.CpPreserveSymlinksFlags)
|
||||
|
||||
srcDir = pctx.VariableConfigMethod("srcDir", Config.SrcDir)
|
||||
|
||||
// A phony rule that is not the built-in Ninja phony rule. The built-in
|
||||
// phony rule has special behavior that is sometimes not desired. See the
|
||||
// Ninja docs for more details.
|
||||
|
@@ -15,8 +15,6 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"android/soong"
|
||||
"android/soong/env"
|
||||
|
||||
@@ -43,12 +41,15 @@ type envSingleton struct{}
|
||||
func (c *envSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
|
||||
envDeps := ctx.Config().(Config).EnvDeps()
|
||||
|
||||
envFile := filepath.Join(ctx.Config().(Config).BuildDir(), ".soong.environment")
|
||||
envFile := PathForOutput(ctx, ".soong.environment")
|
||||
if ctx.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
err := env.WriteEnvFile(envFile, envDeps)
|
||||
err := env.WriteEnvFile(envFile.String(), envDeps)
|
||||
if err != nil {
|
||||
ctx.Errorf(err.Error())
|
||||
}
|
||||
|
||||
ctx.AddNinjaFileDeps(envFile)
|
||||
ctx.AddNinjaFileDeps(envFile.String())
|
||||
}
|
||||
|
135
common/module.go
135
common/module.go
@@ -32,6 +32,19 @@ var (
|
||||
HostExecutable = "host_executable"
|
||||
)
|
||||
|
||||
type ModuleBuildParams struct {
|
||||
Rule blueprint.Rule
|
||||
Output WritablePath
|
||||
Outputs WritablePaths
|
||||
Input Path
|
||||
Inputs Paths
|
||||
Implicit Path
|
||||
Implicits Paths
|
||||
OrderOnly Paths
|
||||
Default bool
|
||||
Args map[string]string
|
||||
}
|
||||
|
||||
type androidBaseContext interface {
|
||||
Arch() Arch
|
||||
HostOrDevice() HostOrDevice
|
||||
@@ -52,12 +65,16 @@ type AndroidModuleContext interface {
|
||||
blueprint.ModuleContext
|
||||
androidBaseContext
|
||||
|
||||
ExpandSources(srcFiles, excludes []string) []string
|
||||
Glob(outDir, globPattern string, excludes []string) []string
|
||||
// Similar to Build, but takes Paths instead of []string,
|
||||
// and performs more verification.
|
||||
ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
|
||||
|
||||
InstallFile(installPath, srcPath string, deps ...string) string
|
||||
InstallFileName(installPath, name, srcPath string, deps ...string) string
|
||||
CheckbuildFile(srcPath string)
|
||||
ExpandSources(srcFiles, excludes []string) Paths
|
||||
Glob(outDir, globPattern string, excludes []string) Paths
|
||||
|
||||
InstallFile(installPath string, srcPath Path, deps ...Path) Path
|
||||
InstallFileName(installPath, name string, srcPath Path, deps ...Path) Path
|
||||
CheckbuildFile(srcPath Path)
|
||||
}
|
||||
|
||||
type AndroidModule interface {
|
||||
@@ -196,8 +213,8 @@ type AndroidModuleBase struct {
|
||||
archProperties []*archProperties
|
||||
|
||||
noAddressSanitizer bool
|
||||
installFiles []string
|
||||
checkbuildFiles []string
|
||||
installFiles Paths
|
||||
checkbuildFiles Paths
|
||||
|
||||
// Used by buildTargetSingleton to create checkbuild and per-directory build targets
|
||||
// Only set on the final variant of each module
|
||||
@@ -254,9 +271,9 @@ func (a *AndroidModuleBase) Enabled() bool {
|
||||
}
|
||||
|
||||
func (a *AndroidModuleBase) computeInstallDeps(
|
||||
ctx blueprint.ModuleContext) []string {
|
||||
ctx blueprint.ModuleContext) Paths {
|
||||
|
||||
result := []string{}
|
||||
result := Paths{}
|
||||
ctx.VisitDepsDepthFirstIf(isFileInstaller,
|
||||
func(m blueprint.Module) {
|
||||
fileInstaller := m.(fileInstaller)
|
||||
@@ -267,7 +284,7 @@ func (a *AndroidModuleBase) computeInstallDeps(
|
||||
return result
|
||||
}
|
||||
|
||||
func (a *AndroidModuleBase) filesToInstall() []string {
|
||||
func (a *AndroidModuleBase) filesToInstall() Paths {
|
||||
return a.installFiles
|
||||
}
|
||||
|
||||
@@ -280,8 +297,8 @@ func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
|
||||
return
|
||||
}
|
||||
|
||||
allInstalledFiles := []string{}
|
||||
allCheckbuildFiles := []string{}
|
||||
allInstalledFiles := Paths{}
|
||||
allCheckbuildFiles := Paths{}
|
||||
ctx.VisitAllModuleVariants(func(module blueprint.Module) {
|
||||
a := module.(AndroidModule).base()
|
||||
allInstalledFiles = append(allInstalledFiles, a.installFiles...)
|
||||
@@ -295,7 +312,7 @@ func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Outputs: []string{name},
|
||||
Implicits: allInstalledFiles,
|
||||
Implicits: allInstalledFiles.Strings(),
|
||||
})
|
||||
deps = append(deps, name)
|
||||
a.installTarget = name
|
||||
@@ -306,7 +323,7 @@ func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Outputs: []string{name},
|
||||
Implicits: allCheckbuildFiles,
|
||||
Implicits: allCheckbuildFiles.Strings(),
|
||||
Optional: true,
|
||||
})
|
||||
deps = append(deps, name)
|
||||
@@ -371,9 +388,9 @@ type androidBaseContextImpl struct {
|
||||
type androidModuleContext struct {
|
||||
blueprint.ModuleContext
|
||||
androidBaseContextImpl
|
||||
installDeps []string
|
||||
installFiles []string
|
||||
checkbuildFiles []string
|
||||
installDeps Paths
|
||||
installFiles Paths
|
||||
checkbuildFiles Paths
|
||||
}
|
||||
|
||||
func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
|
||||
@@ -381,6 +398,30 @@ func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params bluep
|
||||
a.ModuleContext.Build(pctx, params)
|
||||
}
|
||||
|
||||
func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
|
||||
bparams := blueprint.BuildParams{
|
||||
Rule: params.Rule,
|
||||
Outputs: params.Outputs.Strings(),
|
||||
Inputs: params.Inputs.Strings(),
|
||||
Implicits: params.Implicits.Strings(),
|
||||
OrderOnly: params.OrderOnly.Strings(),
|
||||
Args: params.Args,
|
||||
Optional: !params.Default,
|
||||
}
|
||||
|
||||
if params.Output != nil {
|
||||
bparams.Outputs = append(bparams.Outputs, params.Output.String())
|
||||
}
|
||||
if params.Input != nil {
|
||||
bparams.Inputs = append(bparams.Inputs, params.Input.String())
|
||||
}
|
||||
if params.Implicit != nil {
|
||||
bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
|
||||
}
|
||||
|
||||
a.ModuleContext.Build(pctx, bparams)
|
||||
}
|
||||
|
||||
func (a *androidBaseContextImpl) Arch() Arch {
|
||||
return a.arch
|
||||
}
|
||||
@@ -413,31 +454,19 @@ func (a *androidBaseContextImpl) AConfig() Config {
|
||||
return a.config
|
||||
}
|
||||
|
||||
func (a *androidModuleContext) InstallFileName(installPath, name, srcPath string,
|
||||
deps ...string) string {
|
||||
func (a *androidModuleContext) InstallFileName(installPath, name string, srcPath Path,
|
||||
deps ...Path) Path {
|
||||
|
||||
config := a.AConfig()
|
||||
var fullInstallPath string
|
||||
if a.hod.Device() {
|
||||
// TODO: replace unset with a device name once we have device targeting
|
||||
fullInstallPath = filepath.Join(config.DeviceOut(), "system",
|
||||
installPath, name)
|
||||
} else {
|
||||
// TODO
|
||||
if a.ht == Windows {
|
||||
fullInstallPath = filepath.Join(config.BuildDir(), "host", "windows-x86", installPath, name)
|
||||
} else {
|
||||
fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
|
||||
}
|
||||
}
|
||||
fullInstallPath := PathForModuleInstall(a, installPath, name)
|
||||
|
||||
deps = append(deps, a.installDeps...)
|
||||
|
||||
a.ModuleContext.Build(pctx, blueprint.BuildParams{
|
||||
a.ModuleBuild(pctx, ModuleBuildParams{
|
||||
Rule: Cp,
|
||||
Outputs: []string{fullInstallPath},
|
||||
Inputs: []string{srcPath},
|
||||
OrderOnly: deps,
|
||||
Output: fullInstallPath,
|
||||
Input: srcPath,
|
||||
OrderOnly: Paths(deps),
|
||||
Default: true,
|
||||
})
|
||||
|
||||
a.installFiles = append(a.installFiles, fullInstallPath)
|
||||
@@ -445,16 +474,16 @@ func (a *androidModuleContext) InstallFileName(installPath, name, srcPath string
|
||||
return fullInstallPath
|
||||
}
|
||||
|
||||
func (a *androidModuleContext) InstallFile(installPath, srcPath string, deps ...string) string {
|
||||
return a.InstallFileName(installPath, filepath.Base(srcPath), srcPath, deps...)
|
||||
func (a *androidModuleContext) InstallFile(installPath string, srcPath Path, deps ...Path) Path {
|
||||
return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
|
||||
}
|
||||
|
||||
func (a *androidModuleContext) CheckbuildFile(srcPath string) {
|
||||
func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
|
||||
a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
|
||||
}
|
||||
|
||||
type fileInstaller interface {
|
||||
filesToInstall() []string
|
||||
filesToInstall() Paths
|
||||
}
|
||||
|
||||
func isFileInstaller(m blueprint.Module) bool {
|
||||
@@ -476,8 +505,8 @@ func findStringInSlice(str string, slice []string) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) []string {
|
||||
prefix := ModuleSrcDir(ctx)
|
||||
func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
|
||||
prefix := PathForModuleSrc(ctx).String()
|
||||
for i, e := range excludes {
|
||||
j := findStringInSlice(e, srcFiles)
|
||||
if j != -1 {
|
||||
@@ -487,32 +516,24 @@ func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) []st
|
||||
excludes[i] = filepath.Join(prefix, e)
|
||||
}
|
||||
|
||||
for i, srcFile := range srcFiles {
|
||||
srcFiles[i] = filepath.Join(prefix, srcFile)
|
||||
}
|
||||
|
||||
if !hasGlob(srcFiles) {
|
||||
return srcFiles
|
||||
}
|
||||
|
||||
globbedSrcFiles := make([]string, 0, len(srcFiles))
|
||||
globbedSrcFiles := make(Paths, 0, len(srcFiles))
|
||||
for _, s := range srcFiles {
|
||||
if glob.IsGlob(s) {
|
||||
globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", s, excludes)...)
|
||||
globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
|
||||
} else {
|
||||
globbedSrcFiles = append(globbedSrcFiles, s)
|
||||
globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
|
||||
}
|
||||
}
|
||||
|
||||
return globbedSrcFiles
|
||||
}
|
||||
|
||||
func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) []string {
|
||||
ret, err := Glob(ctx, filepath.Join(ModuleOutDir(ctx), outDir), globPattern, excludes)
|
||||
func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
|
||||
ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
|
||||
if err != nil {
|
||||
ctx.ModuleErrorf("glob: %s", err.Error())
|
||||
}
|
||||
return ret
|
||||
return pathsForModuleSrcFromFullPath(ctx, ret)
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
127
common/package_ctx.go
Normal file
127
common/package_ctx.go
Normal file
@@ -0,0 +1,127 @@
|
||||
// Copyright 2015 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 common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
)
|
||||
|
||||
// AndroidPackageContext is a wrapper for blueprint.PackageContext that adds
|
||||
// some android-specific helper functions.
|
||||
type AndroidPackageContext struct {
|
||||
blueprint.PackageContext
|
||||
}
|
||||
|
||||
func NewPackageContext(pkgPath string) AndroidPackageContext {
|
||||
return AndroidPackageContext{blueprint.NewPackageContext(pkgPath)}
|
||||
}
|
||||
|
||||
// configErrorWrapper can be used with Path functions when a Context is not
|
||||
// available. A Config can be provided, and errors are stored as a list for
|
||||
// later retrieval.
|
||||
//
|
||||
// The most common use here will be with VariableFunc, where only a config is
|
||||
// provided, and an error should be returned.
|
||||
type configErrorWrapper struct {
|
||||
config Config
|
||||
errors []error
|
||||
}
|
||||
|
||||
var _ PathContext = &configErrorWrapper{}
|
||||
var _ errorfContext = &configErrorWrapper{}
|
||||
|
||||
func (e *configErrorWrapper) Config() interface{} {
|
||||
return e.config
|
||||
}
|
||||
func (e *configErrorWrapper) Errorf(format string, args ...interface{}) {
|
||||
e.errors = append(e.errors, fmt.Errorf(format, args...))
|
||||
}
|
||||
|
||||
// SourcePathVariable returns a Variable whose value is the source directory
|
||||
// appended with the supplied path. It may only be called during a Go package's
|
||||
// initialization - either from the init() function or as part of a
|
||||
// package-scoped variable's initialization.
|
||||
func (p AndroidPackageContext) SourcePathVariable(name, path string) blueprint.Variable {
|
||||
return p.VariableFunc(name, func(config interface{}) (string, error) {
|
||||
ctx := &configErrorWrapper{config.(Config), []error{}}
|
||||
p := safePathForSource(ctx, path)
|
||||
if len(ctx.errors) > 0 {
|
||||
return "", ctx.errors[0]
|
||||
}
|
||||
return p.String(), nil
|
||||
})
|
||||
}
|
||||
|
||||
// HostBinVariable returns a Variable whose value is the path to a host tool
|
||||
// in the bin directory for host targets. It may only be called during a Go
|
||||
// package's initialization - either from the init() function or as part of a
|
||||
// package-scoped variable's initialization.
|
||||
func (p AndroidPackageContext) HostBinToolVariable(name, path string) blueprint.Variable {
|
||||
return p.VariableFunc(name, func(config interface{}) (string, error) {
|
||||
ctx := &configErrorWrapper{config.(Config), []error{}}
|
||||
p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "bin", path)
|
||||
if len(ctx.errors) > 0 {
|
||||
return "", ctx.errors[0]
|
||||
}
|
||||
return p.String(), nil
|
||||
})
|
||||
}
|
||||
|
||||
// HostJavaToolVariable returns a Variable whose value is the path to a host
|
||||
// tool in the frameworks directory for host targets. It may only be called
|
||||
// during a Go package's initialization - either from the init() function or as
|
||||
// part of a package-scoped variable's initialization.
|
||||
func (p AndroidPackageContext) HostJavaToolVariable(name, path string) blueprint.Variable {
|
||||
return p.VariableFunc(name, func(config interface{}) (string, error) {
|
||||
ctx := &configErrorWrapper{config.(Config), []error{}}
|
||||
p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "framework", path)
|
||||
if len(ctx.errors) > 0 {
|
||||
return "", ctx.errors[0]
|
||||
}
|
||||
return p.String(), nil
|
||||
})
|
||||
}
|
||||
|
||||
// IntermediatesPathVariable returns a Variable whose value is the intermediate
|
||||
// directory appended with the supplied path. It may only be called during a Go
|
||||
// package's initialization - either from the init() function or as part of a
|
||||
// package-scoped variable's initialization.
|
||||
func (p AndroidPackageContext) IntermediatesPathVariable(name, path string) blueprint.Variable {
|
||||
return p.VariableFunc(name, func(config interface{}) (string, error) {
|
||||
ctx := &configErrorWrapper{config.(Config), []error{}}
|
||||
p := PathForIntermediates(ctx, path)
|
||||
if len(ctx.errors) > 0 {
|
||||
return "", ctx.errors[0]
|
||||
}
|
||||
return p.String(), nil
|
||||
})
|
||||
}
|
||||
|
||||
// PrefixedPathsForSourceVariable returns a Variable whose value is the
|
||||
// list of source paths prefixed with the supplied prefix. It may only be
|
||||
// called during a Go package's initialization - either from the init()
|
||||
// function or as part of a package-scoped variable's initialization.
|
||||
func (p AndroidPackageContext) PrefixedPathsForSourceVariable(name, prefix string, paths []string) blueprint.Variable {
|
||||
return p.VariableFunc(name, func(config interface{}) (string, error) {
|
||||
ctx := &configErrorWrapper{config.(Config), []error{}}
|
||||
paths := PathsForSource(ctx, paths)
|
||||
if len(ctx.errors) > 0 {
|
||||
return "", ctx.errors[0]
|
||||
}
|
||||
return JoinWithPrefix(paths.Strings(), prefix), nil
|
||||
})
|
||||
}
|
624
common/paths.go
624
common/paths.go
@@ -18,103 +18,571 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
)
|
||||
|
||||
// ModuleOutDir returns the path to the module-specific output directory.
|
||||
func ModuleOutDir(ctx AndroidModuleContext) string {
|
||||
return filepath.Join(ctx.AConfig().IntermediatesDir(),
|
||||
ctx.ModuleDir(), ctx.ModuleName(), ctx.ModuleSubDir())
|
||||
// PathContext is the subset of a (Module|Singleton)Context required by the
|
||||
// Path methods.
|
||||
type PathContext interface {
|
||||
Config() interface{}
|
||||
}
|
||||
|
||||
// ModuleSrcDir returns the path of the directory that all source file paths are
|
||||
// specified relative to.
|
||||
func ModuleSrcDir(ctx AndroidModuleContext) string {
|
||||
return filepath.Join(ctx.AConfig().SrcDir(), ctx.ModuleDir())
|
||||
var _ PathContext = blueprint.SingletonContext(nil)
|
||||
var _ PathContext = blueprint.ModuleContext(nil)
|
||||
|
||||
// errorfContext is the interface containing the Errorf method matching the
|
||||
// Errorf method in blueprint.SingletonContext.
|
||||
type errorfContext interface {
|
||||
Errorf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
// ModuleBinDir returns the path to the module- and architecture-specific binary
|
||||
// output directory.
|
||||
func ModuleBinDir(ctx AndroidModuleContext) string {
|
||||
return filepath.Join(ModuleOutDir(ctx), "bin")
|
||||
var _ errorfContext = blueprint.SingletonContext(nil)
|
||||
|
||||
// moduleErrorf is the interface containing the ModuleErrorf method matching
|
||||
// the ModuleErrorf method in blueprint.ModuleContext.
|
||||
type moduleErrorf interface {
|
||||
ModuleErrorf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
// ModuleLibDir returns the path to the module- and architecture-specific
|
||||
// library output directory.
|
||||
func ModuleLibDir(ctx AndroidModuleContext) string {
|
||||
return filepath.Join(ModuleOutDir(ctx), "lib")
|
||||
var _ moduleErrorf = blueprint.ModuleContext(nil)
|
||||
|
||||
// pathConfig returns the android Config interface associated to the context.
|
||||
// Panics if the context isn't affiliated with an android build.
|
||||
func pathConfig(ctx PathContext) Config {
|
||||
if ret, ok := ctx.Config().(Config); ok {
|
||||
return ret
|
||||
}
|
||||
panic("Paths may only be used on Soong builds")
|
||||
}
|
||||
|
||||
// ModuleGenDir returns the module directory for generated files
|
||||
// path.
|
||||
func ModuleGenDir(ctx AndroidModuleContext) string {
|
||||
return filepath.Join(ModuleOutDir(ctx), "gen")
|
||||
}
|
||||
|
||||
// ModuleObjDir returns the module- and architecture-specific object directory
|
||||
// path.
|
||||
func ModuleObjDir(ctx AndroidModuleContext) string {
|
||||
return filepath.Join(ModuleOutDir(ctx), "obj")
|
||||
}
|
||||
|
||||
// ModuleGoPackageDir returns the module-specific package root directory path.
|
||||
// This directory is where the final package .a files are output and where
|
||||
// dependent modules search for this package via -I arguments.
|
||||
func ModuleGoPackageDir(ctx AndroidModuleContext) string {
|
||||
return filepath.Join(ModuleOutDir(ctx), "pkg")
|
||||
}
|
||||
|
||||
// ModuleIncludeDir returns the module-specific public include directory path.
|
||||
func ModuleIncludeDir(ctx AndroidModuleContext) string {
|
||||
return filepath.Join(ModuleOutDir(ctx), "include")
|
||||
}
|
||||
|
||||
// ModuleProtoDir returns the module-specific public proto include directory path.
|
||||
func ModuleProtoDir(ctx AndroidModuleContext) string {
|
||||
return filepath.Join(ModuleOutDir(ctx), "proto")
|
||||
}
|
||||
|
||||
func ModuleJSCompiledDir(ctx AndroidModuleContext) string {
|
||||
return filepath.Join(ModuleOutDir(ctx), "js")
|
||||
}
|
||||
|
||||
// CheckModuleSrcDirsExist logs an error on a property if any of the directories relative to the
|
||||
// Blueprints file don't exist.
|
||||
func CheckModuleSrcDirsExist(ctx AndroidModuleContext, dirs []string, prop string) {
|
||||
for _, dir := range dirs {
|
||||
fullDir := filepath.Join(ModuleSrcDir(ctx), dir)
|
||||
if _, err := os.Stat(fullDir); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
ctx.PropertyErrorf(prop, "module source directory %q does not exist", dir)
|
||||
// reportPathError will register an error with the attached context. It
|
||||
// attempts ctx.ModuleErrorf for a better error message first, then falls
|
||||
// back to ctx.Errorf.
|
||||
func reportPathError(ctx PathContext, format string, args ...interface{}) {
|
||||
if mctx, ok := ctx.(moduleErrorf); ok {
|
||||
mctx.ModuleErrorf(format, args...)
|
||||
} else if ectx, ok := ctx.(errorfContext); ok {
|
||||
ectx.Errorf(format, args...)
|
||||
} else {
|
||||
ctx.PropertyErrorf(prop, "%s", err.Error())
|
||||
}
|
||||
}
|
||||
panic(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
// CheckModuleSrcDirsExist logs an error on a property if any of the directories relative to the
|
||||
// top of the source tree don't exist.
|
||||
func CheckSrcDirsExist(ctx AndroidModuleContext, dirs []string, prop string) {
|
||||
for _, dir := range dirs {
|
||||
fullDir := filepath.Join(ctx.AConfig().SrcDir(), dir)
|
||||
if _, err := os.Stat(fullDir); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
ctx.PropertyErrorf(prop, "top-level source directory %q does not exist", dir)
|
||||
type Path interface {
|
||||
// Returns the path in string form
|
||||
String() string
|
||||
|
||||
// Returns the current file extension of the path
|
||||
Ext() string
|
||||
}
|
||||
|
||||
// WritablePath is a type of path that can be used as an output for build rules.
|
||||
type WritablePath interface {
|
||||
Path
|
||||
|
||||
writablePath()
|
||||
}
|
||||
|
||||
type genPathProvider interface {
|
||||
genPathWithExt(ctx AndroidModuleContext, ext string) ModuleGenPath
|
||||
}
|
||||
type objPathProvider interface {
|
||||
objPathWithExt(ctx AndroidModuleContext, subdir, ext string) ModuleObjPath
|
||||
}
|
||||
type resPathProvider interface {
|
||||
resPathWithName(ctx AndroidModuleContext, name string) ModuleResPath
|
||||
}
|
||||
|
||||
// GenPathWithExt derives a new file path in ctx's generated sources directory
|
||||
// from the current path, but with the new extension.
|
||||
func GenPathWithExt(ctx AndroidModuleContext, p Path, ext string) ModuleGenPath {
|
||||
if path, ok := p.(genPathProvider); ok {
|
||||
return path.genPathWithExt(ctx, ext)
|
||||
}
|
||||
reportPathError(ctx, "Tried to create generated file from unsupported path: %s(%s)", reflect.TypeOf(p).Name(), p)
|
||||
return PathForModuleGen(ctx)
|
||||
}
|
||||
|
||||
// ObjPathWithExt derives a new file path in ctx's object directory from the
|
||||
// current path, but with the new extension.
|
||||
func ObjPathWithExt(ctx AndroidModuleContext, p Path, subdir, ext string) ModuleObjPath {
|
||||
if path, ok := p.(objPathProvider); ok {
|
||||
return path.objPathWithExt(ctx, subdir, ext)
|
||||
}
|
||||
reportPathError(ctx, "Tried to create object file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
|
||||
return PathForModuleObj(ctx)
|
||||
}
|
||||
|
||||
// ResPathWithName derives a new path in ctx's output resource directory, using
|
||||
// the current path to create the directory name, and the `name` argument for
|
||||
// the filename.
|
||||
func ResPathWithName(ctx AndroidModuleContext, p Path, name string) ModuleResPath {
|
||||
if path, ok := p.(resPathProvider); ok {
|
||||
return path.resPathWithName(ctx, name)
|
||||
}
|
||||
reportPathError(ctx, "Tried to create object file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
|
||||
return PathForModuleRes(ctx)
|
||||
}
|
||||
|
||||
// OptionalPath is a container that may or may not contain a valid Path.
|
||||
type OptionalPath struct {
|
||||
valid bool
|
||||
path Path
|
||||
}
|
||||
|
||||
// OptionalPathForPath returns an OptionalPath containing the path.
|
||||
func OptionalPathForPath(path Path) OptionalPath {
|
||||
if path == nil {
|
||||
return OptionalPath{}
|
||||
}
|
||||
return OptionalPath{valid: true, path: path}
|
||||
}
|
||||
|
||||
// Valid returns whether there is a valid path
|
||||
func (p OptionalPath) Valid() bool {
|
||||
return p.valid
|
||||
}
|
||||
|
||||
// Path returns the Path embedded in this OptionalPath. You must be sure that
|
||||
// there is a valid path, since this method will panic if there is not.
|
||||
func (p OptionalPath) Path() Path {
|
||||
if !p.valid {
|
||||
panic("Requesting an invalid path")
|
||||
}
|
||||
return p.path
|
||||
}
|
||||
|
||||
// String returns the string version of the Path, or "" if it isn't valid.
|
||||
func (p OptionalPath) String() string {
|
||||
if p.valid {
|
||||
return p.path.String()
|
||||
} else {
|
||||
ctx.PropertyErrorf(prop, "%s", err.Error())
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a path relative to the top level source directory. Panics if path is not inside the
|
||||
// top level source directory.
|
||||
func SrcDirRelPath(ctx AndroidModuleContext, path string) string {
|
||||
srcDir := ctx.AConfig().SrcDir()
|
||||
relPath, err := filepath.Rel(srcDir, path)
|
||||
// Paths is a slice of Path objects, with helpers to operate on the collection.
|
||||
type Paths []Path
|
||||
|
||||
// PathsForSource returns Paths rooted from SrcDir
|
||||
func PathsForSource(ctx PathContext, paths []string) Paths {
|
||||
ret := make(Paths, len(paths))
|
||||
for i, path := range paths {
|
||||
ret[i] = PathForSource(ctx, path)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// PathsForModuleSrc returns Paths rooted from the module's local source
|
||||
// directory
|
||||
func PathsForModuleSrc(ctx AndroidModuleContext, paths []string) Paths {
|
||||
ret := make(Paths, len(paths))
|
||||
for i, path := range paths {
|
||||
ret[i] = PathForModuleSrc(ctx, path)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// pathsForModuleSrcFromFullPath returns Paths rooted from the module's local
|
||||
// source directory, but strip the local source directory from the beginning of
|
||||
// each string.
|
||||
func pathsForModuleSrcFromFullPath(ctx AndroidModuleContext, paths []string) Paths {
|
||||
prefix := filepath.Join(ctx.AConfig().srcDir, ctx.ModuleDir()) + "/"
|
||||
ret := make(Paths, 0, len(paths))
|
||||
for _, p := range paths {
|
||||
path := filepath.Clean(p)
|
||||
if !strings.HasPrefix(path, prefix) {
|
||||
reportPathError(ctx, "Path '%s' is not in module source directory '%s'", p, prefix)
|
||||
continue
|
||||
}
|
||||
ret = append(ret, PathForModuleSrc(ctx, path[len(prefix):]))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// PathsWithOptionalDefaultForModuleSrc returns Paths rooted from the module's
|
||||
// local source directory. If none are provided, use the default if it exists.
|
||||
func PathsWithOptionalDefaultForModuleSrc(ctx AndroidModuleContext, input []string, def string) Paths {
|
||||
if len(input) > 0 {
|
||||
return PathsForModuleSrc(ctx, input)
|
||||
}
|
||||
// Use Glob so that if the default doesn't exist, a dependency is added so that when it
|
||||
// is created, we're run again.
|
||||
path := filepath.Join(ctx.AConfig().srcDir, ctx.ModuleDir(), def)
|
||||
return ctx.Glob("default", path, []string{})
|
||||
}
|
||||
|
||||
// Strings returns the Paths in string form
|
||||
func (p Paths) Strings() []string {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
ret := make([]string, len(p))
|
||||
for i, path := range p {
|
||||
ret[i] = path.String()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// WritablePaths is a slice of WritablePaths, used for multiple outputs.
|
||||
type WritablePaths []WritablePath
|
||||
|
||||
// Strings returns the string forms of the writable paths.
|
||||
func (p WritablePaths) Strings() []string {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
ret := make([]string, len(p))
|
||||
for i, path := range p {
|
||||
ret[i] = path.String()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type basePath struct {
|
||||
path string
|
||||
config Config
|
||||
}
|
||||
|
||||
func (p basePath) Ext() string {
|
||||
return filepath.Ext(p.path)
|
||||
}
|
||||
|
||||
// SourcePath is a Path representing a file path rooted from SrcDir
|
||||
type SourcePath struct {
|
||||
basePath
|
||||
}
|
||||
|
||||
var _ Path = SourcePath{}
|
||||
|
||||
// safePathForSource is for paths that we expect are safe -- only for use by go
|
||||
// code that is embedding ninja variables in paths
|
||||
func safePathForSource(ctx PathContext, path string) SourcePath {
|
||||
p := validateSafePath(ctx, path)
|
||||
ret := SourcePath{basePath{p, pathConfig(ctx)}}
|
||||
|
||||
abs, err := filepath.Abs(ret.String())
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("%q is not inside %q: %s", path, srcDir, err.Error()))
|
||||
reportPathError(ctx, "%s", err.Error())
|
||||
return ret
|
||||
}
|
||||
buildroot, err := filepath.Abs(pathConfig(ctx).buildDir)
|
||||
if err != nil {
|
||||
reportPathError(ctx, "%s", err.Error())
|
||||
return ret
|
||||
}
|
||||
if strings.HasPrefix(abs, buildroot) {
|
||||
reportPathError(ctx, "source path %s is in output", abs)
|
||||
return ret
|
||||
}
|
||||
|
||||
return relPath
|
||||
return ret
|
||||
}
|
||||
|
||||
// PathForSource returns a SourcePath for the provided paths... (which are
|
||||
// joined together with filepath.Join). This also validates that the path
|
||||
// doesn't escape the source dir, or is contained in the build dir. On error, it
|
||||
// will return a usable, but invalid SourcePath, and report a ModuleError.
|
||||
func PathForSource(ctx PathContext, paths ...string) SourcePath {
|
||||
p := validatePath(ctx, paths...)
|
||||
ret := SourcePath{basePath{p, pathConfig(ctx)}}
|
||||
|
||||
abs, err := filepath.Abs(ret.String())
|
||||
if err != nil {
|
||||
reportPathError(ctx, "%s", err.Error())
|
||||
return ret
|
||||
}
|
||||
buildroot, err := filepath.Abs(pathConfig(ctx).buildDir)
|
||||
if err != nil {
|
||||
reportPathError(ctx, "%s", err.Error())
|
||||
return ret
|
||||
}
|
||||
if strings.HasPrefix(abs, buildroot) {
|
||||
reportPathError(ctx, "source path %s is in output", abs)
|
||||
return ret
|
||||
}
|
||||
|
||||
if _, err = os.Stat(ret.String()); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
reportPathError(ctx, "source path %s does not exist", ret)
|
||||
} else {
|
||||
reportPathError(ctx, "%s: %s", ret, err.Error())
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// OptionalPathForSource returns an OptionalPath with the SourcePath if the
|
||||
// path exists, or an empty OptionalPath if it doesn't exist. Dependencies are added
|
||||
// so that the ninja file will be regenerated if the state of the path changes.
|
||||
func OptionalPathForSource(ctx blueprint.SingletonContext, intermediates string, paths ...string) OptionalPath {
|
||||
p := validatePath(ctx, paths...)
|
||||
path := SourcePath{basePath{p, pathConfig(ctx)}}
|
||||
|
||||
abs, err := filepath.Abs(path.String())
|
||||
if err != nil {
|
||||
reportPathError(ctx, "%s", err.Error())
|
||||
return OptionalPath{}
|
||||
}
|
||||
buildroot, err := filepath.Abs(pathConfig(ctx).buildDir)
|
||||
if err != nil {
|
||||
reportPathError(ctx, "%s", err.Error())
|
||||
return OptionalPath{}
|
||||
}
|
||||
if strings.HasPrefix(abs, buildroot) {
|
||||
reportPathError(ctx, "source path %s is in output", abs)
|
||||
return OptionalPath{}
|
||||
}
|
||||
|
||||
// Use glob to produce proper dependencies, even though we only want
|
||||
// a single file.
|
||||
files, err := Glob(ctx, PathForIntermediates(ctx, intermediates).String(), path.String(), nil)
|
||||
if err != nil {
|
||||
reportPathError(ctx, "glob: %s", err.Error())
|
||||
return OptionalPath{}
|
||||
}
|
||||
|
||||
if len(files) == 0 {
|
||||
return OptionalPath{}
|
||||
}
|
||||
return OptionalPathForPath(path)
|
||||
}
|
||||
|
||||
func (p SourcePath) String() string {
|
||||
return filepath.Join(p.config.srcDir, p.path)
|
||||
}
|
||||
|
||||
// Join creates a new SourcePath with paths... joined with the current path. The
|
||||
// provided paths... may not use '..' to escape from the current path.
|
||||
func (p SourcePath) Join(ctx PathContext, paths ...string) SourcePath {
|
||||
path := validatePath(ctx, paths...)
|
||||
return PathForSource(ctx, p.path, path)
|
||||
}
|
||||
|
||||
// OverlayPath returns the overlay for `path' if it exists. This assumes that the
|
||||
// SourcePath is the path to a resource overlay directory.
|
||||
func (p SourcePath) OverlayPath(ctx AndroidModuleContext, path Path) OptionalPath {
|
||||
var relDir string
|
||||
if moduleSrcPath, ok := path.(ModuleSrcPath); ok {
|
||||
relDir = moduleSrcPath.sourcePath.path
|
||||
} else if srcPath, ok := path.(SourcePath); ok {
|
||||
relDir = srcPath.path
|
||||
} else {
|
||||
reportPathError(ctx, "Cannot find relative path for %s(%s)", reflect.TypeOf(path).Name(), path)
|
||||
return OptionalPath{}
|
||||
}
|
||||
dir := filepath.Join(p.config.srcDir, p.path, relDir)
|
||||
// Use Glob so that we are run again if the directory is added.
|
||||
paths, err := Glob(ctx, PathForModuleOut(ctx, "overlay").String(), dir, []string{})
|
||||
if err != nil {
|
||||
reportPathError(ctx, "glob: %s", err.Error())
|
||||
return OptionalPath{}
|
||||
}
|
||||
if len(paths) == 0 {
|
||||
return OptionalPath{}
|
||||
}
|
||||
relPath, err := filepath.Rel(p.config.srcDir, paths[0])
|
||||
if err != nil {
|
||||
reportPathError(ctx, "%s", err.Error())
|
||||
return OptionalPath{}
|
||||
}
|
||||
return OptionalPathForPath(PathForSource(ctx, relPath))
|
||||
}
|
||||
|
||||
// OutputPath is a Path representing a file path rooted from the build directory
|
||||
type OutputPath struct {
|
||||
basePath
|
||||
}
|
||||
|
||||
var _ Path = OutputPath{}
|
||||
|
||||
// PathForOutput returns an OutputPath for the provided paths... (which are
|
||||
// joined together with filepath.Join). This also validates that the path
|
||||
// does not escape the build dir. On error, it will return a usable, but invalid
|
||||
// OutputPath, and report a ModuleError.
|
||||
func PathForOutput(ctx PathContext, paths ...string) OutputPath {
|
||||
path := validatePath(ctx, paths...)
|
||||
return OutputPath{basePath{path, pathConfig(ctx)}}
|
||||
}
|
||||
|
||||
func (p OutputPath) writablePath() {}
|
||||
|
||||
func (p OutputPath) String() string {
|
||||
return filepath.Join(p.config.buildDir, p.path)
|
||||
}
|
||||
|
||||
// Join creates a new OutputPath with paths... joined with the current path. The
|
||||
// provided paths... may not use '..' to escape from the current path.
|
||||
func (p OutputPath) Join(ctx PathContext, paths ...string) OutputPath {
|
||||
path := validatePath(ctx, paths...)
|
||||
return PathForOutput(ctx, p.path, path)
|
||||
}
|
||||
|
||||
// PathForIntermediates returns an OutputPath representing the top-level
|
||||
// intermediates directory.
|
||||
func PathForIntermediates(ctx PathContext, paths ...string) OutputPath {
|
||||
path := validatePath(ctx, paths...)
|
||||
return PathForOutput(ctx, ".intermediates", path)
|
||||
}
|
||||
|
||||
// ModuleSrcPath is a Path representing a file rooted from a module's local source dir
|
||||
type ModuleSrcPath struct {
|
||||
basePath
|
||||
sourcePath SourcePath
|
||||
moduleDir string
|
||||
}
|
||||
|
||||
var _ Path = ModuleSrcPath{}
|
||||
var _ genPathProvider = ModuleSrcPath{}
|
||||
var _ objPathProvider = ModuleSrcPath{}
|
||||
var _ resPathProvider = ModuleSrcPath{}
|
||||
|
||||
// PathForModuleSrc returns a ModuleSrcPath representing the paths... under the
|
||||
// module's local source directory.
|
||||
func PathForModuleSrc(ctx AndroidModuleContext, paths ...string) ModuleSrcPath {
|
||||
path := validatePath(ctx, paths...)
|
||||
return ModuleSrcPath{basePath{path, ctx.AConfig()}, PathForSource(ctx, ctx.ModuleDir(), path), ctx.ModuleDir()}
|
||||
}
|
||||
|
||||
// OptionalPathForModuleSrc returns an OptionalPath. The OptionalPath contains a
|
||||
// valid path if p is non-nil.
|
||||
func OptionalPathForModuleSrc(ctx AndroidModuleContext, p *string) OptionalPath {
|
||||
if p == nil {
|
||||
return OptionalPath{}
|
||||
}
|
||||
return OptionalPathForPath(PathForModuleSrc(ctx, *p))
|
||||
}
|
||||
|
||||
func (p ModuleSrcPath) String() string {
|
||||
return p.sourcePath.String()
|
||||
}
|
||||
|
||||
func (p ModuleSrcPath) genPathWithExt(ctx AndroidModuleContext, ext string) ModuleGenPath {
|
||||
return PathForModuleGen(ctx, p.moduleDir, pathtools.ReplaceExtension(p.path, ext))
|
||||
}
|
||||
|
||||
func (p ModuleSrcPath) objPathWithExt(ctx AndroidModuleContext, subdir, ext string) ModuleObjPath {
|
||||
return PathForModuleObj(ctx, subdir, p.moduleDir, pathtools.ReplaceExtension(p.path, ext))
|
||||
}
|
||||
|
||||
func (p ModuleSrcPath) resPathWithName(ctx AndroidModuleContext, name string) ModuleResPath {
|
||||
// TODO: Use full directory if the new ctx is not the current ctx?
|
||||
return PathForModuleRes(ctx, p.path, name)
|
||||
}
|
||||
|
||||
// ModuleOutPath is a Path representing a module's output directory.
|
||||
type ModuleOutPath struct {
|
||||
OutputPath
|
||||
}
|
||||
|
||||
var _ Path = ModuleOutPath{}
|
||||
|
||||
// PathForModuleOut returns a Path representing the paths... under the module's
|
||||
// output directory.
|
||||
func PathForModuleOut(ctx AndroidModuleContext, paths ...string) ModuleOutPath {
|
||||
p := validatePath(ctx, paths...)
|
||||
return ModuleOutPath{PathForOutput(ctx, ".intermediates", ctx.ModuleDir(), ctx.ModuleName(), ctx.ModuleSubDir(), p)}
|
||||
}
|
||||
|
||||
// ModuleGenPath is a Path representing the 'gen' directory in a module's output
|
||||
// directory. Mainly used for generated sources.
|
||||
type ModuleGenPath struct {
|
||||
ModuleOutPath
|
||||
path string
|
||||
}
|
||||
|
||||
var _ Path = ModuleGenPath{}
|
||||
var _ genPathProvider = ModuleGenPath{}
|
||||
var _ objPathProvider = ModuleGenPath{}
|
||||
|
||||
// PathForModuleGen returns a Path representing the paths... under the module's
|
||||
// `gen' directory.
|
||||
func PathForModuleGen(ctx AndroidModuleContext, paths ...string) ModuleGenPath {
|
||||
p := validatePath(ctx, paths...)
|
||||
return ModuleGenPath{
|
||||
PathForModuleOut(ctx, "gen", p),
|
||||
p,
|
||||
}
|
||||
}
|
||||
|
||||
func (p ModuleGenPath) genPathWithExt(ctx AndroidModuleContext, ext string) ModuleGenPath {
|
||||
// TODO: make a different path for local vs remote generated files?
|
||||
return PathForModuleGen(ctx, pathtools.ReplaceExtension(p.path, ext))
|
||||
}
|
||||
|
||||
func (p ModuleGenPath) objPathWithExt(ctx AndroidModuleContext, subdir, ext string) ModuleObjPath {
|
||||
return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
|
||||
}
|
||||
|
||||
// ModuleObjPath is a Path representing the 'obj' directory in a module's output
|
||||
// directory. Used for compiled objects.
|
||||
type ModuleObjPath struct {
|
||||
ModuleOutPath
|
||||
}
|
||||
|
||||
var _ Path = ModuleObjPath{}
|
||||
|
||||
// PathForModuleObj returns a Path representing the paths... under the module's
|
||||
// 'obj' directory.
|
||||
func PathForModuleObj(ctx AndroidModuleContext, paths ...string) ModuleObjPath {
|
||||
p := validatePath(ctx, paths...)
|
||||
return ModuleObjPath{PathForModuleOut(ctx, "obj", p)}
|
||||
}
|
||||
|
||||
// ModuleResPath is a a Path representing the 'res' directory in a module's
|
||||
// output directory.
|
||||
type ModuleResPath struct {
|
||||
ModuleOutPath
|
||||
}
|
||||
|
||||
var _ Path = ModuleResPath{}
|
||||
|
||||
// PathForModuleRes returns a Path representing the paths... under the module's
|
||||
// 'res' directory.
|
||||
func PathForModuleRes(ctx AndroidModuleContext, paths ...string) ModuleResPath {
|
||||
p := validatePath(ctx, paths...)
|
||||
return ModuleResPath{PathForModuleOut(ctx, "res", p)}
|
||||
}
|
||||
|
||||
// PathForModuleInstall returns a Path representing the install path for the
|
||||
// module appended with paths...
|
||||
func PathForModuleInstall(ctx AndroidModuleContext, paths ...string) OutputPath {
|
||||
var outPaths []string
|
||||
if ctx.Device() {
|
||||
outPaths = []string{"target", "product", ctx.AConfig().DeviceName(), "system"}
|
||||
} else {
|
||||
outPaths = []string{"host", ctx.HostType().String() + "-x86"}
|
||||
}
|
||||
outPaths = append(outPaths, paths...)
|
||||
return PathForOutput(ctx, outPaths...)
|
||||
}
|
||||
|
||||
// validateSafePath validates a path that we trust (may contain ninja variables).
|
||||
// Ensures that it does not attempt to leave the containing directory.
|
||||
func validateSafePath(ctx PathContext, paths ...string) string {
|
||||
// TODO: filepath.Join isn't necessarily correct with embedded ninja
|
||||
// variables. '..' may remove the entire ninja variable, even if it
|
||||
// will be expanded to multiple nested directories.
|
||||
p := filepath.Join(paths...)
|
||||
if p == ".." || strings.HasPrefix(p, "../") || strings.HasPrefix(p, "/") {
|
||||
reportPathError(ctx, "Path is outside directory: %s", p)
|
||||
return ""
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// validatePath validates that a path does not include ninja variables, and does
|
||||
// not attempt to leave the containing directory.
|
||||
func validatePath(ctx PathContext, paths ...string) string {
|
||||
for _, path := range paths {
|
||||
if strings.Contains(path, "$") {
|
||||
reportPathError(ctx, "Path contains invalid character($): %s", path)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return validateSafePath(ctx, paths...)
|
||||
}
|
||||
|
167
common/paths_test.go
Normal file
167
common/paths_test.go
Normal file
@@ -0,0 +1,167 @@
|
||||
// Copyright 2015 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 common
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type strsTestCase struct {
|
||||
in []string
|
||||
out string
|
||||
err []error
|
||||
}
|
||||
|
||||
var commonValidatePathTestCases = []strsTestCase{
|
||||
{
|
||||
in: []string{""},
|
||||
out: "",
|
||||
},
|
||||
{
|
||||
in: []string{"a/b"},
|
||||
out: "a/b",
|
||||
},
|
||||
{
|
||||
in: []string{"a/b", "c"},
|
||||
out: "a/b/c",
|
||||
},
|
||||
{
|
||||
in: []string{"a/.."},
|
||||
out: ".",
|
||||
},
|
||||
{
|
||||
in: []string{"."},
|
||||
out: ".",
|
||||
},
|
||||
{
|
||||
in: []string{".."},
|
||||
out: "",
|
||||
err: []error{errors.New("Path is outside directory: ..")},
|
||||
},
|
||||
{
|
||||
in: []string{"../a"},
|
||||
out: "",
|
||||
err: []error{errors.New("Path is outside directory: ../a")},
|
||||
},
|
||||
{
|
||||
in: []string{"b/../../a"},
|
||||
out: "",
|
||||
err: []error{errors.New("Path is outside directory: ../a")},
|
||||
},
|
||||
{
|
||||
in: []string{"/a"},
|
||||
out: "",
|
||||
err: []error{errors.New("Path is outside directory: /a")},
|
||||
},
|
||||
}
|
||||
|
||||
var validateSafePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
|
||||
{
|
||||
in: []string{"$host/../$a"},
|
||||
out: "$a",
|
||||
},
|
||||
}...)
|
||||
|
||||
var validatePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
|
||||
{
|
||||
in: []string{"$host/../$a"},
|
||||
out: "",
|
||||
err: []error{errors.New("Path contains invalid character($): $host/../$a")},
|
||||
},
|
||||
{
|
||||
in: []string{"$host/.."},
|
||||
out: "",
|
||||
err: []error{errors.New("Path contains invalid character($): $host/..")},
|
||||
},
|
||||
}...)
|
||||
|
||||
func TestValidateSafePath(t *testing.T) {
|
||||
for _, testCase := range validateSafePathTestCases {
|
||||
ctx := &configErrorWrapper{}
|
||||
out := validateSafePath(ctx, testCase.in...)
|
||||
check(t, "validateSafePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidatePath(t *testing.T) {
|
||||
for _, testCase := range validatePathTestCases {
|
||||
ctx := &configErrorWrapper{}
|
||||
out := validatePath(ctx, testCase.in...)
|
||||
check(t, "validatePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOptionalPath(t *testing.T) {
|
||||
var path OptionalPath
|
||||
checkInvalidOptionalPath(t, path)
|
||||
|
||||
path = OptionalPathForPath(nil)
|
||||
checkInvalidOptionalPath(t, path)
|
||||
}
|
||||
|
||||
func checkInvalidOptionalPath(t *testing.T, path OptionalPath) {
|
||||
if path.Valid() {
|
||||
t.Errorf("Uninitialized OptionalPath should not be valid")
|
||||
}
|
||||
if path.String() != "" {
|
||||
t.Errorf("Uninitialized OptionalPath String() should return \"\", not %q", path.String())
|
||||
}
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("Expected a panic when calling Path() on an uninitialized OptionalPath")
|
||||
}
|
||||
}()
|
||||
path.Path()
|
||||
}
|
||||
|
||||
func check(t *testing.T, testType, testString string,
|
||||
got interface{}, err []error,
|
||||
expected interface{}, expectedErr []error) {
|
||||
|
||||
printedTestCase := false
|
||||
e := func(s string, expected, got interface{}) {
|
||||
if !printedTestCase {
|
||||
t.Errorf("test case %s: %s", testType, testString)
|
||||
printedTestCase = true
|
||||
}
|
||||
t.Errorf("incorrect %s", s)
|
||||
t.Errorf(" expected: %s", p(expected))
|
||||
t.Errorf(" got: %s", p(got))
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expectedErr, err) {
|
||||
e("errors:", expectedErr, err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected, got) {
|
||||
e("output:", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func p(in interface{}) string {
|
||||
if v, ok := in.([]interface{}); ok {
|
||||
s := make([]string, len(v))
|
||||
for i := range v {
|
||||
s[i] = fmt.Sprintf("%#v", v[i])
|
||||
}
|
||||
return "[" + strings.Join(s, ", ") + "]"
|
||||
} else {
|
||||
return fmt.Sprintf("%#v", in)
|
||||
}
|
||||
}
|
@@ -15,10 +15,7 @@
|
||||
package genrule
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
|
||||
"android/soong"
|
||||
"android/soong/common"
|
||||
@@ -32,20 +29,20 @@ func init() {
|
||||
}
|
||||
|
||||
var (
|
||||
pctx = blueprint.NewPackageContext("android/soong/genrule")
|
||||
pctx = common.NewPackageContext("android/soong/genrule")
|
||||
)
|
||||
|
||||
func init() {
|
||||
pctx.VariableConfigMethod("srcDir", common.Config.SrcDir)
|
||||
pctx.VariableConfigMethod("hostBin", common.Config.HostBin)
|
||||
pctx.SourcePathVariable("srcDir", "")
|
||||
pctx.HostBinToolVariable("hostBin", "")
|
||||
}
|
||||
|
||||
type SourceFileGenerator interface {
|
||||
GeneratedSourceFiles() []string
|
||||
GeneratedSourceFiles() common.Paths
|
||||
}
|
||||
|
||||
type HostToolProvider interface {
|
||||
HostToolPath() string
|
||||
HostToolPath() common.OptionalPath
|
||||
}
|
||||
|
||||
type generatorProperties struct {
|
||||
@@ -68,20 +65,20 @@ type generator struct {
|
||||
|
||||
tasks taskFunc
|
||||
|
||||
deps []string
|
||||
deps common.Paths
|
||||
rule blueprint.Rule
|
||||
|
||||
outputFiles []string
|
||||
outputFiles common.Paths
|
||||
}
|
||||
|
||||
type taskFunc func(ctx common.AndroidModuleContext) []generateTask
|
||||
|
||||
type generateTask struct {
|
||||
in []string
|
||||
out string
|
||||
in common.Paths
|
||||
out common.ModuleGenPath
|
||||
}
|
||||
|
||||
func (g *generator) GeneratedSourceFiles() []string {
|
||||
func (g *generator) GeneratedSourceFiles() common.Paths {
|
||||
return g.outputFiles
|
||||
}
|
||||
|
||||
@@ -104,8 +101,8 @@ func (g *generator) GenerateAndroidBuildActions(ctx common.AndroidModuleContext)
|
||||
ctx.VisitDirectDeps(func(module blueprint.Module) {
|
||||
if t, ok := module.(HostToolProvider); ok {
|
||||
p := t.HostToolPath()
|
||||
if p != "" {
|
||||
g.deps = append(g.deps, p)
|
||||
if p.Valid() {
|
||||
g.deps = append(g.deps, p.Path())
|
||||
} else {
|
||||
ctx.ModuleErrorf("host tool %q missing output file", ctx.OtherModuleName(module))
|
||||
}
|
||||
@@ -120,12 +117,11 @@ func (g *generator) GenerateAndroidBuildActions(ctx common.AndroidModuleContext)
|
||||
}
|
||||
|
||||
func (g *generator) generateSourceFile(ctx common.AndroidModuleContext, task generateTask) {
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: g.rule,
|
||||
Output: task.out,
|
||||
Inputs: task.in,
|
||||
Implicits: g.deps,
|
||||
Outputs: []string{task.out},
|
||||
})
|
||||
|
||||
g.outputFiles = append(g.outputFiles, task.out)
|
||||
@@ -148,9 +144,10 @@ func GenSrcsFactory() (blueprint.Module, []interface{}) {
|
||||
srcFiles := ctx.ExpandSources(properties.Srcs, nil)
|
||||
tasks := make([]generateTask, 0, len(srcFiles))
|
||||
for _, in := range srcFiles {
|
||||
out := pathtools.ReplaceExtension(in, properties.Output_extension)
|
||||
out = filepath.Join(common.ModuleGenDir(ctx), out)
|
||||
tasks = append(tasks, generateTask{[]string{in}, out})
|
||||
tasks = append(tasks, generateTask{
|
||||
in: common.Paths{in},
|
||||
out: common.GenPathWithExt(ctx, in, properties.Output_extension),
|
||||
})
|
||||
}
|
||||
return tasks
|
||||
}
|
||||
@@ -173,7 +170,7 @@ func GenRuleFactory() (blueprint.Module, []interface{}) {
|
||||
return []generateTask{
|
||||
{
|
||||
in: ctx.ExpandSources(properties.Srcs, nil),
|
||||
out: filepath.Join(common.ModuleGenDir(ctx), properties.Out),
|
||||
out: properties.Out,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -186,5 +183,5 @@ type genRuleProperties struct {
|
||||
Srcs []string
|
||||
|
||||
// name of the output file that will be generated
|
||||
Out string
|
||||
Out common.ModuleGenPath
|
||||
}
|
||||
|
101
java/app.go
101
java/app.go
@@ -17,12 +17,10 @@ package java
|
||||
// This file contains the module types for compiling Android apps.
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
|
||||
"android/soong/common"
|
||||
)
|
||||
@@ -63,8 +61,8 @@ type AndroidApp struct {
|
||||
|
||||
appProperties androidAppProperties
|
||||
|
||||
aaptJavaFileList string
|
||||
exportPackage string
|
||||
aaptJavaFileList common.Path
|
||||
exportPackage common.Path
|
||||
}
|
||||
|
||||
func (a *AndroidApp) JavaDependencies(ctx AndroidJavaModuleContext) []string {
|
||||
@@ -117,7 +115,7 @@ func (a *AndroidApp) GenerateJavaBuildActions(ctx common.AndroidModuleContext) {
|
||||
}
|
||||
|
||||
// apps manifests are handled by aapt, don't let javaBase see them
|
||||
a.properties.Manifest = ""
|
||||
a.properties.Manifest = nil
|
||||
|
||||
//if !ctx.ContainsProperty("proguard.enabled") {
|
||||
// a.properties.Proguard.Enabled = true
|
||||
@@ -141,16 +139,16 @@ func (a *AndroidApp) GenerateJavaBuildActions(ctx common.AndroidModuleContext) {
|
||||
|
||||
certificate := a.appProperties.Certificate
|
||||
if certificate == "" {
|
||||
certificate = ctx.AConfig().DefaultAppCertificate()
|
||||
certificate = ctx.AConfig().DefaultAppCertificate(ctx).String()
|
||||
} else if dir, _ := filepath.Split(certificate); dir == "" {
|
||||
certificate = filepath.Join(ctx.AConfig().DefaultAppCertificateDir(), certificate)
|
||||
certificate = filepath.Join(ctx.AConfig().DefaultAppCertificateDir(ctx).String(), certificate)
|
||||
} else {
|
||||
certificate = filepath.Join(ctx.AConfig().SrcDir(), certificate)
|
||||
certificate = filepath.Join(common.PathForSource(ctx).String(), certificate)
|
||||
}
|
||||
|
||||
certificates := []string{certificate}
|
||||
for _, c := range a.appProperties.Additional_certificates {
|
||||
certificates = append(certificates, filepath.Join(ctx.AConfig().SrcDir(), c))
|
||||
certificates = append(certificates, filepath.Join(common.PathForSource(ctx).String(), c))
|
||||
}
|
||||
|
||||
a.outputFile = CreateAppPackage(ctx, aaptPackageFlags, a.outputFile, certificates)
|
||||
@@ -169,7 +167,7 @@ var aaptIgnoreFilenames = []string{
|
||||
"*~",
|
||||
}
|
||||
|
||||
func (a *AndroidApp) aaptFlags(ctx common.AndroidModuleContext) ([]string, []string, bool) {
|
||||
func (a *AndroidApp) aaptFlags(ctx common.AndroidModuleContext) ([]string, common.Paths, bool) {
|
||||
aaptFlags := a.appProperties.Aaptflags
|
||||
hasVersionCode := false
|
||||
hasVersionName := false
|
||||
@@ -185,54 +183,17 @@ func (a *AndroidApp) aaptFlags(ctx common.AndroidModuleContext) ([]string, []str
|
||||
aaptFlags = append(aaptFlags, "-z")
|
||||
}
|
||||
|
||||
assetDirs := a.appProperties.Asset_dirs
|
||||
if len(assetDirs) == 0 {
|
||||
defaultAssetDir := filepath.Join(common.ModuleSrcDir(ctx), "assets")
|
||||
if _, err := os.Stat(defaultAssetDir); err == nil {
|
||||
assetDirs = []string{defaultAssetDir}
|
||||
} else {
|
||||
// Default asset directory doesn't exist, add a dep on the parent directory to
|
||||
// regenerate the manifest if it is created later
|
||||
// TODO: use glob to avoid rerunning whole regenerate if a different file is created?
|
||||
ctx.AddNinjaFileDeps(common.ModuleSrcDir(ctx))
|
||||
}
|
||||
} else {
|
||||
assetDirs = pathtools.PrefixPaths(assetDirs, common.ModuleSrcDir(ctx))
|
||||
}
|
||||
assetDirs := common.PathsWithOptionalDefaultForModuleSrc(ctx, a.appProperties.Asset_dirs, "assets")
|
||||
resourceDirs := common.PathsWithOptionalDefaultForModuleSrc(ctx, a.appProperties.Android_resource_dirs, "res")
|
||||
|
||||
resourceDirs := a.appProperties.Android_resource_dirs
|
||||
if len(resourceDirs) == 0 {
|
||||
defaultResourceDir := filepath.Join(common.ModuleSrcDir(ctx), "res")
|
||||
if _, err := os.Stat(defaultResourceDir); err == nil {
|
||||
resourceDirs = []string{defaultResourceDir}
|
||||
} else {
|
||||
// Default resource directory doesn't exist, add a dep on the parent directory to
|
||||
// regenerate the manifest if it is created later
|
||||
// TODO: use glob to avoid rerunning whole regenerate if a different file is created?
|
||||
ctx.AddNinjaFileDeps(common.ModuleSrcDir(ctx))
|
||||
}
|
||||
} else {
|
||||
resourceDirs = pathtools.PrefixPaths(resourceDirs, common.ModuleSrcDir(ctx))
|
||||
}
|
||||
|
||||
rootSrcDir := ctx.AConfig().SrcDir()
|
||||
var overlayResourceDirs []string
|
||||
var overlayResourceDirs common.Paths
|
||||
// For every resource directory, check if there is an overlay directory with the same path.
|
||||
// If found, it will be prepended to the list of resource directories.
|
||||
for _, overlayDir := range ctx.AConfig().ResourceOverlays() {
|
||||
for _, resourceDir := range resourceDirs {
|
||||
relResourceDir, err := filepath.Rel(rootSrcDir, resourceDir)
|
||||
if err != nil {
|
||||
ctx.ModuleErrorf("resource directory %q is not in source tree", resourceDir)
|
||||
continue
|
||||
}
|
||||
overlayResourceDir := filepath.Join(overlayDir, relResourceDir)
|
||||
if _, err := os.Stat(overlayResourceDir); err == nil {
|
||||
overlayResourceDirs = append(overlayResourceDirs, overlayResourceDir)
|
||||
} else {
|
||||
// Overlay resource directory doesn't exist, add a dep to regenerate the manifest if
|
||||
// it is created later
|
||||
ctx.AddNinjaFileDeps(overlayResourceDir)
|
||||
overlay := overlayDir.OverlayPath(ctx, resourceDir)
|
||||
if overlay.Valid() {
|
||||
overlayResourceDirs = append(overlayResourceDirs, overlay.Path())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,44 +204,46 @@ func (a *AndroidApp) aaptFlags(ctx common.AndroidModuleContext) ([]string, []str
|
||||
|
||||
// aapt needs to rerun if any files are added or modified in the assets or resource directories,
|
||||
// use glob to create a filelist.
|
||||
var aaptDeps []string
|
||||
var aaptDeps common.Paths
|
||||
var hasResources bool
|
||||
for _, d := range resourceDirs {
|
||||
newDeps := ctx.Glob("app_resources", filepath.Join(d, "**/*"), aaptIgnoreFilenames)
|
||||
newDeps := ctx.Glob("app_resources", filepath.Join(d.String(), "**/*"), aaptIgnoreFilenames)
|
||||
aaptDeps = append(aaptDeps, newDeps...)
|
||||
if len(newDeps) > 0 {
|
||||
hasResources = true
|
||||
}
|
||||
}
|
||||
for _, d := range assetDirs {
|
||||
newDeps := ctx.Glob("app_assets", filepath.Join(d, "**/*"), aaptIgnoreFilenames)
|
||||
newDeps := ctx.Glob("app_assets", filepath.Join(d.String(), "**/*"), aaptIgnoreFilenames)
|
||||
aaptDeps = append(aaptDeps, newDeps...)
|
||||
}
|
||||
|
||||
manifestFile := a.properties.Manifest
|
||||
if manifestFile == "" {
|
||||
var manifestFile string
|
||||
if a.properties.Manifest == nil {
|
||||
manifestFile = "AndroidManifest.xml"
|
||||
} else {
|
||||
manifestFile = *a.properties.Manifest
|
||||
}
|
||||
|
||||
manifestFile = filepath.Join(common.ModuleSrcDir(ctx), manifestFile)
|
||||
aaptDeps = append(aaptDeps, manifestFile)
|
||||
manifestPath := common.PathForModuleSrc(ctx, manifestFile)
|
||||
aaptDeps = append(aaptDeps, manifestPath)
|
||||
|
||||
aaptFlags = append(aaptFlags, "-M "+manifestFile)
|
||||
aaptFlags = append(aaptFlags, common.JoinWithPrefix(assetDirs, "-A "))
|
||||
aaptFlags = append(aaptFlags, common.JoinWithPrefix(resourceDirs, "-S "))
|
||||
aaptFlags = append(aaptFlags, "-M "+manifestPath.String())
|
||||
aaptFlags = append(aaptFlags, common.JoinWithPrefix(assetDirs.Strings(), "-A "))
|
||||
aaptFlags = append(aaptFlags, common.JoinWithPrefix(resourceDirs.Strings(), "-S "))
|
||||
|
||||
ctx.VisitDirectDeps(func(module blueprint.Module) {
|
||||
var depFile string
|
||||
var depFile common.OptionalPath
|
||||
if sdkDep, ok := module.(sdkDependency); ok {
|
||||
depFile = sdkDep.ClasspathFile()
|
||||
depFile = common.OptionalPathForPath(sdkDep.ClasspathFile())
|
||||
} else if javaDep, ok := module.(JavaDependency); ok {
|
||||
if ctx.OtherModuleName(module) == "framework-res" {
|
||||
depFile = javaDep.(*javaBase).module.(*AndroidApp).exportPackage
|
||||
depFile = common.OptionalPathForPath(javaDep.(*javaBase).module.(*AndroidApp).exportPackage)
|
||||
}
|
||||
}
|
||||
if depFile != "" {
|
||||
aaptFlags = append(aaptFlags, "-I "+depFile)
|
||||
aaptDeps = append(aaptDeps, depFile)
|
||||
if depFile.Valid() {
|
||||
aaptFlags = append(aaptFlags, "-I "+depFile.String())
|
||||
aaptDeps = append(aaptDeps, depFile.Path())
|
||||
}
|
||||
})
|
||||
|
||||
|
@@ -19,7 +19,6 @@ package java
|
||||
// functions.
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
@@ -75,44 +74,40 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
pctx.StaticVariable("androidManifestMergerCmd", "${srcDir}/prebuilts/devtools/tools/lib/manifest-merger.jar")
|
||||
pctx.VariableFunc("aaptCmd", func(c interface{}) (string, error) {
|
||||
return c.(common.Config).HostBinTool("aapt")
|
||||
})
|
||||
pctx.VariableFunc("signapkCmd", func(c interface{}) (string, error) {
|
||||
return c.(common.Config).HostJavaTool("signapk.jar")
|
||||
})
|
||||
pctx.SourcePathVariable("androidManifestMergerCmd", "prebuilts/devtools/tools/lib/manifest-merger.jar")
|
||||
pctx.HostBinToolVariable("aaptCmd", "aapt")
|
||||
pctx.HostJavaToolVariable("signapkCmd", "signapk.jar")
|
||||
}
|
||||
|
||||
func CreateResourceJavaFiles(ctx common.AndroidModuleContext, flags []string,
|
||||
deps []string) (string, string, string) {
|
||||
javaDir := filepath.Join(common.ModuleGenDir(ctx), "R")
|
||||
javaFileList := filepath.Join(common.ModuleOutDir(ctx), "R.filelist")
|
||||
publicResourcesFile := filepath.Join(common.ModuleOutDir(ctx), "public_resources.xml")
|
||||
proguardOptionsFile := filepath.Join(common.ModuleOutDir(ctx), "proguard.options")
|
||||
deps common.Paths) (common.Path, common.Path, common.Path) {
|
||||
javaDir := common.PathForModuleGen(ctx, "R")
|
||||
javaFileList := common.PathForModuleOut(ctx, "R.filelist")
|
||||
publicResourcesFile := common.PathForModuleOut(ctx, "public_resources.xml")
|
||||
proguardOptionsFile := common.PathForModuleOut(ctx, "proguard.options")
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: aaptCreateResourceJavaFile,
|
||||
Outputs: []string{publicResourcesFile, proguardOptionsFile, javaFileList},
|
||||
Outputs: common.WritablePaths{publicResourcesFile, proguardOptionsFile, javaFileList},
|
||||
Implicits: deps,
|
||||
Args: map[string]string{
|
||||
"aaptFlags": strings.Join(flags, " "),
|
||||
"publicResourcesFile": publicResourcesFile,
|
||||
"proguardOptionsFile": proguardOptionsFile,
|
||||
"javaDir": javaDir,
|
||||
"javaFileList": javaFileList,
|
||||
"publicResourcesFile": publicResourcesFile.String(),
|
||||
"proguardOptionsFile": proguardOptionsFile.String(),
|
||||
"javaDir": javaDir.String(),
|
||||
"javaFileList": javaFileList.String(),
|
||||
},
|
||||
})
|
||||
|
||||
return publicResourcesFile, proguardOptionsFile, javaFileList
|
||||
}
|
||||
|
||||
func CreateExportPackage(ctx common.AndroidModuleContext, flags []string, deps []string) string {
|
||||
outputFile := filepath.Join(common.ModuleOutDir(ctx), "package-export.apk")
|
||||
func CreateExportPackage(ctx common.AndroidModuleContext, flags []string, deps common.Paths) common.ModuleOutPath {
|
||||
outputFile := common.PathForModuleOut(ctx, "package-export.apk")
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: aaptCreateAssetsPackage,
|
||||
Outputs: []string{outputFile},
|
||||
Output: outputFile,
|
||||
Implicits: deps,
|
||||
Args: map[string]string{
|
||||
"aaptFlags": strings.Join(flags, " "),
|
||||
@@ -122,31 +117,31 @@ func CreateExportPackage(ctx common.AndroidModuleContext, flags []string, deps [
|
||||
return outputFile
|
||||
}
|
||||
|
||||
func CreateAppPackage(ctx common.AndroidModuleContext, flags []string, jarFile string,
|
||||
certificates []string) string {
|
||||
func CreateAppPackage(ctx common.AndroidModuleContext, flags []string, jarFile common.Path,
|
||||
certificates []string) common.Path {
|
||||
|
||||
resourceApk := filepath.Join(common.ModuleOutDir(ctx), "resources.apk")
|
||||
resourceApk := common.PathForModuleOut(ctx, "resources.apk")
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: aaptAddResources,
|
||||
Outputs: []string{resourceApk},
|
||||
Inputs: []string{jarFile},
|
||||
Output: resourceApk,
|
||||
Input: jarFile,
|
||||
Args: map[string]string{
|
||||
"aaptFlags": strings.Join(flags, " "),
|
||||
},
|
||||
})
|
||||
|
||||
outputFile := filepath.Join(common.ModuleOutDir(ctx), "package.apk")
|
||||
outputFile := common.PathForModuleOut(ctx, "package.apk")
|
||||
|
||||
var certificateArgs []string
|
||||
for _, c := range certificates {
|
||||
certificateArgs = append(certificateArgs, c+".x509.pem", c+".pk8")
|
||||
}
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: signapk,
|
||||
Outputs: []string{outputFile},
|
||||
Inputs: []string{resourceApk},
|
||||
Output: outputFile,
|
||||
Input: resourceApk,
|
||||
Args: map[string]string{
|
||||
"certificates": strings.Join(certificateArgs, " "),
|
||||
},
|
||||
|
104
java/builder.go
104
java/builder.go
@@ -29,7 +29,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
pctx = blueprint.NewPackageContext("android/soong/java")
|
||||
pctx = common.NewPackageContext("android/soong/java")
|
||||
|
||||
// Compiling java is not conducive to proper dependency tracking. The path-matches-class-name
|
||||
// requirement leads to unpredictable generated source file names, and a single .java file
|
||||
@@ -91,12 +91,8 @@ func init() {
|
||||
pctx.StaticVariable("commonJdkFlags", "-source 1.7 -target 1.7 -Xmaxerrs 9999999")
|
||||
pctx.StaticVariable("javacCmd", "javac -J-Xmx1024M $commonJdkFlags")
|
||||
pctx.StaticVariable("jarCmd", filepath.Join("${bootstrap.BinDir}", "soong_jar"))
|
||||
pctx.VariableFunc("dxCmd", func(c interface{}) (string, error) {
|
||||
return c.(common.Config).HostBinTool("dx")
|
||||
})
|
||||
pctx.VariableFunc("jarjarCmd", func(c interface{}) (string, error) {
|
||||
return c.(common.Config).HostJavaTool("jarjar.jar")
|
||||
})
|
||||
pctx.HostBinToolVariable("dxCmd", "dx")
|
||||
pctx.HostJavaToolVariable("jarjarCmd", "jarjar.jar")
|
||||
}
|
||||
|
||||
type javaBuilderFlags struct {
|
||||
@@ -108,33 +104,33 @@ type javaBuilderFlags struct {
|
||||
}
|
||||
|
||||
type jarSpec struct {
|
||||
fileList, dir string
|
||||
fileList, dir common.Path
|
||||
}
|
||||
|
||||
func (j jarSpec) soongJarArgs() string {
|
||||
return "-C " + j.dir + " -l " + j.fileList
|
||||
return "-C " + j.dir.String() + " -l " + j.fileList.String()
|
||||
}
|
||||
|
||||
func TransformJavaToClasses(ctx common.AndroidModuleContext, srcFiles []string, srcFileLists []string,
|
||||
flags javaBuilderFlags, deps []string) jarSpec {
|
||||
func TransformJavaToClasses(ctx common.AndroidModuleContext, srcFiles common.Paths, srcFileLists common.Paths,
|
||||
flags javaBuilderFlags, deps common.Paths) jarSpec {
|
||||
|
||||
classDir := filepath.Join(common.ModuleOutDir(ctx), "classes")
|
||||
classFileList := filepath.Join(common.ModuleOutDir(ctx), "classes.list")
|
||||
classDir := common.PathForModuleOut(ctx, "classes")
|
||||
classFileList := common.PathForModuleOut(ctx, "classes.list")
|
||||
|
||||
javacFlags := flags.javacFlags + common.JoinWithPrefix(srcFileLists, "@")
|
||||
javacFlags := flags.javacFlags + common.JoinWithPrefix(srcFileLists.Strings(), "@")
|
||||
|
||||
deps = append(deps, srcFileLists...)
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: javac,
|
||||
Outputs: []string{classFileList},
|
||||
Output: classFileList,
|
||||
Inputs: srcFiles,
|
||||
Implicits: deps,
|
||||
Args: map[string]string{
|
||||
"javacFlags": javacFlags,
|
||||
"bootClasspath": flags.bootClasspath,
|
||||
"classpath": flags.classpath,
|
||||
"outDir": classDir,
|
||||
"outDir": classDir.String(),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -142,11 +138,11 @@ func TransformJavaToClasses(ctx common.AndroidModuleContext, srcFiles []string,
|
||||
}
|
||||
|
||||
func TransformClassesToJar(ctx common.AndroidModuleContext, classes []jarSpec,
|
||||
manifest string) string {
|
||||
manifest common.OptionalPath) common.Path {
|
||||
|
||||
outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes-full-debug.jar")
|
||||
outputFile := common.PathForModuleOut(ctx, "classes-full-debug.jar")
|
||||
|
||||
deps := []string{}
|
||||
deps := common.Paths{}
|
||||
jarArgs := []string{}
|
||||
|
||||
for _, j := range classes {
|
||||
@@ -154,14 +150,14 @@ func TransformClassesToJar(ctx common.AndroidModuleContext, classes []jarSpec,
|
||||
jarArgs = append(jarArgs, j.soongJarArgs())
|
||||
}
|
||||
|
||||
if manifest != "" {
|
||||
deps = append(deps, manifest)
|
||||
jarArgs = append(jarArgs, "-m "+manifest)
|
||||
if manifest.Valid() {
|
||||
deps = append(deps, manifest.Path())
|
||||
jarArgs = append(jarArgs, "-m "+manifest.String())
|
||||
}
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: jar,
|
||||
Outputs: []string{outputFile},
|
||||
Output: outputFile,
|
||||
Implicits: deps,
|
||||
Args: map[string]string{
|
||||
"jarArgs": strings.Join(jarArgs, " "),
|
||||
@@ -171,19 +167,19 @@ func TransformClassesToJar(ctx common.AndroidModuleContext, classes []jarSpec,
|
||||
return outputFile
|
||||
}
|
||||
|
||||
func TransformClassesJarToDex(ctx common.AndroidModuleContext, classesJar string,
|
||||
func TransformClassesJarToDex(ctx common.AndroidModuleContext, classesJar common.Path,
|
||||
flags javaBuilderFlags) jarSpec {
|
||||
|
||||
outDir := filepath.Join(common.ModuleOutDir(ctx), "dex")
|
||||
outputFile := filepath.Join(common.ModuleOutDir(ctx), "dex.filelist")
|
||||
outDir := common.PathForModuleOut(ctx, "dex")
|
||||
outputFile := common.PathForModuleOut(ctx, "dex.filelist")
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: dx,
|
||||
Outputs: []string{outputFile},
|
||||
Inputs: []string{classesJar},
|
||||
Output: outputFile,
|
||||
Input: classesJar,
|
||||
Args: map[string]string{
|
||||
"dxFlags": flags.dxFlags,
|
||||
"outDir": outDir,
|
||||
"outDir": outDir.String(),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -191,10 +187,10 @@ func TransformClassesJarToDex(ctx common.AndroidModuleContext, classesJar string
|
||||
}
|
||||
|
||||
func TransformDexToJavaLib(ctx common.AndroidModuleContext, resources []jarSpec,
|
||||
dexJarSpec jarSpec) string {
|
||||
dexJarSpec jarSpec) common.Path {
|
||||
|
||||
outputFile := filepath.Join(common.ModuleOutDir(ctx), "javalib.jar")
|
||||
var deps []string
|
||||
outputFile := common.PathForModuleOut(ctx, "javalib.jar")
|
||||
var deps common.Paths
|
||||
var jarArgs []string
|
||||
|
||||
for _, j := range resources {
|
||||
@@ -205,9 +201,9 @@ func TransformDexToJavaLib(ctx common.AndroidModuleContext, resources []jarSpec,
|
||||
deps = append(deps, dexJarSpec.fileList)
|
||||
jarArgs = append(jarArgs, dexJarSpec.soongJarArgs())
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: jar,
|
||||
Outputs: []string{outputFile},
|
||||
Output: outputFile,
|
||||
Implicits: deps,
|
||||
Args: map[string]string{
|
||||
"jarArgs": strings.Join(jarArgs, " "),
|
||||
@@ -217,14 +213,15 @@ func TransformDexToJavaLib(ctx common.AndroidModuleContext, resources []jarSpec,
|
||||
return outputFile
|
||||
}
|
||||
|
||||
func TransformJarJar(ctx common.AndroidModuleContext, classesJar string, rulesFile string) string {
|
||||
outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes-jarjar.jar")
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
func TransformJarJar(ctx common.AndroidModuleContext, classesJar common.Path, rulesFile common.Path) common.Path {
|
||||
outputFile := common.PathForModuleOut(ctx, "classes-jarjar.jar")
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: jarjar,
|
||||
Outputs: []string{outputFile},
|
||||
Inputs: []string{classesJar},
|
||||
Output: outputFile,
|
||||
Input: classesJar,
|
||||
Implicit: rulesFile,
|
||||
Args: map[string]string{
|
||||
"rulesFile": rulesFile,
|
||||
"rulesFile": rulesFile.String(),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -232,21 +229,20 @@ func TransformJarJar(ctx common.AndroidModuleContext, classesJar string, rulesFi
|
||||
}
|
||||
|
||||
func TransformPrebuiltJarToClasses(ctx common.AndroidModuleContext,
|
||||
prebuilt string) (classJarSpec, resourceJarSpec jarSpec) {
|
||||
prebuilt common.Path) (classJarSpec, resourceJarSpec jarSpec) {
|
||||
|
||||
extractedDir := filepath.Join(common.ModuleOutDir(ctx), "extracted")
|
||||
classDir := filepath.Join(extractedDir, "classes")
|
||||
classFileList := filepath.Join(extractedDir, "classes.list")
|
||||
resourceFileList := filepath.Join(extractedDir, "resources.list")
|
||||
classDir := common.PathForModuleOut(ctx, "extracted/classes")
|
||||
classFileList := common.PathForModuleOut(ctx, "extracted/classes.list")
|
||||
resourceFileList := common.PathForModuleOut(ctx, "extracted/resources.list")
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: extractPrebuilt,
|
||||
Outputs: []string{classFileList, resourceFileList},
|
||||
Inputs: []string{prebuilt},
|
||||
Outputs: common.WritablePaths{classFileList, resourceFileList},
|
||||
Input: prebuilt,
|
||||
Args: map[string]string{
|
||||
"outDir": classDir,
|
||||
"classFile": classFileList,
|
||||
"resourceFile": resourceFileList,
|
||||
"outDir": classDir.String(),
|
||||
"classFile": classFileList.String(),
|
||||
"resourceFile": resourceFileList.String(),
|
||||
},
|
||||
})
|
||||
|
||||
|
54
java/gen.go
54
java/gen.go
@@ -19,25 +19,17 @@ package java
|
||||
// functions.
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
|
||||
"android/soong/common"
|
||||
)
|
||||
|
||||
func init() {
|
||||
pctx.VariableFunc("aidlCmd", func(c interface{}) (string, error) {
|
||||
return c.(common.Config).HostBinTool("aidl")
|
||||
})
|
||||
pctx.StaticVariable("logtagsCmd", "${srcDir}/build/tools/java-event-log-tags.py")
|
||||
pctx.StaticVariable("mergeLogtagsCmd", "${srcDir}/build/tools/merge-event-log-tags.py")
|
||||
pctx.VariableConfigMethod("srcDir", common.Config.SrcDir)
|
||||
pctx.HostBinToolVariable("aidlCmd", "aidl")
|
||||
pctx.SourcePathVariable("logtagsCmd", "build/tools/java-event-log-tags.py")
|
||||
pctx.SourcePathVariable("mergeLogtagsCmd", "build/tools/merge-event-log-tags.py")
|
||||
|
||||
pctx.VariableFunc("allLogtagsFile", func(c interface{}) (string, error) {
|
||||
return filepath.Join(c.(common.Config).IntermediatesDir(), "all-event-log-tags.txt"), nil
|
||||
})
|
||||
pctx.IntermediatesPathVariable("allLogtagsFile", "all-event-log-tags.txt")
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -64,16 +56,14 @@ var (
|
||||
})
|
||||
)
|
||||
|
||||
func genAidl(ctx common.AndroidModuleContext, aidlFile, aidlFlags string) string {
|
||||
javaFile := common.SrcDirRelPath(ctx, aidlFile)
|
||||
javaFile = filepath.Join(common.ModuleGenDir(ctx), javaFile)
|
||||
javaFile = pathtools.ReplaceExtension(javaFile, "java")
|
||||
depFile := javaFile + ".d"
|
||||
func genAidl(ctx common.AndroidModuleContext, aidlFile common.Path, aidlFlags string) common.Path {
|
||||
javaFile := common.GenPathWithExt(ctx, aidlFile, "java")
|
||||
depFile := javaFile.String() + ".d"
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: aidl,
|
||||
Outputs: []string{javaFile},
|
||||
Inputs: []string{aidlFile},
|
||||
Output: javaFile,
|
||||
Input: aidlFile,
|
||||
Args: map[string]string{
|
||||
"depFile": depFile,
|
||||
"aidlFlags": aidlFlags,
|
||||
@@ -83,25 +73,23 @@ func genAidl(ctx common.AndroidModuleContext, aidlFile, aidlFlags string) string
|
||||
return javaFile
|
||||
}
|
||||
|
||||
func genLogtags(ctx common.AndroidModuleContext, logtagsFile string) string {
|
||||
javaFile := common.SrcDirRelPath(ctx, logtagsFile)
|
||||
javaFile = filepath.Join(common.ModuleGenDir(ctx), javaFile)
|
||||
javaFile = pathtools.ReplaceExtension(javaFile, "java")
|
||||
func genLogtags(ctx common.AndroidModuleContext, logtagsFile common.Path) common.Path {
|
||||
javaFile := common.GenPathWithExt(ctx, logtagsFile, "java")
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
|
||||
Rule: logtags,
|
||||
Outputs: []string{javaFile},
|
||||
Inputs: []string{logtagsFile},
|
||||
Output: javaFile,
|
||||
Input: logtagsFile,
|
||||
})
|
||||
|
||||
return javaFile
|
||||
}
|
||||
|
||||
func (j *javaBase) genSources(ctx common.AndroidModuleContext, srcFiles []string,
|
||||
flags javaBuilderFlags) []string {
|
||||
func (j *javaBase) genSources(ctx common.AndroidModuleContext, srcFiles common.Paths,
|
||||
flags javaBuilderFlags) common.Paths {
|
||||
|
||||
for i, srcFile := range srcFiles {
|
||||
switch filepath.Ext(srcFile) {
|
||||
switch srcFile.Ext() {
|
||||
case ".aidl":
|
||||
javaFile := genAidl(ctx, srcFile, flags.aidlFlags)
|
||||
srcFiles[i] = javaFile
|
||||
@@ -120,13 +108,13 @@ func LogtagsSingleton() blueprint.Singleton {
|
||||
}
|
||||
|
||||
type logtagsProducer interface {
|
||||
logtags() []string
|
||||
logtags() common.Paths
|
||||
}
|
||||
|
||||
type logtagsSingleton struct{}
|
||||
|
||||
func (l *logtagsSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
|
||||
var allLogtags []string
|
||||
var allLogtags common.Paths
|
||||
ctx.VisitAllModules(func(module blueprint.Module) {
|
||||
if logtags, ok := module.(logtagsProducer); ok {
|
||||
allLogtags = append(allLogtags, logtags.logtags()...)
|
||||
@@ -136,6 +124,6 @@ func (l *logtagsSingleton) GenerateBuildActions(ctx blueprint.SingletonContext)
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
Rule: mergeLogtags,
|
||||
Outputs: []string{"$allLogtagsFile"},
|
||||
Inputs: allLogtags,
|
||||
Inputs: allLogtags.Strings(),
|
||||
})
|
||||
}
|
||||
|
106
java/java.go
106
java/java.go
@@ -20,11 +20,9 @@ package java
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
|
||||
"android/soong"
|
||||
"android/soong/common"
|
||||
@@ -93,7 +91,7 @@ type javaBaseProperties struct {
|
||||
Java_static_libs []string `android:"arch_variant"`
|
||||
|
||||
// manifest file to be included in resulting jar
|
||||
Manifest string
|
||||
Manifest *string
|
||||
|
||||
// if not blank, set to the version of the sdk to compile against
|
||||
Sdk_version string
|
||||
@@ -103,7 +101,7 @@ type javaBaseProperties struct {
|
||||
Dex bool `blueprint:"mutated"`
|
||||
|
||||
// if not blank, run jarjar using the specified rules file
|
||||
Jarjar_rules string
|
||||
Jarjar_rules *string
|
||||
|
||||
// directories to pass to aidl tool
|
||||
Aidl_includes []string
|
||||
@@ -122,10 +120,10 @@ type javaBase struct {
|
||||
properties javaBaseProperties
|
||||
|
||||
// output file suitable for inserting into the classpath of another compile
|
||||
classpathFile string
|
||||
classpathFile common.Path
|
||||
|
||||
// output file suitable for installing or running
|
||||
outputFile string
|
||||
outputFile common.Path
|
||||
|
||||
// jarSpecs suitable for inserting classes from a static library into another jar
|
||||
classJarSpecs []jarSpec
|
||||
@@ -133,16 +131,16 @@ type javaBase struct {
|
||||
// jarSpecs suitable for inserting resources from a static library into another jar
|
||||
resourceJarSpecs []jarSpec
|
||||
|
||||
exportAidlIncludeDirs []string
|
||||
exportAidlIncludeDirs common.Paths
|
||||
|
||||
logtagsSrcs []string
|
||||
logtagsSrcs common.Paths
|
||||
|
||||
// filelists of extra source files that should be included in the javac command line,
|
||||
// for example R.java generated by aapt for android apps
|
||||
ExtraSrcLists []string
|
||||
ExtraSrcLists common.Paths
|
||||
|
||||
// installed file for binary dependency
|
||||
installFile string
|
||||
installFile common.Path
|
||||
}
|
||||
|
||||
type AndroidJavaModuleContext common.AndroidBaseContext
|
||||
@@ -153,10 +151,10 @@ type JavaModuleType interface {
|
||||
}
|
||||
|
||||
type JavaDependency interface {
|
||||
ClasspathFile() string
|
||||
ClasspathFile() common.Path
|
||||
ClassJarSpecs() []jarSpec
|
||||
ResourceJarSpecs() []jarSpec
|
||||
AidlIncludeDirs() []string
|
||||
AidlIncludeDirs() common.Paths
|
||||
}
|
||||
|
||||
func NewJavaBase(base *javaBase, module JavaModuleType, hod common.HostOrDeviceSupported,
|
||||
@@ -217,35 +215,35 @@ func (j *javaBase) JavaDependencies(ctx AndroidJavaModuleContext) []string {
|
||||
return deps
|
||||
}
|
||||
|
||||
func (j *javaBase) aidlFlags(ctx common.AndroidModuleContext, aidlPreprocess string,
|
||||
aidlIncludeDirs []string) []string {
|
||||
func (j *javaBase) aidlFlags(ctx common.AndroidModuleContext, aidlPreprocess common.OptionalPath,
|
||||
aidlIncludeDirs common.Paths) []string {
|
||||
|
||||
localAidlIncludes := pathtools.PrefixPaths(j.properties.Aidl_includes, common.ModuleSrcDir(ctx))
|
||||
localAidlIncludes := common.PathsForModuleSrc(ctx, j.properties.Aidl_includes)
|
||||
|
||||
var flags []string
|
||||
if aidlPreprocess != "" {
|
||||
flags = append(flags, "-p"+aidlPreprocess)
|
||||
if aidlPreprocess.Valid() {
|
||||
flags = append(flags, "-p"+aidlPreprocess.String())
|
||||
} else {
|
||||
flags = append(flags, common.JoinWithPrefix(aidlIncludeDirs, "-I"))
|
||||
flags = append(flags, common.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
|
||||
}
|
||||
|
||||
flags = append(flags, common.JoinWithPrefix(j.exportAidlIncludeDirs, "-I"))
|
||||
flags = append(flags, common.JoinWithPrefix(localAidlIncludes, "-I"))
|
||||
flags = append(flags, "-I"+common.ModuleSrcDir(ctx))
|
||||
flags = append(flags, "-I"+filepath.Join(common.ModuleSrcDir(ctx), "src"))
|
||||
flags = append(flags, common.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I"))
|
||||
flags = append(flags, common.JoinWithPrefix(localAidlIncludes.Strings(), "-I"))
|
||||
flags = append(flags, "-I"+common.PathForModuleSrc(ctx).String())
|
||||
flags = append(flags, "-I"+common.PathForModuleSrc(ctx, "src").String())
|
||||
|
||||
return flags
|
||||
}
|
||||
|
||||
func (j *javaBase) collectDeps(ctx common.AndroidModuleContext) (classpath []string,
|
||||
bootClasspath string, classJarSpecs, resourceJarSpecs []jarSpec, aidlPreprocess string,
|
||||
aidlIncludeDirs []string, srcFileLists []string) {
|
||||
func (j *javaBase) collectDeps(ctx common.AndroidModuleContext) (classpath common.Paths,
|
||||
bootClasspath common.OptionalPath, classJarSpecs, resourceJarSpecs []jarSpec, aidlPreprocess common.OptionalPath,
|
||||
aidlIncludeDirs common.Paths, srcFileLists common.Paths) {
|
||||
|
||||
ctx.VisitDirectDeps(func(module blueprint.Module) {
|
||||
otherName := ctx.OtherModuleName(module)
|
||||
if javaDep, ok := module.(JavaDependency); ok {
|
||||
if otherName == j.BootClasspath(ctx) {
|
||||
bootClasspath = javaDep.ClasspathFile()
|
||||
bootClasspath = common.OptionalPathForPath(javaDep.ClasspathFile())
|
||||
} else if inList(otherName, defaultJavaLibraries) {
|
||||
classpath = append(classpath, javaDep.ClasspathFile())
|
||||
} else if inList(otherName, j.properties.Java_libs) {
|
||||
@@ -265,8 +263,8 @@ func (j *javaBase) collectDeps(ctx common.AndroidModuleContext) (classpath []str
|
||||
}
|
||||
aidlIncludeDirs = append(aidlIncludeDirs, javaDep.AidlIncludeDirs()...)
|
||||
if sdkDep, ok := module.(sdkDependency); ok {
|
||||
if sdkDep.AidlPreprocessed() != "" {
|
||||
if aidlPreprocess != "" {
|
||||
if sdkDep.AidlPreprocessed().Valid() {
|
||||
if aidlPreprocess.Valid() {
|
||||
ctx.ModuleErrorf("multiple dependencies with preprocessed aidls:\n %q\n %q",
|
||||
aidlPreprocess, sdkDep.AidlPreprocessed())
|
||||
} else {
|
||||
@@ -287,8 +285,7 @@ func (j *javaBase) GenerateAndroidBuildActions(ctx common.AndroidModuleContext)
|
||||
|
||||
func (j *javaBase) GenerateJavaBuildActions(ctx common.AndroidModuleContext) {
|
||||
|
||||
j.exportAidlIncludeDirs = pathtools.PrefixPaths(j.properties.Export_aidl_include_dirs,
|
||||
common.ModuleSrcDir(ctx))
|
||||
j.exportAidlIncludeDirs = common.PathsForModuleSrc(ctx, j.properties.Export_aidl_include_dirs)
|
||||
|
||||
classpath, bootClasspath, classJarSpecs, resourceJarSpecs, aidlPreprocess,
|
||||
aidlIncludeDirs, srcFileLists := j.collectDeps(ctx)
|
||||
@@ -307,15 +304,15 @@ func (j *javaBase) GenerateJavaBuildActions(ctx common.AndroidModuleContext) {
|
||||
flags.aidlFlags = "$aidlFlags"
|
||||
}
|
||||
|
||||
var javacDeps []string
|
||||
var javacDeps common.Paths
|
||||
|
||||
if bootClasspath != "" {
|
||||
flags.bootClasspath = "-bootclasspath " + bootClasspath
|
||||
javacDeps = append(javacDeps, bootClasspath)
|
||||
if bootClasspath.Valid() {
|
||||
flags.bootClasspath = "-bootclasspath " + bootClasspath.String()
|
||||
javacDeps = append(javacDeps, bootClasspath.Path())
|
||||
}
|
||||
|
||||
if len(classpath) > 0 {
|
||||
flags.classpath = "-classpath " + strings.Join(classpath, ":")
|
||||
flags.classpath = "-classpath " + strings.Join(classpath.Strings(), ":")
|
||||
javacDeps = append(javacDeps, classpath...)
|
||||
}
|
||||
|
||||
@@ -344,10 +341,7 @@ func (j *javaBase) GenerateJavaBuildActions(ctx common.AndroidModuleContext) {
|
||||
resourceJarSpecs = append(ResourceDirsToJarSpecs(ctx, j.properties.Java_resource_dirs, j.properties.Exclude_java_resource_dirs),
|
||||
resourceJarSpecs...)
|
||||
|
||||
manifest := j.properties.Manifest
|
||||
if manifest != "" {
|
||||
manifest = filepath.Join(common.ModuleSrcDir(ctx), manifest)
|
||||
}
|
||||
manifest := common.OptionalPathForModuleSrc(ctx, j.properties.Manifest)
|
||||
|
||||
allJarSpecs := append([]jarSpec(nil), classJarSpecs...)
|
||||
allJarSpecs = append(allJarSpecs, resourceJarSpecs...)
|
||||
@@ -358,8 +352,8 @@ func (j *javaBase) GenerateJavaBuildActions(ctx common.AndroidModuleContext) {
|
||||
return
|
||||
}
|
||||
|
||||
if j.properties.Jarjar_rules != "" {
|
||||
jarjar_rules := filepath.Join(common.ModuleSrcDir(ctx), j.properties.Jarjar_rules)
|
||||
if j.properties.Jarjar_rules != nil {
|
||||
jarjar_rules := common.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
|
||||
// Transform classes-full-debug.jar into classes-jarjar.jar
|
||||
outputFile = TransformJarJar(ctx, outputFile, jarjar_rules)
|
||||
if ctx.Failed() {
|
||||
@@ -394,7 +388,7 @@ func (j *javaBase) GenerateJavaBuildActions(ctx common.AndroidModuleContext) {
|
||||
dxFlags = append(dxFlags,
|
||||
"--debug",
|
||||
"--verbose",
|
||||
"--dump-to="+filepath.Join(common.ModuleOutDir(ctx), "classes.lst"),
|
||||
"--dump-to="+common.PathForModuleOut(ctx, "classes.lst").String(),
|
||||
"--dump-width=1000")
|
||||
}
|
||||
|
||||
@@ -415,7 +409,7 @@ func (j *javaBase) GenerateJavaBuildActions(ctx common.AndroidModuleContext) {
|
||||
|
||||
var _ JavaDependency = (*JavaLibrary)(nil)
|
||||
|
||||
func (j *javaBase) ClasspathFile() string {
|
||||
func (j *javaBase) ClasspathFile() common.Path {
|
||||
return j.classpathFile
|
||||
}
|
||||
|
||||
@@ -427,13 +421,13 @@ func (j *javaBase) ResourceJarSpecs() []jarSpec {
|
||||
return j.resourceJarSpecs
|
||||
}
|
||||
|
||||
func (j *javaBase) AidlIncludeDirs() []string {
|
||||
func (j *javaBase) AidlIncludeDirs() common.Paths {
|
||||
return j.exportAidlIncludeDirs
|
||||
}
|
||||
|
||||
var _ logtagsProducer = (*javaBase)(nil)
|
||||
|
||||
func (j *javaBase) logtags() []string {
|
||||
func (j *javaBase) logtags() common.Paths {
|
||||
return j.logtagsSrcs
|
||||
}
|
||||
|
||||
@@ -485,7 +479,7 @@ func (j *JavaBinary) GenerateJavaBuildActions(ctx common.AndroidModuleContext) {
|
||||
|
||||
// Depend on the installed jar (j.installFile) so that the wrapper doesn't get executed by
|
||||
// another build rule before the jar has been installed.
|
||||
ctx.InstallFile("bin", filepath.Join(common.ModuleSrcDir(ctx), j.binaryProperties.Wrapper),
|
||||
ctx.InstallFile("bin", common.PathForModuleSrc(ctx, j.binaryProperties.Wrapper),
|
||||
j.installFile)
|
||||
}
|
||||
|
||||
@@ -516,7 +510,7 @@ type JavaPrebuilt struct {
|
||||
|
||||
properties javaPrebuiltProperties
|
||||
|
||||
classpathFile string
|
||||
classpathFile common.Path
|
||||
classJarSpecs, resourceJarSpecs []jarSpec
|
||||
}
|
||||
|
||||
@@ -525,7 +519,7 @@ func (j *JavaPrebuilt) GenerateAndroidBuildActions(ctx common.AndroidModuleConte
|
||||
ctx.ModuleErrorf("expected exactly one jar in srcs")
|
||||
return
|
||||
}
|
||||
prebuilt := filepath.Join(common.ModuleSrcDir(ctx), j.properties.Srcs[0])
|
||||
prebuilt := common.PathForModuleSrc(ctx, j.properties.Srcs[0])
|
||||
|
||||
classJarSpec, resourceJarSpec := TransformPrebuiltJarToClasses(ctx, prebuilt)
|
||||
|
||||
@@ -537,7 +531,7 @@ func (j *JavaPrebuilt) GenerateAndroidBuildActions(ctx common.AndroidModuleConte
|
||||
|
||||
var _ JavaDependency = (*JavaPrebuilt)(nil)
|
||||
|
||||
func (j *JavaPrebuilt) ClasspathFile() string {
|
||||
func (j *JavaPrebuilt) ClasspathFile() common.Path {
|
||||
return j.classpathFile
|
||||
}
|
||||
|
||||
@@ -549,7 +543,7 @@ func (j *JavaPrebuilt) ResourceJarSpecs() []jarSpec {
|
||||
return j.resourceJarSpecs
|
||||
}
|
||||
|
||||
func (j *JavaPrebuilt) AidlIncludeDirs() []string {
|
||||
func (j *JavaPrebuilt) AidlIncludeDirs() common.Paths {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -566,13 +560,13 @@ func JavaPrebuiltFactory() (blueprint.Module, []interface{}) {
|
||||
|
||||
type sdkDependency interface {
|
||||
JavaDependency
|
||||
AidlPreprocessed() string
|
||||
AidlPreprocessed() common.OptionalPath
|
||||
}
|
||||
|
||||
var _ sdkDependency = (*sdkPrebuilt)(nil)
|
||||
|
||||
type sdkPrebuiltProperties struct {
|
||||
Aidl_preprocessed string
|
||||
Aidl_preprocessed *string
|
||||
}
|
||||
|
||||
type sdkPrebuilt struct {
|
||||
@@ -580,18 +574,16 @@ type sdkPrebuilt struct {
|
||||
|
||||
sdkProperties sdkPrebuiltProperties
|
||||
|
||||
aidlPreprocessed string
|
||||
aidlPreprocessed common.OptionalPath
|
||||
}
|
||||
|
||||
func (j *sdkPrebuilt) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
|
||||
j.JavaPrebuilt.GenerateAndroidBuildActions(ctx)
|
||||
|
||||
if j.sdkProperties.Aidl_preprocessed != "" {
|
||||
j.aidlPreprocessed = filepath.Join(common.ModuleSrcDir(ctx), j.sdkProperties.Aidl_preprocessed)
|
||||
}
|
||||
j.aidlPreprocessed = common.OptionalPathForModuleSrc(ctx, j.sdkProperties.Aidl_preprocessed)
|
||||
}
|
||||
|
||||
func (j *sdkPrebuilt) AidlPreprocessed() string {
|
||||
func (j *sdkPrebuilt) AidlPreprocessed() common.OptionalPath {
|
||||
return j.aidlPreprocessed
|
||||
}
|
||||
|
||||
|
@@ -42,7 +42,7 @@ func ResourceDirsToJarSpecs(ctx common.AndroidModuleContext, resourceDirs, exclu
|
||||
var excludes []string
|
||||
|
||||
for _, exclude := range excludeDirs {
|
||||
excludes = append(excludes, filepath.Join(common.ModuleSrcDir(ctx), exclude, "**/*"))
|
||||
excludes = append(excludes, common.PathForModuleSrc(ctx, exclude, "**/*").String())
|
||||
}
|
||||
|
||||
excludes = append(excludes, resourceExcludes...)
|
||||
@@ -53,15 +53,14 @@ func ResourceDirsToJarSpecs(ctx common.AndroidModuleContext, resourceDirs, exclu
|
||||
if isStringInSlice(resourceDir, excludeDirs) {
|
||||
continue
|
||||
}
|
||||
resourceDir := filepath.Join(common.ModuleSrcDir(ctx), resourceDir)
|
||||
dirs := ctx.Glob("java_resources", resourceDir, nil)
|
||||
resourceDir := common.PathForModuleSrc(ctx, resourceDir)
|
||||
dirs := ctx.Glob("java_resources", resourceDir.String(), nil)
|
||||
for _, dir := range dirs {
|
||||
relDir := common.SrcDirRelPath(ctx, dir)
|
||||
fileListFile := filepath.Join(common.ModuleOutDir(ctx), "res", relDir, "resources.list")
|
||||
depFile := fileListFile + ".d"
|
||||
fileListFile := common.ResPathWithName(ctx, dir, "resources.list")
|
||||
depFile := fileListFile.String() + ".d"
|
||||
|
||||
glob := filepath.Join(dir, "**/*")
|
||||
common.GlobRule(ctx, glob, excludes, fileListFile, depFile)
|
||||
glob := filepath.Join(dir.String(), "**/*")
|
||||
common.GlobRule(ctx, glob, excludes, fileListFile.String(), depFile)
|
||||
jarSpecs = append(jarSpecs, jarSpec{fileListFile, dir})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user