iT邦幫忙

2023 iThome 鐵人賽

DAY 6
0

在專案中為了更容易擴充、維護專案,都會將原始碼拆分成多個檔案,並使用資料夾分門別類放好,例如存放標頭檔的include資料夾、原始碼的src資料夾,還有專門存放建構過程中產生中間文件和目標文件的build資料夾。

// 今天的目錄架構
.
├── build
├── include
│   └── mysqrt.h
└── src
    ├── main.cpp
    └── mysqrt.cpp

然後拆分出來每個獨立的 .h 和 .cpp 檔都應該要可以各自被預處理、編譯、彙編成 .o 檔而不報錯,並且在最後將各個.o檔鍊結到一個可執行文件中。

https://ithelp.ithome.com.tw/upload/images/20230920/20162026Uhyf0D14OP.png

接下來會先使用g++來展示編譯多檔案的步驟,了解完原理後才會使用CMake。

使用g++ 編譯多個檔案

$ git clone https://github.com/m11112089/2023_iT_CMake.git
$ cd ~/2023_iT_CMake/Day6/g++

1. 將原始碼編譯成 .o檔
因為我們將.h檔放入了include資料夾中,與.cpp並不在同一資料夾中,因此需要-I 這個參數新增include所在路徑,讓g++能夠搜尋到標頭檔。

語法: -I <.h檔所在路徑> -c <.cpp所在相對路徑/ .cpp名稱>

$ cd build
$ g++ -I ../include -c ../src/main.cpp
$ g++ -I ../include -c ../src/mysqrt.cpp

可以看到在 build 資料夾中生成了兩個.o檔

kai@esoc:~/2023_iT_CMake/Day6/g++/build$ tree
.
├── main.o
└── mysqrt.o

2. 鍊結兩個 .o 檔,並生成最終的執行檔main

語法:g++ -o <執行檔名稱> <1.o> <2.o> <3...>

$ g++ -o main main.o mysqrt.o

可以看到形成的執行檔 main

kai@esoc:~/2023_iT_CMake/Day6/g++/build$ tree
.
├── main
├── main.o
└── mysqrt.o

3. 執行

$ ./main

// output
kai@esoc:~/2023_iT_CMake/Day6/g++/build$ g++ -I ../include -c ../src/main.cpp
kai@esoc:~/Desktop/2023_iT_CMake/Day6/g++/build$ g++ -I ../include -c ../src/mysqrt.cpp
kai@esoc:~/Desktop/2023_iT_CMake/Day6/g++/build$ g++ -o main main.o mysqrt.o
kai@esoc:~/Desktop/2023_iT_CMake/Day6/g++/build$ ./main 10
Computing sqrt of 10 to be 5.5
Computing sqrt of 10 to be 3.65909
Computing sqrt of 10 to be 3.19601
Computing sqrt of 10 to be 3.16246
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
The square root of 10 is 3.16228


使用CMake編譯多個檔案

CMake 語法

include_directories

定義:設定編譯器搜尋.h的路徑

include_directories( dir1 [dir2 ...])
---
dir : CMake搜尋.h的路徑

set

定義:設定變數與變數內容

set(<variable> <value>)
---
variable : 變數名稱
value : 變數內容

步驟

$ cd ~/2023_iT_CMake/Day6/cmake

一、編寫CMakeLists.txt

  1. 將include資料夾加入編譯器搜尋.h的路徑
include_directories(${PROJECT_SOURCE_DIR}/include)
# 將include資料夾加入include路徑
  1. 設定原始碼所在路徑
set(SRC_DIR ${PROJECT_SOURCE_DIR}/src)
# 將原始碼所在路徑設定成變數 SRC_DIR
  1. 編譯並鍊結成執行檔
add_executable(main ${SRC_DIR}/main.cpp ${SRC_DIR}/mysqrt.cpp)
# 將main.cpp與mysqrt.cpp編譯並鍊結成執行檔main

二、使用CMake讀取CMakeLists.txt生成makefile

先進入build資料夾,避免編譯過程中產生的中間文件破壞專案目錄結構,比較整齊。

$ cd build
$ cmake ..

cmake 後面那個點點的意思是讓CMake在目前所在目錄(~/2023_iT_CMake/Day6/cmake/build)的上一層目錄尋找CMakeLists.txt進行構建。

三、 使用make讀取makefile構建執行檔

$ make

這個時候可以到 CMakeFiles/main.dir/src 中查看編譯出來的 mysqrt.cpp.o 與main.cpp.o

$ cd CMakeFiles/main.dir/src

kai@esoc:~/2023_iT_CMake/Day6/cmake/build/CMakeFiles/main.dir/src$ tree
.
├── main.cpp.o
├── main.cpp.o.d
├── mysqrt.cpp.o
└── mysqrt.cpp.o.d

在這裡也可以向上一段落一樣,直接用g++將兩個.o檔鍊結成執行檔 main。

$ g++ -o main main.cpp.o mysqrt.cpp.o
$ ./main 10

kai@esoc:~/2023_iT_CMake/Day6/cmake/build/CMakeFiles/main.dir/src$ tree
.
├── main
├── main.cpp.o
├── main.cpp.o.d
├── mysqrt.cpp.o
└── mysqrt.cpp.o.d

四、 執行

$ ./main

kai@esoc:~/2023_iT_CMake/Day6/cmake/build$ cmake ..
-- The CXX compiler identification is GNU 11.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/kai/2023_iT_CMake/Day6/cmake/build
kai@esoc:~/2023_iT_CMake/Day6/cmake/build$ make
[ 33%] Building CXX object CMakeFiles/main.dir/src/main.cpp.o
[ 66%] Building CXX object CMakeFiles/main.dir/src/mysqrt.cpp.o
[100%] Linking CXX executable main
[100%] Built target main
kai@esoc:~/2023_iT_CMake/Day6/cmake/build$ ./main 10
Computing sqrt of 10 to be 5.5
Computing sqrt of 10 to be 3.65909
Computing sqrt of 10 to be 3.19601
Computing sqrt of 10 to be 3.16246
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
The square root of 10 is 3.16228


上一篇
[Day 5] 第一個CMake專案
下一篇
[Day 7] 定義與宣告—多檔案共用變數
系列文
建構屬於自己的C/C++專案 : 我的30天CMake學習之旅29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言