03_wmake
Important
Visit https://aerosand.cc for the latest updates.
0. Preface
Having understood the Make-based implementation of C++ projects, we can now more easily grasp the wmake implementation approach provided by OpenFOAM.
This section primarily covers:
- A brief understanding of
wmake - Direct linking using
wmake - Dynamic library linking using
wmake - Understanding Make
- Compiling and running a
wmake-based project
1. Understanding wmake
wmake in OpenFOAM is a build tool based on make. Essentially, it is a set of scripts and configuration files specifically designed for OpenFOAM projects. It simplifies the compilation process of OpenFOAM and automatically handles certain dependencies and path settings.
wmakeis a wrapper script aroundmakethat sets up the environment variables and rules required for OpenFOAM compilation.wmakeautomatically locates OpenFOAM’s specific directory structure and sets corresponding compilation options (such as include paths, library paths, etc.).wmakeprovides an interface similar tomakebut is optimized for OpenFOAM.
OpenFOAM uses Make/files and Make/options to manage compilation with wmake.
Tip
Simply put, the two files files and options under the Make folder together serve the function of a Makefile.
OpenFOAM convention uses .C as the suffix for source files and .H for header files.
To avoid confusion regarding file structure, a loose distinction is made here. OpenFOAM’s project-level .H files are often used merely to split the main source code by functionality, facilitating code reading and maintenance; many of these are not class header files. This differs from class header files at the C++ development level and from source-level header files in OpenFOAM (e.g., $FOAM_SRC/OpenFOAM/dimensionSet/dimensionSet.H).
Tip
In OpenFOAM, applications include:
- Solvers
- Utilities
- Pre-processing Applications
- Post-processing Applications
In this series, a project refers to all components that solve a given problem, including:
- Solver
- Test case
- Linked libraries
- Utilities
- etc.
The following discussion focuses on simple source-level header files.
2. Project
Run the following commands in the terminal to create the project for this section:
ofsp
mkdir ofsp_03_wmake
code ofsp_03_wmakeContinue using terminal commands or the VS Code interface to create additional files. The final file structure is as follows:
tree
.
├── Aerosand
│ ├── Aerosand.C
│ └── Aerosand.H
├── Make
│ ├── files
│ └── options
└── ofsp_03_wmake.CThe declaration of the Aerosand library in Aerosand.H is as follows:
| |
Warning
Ensure that each code file ends with a blank line; otherwise, OpenFOAM will issue a parse error during compilation.
The definition of the Aerosand library in Aerosand.C is as follows:
| |
The main application source file ofsp_03_wmake.C is as follows:
| |
OpenFOAM provides Make to assist development, where:
- The
/Make/filesfile specifies the source files to compile and the name and location of the target to generate. - The
/Make/optionsfile specifies compilation and linking options, including header file paths and libraries to link.
Note that #include "Aerosand.H" does not require a path specification because the path will be handled in the Make.
The following sections discuss different linking approaches and the details of the Make.
3. Direct Linking
Similar to the direct linking discussed in 02_helloWorld/3.4. Linking, this can also be achieved in OpenFOAM.
3.1. Configuring Make
The contents of ofsp_03_wmake/Make/files are as follows:
Aerosand/Aerosand.C
ofsp_03_wmake.C
EXE = $(FOAM_USER_APPBIN)/ofsp_00_helloWorld_wmake- The source files are
Aerosand.Candofsp_03_wmake.C. - The location of the generated target is
$(FOAM_USER_APPBIN). - The name of the generated target is
ofsp_03_wmake.
The contents of ofsp_03_wmake/Make/options are as follows:
EXE_INC = \
-IAerosand
EXE_LIBS = \- The prefix
EXEindicates that this configuration is for an executable (the prefixLIBindicates configuration for a library). - The suffix
INCdenotes include paths.- The
-Iflag specifies header file search paths. - Typically points to the
lnIncludedirectory of an OpenFOAM module (linked include directory). - Can include system header paths or third-party library header paths.
- The
- The suffix
LIBSdenotes library linking (for direct linking, no libraries need to be linked; this can be left blank).- The
-lflag specifies libraries to link. - Library names omit the
libprefix and.sosuffix (e.g.,-lfiniteVolumecorresponds tolibfiniteVolume.so). - The
-Lflag specifies library search paths.
- The
Run the following command in the terminal to compile:
wclean
wmake3.2. Compilation
The terminal output consists of three sections, corresponding to the three stages of application compilation.
The first section is the compilation of the custom Aerosand class, producing the object file Aerosand.o (see the end of the output):
g++ -std=c++14 -m64 -pthread -DOPENFOAM=2406 -DWM_DP -DWM_LABEL_SIZE=32 -Wall
-Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid
-offsetof -Wno-attributes -Wno-unknown-pragmas -O3 -DNoRepository -ftemplate
-depth-100 -IAerosand -iquote. -IlnInclude
-I/usr/lib/openfoam/openfoam2406/src/OpenFOAM/lnInclude
-I/usr/lib/openfoam/openfoam2406/src/OSspecific/POSIX/lnInclude -fPIC
-c Aerosand/Aerosand.C -o Make/linux64GccDPInt32Opt/Aerosand/Aerosand.oThe second section is the compilation of the main source file, producing the object file ofsp_03_wmake.o (see the end of the output):
g++ -std=c++14 -m64 -pthread -DOPENFOAM=2406 -DWM_DP -DWM_LABEL_SIZE=32 -Wall
-Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid
-offsetof -Wno-attributes -Wno-unknown-pragmas -O3 -DNoRepository -ftemplate
-depth-100 -IAerosand -iquote. -IlnInclude
-I/usr/lib/openfoam/openfoam2406/src/OpenFOAM/lnInclude
-I/usr/lib/openfoam/openfoam2406/src/OSspecific/POSIX/lnInclude -fPIC
-c ofsp_03_wmake.C -o Make/linux64GccDPInt32Opt/ofsp_03_wmake.oThe third section is the linking stage, where the two object files are directly linked to produce the final executable (see the end of the output):
g++ -std=c++14 -m64 -pthread -DOPENFOAM=2406 -DWM_DP -DWM_LABEL_SIZE=32 -Wall
-Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid
-offsetof -Wno-attributes -Wno-unknown-pragmas -O3 -DNoRepository -ftemplate
-depth-100 -IAerosand -iquote. -IlnInclude
-I/usr/lib/openfoam/openfoam2406/src/OpenFOAM/lnInclude
-I/usr/lib/openfoam/openfoam2406/src/OSspecific/POSIX/lnInclude
-fPIC -Xlinker --add-needed -Xlinker --no-as-needed
Make/linux64GccDPInt32Opt/Aerosand/Aerosand.o
Make/linux64GccDPInt32Opt/ofsp_03_wmake.o
-L/usr/lib/openfoam/openfoam2406/platforms/linux64GccDPInt32Opt/lib \
-lOpenFOAM -ldl \
-lm -o /home/aerosand/OpenFOAM/aerosand
-v2406/platforms/linux64GccDPInt32Opt/bin/ofsp_03_wmakeThe intermediate build files are located in ofsp_03_wmake/Make/linux64GccDPInt32Opt/ (the exact path may vary depending on the platform). The generated executable is placed in the $FOAM_USER_APPBIN directory (as specified in Make/files).
Run the following command in the terminal to locate all successfully generated executables:
tree $FOAM_USER_APPBIN3.3. Running
This executable is a standalone program that does not require any external files for input parameters. Thanks to OpenFOAM’s environment variables, the compiled program can be run directly from the terminal in any directory.
Run the following command in the terminal:
ofsp_03_wmakeThe output is as follows:
Hi, OpenFOAM! Here we are.
1 + 3.14159 = 4.14159
1 * 3.14159 = 3.14159
Current time step is : 0.24. Dynamic Library Linking
In practical development, we still use dynamic libraries to ensure memory efficiency and performance.
Adjust the file structure as follows:
.
├── Aerosand
│ ├── Aerosand.C
│ ├── Aerosand.H
│ └── Make
│ ├── files
│ └── options
├── Make
│ ├── files
│ └── options
└── ofsp_03_wmake.C4.1. Library Make
Create a Make for the library.
The contents of /Aerosand/Make/files are as follows:
Aerosand.C
LIB = $(FOAM_USER_LIBBIN)/libAerosand- Note that
LIBis used instead ofEXEfor a library. - The target path ends with
LIBBINinstead ofAPPBIN. - The target file must be prefixed with
lib.
Since this Aerosand library does not require linking with any other libraries, /Aerosand/Make/options can be left empty.
Run the following command in the terminal to compile the library from the root directory:
wmake AerosandThe terminal output consists of two sections, corresponding to the compilation stages.
The first section compiles the custom Aerosand library, producing the object file Aerosand.o (see the end of the output):
g++ -std=c++14 -m64 -pthread -DOPENFOAM=2406 -DWM_DP -DWM_LABEL_SIZE=32 -Wall
-Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid
-offsetof -Wno-attributes -Wno-unknown-pragmas -O3 -DNoRepository -ftemplate
-depth-100 -iquote. -IlnInclude
-I/usr/lib/openfoam/openfoam2406/src/OpenFOAM/lnInclude
-I/usr/lib/openfoam/openfoam2406/src/OSspecific/POSIX/lnInclude -fPIC
-c Aerosand.C -o Make/linux64GccDPInt32Opt/Aerosand.oThe second section links the object file Aerosand.o into a dynamic library Aerosand.so (see the end of the output):
g++ -std=c++14 -m64 -pthread -DOPENFOAM=2406 -DWM_DP -DWM_LABEL_SIZE=32 -Wall
-Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid
-offsetof -Wno-attributes -Wno-unknown-pragmas -O3 -DNoRepository -ftemplate
-depth-100 -iquote. -IlnInclude
-I/usr/lib/openfoam/openfoam2406/src/OpenFOAM/lnInclude
-I/usr/lib/openfoam/openfoam2406/src/OSspecific/POSIX/lnInclude -fPIC -shared
-Xlinker --add-needed -Xlinker
--no-as-needed Make/linux64GccDPInt32Opt/Aerosand.o
-L/usr/lib/openfoam/openfoam2406/platforms/linux64GccDPInt32Opt/lib \
-o /home/aerosand/OpenFOAM/aerosand
-v2406/platforms/linux64GccDPInt32Opt/lib/libAerosand.soThe intermediate build files are located in ofsp_03_wmake/Aerosand/Make/linux64GccDPInt32Opt/ (the exact path may vary depending on the platform). The generated dynamic library is placed in the $FOAM_USER_LIBBIN directory (as specified in Make/files).
Run the following command in the terminal to locate all successfully generated dynamic libraries:
tree $FOAM_USER_LIBBINA library may contain multiple classes or even other sub-libraries. After compilation, an lnInclude folder is generated in the library’s path. This folder contains symbolic links to the declarations (.H files) and implementations (.C files) of all classes (or sub-libraries) within the library, providing a unified and simplified path for subsequent linking. For reference, examine the $FOAM_SRC/OpenFOAM library in OpenFOAM, where the lnInclude folder contains shortcuts to all classes (or sub-libraries) within that library.
Run the following command to view the file structure of the compiled Aerosand library:
Aerosand
├── Aerosand.C
├── Aerosand.H
├── lnInclude
│ ├── Aerosand.C -> ../Aerosand.C
│ └── Aerosand.H -> ../Aerosand.H
└── Make
├── files
├── linux64GccDPInt32Opt
│ ├── Aerosand.C.dep
│ ├── Aerosand.o
│ ├── options
│ ├── sourceFiles
│ └── variables
└── options4.2. Project Make
Because the Aerosand library has been compiled into a dynamic library, we need to specify it in the project’s Make.
Modify /Make/files as follows:
ofsp_03_wmake.C
EXE = $(FOAM_USER_APPBIN)/ofsp_03_wmakeModify /Make/options as follows:
EXE_INC = \
-IAerosand/lnInclude
EXE_LIBS = \
-L$(FOAM_USER_LIBBIN) \
-lAerosand- The prefix
EXEindicates that this configuration is for an executable (the prefixLIBindicates configuration for a library). - The suffix
INCdenotes include paths.- The
-Iflag specifies header file search paths. - Typically points to the
lnIncludedirectory of an OpenFOAM module (linked include directory). - Can include system header paths or third-party library header paths.
- The
- The suffix
LIBSdenotes library linking.- The
-lflag specifies libraries to link. - Library names omit the
libprefix and.sosuffix (e.g.,-lAerosandcorresponds tolibAerosand.so). - The
-Lflag specifies library search paths.
- The
- Ensure the file ends with a blank line to avoid OpenFOAM compilation warnings.
Tip
In common OpenFOAM solver Make/options files, you will often see only -l flags without -L flags. This is because the solvers use built-in libraries whose paths are already configured, so only the library names need to be specified with -l. For user-defined libraries compiled in other locations, -L path specification is necessary.
Pay close attention to paths, as they are crucial for successful compilation. Typically, paths are specified relative to the project root directory (absolute paths can also be used, as demonstrated below).
4.3. Compilation
Run the following command in the terminal to perform the compilation:
wclean
wmakeThe terminal output consists of two sections, corresponding to the compilation stages.
The first section compiles the main source file, producing the object file ofsp_03_wmake.o (see the end of the output):
g++ -std=c++14 -m64 -pthread -DOPENFOAM=2406 -DWM_DP -DWM_LABEL_SIZE=32 -Wall
-Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid
-offsetof -Wno-attributes -Wno-unknown-pragmas -O3 -DNoRepository -ftemplate
-depth-100 -IAerosand/lnInclude -iquote. -IlnInclude
-I/usr/lib/openfoam/openfoam2406/src/OpenFOAM/lnInclude
-I/usr/lib/openfoam/openfoam2406/src/OSspecific/POSIX/lnInclude -fPIC
-c ofsp_03_wmake.C -o Make/linux64GccDPInt32Opt/ofsp_03_wmake.oThe second section links the dynamic library to the application and generates the executable ofsp_03_wmake (see the end of the output):
g++ -std=c++14 -m64 -pthread -DOPENFOAM=2406 -DWM_DP -DWM_LABEL_SIZE=32 -Wall
-Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid
-offsetof -Wno-attributes -Wno-unknown-pragmas -O3 -DNoRepository -ftemplate
-depth-100 -IAerosand/lnInclude -iquote. -IlnInclude
-I/usr/lib/openfoam/openfoam2406/src/OpenFOAM/lnInclude
-I/usr/lib/openfoam/openfoam2406/src/OSspecific/POSIX/lnInclude -fPIC -Xlinker
--add-needed -Xlinker --no-as-needed Make/linux64GccDPInt32Opt/ofsp_03_wmake.o
-L/usr/lib/openfoam/openfoam2406/platforms/linux64GccDPInt32Opt/lib \
-L/home/aerosand/OpenFOAM/aerosand-v2406/platforms/linux64GccDPInt32Opt/lib
-lAerosand -lOpenFOAM -ldl \
-lm -o /home/aerosand/OpenFOAM/aerosand
-v2406/platforms/linux64GccDPInt32Opt/bin/ofsp_03_wmakeSimilarly, the generated executable is placed in the $FOAM_USER_APPBIN directory (as specified in Make/files).
4.4. Running
Run the following command in the terminal:
ofsp_03_wmakeThe output is as follows:
Hi, OpenFOAM! Here we are.
1 + 3.14159 = 4.14159
1 * 3.14159 = 3.14159
Current time step is : 0.25. Summary
This section has completed the following discussions:
- A brief understanding of
wmake - Direct linking using
wmake - Dynamic library linking using
wmake - Understanding Make
- Compiling and running a
wmake-based project
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
