@@ -605,26 +605,26 @@ func startInstall(dir string) chan struct{} {
605
605
606
606
// runInstall installs the library, package, or binary associated with dir,
607
607
// which is relative to $GOROOT/src.
608
- func runInstall (dir string , ch chan struct {}) {
609
- if dir == "net" || dir == "os/user" || dir == "crypto/x509" {
610
- fatalf ("go_bootstrap cannot depend on cgo package %s" , dir )
608
+ func runInstall (pkg string , ch chan struct {}) {
609
+ if pkg == "net" || pkg == "os/user" || pkg == "crypto/x509" {
610
+ fatalf ("go_bootstrap cannot depend on cgo package %s" , pkg )
611
611
}
612
612
613
613
defer close (ch )
614
614
615
- if dir == "unsafe" {
615
+ if pkg == "unsafe" {
616
616
return
617
617
}
618
618
619
619
if vflag > 0 {
620
620
if goos != gohostos || goarch != gohostarch {
621
- errprintf ("%s (%s/%s)\n " , dir , goos , goarch )
621
+ errprintf ("%s (%s/%s)\n " , pkg , goos , goarch )
622
622
} else {
623
- errprintf ("%s\n " , dir )
623
+ errprintf ("%s\n " , pkg )
624
624
}
625
625
}
626
626
627
- workdir := pathf ("%s/%s" , workdir , dir )
627
+ workdir := pathf ("%s/%s" , workdir , pkg )
628
628
xmkdirall (workdir )
629
629
630
630
var clean []string
@@ -634,11 +634,14 @@ func runInstall(dir string, ch chan struct{}) {
634
634
}
635
635
}()
636
636
637
- // path = full path to dir .
638
- path := pathf ("%s/src/%s" , goroot , dir )
637
+ // dir = full path to pkg .
638
+ dir := pathf ("%s/src/%s" , goroot , pkg )
639
639
name := filepath .Base (dir )
640
640
641
- ispkg := ! strings .HasPrefix (dir , "cmd/" ) || strings .Contains (dir , "/internal/" )
641
+ // ispkg predicts whether the package should be linked as a binary, based
642
+ // on the name. There should be no "main" packages in vendor, since
643
+ // 'go mod vendor' will only copy imported packages there.
644
+ ispkg := ! strings .HasPrefix (pkg , "cmd/" ) || strings .Contains (pkg , "/internal/" ) || strings .Contains (pkg , "/vendor/" )
642
645
643
646
// Start final link command line.
644
647
// Note: code below knows that link.p[targ] is the target.
@@ -650,7 +653,7 @@ func runInstall(dir string, ch chan struct{}) {
650
653
if ispkg {
651
654
// Go library (package).
652
655
ispackcmd = true
653
- link = []string {"pack" , pathf ( "%s/ pkg/%s_%s/%s.a" , goroot , goos , goarch , dir )}
656
+ link = []string {"pack" , packagefile ( pkg )}
654
657
targ = len (link ) - 1
655
658
xmkdirall (filepath .Dir (link [targ ]))
656
659
} else {
@@ -675,7 +678,7 @@ func runInstall(dir string, ch chan struct{}) {
675
678
// Gather files that are sources for this target.
676
679
// Everything in that directory, and any target-specific
677
680
// additions.
678
- files := xreaddir (path )
681
+ files := xreaddir (dir )
679
682
680
683
// Remove files beginning with . or _,
681
684
// which are likely to be editor temporary files.
@@ -687,7 +690,7 @@ func runInstall(dir string, ch chan struct{}) {
687
690
})
688
691
689
692
for _ , dt := range deptab {
690
- if dir == dt .prefix || strings .HasSuffix (dt .prefix , "/" ) && strings .HasPrefix (dir , dt .prefix ) {
693
+ if pkg == dt .prefix || strings .HasSuffix (dt .prefix , "/" ) && strings .HasPrefix (pkg , dt .prefix ) {
691
694
for _ , p := range dt .dep {
692
695
p = os .ExpandEnv (p )
693
696
files = append (files , p )
@@ -699,7 +702,7 @@ func runInstall(dir string, ch chan struct{}) {
699
702
// Convert to absolute paths.
700
703
for i , p := range files {
701
704
if ! filepath .IsAbs (p ) {
702
- files [i ] = pathf ("%s/%s" , path , p )
705
+ files [i ] = pathf ("%s/%s" , dir , p )
703
706
}
704
707
}
705
708
@@ -715,7 +718,7 @@ func runInstall(dir string, ch chan struct{}) {
715
718
return false
716
719
ok:
717
720
t := mtime (p )
718
- if ! t .IsZero () && ! strings .HasSuffix (p , ".a" ) && ! shouldbuild (p , dir ) {
721
+ if ! t .IsZero () && ! strings .HasSuffix (p , ".a" ) && ! shouldbuild (p , pkg ) {
719
722
return false
720
723
}
721
724
if strings .HasSuffix (p , ".go" ) {
@@ -742,7 +745,7 @@ func runInstall(dir string, ch chan struct{}) {
742
745
}
743
746
744
747
// For package runtime, copy some files into the work space.
745
- if dir == "runtime" {
748
+ if pkg == "runtime" {
746
749
xmkdirall (pathf ("%s/pkg/include" , goroot ))
747
750
// For use by assembly and C files.
748
751
copyfile (pathf ("%s/pkg/include/textflag.h" , goroot ),
@@ -764,7 +767,7 @@ func runInstall(dir string, ch chan struct{}) {
764
767
if vflag > 1 {
765
768
errprintf ("generate %s\n " , p )
766
769
}
767
- gt .gen (path , p )
770
+ gt .gen (dir , p )
768
771
// Do not add generated file to clean list.
769
772
// In runtime, we want to be able to
770
773
// build the package with the go tool,
@@ -782,22 +785,31 @@ func runInstall(dir string, ch chan struct{}) {
782
785
built:
783
786
}
784
787
785
- // Make sure dependencies are installed.
786
- var deps []string
788
+ // Resolve imported packages to actual package paths.
789
+ // Make sure they're installed.
790
+ importMap := make (map [string ]string )
787
791
for _ , p := range gofiles {
788
- deps = append (deps , readimports (p )... )
792
+ for _ , imp := range readimports (p ) {
793
+ importMap [imp ] = resolveVendor (imp , dir )
794
+ }
795
+ }
796
+ sortedImports := make ([]string , 0 , len (importMap ))
797
+ for imp := range importMap {
798
+ sortedImports = append (sortedImports , imp )
789
799
}
790
- for _ , dir1 := range deps {
791
- startInstall (dir1 )
800
+ sort .Strings (sortedImports )
801
+
802
+ for _ , dep := range importMap {
803
+ startInstall (dep )
792
804
}
793
- for _ , dir1 := range deps {
794
- install (dir1 )
805
+ for _ , dep := range importMap {
806
+ install (dep )
795
807
}
796
808
797
809
if goos != gohostos || goarch != gohostarch {
798
810
// We've generated the right files; the go command can do the build.
799
811
if vflag > 1 {
800
- errprintf ("skip build for cross-compile %s\n " , dir )
812
+ errprintf ("skip build for cross-compile %s\n " , pkg )
801
813
}
802
814
return
803
815
}
@@ -830,18 +842,35 @@ func runInstall(dir string, ch chan struct{}) {
830
842
if err := ioutil .WriteFile (goasmh , nil , 0666 ); err != nil {
831
843
fatalf ("cannot write empty go_asm.h: %s" , err )
832
844
}
833
- bgrun (& wg , path , asmabis ... )
845
+ bgrun (& wg , dir , asmabis ... )
834
846
bgwait (& wg )
835
847
}
836
848
849
+ // Build an importcfg file for the compiler.
850
+ buf := & bytes.Buffer {}
851
+ for _ , imp := range sortedImports {
852
+ if imp == "unsafe" {
853
+ continue
854
+ }
855
+ dep := importMap [imp ]
856
+ if imp != dep {
857
+ fmt .Fprintf (buf , "importmap %s=%s\n " , imp , dep )
858
+ }
859
+ fmt .Fprintf (buf , "packagefile %s=%s\n " , dep , packagefile (dep ))
860
+ }
861
+ importcfg := pathf ("%s/importcfg" , workdir )
862
+ if err := ioutil .WriteFile (importcfg , buf .Bytes (), 0666 ); err != nil {
863
+ fatalf ("cannot write importcfg file: %v" , err )
864
+ }
865
+
837
866
var archive string
838
867
// The next loop will compile individual non-Go files.
839
868
// Hand the Go files to the compiler en masse.
840
869
// For packages containing assembly, this writes go_asm.h, which
841
870
// the assembly files will need.
842
- pkg := dir
843
- if strings .HasPrefix (dir , "cmd/" ) && strings .Count (dir , "/" ) == 1 {
844
- pkg = "main"
871
+ pkgName := pkg
872
+ if strings .HasPrefix (pkg , "cmd/" ) && strings .Count (pkg , "/" ) == 1 {
873
+ pkgName = "main"
845
874
}
846
875
b := pathf ("%s/_go_.a" , workdir )
847
876
clean = append (clean , b )
@@ -852,11 +881,11 @@ func runInstall(dir string, ch chan struct{}) {
852
881
}
853
882
854
883
// Compile Go code.
855
- compile := []string {pathf ("%s/compile" , tooldir ), "-std" , "-pack" , "-o" , b , "-p" , pkg }
884
+ compile := []string {pathf ("%s/compile" , tooldir ), "-std" , "-pack" , "-o" , b , "-p" , pkgName , "-importcfg" , importcfg }
856
885
if gogcflags != "" {
857
886
compile = append (compile , strings .Fields (gogcflags )... )
858
887
}
859
- if dir == "runtime" {
888
+ if pkg == "runtime" {
860
889
compile = append (compile , "-+" )
861
890
}
862
891
if len (sfiles ) > 0 {
@@ -874,7 +903,7 @@ func runInstall(dir string, ch chan struct{}) {
874
903
// We use bgrun and immediately wait for it instead of calling run() synchronously.
875
904
// This executes all jobs through the bgwork channel and allows the process
876
905
// to exit cleanly in case an error occurs.
877
- bgrun (& wg , path , compile ... )
906
+ bgrun (& wg , dir , compile ... )
878
907
bgwait (& wg )
879
908
880
909
// Compile the files.
@@ -888,7 +917,7 @@ func runInstall(dir string, ch chan struct{}) {
888
917
// Change the last character of the output file (which was c or s).
889
918
b = b [:len (b )- 1 ] + "o"
890
919
compile = append (compile , "-o" , b , p )
891
- bgrun (& wg , path , compile ... )
920
+ bgrun (& wg , dir , compile ... )
892
921
893
922
link = append (link , b )
894
923
if doclean {
@@ -909,6 +938,12 @@ func runInstall(dir string, ch chan struct{}) {
909
938
bgwait (& wg )
910
939
}
911
940
941
+ // packagefile returns the path to a compiled .a file for the given package
942
+ // path. Paths may need to be resolved with resolveVendor first.
943
+ func packagefile (pkg string ) string {
944
+ return pathf ("%s/pkg/%s_%s/%s.a" , goroot , goos , goarch , pkg )
945
+ }
946
+
912
947
// matchfield reports whether the field (x,y,z) matches this build.
913
948
// all the elements in the field must be satisfied.
914
949
func matchfield (f string ) bool {
@@ -940,7 +975,7 @@ func matchtag(tag string) bool {
940
975
// of GOOS and GOARCH.
941
976
// We also allow the special tag cmd_go_bootstrap.
942
977
// See ../go/bootstrap.go and package go/build.
943
- func shouldbuild (file , dir string ) bool {
978
+ func shouldbuild (file , pkg string ) bool {
944
979
// Check file name for GOOS or GOARCH.
945
980
name := filepath .Base (file )
946
981
excluded := func (list []string , ok string ) bool {
@@ -982,7 +1017,7 @@ func shouldbuild(file, dir string) bool {
982
1017
if code == "package documentation" {
983
1018
return false
984
1019
}
985
- if code == "package main" && dir != "cmd/go" && dir != "cmd/cgo" {
1020
+ if code == "package main" && pkg != "cmd/go" && pkg != "cmd/cgo" {
986
1021
return false
987
1022
}
988
1023
if ! strings .HasPrefix (p , "//" ) {
0 commit comments