Sublime Text 3 Build Tool
In this tutorial we go through the process of setting up a custom Sublime Text build tool that calls our build.bat file in our project directory, captures error output, and uses a custom syntax to color the output from the MSVC compiler.
Step 0: Setup
STEP 1: Project Files
Step 2: Creating The build Tool
Step 3: Build Tool Options
Step 4: Capturing Errors
Step 5: Output Syntax
Step 0: Setup
The only thing you really need for this tutorial is Sublime Text 3. We will be editing and testing everything from within Sublime Text. You can download Sublime Text 3 from here. The evaluation version is free to use for as long as you want. If you like it, I recommend buying the licensed version to get rid of the pop up and to support the creators.
This tutorial is geared towards windows and building with a batch file, however much of the content can be useful when working in other environments as well. Sublime Text is fully cross platform and most of the customization process is platform independent.
We will be making a build system that uses the Microsoft Visual Studios Command Line Visual C Compiler, so if you want to follow along exactly you will need to download Visual Studios.
We will be briefly dealing with a windows batch file, a YAML file, and C/C++ code. Though you do not need to know any of those languages to follow along. It can be useful to know the basic JSON format since it's the format of most configuration files in Sublime Text. You can find information about JSON here.
Step 1: Project Files
In this tutorial we will be building a C++ program using a custom batch file called build.bat. You can create your own program and batch file or download some example ones from here:
NOTE: The build.bat file is configured to look for vcvarsall.bat in C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat. You may need to change this depending on which version of Visual Studios you have installed.
We will also be making use of Sublime Text's project features when we set up the build tool so that it can be used between different projects without changing the configuration.
To make a project you simply need to save it by going to Project->Save Project As... Save your project file next to the build.bat file so that we'll be able to find it when we run the build tool.
NOTE: You can also optionally add folders to your project so they show up in the sidebar by going to Project->Add Folder to Project... though this isn't required for this tutorial. I will be adding the Sublime Build Tutorial folder to my project so I can access the files in it easily.
Step 2: Creating The build Tool
To get things started we're going to need to create our own build tool. One way you can do this is by creating a .sublime-build file in Sublime Text's User Packages directory (on windows it can be found at C:/Users/$USERNAME/AppData/Roaming/Sublime Text 3/Packages/User/). If the folder doesn't exist you can create it. If you don't see the AppData folder make sure you have hidden files being shown in windows file explorer. You can name the file whatever you like, just make sure it ends with .sublime-build.
You can also create the file from Sublime Text by going to Tools->Build System->New Build System... Sublime will open a new file for you that you can name whatever you like when you go to save it. If you do this option Sublime will add some lines to the file automatically. We'll be replacing them in a second.
The sublime-build file format, like most other file formats you'll be working with to customize Sublime Text, is a JSON file. If you don't know JSON, it's a format used largely for web APIs. It's a very simple format so don't worry too much if you haven't seen it before. You can find more information about JSON here.
If you've placed the sublime-build in the right directory Sublime Text will automatically reload the file whenever you save it. You can see it reload the file by opening the console window (ctrl+tilde on windows by default), or you can find it in the Build System drop down in Tools->Build System->...
Step 3: Build Tool Options
Now that we have the file in place, let's actually fill it so it does something useful. You can get rid of anything already in the file and just add an open and close curly brace to the beginning and end.
Sublime Text has a preset list of options that it will accept in the build file which can be found here. In this tutorial we will only be using the "cmd", "file_regex", "working_dir", "shell", and "syntax" options. Go ahead and add these options to the file so yours matches the picture below:
The "cmd" option will allow us to define what should be run in the windows command prompt. Since we simply want to run a batch file we can set this to "build.bat". If you have some other program or command you'd like to run you can type it in here.
NOTE: JSON will require you to escape quotation marks using a single \ and any backslashes will need to be escaped as well: \\
Now we need to specify which folder we want the shell to start in so it can find the build.bat file. This can be a hard coded path if you want the build tool to only ever run one batch file but we can also use a feature of sublime text to get the directory of the sublime-project file we saved earlier. We can do that by putting $project_path in the quotes after working_dir. You can also use one of the other variables Sublime Text provides to find a different directory. The other options can be found under Variables on the Build Systems reference page.
We should also take a moment and set shell to true telling sublime that we want the cmd to be run in a command line shell.
Now that we have those options in place we should be able to run our build system for the first time. Make sure you have the build system selected under Tools->Build System->... and then either hit ctrl+b or select Tools->Build.
The output of the build should show up in a panel near the bottom of the screen. Assuming Sublime Text was able to find the build.bat file you should see something like the following:
If you're running the example build.bat it should have also created main.exe and main.obj in the same folder as itself. You can run it to get a simple Hello World console program.
Congratulations, you have a working build system! Now let's add some fun stuff to it.
Step 4: Capturing Errors
Now we can run our build process from within Sublime Text but all it does is show us the output of the build.bat (which is mainly the output of the MSVC compiler). Currently though if our program has errors during compile we can see them on the output panel but sublime text doesn't know how to interpret or even find the error lines.
The next thing we want to do is tell sublime text about what errors look like so it can integrate some of the error information into the UI. To do this we have to use regular expressions, which are pretty complicated and outside of the scope of this tutorial for me to explain how they work. You can find some great resources here, and here.
Back in our .sublime-build file we're going to fill our "file_regex" value with a regular expression that will match any error lines that get output by MSVC. Generally the errors from this version of the MSVC compiler look like this:
Or warnings, like we saw in the output above, might look something like this:
Depending on where the build.bat is compiling from and which files it's compiling it may decide to output a full file path, or a relative one. We'll have to deal with this in a second but for now let's go ahead and get our regular expression. For this tutorial I will provide you with the regular expression I've made for capturing MSVC error outputs but if you are compiling something with different error outputs the you'll have to find or make your own. Go ahead and copy and paste this into the quotes after file regex:
^((?:\\w\\:)?[^\\:\\n]+)\\((\\d+)\\)\\: (?:error|warning) \\w\\d+: ()([^\\n]+)$
NOTE: Since the regular expression is going into a JSON string all the backslashes need to be doubled. The actual regular expression that gets evaluated looks something more like this:
Your file should look something like this now:
If you're making your own regular expression you'll want to note that Sublime Text is going to be looking for captured parts of the line to determine the file name, line number, column number, and error string. The file name and line number are required for sublime to start reacting to the regular expression match. In order to capture these parts of the string we need to put parentheses around each part in the order that I listed them above. If you have parentheses for other parts of your regular expression that you don't want captured as one of these pieces of information you can put a ?: after the opening parenthesis like we've done for (?:error|warning).
Alright so with your regular expressions set up we can try building again! If you go ahead and build now you may or may not get any errors/warnings. Since we are working with errors we probably want to make sure we have some. Go ahead and open up main.cpp and type in some garbage text somewhere, like I've done below:
Now if we compile we should get some errors:
If you still have main.cpp open, you should now see some error windows show up:
NOTE: These error windows are called phantoms in Sublime Text and were added in Sublime Text 3, version 3124. So if you have an earlier version don't be surprised if these don't show up.
You can also double-click on the error lines in the output panel and it will jump to the file name and line number captured in the regular expression. Another option is to use the F4 or Shift+F4 shortcuts to move forward and back through the errors.
If double-clicking on the line in the output panel doesn't work, it probably means your regular expression didn't match the error output line. Or the file name and line number captured by the regular expression were invalid or referencing a file that Sublime Text could not find.
One problem might be if your relative file paths are not relative to the same directory defined by "working_dir" in the build system then sublime text will not find the file correctly. The only way to solve this currently is to change your build system so your working directory is where the relative file paths are relative to. Another option is to make your own execution command that will allow you to set the result_base_dir and working_dir separately. I suggest taking a look at the ExecCommand in $SublimeInstallPath/Packages/Default.sublime-package/exec.py. (sublime-package files are just renamed zip files). You can copy the code for the ExecCommand from there, rename it, modify it, and save it in the User Packages Folder where we saved our sublime-build file. Then to get your build system to run this new command you can specify a "target" option in the sublime-build file with the name of your new command. This is basically the same as making a custom plugin, so check out that tutorial if you're interested in learning more about how plugins work.
STEP 5: Output Syntax
One thing you might have noticed is that the text in the output panel is all a single color. This can make it hard to see which lines are error lines and which are just informational.
Luckily you can specify what sort of syntax the build system should use in it's output panel by defining a "syntax" option in your sublime-build file. Now most likely you don't have a syntax type that will color the output of an MSVC compilation like we want so we're going to have to use a custom syntax. If you want to learn how to make your own custom syntax you can check out that tutorial here. For this tutorial I've made a simple syntax that will work with the default Monokai color scheme that you can download from here:
NOTE: Make sure you save the sublime-syntax file in the same place you saved your sublime-build file (C:/Users/$USERNAME/AppData/Roaming/Sublime Text 3/Packages/User/ on windows).
Alright, with our custom syntax in hand we can go ahead and specify which syntax to use in our output panel. Go ahead and set "syntax" to "MSVC Build.sublime-syntax" to point it to the syntax file you just placed in your User Packages Folder. Your completed sublime-build file should now look like this:
With the custom syntax now defined we can try building again. If you're compiling with the garbage text similar to what I have above you should get something similar to this in your output window:
Conclusion
So that's all there is to it. There's a lot of other options and things you can do with Sublime's Build System but these are some of the main things I've found to be useful for my purposes. Hopefully this example was useful for you. If you liked the tutorial, or you have any questions, please let me know in the comments below! I will be making more Sublime Text tutorials here soon.
You can download all the files that were used in this tutorial (including the finished sublime-build file) by clicking the download link below: