Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>MakefileNew to Visual Studio Code? Get it now.
Makefile

Makefile

weixu

|
525 installs
| (0) | Free
Makefile (GNU Make) editing — syntax highlighting and outline powered by a Rust analyzer compiled to WebAssembly.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Makefile

GNU Make support for VS Code: syntax highlighting, an outline, folding, and diagnostics for the mistakes Make punishes hardest — spaces where a tab belongs, an unclosed define, a dangling ifeq. The parser is a Rust crate compiled to WebAssembly and running in the extension host, so there is no language server and no toolchain to install. Recipe lines also get shell option completion drawn from fish-shell's completion data.

Features

  • Syntax highlighting for targets and prerequisites, # comments, assignment operators (=, :=, ::=, :::=, ?=, +=, !=) with any mix of export / unexport / override / private in front, the conditional keywords (ifeq, ifneq, ifdef, ifndef, else, endif), the directives export, unexport, override, private, undefine, vpath and load, define … endef blocks (including override define, export define, nested defines and define NAME := forms), and include / -include / sinclude lines with their paths.

  • Recipe bodies are highlighted as recipes: the leading @, - and + prefix characters are called out, and inside the line you get variable references ($(CC), ${CC}, and $$ as an escape), automatic variables ($@, $<, $^, $?, $*, $%, $+, $|, plus the $(@D) / $(@F) forms), function calls such as $(shell …), $(wildcard …) and $(patsubst …), single-, double- and backtick-quoted shell strings, # shell comments, and trailing \ line continuations. Variable and automatic variable references are also highlighted in prerequisite lists and inside define bodies.

  • Outline and breadcrumbs built from the parsed file, not a regex sweep. The parser follows GNU Make's own reading rules: trailing # comments, \ continuations, escaped \: and \ in names, archive members such as lib.a(a.o b.o), ; inline recipes, order-only prerequisites after |, static pattern rules, grouped targets (&:), target-specific variables, recipe lines inside or after the ifeq blocks around a rule, and .RECIPEPREFIX are all understood. Rules appear under their first target, with the remaining targets, the prerequisite list and a :: marker for double-colon rules shown as detail; pattern rules (any target containing %) are recognised as such. Variable assignments show their modifiers, operator and a truncated value preview (target-specific ones also show their targets), define blocks show define plus the operator, include lines show their paths, and ifeq / ifdef blocks become a container node whose children are the items in both branches.

  • Folding for rule bodies that have a recipe, define … endef blocks and conditional blocks, on top of the # region / # endregion markers from the language configuration.

  • Diagnostics reported with a MAKE0nn code:

    Code Message
    MAKE001 recipe line uses spaces where a tab is required
    MAKE002 recipe line appears outside of any target rule
    MAKE003 `define` block is not closed — expected endef
    MAKE004 `ifeq` (or ifneq / ifdef / ifndef) is not closed — expected endif
    MAKE005 `endef` without a matching define
    MAKE006 `endif` without a matching if
    MAKE008 empty variable name
    MAKE009 extraneous text after a define, endef, else or endif directive
    MAKE010 `else` without a matching if, or a second else in one conditional
    MAKE011 invalid conditional: ifeq / ifneq arguments not in (a,b), "a" "b" or 'a' 'b' form, ifdef / ifndef with more than one word, or no whitespace after the keyword
    MAKE012 missing separator — a line that is neither a rule, an assignment nor a directive (lines built from $(…) references are not checked, since they may expand to anything)

    They are computed when a file is opened, on save, and — unless you turn makefile.diagnostics.onType off — about 150 ms after you stop typing.

  • Tabs are enforced for you. The extension sets editor.insertSpaces: false, editor.detectIndentation: false and editor.useTabStops: true for the makefile language, so a press of Tab in a recipe inserts a real tab regardless of how the rest of your editor is configured. If a space-indented command still sneaks into a rule's recipe, MAKE001 flags it. Indented assignments ( FOO = 1), directives and conditionals are left alone, but FOO=1 ./run reads as a command.

  • Shell completion inside recipes. Put the cursor in a recipe line and the extension completes the current command's options, its subcommands, and the values after --option=, from a database generated from fish-shell's completion scripts (roughly a thousand commands). It skips the recipe prefix characters, follows ;, |, ||, && and backticks to find the command you are actually in, respects single and double quotes, joins \ continuations, and strips a path so /usr/bin/curl still completes as curl. Nothing is offered on target headers, assignments or comments, and the command name itself is not completed — only its arguments. Results are capped at 250 per keystroke and descriptions are trimmed to their first sentence.

  • Editing niceties from the language configuration: # line-comment toggling, bracket matching and auto-closing for {}, [] and (), auto-closing and surrounding for ", ' and ` outside strings and comments, and # region / # endregion folding markers.

# region build
CC      := gcc
CFLAGS  ?= -O2 -Wall
SRC     := $(wildcard src/*.c)
OBJ     := $(patsubst %.c,%.o,$(SRC))
VERSION != git describe --tags

.PHONY: all clean

all: app

app: $(OBJ)
	$(CC) $(CFLAGS) -o $@ $^

%.o: %.c
	@$(CC) $(CFLAGS) -c $< -o $@

ifeq ($(shell uname -s),Linux)
LDFLAGS += -ldl
endif

define greet
	echo "building $(1)"
endef

clean:
	-rm -f $(OBJ) app
# endregion

-include local.mk

Files it applies to

The makefile language is bound to the filenames Makefile, makefile and GNUmakefile, and to the extensions .mk, .mak and .make. Other spellings (Makefile.local, *.makefile) are not claimed; use the language picker in the status bar, or a files.associations entry, for those.

Settings

Setting Default Description
makefile.diagnostics.enabled true Emit diagnostics for unterminated define blocks, unclosed conditionals, and recipe lines that use spaces instead of tabs
makefile.diagnostics.onType true Recompute diagnostics as you type (debounced). Turn off to only recompute on save
makefile.outline.showPhonyDeclarations false Show .PHONY: … declaration lines in the document outline

License

Distributed under GPL-2.0-or-later. The extension's own code was written for this project, but the shipped WebAssembly bundle embeds completion data derived from fish-shell, which is GPL-2-or-later — see LICENSE.md and THIRD_PARTY_NOTICES.md.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft