基于CMake+CLion创建OpenGL开发环境总结

作为一名iOS开发工程师,平时使用的开发工具都是Xcode偏多,以往链接开发文件、第三方库、图片字体资源等等都只需要交给Xcode来处理即可,我只需要做一个简单的创建或导入操作,还有就是借助方便快捷的CocoaPods强大管理库工具十分简单完成。最近打算写一个文本渲染的项目,最终选择的技术方案是C++、OpenGL和FreeType,并且希望是可以跨平台编译和运行的,经过一番咨询和查找,了解CMake作为首选的工具之一,本着大众原则因此选择CMake构建项目。没想到CMake的使用程度难倒我不少时间,经过一番的学习和研究,从未接触过CMake到了解CMake实现基本的项目构建,因此想通过输出的方式,总结所学的知识,那么就开始吧。 项目链接 如果能帮到你,希望你能给我点个赞或评论吧~

开发项目需要借助一个好的工具,因此我的开发环境是

objectivec 复制代码
macOS Ventura 13.2.x
CLion 

CLion 创建项目后会自动生成一个CMakeLists.text的文件,主要构建项目的编译逻辑就在这个文件中,CLion生成一个新的项目后,在CMakeLists.text会生成一些基础代码,如下:

js 复制代码
cmake_minimum_required(VERSION 3.25)  
project(CmakeDemo)  
  
set(CMAKE_CXX_STANDARD 17)  
  
add_executable(CmakeDemo main.cpp)
  • cmake_minimum_required(VERSION 3.25) 表示CMake最小版本号, 运行的CMake版本要大于或等于该版本号
  • project(CmakeDemo) CmakeDemo表示项目名称,
  • project(CmakeDemo VERSION 1.0.0)该语句还可以定义项目的版本号
  • set(CMAKE_CXX_STANDARD 17) 表示项目编译语言和版本,这里表示支持 C++ 17语言标准
  • add_executable(CmakeDemo main.cpp) 添加执行文件,比如 main.cpp

简单的项目构建就完成了,不过十分简单还不满足用于项目。 因此我们需要一个大致完整的项目结构,一个项目主要分为src源文件、deps第三方依赖库、resource图片字体等资源,因此如下文件结构:

css 复制代码
├── deps
├── resources
└── src
    ├── CMakeLists.txt
    ├── hello.hpp
    ├── test1.hpp
    ├── test3.cpp
    └── test3.hpp

src

