Sublime Forum

Build System for C++

#1

Hi, I am new to sublime text. I want to use this editor to work with compiler as well. I found out that the build systems could be edited and can be used with various compilers. Currently am able to build my python programs, what I want is support for c/c++. I am using this build system:

{
"cmd": "g++", "${file}", "-o", "${file_path}/${file_base_name}"],
"file_regex": "^(..^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"working_dir": "${file_path}",
"selector": "source.c, source.c++",
"path":"C:/Program Files (x86)/CodeBlocks/MinGW/bin",

"variants":

{
"name": "Run",
"cmd": "g++ ${file} -o ${file_path}/${file_base_name} && ${file_path}/${file_base_name}<${file_path}/${file_base_name}.txt"],
"shell":true
}
]
} 

This is able to compile and run the program, but the problem occurs if the file path has a space in it. For ex: E:\foo.cpp but it’ll fail for** E:\foo abc\foo.cpp**
Please let me know if something can be edited in above file so as to make this thing work.

0 Likes

Build whole project
#2

This seems to be working fine for me, with the exception of the “Run” variant, which needs to have the “cmd” value changed.

The “cmd” key should take an array of commands, so use:

"g++", "${file}", "-o", "${file_path}/${file_base_name}", "&&", "${file_path}/${file_base_name}", "<", "${file_path}/${file_base_name}.txt"

with each command split into it’s own string.

Once you start getting into bigger projects it might be worth setting up the build system to use something like CMake and Make.

0 Likes

#3

I tried changing to the value you suggested. Am getting this:

:unamused:
And could you elaborate more on this cmake and make or provide a helpful link that may guide me

0 Likes

#4

Part of your command is this:

"${file_path}/${file_base_name}", "<", "${file_path}/${file_base_name}.txt"

So if your cpp file is called foo.cpp, then it will evaluate to this:

"/your/path/foo.cpp < /your/path/foo.txt"

So I assume it can’t find foo.txt if it doesn’t exist.

I will be over-simplifying it, but the reason I mention CMake and Make is because Sublime Text is of course just a Text Editor, not an IDE.
As such, it doesn’t do any of the work for you that an IDE like CodeBlocks or Visual Studio does for you in the background.

For example, the default Sublime C++ build system (and the system you posted above) only builds the file you currently have open.
As you have probably guessed, when building from the command line you need to provide the g++ command with a list of all of the files you want to compile in a project, or compile them separately and manually link the resulting .o files.

This is fine if your project fits in one, or even a few files since it’s easy to write out something like:

g++ foo.cpp bar.cpp -o foobar

But once your project grows and is made up of dozens or even hundreds of files, keeping track of what you need to recompile and link together etc can quickly become unmaintainable.

This is where Make comes in.
Make is a utility which automatically determines which files in a program need to be recompiled and then recompiles them.
You can use Make on Windows by searching Google for “Make for Windows” and downloading it.
Once installed, you can write a Makefile for your project which describes the files to be used to build the final executable file.
When you run make it will look determine the files to be recompiled, recompile them and output the final program for you.

Since make is a command line utility you can easily use it in a Sublime build system.
So, instead of using g++ in your build system, you use make instead.
This will allow you to maintain larger projects easier, but makefiles can also become difficult to maintain after a while and learning how to write them properly can be a bit of a confusing task.

This is where CMake comes in.
CMake is yet another utility which generates build systems (for example, you can set it up to generate the Makefiles for you).
To use CMake you need to download it (just search for it on Google again), and once you have installed it you can use it from the command line or via a GUI they provide if you need it.

The nice thing about CMake is that it can generate more than just Makefiles.
It can generate many more build systems, you just have to specify which one you want.

So, like the make utility, CMake can be run from the command line, so you can set up a Sublime build system to run CMake.
CMake basically looks for files within your project named CMakeLists.txt.
These CMakeLists.txt files contain instructions written by you to tell it which files to include in the building of your project.

So basically, you set up a Sublime Text build system to have:

  • A variant for running CMake on your project (generates the Make build system)
  • A variant for running Make on your project (compiles your code and creates an executable)
  • A variant to run the final compiled program

These three steps can be set up twice with different key bindings to work on debug and release builds.

You can find tutorials online about Make and CMake, and once you know how to use them it’s quite easy to set it all up in Sublime.
But you only really need to learn about CMake since CMake will generate the Makefiles for you.

I don’t have any links that specify how to set all of this up in a Sublime Text build system.
The only things I have found on Google are about how to build one file, just like the Sublime default C++ build system does.

