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
- 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.
- Replace the Fortran glue with a SWIG interface (.swig file) so p.UsesSwig() is true.
- Remove the .f/.f90/.for file from the package directory if it is not actually needed.
- 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
- Treat any .f/.f90/.cxx/.m file added to a Go package as a build-breaker unless a cgo or SWIG shim is already present in the same package.
- Run `go vet ./...` in CI to catch source-class validation errors before `go build`.
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
- C compiler %q not found: %v
- %s requires external (cgo) linking, but cgo is not enabled
- must have SWIG version >= 3.0.6
- SWIG file must not use prefix 'cgo'
- main package is in repository %q but current directory is in
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/7a6af5c89e96235f.
Report an issue: GitHub.