首先从src源文件开始,分为两种情况:

  • 如果src只有头文件,那么在主目录中的CMakeLists.text如下设置:

    js 复制代码
    file(GLOB SRC_FILE src/*.hpp) # GLOB 表示将所有.hpp结尾的文件都存入`SRC_FILE`这个变量中
    add_executable(CmakeDemo main.cpp ${SRC_FILE})
    target_include_directories(${PROJECT_NAME} PRIVATE src) # src 为路径名称

    那么就可以通过#include "hello.hpp"进行调用

  • 如果src包含头文件和源文件cpp的话,那么可以在目录中创建CMakeLists.text来管理该文件的构建,在src/CMakeLists.text可以这样写

js 复制代码
set(SRC_FILES  
       hello.hpp  
       test3.cpp  
       test3.hpp  
       test1.hpp  
       )  
 
add_library(src_lib ${SRC_FILES})  #
target_include_directories(src_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
  • add_library: 将路径中文件创建一个名为src_lib的库
  • target_include_directories:这个设置会将src目录的路径添加到src_library(这是在目录中创建的可执行文件或其他目标)的头文件搜索路径中。这样,在项目中的任何源文件中,都可以使用#include包含src目录中的头文件,例如:#include "hello.hpp".
  • 然后在主目录的CMakeLists.text 设置以下语句即可:
js 复制代码
add_subdirectory(src)  
  
add_executable(CmakeDemo main.cpp)  
// 该语句需要在add_executable 下面
target_link_libraries(${PROJECT_NAME} PRIVATE src_lib)
  • add_subdirectory: 添加子目录src
  • target_link_libraries: 将生成的库src_lib连接到项目中 最后简单的子目录构建编译就完成了

deps 第三方库的添加

第三方库添加入项目主要分为源码git submodelfind_package等等,这里只总结源码和find_package两种情况

源码

项目创建一个名为deps的文件主要存放第三方库的源码,因为我是创建OpenGL的相关的项目,需要用到gladglm库,以这两个库为例子。

点击构建按钮创建所需版本的glad项目,最后下载下来得到一份glad的源码。 我们直接拖进项目中的deps目录中即可。 CMakeLists.text新增glad和glm库的设置

js 复制代码
# glad  
## 添加源文件生成一个库  
add_library(glad deps/glad/src/glad.c)  
# 定义目标索引位置  
target_include_directories(glad PUBLIC deps/glad/include)

#glm  
add_subdirectory(deps/glm)  
## 创建一个库并生成别名  
add_library(glm:glm ALIAS glm)

# 链接库到主项目中
target_link_libraries(${PROJECT_NAME} PRIVATE glad glm:glm)
  • glad:根据源文件glad.c生成一个名为glad的库,并定义目标索引位置供项目方便调用,并最终链接到主项目中
  • glm:首先添加子目录文件,最后target_link_libraries链接到主项目中, 至此源码导入工程就完成了.
  • 总结:
    • 一般第三方库没有CMakeLists.text 文件的话,那么就要我们自己添加源文件(.cpp)生成一个库,并且定义目标索引位置方便查找。一般是src和include两个文件的处理。
    • 第三方库提供CMakeLists.text处理文件构建的话,那么我们只需要构建子目录add_subdirectory并根据子目录CMakeLists.text中生成库的名称例如glm,链接到主项目中。

源码的方式适用于无法通过find_package语句搜索到的第三方库或者自定义的库中使用,而一般比较出名的第三方都可以通过find_package进行依赖使用。

find_package

find_package 的作用是引入外部依赖包,通过CMake内置模块导入依赖库,这些库可以在/usr/local/Cellar/cmake/3.22.3/share/cmake/Modules CMake的安装路径中可以查找到,/usr/local/Cellar是我的路径,你可以根据你自己的路径查找出来。在Modules的文件下,每个以Find<LibaryName>.cmake命名的文件都可以帮我们找到一个包,例如`FindOpenGL.cmake就是OpenGL的库。使用方式也很简单:

js 复制代码
# OpenGL  
find_package(OpenGL REQUIRED) # REQUIRED:必须的意思  
# FreeType  
find_package(Freetype REQUIRED)  
# glfw3  
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)  
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)  
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)  
find_package(glfw3 3.3 REQUIRED)

### 部分省略,可以看源码

target_link_libraries(${PROJECT_NAME} PRIVATE src_lib glad glfw glm OpenGL::GL Freetype::Freetype )

glfw3 3.3Freetype这些名称都是由库自身的官方提供,或者CMake 官方内置提供。

这种方式就比较方便,不需要自己去链接文件和生成库处理,find_package还可以查找你的系统文件夹或者系统库。如果在CMakeModule文件中没有找到需要的库,也可以自行安装(只对支持CMake编译安装的库有效),具体方式这里就不展开了,详情可以网上搜索find_package引入非官方的库

如何导入资源

在开发过程中,经常会用到图片、字体、或者着色器等资源文件,那么我们也需要在CMake构建中处理这些资源文件。当前资源目录如下:

js 复制代码
├── resources
│   └── fonts
│       ├── Songti.ttc
│       ├── antoniolight.ttf
│       └── jianti.ttf

图片、字体、着色器资源都可以向上述目录路径放置,在CMakeLists.text的处理也是十分简单:

js 复制代码
add_custom_command( TARGET ${PROJECT_NAME} POST_BUILD  
COMMAND ${CMAKE_COMMAND} -E copy_directory  
${CMAKE_SOURCE_DIR}/resources  
$<TARGET_FILE_DIR:${PROJECT_NAME}>/resources  
)

add_custom_command 这种方式有一个好处就是,每次添加文件的时候不需要执行一次CMake,而是放在编译的时候去执行,因此可以直接添加所需文件执行程序即可。

主文件中的CMakeLists.text文件内容如下:

js 复制代码
cmake_minimum_required(VERSION 3.25)  
project(CmakeDemo VERSION 1.0.0)  
  
set(CMAKE_CXX_STANDARD 17)  
  
# OpenGL  
find_package(OpenGL REQUIRED) # REQUIRED:必须的意思  
# FreeType  
find_package(Freetype REQUIRED)  
# glfw3  
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)  
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)  
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)  
find_package(glfw3 3.3 REQUIRED)  
# glad  
## 添加源文件生成一个库  
add_library(glad deps/glad/src/glad.c)  
# 定义目标索引位置  
target_include_directories(glad PUBLIC deps/glad/include)  
#glm  
add_subdirectory(deps/glm)   
  
add_subdirectory(src)  
  
add_executable(CmakeDemo main.cpp)  
  
add_custom_command( TARGET ${PROJECT_NAME} POST_BUILD  
COMMAND ${CMAKE_COMMAND} -E copy_directory  
${CMAKE_SOURCE_DIR}/resources  
$<TARGET_FILE_DIR:${PROJECT_NAME}>/resources  
)  
  
target_link_libraries(${PROJECT_NAME} PRIVATE src_lib glad glfw glm OpenGL::GL Freetype::Freetype )

总结

经过srcdepsresource三个模块的构建之后就得出一个基础开发的环境,同时根据自己的需求在里面添砖加瓦。

CMake这个构建项目工具我也是第一次使用,还有很多知识点的缺少,想要深入理解还需要查看CMake的文档,不过这篇文章我相信足够一般基础的使用,最后希望能帮你吧!

项目链接: 如果能帮到你,希望你能给我点个赞或评论吧~

相关推荐
愈努力俞幸运5 分钟前
c++ 头文件
开发语言·c++
~山有木兮17 分钟前
C++设计模式 - 单例模式
c++·单例模式·设计模式
十五年专注C++开发29 分钟前
CMake基础:gcc/g++编译选项详解
开发语言·c++·gcc·g++
HUN金克斯1 小时前
C++/C函数
c语言·开发语言·c++
慢半拍iii1 小时前
数据结构——F/图
c语言·开发语言·数据结构·c++
iceslime2 小时前
旅行商问题(TSP)的 C++ 动态规划解法教学攻略
数据结构·c++·算法·算法设计与分析
虾球xz2 小时前
CppCon 2015 学习:3D Face Tracking and Reconstruction using Modern C++
开发语言·c++·学习·3d
small_wh1te_coder3 小时前
c语言超详细知识点总结 1500行手写源码 持续更新中ing 从25年5月到6月5日
c++·c
SteveDraw4 小时前
C++动态链接库封装,供C#/C++ 等编程语言使用——C++动态链接库概述(总)
开发语言·c++·c#·封装·动态链接库
十五年专注C++开发5 小时前
设计模式之单例模式(二): 心得体会
开发语言·c++·单例模式·设计模式