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
diff --git a/cc/builder.go b/cc/builder.go
index 64437d2..f5fc9ee 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -28,7 +28,6 @@
"strings"
"github.com/google/blueprint"
- "github.com/google/blueprint/pathtools"
)
const (
@@ -37,7 +36,7 @@
)
var (
- pctx = blueprint.NewPackageContext("android/soong/cc")
+ pctx = common.NewPackageContext("android/soong/cc")
cc = pctx.StaticRule("cc",
blueprint.RuleParams{
@@ -102,7 +101,7 @@
},
"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 @@
}
// 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 @@
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 @@
}
// 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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 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,