go/build: support language-specific go:build comment prefixes for non-Go files#79537
Open
MohammadRaziei wants to merge 1 commit into
Open
go/build: support language-specific go:build comment prefixes for non-Go files#79537MohammadRaziei wants to merge 1 commit into
go:build comment prefixes for non-Go files#79537MohammadRaziei wants to merge 1 commit into
Conversation
…-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)
|
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. |
Author
|
I do CLA now! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Problem
Go and MATLAB cannot coexist in the same directory — at all.
MATLAB source files use the
.mextension. Go's build system also recognises.mas Objective-C. The moment you place a.mfile next to ago.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.gofiles. It works for.cfiles. It works for.sfiles.It does not work for MATLAB.
Because
//is not a comment in MATLAB. Adding//go:build ignoreto the top of a.mfile 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 ignorewas 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
.mMATLAB 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:buildconstraints using their own language's comment syntax, not Go's.A MATLAB file can now opt out of the Go build with a single line that is also a perfectly valid MATLAB comment:
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.goextCommentPrefix— a map from file extension to its native line-comment prefix forgo:builddirectivesisGoBuildCommentWithPrefix— generalised version ofisGoBuildCommentthat accepts a configurable prefixparseFileHeaderWithPrefix— likeparseFileHeaderbut for single-line comment syntaxes (no/* */block-comment tracking needed)shouldBuildWithPrefix—shouldBuildextended with an optionalcommentPrefix; the originalshouldBuilddelegates to it withnil, so all existing call sites are unaffectedmatchFile— passes the appropriate prefix for non-Go files; Go files are completely unchangedsrc/cmd/go/internal/modindex/build.goSame 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.goTestShouldBuildWithPrefix— unit tests covering% go:build(MATLAB) and# go:build(shell/Python/R) with ignore, platform tags, boolean expressions, and lookalike-but-not-constraint linesTestMatlabFileBuildTags—ImportDirintegration test that verifiesignored.mis excluded,included.mis always present, andlinux_only.mis included on LinuxThis Is a Design Gap, Not a Feature Request
//go:build ignoreexists 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 ignoreas 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.