Since your real goal seems to be to automate whatever needs to be done to run your program, I suggest a different approach. Instead of writing a shell script, you can use a makefile. If you like, you can write a rule in your makefile for running your executable once it is built. You will then have two files--your C++ source code file and your makefile--and you will be able to run a single command that efficiently:
- Builds or rebuilds your C++ program, if and only if necessary.
- Runs your program.
The subsequent sections of this post explain why you can't call a
.cpp file directly (but must create an executable from it first); how to install
make, how to use it, and what it's doing behind the scenes; and how to avoid common pitfalls. But in case you want to get a feeling of what this approach looks like before delving in, you will run
make run after putting this0 in
I like that better for this purpose than a shell script, and I think you might, too.
Unlike some interpreted languages like Python and Bash, C++ is a compiled language.1 Programs written in C++ must be built before they are run. (Building is also sometimes called compiling, though compiling more properly refers to one of the steps of building.) You cannot run a C++ source code file; it must instead be compiled into object code2, in this case machine language. The object files must then be linked together, and even if there is only one, it must still be linked to any shared libraries it uses. Linking produces an executable which may be run.
In short, you have to build your program before you run it, the first time. Before subsequent runs it need not be rebuilt, unless you have changed its source code, in which case you must build it again if you want your changes to be reflected in the program that runs. The
make utility is designed specifically for this sort of situation, where one wishes to perform actions conditionally depending on whether or not, and when, they have already been done.
You may already have the
make command installed; try running it to find out. If it is installed, you'll see something like:
make: *** No targets specified and no makefile found. Stop.
To get make you can install the make package, but I suggest installing build-essential which provides a number of other handy tools. (You might've installed build-essential to get
g++, which is one way you might already have
make.) You can use the Software Center to install it or run the command:
sudo apt-get update && sudo apt-get install build-essential
make Without a Makefile
To see how
make works, I suggest running it without a makefile first, passing it the basename of your source code file:
$ make myProg
g++ myProg.cpp -o myProg
On subsequent runs,
make compares the modification timestamps (mtimes) on the input and output files, and won't rebuild your program unnecessarily:
$ make myProg
make: 'myProg' is up to date.
When you change
myProg.cpp, that updates its modification timestamp, so
make will know to rebuild it. (You can also update a file's timestamp with the
touch command, if you need or want to force any output files depending on it to be rebuilt. And of course, deleting the output files will also ensure they be rebuilt when you run
make--just don't delete the wrong file!)
$ touch myProg.cpp
$ make myProg
g++ myProg.cpp -o myProg
make know what to do when you run
myProg argument to
make is called a target.
- Targets are often, but not always, the names of files to be created. Targets may be defined explicitly in a makefile.
- When a target is not defined in the makefile or (as in this case) there is no makefile,
make looks for input (i.e., source code) files named in such a way as to suggest they are intended for building the target.
make infers what utility and syntax to use in building a file from its suffix (in this case,
All this can be customized, but in simple cases like this often doesn't need to be.
Creating a Makefile to Automate Building and Running Your Program
To automate more complex tasks than building a program from a single source code file, such as if there are multiple input files or (more applicably to your immediate needs) actions you wish done besides running the compiler, you can create a makefile to define targets for
make and specify how they depend on other targets.
The first target defined in a makefile is the default target: it is what
make attempts to build when run with no command-line arguments (i.e., when you run just
make, and not something like
The usual way to use makefiles is to create a directory containing all source code files (and any other files) used to build your program, as well as the makefile, which is usually called
Makefile. By that name,
make will automatically find it.
To create a makefile you can use to run
myProg and that will automatically build it first when necessary, put
myProg.cpp in new, otherwise empty directory. Create another text file in that directory called
You can use any text editor for this, but the recipe for a rule--the commands listed under it that will be run to make its target--must must be indented with tabs rather than spaces.3 So if your text editor is currently configured to indent with spaces when you press Tab, you should change this.
For example, in Gedit or Pluma, you would go into Edit > Preferences, click the Editor tab, and ensure Insert spaces instead of tabs is unchecked:
Many editors default to indenting with tabs and not spaces, so if you haven't changed this setting before, it may already be set correctly for makefiles.
Once you're in your editor and (if necessary) configured it to indent with tabs, put this in:
If you copy and paste this, it will be wrong because spaces will be coped in even though your text editor doesn't make them when you press Tab. (This has to do with the way Ask Ubuntu displays code.) But you can simply remove the four spaces preceding
./myProg and press Tab to make a tab in their place.
Some text editors default to showing a tab as 8 spaces, or some other number. That's fine.
What That Makefile Does, and How to Use It
Use the command:
make, to build the program unless it is already built and the executable is current to the source code. Or,
make run, to run the program, building it first if necessary (i.e., if there is no current executable).
This makefile defines two targets:
all target has no recipe of its own, but depends on the
myProg target. This target is not explicitly defined, so it implicitly tells
make to attempt building
myProg from whatever source code files are available for it in the current directory. (See the
make Without a Makefile section above for details.)
all is the first target explicitly defined in
Makefile, it will be built when
make is run from the directory in which
Makefile resides. Thus we have set things up so running
make by itself is equivalent to running
run target runs the program. Its recipe consists of the command that does so,
run declares the
all target as a dependency. This makes it so that when you run
myProg gets rebuilt if the current
myProg executable is not current (or does not yet exist).
We could just as well have made
run depend on
myProg rather than on
all, but we would still have needed the explicit
all target (or an equivalent target of a different name) to prevent
run from being the default target. Of course, if you want your program built and run even when you run
make by itself, you could do this.
Another benefit of depending on the
all target is in case later there are more actions that must be taken before your program ought to be run. You could then add a recipe to the rule for
Using the makefile to run the program looks like this, if it needs to be built:
$ cd myProg/
$ make run
g++ myProg.cpp -o myProg
Or this, if it doesn't need to be built:
$ make run
And if you just want to make sure the program is built (since the source code file was last modified) without running the program, simply run
make with no arguments:
$ make # Here, I run make and myProg isn't current.
g++ myProg.cpp -o myProg
$ make # Running "make" again after "make" or "make run" does nothing.
make: Nothing to be done for 'all'.
make myProg will still work, too.)
A Refinement: Custom Compiler Flags
make is an extremely powerful tool, handy for simple purposes like this but also well suited to large, complex projects. Attempting to detail all the things you can do with
make would be a whole book (specifically, this one).
But it occurred to me you might want to see warnings from the compiler, when something doesn't prevent the build from completing but still is a potential error. These won't catch all the bugs in the programs you write, but they may catch many.
When using GCC (as with the
g++ command), I recommend passing at least
-Wall to the compiler. This actually doesn't enable all warnings, but you can enable most of the rest with
-Wextra. You may sometimes also want
man gcc and 3.8 Options to Request or Suppress Warnings in the GCC reference manual.)
g++ manually with these flags, you'd run:
g++ -Wall -Wextra -pedantic -o myProg myProg.cpp
make invoke the C++ compiler (
g++) with the
-pedantic flags, add a
CXXFLAGS= line with them to the top of
CXXFLAGS=-Wall -Wextra -pedantic
myProg still exists and is newer than
make run after editing
Makefile will still build the program again, because
Makefile is now newer than
myProg. This is a good thing, because:
- In this case, rebuilding the executable causes you to see warnings if there are any (there shouldn't be, for that particular program).
- More generally, sometimes when you edit a makefile it's because you want different files to be produced, or to be produced with different contents. (For example, if you had added the
-O3 flag for heavy optimizations or
-g to make the compiler generate debug symbols, the resulting
myProg executable would be different.)
0: I recommend reading further to see how to make this work. But in case you want to attempt it first yourself: you must indent lines with tabs rather than spaces.
1: Strictly speaking, virtually any programming language could be either interpreted or compiled depending on what implementations for it have been written. For some languages, both interpreters and compilers exist. However, interpreted C++ is uncommon--though not unheard of.
2: Dividing building into compiling and linking, and calling the translation of a C++ source code file (.cc/.cpp/.cxx/.C) into object code compiling, is not the whole story. Programs in C and C++ (and some other languages) are first preprocessed. In your program, the C preprocessor replaces
#include<iostream> with the contents of the
<iostream> header file before actual compilation starts. And in the narrowest sense compiling converts source code into assembly language rather than object code. Many compilers (like GCC/
g++) can combine compilation and assembly in a single step, and don't produce assembly code unless asked to do so.
While preprocessing is a separate step, GCC and other compilers automatically run the preprocessor. Similarly, they can automatically run the linker, which is why the entire sequence of preprocessing, compilation, assembly, and linkage is sometimes called "compiling" rather than "building." (Note also that building may contain more than those steps--for example, it may involve generating resource files, running a script to configure how things will be built, etc.)
3: You only have to indent with tabs in the makefile itself. Using a makefile doesn't impose any requirements on the way you write your C++ source code files themselves. Feel free to switch indentation back from tabs to spaces when you're working on other files. (And if you really don't like indenting with tabs in a makefile, you can set the
.RECIPEPREFIX special variable.)