Manage Project C++ dengan Make


Bagus Koko Wibawanto

14 Desember 2023

Ketika kita membuat sebuah project di C++ dengan menggunakan paradigma OOP (Oject Oriented Programming) biasanya kita tidak akan menulis semua code di dalam 1 file saja, melainkan kita akan memecahnya agar ketika proses development tidak ribet. Tetapi proses development dengan menggunakan file terpisah itu juga akan menambah sedikit kerumitan saat proses compile.


Kenapa bisa membuat ribet?


Mungkin sebelum memberikan alasan kenapa bisa membuat ribet, kita bahas dulu proses sederhana bagaimana dari code C++ menjadi sebuah executable file.

Dimulai dengan sebuah file code, dimana di dalam source code tersebut pasti kita akan menuliskan #include <...>. Ini artinya kita menambahkan header file dan semua di C++ yang di awali dengan tanda "#" itu akan melewati proses preprocessing directive, Sederhananya kita akan meng-copy semua isi dari header file yang kita include.


Setelah proses preprocessing, selanjutnya compiler akan melakukan proses compiling dan menghasilkan file object. Kemudian proses terakhir adalah Linking yaitu menggabungkan file object.


Nah ketika kita menggunakan OOP kita akan sedikit ribet di bagian proses Linking, karena harus menggabungkan semua file object. File file object ini terpisah karena dalam paradigma OOP orang orang seringnya akan menuliskan code terpisah, tujuannya agar lebih terstruktur.


Saya akan memberikan contoh project kalkulator dimana menggunakan paradigma OOP. Berikut struktur projectnya.


File include/calculator.hpp


#ifndef __CALCULATOR
#define __CALCULATOR

class Calculator {
        private:
                int FirstNumber;
                int SecondNumber;
                char* Operation;
        public:
                Calculator(int, char*, int);
                int penjumlahan();
                int pengurangan();
                int perkalian();
                int pembagian();
                void result();


};

#endif
					

File src/calculator.cpp


#include <iostream>
#include <cstring>
#include "../include/calculator.hpp"

Calculator::Calculator(int firstNumber, char* operation, int secondNumber) {
        this->FirstNumber = firstNumber;
        this->Operation = operation;
        this->SecondNumber = secondNumber;
}

void Calculator::result() {
        if(strcmp(this->Operation, "+") == 0) {
                std::cout << "Hasil = " << penjumlahan() << "\n";
        } else if(strcmp(this->Operation, "-") == 0) {
                std::cout << "Hasil = " << pengurangan() << "\n";
        } else if(strcmp(this->Operation, ":") == 0) {
                std::cout << "Hasil = " << pembagian() << "\n";
        } else if(strcmp(this->Operation, "x") == 0) {
                std::cout << "Hasil = " << perkalian() << "\n";
        } else {
                std::cout << "Error!\n";
        }
}
						

File include/operations.cpp


#include <iostream>
#include "../include/calculator.hpp"

int Calculator::penjumlahan() {
        return this->FirstNumber + this->SecondNumber;
}

int Calculator::pengurangan() {
        return this->FirstNumber - this->SecondNumber;
}

int Calculator::perkalian() {
        return this->FirstNumber * this->SecondNumber;
}

int Calculator::pembagian() {
        return this->FirstNumber / this->SecondNumber;
}
					

File include/main.cpp


#include <iostream>
#include "../include/calculator.hpp"

int main(int argc, char* argv[]) {
        int firstNumber = std::stoi(argv[1]);
        int secondNumber = std::stoi(argv[3]);
        char* operation = argv[2];

        Calculator* calculator = new Calculator(firstNumber, operation, secondNumber);
        calculator->result();

        return 0;
}

					

Untuk mengcompilenya sebenarnya kita bisa menggunakan command


g++ -std=c++17 main.cpp calculator.cpp operations.cpp -o calc
					

Jika untuk project kecil mungkin cara ini masih bisa, tetapi bagaimana jika untuk projet besar? Tentu ini akan ribet untuk memanage file file code C++.


Make hadir untuk mengatasi masalah ini. Sederhananya Make itu tool untuk automasi compile. Dengan menggunakan Make, project kita akan termanage dengan baik. Oke saya akan contohkan proses compile dengan menggunakan Make.


File Makefile


CXX := g++
CXX_FLAGS := -std=c++17
OBJECT := build/objects
BIN := build/bin

all: build main.o calculator.o operations.o
        $(CXX) $(CXX_FLAGS) $(OBJECT)/main.o $(OBJECT)/calculator.o $(OBJECT)/operations.o  -o $(BIN)/calc

build:
        if [ ! -d build/objects ] && [ ! -d build/bin ]; then \
                mkdir -p build/objects; \
                mkdir -p build/bin; \
        fi 

main.o:
        $(CXX) -c src/main.cpp $(CXX_FLAGS) -o $(OBJECT)/main.o

calculator.o:
        $(CXX) -c src/calculator.cpp $(CXX_FLAGS) -o $(OBJECT)/calculator.o

operations.o:
        $(CXX) -c src/operations.cpp $(CXX_FLAGS) -o $(OBJECT)/operations.o

clean:
        @echo "Clearing..."
        @rm -rf build
					

Untuk Compile kita kita tinggal menjalankan command "make".

Kita test simple calculator.

Jika kita ingin membersihkan hasil compile, kita tinggal menjalankan command "make clean" & otomatis semua hasil compile akan terhapus.

Jadi itu sedikit pengenalan tentang Make. Di article ini saya tidak membahas cara menulis Makefile, tetapi lebih ke pengenalan Make itu sendiri, karena yang saya rasakan adalah lebih mudah untuk memanage project C++ dengan menggunakan Make ini. Dan jika teman teman mau mencoba menggunakan Make di project C++, teman teman bisa cari tutorial di internet tentang Make.