|
|
@ -70,7 +70,14 @@ var _ moduleErrorf = blueprint.ModuleContext(nil)
|
|
|
|
// reportPathError will register an error with the attached context. It
|
|
|
|
// reportPathError will register an error with the attached context. It
|
|
|
|
// attempts ctx.ModuleErrorf for a better error message first, then falls
|
|
|
|
// attempts ctx.ModuleErrorf for a better error message first, then falls
|
|
|
|
// back to ctx.Errorf.
|
|
|
|
// back to ctx.Errorf.
|
|
|
|
func reportPathError(ctx PathContext, format string, args ...interface{}) {
|
|
|
|
func reportPathError(ctx PathContext, err error) {
|
|
|
|
|
|
|
|
reportPathErrorf(ctx, "%s", err.Error())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// reportPathErrorf 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 reportPathErrorf(ctx PathContext, format string, args ...interface{}) {
|
|
|
|
if mctx, ok := ctx.(moduleErrorf); ok {
|
|
|
|
if mctx, ok := ctx.(moduleErrorf); ok {
|
|
|
|
mctx.ModuleErrorf(format, args...)
|
|
|
|
mctx.ModuleErrorf(format, args...)
|
|
|
|
} else if ectx, ok := ctx.(errorfContext); ok {
|
|
|
|
} else if ectx, ok := ctx.(errorfContext); ok {
|
|
|
@ -121,7 +128,7 @@ func GenPathWithExt(ctx ModuleContext, subdir string, p Path, ext string) Module
|
|
|
|
if path, ok := p.(genPathProvider); ok {
|
|
|
|
if path, ok := p.(genPathProvider); ok {
|
|
|
|
return path.genPathWithExt(ctx, subdir, ext)
|
|
|
|
return path.genPathWithExt(ctx, subdir, ext)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
reportPathError(ctx, "Tried to create generated file from unsupported path: %s(%s)", reflect.TypeOf(p).Name(), p)
|
|
|
|
reportPathErrorf(ctx, "Tried to create generated file from unsupported path: %s(%s)", reflect.TypeOf(p).Name(), p)
|
|
|
|
return PathForModuleGen(ctx)
|
|
|
|
return PathForModuleGen(ctx)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -131,7 +138,7 @@ func ObjPathWithExt(ctx ModuleContext, subdir string, p Path, ext string) Module
|
|
|
|
if path, ok := p.(objPathProvider); ok {
|
|
|
|
if path, ok := p.(objPathProvider); ok {
|
|
|
|
return path.objPathWithExt(ctx, subdir, ext)
|
|
|
|
return path.objPathWithExt(ctx, subdir, ext)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
reportPathError(ctx, "Tried to create object file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
|
|
|
|
reportPathErrorf(ctx, "Tried to create object file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
|
|
|
|
return PathForModuleObj(ctx)
|
|
|
|
return PathForModuleObj(ctx)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -142,7 +149,7 @@ func ResPathWithName(ctx ModuleContext, p Path, name string) ModuleResPath {
|
|
|
|
if path, ok := p.(resPathProvider); ok {
|
|
|
|
if path, ok := p.(resPathProvider); ok {
|
|
|
|
return path.resPathWithName(ctx, name)
|
|
|
|
return path.resPathWithName(ctx, name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
reportPathError(ctx, "Tried to create res file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
|
|
|
|
reportPathErrorf(ctx, "Tried to create res file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
|
|
|
|
return PathForModuleRes(ctx)
|
|
|
|
return PathForModuleRes(ctx)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -188,21 +195,6 @@ type Paths []Path
|
|
|
|
|
|
|
|
|
|
|
|
// PathsForSource returns Paths rooted from SrcDir
|
|
|
|
// PathsForSource returns Paths rooted from SrcDir
|
|
|
|
func PathsForSource(ctx PathContext, paths []string) Paths {
|
|
|
|
func PathsForSource(ctx PathContext, paths []string) Paths {
|
|
|
|
if ctx.Config().AllowMissingDependencies() {
|
|
|
|
|
|
|
|
if modCtx, ok := ctx.(ModuleContext); ok {
|
|
|
|
|
|
|
|
ret := make(Paths, 0, len(paths))
|
|
|
|
|
|
|
|
intermediates := pathForModule(modCtx).withRel("missing")
|
|
|
|
|
|
|
|
for _, path := range paths {
|
|
|
|
|
|
|
|
p := ExistentPathForSource(ctx, intermediates.String(), path)
|
|
|
|
|
|
|
|
if p.Valid() {
|
|
|
|
|
|
|
|
ret = append(ret, p.Path())
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
modCtx.AddMissingDependencies([]string{path})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ret := make(Paths, len(paths))
|
|
|
|
ret := make(Paths, len(paths))
|
|
|
|
for i, path := range paths {
|
|
|
|
for i, path := range paths {
|
|
|
|
ret[i] = PathForSource(ctx, path)
|
|
|
|
ret[i] = PathForSource(ctx, path)
|
|
|
@ -213,10 +205,10 @@ func PathsForSource(ctx PathContext, paths []string) Paths {
|
|
|
|
// ExistentPathsForSources returns a list of Paths rooted from SrcDir that are
|
|
|
|
// ExistentPathsForSources returns a list of Paths rooted from SrcDir that are
|
|
|
|
// found in the tree. If any are not found, they are omitted from the list,
|
|
|
|
// found in the tree. If any are not found, they are omitted from the list,
|
|
|
|
// and dependencies are added so that we're re-run when they are added.
|
|
|
|
// and dependencies are added so that we're re-run when they are added.
|
|
|
|
func ExistentPathsForSources(ctx PathContext, intermediates string, paths []string) Paths {
|
|
|
|
func ExistentPathsForSources(ctx PathContext, paths []string) Paths {
|
|
|
|
ret := make(Paths, 0, len(paths))
|
|
|
|
ret := make(Paths, 0, len(paths))
|
|
|
|
for _, path := range paths {
|
|
|
|
for _, path := range paths {
|
|
|
|
p := ExistentPathForSource(ctx, intermediates, path)
|
|
|
|
p := ExistentPathForSource(ctx, path)
|
|
|
|
if p.Valid() {
|
|
|
|
if p.Valid() {
|
|
|
|
ret = append(ret, p.Path())
|
|
|
|
ret = append(ret, p.Path())
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -246,7 +238,7 @@ func pathsForModuleSrcFromFullPath(ctx ModuleContext, paths []string) Paths {
|
|
|
|
for _, p := range paths {
|
|
|
|
for _, p := range paths {
|
|
|
|
path := filepath.Clean(p)
|
|
|
|
path := filepath.Clean(p)
|
|
|
|
if !strings.HasPrefix(path, prefix) {
|
|
|
|
if !strings.HasPrefix(path, prefix) {
|
|
|
|
reportPathError(ctx, "Path '%s' is not in module source directory '%s'", p, prefix)
|
|
|
|
reportPathErrorf(ctx, "Path '%s' is not in module source directory '%s'", p, prefix)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret = append(ret, PathForModuleSrc(ctx, path[len(prefix):]))
|
|
|
|
ret = append(ret, PathForModuleSrc(ctx, path[len(prefix):]))
|
|
|
@ -477,118 +469,124 @@ func (p SourcePath) withRel(rel string) SourcePath {
|
|
|
|
// safePathForSource is for paths that we expect are safe -- only for use by go
|
|
|
|
// safePathForSource is for paths that we expect are safe -- only for use by go
|
|
|
|
// code that is embedding ninja variables in paths
|
|
|
|
// code that is embedding ninja variables in paths
|
|
|
|
func safePathForSource(ctx PathContext, path string) SourcePath {
|
|
|
|
func safePathForSource(ctx PathContext, path string) SourcePath {
|
|
|
|
p := validateSafePath(ctx, path)
|
|
|
|
p, err := validateSafePath(path)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
ret := SourcePath{basePath{p, ctx.Config(), ""}}
|
|
|
|
ret := SourcePath{basePath{p, ctx.Config(), ""}}
|
|
|
|
|
|
|
|
|
|
|
|
abs, err := filepath.Abs(ret.String())
|
|
|
|
abs, err := filepath.Abs(ret.String())
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
reportPathError(ctx, "%s", err.Error())
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
return ret
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
buildroot, err := filepath.Abs(ctx.Config().buildDir)
|
|
|
|
buildroot, err := filepath.Abs(ctx.Config().buildDir)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
reportPathError(ctx, "%s", err.Error())
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
return ret
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if strings.HasPrefix(abs, buildroot) {
|
|
|
|
if strings.HasPrefix(abs, buildroot) {
|
|
|
|
reportPathError(ctx, "source path %s is in output", abs)
|
|
|
|
reportPathErrorf(ctx, "source path %s is in output", abs)
|
|
|
|
return ret
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ret
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// pathForSource creates a SourcePath from pathComponents, but does not check that it exists.
|
|
|
|
|
|
|
|
func pathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) {
|
|
|
|
|
|
|
|
p, err := validatePath(pathComponents...)
|
|
|
|
|
|
|
|
ret := SourcePath{basePath{p, ctx.Config(), ""}}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return ret, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
abs, err := filepath.Abs(ret.String())
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return ret, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
buildroot, err := filepath.Abs(ctx.Config().buildDir)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return ret, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if strings.HasPrefix(abs, buildroot) {
|
|
|
|
|
|
|
|
return ret, fmt.Errorf("source path %s is in output", abs)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if pathtools.IsGlob(ret.String()) {
|
|
|
|
|
|
|
|
return ret, fmt.Errorf("path may not contain a glob: %s", ret.String())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ret, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// existsWithDependencies returns true if the path exists, and adds appropriate dependencies to rerun if the
|
|
|
|
|
|
|
|
// path does not exist.
|
|
|
|
|
|
|
|
func existsWithDependencies(ctx PathContext, path SourcePath) (exists bool, err error) {
|
|
|
|
|
|
|
|
var files []string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if gctx, ok := ctx.(PathGlobContext); ok {
|
|
|
|
|
|
|
|
// Use glob to produce proper dependencies, even though we only want
|
|
|
|
|
|
|
|
// a single file.
|
|
|
|
|
|
|
|
files, err = gctx.GlobWithDeps(path.String(), nil)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
var deps []string
|
|
|
|
|
|
|
|
// We cannot add build statements in this context, so we fall back to
|
|
|
|
|
|
|
|
// AddNinjaFileDeps
|
|
|
|
|
|
|
|
files, deps, err = pathtools.Glob(path.String(), nil)
|
|
|
|
|
|
|
|
ctx.AddNinjaFileDeps(deps...)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return false, fmt.Errorf("glob: %s", err.Error())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return len(files) > 0, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// PathForSource joins the provided path components and validates that the result
|
|
|
|
// PathForSource joins the provided path components and validates that the result
|
|
|
|
// neither escapes the source dir nor is in the out dir.
|
|
|
|
// neither escapes the source dir nor is in the out dir.
|
|
|
|
// On error, it will return a usable, but invalid SourcePath, and report a ModuleError.
|
|
|
|
// On error, it will return a usable, but invalid SourcePath, and report a ModuleError.
|
|
|
|
func PathForSource(ctx PathContext, pathComponents ...string) SourcePath {
|
|
|
|
func PathForSource(ctx PathContext, pathComponents ...string) SourcePath {
|
|
|
|
p := validatePath(ctx, pathComponents...)
|
|
|
|
path, err := pathForSource(ctx, pathComponents...)
|
|
|
|
ret := SourcePath{basePath{p, ctx.Config(), ""}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
abs, err := filepath.Abs(ret.String())
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
reportPathError(ctx, "%s", err.Error())
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
return ret
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
buildroot, err := filepath.Abs(ctx.Config().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 exists, _, err := ctx.Fs().Exists(ret.String()); err != nil {
|
|
|
|
if modCtx, ok := ctx.(ModuleContext); ok && ctx.Config().AllowMissingDependencies() {
|
|
|
|
reportPathError(ctx, "%s: %s", ret, err.Error())
|
|
|
|
exists, err := existsWithDependencies(ctx, path)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if !exists {
|
|
|
|
|
|
|
|
modCtx.AddMissingDependencies([]string{path.String()})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if exists, _, err := ctx.Fs().Exists(path.String()); err != nil {
|
|
|
|
|
|
|
|
reportPathErrorf(ctx, "%s: %s", path, err.Error())
|
|
|
|
} else if !exists {
|
|
|
|
} else if !exists {
|
|
|
|
reportPathError(ctx, "source path %s does not exist", ret)
|
|
|
|
reportPathErrorf(ctx, "source path %s does not exist", path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
return path
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ExistentPathForSource returns an OptionalPath with the SourcePath if the
|
|
|
|
// ExistentPathForSource returns an OptionalPath with the SourcePath if the
|
|
|
|
// path exists, or an empty OptionalPath if it doesn't exist. Dependencies are added
|
|
|
|
// 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.
|
|
|
|
// so that the ninja file will be regenerated if the state of the path changes.
|
|
|
|
func ExistentPathForSource(ctx PathContext, intermediates string, pathComponents ...string) OptionalPath {
|
|
|
|
func ExistentPathForSource(ctx PathContext, pathComponents ...string) OptionalPath {
|
|
|
|
if len(pathComponents) == 0 {
|
|
|
|
path, err := pathForSource(ctx, pathComponents...)
|
|
|
|
// For when someone forgets the 'intermediates' argument
|
|
|
|
|
|
|
|
panic("Missing path(s)")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p := validatePath(ctx, pathComponents...)
|
|
|
|
|
|
|
|
path := SourcePath{basePath{p, ctx.Config(), ""}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
abs, err := filepath.Abs(path.String())
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
reportPathError(ctx, "%s", err.Error())
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
return OptionalPath{}
|
|
|
|
return OptionalPath{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
buildroot, err := filepath.Abs(ctx.Config().buildDir)
|
|
|
|
|
|
|
|
|
|
|
|
exists, err := existsWithDependencies(ctx, path)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
reportPathError(ctx, "%s", err.Error())
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
return OptionalPath{}
|
|
|
|
return OptionalPath{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if strings.HasPrefix(abs, buildroot) {
|
|
|
|
if !exists {
|
|
|
|
reportPathError(ctx, "source path %s is in output", abs)
|
|
|
|
|
|
|
|
return OptionalPath{}
|
|
|
|
return OptionalPath{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if pathtools.IsGlob(path.String()) {
|
|
|
|
|
|
|
|
reportPathError(ctx, "path may not contain a glob: %s", path.String())
|
|
|
|
|
|
|
|
return OptionalPath{}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if gctx, ok := ctx.(PathGlobContext); ok {
|
|
|
|
|
|
|
|
// Use glob to produce proper dependencies, even though we only want
|
|
|
|
|
|
|
|
// a single file.
|
|
|
|
|
|
|
|
files, err := gctx.GlobWithDeps(path.String(), nil)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, "glob: %s", err.Error())
|
|
|
|
|
|
|
|
return OptionalPath{}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if len(files) == 0 {
|
|
|
|
|
|
|
|
return OptionalPath{}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// We cannot add build statements in this context, so we fall back to
|
|
|
|
|
|
|
|
// AddNinjaFileDeps
|
|
|
|
|
|
|
|
files, dirs, err := pathtools.Glob(path.String(), nil)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, "glob: %s", err.Error())
|
|
|
|
|
|
|
|
return OptionalPath{}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ctx.AddNinjaFileDeps(dirs...)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if len(files) == 0 {
|
|
|
|
|
|
|
|
return OptionalPath{}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ctx.AddNinjaFileDeps(path.String())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return OptionalPathForPath(path)
|
|
|
|
return OptionalPathForPath(path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -599,7 +597,10 @@ func (p SourcePath) String() string {
|
|
|
|
// Join creates a new SourcePath with paths... joined with the current path. The
|
|
|
|
// Join creates a new SourcePath with paths... joined with the current path. The
|
|
|
|
// provided paths... may not use '..' to escape from the current path.
|
|
|
|
// provided paths... may not use '..' to escape from the current path.
|
|
|
|
func (p SourcePath) Join(ctx PathContext, paths ...string) SourcePath {
|
|
|
|
func (p SourcePath) Join(ctx PathContext, paths ...string) SourcePath {
|
|
|
|
path := validatePath(ctx, paths...)
|
|
|
|
path, err := validatePath(paths...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
return p.withRel(path)
|
|
|
|
return p.withRel(path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -612,17 +613,17 @@ func (p SourcePath) OverlayPath(ctx ModuleContext, path Path) OptionalPath {
|
|
|
|
} else if srcPath, ok := path.(SourcePath); ok {
|
|
|
|
} else if srcPath, ok := path.(SourcePath); ok {
|
|
|
|
relDir = srcPath.path
|
|
|
|
relDir = srcPath.path
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
reportPathError(ctx, "Cannot find relative path for %s(%s)", reflect.TypeOf(path).Name(), path)
|
|
|
|
reportPathErrorf(ctx, "Cannot find relative path for %s(%s)", reflect.TypeOf(path).Name(), path)
|
|
|
|
return OptionalPath{}
|
|
|
|
return OptionalPath{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dir := filepath.Join(p.config.srcDir, p.path, relDir)
|
|
|
|
dir := filepath.Join(p.config.srcDir, p.path, relDir)
|
|
|
|
// Use Glob so that we are run again if the directory is added.
|
|
|
|
// Use Glob so that we are run again if the directory is added.
|
|
|
|
if pathtools.IsGlob(dir) {
|
|
|
|
if pathtools.IsGlob(dir) {
|
|
|
|
reportPathError(ctx, "Path may not contain a glob: %s", dir)
|
|
|
|
reportPathErrorf(ctx, "Path may not contain a glob: %s", dir)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
paths, err := ctx.GlobWithDeps(dir, []string{})
|
|
|
|
paths, err := ctx.GlobWithDeps(dir, []string{})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
reportPathError(ctx, "glob: %s", err.Error())
|
|
|
|
reportPathErrorf(ctx, "glob: %s", err.Error())
|
|
|
|
return OptionalPath{}
|
|
|
|
return OptionalPath{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(paths) == 0 {
|
|
|
|
if len(paths) == 0 {
|
|
|
@ -630,7 +631,7 @@ func (p SourcePath) OverlayPath(ctx ModuleContext, path Path) OptionalPath {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
relPath, err := filepath.Rel(p.config.srcDir, paths[0])
|
|
|
|
relPath, err := filepath.Rel(p.config.srcDir, paths[0])
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
reportPathError(ctx, "%s", err.Error())
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
return OptionalPath{}
|
|
|
|
return OptionalPath{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return OptionalPathForPath(PathForSource(ctx, relPath))
|
|
|
|
return OptionalPathForPath(PathForSource(ctx, relPath))
|
|
|
@ -652,7 +653,10 @@ var _ Path = OutputPath{}
|
|
|
|
// validated to not escape the build dir.
|
|
|
|
// validated to not escape the build dir.
|
|
|
|
// On error, it will return a usable, but invalid OutputPath, and report a ModuleError.
|
|
|
|
// On error, it will return a usable, but invalid OutputPath, and report a ModuleError.
|
|
|
|
func PathForOutput(ctx PathContext, pathComponents ...string) OutputPath {
|
|
|
|
func PathForOutput(ctx PathContext, pathComponents ...string) OutputPath {
|
|
|
|
path := validatePath(ctx, pathComponents...)
|
|
|
|
path, err := validatePath(pathComponents...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
return OutputPath{basePath{path, ctx.Config(), ""}}
|
|
|
|
return OutputPath{basePath{path, ctx.Config(), ""}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -669,14 +673,20 @@ func (p OutputPath) RelPathString() string {
|
|
|
|
// Join creates a new OutputPath with paths... joined with the current path. The
|
|
|
|
// Join creates a new OutputPath with paths... joined with the current path. The
|
|
|
|
// provided paths... may not use '..' to escape from the current path.
|
|
|
|
// provided paths... may not use '..' to escape from the current path.
|
|
|
|
func (p OutputPath) Join(ctx PathContext, paths ...string) OutputPath {
|
|
|
|
func (p OutputPath) Join(ctx PathContext, paths ...string) OutputPath {
|
|
|
|
path := validatePath(ctx, paths...)
|
|
|
|
path, err := validatePath(paths...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
return p.withRel(path)
|
|
|
|
return p.withRel(path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// PathForIntermediates returns an OutputPath representing the top-level
|
|
|
|
// PathForIntermediates returns an OutputPath representing the top-level
|
|
|
|
// intermediates directory.
|
|
|
|
// intermediates directory.
|
|
|
|
func PathForIntermediates(ctx PathContext, paths ...string) OutputPath {
|
|
|
|
func PathForIntermediates(ctx PathContext, paths ...string) OutputPath {
|
|
|
|
path := validatePath(ctx, paths...)
|
|
|
|
path, err := validatePath(paths...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
return PathForOutput(ctx, ".intermediates", path)
|
|
|
|
return PathForOutput(ctx, ".intermediates", path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -693,7 +703,10 @@ var _ resPathProvider = ModuleSrcPath{}
|
|
|
|
// PathForModuleSrc returns a ModuleSrcPath representing the paths... under the
|
|
|
|
// PathForModuleSrc returns a ModuleSrcPath representing the paths... under the
|
|
|
|
// module's local source directory.
|
|
|
|
// module's local source directory.
|
|
|
|
func PathForModuleSrc(ctx ModuleContext, paths ...string) ModuleSrcPath {
|
|
|
|
func PathForModuleSrc(ctx ModuleContext, paths ...string) ModuleSrcPath {
|
|
|
|
p := validatePath(ctx, paths...)
|
|
|
|
p, err := validatePath(paths...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
path := ModuleSrcPath{PathForSource(ctx, ctx.ModuleDir(), p)}
|
|
|
|
path := ModuleSrcPath{PathForSource(ctx, ctx.ModuleDir(), p)}
|
|
|
|
path.basePath.rel = p
|
|
|
|
path.basePath.rel = p
|
|
|
|
return path
|
|
|
|
return path
|
|
|
@ -765,13 +778,16 @@ func PathForVndkRefAbiDump(ctx ModuleContext, version, fileName string, vndkOrNd
|
|
|
|
}
|
|
|
|
}
|
|
|
|
refDumpFileStr := "prebuilts/abi-dumps/" + vndkOrNdkDir + "/" + version + "/" +
|
|
|
|
refDumpFileStr := "prebuilts/abi-dumps/" + vndkOrNdkDir + "/" + version + "/" +
|
|
|
|
archName + "/" + sourceOrBinaryDir + "/" + fileName + ext
|
|
|
|
archName + "/" + sourceOrBinaryDir + "/" + fileName + ext
|
|
|
|
return ExistentPathForSource(ctx, "", refDumpFileStr)
|
|
|
|
return ExistentPathForSource(ctx, refDumpFileStr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// PathForModuleOut returns a Path representing the paths... under the module's
|
|
|
|
// PathForModuleOut returns a Path representing the paths... under the module's
|
|
|
|
// output directory.
|
|
|
|
// output directory.
|
|
|
|
func PathForModuleOut(ctx ModuleContext, paths ...string) ModuleOutPath {
|
|
|
|
func PathForModuleOut(ctx ModuleContext, paths ...string) ModuleOutPath {
|
|
|
|
p := validatePath(ctx, paths...)
|
|
|
|
p, err := validatePath(paths...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
return ModuleOutPath{
|
|
|
|
return ModuleOutPath{
|
|
|
|
OutputPath: pathForModule(ctx).withRel(p),
|
|
|
|
OutputPath: pathForModule(ctx).withRel(p),
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -790,7 +806,10 @@ var _ objPathProvider = ModuleGenPath{}
|
|
|
|
// PathForModuleGen returns a Path representing the paths... under the module's
|
|
|
|
// PathForModuleGen returns a Path representing the paths... under the module's
|
|
|
|
// `gen' directory.
|
|
|
|
// `gen' directory.
|
|
|
|
func PathForModuleGen(ctx ModuleContext, paths ...string) ModuleGenPath {
|
|
|
|
func PathForModuleGen(ctx ModuleContext, paths ...string) ModuleGenPath {
|
|
|
|
p := validatePath(ctx, paths...)
|
|
|
|
p, err := validatePath(paths...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
return ModuleGenPath{
|
|
|
|
return ModuleGenPath{
|
|
|
|
ModuleOutPath: ModuleOutPath{
|
|
|
|
ModuleOutPath: ModuleOutPath{
|
|
|
|
OutputPath: pathForModule(ctx).withRel("gen").withRel(p),
|
|
|
|
OutputPath: pathForModule(ctx).withRel("gen").withRel(p),
|
|
|
@ -818,7 +837,10 @@ var _ Path = ModuleObjPath{}
|
|
|
|
// PathForModuleObj returns a Path representing the paths... under the module's
|
|
|
|
// PathForModuleObj returns a Path representing the paths... under the module's
|
|
|
|
// 'obj' directory.
|
|
|
|
// 'obj' directory.
|
|
|
|
func PathForModuleObj(ctx ModuleContext, pathComponents ...string) ModuleObjPath {
|
|
|
|
func PathForModuleObj(ctx ModuleContext, pathComponents ...string) ModuleObjPath {
|
|
|
|
p := validatePath(ctx, pathComponents...)
|
|
|
|
p, err := validatePath(pathComponents...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
return ModuleObjPath{PathForModuleOut(ctx, "obj", p)}
|
|
|
|
return ModuleObjPath{PathForModuleOut(ctx, "obj", p)}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -833,7 +855,11 @@ var _ Path = ModuleResPath{}
|
|
|
|
// PathForModuleRes returns a Path representing the paths... under the module's
|
|
|
|
// PathForModuleRes returns a Path representing the paths... under the module's
|
|
|
|
// 'res' directory.
|
|
|
|
// 'res' directory.
|
|
|
|
func PathForModuleRes(ctx ModuleContext, pathComponents ...string) ModuleResPath {
|
|
|
|
func PathForModuleRes(ctx ModuleContext, pathComponents ...string) ModuleResPath {
|
|
|
|
p := validatePath(ctx, pathComponents...)
|
|
|
|
p, err := validatePath(pathComponents...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
reportPathError(ctx, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ModuleResPath{PathForModuleOut(ctx, "res", p)}
|
|
|
|
return ModuleResPath{PathForModuleOut(ctx, "res", p)}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -879,36 +905,34 @@ func PathForModuleInstall(ctx ModuleInstallPathContext, pathComponents ...string
|
|
|
|
|
|
|
|
|
|
|
|
// validateSafePath validates a path that we trust (may contain ninja variables).
|
|
|
|
// validateSafePath validates a path that we trust (may contain ninja variables).
|
|
|
|
// Ensures that each path component does not attempt to leave its component.
|
|
|
|
// Ensures that each path component does not attempt to leave its component.
|
|
|
|
func validateSafePath(ctx PathContext, pathComponents ...string) string {
|
|
|
|
func validateSafePath(pathComponents ...string) (string, error) {
|
|
|
|
for _, path := range pathComponents {
|
|
|
|
for _, path := range pathComponents {
|
|
|
|
path := filepath.Clean(path)
|
|
|
|
path := filepath.Clean(path)
|
|
|
|
if path == ".." || strings.HasPrefix(path, "../") || strings.HasPrefix(path, "/") {
|
|
|
|
if path == ".." || strings.HasPrefix(path, "../") || strings.HasPrefix(path, "/") {
|
|
|
|
reportPathError(ctx, "Path is outside directory: %s", path)
|
|
|
|
return "", fmt.Errorf("Path is outside directory: %s", path)
|
|
|
|
return ""
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// TODO: filepath.Join isn't necessarily correct with embedded ninja
|
|
|
|
// TODO: filepath.Join isn't necessarily correct with embedded ninja
|
|
|
|
// variables. '..' may remove the entire ninja variable, even if it
|
|
|
|
// variables. '..' may remove the entire ninja variable, even if it
|
|
|
|
// will be expanded to multiple nested directories.
|
|
|
|
// will be expanded to multiple nested directories.
|
|
|
|
return filepath.Join(pathComponents...)
|
|
|
|
return filepath.Join(pathComponents...), nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// validatePath validates that a path does not include ninja variables, and that
|
|
|
|
// validatePath validates that a path does not include ninja variables, and that
|
|
|
|
// each path component does not attempt to leave its component. Returns a joined
|
|
|
|
// each path component does not attempt to leave its component. Returns a joined
|
|
|
|
// version of each path component.
|
|
|
|
// version of each path component.
|
|
|
|
func validatePath(ctx PathContext, pathComponents ...string) string {
|
|
|
|
func validatePath(pathComponents ...string) (string, error) {
|
|
|
|
for _, path := range pathComponents {
|
|
|
|
for _, path := range pathComponents {
|
|
|
|
if strings.Contains(path, "$") {
|
|
|
|
if strings.Contains(path, "$") {
|
|
|
|
reportPathError(ctx, "Path contains invalid character($): %s", path)
|
|
|
|
return "", fmt.Errorf("Path contains invalid character($): %s", path)
|
|
|
|
return ""
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return validateSafePath(ctx, pathComponents...)
|
|
|
|
return validateSafePath(pathComponents...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func PathForPhony(ctx PathContext, phony string) WritablePath {
|
|
|
|
func PathForPhony(ctx PathContext, phony string) WritablePath {
|
|
|
|
if strings.ContainsAny(phony, "$/") {
|
|
|
|
if strings.ContainsAny(phony, "$/") {
|
|
|
|
reportPathError(ctx, "Phony target contains invalid character ($ or /): %s", phony)
|
|
|
|
reportPathErrorf(ctx, "Phony target contains invalid character ($ or /): %s", phony)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PhonyPath{basePath{phony, ctx.Config(), ""}}
|
|
|
|
return PhonyPath{basePath{phony, ctx.Config(), ""}}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -931,7 +955,10 @@ func (p testPath) String() string {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func PathForTesting(paths ...string) Path {
|
|
|
|
func PathForTesting(paths ...string) Path {
|
|
|
|
p := validateSafePath(nil, paths...)
|
|
|
|
p, err := validateSafePath(paths...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
panic(err)
|
|
|
|
|
|
|
|
}
|
|
|
|
return testPath{basePath{path: p, rel: p}}
|
|
|
|
return testPath{basePath{path: p, rel: p}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|