@@ -410,14 +410,12 @@ func (t *tester) registerTests() {
410
410
t .registerTest ("testgodefs" , "../misc/cgo/testgodefs" , "./test.bash" )
411
411
}
412
412
if t .cgoEnabled {
413
- if t .gohostos == "windows" {
413
+ if t .cgoTestSOSupported () {
414
414
t .tests = append (t .tests , distTest {
415
415
name : "testso" ,
416
416
heading : "../misc/cgo/testso" ,
417
- fn : t .cgoTestSOWindows ,
417
+ fn : t .cgoTestSO ,
418
418
})
419
- } else if t .hasBash () && t .goos != "android" && ! t .iOS () {
420
- t .registerTest ("testso" , "../misc/cgo/testso" , "./test.bash" )
421
419
}
422
420
if t .supportedBuildmode ("c-archive" ) {
423
421
t .registerTest ("testcarchive" , "../misc/cgo/testcarchive" , "./test.bash" )
@@ -714,21 +712,67 @@ func (t *tester) cgoTest() error {
714
712
return nil
715
713
}
716
714
717
- func (t * tester ) cgoTestSOWindows () error {
718
- cmd := t .dirCmd ("misc/cgo/testso" , `.\test` )
719
- var buf bytes.Buffer
720
- cmd .Stdout = & buf
721
- cmd .Stderr = & buf
722
- err := cmd .Run ()
723
- s := buf .String ()
724
- fmt .Println (s )
715
+ func (t * tester ) cgoTestSOSupported () bool {
716
+ if t .goos == "android" || t .iOS () {
717
+ // No exec facility on Android or iOS.
718
+ return false
719
+ }
720
+ if t .goos == "ppc64le" || t .goos == "ppc64" {
721
+ // External linking not implemented on ppc64 (issue #8912).
722
+ return false
723
+ }
724
+ return true
725
+ }
726
+
727
+ func (t * tester ) cgoTestSO () error {
728
+ dir := filepath .Join (t .goroot , "misc/cgo/testso" )
729
+
730
+ // build shared object
731
+ output , err := exec .Command ("go" , "env" , "CC" ).Output ()
732
+ if err != nil {
733
+ return fmt .Errorf ("Error running go env CC: %v" , err )
734
+ }
735
+ cc := strings .TrimSuffix (string (output ), "\n " )
736
+ if cc == "" {
737
+ return errors .New ("CC environment variable (go env CC) cannot be empty" )
738
+ }
739
+ output , err = exec .Command ("go" , "env" , "GOGCCFLAGS" ).Output ()
725
740
if err != nil {
741
+ return fmt .Errorf ("Error running go env GOGCCFLAGS: %v" , err )
742
+ }
743
+ gogccflags := strings .Split (strings .TrimSuffix (string (output ), "\n " ), " " )
744
+
745
+ ext := "so"
746
+ args := append (gogccflags , "-shared" )
747
+ switch t .goos {
748
+ case "darwin" :
749
+ ext = "dylib"
750
+ args = append (args , "-undefined" , "suppress" , "-flat_namespace" )
751
+ case "windows" :
752
+ ext = "dll"
753
+ }
754
+ sofname := "libcgosotest." + ext
755
+ args = append (args , "-o" , sofname , "cgoso_c.c" )
756
+
757
+ if err := t .dirCmd (dir , cc , args ... ).Run (); err != nil {
726
758
return err
727
759
}
728
- if strings .Contains (s , "FAIL" ) {
729
- return errors .New ("test failed" )
760
+ defer os .Remove (filepath .Join (dir , sofname ))
761
+
762
+ if err := t .dirCmd (dir , "go" , "build" , "-o" , "main.exe" , "main.go" ).Run (); err != nil {
763
+ return err
730
764
}
731
- return nil
765
+ defer os .Remove (filepath .Join (dir , "main.exe" ))
766
+
767
+ cmd := t .dirCmd (dir , "./main.exe" )
768
+ if t .goos != "windows" {
769
+ s := "LD_LIBRARY_PATH"
770
+ if t .goos == "darwin" {
771
+ s = "DYLD_LIBRARY_PATH"
772
+ }
773
+ cmd .Env = mergeEnvLists ([]string {s + "=." }, os .Environ ())
774
+ }
775
+ return cmd .Run ()
732
776
}
733
777
734
778
func (t * tester ) hasBash () bool {
0 commit comments