golang/go · error · PackageError

Fortran source files not allowed when not using cgo or SWIG:

Error message

Fortran source files not allowed when not using cgo or SWIG: %s

What it means

Thrown while validating a package's source files in the gc/go build. A package directory contains Fortran source files (matched into p.FFiles, e.g. .f/.f90/.F95) but the package does not use cgo (no `import "C"`) and does not use SWIG (no .swig/.swigcxx files). The gc toolchain only knows how to compile Fortran through the cgo or SWIG glue layers, so bare .f files are rejected. C++ and Objective-C follow the identical rule; C files have the same rule but only under the gc compiler (see line 2103).

Source

Thrown at src/cmd/go/internal/load/pkg.go:2119

	// The gc toolchain only permits C source files with cgo or SWIG.
	if len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == "gc" {
		setError(fmt.Errorf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " ")))
		return
	}

	// C++, Objective-C, and Fortran source files are permitted only with cgo or SWIG,
	// regardless of toolchain.
	if len(p.CXXFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
		setError(fmt.Errorf("C++ source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CXXFiles, " ")))
		return
	}
	if len(p.MFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
		setError(fmt.Errorf("Objective-C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.MFiles, " ")))
		return
	}
	if len(p.FFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
		setError(fmt.Errorf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " ")))
		return
	}
}

// An EmbedError indicates a problem with a go:embed directive.
type EmbedError struct {
	Pattern string
	Err     error
}

func (e *EmbedError) Error() string {
	return fmt.Sprintf("pattern %s: %v", e.Pattern, e.Err)
}

func (e *EmbedError) Unwrap() error {
	return e.Err
}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Add a cgo shim: create a .go file in the package with `import "C"` and the necessary cgo directives/CFLAGS/LDFLAGS so p.UsesCgo() becomes true, then run with CGO_ENABLED=1.
  2. Replace the Fortran glue with a SWIG interface (.swig file) so p.UsesSwig() is true.
  3. Remove the .f/.f90/.for file from the package directory if it is not actually needed.
  4. Move the Fortran source into a subdirectory that is not a Go package and build it out-of-band, then link via cgo from a parent package.

Example fix

// before: pkg/foo.go has no cgo, pkg/blas.f present -> error
// after: add pkg/blas.go
package foo

/*
#cgo LDFLAGS: -lgfortran
void dgemm_(...);
*/
import "C"
Defensive patterns

Strategy: validation

Validate before calling

// Before building, ensure Fortran/C++/ObjC files are gated by cgo/SWIG in the package.
// go vet ./...  surfaces this as a PackageError before deploy.
//
// Programmatic check that the package uses cgo when *.f* files are present:
//   grep -L 'import "C"' $(ls *.go) && ls *.f* 2>/dev/null
// If both halves match, add a cgo shim or remove the .f file.

Try / catch

// When driving `go build` from code, capture stderr and look for the
// "not allowed when not using cgo or SWIG" substring, then advise the user:
//
//   out, err := exec.Command("go", "build", "./...").CombinedOutput()
//   if err != nil && bytes.Contains(out, []byte("not allowed when not using cgo or SWIG")) {
//       return fmt.Errorf("enable cgo (import \"C\" + CGO_ENABLED=1) or remove the foreign source file")
//   }

Prevention

When it happens

Trigger: Adding a .f/.f90/.F/.for file to a package whose .go sources lack `import "C"` and that has no .swig interface file; running `go build`/`go test`/`go vet` on such a package. CGO_ENABLED is irrelevant to the check itself — the check is on p.UsesCgo()/p.UsesSwig(), which are set by the presence of `import "C"` / SWIG files, not by the env var.

Common situations: Copying a scientific computing package (BLAS/LAPACK Fortran sources) into a pure-Go module; vendoring a C/Fortran library but forgetting the cgo shim file; building on a machine without a C toolchain so cgo was thought to be off; mixing a legacy Fortran routine into a Go package during a port.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/7a6af5c89e96235f. Report an issue: GitHub.