[CMake翻译]CMake目标

133 阅读5分钟

原文地址:thatonegamedev.com/cpp/cmake-t…

原文作者:thatonegamedev.com/

发布时间:2021年01月08日

当使用任何一种编程语言时,你通常可以选择创建某种可执行文件或库。可执行文件是最终产品--你运行的东西,然后它执行逻辑并返回一个结果--创建一个窗口,运行一个游戏,输出计算,显示东西,等等。库是可重复使用的编译代码,可以编译到其他应用程序中。

在你开始之前

本文要求你有一定的基础知识。

程式库

对于你的C/C++项目来说,主要有两种类型的目标。让我们从库开始,因为它是可执行文件的构建模块。库包含了你写的代码,你想在多个项目之间共享。在互联网上,你可以找到许多由其他人维护的项目库。使用库可以为你节省大量的时间和精力来学习如何制作某些东西。

你也可以自己编写库。在C/C++中,用库写代码还有其他好处。

其中一个好处是可以测试你的代码。在一个单独的库上配置单元/集成测试比在一个可执行文件上配置单元/集成测试要容易得多。

另一个主要的好处是,你可以将你的代码分割成有意义的块。以后如果你在另一个项目中工作,你可以把这些块分开,然后把你需要的和可重用的分开。

静态与动态

在创建一个库时,你有两个选择--使其成为静态或动态。我知道动态链接的选择只有在Windows上才有,但这对每个人来说都是有用的。

静态库产生一个单一的文件,你可以在以后将其链接到可执行文件中(阅读更多关于编译和链接的内容)。静态链接意味着lib文件的内容将被编译到最终的可执行文件中。这在构建可执行文件的过程中需要更多的时间,并且产生一个更大的可执行文件,但从长远来看,应用程序将运行得更快。

动态库会产生两个文件--一个是空心的、只有引用的静态库,另一个是应该沿着可执行文件复制的动态库。静态库将在链接过程中使用,并将产生一个较小的可执行文件,并将有一个更快的构建时间。动态库将在运行时被评估,并且需要沿着可执行文件(通常在同一个文件夹中)。

通常这些库的扩展名会是。( .lib, .bc, .a)代表静态库,( .dll)代表动态库。

对于游戏开发,我的建议是在调试过程中使用动态链接(调试构建),因为你会想要更快的构建时间,而在创建发布构建时使用静态链接。

如何在CMake中创建一个库目标

其实真的很简单。让我们从我常用的库的项目strcuture开始。

libfolder
├── include/
│  └── A.h
├── src/
│  └── A.cpp
└── CMakeLists.txt

你会发现头文件和源文件是分开的。这是为了方便以后复制头文件目录,因为要使用一个库,你通常需要在另一个项目中指定相同的函数签名。最好将函数的定义写在include文件中,并且在另一个项目中可以很容易地使用它们。

project(libfolder LANGUAGES C CXX)

# Creating a static library
# libfolder_static is called a target name and can be used later
add_library(libfolder_static STATIC include/A.h src/A.cpp)

# Creating a dynamic lybrary
# add_library(libfolder_dynamic SHARED include/A.h src/A.cpp)

# This will set include directories for this target
# This means that A.cpp can include A.h by writing
# #include "A.h"
# instead of using relative path like
# #include "../include/A.h"
# 
# Also because we set that to public any other target that links to
# libfolder_static would also have those includes
target_include_directories(libfolder_static
  PUBLIC
  $<INSTALL_INTERFACE:include>
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
  PRIVATE
  ${CMAKE_CURRENT_SOURCE_DIR}/src
)

创建库很简单吧?你也可以针对其他创建的库进行链接。如果其他库是你的整个CMake项目结构的一部分,你可以使用目标名称进行链接(例如,如果你想创建一个名为libfolder2的新库,你可以将libfolder_static链接到其中。另一种方法是直接链接libfolder.lib文件。

project(libfolder2 LANGUAGES C CXX)

add_library(libfolder2_static STATIC include/B.h src/B.cpp)

# Linking against our first target
target_link_libraries(libfolder2_static PUBLIC libfolder_static )

# Or
# target_link_libraries(libfolder2_static PUBLIC libfolder_static.lib)
# if we consider that the lib file is in the current directory. 
# You would still need the include files also...

可执行文件

可执行目标的作用仅仅是创建一个可以被操作系统运行的文件,并执行一组命令然后完成。它们要求有一个可以运行的主函数,否则构建会失败。你可以把库链接到可执行文件中,就像把库链接到其他库一样。

如何在CMake中创建一个可执行文件目标

可执行文件比库更容易创建。你不需要考虑你的代码会被其他目标使用,所以你可以自由地将你的代码只放在一个源目录中(或者为了保持一致性,保持与include目录的结构)。创建一个可执行文件的代码和创建一个库的代码几乎是一样的。

project(exefolder LANGUAGES C CXX)

add_executable(exefolder src/C.cpp src/C.h)

# The libfolder include directories would automatically be included here also
target_link_libraries(exefolder PRIVATE libfolder)

target_include_directories(exefolder PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)

空/自定义目标

CMake也提供了创建其他类型的空目标的选项。它们不会在最后提供一个可执行的库文件,但是它们可以用来运行命令行脚本。它们被称为自定义目标,通常可以直接在其中运行命令。它们也可以被设置为依赖于其他目标。

add_custom_target(mytarget ALL
  COMMENT "Just something to print out when this is run"
  COMMAND <... command line to be run ...>
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_dependencies(mytarget exefolder)

其实要运行命令,你也可以直接使用add_custom_command,必须附加到一个现有的目标上。你也可以这样做来为你的自定义目标添加命令。

结束语

这篇文章涵盖了CMake中项目管理的核心概念之一。有了这些知识,你现在可以正确地使用更现代的方法创建自己的项目。


通过www.DeepL.com/Translator(免费版)翻译