为什么我们需要cmake?
Why do we need cmake?
我不明白,为什么我们需要cmake来构建库?如果我的问题很愚蠢,我很抱歉,但我需要在 Widnows 上使用一些库,无论我选择什么库,我都需要构建它 and/or 用 cmake 编译它。它有什么用?为什么我不能只#include "path" 我需要的东西到我的项目中,而不是 compiled/built 同时作为我的项目?
而且,有时我需要安装 Ruby、Perl、Python 所有这些都是一些特定的版本,以便 cmake 可以构建库...为什么我需要这些程序,我会吗只需要它们来构建库或以后在我的项目中也需要它们吗? (具体建库后可以卸载那些程序吗?)
目前在不同平台上用 C++ 构建东西是一团糟。
有几种不同的构建系统,但没有标准的方法来执行此操作。仅提供 visual studio 解决方案无助于 linux 或 mac.
上的编译
如果为 linux 或 mac 添加 makefile,则需要在解决方案和 makefile 之间重复配置。这会导致大量的维护开销。此外,与现有的新工具相比,makefile 并不是真正好的构建工具。
您只有 CMake 库主要是巧合。 CMake 目前是一个流行的选择。
有多种解决方案可以统一构建。 CMake 是一种特殊方式的构建工具。它可以创建 makefile 并构建它们,但如果您愿意,您也可以告诉 cmake 创建一个 visual studio 解决方案。
外部程序也是如此。它们是您使用的库的维护者的选择,代码生成等方面没有标准。
虽然 CMake 可能不是 "the" 解决方案(尽管即将到来的 visual studio 2015 正在集成 cmake 支持)但是 cross-platform 构建系统的趋势越来越大在这个方向。
关于你为什么不能只包含 header 的问题:
很少有库只是 header 并且需要编译。您可以预编译 libs/dlls 并只包含 header + 添加链接器路径。这在 linux 中更容易,因为您可以拥有 -dev
只安装预构建库的包,并且它是 header 通过包管理器。 Windows 原生没有。
或者您必须使用库使用的任何构建工具自行构建它。
简短的回答是你不知道,但没有它可能很难构建项目。
CMake 不构建代码,而是一个构建文件生成器。它由 KitWare(在 2000 年左右的 ITK 项目期间)开发,旨在使跨多个平台的构建代码“更简单”。它不是一种易于使用的语言(Kitware 公开承认这一点),但它统一了 Windows、Mac 和 Linux 在构建代码时所做的不同事情。
- 在Linux上,autoconf通常用于制作构建文件,然后由gcc/g++编译(and/or clang)
- 在 Windows 上,您通常会使用 Visual Studio IDE 并创建他们所谓的“解决方案”,然后由 msvc(Microsoft Visual C++ 编译器)编译
- 关于Mac,我承认我不熟悉所使用的编译器,但我相信这与XCode
有关
CMake 允许您编写一个脚本,您可以使用该脚本在多台机器上构建并为每台机器指定不同的选项。
与 C++ 一样,CMake 分为 traditional/old-style CMake(版本 < 3.x)和现代 CMake(版本 >= 3.0)。 使用现代 CMake。以下为优秀教程:
- Effective CMake, by Daniel Pfeifer, C++Now 2017*
- Modern CMake Patterns, by Matheiu Ropert, CppCon 2017
- Better CMake
- CMake Tutorial
*在 C++Now 2017 大会上获得最有用的演讲奖
按所列顺序观看这些内容。您将了解现代 CMake 的外观(和旧式 CMake)并了解如何
- CMake 帮助您指定构建顺序和依赖项,并且
- 现代 CMake 有助于防止在扩展到更大的项目时产生循环依赖和常见错误。
此外,最后一个视频介绍了 C++ 的 包管理器 (在使用外部库时很有用,例如 Boost
,您可以在其中使用 CMake find_package()
命令),其中最常见的两个是:
一般来说,
将 targets 视为 objects
一个。有两种,executables和libraries,它们是用
“构建”的
add_executable(myexe ...) # Creates an executable target "myexe"
add_library(mylib ...) # Creates a library target "mylib"
- 每个目标都有 属性,它们是目标的变量。但是,它们是用 下划线 指定的,而不是点,并且(通常)使用大写字母
myexe_FOO_PROPERTY # Foo property for myexe target
- 当 运行
时,CMake 中的函数还可以在目标“对象”(底层)上设置一些属性
target_compile_definitions()/features()/options()
target_sources()
target_include_directories()
target_link_libraries()
CMake 是一种命令语言,类似于shell脚本,但没有命令的嵌套或管道.相反
一个。每个命令(函数)在其自己的行上并做一件事
b.所有命令(函数)的参数是 strings
C。除非目标名称明确传递给函数,否则该命令适用于最后创建的目标
add_executable(myexe ...) # Create exe target
target_compile_definitions(...) # Applies to "myexe"
target_include_directories(...) # Applies to "myexe"
# ...etc.
add_library(mylib ...) # Create lib target
target_sources(...) # Applies to "mylib"
# ...etc.
d。命令按从上到下的顺序执行,(注意:如果目标需要另一个目标,则必须先创建目标)
执行范围是当前活动的CMakeLists.txt
文件。使用 add_subdirectory()
命令
可以 运行(添加到范围)附加文件
一个。 这与 shell exec
命令非常相似;当前的 CMake 环境(目标和属性,PRIVATE
属性除外)被“复制”到一个新的范围(“shell”),在那里完成了额外的工作。
b。但是,“环境”是 而不是 shell 环境 (CMake 目标属性不会像 $PATH
那样作为环境变量传递给 shell)。相反,CMake 语言 在 顶级全局范围 CACHE
中维护所有目标和属性
PRIVATE
属性被当前模块使用。 INTERFACE
属性被传递到子目录模块。 PUBLIC
用于当前模块和子模块(属性 适用于当前模块并应用 to/should 被 link 反对它的模块使用。
target_link_libraries
用于 直接模块依赖关系 ,但 它也解决了所有传递依赖关系。这意味着当您 link 到一个库时,您也会获得父模块的所有 PUBLIC
属性。
一个。如果你想link到一个有直接路径的库,你可以使用target_link_libraries
、和
b。如果你想 link 到一个带有项目的模块并获取它的接口,你 也可以使用 target_link_libraries
你 运行 CMake on CMakeLists.txt
文件来生成你想要的系统构建文件(ninja
, Visual Studio solution
, Linux make
, 等等)和 运行 那些要编译的和 link 代码。
我不明白,为什么我们需要cmake来构建库?如果我的问题很愚蠢,我很抱歉,但我需要在 Widnows 上使用一些库,无论我选择什么库,我都需要构建它 and/or 用 cmake 编译它。它有什么用?为什么我不能只#include "path" 我需要的东西到我的项目中,而不是 compiled/built 同时作为我的项目?
而且,有时我需要安装 Ruby、Perl、Python 所有这些都是一些特定的版本,以便 cmake 可以构建库...为什么我需要这些程序,我会吗只需要它们来构建库或以后在我的项目中也需要它们吗? (具体建库后可以卸载那些程序吗?)
目前在不同平台上用 C++ 构建东西是一团糟。
有几种不同的构建系统,但没有标准的方法来执行此操作。仅提供 visual studio 解决方案无助于 linux 或 mac.
上的编译如果为 linux 或 mac 添加 makefile,则需要在解决方案和 makefile 之间重复配置。这会导致大量的维护开销。此外,与现有的新工具相比,makefile 并不是真正好的构建工具。
您只有 CMake 库主要是巧合。 CMake 目前是一个流行的选择。
有多种解决方案可以统一构建。 CMake 是一种特殊方式的构建工具。它可以创建 makefile 并构建它们,但如果您愿意,您也可以告诉 cmake 创建一个 visual studio 解决方案。
外部程序也是如此。它们是您使用的库的维护者的选择,代码生成等方面没有标准。
虽然 CMake 可能不是 "the" 解决方案(尽管即将到来的 visual studio 2015 正在集成 cmake 支持)但是 cross-platform 构建系统的趋势越来越大在这个方向。
关于你为什么不能只包含 header 的问题:
很少有库只是 header 并且需要编译。您可以预编译 libs/dlls 并只包含 header + 添加链接器路径。这在 linux 中更容易,因为您可以拥有 -dev
只安装预构建库的包,并且它是 header 通过包管理器。 Windows 原生没有。
或者您必须使用库使用的任何构建工具自行构建它。
简短的回答是你不知道,但没有它可能很难构建项目。
CMake 不构建代码,而是一个构建文件生成器。它由 KitWare(在 2000 年左右的 ITK 项目期间)开发,旨在使跨多个平台的构建代码“更简单”。它不是一种易于使用的语言(Kitware 公开承认这一点),但它统一了 Windows、Mac 和 Linux 在构建代码时所做的不同事情。
- 在Linux上,autoconf通常用于制作构建文件,然后由gcc/g++编译(and/or clang)
- 在 Windows 上,您通常会使用 Visual Studio IDE 并创建他们所谓的“解决方案”,然后由 msvc(Microsoft Visual C++ 编译器)编译
- 关于Mac,我承认我不熟悉所使用的编译器,但我相信这与XCode 有关
CMake 允许您编写一个脚本,您可以使用该脚本在多台机器上构建并为每台机器指定不同的选项。
与 C++ 一样,CMake 分为 traditional/old-style CMake(版本 < 3.x)和现代 CMake(版本 >= 3.0)。 使用现代 CMake。以下为优秀教程:
- Effective CMake, by Daniel Pfeifer, C++Now 2017*
- Modern CMake Patterns, by Matheiu Ropert, CppCon 2017
- Better CMake
- CMake Tutorial
*在 C++Now 2017 大会上获得最有用的演讲奖
按所列顺序观看这些内容。您将了解现代 CMake 的外观(和旧式 CMake)并了解如何
- CMake 帮助您指定构建顺序和依赖项,并且
- 现代 CMake 有助于防止在扩展到更大的项目时产生循环依赖和常见错误。
此外,最后一个视频介绍了 C++ 的 包管理器 (在使用外部库时很有用,例如 Boost
,您可以在其中使用 CMake find_package()
命令),其中最常见的两个是:
一般来说,
将 targets 视为 objects
一个。有两种,executables和libraries,它们是用
“构建”的
add_executable(myexe ...) # Creates an executable target "myexe"
add_library(mylib ...) # Creates a library target "mylib"
- 每个目标都有 属性,它们是目标的变量。但是,它们是用 下划线 指定的,而不是点,并且(通常)使用大写字母
myexe_FOO_PROPERTY # Foo property for myexe target
- 当 运行 时,CMake 中的函数还可以在目标“对象”(底层)上设置一些属性
target_compile_definitions()/features()/options()
target_sources()
target_include_directories()
target_link_libraries()
CMake 是一种命令语言,类似于shell脚本,但没有命令的嵌套或管道.相反
一个。每个命令(函数)在其自己的行上并做一件事
b.所有命令(函数)的参数是 strings
C。除非目标名称明确传递给函数,否则该命令适用于最后创建的目标
add_executable(myexe ...) # Create exe target
target_compile_definitions(...) # Applies to "myexe"
target_include_directories(...) # Applies to "myexe"
# ...etc.
add_library(mylib ...) # Create lib target
target_sources(...) # Applies to "mylib"
# ...etc.
d。命令按从上到下的顺序执行,(注意:如果目标需要另一个目标,则必须先创建目标)
执行范围是当前活动的
可以 运行(添加到范围)附加文件CMakeLists.txt
文件。使用add_subdirectory()
命令一个。 这与 shell
exec
命令非常相似;当前的 CMake 环境(目标和属性,PRIVATE
属性除外)被“复制”到一个新的范围(“shell”),在那里完成了额外的工作。b。但是,“环境”是 而不是 shell 环境 (CMake 目标属性不会像
中维护所有目标和属性$PATH
那样作为环境变量传递给 shell)。相反,CMake 语言 在 顶级全局范围CACHE
PRIVATE
属性被当前模块使用。INTERFACE
属性被传递到子目录模块。PUBLIC
用于当前模块和子模块(属性 适用于当前模块并应用 to/should 被 link 反对它的模块使用。target_link_libraries
用于 直接模块依赖关系 ,但 它也解决了所有传递依赖关系。这意味着当您 link 到一个库时,您也会获得父模块的所有PUBLIC
属性。一个。如果你想link到一个有直接路径的库,你可以使用
target_link_libraries
、和b。如果你想 link 到一个带有项目的模块并获取它的接口,你 也可以使用
target_link_libraries
你 运行 CMake on CMakeLists.txt
文件来生成你想要的系统构建文件(ninja
, Visual Studio solution
, Linux make
, 等等)和 运行 那些要编译的和 link 代码。