diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:25:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:25:22 +0000 |
commit | f6ad4dcef54c5ce997a4bad5a6d86de229015700 (patch) | |
tree | 7cfa4e31ace5c2bd95c72b154d15af494b2bcbef /src/cmd/cgo/internal/testfortran | |
parent | Initial commit. (diff) | |
download | golang-1.22-f6ad4dcef54c5ce997a4bad5a6d86de229015700.tar.xz golang-1.22-f6ad4dcef54c5ce997a4bad5a6d86de229015700.zip |
Adding upstream version 1.22.1.upstream/1.22.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/cmd/cgo/internal/testfortran')
4 files changed, 127 insertions, 0 deletions
diff --git a/src/cmd/cgo/internal/testfortran/fortran_test.go b/src/cmd/cgo/internal/testfortran/fortran_test.go new file mode 100644 index 0000000..0eae7c5 --- /dev/null +++ b/src/cmd/cgo/internal/testfortran/fortran_test.go @@ -0,0 +1,91 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package fortran + +import ( + "internal/testenv" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "testing" +) + +func TestFortran(t *testing.T) { + testenv.MustHaveGoRun(t) + testenv.MustHaveCGO(t) + + // Find the FORTRAN compiler. + fc := os.Getenv("FC") + if fc == "" { + fc, _ = exec.LookPath("gfortran") + } + if fc == "" { + t.Skip("fortran compiler not found (try setting $FC)") + } + + var fcExtra []string + if strings.Contains(fc, "gfortran") { + // TODO: This duplicates but also diverges from logic from cmd/go + // itself. For example, cmd/go merely adds -lgfortran without the extra + // library path work. If this is what's necessary to run gfortran, we + // should reconcile the logic here and in cmd/go.. Maybe this should + // become a cmd/go script test to share that logic. + + // Add -m32 if we're targeting 386, in case this is a cross-compile. + if runtime.GOARCH == "386" { + fcExtra = append(fcExtra, "-m32") + } + + // Find libgfortran. If the FORTRAN compiler isn't bundled + // with the C linker, this may be in a path the C linker can't + // find on its own. (See #14544) + libExt := "so" + switch runtime.GOOS { + case "darwin": + libExt = "dylib" + case "aix": + libExt = "a" + } + libPath, err := exec.Command(fc, append([]string{"-print-file-name=libgfortran." + libExt}, fcExtra...)...).CombinedOutput() + if err != nil { + t.Errorf("error invoking %s: %s", fc, err) + } + libDir := filepath.Dir(string(libPath)) + cgoLDFlags := os.Getenv("CGO_LDFLAGS") + cgoLDFlags += " -L " + libDir + if runtime.GOOS != "aix" { + cgoLDFlags += " -Wl,-rpath," + libDir + } + t.Logf("CGO_LDFLAGS=%s", cgoLDFlags) + os.Setenv("CGO_LDFLAGS", cgoLDFlags) + + } + + // Do a test build that doesn't involve Go FORTRAN support. + fcArgs := append([]string{"testdata/helloworld/helloworld.f90", "-o", "/dev/null"}, fcExtra...) + t.Logf("%s %s", fc, fcArgs) + if err := exec.Command(fc, fcArgs...).Run(); err != nil { + t.Skipf("skipping Fortran test: could not build helloworld.f90 with %s: %s", fc, err) + } + + // Finally, run the actual test. + t.Log("go", "run", "./testdata/testprog") + var stdout, stderr strings.Builder + cmd := exec.Command("go", "run", "./testdata/testprog") + cmd.Stdout = &stdout + cmd.Stderr = &stderr + err := cmd.Run() + t.Logf("%v", cmd) + if stderr.Len() != 0 { + t.Logf("stderr:\n%s", stderr.String()) + } + if err != nil { + t.Errorf("%v\n%s", err, stdout.String()) + } else if stdout.String() != "ok\n" { + t.Errorf("stdout:\n%s\nwant \"ok\"", stdout.String()) + } +} diff --git a/src/cmd/cgo/internal/testfortran/testdata/helloworld/helloworld.f90 b/src/cmd/cgo/internal/testfortran/testdata/helloworld/helloworld.f90 new file mode 100644 index 0000000..cbc34c1 --- /dev/null +++ b/src/cmd/cgo/internal/testfortran/testdata/helloworld/helloworld.f90 @@ -0,0 +1,3 @@ + program HelloWorldF90 + write(*,*) "Hello World!" + end program HelloWorldF90 diff --git a/src/cmd/cgo/internal/testfortran/testdata/testprog/answer.f90 b/src/cmd/cgo/internal/testfortran/testdata/testprog/answer.f90 new file mode 100644 index 0000000..b3717ee --- /dev/null +++ b/src/cmd/cgo/internal/testfortran/testdata/testprog/answer.f90 @@ -0,0 +1,9 @@ +! Copyright 2016 The Go Authors. All rights reserved. +! Use of this source code is governed by a BSD-style +! license that can be found in the LICENSE file. + +function the_answer() result(j) bind(C) + use iso_c_binding, only: c_int + integer(c_int) :: j ! output + j = 42 +end function the_answer diff --git a/src/cmd/cgo/internal/testfortran/testdata/testprog/fortran.go b/src/cmd/cgo/internal/testfortran/testdata/testprog/fortran.go new file mode 100644 index 0000000..e98d76c --- /dev/null +++ b/src/cmd/cgo/internal/testfortran/testdata/testprog/fortran.go @@ -0,0 +1,24 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// int the_answer(); +import "C" +import ( + "fmt" + "os" +) + +func TheAnswer() int { + return int(C.the_answer()) +} + +func main() { + if a := TheAnswer(); a != 42 { + fmt.Fprintln(os.Stderr, "Unexpected result for The Answer. Got:", a, " Want: 42") + os.Exit(1) + } + fmt.Fprintln(os.Stdout, "ok") +} |