我的CMake项目结构

我的CMake项目结构

项目类型

  • 类库项目 项目的主要输出目标为库文件
  • 可执行项目 项目的主要输出为可执行文件

项目结构

  • 3rdparty 第三方库
    • xxx 库名称,如stb、spdlog
      • include 头文件
      • src/lib/... (可选)源文件、库文件等
  • src 项目源码
    • CMakeLists.txt
  • demo (可选)例程,一般类库项目会有
    • CMakeLists.txt
  • .clang-format clang格式化配置
  • .clangd clangd配置
  • .gitignore git忽略列表
  • CMakeLists.txt 主要CMakeLists,包含子项目
  • README.md 项目说明
  • LICENSE

3rdparty

第三方库,一般编译输出结果为bin、lib、include,我们首先创建目录,命名就是第三方库名称,然后将include和lib放进去即可,在CMakeLists.txt中包含该库时包含到前述目录

有些header-only的库只有include,如stb

有些库需要包含源文件,如glad

src

不一定叫这个名字,但其作用是一样的,就是列出项目的主要源文件

注意版本号按需配置

创建库:

cmake_minimum_required(VERSION x.xx)

get_filename_component(DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${DIR_NAME})

aux_source_directory("${CMAKE_CURRENT_SOURCE_DIR}" SRC)

add_library(${PROJECT_NAME} ${SRC})

set(CMAKE_PREFIX_PATH
    "${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/xxxxx/lib/cmake/xxxxx"
)

find_package(xxxxx REQUIRED)

target_include_directories(${PROJECT_NAME} PRIVATE
    "${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/xxxxx/include"
)

target_link_directories(${PROJECT_NAME} PRIVATE
    "${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/xxxxx/lib"
)

if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
    target_link_options(${PROJECT_NAME} PRIVATE "/NODEFAULTLIB:MSVCRT")
endif()

target_link_libraries(${PROJECT_NAME} PRIVATE
    xxxxx::xxxxx
    "yyyyy"
)

创建可执行文件:

cmake_minimum_required(VERSION x.xx)

get_filename_component(DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${DIR_NAME})

aux_source_directory("${CMAKE_CURRENT_SOURCE_DIR}" SRC)

add_executable(${PROJECT_NAME} ${SRC})

set(CMAKE_PREFIX_PATH
    "${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/xxxxx/lib/cmake/xxxxx"
)

find_package(xxxxx REQUIRED)

target_include_directories(${PROJECT_NAME} PRIVATE
    "${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/xxxxx/include"
)

target_link_directories(${PROJECT_NAME} PRIVATE
    "${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/xxxxx/lib"
)

if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
    target_link_options(${PROJECT_NAME} PRIVATE "/NODEFAULTLIB:MSVCRT")
endif()

target_link_libraries(${PROJECT_NAME} PUBLIC
    xxxxx::xxxxx
    "yyyyy"
)

demo

对于类库项目,可能提供一组样例,里面可能包含多个子项目

.clang-format

我比较习惯的一组配置

BasedOnStyle: LLVM
UseTab: Never
IndentWidth: 4
TabWidth: 4
IndentCaseLabels: false
ColumnLimit: 0
AlignAfterOpenBracket: DontAlign
AccessModifierOffset: -4
NamespaceIndentation: All
FixNamespaceComments: false
SortIncludes: false
# AlignConsecutiveShortCaseStatements: true
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true
# AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
# AllowShortIfStatementsOnASingleLine: true
AllowShortLambdasOnASingleLine: All
# AllowShortLoopsOnASingleLine: true
BreakBeforeBraces: Custom
BraceWrapping:
  AfterCaseLabel: true
  AfterClass: true
  AfterControlStatement: Always
  AfterEnum: true
  AfterFunction: true
  AfterNamespace: true
  AfterObjCDeclaration: true
  AfterStruct: true
  AfterUnion: true
  AfterExternBlock: true
  BeforeCatch: true
  BeforeElse: true
  BeforeLambdaBody: false
  BeforeWhile: true
  IndentBraces: false
  SplitEmptyFunction: true
  SplitEmptyRecord: true
  SplitEmptyNamespace: true

.clangd

也是我习惯的配置

自动补include纯属瞎搞,检测未使用的include也是瞎检测,因此都忽略了

Diagnostics:
  MissingIncludes: None
  UnusedIncludes: None

.gitignore

忽略vscode配置、clangd解析缓存、cmake构建文件

.vscode
.cache
build

CMakeLists.txt

整体的文件,主要用于包含子项目

注意CMAKE_EXPORT_COMPILE_COMMANDS适用于生成compile_commands.json的,这个文件用于clangd解析,很好用,但并非所有编译器都支持,gcc是支持的,MSVC就不支持,因此在Windows上,我选择使用clangd

cmake_minimum_required(VERSION x.xx)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

get_filename_component(DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${DIR_NAME})

# set(CMAKE_CXX_STANDARD 20)
# set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_subdirectory(src)
add_subdirectory(demo)

不慎成熟,欢迎拍砖

posted @ 2024-10-08 10:47  I加加  阅读(129)  评论(0)    收藏  举报