A good rule of thumb (according to OdatNurd, at any rate) for using a Sublime build system to compile a C/C++ program is this:
If the sequence of commands required to compile and link your program is so lengthy or complicated that you can’t just rattle them off the top of your head, out of your fingers and into a terminal and have the Right Thing happen, it’s probably best not to.
Basically, anything outside of compiling and linking a single source file is a recipe for maintenance nightmares, and as software developers we tend to be way lazy and want the computer to do as much for us as it can (I know I do, anyway).
The only way to have multiple commands execute from a Sublime build is to use shell_cmd
and chain them together using &&
, as you would do from the terminal if you wanted to execute the whole thing as a single command.
For your case, that would look something like this:
{
"shell_cmd": "g++ -Wall -fexceptions -g -fpermissive -I/usr/include/mysql -I/usr/include/mysql++ -I/usr/include/mysql -I/usr/include/mysql++ -c Customers.cpp -o Customers.o && g++ -Wall -fexceptions -g -fpermissive -I/usr/include/mysql -I/usr/include/mysql++ -I/usr/include/mysql -I/usr/include/mysql++ -c shared.cpp -o shared.o && g++ -o Customers Customers.o shared.o -lncurses -lform -lmenu -lmysqlpp -lmysqlclient",
"working_dir": "${folder:${project_path:${file_path}}}",
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$"
}
That will do what you want, but it’s a nightmare to modify in any way because it’s 423 columns wide (really wide monitors and tiny font sizes may help there, though). It’s also sloppy because it requires the compiler to compile both files every time, even if only one of them has changed.
I would strongly urge a more appropriate tool for the job, such as make
. There is a simple Makefile Tutorial available, but in short something like this will hook you up:
# Compiler options and linker flags
CFLAGS=-Wall -fexceptions -g -fpermissive -I/usr/include/mysql -I/usr/include/mysql++ -I/usr/include/mysql -I/usr/include/mysql++
LIBS=-lncurses -lform -lmenu -lmysqlpp -lmysqlclient
Customers: Customers.o shared.o
g++ -o Customers Customers.o shared.o $(LIBS)
Customers.o: Customers.cpp
g++ $(CFLAGS) -c Customers.cpp -o Customers.o
shared.o: shared.cpp
g++ $(CFLAGS) -c shared.cpp -o shared.o
clean:
rm -f Customers Customers.o shared.o
You can save this as Makefile
in your project directory, choose the Make
build system (if it’s not automatically selected) and you’re good to go.
NOTE: It’s important that the lines that are indented be indented with actual tab characters and not spaces, or make
will get all angry at you and say “Missing separator”. If you see that, the line that the error happens on is one that’s not indented correctly. Generally Sublime is smart enough to know that it should use tabs in a Makefile
, though.
make
is pretty powerful, but although a Makefile can potentially be quite complicated ($DEITY help you if you ever need to look inside of one created by cmake
or autoconf
, for example) this one is very simple, easy to extend and very straight forward.
Without going into a ton of detail, a Makefile
basically consists of a series of rules in the form:
ThingToMake: ThingsNeededToMakeThatThing
CommandsToMakeTheThingWithTheStuff
The last modification times of the items on either side of the colon are checked, so make
will only execute the commands if ThingToMake
either does not exist, or it does but one of ThingsNeededToMakeThatThing
is newer.
Also the rules are recursively applied; if one of the ThingsNeededToMakeThatThing
does not exist, but there is a rule that tells make
how to build it, it will go and do that first before proceeding.