skip to Main Content

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


  1. You probably want to learn about make. In the simplest case you can do something like this which is entirely generic in a single file Makefile:

    sources :=      $(wildcard *.cpp)
    objects :=      $(sources:.cpp=.o)
    
    myapp:          $(objects)
                    $(CXX) -o $@ $^
    

    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. Because make 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 now make 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:

    $ make -n
    g++    -c -o main.o main.cpp
    g++    -c -o misClass1.o miscClass1.cpp
    g++ -o myapp main.o miscClass1.o
    $ 
    

    If you remove the -n, it will it. You can, but do not have to, define options via CXXFLAGS and so on. Ditto for the actual compiler choice, C++ language style etc.

    So adding, say,

     CXXFLAGS = -Wall -pedantic -O2
    

    lets you build an optimised binary:

     $ make
     g++ -Wall -pedantic -O2   -c -o main.o main.cpp
     g++ -Wall -pedantic -O2   -c -o miscClass1.o miscClass1.cpp
     g++ -o myapp main.o miscClass1.o
     $ 
    

    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.

    Login or Signup to reply.
  2. 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)

    cmake_minimum_required(VERSION 3.0) # optional line, but prevents a warning
    
    project(MyProject)
    
    add_executable(myapp
        main.cpp
        misClass1.cpp
        misClass1.h # technically we don't need to list headers, but e.g. VS adds them to the target this way
    )
    

    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 is src:

    You once set up the project specifying any configuration options like e.g. choosing the build configuration.

    cmake -D CMAKE_BUILD_TYPE=Release -S src -B build
    

    and then every time you want to build the project, you can simply use

    cmake --build build
    

    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).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search