Build Systems Version:
Sublime Text providesbuild systems to allow users to run external programs.Examples of common uses for build systems include: compiling, transpiling,linting, and executing tests.
Build systems are specified via JSON and saved in a file with theextension.sublime-build. A new build system can be created bytheTools Build System
New Build System… menu item or the
Build:NewBuildSystem command palette entry.
Build systems have various ways they can associate themselves with files andprojects. Using this information, Sublime Text can intelligently display onlyviable build systems to the user. The built-inexec targetprovides common options to get up and running quickly. For more complexrequirements, build systems can target custom Sublime Text commands written inPython.
Basic Example🔗
The following is a basic example of a build system. This build system willexecute the currently-open Python file.
{"cmd":["python","$file"],"selector":"source.python","file_regex":"^\\s*File \"(...*?)\", line ([0-9]*)"}
TheUsage andOptions sections will discuss how to use and customize abuild system.
Usage🔗
Build systems include the following functionality:
Automatic selection of a build system based on file type
Remembering the last used build system
Navigation of build system results
Ability to cancel a build
Running a Build🔗
A build can be run by one of the following methods:
Keyboard | Menu | ||
|---|---|---|---|
Windows/Linux | Mac | All | Tools |
Ctrl+B | ⌘+B | F7 | |
Output will be shown in an output panel displayed at the bottom of the SublimeText window.
Selecting a Build System🔗
By default, Sublime Text uses automatic selection of build systems. When a userinvokes a build, the current file’s syntax and filename will be used to pickthe appropriate build system.
If more than one build system matches the current file type, the user will beprompted to pick the build system they wish to use. Once a build system hasbeen selected, Sublime Text will remember it until the user changes theirselection.
To manually choose a build system, use:Tools Build System
To change the build system, within the viable options, use one of the followingmethods:
Keyboard | Menu | Command Palette | |
|---|---|---|---|
Windows/Linux | Mac | Tools |
|
Ctrl+Shift+B | ⇧+⌘+B | ||
Navigating Results🔗
Build systems allow navigation of files specified in the build output. Typicallythis is used to jump to the location of errors. Navigation can be performedvia:
Command | Keyboard | Menu |
|---|---|---|
Next Result | F4 | Tools |
Previous Result | Shift+F4 | Tools |
Cancelling a Build🔗
An in-process build can be cancelled via:
Keyboard | Menu | Command Palette | |
|---|---|---|---|
Windows/Linux | Mac | Tools |
|
Ctrl+Break | Ctrl+C | ||
Options🔗
All build systems may use the following top-level keys inthe.sublime-build file:
- "selector"string🔗
Aselector to match the syntax that this build system shouldbe enabled for.
Example:
"source.python"
- "file_patterns"arrayofstrings🔗
Patterns of file names the build system should be enabledfor.
Example:
["*.py"]
- "keyfiles"arrayofstrings🔗
File names, if present in one of the opened folders, that will cause thebuild system to be enabled.
Example:
["Makefile"]
- "variants"arrayofobjects🔗
Subsidiary build systems that will inherit the options from the top-levelbuild system. Each variant needs to specify a
"name"key, and mayoverride or add options to the top-level build system.Example:
[{"name":"Debug Symbols","cmd":["my_command","-D","$file"]}]
- "cancel"string,arrayofstrings🔗
A string command name, or an array of string options.
If a string is specified, the command specified will be used to cancel thebuild.
If an array of strings, the primary
"target"will be called, with theseoptions added on. This only needs to be specified when using a custom"target".Examples:
"cancel_my_build"or{"kill":true}
- "target"string🔗
The command to run when the build system is invoked. The default value of
execallows use of the additional options specified inexec TargetOptions.If a value other than
"exec"is specified, none of the options inexecTarget Options will do anything.See theAdvanced Example for a complete example.
Example:
"my_build"
- "windows"object🔗
Options to use when the build system is being executed on a Windowsmachine.
Example:
{"cmd":["my_command.exe","/D","$file"]}
- "osx"object🔗
Options to use when the build system is being executed on a Mac machine.
Example:
{"cmd":["/Applications/MyProgram.app/Contents/MacOS/my_command","-d","$file"]}
- "linux"object🔗
Options to use when the build system is being executed on a Linux machine.
Example:
{"cmd":["/usr/local/bin/my_command","-d","$file"]}
exec Target Options🔗
The defaulttarget ofexec is used by the majority of build systems. Itprovides the following options to control what program to execute, and how todisplay the results.
- "cmd"arrayofstrings🔗
The executable to run, plus any arguments to pass to it. Shell constructssuch as piping and redirection are not supported – see
"shell_cmd".May usevariables.
Example:
["my_command","-d","$file"]
- "shell_cmd"string🔗
A shell command to execute. Unlike the
"cmd"option, this does allowpiping and redirection. Will usebashon Mac and Linux machine, andcmd.exeon Windows.This takes precedence over
"cmd". If you want to override the"shell_cmd"in a build variant with a"cmd"then also set the"shell_cmd"tonull.May usevariables.
Example:
"my_command\"$file\"|other_command"
- "working_dir"string🔗
The directory to execute the
"cmd"or"shell_cmd"within.May usevariables.
Example:
"$file_path"
- "file_regex"string🔗
A regular expression to run on the build output to match file information.The matched file information is used to enable result navigation. The regexshould capture 2, 3 or 4 groups.
The capture groups should be:
filename
line number
column number
message
Example:
"^\s*(\\S[^:]*)\\((\\d+):(\\d+)\\):([^\\n]+)"
- "line_regex"string🔗
A regular expression to run on the build output to match line information.The matched file information is used to enable result navigation. The regexshould capture 1, 2 or 3 groups.
The groups should capture:
line number
column number
error message
This regular expression is only necessary when some results contain strictlya line number, line and column numbers, or line and column numbers with amessage. When such a match is made, the
"file_regex"option will be usedto search backwards to find the appropriate file name.Example:
"^\s*line(\\d+)col(\\d+):([^\\n]+)"
- "encoding"string🔗
The encoding of the build system output. UsesPython codec names. Defaults to
"utf-8".Example:
"iso-8859-1"
- "env"object🔗
Environment variable values to use when running the
"cmd"or"shell_cmd".Example:
{"PYTHONIOENCODING":"utf-8"}
- "quiet"boolean🔗
Reduces the amount of output about the build system invocation.
Example:
true
- "word_wrap"boolean🔗
Turns on word wrapping in the build system output panel.
Example:
true
- "syntax"string🔗
The syntax file to use to highlight the build system output panel.
Example:
"Packages/JavaScript/JSON.sublime-syntax"
- "path"string🔗
Shortcut for providing the
PATHenvironment variable.
- "interactive"boolean🔗 4197
Provides an input box for interacting with the running process.
Example:
true
Custom Options🔗
When implementing a command to act as a build system target, the command’skeyword arguments are available via options in the.sublime-build file.However, certain parameter names will not work since they conflict withbuilt-in build system functionality.
The following names will not be passed as arguments to commands. This alsoapplies to other situations, such as options specified in the"cancel","linux","osx" and"windows" options.
"cancel""file_patterns""keyfile""keyfiles""linux""osx""save_untitled_files""selector""target""variants""windows"
Variables🔗
The following variables will be expanded within any string specified in the"cmd","shell_cmd" or"working_dir" options.
If a literal$ needs to be specified in one of these options, it must beescaped with a\. Since JSON uses backslashes for escaping also,$ willneed to be written as\\$.
Please note that this substitution will occur for any <spanclass=”key”>”target”</span>. If a custom target is used, it may implementvariable expansion for additional options by usingsublime.expand_variables() with the result fromself.window.extract_variables(). </p>
Variable | Description |
|---|---|
| The path to thePackages/ folder. |
| The platform Sublime Text is running on: |
| The full path, including folder, to the file in the active view. |
| The path to the folder that contains the file in the active view. |
| The file name (sans folder path) of the file in the active view. |
| The file name, exluding the extension, of the file in the active view. |
| The extension of the file name of the file in the active view. |
| The full path to the first folder listed in the side bar. |
| The full path to the current project file. |
| The path to the folder containing the current project file. |
| The file name (sans folder path) of the current project file. |
| The file name, excluding the extension, of the current project file. |
| The extension of the current project file. |
Advanced Example🔗
The following example shows a customtarget command, with the ability tocancel a build and navigate results.
Atarget for a build system should be asublime_plugin.WindowCommand. Thiswill provide the instance variable ofself.window to allow interaction withthe current project, window and active view.
Please note that the following example is somewhat simplistic in itsimplementation, and it won’t handle many common edge cases.
The following Python can be saved to a filenamedPackage/User/my_example_build.py:
importsublimeimportsublime_pluginimportsubprocessimportthreadingimportosclassMyExampleBuildCommand(sublime_plugin.WindowCommand):encoding='utf-8'killed=Falseproc=Nonepanel=Nonepanel_lock=threading.Lock()defis_enabled(self,lint=False,integration=False,kill=False):# The Cancel build option should only be available# when the process is still runningifkill:returnself.procisnotNoneandself.proc.poll()isNonereturnTruedefrun(self,lint=False,integration=False,kill=False):ifkill:ifself.proc:self.killed=Trueself.proc.terminate()returnvars=self.window.extract_variables()working_dir=vars['file_path']# A lock is used to ensure only one thread is# touching the output panel at a timewithself.panel_lock:# Creating the panel implicitly clears any previous contentsself.panel=self.window.create_output_panel('exec')# Enable result navigation. The result_file_regex does# the primary matching, but result_line_regex is used# when build output includes some entries that only# contain line/column info beneath a previous line# listing the file info. The result_base_dir sets the# path to resolve relative file names against.settings=self.panel.settings()settings.set('result_file_regex',r'^File "([^"]+)" line (\d+) col (\d+)')settings.set('result_line_regex',r'^\s+line (\d+) col (\d+)')settings.set('result_base_dir',working_dir)self.window.run_command('show_panel',{'panel':'output.exec'})ifself.procisnotNone:self.proc.terminate()self.proc=Noneargs=['my_cli']iflint:args.append('-l')elifintegration:args.append('-i')args.append(vars['file_name'])self.proc=subprocess.Popen(args,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,cwd=working_dir)self.killed=Falsethreading.Thread(target=self.read_handle,args=(self.proc.stdout,)).start()defread_handle(self,handle):chunk_size=2**13out=b''whileTrue:try:data=os.read(handle.fileno(),chunk_size)# If exactly the requested number of bytes was# read, there may be more data, and the current# data may contain part of a multibyte charout+=dataiflen(data)==chunk_size:continueifdata==b''andout==b'':raiseIOError('EOF')# We pass out to a function to ensure the# timeout gets the value of out right now,# rather than a future (mutated) versionself.queue_write(out.decode(self.encoding))ifdata==b'':raiseIOError('EOF')out=b''except(UnicodeDecodeError)ase:msg='Error decoding output using%s -%s'self.queue_write(msg%(self.encoding,str(e)))breakexcept(IOError):ifself.killed:msg='Cancelled'else:msg='Finished'self.queue_write('\n[%s]'%msg)breakdefqueue_write(self,text):sublime.set_timeout(lambda:self.do_write(text),1)defdo_write(self,text):withself.panel_lock:self.panel.run_command('append',{'characters':text})
The customMyExampleBuildCommand can be configured as a build system usingthe following JSON saved to a file namedPackages/User/My ExampleBuild.sublime-build:
{"target":"my_example_build","selector":"source.mylang","cancel":{"kill":true},"variants":[{"name":"Lint","lint":true},{"name":"Integration Tests","integration":true}]}