为什么CMake区分“目标”和“命令”?

在CMake语义中,“目标”和“命令”之间存在某种区别,这让我们感到困惑。在Makefiles中,没有这样的区别:

targetname:dependency command 

即目标对应于同名的生成文件。

在CMake中,你有类似于“add_custom_command”和“add_custom_target”这样具有重叠function的命令,即使在官方文档中,语义也是混淆的,即在“添加自定义目标”下的“掌握CMake,第5版”

DEPENDS参数设置自定义目标和自定义命令之间的依赖关系。

我的理解是,目标(生成的文件)具有依赖关系(其他文件,生成或不),以及一个命令来实际生成。 说一个目标取决于一个命令是无稽之谈。 更糟的是,有两种types的“add_custom_command”可以将一个额外的命令附加到一个已经存在的目标上,或者将命令吐出来。

有人可以解释为什么这种区别甚至存在?

目标

通常,目标包括通过调用add_executableadd_library来定义的可执行文件或库,并且可以有许多属性设置。

他们之间可能有依赖关系,对于这样的目标来说,就意味着依赖关系会依赖于依赖关系。

但是,您也可以通过add_custom_target定义“自定义目标”。 从文档:

添加一个执行给定命令的给定名称的目标。 目标没有输出文件,即使命令尝试使用目标名称创build文件,也总是被认为是在date之外。 使用ADD_CUSTOM_COMMAND生成一个具有依赖关系的文件。 默认情况下,什么都不依赖于自定义目标 使用ADD_DEPENDENCIES向其他目标添加依赖关系。

所以这些不同于“正常”的目标,因为它们不代表会产生exe或lib的东西,但是它们仍然从目标可以拥有的所有属性中受益,包括拥有或者是依赖。 它们显示为可以构build的目标(例如, make MyCustomTargetmsbuild MyCustomTarget.vcxproj )。 在构build它们时,只需调用为其设置的命令即可。 如果他们依赖于其他目标(正常或习惯),那么这些将被首先build立。

自定义命令

通过add_custom_command定义的一个自定义命令是非常不同的,因为它不是一个“可构build的”对象,并且没有可设置的属性,不像目标所做的那样 – 它不是一个命名的对象,它可以在添加后被明确地引用CMakeLists.txt。

它基本上是一个命令(或一组命令),它将在构build一个依赖目标之前被调用。 这就是所谓“依赖”在这里的真正意义(至less这是我如何看待它) – 这只是说,如果A依赖于B,那么B将在A构build之前被构build/执行。

自定义命令的依赖项可以使用add_custom_command(TARGET target ... form)显式设置,也可以通过创build包含通过add_custom_command(OUTPUT output1 ... form)生成的文件的目标来隐式设置。

在第一种情况下,每次构buildtarget ,都会首先执行自定义命令。

在第二种情况下,它更复杂一点。 如果自定义命令具有依赖于其输出文件的目标(并且输出文件尚不存在),则会在构build这些依赖对象之前调用它。 当你做add_library(MyLib output1.h ... ) ,隐式创build依赖关系,其中output1.h是通过add_custom_command(OUTPUT output1.h ... )生成的文件。