c++项目结构与CMakeLists.txt
·
文章目录
c++项目结构与CMakeLists.txt
- 写c++项目有一段时间了,以前对于项目中代码、编译文件、可执行文件以及项目中其他文件的组织不够有秩序,存放的路径位置有些松散。
- 后来调整了下各种文件的文件夹归属,以及对应的如何在CMakeList.txt设置可执行文件输出目录,设置库文件的路径和源码的路径。
- 以上仅仅是个人的使用习惯,如果可改善的地方,还望指出,谢谢!!
c++项目结构
文件树状图
├─.git
├─bin
│ ├─config
│ ├─Log
│ └─models
│ └─onnx
├─build
│ ├─.cmake
│ ├─CMakeFiles
│ ├─Release
│ └─x64
├─data
├─doc
├─lib
│ ├─camera
│ │ ├─include
│ │ └─lib
│ ├─cuda118
│ │ ├─include
│ │ └─lib
│ ├─curl
│ │ ├─bin
│ │ ├─include
│ │ └─lib
│ ├─freetype
│ │ ├─include
│ │ └─lib
│ │ ├─Debug
│ │ └─Release
│ ├─httplib
│ ├─libhv
│ │ ├─include
│ │ └─lib
│ ├─log4cpp
│ │ ├─include
│ │ └─lib
│ ├─nlohmann
│ │ └─include
│ ├─opencv411
│ │ ├─include
│ │ └─lib
│ ├─openssl
│ │ ├─bin
│ │ ├─include
│ │ └─lib
│ └─TensorRT-8.6.1.6
├─src
│ ├─algorithm
│ │ ├─InferWorker.cpp
│ │ ├─InferWorker.h
│ │ └─下同,省略
│ ├─application
│ ├─camera
│ ├─communication
│ ├─config
│ ├─logtool
│ ├─threadtool
│ ├─tool
│ ├─trtbase
│ └─main.cpp
├─.gitignore
├─CMakeLists.txt
├─README.md
文件层级说明
- bin 项目生成的可执行程序等
- config 项目的配置文件
- Log 项目运行过程中产生的日志
- models 项目运行时用到的模型
- build 项目编译生成的文件
- data 项目相关数据
- doc 项目相关文档
- lib 项目使用到的第三方库
- 一般我会将库的头文件和库文件都一起放在这个目录里
- src 项目源码
- 每个模块的代码以文件夹区分
- .gitignore git忽略配置文件
- CMakeLists.txt
- README.md 项目说明文档
CMakeLists.txt
设置项目的可执行文件生成路径
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE})
使用APPEND来添加头文件目录和库文件目录
list(APPEND Ex_INC_DIR "lib/camera/include")
list(APPEND Ex_Lib_DIR "lib/camera/lib")
list(APPEND Ex_INC_DIR "lib/freetype/include")
list(APPEND Ex_Lib_DIR "lib/freetype/lib")
# 下同省略
include_directories(${Ex_INC_DIR})
link_directories(${Ex_Lib_DIR})
使用函数收集文件夹下的源码
function(collect_files DIR VARIABLE_PREFIX)
file(GLOB_RECURSE ${VARIABLE_PREFIX}_SRCS
"${DIR}/*.cpp"
"${DIR}/*.c"
"${DIR}/*.cxx"
)
file(GLOB_RECURSE ${VARIABLE_PREFIX}_HEADERSS
"${DIR}/*.h"
"${DIR}/*.hpp"
"${DIR}/*.hxx"
)
set(${VARIABLE_PREFIX}_HEADERS
${${VARIABLE_PREFIX}_HEADERSS}
# PARENT_SCOPE修改的是上一级作用域变量的值
PARENT_SCOPE
)
set(${VARIABLE_PREFIX}_ALL_FILES
${${VARIABLE_PREFIX}_SRCS}
${${VARIABLE_PREFIX}_HEADERSS}
# PARENT_SCOPE修改的是上一级作用域变量的值
PARENT_SCOPE
)
endfunction()
collect_files(${CMAKE_SOURCE_DIR}/src DIR_src)
collect_files(${CMAKE_SOURCE_DIR}/src/algorithm DIR_algorithm)
set(ALL_FILES
${DIR_src_ALL_FILES}
${DIR_algorithm_ALL_FILES})
source_group(TREE ${CMAKE_SOURCE_DIR} FILES ${ALL_FILES})
add_executable(${PROJECT_NAME} ${ALL_FILES})
设置vs启动项
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME})
完整示例
- 相似的操作省略掉了一些
cmake_minimum_required(VERSION 3.16)
project(ProjestName LANGUAGES CXX CUDA)
# 设置C++标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 设置输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE})
# 根据构建类型设置输出目录变量
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(OUTPUT_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG})
set(LIB_SUFFIX "d")
else()
set(OUTPUT_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE})
set(LIB_SUFFIX "")
endif()
if(WIN32)
add_definitions(-DNOMINMAX) # 禁用min/max宏
add_definitions(-DWIN32_LEAN_AND_MEAN) # 减少Windows头文件
add_definitions(-D_CRT_SECURE_NO_WARNINGS) # 禁用安全警告
# 如果是Visual Studio
if(MSVC)
# 设置字符集为UTF-8
add_definitions(/utf-8)
# 禁用特定警告
add_compile_options(/wd4251) # DLL接口警告
add_compile_options(/wd4819) # 代码页警告
# 通用编译选项
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")
# Debug模式编译选项
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd /Zi /Od /RTC1")
# Release模式编译选项
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD /O2 /DNDEBUG")
endif()
endif()
list(APPEND Ex_INC_DIR "lib/camera/include")
list(APPEND Ex_Lib_DIR "lib/camera/lib")
list(APPEND Ex_INC_DIR "lib/freetype/include")
list(APPEND Ex_Lib_DIR "lib/freetype/lib")
if(WIN32)
file(GLOB cam_Lib "lib/camera/lib/*64.lib")
file(GLOB free_Lib "lib/freetype/lib/Release/*.lib")
else()
file(GLOB cam_Lib "lib/camera/lib/x64/*.so")
file(GLOB free_Lib "lib/freetype/lib/Release/*.so")
endif()
function(collect_files DIR VARIABLE_PREFIX)
file(GLOB_RECURSE ${VARIABLE_PREFIX}_SRCS
"${DIR}/*.cpp"
"${DIR}/*.c"
"${DIR}/*.cxx"
)
file(GLOB_RECURSE ${VARIABLE_PREFIX}_HEADERSS
"${DIR}/*.h"
"${DIR}/*.hpp"
"${DIR}/*.hxx"
)
set(${VARIABLE_PREFIX}_HEADERS
${${VARIABLE_PREFIX}_HEADERSS}
# PARENT_SCOPE修改的是上一级作用域变量的值
PARENT_SCOPE
)
set(${VARIABLE_PREFIX}_ALL_FILES
${${VARIABLE_PREFIX}_SRCS}
# 可选:添加头文件以便 IDE 显示
${${VARIABLE_PREFIX}_HEADERSS}
# PARENT_SCOPE修改的是上一级作用域变量的值
PARENT_SCOPE
)
endfunction()
collect_files(${CMAKE_SOURCE_DIR}/src DIR_src)
collect_files(${CMAKE_SOURCE_DIR}/src/algorithm DIR_algorithm)
list(APPEND Ex_INC_DIR "src")
list(APPEND Ex_INC_DIR "src/algorithm")
set(ALL_FILES
${DIR_src_ALL_FILES}
${DIR_algorithm_ALL_FILES})
# 在 Visual Studio 中能保持文件夹结构,便于开发
source_group(TREE ${CMAKE_SOURCE_DIR} FILES ${ALL_FILES})
include_directories(${PROJECT_NAME} PRIVATE ${Ex_INC_DIR})
link_directories(${PROJECT_NAME} PRIVATE ${Ex_Lib_DIR})
add_executable(${PROJECT_NAME} ${ALL_FILES})
target_link_libraries(${PROJECT_NAME} ${cam_Lib})
# 设置启动项目
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME})
if(MSVC)
# 方法1:直接全局设置(所有构建类型均生效)
# add_compile_options(/Zi) # 编译器选项:生成调试信息
# add_link_options(/DEBUG) # 链接器选项:生成调试符号
# 方法2:针对 Release 模式单独设置(推荐)
# 设置编译器选项(/Zi)
target_compile_options(${PROJECT_NAME} PRIVATE
"$<$<CONFIG:Release>:/Zi>"
)
# 设置链接器选项(/DEBUG)
target_link_options(${PROJECT_NAME} PRIVATE
"$<$<CONFIG:Release>:/DEBUG>"
)
target_compile_options(${PROJECT_NAME} PRIVATE "/wd4005") # 忽略宏重定义警告
set_target_properties(${PROJECT_NAME} PROPERTIES
# 设置所有配置的默认调试工作目录为输出目录
VS_DEBUGGER_WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
)
else()
target_compile_options(${PROJECT_NAME} PRIVATE "-Wno-macro-redefined")
endif()
更多推荐

所有评论(0)