1. 程式人生 > 實用技巧 >CMake 多 main() 入口專案搭建(刷題向)

CMake 多 main() 入口專案搭建(刷題向)

在 ACM 演算法競賽 / LeetCode 使用 C++ 進行刷題等場景中,通常:

  • 需要維護很多的 C++ 原始碼
  • 需要有多個 main 函式入口方便執行測試
  • 有一些自己寫的公共函式類庫 (如除錯輸出vector等) 在多個檔案中引用

本文介紹了通過 CMake 及一些自生成配置檔案的工具,通過一個統一的庫,方便管理所有程式碼的方法。

CMake 是一個平臺無關的可以定製 C++ 編譯流程的工具,可以生成特定平臺的 Makefile 檔案。預設被 Intellij CLion 支援。


需要首先通過 CLion 建立一個 C++ 工程:

創建出自己需要的目錄結構來:我們把所有的原始碼 .cpp 等檔案放在 /src 中, 一些工具類放在 /src/utils 中

CMakeLists.txt 檔案就是我們的 CMake 編譯流程配置檔案了。為了支援多個 main() 函式入口,我們用add_executable命令新增多個 target,這種才能在每個 main() 入口單獨執行:

cmake_minimum_required(VERSION 3.17)
project(lc-cpp)

set(CMAKE_CXX_STANDARD 17)
add_definitions("-DKUN_DEBUG")

add_executable(training_p1 src/normal/cat0/cat00/cat000/p1.cpp)
add_executable(training_p15 src/normal/cat0/cat00/cat001/p15.cpp)
add_executable(biweekly_34_2 src/match/biweekly/biweekly34/p2.cpp)
add_executable(biweekly_34_3 src/match/biweekly/biweekly34/p3.cpp)
add_executable(biweekly_34_4 src/match/biweekly/biweekly34/p4.cpp)

接下來我們處理公共類庫的問題,只需要將 utils 目錄宣告為編譯器的標頭檔案搜尋路徑之下,這樣就能被其他檔案引用了。

像是 LeetCode 的 TreeNode, ListNode 等基礎資料結構及其解析、debug 工具可以放在這裡面:

include_directories("src/utils")

再來解決最後一個問題。我們每次建立一些 .cpp 程式碼後,就需要去CMakeLists.txt 檔案中新增對應的 add_executable 程式碼。這部分工作我們可以通過指令碼的形式去自動生成,附上 Python3 程式碼:

import os

HEAD = '''
cmake_minimum_required(VERSION 3.17) project(lc-cpp) set(CMAKE_CXX_STANDARD 17) add_definitions("-DKUN_DEBUG") include_directories("src/utils") ''' def update_cmake(): file_list = [] for root, dirs, files in os.walk("src"): if len(files) == 0: continue for f in files: file_list.append(root + os.sep + f) res = HEAD for i in sorted(file_list): if 'utils' in i: continue split = i.split(os.sep) name_ids = filter(lambda x: x != 'src', split) name = "_".join(name_ids).replace(".cpp", "") path = "/".join(split) code = f'add_executable({name} {path})\n' res += code with open('CMakeLists.txt', "w") as f: f.write(res) if __name__ == '__main__': update_cmake()

至此,通過把所以題目按照分類資料夾管理,然後自動生成可執行檔案編譯配置,一個比較完成的方便 C++ 刷題的專案環境就建立好了。