Exemple #1
0
/* Building a ROM elf is used for shared application linking.
 * A ROM elf requires a rebuild if any of archives (.a files) are newer
 * than the rom elf, or if the elf file is newer than the rom_elf */
func (tracker *DepTracker) RomElfBuildRequired(dstFile string, elfFile string,
	archFiles []string) (bool, error) {

	// If the rom_elf file doesn't exist or is older than any input file, a
	// rebuild is required.
	dstModTime, err := util.FileModificationTime(dstFile)
	if err != nil {
		return false, err
	}

	// If the elf file doesn't exist or is older than any input file, a rebuild
	// is required.
	elfDstModTime, err := util.FileModificationTime(elfFile)
	if err != nil {
		return false, err
	}

	if elfDstModTime.After(dstModTime) {
		return true, nil
	}

	for _, arch := range archFiles {
		objModTime, err := util.FileModificationTime(arch)
		if err != nil {
			return false, err
		}

		if objModTime.After(dstModTime) {
			return true, nil
		}
	}
	return false, nil
}
Exemple #2
0
// Determines if the specified elf file needs to be linked.  Linking is
// necessary if the elf file does not exist or has an older modification time
// than any source object or library file.
// Determines if the specified static library needs to be rearchived.  The
// library needs to be archived if any of the following is true:
//     * The destination library file does not exist.
//     * The existing library file was built with a different compiler
//       invocation.
//     * One or more source object files has a newer modification time than the
//       library file.
func (tracker *DepTracker) LinkRequired(dstFile string,
	options map[string]bool, objFiles []string,
	keepSymbols []string, elfLib string) (bool, error) {

	// If the elf file was previously built with a different set of options, a
	// rebuild is required.
	cmd := tracker.compiler.CompileBinaryCmd(dstFile, options, objFiles, keepSymbols, elfLib)
	if commandHasChanged(dstFile, cmd) {
		util.StatusMessage(util.VERBOSITY_VERBOSE, "%s - link required; "+
			"different command\n", dstFile)
		return true, nil
	}

	// If the elf file doesn't exist or is older than any input file, a rebuild
	// is required.
	dstModTime, err := util.FileModificationTime(dstFile)
	if err != nil {
		return false, err
	}

	// If the elf file doesn't exist or is older than any input file, a rebuild
	// is required.
	if elfLib != "" {
		elfDstModTime, err := util.FileModificationTime(elfLib)
		if err != nil {
			return false, err
		}
		if elfDstModTime.After(dstModTime) {
			util.StatusMessage(util.VERBOSITY_VERBOSE, "%s - link required; "+
				"old elf file\n", elfLib)
			return true, nil
		}
	}

	// Check timestamp of each .o file in the project.
	if tracker.MostRecent.After(dstModTime) {
		util.StatusMessage(util.VERBOSITY_VERBOSE, "%s - link required; "+
			"source newer than elf\n", dstFile)
		return true, nil
	}

	// Check timestamp of the linker script and all input libraries.
	for _, ls := range tracker.compiler.LinkerScripts {
		objFiles = append(objFiles, ls)
	}
	for _, obj := range objFiles {
		objModTime, err := util.FileModificationTime(obj)
		if err != nil {
			return false, err
		}

		if objModTime.After(dstModTime) {
			util.StatusMessage(util.VERBOSITY_VERBOSE, "%s - rebuild "+
				"required; obj older than dependency (%s)\n", dstFile, obj)
			return true, nil
		}
	}

	return false, nil
}
Exemple #3
0
func (tracker *DepTracker) TrimmedArchiveRequired(dstFile string,
	srcFile string, elfLib string) (bool, error) {

	// If the .A file doesn't exist or is older than the input file, a rebuild
	// is required.
	dstModTime, err := util.FileModificationTime(dstFile)
	if err != nil {
		return false, err
	}

	// If the elf file doesn't exist or is older than any input file,
	// a rebuild is required.
	if elfLib != "" {
		elfDstModTime, err := util.FileModificationTime(elfLib)
		if err != nil {
			return false, err
		}

		if elfDstModTime.After(dstModTime) {
			return true, nil
		}
	}
	objModTime, err := util.FileModificationTime(srcFile)
	if err != nil {
		return false, err
	}

	if objModTime.After(dstModTime) {
		return true, nil
	}
	return false, nil
}
Exemple #4
0
// Determines if the specified static library needs to be copied.  The
// library needs to be archived if any of the following is true:
//     * The destination library file does not exist.
//     * Source object files has a newer modification time than the
//       target file.
func (tracker *DepTracker) CopyRequired(srcFile string) (bool, error) {

	tgtFile := tracker.compiler.DstDir() + "/" + filepath.Base(srcFile)

	// If the target doesn't exist or is older than source file, a copy
	// is required.
	srcModTime, err := util.FileModificationTime(srcFile)
	if err != nil {
		return false, err
	}
	tgtModTime, err := util.FileModificationTime(tgtFile)
	if err != nil {
		return false, err
	}
	if srcModTime.After(tgtModTime) {
		return true, nil
	}

	// The target is up to date.
	return false, nil
}
Exemple #5
0
// Updates the dependency tracker's most recent timestamp according to the
// modification time of the specified file.  If the specified file is older
// than the tracker's currently most-recent time, this function has no effect.
func (tracker *DepTracker) ProcessFileTime(file string) error {
	modTime, err := util.FileModificationTime(file)
	if err != nil {
		return err
	}

	if modTime.After(tracker.MostRecent) {
		tracker.MostRecent = modTime
	}

	return nil
}
Exemple #6
0
// Determines if the specified static library needs to be rearchived.  The
// library needs to be archived if any of the following is true:
//     * The destination library file does not exist.
//     * The existing library file was built with a different compiler
//       invocation.
//     * One or more source object files has a newer modification time than the
//       library file.
func (tracker *DepTracker) ArchiveRequired(archiveFile string,
	objFiles []string) (bool, error) {

	// If the archive was previously built with a different set of options, a
	// rebuild is required.
	cmd := tracker.compiler.CompileArchiveCmd(archiveFile, objFiles)
	if commandHasChanged(archiveFile, cmd) {
		return true, nil
	}

	// If the archive doesn't exist or is older than any object file, a rebuild
	// is required.
	aModTime, err := util.FileModificationTime(archiveFile)
	if err != nil {
		return false, err
	}
	if tracker.MostRecent.After(aModTime) {
		return true, nil
	}

	// The library is up to date.
	return false, nil
}
Exemple #7
0
// Determines if the specified C or assembly file needs to be built.  A compile
// is required if any of the following is true:
//     * The destination object file does not exist.
//     * The existing object file was built with a different compiler
//       invocation.
//     * The source file has a newer modification time than the object file.
//     * One or more included header files has a newer modification time than
//       the object file.
func (tracker *DepTracker) CompileRequired(srcFile string,
	compilerType int) (bool, error) {

	objFile := tracker.compiler.DstDir() + "/" +
		strings.TrimSuffix(srcFile, filepath.Ext(srcFile)) + ".o"
	depFile := tracker.compiler.DstDir() + "/" +
		strings.TrimSuffix(srcFile, filepath.Ext(srcFile)) + ".d"

	// If the object was previously built with a different set of options, a
	// rebuild is necessary.
	cmd, err := tracker.compiler.CompileFileCmd(srcFile, compilerType)
	if err != nil {
		return false, err
	}

	if commandHasChanged(objFile, cmd) {
		util.StatusMessage(util.VERBOSITY_VERBOSE, "%s - rebuild required; "+
			"different command\n", srcFile)
		err := tracker.compiler.GenDepsForFile(srcFile)
		if err != nil {
			return false, err
		}
		return true, nil
	}

	if util.NodeNotExist(depFile) {
		err := tracker.compiler.GenDepsForFile(srcFile)
		if err != nil {
			return false, err
		}
	}

	srcModTime, err := util.FileModificationTime(srcFile)
	if err != nil {
		return false, err
	}

	objModTime, err := util.FileModificationTime(objFile)
	if err != nil {
		return false, err
	}

	// If the object doesn't exist or is older than the source file, a build is
	// required; no need to check dependencies.
	if srcModTime.After(objModTime) {
		util.StatusMessage(util.VERBOSITY_VERBOSE, "%s - rebuild required; "+
			"source newer than obj\n", srcFile)
		return true, nil
	}

	// Determine if the dependency (.d) file needs to be generated.  If it
	// doesn't exist or is older than the source file, it is out of date and
	// needs to be created.
	depModTime, err := util.FileModificationTime(depFile)
	if err != nil {
		return false, err
	}

	if srcModTime.After(depModTime) {
		err := tracker.compiler.GenDepsForFile(srcFile)
		if err != nil {
			return false, err
		}
	}

	// Extract the dependency filenames from the dependency file.
	deps, err := ParseDepsFile(depFile)
	if err != nil {
		return false, err
	}

	// Check if any dependencies are newer than the destination object file.
	for _, dep := range deps {
		if util.NodeNotExist(dep) {
			// The dependency has been deleted; a rebuild is required.  Also,
			// the dependency file is out of date, so it needs to be deleted.
			// We cannot regenerate it now because the source file might be
			// including a nonexistent header.
			os.Remove(depFile)
			return true, nil
		} else {
			depModTime, err = util.FileModificationTime(dep)
			if err != nil {
				return false, err
			}
		}

		if depModTime.After(objModTime) {
			util.StatusMessage(util.VERBOSITY_VERBOSE, "%s - rebuild required; obj older than dependency (%s)\n", srcFile, dep)
			return true, nil
		}
	}

	return false, nil
}