Add refactored CMake example
This commit is contained in:
13
CMakeLists.txt
Normal file
13
CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project("Refactoring")
|
||||
|
||||
set_property(GLOBAL PROPERTY CXX_STANDARD 23)
|
||||
|
||||
# Build modules
|
||||
add_subdirectory("modules/ModuleA")
|
||||
add_subdirectory("modules/ModuleB")
|
||||
add_subdirectory("modules/ModuleC")
|
||||
|
||||
# Build app
|
||||
add_subdirectory("app")
|
||||
72
README.md
Normal file
72
README.md
Normal file
@ -0,0 +1,72 @@
|
||||
# Refactoring project
|
||||
|
||||
## How to build
|
||||
|
||||
Build the project by running following commands:
|
||||
```
|
||||
cmake -B build
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
## Static libraries
|
||||
|
||||
The project uses static libraries for the modules. The reassoning behind this is that the main purpose of this refactoring is to modularize the code base. Static linking does not change how the app is compiled or installed. This keeps things simple for now. But for future improvements modules can be linked dynamically to allow of updating individual modules without recompilation if the ABI does not change.
|
||||
|
||||
## Directory structure
|
||||
|
||||
The current directory structure looks like this.
|
||||
|
||||
```
|
||||
refactoring
|
||||
├── app
|
||||
│ ├── CMakeLists.txt
|
||||
│ └── src
|
||||
│ └── main.cpp
|
||||
├── CMakeLists.txt
|
||||
├── modules
|
||||
│ ├── ModuleA
|
||||
│ │ ├── CMakeLists.txt
|
||||
│ │ ├── include
|
||||
│ │ │ └── moduleA
|
||||
│ │ │ └── ClassA.h
|
||||
│ │ └── src
|
||||
│ │ └── ClassA.cpp
|
||||
│ ├── ModuleB
|
||||
│ │ ├── CMakeLists.txt
|
||||
│ │ ├── include
|
||||
│ │ │ └── moduleB
|
||||
│ │ │ └── ClassB.h
|
||||
│ │ └── src
|
||||
│ │ └── ClassB.cpp
|
||||
│ └── ModuleC
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── include
|
||||
│ │ └── moduleC
|
||||
│ │ └── ClassC.h
|
||||
│ └── src
|
||||
│ └── ClassC.cpp
|
||||
└── README.md
|
||||
|
||||
16 directories, 13 files
|
||||
```
|
||||
|
||||
This is mostly straightforward - app and modules are separated. Each module has its own directory in which CMakeLists.txt specifies how to should be built.
|
||||
|
||||
### Structure of module include directory
|
||||
|
||||
Only maybe unexpected thing is that every module include directory contains another directory e.g. `ModuleA/include/moduleA/ClassA.h`. This is to prevent conflicts when including files with same name from different modules. It also allows be visible from which module the included file in the app is from.
|
||||
|
||||
[app source file](app/src/main.cpp):
|
||||
```
|
||||
// app/main.cpp
|
||||
`#include "moduleA/ClassA.h"`
|
||||
```
|
||||
|
||||
If there are many modules a programmer of the app does not get lost where did the class come from. This makes it easy to locate the file without the need for searching.
|
||||
In the module itself it most inner directory is included so that we don't need to specify the module.
|
||||
|
||||
[module source file](modules/ModuleA/src/ClassA.cpp):
|
||||
```
|
||||
// ModuleA/src/ClassA.cpp
|
||||
#include "ClassA.h"
|
||||
```
|
||||
8
app/CMakeLists.txt
Normal file
8
app/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
set(MY_EXE "app")
|
||||
|
||||
add_executable(${MY_EXE} "src/main.cpp")
|
||||
|
||||
target_link_libraries(${MY_EXE} "moduleA" "moduleB" "moduleC")
|
||||
|
||||
# no need to include directories, because they are included automatically
|
||||
# thanks to exposing the directories using PUBLIC
|
||||
10
app/src/main.cpp
Normal file
10
app/src/main.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "moduleA/ClassA.h"
|
||||
#include "moduleB/ClassB.h"
|
||||
#include "moduleC/ClassC.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
ClassA::hello();
|
||||
ClassB::hello();
|
||||
ClassC::hello();
|
||||
}
|
||||
7
modules/ModuleA/CMakeLists.txt
Normal file
7
modules/ModuleA/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
set(MY_LIB "moduleA")
|
||||
|
||||
add_library(${MY_LIB} STATIC "src/ClassA.cpp")
|
||||
|
||||
target_include_directories(${MY_LIB} PRIVATE "include/moduleA")
|
||||
|
||||
target_include_directories(${MY_LIB} PUBLIC "include")
|
||||
9
modules/ModuleA/include/moduleA/ClassA.h
Normal file
9
modules/ModuleA/include/moduleA/ClassA.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef CLASS_A_
|
||||
#define CLASS_A_
|
||||
|
||||
class ClassA {
|
||||
public:
|
||||
static void hello();
|
||||
};
|
||||
|
||||
#endif
|
||||
4
modules/ModuleA/src/ClassA.cpp
Normal file
4
modules/ModuleA/src/ClassA.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
#include "ClassA.h"
|
||||
#include <iostream>
|
||||
|
||||
void ClassA::hello() { std::cout << "Hello from A" << std::endl; }
|
||||
7
modules/ModuleB/CMakeLists.txt
Normal file
7
modules/ModuleB/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
set(MY_LIB "moduleB")
|
||||
|
||||
add_library(${MY_LIB} STATIC "src/ClassB.cpp")
|
||||
|
||||
target_include_directories(${MY_LIB} PRIVATE "include/moduleB")
|
||||
|
||||
target_include_directories(${MY_LIB} PUBLIC "include")
|
||||
9
modules/ModuleB/include/moduleB/ClassB.h
Normal file
9
modules/ModuleB/include/moduleB/ClassB.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef CLASS_B_
|
||||
#define CLASS_B_
|
||||
|
||||
class ClassB {
|
||||
public:
|
||||
static void hello();
|
||||
};
|
||||
|
||||
#endif
|
||||
4
modules/ModuleB/src/ClassB.cpp
Normal file
4
modules/ModuleB/src/ClassB.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
#include "ClassB.h"
|
||||
#include <iostream>
|
||||
|
||||
void ClassB::hello() { std::cout << "Hello from B" << std::endl; }
|
||||
7
modules/ModuleC/CMakeLists.txt
Normal file
7
modules/ModuleC/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
set(MY_LIB "moduleC")
|
||||
|
||||
add_library(${MY_LIB} STATIC "src/ClassC.cpp")
|
||||
|
||||
target_include_directories(${MY_LIB} PRIVATE "include/moduleC")
|
||||
|
||||
target_include_directories(${MY_LIB} PUBLIC "include")
|
||||
9
modules/ModuleC/include/moduleC/ClassC.h
Normal file
9
modules/ModuleC/include/moduleC/ClassC.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef CLASS_C_
|
||||
#define CLASS_C_
|
||||
|
||||
class ClassC {
|
||||
public:
|
||||
static void hello();
|
||||
};
|
||||
|
||||
#endif
|
||||
4
modules/ModuleC/src/ClassC.cpp
Normal file
4
modules/ModuleC/src/ClassC.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
#include "ClassC.h"
|
||||
#include <iostream>
|
||||
|
||||
void ClassC::hello() { std::cout << "Hello from C" << std::endl; }
|
||||
Reference in New Issue
Block a user