Skip to content

Commit a0ec665

Browse files
committed
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.
1 parent cbaa907 commit a0ec665

File tree

3 files changed

+54
-24
lines changed

3 files changed

+54
-24
lines changed

newt/builder/build.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"os"
2727
"path/filepath"
2828
"runtime"
29+
"strings"
2930

3031
log "github.com/sirupsen/logrus"
3132

@@ -410,8 +411,11 @@ func (b *Builder) createArchive(c *toolchain.Compiler,
410411

411412
// Create a static library ("archive").
412413
c.SetSrcDir(bpkg.rpkg.Lpkg.RelativePath())
413-
archiveFile := b.ArchivePath(bpkg)
414-
if err := c.CompileArchive(archiveFile); err != nil {
414+
outputFile := b.ArchivePath(bpkg)
415+
if c.GetCompilerInfo().WholeArch {
416+
outputFile = strings.TrimSuffix(outputFile, ".a") + ".list"
417+
}
418+
if err := c.CompileArchive(outputFile, c.GetCompilerInfo().WholeArch); err != nil {
415419
return err
416420
}
417421

@@ -468,7 +472,12 @@ func (b *Builder) link(elfName string, linkerScripts []string,
468472
c.AddInfo(&toolchain.CompilerInfo{Lflags: ci.Lflags})
469473
fullANames, _ := filepath.Glob(b.PkgBinDir(bpkg) + "/*.a")
470474
for _, archiveName := range fullANames {
471-
s := util.NewStaticLib(archiveName, ci.WholeArch)
475+
s := util.NewStaticLib(archiveName, false)
476+
staticLibs = append(staticLibs, s)
477+
}
478+
fullListNames, _ := filepath.Glob(b.PkgBinDir(bpkg) + "/*.list")
479+
for _, listName := range fullListNames {
480+
s := util.NewStaticLib(listName, true)
472481
staticLibs = append(staticLibs, s)
473482
}
474483
}

newt/toolchain/compiler.go

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ func (ci *CompilerInfo) AddCompilerInfo(newCi *CompilerInfo) {
252252
ci.Aflags = addFlags("aflag", ci.Aflags, newCi.Aflags)
253253
ci.IgnoreFiles = append(ci.IgnoreFiles, newCi.IgnoreFiles...)
254254
ci.IgnoreDirs = append(ci.IgnoreDirs, newCi.IgnoreDirs...)
255+
if newCi.WholeArch == true {
256+
ci.WholeArch = true
257+
}
255258
}
256259

257260
func NewCompiler(compilerDir string, dstDir string,
@@ -1034,12 +1037,10 @@ func (c *Compiler) CompileBinaryCmd(dstFile string, options map[string]bool,
10341037
}
10351038

10361039
for _, lib := range libList {
1037-
if lib.WholeArch {
1038-
cmd = append(cmd, "-Wl,--whole-archive")
1039-
}
1040-
cmd = append(cmd, lib.File)
1041-
if lib.WholeArch {
1042-
cmd = append(cmd, "-Wl,--no-whole-archive")
1040+
if lib.IsObjList {
1041+
cmd = append(cmd, "@"+lib.File)
1042+
} else {
1043+
cmd = append(cmd, lib.File)
10431044
}
10441045
}
10451046
if c.ldResolveCircularDeps {
@@ -1387,25 +1388,29 @@ func (c *Compiler) BuildSplitArchiveCmd(archiveFile string) string {
13871388
return str
13881389
}
13891390

1390-
// Archives the specified static library.
1391+
// Archives the specified static library or creates file with list of
1392+
// object files.
13911393
//
1392-
// @param archiveFile The filename of the library to archive.
1393-
// @param objFiles An array of the source .o filenames.
1394-
func (c *Compiler) CompileArchive(archiveFile string) error {
1394+
// @param outputFile The filename of the library to archive.
1395+
// @param createList If true archive will not be compiled. Instead
1396+
// the file with list of all paths to object files
1397+
// from the library will be created, which later
1398+
// can be passed with @ to the linker.
1399+
func (c *Compiler) CompileArchive(outputFile string, createList bool) error {
13951400
objFiles := []string{}
13961401

13971402
// Make sure the compiler package info is added to the global set.
13981403
c.ensureLclInfoAdded()
13991404

1400-
arRequired, err := c.depTracker.ArchiveRequired(archiveFile, objFiles)
1405+
arRequired, err := c.depTracker.ArchiveRequired(outputFile, objFiles)
14011406
if err != nil {
14021407
return err
14031408
}
14041409
if !arRequired {
14051410
return nil
14061411
}
14071412

1408-
if err := os.MkdirAll(filepath.Dir(archiveFile), 0755); err != nil {
1413+
if err := os.MkdirAll(filepath.Dir(outputFile), 0755); err != nil {
14091414
return util.NewNewtError(err.Error())
14101415
}
14111416

@@ -1416,25 +1421,41 @@ func (c *Compiler) CompileArchive(archiveFile string) error {
14161421

14171422
if len(objList) == 0 {
14181423
util.StatusMessage(util.VERBOSITY_VERBOSE,
1419-
"Not archiving %s; no object files\n", archiveFile)
1424+
"Not archiving %s; no object files\n", outputFile)
14201425
return nil
14211426
}
14221427

14231428
util.StatusMessage(util.VERBOSITY_DEFAULT, "Archiving %s",
1424-
path.Base(archiveFile))
1429+
path.Base(outputFile))
14251430
util.StatusMessage(util.VERBOSITY_VERBOSE, " with object files %s",
14261431
strings.Join(objList, " "))
14271432
util.StatusMessage(util.VERBOSITY_DEFAULT, "\n")
14281433

14291434
// Delete the old archive, if it exists.
1430-
err = os.Remove(archiveFile)
1435+
err = os.Remove(outputFile)
14311436
if err != nil && !os.IsNotExist(err) {
14321437
return util.NewNewtError(err.Error())
14331438
}
14341439

1435-
fullCmd := c.CompileArchiveCmd(archiveFile, objFiles)
1440+
if createList {
1441+
file, err := os.Create(outputFile)
1442+
if err != nil {
1443+
return util.NewNewtError(err.Error())
1444+
}
1445+
1446+
for _, objFilePath := range objList {
1447+
_, err = file.WriteString(objFilePath + "\n")
1448+
if err != nil {
1449+
return util.NewNewtError(err.Error())
1450+
}
1451+
}
1452+
1453+
return nil
1454+
}
1455+
1456+
fullCmd := c.CompileArchiveCmd(outputFile, objFiles)
14361457

1437-
cmdSafe := c.CompileArchiveCmdSafe(archiveFile, objFiles)
1458+
cmdSafe := c.CompileArchiveCmdSafe(outputFile, objFiles)
14381459
for _, cmd := range cmdSafe {
14391460
o, err := util.ShellCommand(cmd, nil)
14401461
if err != nil {
@@ -1443,7 +1464,7 @@ func (c *Compiler) CompileArchive(archiveFile string) error {
14431464
util.StatusMessage(util.VERBOSITY_DEFAULT, "%s", string(o))
14441465
}
14451466

1446-
err = writeCommandFile(archiveFile, fullCmd)
1467+
err = writeCommandFile(outputFile, fullCmd)
14471468
if err != nil {
14481469
return err
14491470
}

util/util.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ const (
7474

7575
type StaticLib struct {
7676
File string
77-
WholeArch bool
77+
IsObjList bool
7878
}
7979

80-
func NewStaticLib(file string, wholeArch bool) StaticLib {
80+
func NewStaticLib(file string, isObjList bool) StaticLib {
8181
s := StaticLib{
8282
File: file,
83-
WholeArch: wholeArch,
83+
IsObjList: isObjList,
8484
}
8585
return s
8686
}

0 commit comments

Comments
 (0)