I’m writing a simple practice program in c++ on my desktop with the Ubuntu OS. This is my main.cpp, with the main() method:
#include "miscClass1.h"
#include <iostream>
using namespace std;
int main(){
miscClass1 A(3, 5);
cout << A.getX() << endl;
}
this is the header file for my misc class where I just define a few simple fields and functions(misClass1.h)
#ifndef MISCCLASS1_H
#define MISCCLASS1_H
class miscClass1 {
int X;
int Y;
public:
miscClass1(int x, int y);
int addXY();//adds the two variables x and y
int getX();
int getY();//accessors
void setX(int x);
void setY(int y);//mutators
};
#endif
and this is the source file for the header file of the class(misClass1.cpp):
#include "miscClass1.h"
miscClass1::miscClass1(int x, int y)
{
X = x;
Y = y;
}
int miscClass1::addXY()
{
return (X + Y);
}
int miscClass1::getX()
{
return (X);
}
int miscClass1::getY()
{
return (Y);
}
void miscClass1::setX(int x)
{
X = x;
}
void miscClass1::setY(int y)
{
Y = y;
}
This works, but I had to use the command:
$g++ main.cpp misClass1.cpp
While compiling, so if I ever had to compile a serious program with several classes/libraries, each stored in their own .cpp file, I would need to include each and every one of them if even if there were hundreds or thousands, which would be unattainable. How do I more efficiently compile my program, without calling every single file while compiling? I’d also like to know if anything else I’m doing in the program is bad practice.
2
Answers
You probably want to learn about
make
. In the simplest case you can do something like this which is entirely generic in a single fileMakefile
:It does two things. It defines ‘sources’ by relying on a directory listing. So if you add another, say,
myclass2.cpp
it will added automagically to the list. Next, it defines ‘objects’ as a transformation from the files in sources but replacing the.cpp
ending with.o
. Becausemake
knows about compilation, this enough (!!).Finally we say that we want a build target
myapp
(you can give it any name) that depends on the ‘objects’. The declares the actual dependency so nowmake
know it needs to create objects and looks at the preceding two declaration to figure out how. It then uses the compiler to create the target on the left (defined via$@
) from the dependencies on the right (via$^
)You can simulate the build in a ‘dry-run’ by adding
-n
:If you remove the
-n
, it will it. You can, but do not have to, define options viaCXXFLAGS
and so on. Ditto for the actual compiler choice, C++ language style etc.So adding, say,
lets you build an optimised binary:
The other key benefit is that you can now just alter any of the C++ files and just say
make
and it will take care of things. There is lots more (and there are a ton of answered questions here) but this should get you going.With CMake you can create a project that not only allows you to build the program using Make in the background, but also allowing you to use the same files for a Visual Studio project on Windows. It also has features to aid installing the program or creating deployable packages.
CMakeLists.txt (place in same directory as source files)
To build the program now you decide on a directory where the build files are created (We’ll use
build
). Assuming the directory containing the sources issrc
:You once set up the project specifying any configuration options like e.g. choosing the build configuration.
and then every time you want to build the project, you can simply use
Any modification of the
CMakeLists.txt
file will automatically be picked up when performing the latter step.Imho it’s preferrable to pure makefiles, especially if you don’t want to bother writing the actual compiler commands yourself.
Also nowadays many existing projects can be built using cmake and many libraries provide logic for easily using them in your own project (Boost, GoogleTest, Qt to name a few).