@@ -691,7 +691,6 @@ type Action struct {
691
691
triggers []* Action // inverse of deps
692
692
693
693
// Generated files, directories.
694
- Link bool // target is executable, not just package
695
694
Objdir string // directory for intermediate objects
696
695
Target string // goal of the action: the created package or executable
697
696
@@ -749,7 +748,6 @@ func actionGraphJSON(a *Action) string {
749
748
ID : id ,
750
749
IgnoreFail : a .IgnoreFail ,
751
750
Args : a .Args ,
752
- Link : a .Link ,
753
751
Objdir : a .Objdir ,
754
752
Target : a .Target ,
755
753
Failed : a .Failed ,
@@ -955,7 +953,7 @@ func (b *Builder) action1(mode BuildMode, depMode BuildMode, p *load.Package, lo
955
953
mode = ModeBuild
956
954
}
957
955
a .Objdir = b .NewObjdir ()
958
- a . Link = p .Name == "main" && ! p .Internal .ForceLibrary
956
+ link : = p .Name == "main" && ! p .Internal .ForceLibrary
959
957
960
958
switch mode {
961
959
case ModeInstall :
@@ -989,7 +987,16 @@ func (b *Builder) action1(mode BuildMode, depMode BuildMode, p *load.Package, lo
989
987
a .Func = (* Builder ).build
990
988
a .Target = a .Objdir + "_pkg_.a"
991
989
a .Package .Internal .Pkgfile = a .Target
992
- if a .Link {
990
+
991
+ if link {
992
+ a = & Action {
993
+ Mode : "link" ,
994
+ Func : (* Builder ).link ,
995
+ Package : a .Package ,
996
+ Objdir : a .Objdir ,
997
+ Deps : []* Action {a },
998
+ }
999
+
993
1000
// An executable file. (This is the name of a temporary file.)
994
1001
// Because we run the temporary file in 'go run' and 'go test',
995
1002
// the name will show up in ps listings. If the caller has specified
@@ -1018,7 +1025,10 @@ func (b *Builder) action1(mode BuildMode, depMode BuildMode, p *load.Package, lo
1018
1025
}
1019
1026
1020
1027
func (b * Builder ) libaction (libname string , pkgs []* load.Package , mode , depMode BuildMode ) * Action {
1021
- a := & Action {Mode : "libaction???" }
1028
+ a := & Action {
1029
+ Mode : "libaction" , // should be overwritten below
1030
+ Objdir : b .NewObjdir (),
1031
+ }
1022
1032
switch mode {
1023
1033
default :
1024
1034
base .Fatalf ("unrecognized mode %v" , mode )
@@ -1201,8 +1211,14 @@ func (b *Builder) Do(root *Action) {
1201
1211
// any actions that are runnable as a result.
1202
1212
handle := func (a * Action ) {
1203
1213
var err error
1214
+
1204
1215
if a .Func != nil && (! a .Failed || a .IgnoreFail ) {
1205
- err = a .Func (b , a )
1216
+ if a .Objdir != "" {
1217
+ err = b .Mkdir (a .Objdir )
1218
+ }
1219
+ if err == nil {
1220
+ err = a .Func (b , a )
1221
+ }
1206
1222
}
1207
1223
1208
1224
// The actions run in parallel but all the updates to the
@@ -1316,11 +1332,7 @@ func (b *Builder) build(a *Action) (err error) {
1316
1332
b .Print (a .Package .ImportPath + "\n " )
1317
1333
}
1318
1334
1319
- // Make build directory.
1320
1335
objdir := a .Objdir
1321
- if err := b .Mkdir (objdir ); err != nil {
1322
- return err
1323
- }
1324
1336
1325
1337
// make target directory
1326
1338
dir , _ := filepath .Split (a .Target )
@@ -1554,22 +1566,32 @@ func (b *Builder) build(a *Action) (err error) {
1554
1566
}
1555
1567
}
1556
1568
1557
- // Link if needed.
1558
- if a .Link {
1559
- importcfg := a .Objdir + "importcfg.link"
1560
- if err := b .writeLinkImportcfg (a , importcfg ); err != nil {
1561
- return err
1562
- }
1569
+ return nil
1570
+ }
1563
1571
1564
- // The compiler only cares about direct imports, but the
1565
- // linker needs the whole dependency tree.
1566
- all := ActionList (a )
1567
- all = all [:len (all )- 1 ] // drop a
1568
- if err := BuildToolchain .ld (b , a , a .Target , importcfg , all , objpkg , objects ); err != nil {
1572
+ func (b * Builder ) link (a * Action ) (err error ) {
1573
+ importcfg := a .Objdir + "importcfg.link"
1574
+ if err := b .writeLinkImportcfg (a , importcfg ); err != nil {
1575
+ return err
1576
+ }
1577
+
1578
+ // make target directory
1579
+ dir , _ := filepath .Split (a .Target )
1580
+ if dir != "" {
1581
+ if err := b .Mkdir (dir ); err != nil {
1569
1582
return err
1570
1583
}
1571
1584
}
1572
1585
1586
+ // The compiler only cares about direct imports, but the
1587
+ // linker needs the whole dependency tree.
1588
+ all := ActionList (a )
1589
+ all = all [:len (all )- 1 ] // drop a
1590
+ objpkg := a .Objdir + "_pkg_.a"
1591
+ if err := BuildToolchain .ld (b , a , a .Target , importcfg , all , objpkg , nil ); err != nil { // TODO: ofiles
1592
+ return err
1593
+ }
1594
+
1573
1595
return nil
1574
1596
}
1575
1597
@@ -1698,7 +1720,7 @@ func BuildInstallFunc(b *Builder, a *Action) (err error) {
1698
1720
}()
1699
1721
a1 := a .Deps [0 ]
1700
1722
perm := os .FileMode (0666 )
1701
- if a1 .Link {
1723
+ if a1 .Mode == "link" {
1702
1724
switch cfg .BuildBuildmode {
1703
1725
case "c-archive" , "c-shared" , "plugin" :
1704
1726
default :
@@ -2859,7 +2881,7 @@ func (gccgoToolchain) pack(b *Builder, a *Action, afile string, ofiles []string)
2859
2881
return b .run (p .Dir , p .ImportPath , nil , "ar" , "rc" , mkAbs (objdir , afile ), absOfiles )
2860
2882
}
2861
2883
2862
- func (tools gccgoToolchain ) link (b * Builder , root * Action , out , importcfg string , allactions []* Action , mainpkg string , ofiles [] string , buildmode , desc string ) error {
2884
+ func (tools gccgoToolchain ) link (b * Builder , root * Action , out , importcfg string , allactions []* Action , buildmode , desc string ) error {
2863
2885
// gccgo needs explicit linking with all package dependencies,
2864
2886
// and all LDFLAGS from cgo dependencies.
2865
2887
apackagePathsSeen := make (map [string ]bool )
@@ -2899,42 +2921,36 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string
2899
2921
return nil
2900
2922
}
2901
2923
2924
+ newID := 0
2902
2925
readAndRemoveCgoFlags := func (archive string ) (string , error ) {
2903
- newa , err := ioutil .TempFile (b .WorkDir , filepath .Base (archive ))
2904
- if err != nil {
2905
- return "" , err
2906
- }
2907
- olda , err := os .Open (archive )
2908
- if err != nil {
2909
- return "" , err
2910
- }
2911
- _ , err = io .Copy (newa , olda )
2912
- if err != nil {
2926
+ newID ++
2927
+ newArchive := root .Objdir + fmt .Sprintf ("_pkg%d_.a" , newID )
2928
+ if err := b .copyFile (root , newArchive , archive , 0666 , false ); err != nil {
2913
2929
return "" , err
2914
2930
}
2915
- err = olda .Close ()
2916
- if err != nil {
2917
- return "" , err
2918
- }
2919
- err = newa .Close ()
2920
- if err != nil {
2921
- return "" , err
2931
+ if cfg .BuildN || cfg .BuildX {
2932
+ b .Showcmd ("" , "ar d %s _cgo_flags" , newArchive )
2933
+ if cfg .BuildN {
2934
+ // TODO(rsc): We could do better about showing the right _cgo_flags even in -n mode.
2935
+ // Either the archive is already built and we can read them out,
2936
+ // or we're printing commands to build the archive and can
2937
+ // forward the _cgo_flags directly to this step.
2938
+ return "" , nil
2939
+ }
2922
2940
}
2923
-
2924
- newarchive := newa .Name ()
2925
- err = b .run (b .WorkDir , desc , nil , "ar" , "x" , newarchive , "_cgo_flags" )
2941
+ err := b .run (root .Objdir , desc , nil , "ar" , "x" , newArchive , "_cgo_flags" )
2926
2942
if err != nil {
2927
2943
return "" , err
2928
2944
}
2929
- err = b .run ("." , desc , nil , "ar" , "d" , newarchive , "_cgo_flags" )
2945
+ err = b .run ("." , desc , nil , "ar" , "d" , newArchive , "_cgo_flags" )
2930
2946
if err != nil {
2931
2947
return "" , err
2932
2948
}
2933
- err = readCgoFlags (filepath .Join (b . WorkDir , "_cgo_flags" ))
2949
+ err = readCgoFlags (filepath .Join (root . Objdir , "_cgo_flags" ))
2934
2950
if err != nil {
2935
2951
return "" , err
2936
2952
}
2937
- return newarchive , nil
2953
+ return newArchive , nil
2938
2954
}
2939
2955
2940
2956
actionsSeen := make (map [* Action ]bool )
@@ -3018,14 +3034,6 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string
3018
3034
}
3019
3035
}
3020
3036
3021
- for i , o := range ofiles {
3022
- if filepath .Base (o ) == "_cgo_flags" {
3023
- readCgoFlags (o )
3024
- ofiles = append (ofiles [:i ], ofiles [i + 1 :]... )
3025
- break
3026
- }
3027
- }
3028
-
3029
3037
ldflags = append (ldflags , "-Wl,--whole-archive" )
3030
3038
ldflags = append (ldflags , afiles ... )
3031
3039
ldflags = append (ldflags , "-Wl,--no-whole-archive" )
@@ -3112,7 +3120,7 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string
3112
3120
}
3113
3121
}
3114
3122
3115
- if err := b .run ("." , desc , nil , tools .linker (), "-o" , out , ofiles , ldflags , buildGccgoflags ); err != nil {
3123
+ if err := b .run ("." , desc , nil , tools .linker (), "-o" , out , ldflags , buildGccgoflags ); err != nil {
3116
3124
return err
3117
3125
}
3118
3126
@@ -3126,13 +3134,13 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string
3126
3134
}
3127
3135
3128
3136
func (tools gccgoToolchain ) ld (b * Builder , root * Action , out , importcfg string , allactions []* Action , mainpkg string , ofiles []string ) error {
3129
- return tools .link (b , root , out , importcfg , allactions , mainpkg , ofiles , ldBuildmode , root .Package .ImportPath )
3137
+ return tools .link (b , root , out , importcfg , allactions , ldBuildmode , root .Package .ImportPath )
3130
3138
}
3131
3139
3132
3140
func (tools gccgoToolchain ) ldShared (b * Builder , toplevelactions []* Action , out , importcfg string , allactions []* Action ) error {
3133
3141
fakeRoot := & Action {Mode : "gccgo ldshared" }
3134
3142
fakeRoot .Deps = toplevelactions
3135
- return tools .link (b , fakeRoot , out , importcfg , allactions , "" , nil , " shared" , out )
3143
+ return tools .link (b , fakeRoot , out , importcfg , allactions , "shared" , out )
3136
3144
}
3137
3145
3138
3146
func (tools gccgoToolchain ) cc (b * Builder , a * Action , ofile , cfile string ) error {
0 commit comments