Skip to content

Commit 1e9a755

Browse files
committed
misc/cgo/fortran: convert to Go test
Currently, the entry-point to this test is a Bash script that smoke tests the FORTRAN compiler and then runs a FORTRAN-containing Go test. This CL rearranges things so a pure Go Go test smoke tests the FORTRAN compiler and then runs a non-test FORTRAN-containing Go binary. While we're here, we fix a discrepancy when the host is GOARCH=amd64, but the target is GOARCH=386. Previously, we would pick the wrong libgfortran path because we didn't account for the cross-compilation, causing the link to fail. Except for some reason this was ignored and the test nevertheless "passed". In the new test we're a little more strict, so this build failure will cause the test to fail, so we add a little logic to account for cross-compilation with the host toolchain. For #37486. Change-Id: Ie6f70066885d6fbb4e1b5a2b1e13b85dee5b359b Reviewed-on: https://go-review.googlesource.com/c/go/+/443069 Reviewed-by: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Bryan Mills <[email protected]> Run-TryBot: Austin Clements <[email protected]>
1 parent 03272d1 commit 1e9a755

File tree

5 files changed

+84
-62
lines changed

5 files changed

+84
-62
lines changed

misc/cgo/fortran/fortran_test.go

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,81 @@
1-
// Copyright 2016 The Go Authors. All rights reserved.
1+
// Copyright 2022 The Go Authors. All rights reserved.
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

55
package fortran
66

7-
import "testing"
7+
import (
8+
"fmt"
9+
"os"
10+
"os/exec"
11+
"path/filepath"
12+
"runtime"
13+
"strings"
14+
"testing"
15+
)
816

917
func TestFortran(t *testing.T) {
10-
if a := TheAnswer(); a != 42 {
11-
t.Errorf("Unexpected result for The Answer. Got: %d Want: 42", a)
18+
// Find the FORTRAN compiler.
19+
fc := os.Getenv("FC")
20+
if fc == "" {
21+
fc, _ = exec.LookPath("gfortran")
22+
}
23+
if fc == "" {
24+
t.Skip("fortran compiler not found (try setting $FC)")
25+
}
26+
27+
var fcExtra []string
28+
if strings.Contains(fc, "gfortran") {
29+
// TODO: This duplicates but also diverges from logic from cmd/go
30+
// itself. For example, cmd/go merely adds -lgfortran without the extra
31+
// library path work. If this is what's necessary to run gfortran, we
32+
// should reconcile the logic here and in cmd/go.. Maybe this should
33+
// become a cmd/go script test to share that logic.
34+
35+
// Add -m32 if we're targeting 386, in case this is a cross-compile.
36+
if runtime.GOARCH == "386" {
37+
fcExtra = append(fcExtra, "-m32")
38+
}
39+
40+
// Find libgfortran. If the FORTRAN compiler isn't bundled
41+
// with the C linker, this may be in a path the C linker can't
42+
// find on its own. (See #14544)
43+
libExt := "so"
44+
switch runtime.GOOS {
45+
case "darwin":
46+
libExt = "dylib"
47+
case "aix":
48+
libExt = "a"
49+
}
50+
libPath, err := exec.Command(fc, append([]string{"-print-file-name=libgfortran." + libExt}, fcExtra...)...).CombinedOutput()
51+
if err != nil {
52+
t.Errorf("error invoking %s: %s", fc, err)
53+
}
54+
libDir := filepath.Dir(string(libPath))
55+
cgoLDFlags := os.Getenv("CGO_LDFLAGS")
56+
cgoLDFlags += " -L " + libDir
57+
if runtime.GOOS != "aix" {
58+
cgoLDFlags += " -Wl,-rpath," + libDir
59+
}
60+
t.Logf("CGO_LDFLAGS=%s", cgoLDFlags)
61+
os.Setenv("CGO_LDFLAGS", cgoLDFlags)
62+
63+
}
64+
65+
// Do a test build that doesn't involve Go FORTRAN support.
66+
fcArgs := append([]string{"helloworld/helloworld.f90", "-o", "/dev/null"}, fcExtra...)
67+
t.Logf("%s %s", fc, fcArgs)
68+
if err := exec.Command(fc, fcArgs...).Run(); err != nil {
69+
t.Skipf("skipping Fortran test: could not build helloworld.f90 with %s: %s", fc, err)
70+
}
71+
72+
// Finally, run the actual test.
73+
t.Log("go", "run", "./testdata/testprog")
74+
out, err := exec.Command("go", "run", "./testdata/testprog").CombinedOutput()
75+
if err == nil && string(out) != "ok\n" {
76+
err = fmt.Errorf("expected ok")
77+
}
78+
if err != nil {
79+
t.Errorf("%s\nOutput:\n%s", err, string(out))
1280
}
1381
}

misc/cgo/fortran/test.bash

Lines changed: 0 additions & 44 deletions
This file was deleted.

misc/cgo/fortran/fortran.go renamed to misc/cgo/fortran/testdata/testprog/fortran.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,20 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
package fortran
5+
package main
66

77
// int the_answer();
88
import "C"
9+
import "os"
910

1011
func TheAnswer() int {
1112
return int(C.the_answer())
1213
}
14+
15+
func main() {
16+
if a := TheAnswer(); a != 42 {
17+
println("Unexpected result for The Answer. Got:", a, " Want: 42")
18+
os.Exit(1)
19+
}
20+
println("ok")
21+
}

src/cmd/dist/test.go

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -746,19 +746,8 @@ func (t *tester) registerTests() {
746746
// Disabled on iOS. golang.org/issue/15919
747747
t.registerHostTest("cgo_stdio", "../misc/cgo/stdio", "misc/cgo/stdio", ".")
748748
t.registerHostTest("cgo_life", "../misc/cgo/life", "misc/cgo/life", ".")
749-
fortran := os.Getenv("FC")
750-
if fortran == "" {
751-
fortran, _ = exec.LookPath("gfortran")
752-
}
753-
if t.hasBash() && goos != "android" && fortran != "" {
754-
t.tests = append(t.tests, distTest{
755-
name: "cgo_fortran",
756-
heading: "../misc/cgo/fortran",
757-
fn: func(dt *distTest) error {
758-
t.addCmd(dt, "misc/cgo/fortran", "./test.bash", fortran)
759-
return nil
760-
},
761-
})
749+
if goos != "android" {
750+
t.registerHostTest("cgo_fortran", "../misc/cgo/fortran", "misc/cgo/fortran", ".")
762751
}
763752
if t.hasSwig() && goos != "android" {
764753
t.tests = append(t.tests, distTest{

0 commit comments

Comments
 (0)