Skip to content

go/build: support language-specific go:build comment prefixes for non-Go files#79537

Open
MohammadRaziei wants to merge 1 commit into
golang:masterfrom
MohammadRaziei:master
Open

go/build: support language-specific go:build comment prefixes for non-Go files#79537
MohammadRaziei wants to merge 1 commit into
golang:masterfrom
MohammadRaziei:master

Conversation

@MohammadRaziei
Copy link
Copy Markdown

The Problem

Go and MATLAB cannot coexist in the same directory — at all.

MATLAB source files use the .m extension. Go's build system also recognises .m as Objective-C. The moment you place a .m file next to a go.mod, the toolchain reads it, fails to parse it as valid Go/ObjC source, and either errors out or silently misclassifies the file. Two completely unrelated tools, in the same filesystem directory, and they are fundamentally incompatible with each other.

The standard escape hatch for situations like this is //go:build ignore. It was designed exactly for this purpose: to tell the Go toolchain "don't touch this file". It works beautifully for .go files. It works for .c files. It works for .s files.

It does not work for MATLAB.

Because // is not a comment in MATLAB. Adding //go:build ignore to the top of a .m file makes Go happy and breaks MATLAB. You cannot win. The file is either valid MATLAB or it is ignored by Go — never both at the same time.

This is a design gap. If //go:build ignore was designed as the solution to "I have a file Go should not touch", then that solution must be reachable from every language Go shares extensions with. Right now it is not.

Why This Matters More Than It Used To

Polyglot and multi-language projects are not exotic anymore. Scientific computing workflows that combine Go services with MATLAB or Python processing pipelines are increasingly common. Monorepos routinely mix languages. The Go toolchain's assumption that it owns every file with a recognised extension — and that everyone speaks // comments — does not hold in these environments.

A Go module that shares a directory with a .m MATLAB file should not scream. It should not error. It should not require the MATLAB file to be moved, renamed, or corrupted with foreign syntax just to appease the build system. The current behaviour is not a corner case; it is a wall that polyglot projects hit and cannot get past cleanly.

What This PR Does

It teaches the build system that non-Go source files may carry go:build constraints using their own language's comment syntax, not Go's.

Extension   Prefix         Language
─────────────────────────────────────
.m          % go:build     MATLAB
.f90        ! go:build     Fortran (free-form)

A MATLAB file can now opt out of the Go build with a single line that is also a perfectly valid MATLAB comment:

% go:build ignore

function result = process(data)
    % ... actual MATLAB code ...
end

Go sees a build constraint and ignores the file. MATLAB sees a comment and parses the file normally. Both tools are happy. The file does not have to move.

Implementation

The change is intentionally minimal and backward-compatible. No existing behaviour changes; only new prefixes are recognised for non-Go extensions.

src/go/build/build.go

  • extCommentPrefix — a map from file extension to its native line-comment prefix for go:build directives
  • isGoBuildCommentWithPrefix — generalised version of isGoBuildComment that accepts a configurable prefix
  • parseFileHeaderWithPrefix — like parseFileHeader but for single-line comment syntaxes (no /* */ block-comment tracking needed)
  • shouldBuildWithPrefixshouldBuild extended with an optional commentPrefix; the original shouldBuild delegates to it with nil, so all existing call sites are unaffected
  • matchFile — passes the appropriate prefix for non-Go files; Go files are completely unchanged

src/cmd/go/internal/modindex/build.go
Same changes mirrored in the module-index copy of the build logic (getConstraintsWithPrefix, parseFileHeaderWithPrefix, isGoBuildCommentWithPrefix).

src/go/build/testdata/non_go_build_tags/
New test fixtures: ignored.m, included.m, linux_only.m, doc.go.

src/go/build/build_test.go

  • TestShouldBuildWithPrefix — unit tests covering % go:build (MATLAB) and # go:build (shell/Python/R) with ignore, platform tags, boolean expressions, and lookalike-but-not-constraint lines
  • TestMatlabFileBuildTagsImportDir integration test that verifies ignored.m is excluded, included.m is always present, and linux_only.m is included on Linux

This Is a Design Gap, Not a Feature Request

//go:build ignore exists precisely because the Go team recognised that sometimes a file should not be compiled. The mechanism was designed to be the answer. The problem is that the answer is only expressible in one language's comment syntax.

If the intent was "files that should be skipped can say so", then the implementation should honour that intent for all the languages those files are written in. A MATLAB file deserves the same ability to say go:build ignore as a Go file does — in a way that does not break the tool that actually owns the file.

This PR closes that gap.


I would be genuinely happy if this gets accepted. The fix is small, the scope is contained, and it unblocks a real class of projects that currently have no good answer. Happy to revise, split, or adjust anything based on feedback.

…-Go files

Files in languages other than Go that happen to share an extension
recognised by the Go toolchain (most notably MATLAB .m files, which
Go treats as Objective-C) cannot currently carry go:build constraints
using their native comment syntax.  The only workaround is to add a
//go:build line at the top of the file, but that line is a syntax
error in MATLAB (and other languages), causing those tools to reject
the file.

This change teaches the build system to recognise language-specific
line-comment prefixes for go:build directives in non-Go source files:

  Extension  Prefix        Language
  .m         % go:build    MATLAB
  .f90       ! go:build    Fortran (free-form)

A MATLAB file can now opt out of the build with:

  % go:build ignore

and MATLAB itself will continue to parse the file normally, because
the line is a valid MATLAB comment.

Implementation
--------------
* go/build/build.go
  - extCommentPrefix: map[string][]byte of extension → comment prefix
  - goBuildCommentForExt: helper to look up the prefix
  - isGoBuildCommentWithPrefix: generalised isGoBuildComment
  - parseFileHeaderWithPrefix: like parseFileHeader but for single-
    line comment syntaxes (no /* */ block-comment tracking needed)
  - shouldBuildWithPrefix: shouldBuild extended with an optional
    commentPrefix parameter; shouldBuild delegates to it with nil
  - matchFile: passes the appropriate commentPrefix for non-Go files

* cmd/go/internal/modindex/build.go
  Same changes mirrored in the module-index copy of the logic:
  getConstraintsWithPrefix, parseFileHeaderWithPrefix,
  isGoBuildCommentWithPrefix, extCommentPrefix.

Tests
-----
* TestShouldBuildWithPrefix  – unit tests for % go:build and # go:build
* TestMatlabFileBuildTags    – ImportDir integration test using real
  testdata .m files (ignored.m, included.m, linux_only.m)
@google-cla
Copy link
Copy Markdown

google-cla Bot commented May 20, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@MohammadRaziei
Copy link
Copy Markdown
Author

I do CLA now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant