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:
Dan Willemsen
2015-09-23 15:26:20 -07:00
parent fafa3dc7e2
commit 34cc69e4bf
30 changed files with 1430 additions and 763 deletions

View File

@@ -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,16 +203,16 @@ 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{
Rule: ar,
Outputs: []string{outputFile},
Inputs: objFiles,
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
Rule: ar,
Output: outputFile,
Inputs: objFiles,
Args: map[string]string{
"arFlags": arFlags,
"arCmd": arCmd,
@@ -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,27 +356,27 @@ func TransformObjsToObj(ctx common.AndroidModuleContext, objFiles []string,
ldCmd = gccCmd(flags.toolchain, "g++")
}
ctx.Build(pctx, blueprint.BuildParams{
Rule: partialLd,
Outputs: []string{outputFile},
Inputs: objFiles,
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
Rule: partialLd,
Output: outputFile,
Inputs: objFiles,
Args: map[string]string{
"ldCmd": ldCmd,
"ldCmd": ldCmd,
"ldFlags": flags.ldFlags,
},
})
}
// 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{
Rule: prefixSymbols,
Outputs: []string{outputFile},
Inputs: []string{inputFile},
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
Rule: prefixSymbols,
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{
Rule: copyGccLib,
Outputs: []string{outputFile},
ctx.ModuleBuild(pctx, common.ModuleBuildParams{
Rule: copyGccLib,
Output: outputFile,
Args: map[string]string{
"ccCmd": gccCmd(flags.toolchain, "gcc"),
"cFlags": flags.globalFlags,