C++项目结构优化

2025-03-09 17:19:13

# 前言

之前在C++项目结构及交叉编译中也有介绍C++的项目结构,本次基于实际工程化做出一些改进,更加适合库的开发流程。

# 结构

.
├── assets
│   └── shader
├── build
│   ├── cmake_install.cmake
│   ├── CMakeCache.txt
│   ├── CMakeDoxyfile.in
│   ├── CMakeDoxygenDefaults.cmake
│   ├── CMakeFiles
│   ├── compile_commands.json
│   ├── libhierro.a
│   ├── Makefile
│   └── third_party
├── CMakeLists.txt
├── include
│   └── hierro
├── justfile
├── LICENSE
├── src
│   ├── app.cpp
│   ├── color.cpp
│   ├── component
│   └── err.cpp
├── tests
│   ├── build
│   ├── CMakeLists.txt
│   ├── justfile
│   └── src
├── third_party
│   ├── glad
│   └── glfw-3.4
└── toolchain.cmake

对于最外层:

.
├── assets
├── build
├── CMakeLists.txt
├── include
├── justfile
├── LICENSE
├── src
├── tests
├── third_party
└── toolchain.cmake

主要改进如下:

.
└── shader
    ├── fragment.glsl
    └── vertex.glsl
.
├── build
├── CMakeLists.txt
├── justfile
└── src

一个示例程序结构应当符合本文所介绍的规范,但进行简化。

.
├── app.cpp
├── color.cpp
├── component
│   └── block.cpp
└── err.cpp
.
└── hierro
    ├── app.h
    ├── color.h
    ├── component
    │   ├── block.h
    │   └── component.h
    ├── err.h
    └── shader
        ├── fragment.h
        └── vertex.h

使用这种方式,用户可以以#include "hierro/app.h"的方式引用头文件,从而避免命名冲突。

# CMakeLists

# project
set(name "hierro")
cmake_minimum_required(VERSION 3.10)
project(${name} CXX)

# clang setting
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# set(CMAKE_CXX_COMPILER "/usr/bin/clang++" CACHE STRING "C++ compiler" FORCE)
set(CMAKE_CXX_STANDARD 26)

# src
file(GLOB_RECURSE SRC src/*.cpp)
add_library(${name} ${SRC})
target_include_directories(${name} PUBLIC include/)

# link std library static
target_link_options(${name} PRIVATE -static-libgcc -static-libstdc++)

# third party
add_subdirectory(./third_party/glfw-3.4)
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
target_link_libraries(${name} glfw)

find_package(OpenGL REQUIRED)
target_link_libraries(${name} OpenGL::GL)

add_subdirectory(./third_party/glad)
target_link_libraries(${name} glad)

# 构建脚本

name := `cat build/CMakeCache.txt | grep CMAKE_PROJECT_NAME | awk -F '=' '{print $2}'`

init:
  cmake -B build

init_windows:
  cmake -B build -DCMAKE_TOOLCHAIN_FILE=./toolchain.cmake

build:
  cmake --build build

embed:
  xxd -n _vertex_shader_code -i ./assets/shader/vertex.glsl | sed "s/}/,\'\\\0\'}/" > ./include/shader/vertex.h
  xxd -n _fragment_shader_code -i ./assets/shader/fragment.glsl | sed "s/}/,\'\\\0\'}/" > ./include/shader/fragment.h
  clang-format -i ./include/shader/*

run:
  just build
  ./build/{{name}}

run_windows:
  just build
  ./build/{{name}}.exe

clean:
  rm -rf build