我的CMake项目结构
项目类型
- 类库项目 项目的主要输出目标为库文件
- 可执行项目 项目的主要输出为可执行文件
项目结构
- 3rdparty 第三方库
- xxx 库名称,如stb、spdlog
- include 头文件
- src/lib/... (可选)源文件、库文件等
- xxx 库名称,如stb、spdlog
- 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)
不慎成熟,欢迎拍砖
标签:CMAKE,NAME,项目,SOURCE,CMake,true,xxxxx,DIR,结构 From: https://www.cnblogs.com/ippfcox/p/18451214