Skip to content

Commit f1e9586

Browse files
committed
Add CMake learning
1 parent 19aa465 commit f1e9586

1 file changed

Lines changed: 283 additions & 21 deletions

File tree

content/posts/cmake-learning.md

Lines changed: 283 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,294 @@ ShowToc: true # Determines whether to display the Table of Contents (TOC) for
1111
TocOpen: true # Controls whether the TOC is expanded when the post is loaded.
1212
weight: 2 # The order in which the post appears in a list of posts. Lower numbers make the post appear earlier.
1313
---
14+
1415
## 1. Introduction
1516
- It's a meta-build system generator.
1617
- How it works:
17-
- We write high-level instructions in a CMakeLists.txt file (platform-agnostic).Then CMake generates build system files for the platform we choose:
18-
- On Linux/Unix → generates Makefile (for make) or build.ninja (for ninja).
19-
- On Windows → generates Visual Studio solutions (.sln).
20-
- On macOS → can generate Xcode projects.
21-
22-
## 2. Setup
23-
- Linux: Install: `sudo apt install cmake` , Verify: `cmake --version`
24-
25-
## 3. How to work with CMake
26-
27-
1. Create CMakeLists.txt and resources file
28-
2. Create and cd to `project-build` folder & Run `cmake <dir-contain-CMakeLists.txt>` (`cmake ../`) to set up & generate build system.
29-
3. Run `cmake --build <dir-contain-buildsystem>` ( `cmake --build ./`) to actually build/compile the project.
30-
4. Run the target build (e.g. `./targetName`)
31-
32-
### 3.1.
33-
> CMakeLists.txt
34-
```makefile
35-
cmake_minimum_required(VERSION 3.0) // specifying a minimum CMake version
36-
project(CmakeprojectName) // set the project name
37-
add_executeable(targetName "headerfile.h" "sourcefile1.cpp" "sourcefile2.cpp") // specified source code files
18+
- We write high-level instructions in a `CMakeLists.txt` file (platform-agnostic).Then CMake generates build system files for the platform we choose:
19+
- On Linux/Unix: generates Makefile (for make) or build.ninja (for ninja).
20+
- On Windows: generates Visual Studio solutions (.sln).
21+
- On macOS: can generate Xcode projects.
22+
23+
- **CMake Generators:** CMake support multiple build systems output a.k.a generators. Which generator is used can be controlled via `CMAKE_GENERATOR` or `cmake -G` option
24+
- **Single/Multi-Configuration Generators**: Software builds often have several variants e.g. Debug, Release, RelWithDebInfo, and MinSizeRel. To select build type:
25+
- single-generator(ninja,make): via `cmake --DCMAKE_BUILD_TYPE=<config>`
26+
- multi-generator(ninja-mul,vs): single & `cmake --build --config `
27+
28+
- **Usage Basics:**
29+
```bash
30+
# install cmake
31+
$ sudo apt install cmake
32+
33+
# verify cmake
34+
$ cmake --version
35+
cmake version 3.23.5
36+
37+
# specific project root dir, which contains the root CMakeLists.txt
38+
# default current dir
39+
$ cmake -S <dir>
40+
41+
# specific build dir
42+
# default current dir
43+
$ cmake -B <dir>
44+
45+
# specific generator to generate the build system in <dir>
46+
# must delete <dir> when switch <gen>
47+
$ cmake -G "<gen>" -B <dir>
48+
49+
# run the build system in the build dir
50+
# single-config
51+
$ cmake --build <dir>
52+
53+
# multi-configs
54+
$ cmake --build <dir> --config <cfg>
55+
56+
# clean when reorganization
57+
$ cmake --build build --clean-first
3858
```
3959

60+
- **Example:**
61+
```bash
62+
$ cd project
63+
# project structure
64+
$ tree
65+
.
66+
├── CMakeLists.txt
67+
└── HelloWorld.cxx
68+
69+
1 directory, 2 files
70+
71+
$ cat HelloWorld.cxx
72+
#include <cstdio>
73+
74+
int main()
75+
{
76+
std::printf("Hello World\n");
77+
}
78+
79+
$ cat CMakeLists.txt
80+
cmake_minimum_required(VERSION 3.23)
81+
82+
project(Tutorial)
83+
84+
add_executable(hello)
85+
target_sources(hello
86+
PRIVATE
87+
HelloWorld.cxx
88+
)
89+
#######################################################################
90+
# Step 1: generate build system in folder 'build' using Unix Makefiles
91+
$ cmake -G "Unix Makefiles" -B build
92+
93+
# Step 2: run the build system in the folder 'build'
94+
$ cmake --build build
95+
96+
# Step 3: run the executable
97+
$ ./build/hello
98+
Hello World
99+
```
100+
101+
## 2. Getting Started
102+
- This section help us will be able to describe executables, libraries, source and header files, and the linkage relationship between them.
103+
104+
- A `CMakeLists.txt` (list file-CML) will exist within any directory where we want to provide instructions to CMake on how to handle files, and operations local to that dir or sub-dir.
105+
- There are four backbone commands of most CMake usage:
106+
- `add_executable() and add_library()` for describing output artifacts the software project wants to produce,
107+
- `target_sources()` for associating input files with their respective output artifacts, and the
108+
- `target_link_libraries()` for associating output artifacts with one another.
109+
110+
111+
- Strongly recommend that the **project root CMakeLists.txt**
112+
```bash
113+
$ cat CMakeLists.txt
114+
115+
# should always contain these two commands at the top/near
116+
cmake_minium_required(VERSION 3.23)
117+
project(MyProjectName)
118+
```
119+
120+
### 2.1. Building an Executable
121+
- We need at least four commands:
122+
- **cmake_minium_required(VERSION <min>)**
123+
- **project(<name> VERSION <ver>)**
124+
- **add_executable(<name>)**: create a target, we can now start associating properties with it like source files we want to build and link.
125+
- **target_sources(<target> {INTERFACE|PUBLIC|PRIVATE} <source>)**: add source to target
126+
127+
- The scope keyword for executable should always be **PRIVATE**
128+
- e.g.
129+
```bash
130+
$ cat CMakeLists.txt
131+
# Set the minimum required version of CMake to be 3.23
132+
cmake_minimum_required(VERSION 3.23)
133+
# Create a project named Tutorial
134+
project(Tutorial)
135+
136+
# Add an executable target called Tutorial to the project
137+
add_executable(Tutorial)
138+
# Add the Tutorial/Tutorial.cxx source file to the Tutorial target
139+
target_sources(Tutorial
140+
PRIVATE
141+
Tutorial/Tutorial.cxx
142+
)
143+
```
144+
145+
146+
### 2.2. Building a Library
147+
- For example:
148+
```bash
149+
$ cat CMakeLists.txt
150+
cmake_minimum_required(VERSION 3.23)
151+
project(example)
152+
153+
# target 1
154+
add_executable(Tutorial1)
155+
target_sources(Tutorial1
156+
PRIVATE
157+
Tutorial/Tutorial.cxx
158+
)
159+
160+
# target 2
161+
add_executable(Tutorial2)
162+
target_sources(Tutorial2
163+
PRIVATE
164+
Tutorial/Tutorial.cxx
165+
)
166+
```
167+
=> Both Tutorial1 and Tutorial2 compile the same source file:
168+
169+
- Use `add_library` to add a library to the project
170+
- Use a `FILE_SET` to describe a collection of header files in the `target_source`
171+
```bash
172+
# Add a library called MyLibrary
173+
add_library(MyLibrary)
174+
175+
target_sources(MyLibrary
176+
PRIVATE # private source files, target cannot see
177+
library_implementation.cxx
178+
179+
PUBLIC # public source files
180+
# FILE_SET myHeaders # name
181+
# TYPE HEADERS # kind
182+
FILE_SET HEADERS # don't need to provide type
183+
BASE_DIRS # base locations of the file
184+
include
185+
FILES # list of files
186+
include/library_header.h
187+
188+
189+
190+
########################################################
191+
PRIVATE # PRIVATE is for me
192+
FILE_SET internalOnlyHeaders
193+
TYPE HEADERS
194+
FILES
195+
InternalOnlyHeader.h
196+
197+
INTERFACE # INTERFACE is for others
198+
FILE_SET consumerOnlyHeaders
199+
TYPE HEADERS
200+
FILES
201+
ConsumerOnlyHeader.h
202+
203+
PUBLIC # PUBLIC is for all of us
204+
FILE_SET publicHeaders
205+
TYPE HEADERS
206+
FILES
207+
PublicHeader.h
208+
)
209+
```
210+
- We now can include directive were `#include <MyLibrary/library_header.h>`
211+
212+
### 2.3. Linking Together Libraries and Executables
213+
- Use `target_link_libraries()` to invoke linkers to combine targets/libs
214+
```bash
215+
# Add the MyLibrary library as a linked dependency
216+
# to the Tutorial target
217+
target_link_libraries(Tutorial
218+
PRIVATE
219+
MyLibrary
220+
)
221+
222+
target_link_libraries(Tutorial2
223+
PRIVATE
224+
MyLibrary
225+
)
226+
```
227+
228+
### 2.4. Subdirectories
229+
- Use add_subdirectory(<subname>) to incorporate the CLMs - CMakeLists.txt located in a subdirectory of the project.
230+
- The relative paths used inside that subdirectory’s CMakeLists.txt are interpreted relative to that subdirectory.
231+
232+
- e.g
233+
```bash
234+
$ cd TutorialProject
235+
# project structure
236+
$ tree
237+
├── CMakeLists.txt
238+
├── Tutorial/
239+
│ ├── CMakeLists.txt
240+
│ └── Tutorial.cxx
241+
└── MathFunctions/
242+
├── CMakeLists.txt
243+
├── MathFunctions.cxx
244+
└── MathFunctions.h
245+
246+
$ cat CMakeLists.txt # root CMakeLists.txt
247+
cmake_minimum_required(VERSION 3.23)
248+
249+
project(Tutorial)
250+
251+
# include subdirectories so CMake processes their CMakeLists.txt
252+
add_subdirectory(MathFunctions)
253+
add_subdirectory(Tutorial)
254+
255+
$ cat ./Tutorial/CMakeLists.txt
256+
add_executable(Tutorial)
257+
258+
# add source file for this executable
259+
# path is relative to this directory (Tutorial/)
260+
target_sources(Tutorial
261+
PRIVATE
262+
Tutorial.cxx
263+
)
264+
265+
# link the MathFunctions library to the executable
266+
target_link_libraries(Tutorial
267+
PRIVATE
268+
MathFunctions
269+
)
270+
271+
$ cat ./MathFunctions/CMakeLists.txt
272+
# create a library target MathFunctions
273+
add_library(MathFunctions)
274+
275+
target_sources(MathFunctions
276+
PRIVATE
277+
MathFunctions.cxx
278+
279+
# expose header file to other targets that link this library
280+
PUBLIC
281+
FILE_SET HEADERS
282+
FILES
283+
MathFunctions.h
284+
)
285+
```
286+
287+
288+
289+
290+
291+
292+
293+
294+
295+
296+
297+
298+
299+
300+
301+
40302
## 4. Docker:
41303
1. Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker's methodologies for shipping, testing, and deploying code, you can significantly reduce the delay between writing code and running it in production.
42304

0 commit comments

Comments
 (0)