02_make
Important
Visit https://aerosand.cc for the latest updates.
0. Preface
Although the compilation process discussed in the previous section is conceptually clear, executing it step by step is rather tedious and inefficient in practice.
In order to simplify project compilation while still preserving a clear understanding of the underlying compilation mechanisms, we introduce the make utility to manage the development workflow. Many modern projects also employ cmake, which offers a more concise and efficient interface; however, it is fundamentally still built upon makefile.
By providing a makefile for the project, all compilation steps can be explicitly described. Consequently, the entire project can be built through a single command, significantly improving both debugging efficiency and execution convenience. Furthermore, since all source files in previous examples were placed within a single
directory—resulting in poor organization—we now introduce a structured project architecture.
This section focuses on the following objectives:
- Understanding the usage of
make - Writing a general and reusable
makefile - Compiling and executing a project managed by
make
1. Project
Execute the following commands in the terminal to create the project:
ofsp
mkdir ofsp_02_make
code ofsp_02_makeContinue using either terminal commands or the VS Code interface to create the remaining files. The final project structure is as follows:
tree
.
├── Aerosand
│ ├── Aerosand.cpp
│ ├── Aerosand.h
│ └── makefile
├── makefile
└── ofsp_02_make.cppTip
At this stage, the directory Aerosand can be regarded as a library that contains a class of the same name.
The declaration of class Aerosand in Aerosand.h remains unchanged:
| |
The definition of class Aerosand in Aerosand.cpp remains unchanged:
| |
The main source file ofsp_02_make.cpp requires a modification to the header file path; the rest of the content remains unchanged:
| |
2. make
The automated build tool make can automatically perform the compilation and linking process based on the rules defined in a Makefile.
The basic format of a Makefile is as follows:
<target>: <support>
<command>
It is important to note that when we run the make command, it attempts to build the first target and its dependencies. In principle, the order of targets other than the first does not matter. If make finds that a target lacks a dependency during the build process, it will look for a rule to build that dependency elsewhere in the Makefile.
When multiple targets need to be built simultaneously, it is good practice to use all as the default target.
2.1. Makefile for the Library
Based on the discussion of the C++ compilation process in the previous section, we can provide a Makefile for the Aerosand library, directly specifying the compilation commands.
Note that if the file content is as follows:
| |
The first target is incorrect; running make will only generate Aerosand.o and will not produce the dynamic library.
By adjusting the order of the rules, a successful compilation can be achieved:
| |
Run the following command in the terminal to successfully generate the dynamic library:
cd Aerosand
makeThe file structure of the current directory is as follows:
tree
.
├── Aerosand.cpp
├── Aerosand.h
├── Aerosand.o
├── libAerosand.so
└── makefileThe dynamic library libAerosand.so has been successfully generated.
2.2. Optimizing the Library Makefile
As discussed regarding target order, when there are many build targets, it is necessary to better organize the Makefile to improve efficiency and maintainability. An optimized Makefile is as follows:
| |
Tip
.PHONY is a special declaration in Makefiles used to tell make that a target is not an actual file, but rather a phony target. This is a very important and commonly used feature with the following advantages:
- Prevents conflicts with real files
- Improves performance
- Clearly conveys intent to other readers
The following automatic variables are used in the Makefile:
$^Â represents all dependencies$@Â represents the target file$<Â represents the first dependency
Readers should not be overly concerned with the syntax of the Makefile. The extensive use of macros and variables makes the script more generic. For unfamiliar syntax, it is sufficient to know that it can be used in this way; there is no need to spend excessive time understanding the underlying reasons and principles.
A brief explanation is provided as follows:
- The first and second sections define macro variables to facilitate subsequent script writing.
- The third and fourth sections implement compilation commands using these macros; the order of these two sections does not affect the compilation result.
- The fifth section explicitly defines the first target, defining theÂ
make all command to perform a complete compilation. - The sixth section defines theÂ
make clean command to clean up build artifacts.
Run the following command in the terminal to compile the library:
make clean
make allThe final result is the same as in the previous section, and the dynamic library is successfully compiled and generated.
2.3. Makefile for the Project
Building on the previous discussion, we directly provide the Makefile for the project as follows:
| |
Compared to the previous Makefile, this one includes statements for linking the dynamic library, which is straightforward.
Run the following commands in the terminal to compile the code:
cd ..
make clean
make all
make runThe output is as follows:
Hi, OpenFOAM! Here we are.
1 + 3.14159 = 4.14159
1 * 3.14159 = 3.14159
Current time step is : 0.23. VS Code Extensions
3.1. C/C++ Project Generator
For general C++ projects, the VS Code extension C/C++ Project Generator can be used. It provides a multi-file project template based on Makefile.
Operations and notes are as follows:
Create a New Project
- PressÂ
F1Â to open the command palette, enter the keyword, and selectÂCreate C++ project. - Enter the project name.
- In the pop-up window, select the parent directory for the new project, and open it.
Write Code
- Develop the main function code inÂ
src/main.cpp. - Write header file declarations in theÂ
include/Â directory. - Write header file definitions in theÂ
src/Â directory.
Compile and Run
- Use the commandÂ
make in the terminal to compile the project;Âmake run to compile and run;Âmake clean to clean the project. - Use the commandÂ
./output/main in the terminal to run the main program directly.
3.2. C Cpp CMake Project Creator
This is a multi-file project template based on CMake.
Operations and notes are as follows:
Create a New Project
- PressÂ
F1Â to open the command palette, enter the keyword, and selectÂCMake Project: Create Project. - In the pop-up window, navigate to the prepared empty project folder and open it.
Write Code
- Develop the main function code inÂ
src/main.cpp. - Write header file declarations in theÂ
include/Â directory. - Write header file definitions in theÂ
src/Â directory.
Compile and Run
- Use the commandÂ
cmake build/Â in the terminal to generate the build system. - Use the commandÂ
make -C build/Â in the terminal to compile the project. - Use the commandÂ
./build/xxx in the terminal to run the main program.
4. Summary
This section has completed the following discussions:
- Understanding the usage of
make - Writing a general and reusable
makefile - Compiling and executing a project managed by
make
Support us
Tip
Hopefully, the sharing here can be helpful to you.
If you find this content helpful, your comments or donations would be greatly appreciated. Your support helps ensure the ongoing updates, corrections, refinements, and improvements to this and future series, ultimately benefiting new readers as well.
The information and message provided during donation will be displayed as an acknowledgment of your support.
Copyright @ 2026 Aerosand
- Course (text, images, etc.):CC BY-NC-SA 4.0
- Code derived from OpenFOAM:GPL v3
- Other code:MIT License
