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

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


The following commit(s) were added to refs/heads/master by this push:
     new b7571a17 newt/build: Workaround for whole-archive flag
b7571a17 is described below

commit b7571a177abbc5433d19d5d6daec9bf57b169da9
Author: Michal Gorecki <[email protected]>
AuthorDate: Mon Jun 2 15:55:42 2025 +0200

    newt/build: Workaround for whole-archive flag
    
    Flag whole-archive is not supported on Mac and it was causing
    CI failures. Now instead of using this flag with .a file
    we just pass a text file with list of all object files from package
    to the linker. So now it looks like this:
    @pkg.list
    instead of:
    --whole-archive pkg.a --no-whole-archive
    
    Passing list of object files will result in pulling unreferenced
    object code just like in case of whole-archive flag and
    should work with all compilers.
---
 newt/builder/build.go      | 22 +++++++++++++++----
 newt/toolchain/compiler.go | 54 ++++++++++++++++++++++++++++++----------------
 util/util.go               |  6 +++---
 3 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/newt/builder/build.go b/newt/builder/build.go
index 6ce3fb4c..2c868961 100644
--- a/newt/builder/build.go
+++ b/newt/builder/build.go
@@ -26,6 +26,7 @@ import (
        "os"
        "path/filepath"
        "runtime"
+       "strings"
 
        log "github.com/sirupsen/logrus"
 
@@ -410,8 +411,15 @@ func (b *Builder) createArchive(c *toolchain.Compiler,
 
        // Create a static library ("archive").
        c.SetSrcDir(bpkg.rpkg.Lpkg.RelativePath())
-       archiveFile := b.ArchivePath(bpkg)
-       if err := c.CompileArchive(archiveFile); err != nil {
+       outputFile := b.ArchivePath(bpkg)
+       ci, err := bpkg.CompilerInfo(b)
+       if err != nil {
+               return err
+       }
+       if ci.WholeArch {
+               outputFile = strings.TrimSuffix(outputFile, ".a") + ".list"
+       }
+       if err := c.CompileArchive(outputFile, ci.WholeArch); err != nil {
                return err
        }
 
@@ -454,6 +462,7 @@ func (b *Builder) link(elfName string, linkerScripts 
[]string,
        // Calculate the list of directories containing source .a files.
        var dirs []string
        staticLibs := []util.StaticLib{}
+       var extension string
 
        for _, bpkg := range b.sortedBuildPackages() {
 
@@ -466,8 +475,13 @@ func (b *Builder) link(elfName string, linkerScripts 
[]string,
                }
 
                c.AddInfo(&toolchain.CompilerInfo{Lflags: ci.Lflags})
-               fullANames, _ := filepath.Glob(b.PkgBinDir(bpkg) + "/*.a")
-               for _, archiveName := range fullANames {
+               if ci.WholeArch {
+                       extension = "/*.list"
+               } else {
+                       extension = "/*.a"
+               }
+               fullNames, _ := filepath.Glob(b.PkgBinDir(bpkg) + extension)
+               for _, archiveName := range fullNames {
                        s := util.NewStaticLib(archiveName, ci.WholeArch)
                        staticLibs = append(staticLibs, s)
                }
diff --git a/newt/toolchain/compiler.go b/newt/toolchain/compiler.go
index f84e16ed..0cc42a7b 100644
--- a/newt/toolchain/compiler.go
+++ b/newt/toolchain/compiler.go
@@ -1034,12 +1034,10 @@ func (c *Compiler) CompileBinaryCmd(dstFile string, 
options map[string]bool,
        }
 
        for _, lib := range libList {
-               if lib.WholeArch {
-                       cmd = append(cmd, "-Wl,--whole-archive")
-               }
-               cmd = append(cmd, lib.File)
-               if lib.WholeArch {
-                       cmd = append(cmd, "-Wl,--no-whole-archive")
+               if lib.IsObjList {
+                       cmd = append(cmd, "@"+lib.File)
+               } else {
+                       cmd = append(cmd, lib.File)
                }
        }
        if c.ldResolveCircularDeps {
@@ -1387,17 +1385,21 @@ func (c *Compiler) BuildSplitArchiveCmd(archiveFile 
string) string {
        return str
 }
 
-// Archives the specified static library.
+// Archives the specified static library or creates file with list of
+// object files.
 //
-// @param archiveFile           The filename of the library to archive.
-// @param objFiles              An array of the source .o filenames.
-func (c *Compiler) CompileArchive(archiveFile string) error {
+// @param outputFile            The filename of the library to archive.
+// @param createList            If true archive will not be compiled. Instead
+//                              the file with list of all paths to object files
+//                              from the library will be created, which later
+//                              can be passed with @ to the linker.
+func (c *Compiler) CompileArchive(outputFile string, createList bool) error {
        objFiles := []string{}
 
        // Make sure the compiler package info is added to the global set.
        c.ensureLclInfoAdded()
 
-       arRequired, err := c.depTracker.ArchiveRequired(archiveFile, objFiles)
+       arRequired, err := c.depTracker.ArchiveRequired(outputFile, objFiles)
        if err != nil {
                return err
        }
@@ -1405,7 +1407,7 @@ func (c *Compiler) CompileArchive(archiveFile string) 
error {
                return nil
        }
 
-       if err := os.MkdirAll(filepath.Dir(archiveFile), 0755); err != nil {
+       if err := os.MkdirAll(filepath.Dir(outputFile), 0755); err != nil {
                return util.NewNewtError(err.Error())
        }
 
@@ -1416,25 +1418,41 @@ func (c *Compiler) CompileArchive(archiveFile string) 
error {
 
        if len(objList) == 0 {
                util.StatusMessage(util.VERBOSITY_VERBOSE,
-                       "Not archiving %s; no object files\n", archiveFile)
+                       "Not archiving %s; no object files\n", outputFile)
                return nil
        }
 
        util.StatusMessage(util.VERBOSITY_DEFAULT, "Archiving %s",
-               path.Base(archiveFile))
+               path.Base(outputFile))
        util.StatusMessage(util.VERBOSITY_VERBOSE, " with object files %s",
                strings.Join(objList, " "))
        util.StatusMessage(util.VERBOSITY_DEFAULT, "\n")
 
        // Delete the old archive, if it exists.
-       err = os.Remove(archiveFile)
+       err = os.Remove(outputFile)
        if err != nil && !os.IsNotExist(err) {
                return util.NewNewtError(err.Error())
        }
 
-       fullCmd := c.CompileArchiveCmd(archiveFile, objFiles)
+       if createList {
+               file, err := os.Create(outputFile)
+               if err != nil {
+                       return util.NewNewtError(err.Error())
+               }
+
+               for _, objFilePath := range objList {
+                       _, err = file.WriteString(objFilePath + "\n")
+                       if err != nil {
+                               return util.NewNewtError(err.Error())
+                       }
+               }
+
+               return nil
+       }
+
+       fullCmd := c.CompileArchiveCmd(outputFile, objFiles)
 
-       cmdSafe := c.CompileArchiveCmdSafe(archiveFile, objFiles)
+       cmdSafe := c.CompileArchiveCmdSafe(outputFile, objFiles)
        for _, cmd := range cmdSafe {
                o, err := util.ShellCommand(cmd, nil)
                if err != nil {
@@ -1443,7 +1461,7 @@ func (c *Compiler) CompileArchive(archiveFile string) 
error {
                util.StatusMessage(util.VERBOSITY_DEFAULT, "%s", string(o))
        }
 
-       err = writeCommandFile(archiveFile, fullCmd)
+       err = writeCommandFile(outputFile, fullCmd)
        if err != nil {
                return err
        }
diff --git a/util/util.go b/util/util.go
index 5ab9ac1b..727f349e 100644
--- a/util/util.go
+++ b/util/util.go
@@ -74,13 +74,13 @@ const (
 
 type StaticLib struct {
        File      string
-       WholeArch bool
+       IsObjList bool
 }
 
-func NewStaticLib(file string, wholeArch bool) StaticLib {
+func NewStaticLib(file string, isObjList bool) StaticLib {
        s := StaticLib{
                File:      file,
-               WholeArch: wholeArch,
+               IsObjList: isObjList,
        }
        return s
 }

Reply via email to