Why does CMake make a distinction between a “target” and a “command”?

前端 未结 2 1243
悲哀的现实
悲哀的现实 2021-01-30 08:07

In CMake semantics there is some sort of distinction between \"targets\" and commands\" that is baffling me. In Makefiles, there is no such distinction:

targetn         


        
2条回答
  •  温柔的废话
    2021-01-30 08:47

    Targets

    In general, targets comprise executables or libraries which are defined by calling add_executable or add_library and which can have many properties set.

    They can have dependencies on one another, which for targets such as these just means that dependent ones will be built after their dependencies.

    However, you can also define "custom targets" via add_custom_target. From the docs:

    Adds a target with the given name that executes the given commands. The target has no output file and is ALWAYS CONSIDERED OUT OF DATE even if the commands try to create a file with the name of the target. Use ADD_CUSTOM_COMMAND to generate a file with dependencies. By default nothing depends on the custom target. Use ADD_DEPENDENCIES to add dependencies to or from other targets.

    So these are different from "normal" targets in that they don't represent things which will produce an exe or lib, but they still benefit from all the properties that targets can have, including having or being dependencies. They appear as a target which can be built (e.g. make MyCustomTarget or msbuild MyCustomTarget.vcxproj). When you build them, you're simply invoking the commands that have been set for them. If they have dependencies on other targets (normal or custom), then these will be built first.


    Custom Commands

    A custom command defined via add_custom_command is quite different in that it's not a "buildable" object, and doesn't have settable properties in the way that a target does - it's not a named object which can be explicitly referred to again after it's added in the CMakeLists.txt.

    It is basically a command (or set of commands) which will be invoked before building a dependent target. That's all that "depends" really means here (at least that's how I view it) - it's just saying that if A depends on B, then B will be built/executed before A is built.

    The dependees of a custom command can be either set explicitly using the add_custom_command(TARGET target ... form, or implicitly by creating targets which include the files generated via the add_custom_command(OUTPUT output1 ... form.

    In the first case, every time target is built, the custom command is executed first.

    In the second case, it's a little more complex. If the custom command has targets which depend on its output file (and the output file doesn't already exist), it is invoked before these dependent objects are built. The dependencies are implicitly created when you do e.g. add_library(MyLib output1.h ... ) where output1.h is a file generated via add_custom_command(OUTPUT output1.h ... ).

提交回复
热议问题