Skip to content

Commit 30a67fe

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 30a67fe

File tree

3 files changed

+57
-25
lines changed

3 files changed

+57
-25
lines changed

newt/builder/build.go

Lines changed: 18 additions & 4 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,15 @@ 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+
ci, err := bpkg.CompilerInfo(b)
416+
if err != nil {
417+
return err
418+
}
419+
if ci.WholeArch {
420+
outputFile = strings.TrimSuffix(outputFile, ".a") + ".list"
421+
}
422+
if err := c.CompileArchive(outputFile, ci.WholeArch); err != nil {
415423
return err
416424
}
417425

@@ -454,6 +462,7 @@ func (b *Builder) link(elfName string, linkerScripts []string,
454462
// Calculate the list of directories containing source .a files.
455463
var dirs []string
456464
staticLibs := []util.StaticLib{}
465+
var extension string
457466

458467
for _, bpkg := range b.sortedBuildPackages() {
459468

@@ -466,8 +475,13 @@ func (b *Builder) link(elfName string, linkerScripts []string,
466475
}
467476

468477
c.AddInfo(&toolchain.CompilerInfo{Lflags: ci.Lflags})
469-
fullANames, _ := filepath.Glob(b.PkgBinDir(bpkg) + "/*.a")
470-
for _, archiveName := range fullANames {
478+
if ci.WholeArch {
479+
extension = "/*.list"
480+
} else {
481+
extension = "/*.a"
482+
}
483+
fullNames, _ := filepath.Glob(b.PkgBinDir(bpkg) + extension)
484+
for _, archiveName := range fullNames {
471485
s := util.NewStaticLib(archiveName, ci.WholeArch)
472486
staticLibs = append(staticLibs, s)
473487
}

newt/toolchain/compiler.go

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,12 +1034,10 @@ func (c *Compiler) CompileBinaryCmd(dstFile string, options map[string]bool,
10341034
}
10351035

10361036
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")
1037+
if lib.IsObjList {
1038+
cmd = append(cmd, "@"+lib.File)
1039+
} else {
1040+
cmd = append(cmd, lib.File)
10431041
}
10441042
}
10451043
if c.ldResolveCircularDeps {
@@ -1387,25 +1385,29 @@ func (c *Compiler) BuildSplitArchiveCmd(archiveFile string) string {
13871385
return str
13881386
}
13891387

1390-
// Archives the specified static library.
1388+
// Archives the specified static library or creates file with list of
1389+
// object files.
13911390
//
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 {
1391+
// @param outputFile The filename of the library to archive.
1392+
// @param createList If true archive will not be compiled. Instead
1393+
// the file with list of all paths to object files
1394+
// from the library will be created, which later
1395+
// can be passed with @ to the linker.
1396+
func (c *Compiler) CompileArchive(outputFile string, createList bool) error {
13951397
objFiles := []string{}
13961398

13971399
// Make sure the compiler package info is added to the global set.
13981400
c.ensureLclInfoAdded()
13991401

1400-
arRequired, err := c.depTracker.ArchiveRequired(archiveFile, objFiles)
1402+
arRequired, err := c.depTracker.ArchiveRequired(outputFile, objFiles)
14011403
if err != nil {
14021404
return err
14031405
}
14041406
if !arRequired {
14051407
return nil
14061408
}
14071409

1408-
if err := os.MkdirAll(filepath.Dir(archiveFile), 0755); err != nil {
1410+
if err := os.MkdirAll(filepath.Dir(outputFile), 0755); err != nil {
14091411
return util.NewNewtError(err.Error())
14101412
}
14111413

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

14171419
if len(objList) == 0 {
14181420
util.StatusMessage(util.VERBOSITY_VERBOSE,
1419-
"Not archiving %s; no object files\n", archiveFile)
1421+
"Not archiving %s; no object files\n", outputFile)
14201422
return nil
14211423
}
14221424

14231425
util.StatusMessage(util.VERBOSITY_DEFAULT, "Archiving %s",
1424-
path.Base(archiveFile))
1426+
path.Base(outputFile))
14251427
util.StatusMessage(util.VERBOSITY_VERBOSE, " with object files %s",
14261428
strings.Join(objList, " "))
14271429
util.StatusMessage(util.VERBOSITY_DEFAULT, "\n")
14281430

14291431
// Delete the old archive, if it exists.
1430-
err = os.Remove(archiveFile)
1432+
err = os.Remove(outputFile)
14311433
if err != nil && !os.IsNotExist(err) {
14321434
return util.NewNewtError(err.Error())
14331435
}
14341436

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

1437-
cmdSafe := c.CompileArchiveCmdSafe(archiveFile, objFiles)
1455+
cmdSafe := c.CompileArchiveCmdSafe(outputFile, objFiles)
14381456
for _, cmd := range cmdSafe {
14391457
o, err := util.ShellCommand(cmd, nil)
14401458
if err != nil {
@@ -1443,7 +1461,7 @@ func (c *Compiler) CompileArchive(archiveFile string) error {
14431461
util.StatusMessage(util.VERBOSITY_DEFAULT, "%s", string(o))
14441462
}
14451463

1446-
err = writeCommandFile(archiveFile, fullCmd)
1464+
err = writeCommandFile(outputFile, fullCmd)
14471465
if err != nil {
14481466
return err
14491467
}

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)