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:
130
cc/builder.go
130
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,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,
|
||||
|
Reference in New Issue
Block a user