CMP0058.rst 4.9 KB

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