golang/go · error · PackageError

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

Error message

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

What it means

A Go package contains .c files but no .go file has 'import "C"' (cgo) and no SWIG (.swig/.swigcxx) files are present. The gc compiler toolchain only allows C source files when cgo or SWIG is active. This check is specific to cfg.BuildContext.Compiler == "gc"; gccgo handles C files differently. The p.UsesCgo() and p.UsesSwig() methods determine whether cgo or SWIG is active.

Source

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

	}

	// If cgo is not enabled, ignore cgo supporting sources
	// just as we ignore go files containing import "C".
	if !cfg.BuildContext.CgoEnabled {
		p.CFiles = nil
		p.CXXFiles = nil
		p.MFiles = nil
		p.SwigFiles = nil
		p.SwigCXXFiles = nil
		// Note that SFiles are okay (they go to the Go assembler)
		// and HFiles are okay (they might be used by the SFiles).
		// Also Sysofiles are okay (they might not contain object
		// code; see issue #16050).
	}

	// 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
	}
}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. If you need the C files, add cgo to the package: create a .go file with import "C" and a // #cgo or // #include preamble.
  2. Ensure CGO_ENABLED=1 in your build environment (check with: go env CGO_ENABLED).
  3. If you don't need the C files, remove them from the package directory.
  4. If using SWIG, add the appropriate .swig or .swigcxx file.

Example fix

// before — .c file present but no cgo
// mypackage/
//   main.go
//   helper.c

// after — add cgo preamble to a .go file
// mypackage/main.go
package main

/*
#include "helper.c"
*/
import "C"

func main() {}
// mypackage/helper.c remains
Defensive patterns

Strategy: validation

Validate before calling

// Check that C files are accompanied by cgo or SWIG before building.
func checkCgoRequirement(pkgDir string) error {
    entries, _ := os.ReadDir(pkgDir)
    var hasC, hasCgo, hasSwig bool
    for _, e := range entries {
        name := e.Name()
        if strings.HasSuffix(name, ".c") {
            hasC = true
        }
        if strings.HasSuffix(name, ".swig") || strings.HasSuffix(name, ".swigcxx") {
            hasSwig = true
        }
        if strings.HasSuffix(name, ".go") {
            data, _ := os.ReadFile(filepath.Join(pkgDir, name))
            if bytes.Contains(data, []byte("import \"C\"")) {
                hasCgo = true
            }
        }
    }
    if hasC && !hasCgo && !hasSwig {
        return fmt.Errorf("C files present without cgo or SWIG — add import \"C\" or set CGO_ENABLED=1")
    }
    return nil
}

Prevention

When it happens

Trigger: Adding a .c file to a Go package directory without also having cgo (import "C" in a .go file) or SWIG interface files. Cgo is disabled via CGO_ENABLED=0 but .c files remain in the directory. Removing import "C" from Go files while leaving C files in place.

Common situations: Adding C helper files without setting up cgo properly. Setting CGO_ENABLED=0 (common in cross-compilation or minimal containers) while C files remain. Removing cgo integration from a package but forgetting to delete the C files. Accidental inclusion of C files from a third-party dependency.

Related errors


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