CMP0058.rst 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. CMP0058
  2. -------
  3. .. versionadded:: 3.3
  4. Ninja requires custom command byproducts to be explicit.
  5. When an intermediate file generated during the build is consumed
  6. by an expensive operation or a large tree of dependents, one may
  7. reduce the work needed for an incremental rebuild by updating the
  8. file timestamp only when its content changes. With this approach
  9. the generation rule must have a separate output file that is always
  10. updated with a new timestamp that is newer than any dependencies of
  11. the rule so that the build tool re-runs the rule only when the input
  12. changes. We refer to the separate output file as a rule's *witness*
  13. and the generated file as a rule's *byproduct*.
  14. Byproducts may not be listed as outputs because their timestamps are
  15. allowed to be older than the inputs. No build tools (like ``make``)
  16. that existed when CMake was designed have a way to express byproducts.
  17. Therefore CMake versions prior to 3.2 had no way to specify them.
  18. Projects typically left byproducts undeclared in the rules that
  19. generate them. For example:
  20. .. code-block:: cmake
  21. add_custom_command(
  22. OUTPUT witness.txt
  23. COMMAND ${CMAKE_COMMAND} -E copy_if_different
  24. ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
  25. byproduct.txt # timestamp may not change
  26. COMMAND ${CMAKE_COMMAND} -E touch witness.txt
  27. DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
  28. )
  29. add_custom_target(Provider DEPENDS witness.txt)
  30. add_custom_command(
  31. OUTPUT generated.c
  32. COMMAND expensive-task -i byproduct.txt -o generated.c
  33. DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/byproduct.txt
  34. )
  35. add_library(Consumer generated.c)
  36. add_dependencies(Consumer Provider)
  37. This works well for all generators except :generator:`Ninja`.
  38. The Ninja build tool sees a rule listing ``byproduct.txt``
  39. as a dependency and no rule listing it as an output. Ninja then
  40. complains that there is no way to satisfy the dependency and
  41. stops building even though there are order-only dependencies
  42. that ensure ``byproduct.txt`` will exist before its consumers
  43. need it. See discussion of this problem in `Ninja Issue 760`_
  44. for further details on why Ninja works this way.
  45. .. _`Ninja Issue 760`: https://github.com/martine/ninja/issues/760
  46. Instead of leaving byproducts undeclared in the rules that generate
  47. them, Ninja expects byproducts to be listed along with other outputs.
  48. Such rules may be marked with a ``restat`` option that tells Ninja
  49. to check the timestamps of outputs after the rules run. This
  50. prevents byproducts whose timestamps do not change from causing
  51. their dependents to re-build unnecessarily.
  52. Since the above approach does not tell CMake what custom command
  53. generates ``byproduct.txt``, the Ninja generator does not have
  54. enough information to add the byproduct as an output of any rule.
  55. CMake 2.8.12 and above work around this problem and allow projects
  56. using the above approach to build by generating ``phony`` build
  57. rules to tell Ninja to tolerate such missing files. However, this
  58. workaround prevents Ninja from diagnosing a dependency that is
  59. really missing. It also works poorly in in-source builds where
  60. every custom command dependency, even on source files, needs to
  61. be treated this way because CMake does not have enough information
  62. to know which files are generated as byproducts of custom commands.
  63. CMake 3.2 introduced the ``BYPRODUCTS`` option to the
  64. :command:`add_custom_command` and :command:`add_custom_target`
  65. commands. This option allows byproducts to be specified explicitly:
  66. .. code-block:: cmake
  67. add_custom_command(
  68. OUTPUT witness.txt
  69. BYPRODUCTS byproduct.txt # explicit byproduct specification
  70. COMMAND ${CMAKE_COMMAND} -E copy_if_different
  71. ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
  72. byproduct.txt # timestamp may not change
  73. ...
  74. The ``BYPRODUCTS`` option is used by the :generator:`Ninja` generator
  75. to list byproducts among the outputs of the custom commands that
  76. generate them, and is ignored by other generators.
  77. CMake 3.3 and above prefer to require projects to specify custom
  78. command byproducts explicitly so that it can avoid using the
  79. ``phony`` rule workaround altogether. Policy ``CMP0058`` was
  80. introduced to provide compatibility with existing projects that
  81. still need the workaround.
  82. This policy has no effect on generators other than :generator:`Ninja`.
  83. The ``OLD`` behavior for this policy is to generate Ninja ``phony``
  84. rules for unknown dependencies in the build tree. The ``NEW``
  85. behavior for this policy is to not generate these and instead
  86. require projects to specify custom command ``BYPRODUCTS`` explicitly.
  87. This policy was introduced in CMake version 3.3.
  88. CMake version |release| warns when it sees unknown dependencies in
  89. out-of-source build trees if the policy is not set and then uses
  90. ``OLD`` behavior. Use the :command:`cmake_policy` command to set
  91. the policy to ``OLD`` or ``NEW`` explicitly. The policy setting
  92. must be in scope at the end of the top-level ``CMakeLists.txt``
  93. file of the project and has global effect.
  94. .. include:: DEPRECATED.txt