Maybe I will write up how I set my projects up if it would help, but I don’t know when I will get around to it.
If I get to do it in the next few days I’ll post a link here.

Anyway, it can be a bit of work to set up large projects in Sublime properly, but once you get it working the first time any project after that will use the same build system and folder structure etc.
So if you have the patience it’s worth putting in the time to be able to use Sublime for C++ projects.

0 Likes

#5

Thanks for such a detailed response :smiley: I’ll look into these and try to merge my previous projects from within sublime text.

And on the previous problem, you were right, I didn’t have the text file hence it was giving that error. Now with a text file there, it works like a charm , even if there’s a space in path.

Now the final thing that I want is to do something like this (for a file say foo.cpp):
*in the run variant->make a check, if there’s a file called foo.txt then run the command foo.exe < foo.txt in cmd **otherwise *just run foo.exe and not look for foo.txt
Would something like that be possible?

1 Like

#6

As far as I know there is no way to do checks like that in the build system itself.
You could however write a script or program that checks for the existence of files and then runs the build for you.
You could then run that script/program from the build system instead.

0 Likes

#7

Well I couldn’t think of that script thing, what I did (for now) is add another variant into the system build file and added a key shortcut for it (f10)

{ "name": "Noinput", "cmd":"g++", "${file}", "-o", "${file_path}/${file_base_name}", "&&", "${file_path}/${file_base_name}"], "shell":true }

So basically when I press f9, it expects an input file (foo.exe < foo.txt) and if I press f10 it doesn’t (foo.exe)
I think it serves the purpose, but it would had been cool if I could write a script to auto check for presence of foo.txt file and then run using one short cut only :smiley:

Thanks for your help :smile:

0 Likes

#8

Thanks for this reply, and naman for the question.
I just started using Sublime, and am looking at porting Windows VS6/VS2013 C++ code into g++. I’m trying to setup project folders, and the first issue was that the WorkingDirectory is not ./src for the default build to find my makefile.
With the answers here, I should be closer to getting something working.
I’m disappointed that the online Documentation doesn’t have a more comprehensive example of a C++ project in sublime… a mirror of a VS2013/VS6.0 Workspace with multiple projects etc. Something with “source” and “resource” folders etc.
Along with some build images.

I’m reviving this topic as this information was useful for me… It would be GREAT to see a CMake or just a more comprehensive build setup in the documentation.

I searched for .sublime-build files in my entire directory tree, but didn’t find anything…
so this is the first useful breadcrumb I found on my search.

0 Likes

#9

Great point that sublime is not an IDE :(. But it is almost there.

0 Likes

#10

Per Packages\Makefile\Make.sublime-build, the working directory specified for the make command to run in is:

"working_dir": "${folder:${project_path:${file_path}}}",

This equates to "the first folder in the current project, or if there are no folders, the folder that the current project file is stored in, or if there is no project, the folder that the current file is stored in. You probably want to override it to something like ${project_path}/src or something (depending on if you keep your .sublime-project` file in the same directory as everything else or not.

For my own use, Every folder in my build tree has a Makefile in it that recursively builds everything under it, so I’ve overridden the working dir to be ${file_path} so that I always build where I’m editing.

The tricky part of this is that the details of how the build builds is specified by you and then Sublime just invokes the tool. So the bulk of the information for any given build system is outside the scope of Sublime.

That said, CMake is a bit more complicated since you need to invoke cmake to generate your Makefiles for you. I assume for speed purposes you would probably want the build to be smart enough to invoke CMake for you if there is no Makefile yet (and again if the cmake control file is newer than the Makefile?), so I can see where you’re going with your question.

From a Sublime perspective you’re probably either looking at a batch file/shell script that makes that decision for you when you invoke it, and having the build system invoke that, or making a more clever build system for CMake that has customized python logic via a target parameter in the build file. That sounds like an interesting problem to look at, actually.

This is because all of the bundles packages that come with Sublime are stored in sublime-package files, which are just renamed zip files. Also, they’re stored in the installation directory of Sublime and not in your user specific configuration files are kept (see here for more information).

If you don’t already have it, I highly recommend installing PackageResourceViewer. It’s an invaluable tool for looking inside any package to see how everything fits together, as well as for overriding things as you need. One of the best ways to figure out how/why something works the way it does is to look at the package that’s doing it.

Also, if you haven’t already checked it out, there is unofficial documentation for build systems that is also quite helpful.

1 Like