You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2019/10/10 17:15:12 UTC

[mynewt-newt] 08/08: Pass pre-link artifacts to linker

This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newt.git

commit 35f4af9289a3cb5ffe19d8513c2b55bb72b7f4bd
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Oct 9 15:30:33 2019 -0700

    Pass pre-link artifacts to linker
    
    .a files produced by pre-link user scripts were not being passed to the
    linker.  This commit adds the pre-link "user source" directory to the
    list of directories to scan at link time.
    
    Note: Artifacts produced by pre-build scripts (not pre-link) do get used
    as intended.  At compile time, newt copies .a files from package source
    directories to their respective binary directories.  Since pre-link
    scripts run after compile time, this copy never happens for pre-link
    artifacts, so we need to tell newt where to look.
---
 newt/builder/build.go       | 61 +++++++++++++++++++++++++--------------------
 newt/builder/selftest.go    |  2 +-
 newt/builder/targetbuild.go | 34 ++++++++++++++++++++-----
 3 files changed, 63 insertions(+), 34 deletions(-)

diff --git a/newt/builder/build.go b/newt/builder/build.go
index d23d44d..7a25e76 100644
--- a/newt/builder/build.go
+++ b/newt/builder/build.go
@@ -90,9 +90,6 @@ func NewBuilder(
 	if _, err := b.addUserPreBuildBpkg(); err != nil {
 		return nil, err
 	}
-	if _, err := b.addUserPreLinkBpkg(); err != nil {
-		return nil, err
-	}
 
 	for api, rpkg := range apiMap {
 		bpkg := b.PkgMap[rpkg]
@@ -400,22 +397,17 @@ func (b *Builder) ExtractSymbolInfo() (error, *symbol.SymbolMap) {
 }
 
 func (b *Builder) link(elfName string, linkerScripts []string,
-	keepSymbols []string) error {
+	keepSymbols []string, extraADirs []string) error {
 
 	c, err := b.newCompiler(b.appPkg, b.FileBinDir(elfName))
 	if err != nil {
 		return err
 	}
 
-	/* Always used the trimmed archive files. */
-	pkgNames := []string{}
-
+	// Calculate the list of directories containing source .a files.
+	var dirs []string
 	for _, bpkg := range b.sortedBuildPackages() {
-		archiveNames, _ := filepath.Glob(b.PkgBinDir(bpkg) + "/*.a")
-		for i, archiveName := range archiveNames {
-			archiveNames[i] = filepath.ToSlash(archiveName)
-		}
-		pkgNames = append(pkgNames, archiveNames...)
+		dirs = append(dirs, b.PkgBinDir(bpkg))
 
 		// Collect lflags from all constituent packages.  Discard everything
 		// from the compiler info except lflags; that is all that is relevant
@@ -426,9 +418,20 @@ func (b *Builder) link(elfName string, linkerScripts []string,
 		}
 		c.AddInfo(&toolchain.CompilerInfo{Lflags: ci.Lflags})
 	}
+	dirs = append(dirs, extraADirs...)
+
+	// Find all .a files in the input directories.
+	trimmedANames := []string{}
+	for _, dir := range dirs {
+		fullANames, _ := filepath.Glob(dir + "/*.a")
+		for i, archiveName := range fullANames {
+			fullANames[i] = filepath.ToSlash(archiveName)
+		}
+		trimmedANames = append(trimmedANames, fullANames...)
+	}
 
 	c.LinkerScripts = linkerScripts
-	err = c.CompileElf(elfName, pkgNames, keepSymbols, b.linkElf)
+	err = c.CompileElf(elfName, trimmedANames, keepSymbols, b.linkElf)
 	if err != nil {
 		return err
 	}
@@ -555,13 +558,6 @@ func (b *Builder) addUserPreBuildBpkg() (*BuildPackage, error) {
 		UserPreBuildDir(b.targetPkg.rpkg.Lpkg.FullName()))
 }
 
-// addUserPreLinkBpkg adds the pseudo user build package to the builder.  The
-// user build package contains inputs emitted by external scripts.
-func (b *Builder) addUserPreLinkBpkg() (*BuildPackage, error) {
-	return b.addPseudoBpkg("user-pre-link",
-		UserPreLinkDir(b.targetPkg.rpkg.Lpkg.FullName()))
-}
-
 // Runs build jobs while any remain.  On failure, signals the other workers to
 // stop via the stop channel.  On error, the error object is signaled via the
 // results channel.  On successful completion, nil is signaled via the results
@@ -693,15 +689,17 @@ func (b *Builder) Build() error {
 	return nil
 }
 
-func (b *Builder) Link(linkerScripts []string) error {
-	if err := b.link(b.AppElfPath(), linkerScripts, nil); err != nil {
+func (b *Builder) Link(linkerScripts []string, extraADirs []string) error {
+	if err := b.link(b.AppElfPath(), linkerScripts, nil,
+		extraADirs); err != nil {
+
 		return err
 	}
 	return nil
 }
 
-func (b *Builder) KeepLink(
-	linkerScripts []string, keepMap *symbol.SymbolMap) error {
+func (b *Builder) KeepLink(linkerScripts []string, keepMap *symbol.SymbolMap,
+	extraADirs []string) error {
 
 	keepSymbols := make([]string, 0)
 
@@ -710,16 +708,25 @@ func (b *Builder) KeepLink(
 			keepSymbols = append(keepSymbols, info.Name)
 		}
 	}
-	if err := b.link(b.AppElfPath(), linkerScripts, keepSymbols); err != nil {
+
+	if err := b.link(b.AppElfPath(), linkerScripts, keepSymbols,
+		extraADirs); err != nil {
+
 		return err
 	}
+
 	return nil
 }
 
-func (b *Builder) TentativeLink(linkerScripts []string) error {
-	if err := b.link(b.AppTentativeElfPath(), linkerScripts, nil); err != nil {
+func (b *Builder) TentativeLink(linkerScripts []string,
+	extraADirs []string) error {
+
+	if err := b.link(b.AppTentativeElfPath(), linkerScripts, nil,
+		extraADirs); err != nil {
+
 		return err
 	}
+
 	return nil
 }
 
diff --git a/newt/builder/selftest.go b/newt/builder/selftest.go
index 1fb4cc3..1ff1aae 100644
--- a/newt/builder/selftest.go
+++ b/newt/builder/selftest.go
@@ -33,7 +33,7 @@ import (
 
 func (b *Builder) SelfTestLink(rpkg *resolve.ResolvePackage) error {
 	testPath := b.TestExePath()
-	if err := b.link(testPath, nil, nil); err != nil {
+	if err := b.link(testPath, nil, nil, nil); err != nil {
 		return err
 	}
 
diff --git a/newt/builder/targetbuild.go b/newt/builder/targetbuild.go
index db337e5..bbc35ff 100644
--- a/newt/builder/targetbuild.go
+++ b/newt/builder/targetbuild.go
@@ -325,6 +325,22 @@ func (t *TargetBuilder) validateAndWriteCfg() error {
 	return nil
 }
 
+// extraADirs returns a slice of extra directories that should be used at link
+// time.  .a files in these directores are used as input to the link (in
+// addition to .a files produced by building packages).
+func (t *TargetBuilder) extraADirs() []string {
+	return []string{
+		// Artifacts generated by pre-link user scripts.
+		UserPreLinkSrcDir(t.target.FullName()),
+	}
+
+	// Note: we don't include the pre-build source directory in this list.  At
+	// compile time, newt copies .a files from package source directories to
+	// their respective binary directories.  Since pre-link scripts run after
+	// compile time, this copy never happens for pre-link artifacts, so we need
+	// to tell newt where to look.
+}
+
 func (t *TargetBuilder) PrepBuild() error {
 	if err := t.ensureResolved(); err != nil {
 		return err
@@ -395,8 +411,12 @@ func (t *TargetBuilder) PrepBuild() error {
 }
 
 func (t *TargetBuilder) buildLoader() error {
-	/* Tentatively link the app (using the normal single image linker script) */
-	if err := t.AppBuilder.TentativeLink(t.bspPkg.LinkerScripts); err != nil {
+	/* Tentatively link the app (using the normal single image linker
+	 * script)
+	 */
+	if err := t.AppBuilder.TentativeLink(t.bspPkg.LinkerScripts,
+		t.extraADirs()); err != nil {
+
 		return err
 	}
 
@@ -412,7 +432,9 @@ func (t *TargetBuilder) buildLoader() error {
 	}
 
 	/* Tentatively link the loader */
-	if err := t.LoaderBuilder.TentativeLink(t.bspPkg.LinkerScripts); err != nil {
+	if err := t.LoaderBuilder.TentativeLink(t.bspPkg.LinkerScripts,
+		t.extraADirs()); err != nil {
+
 		return err
 	}
 
@@ -554,7 +576,7 @@ func (t *TargetBuilder) Build() error {
 	}
 
 	/* Link the app. */
-	if err := t.AppBuilder.Link(linkerScripts); err != nil {
+	if err := t.AppBuilder.Link(linkerScripts, t.extraADirs()); err != nil {
 		return err
 	}
 
@@ -685,8 +707,8 @@ func (t *TargetBuilder) RelinkLoader() (error, map[string]bool,
 	util.StatusMessage(util.VERBOSITY_VERBOSE,
 		"Migrating %d unused symbols into Loader\n", len(*preserveElf))
 
-	err = t.LoaderBuilder.KeepLink(t.bspPkg.LinkerScripts, preserveElf)
-
+	err = t.LoaderBuilder.KeepLink(t.bspPkg.LinkerScripts, preserveElf,
+		t.extraADirs())
 	if err != nil {
 		return err, nil, nil
 	}