{"record":{"id":"7a6af5c89e96235f","repo":"golang/go","slug":"fortran-source-files-not-allowed-when-not-using-cg","errorCode":null,"errorMessage":"Fortran source files not allowed when not using cgo or SWIG: %s","messagePattern":"Fortran source files not allowed when not using cgo or SWIG: (.+?)","errorType":"exception","errorClass":"PackageError","httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/load/pkg.go","lineNumber":2119,"sourceCode":"\n\t// The gc toolchain only permits C source files with cgo or SWIG.\n\tif len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == \"gc\" {\n\t\tsetError(fmt.Errorf(\"C source files not allowed when not using cgo or SWIG: %s\", strings.Join(p.CFiles, \" \")))\n\t\treturn\n\t}\n\n\t// C++, Objective-C, and Fortran source files are permitted only with cgo or SWIG,\n\t// regardless of toolchain.\n\tif len(p.CXXFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {\n\t\tsetError(fmt.Errorf(\"C++ source files not allowed when not using cgo or SWIG: %s\", strings.Join(p.CXXFiles, \" \")))\n\t\treturn\n\t}\n\tif len(p.MFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {\n\t\tsetError(fmt.Errorf(\"Objective-C source files not allowed when not using cgo or SWIG: %s\", strings.Join(p.MFiles, \" \")))\n\t\treturn\n\t}\n\tif len(p.FFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {\n\t\tsetError(fmt.Errorf(\"Fortran source files not allowed when not using cgo or SWIG: %s\", strings.Join(p.FFiles, \" \")))\n\t\treturn\n\t}\n}\n\n// An EmbedError indicates a problem with a go:embed directive.\ntype EmbedError struct {\n\tPattern string\n\tErr     error\n}\n\nfunc (e *EmbedError) Error() string {\n\treturn fmt.Sprintf(\"pattern %s: %v\", e.Pattern, e.Err)\n}\n\nfunc (e *EmbedError) Unwrap() error {\n\treturn e.Err\n}\n","sourceCodeStart":2101,"sourceCodeEnd":2137,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/load/pkg.go#L2101-L2137","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: pkg/foo.go has no cgo, pkg/blas.f present -> error\n// after: add pkg/blas.go\npackage foo\n\n/*\n#cgo LDFLAGS: -lgfortran\nvoid dgemm_(...);\n*/\nimport \"C\"","handlingStrategy":"validation","validationCode":"// Before building, ensure Fortran/C++/ObjC files are gated by cgo/SWIG in the package.\n// go vet ./...  surfaces this as a PackageError before deploy.\n//\n// Programmatic check that the package uses cgo when *.f* files are present:\n//   grep -L 'import \"C\"' $(ls *.go) && ls *.f* 2>/dev/null\n// If both halves match, add a cgo shim or remove the .f file.","typeGuard":null,"tryCatchPattern":"// When driving `go build` from code, capture stderr and look for the\n// \"not allowed when not using cgo or SWIG\" substring, then advise the user:\n//\n//   out, err := exec.Command(\"go\", \"build\", \"./...\").CombinedOutput()\n//   if err != nil && bytes.Contains(out, []byte(\"not allowed when not using cgo or SWIG\")) {\n//       return fmt.Errorf(\"enable cgo (import \\\"C\\\" + CGO_ENABLED=1) or remove the foreign source file\")\n//   }","preventionTips":["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`."],"tags":["cgo","fortran","swig","build","toolchain"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}