RunCMake.cmake 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. if(NOT DEFINED CMake_SOURCE_DIR)
  2. message(FATAL_ERROR "CMake_SOURCE_DIR not defined")
  3. endif()
  4. if(NOT DEFINED dir)
  5. message(FATAL_ERROR "dir not defined")
  6. endif()
  7. if(NOT DEFINED gen)
  8. message(FATAL_ERROR "gen not defined")
  9. endif()
  10. # Call cmake once to get a baseline/reference output build tree: "Build".
  11. # Then call cmake N more times, each time making a copy of the entire
  12. # build tree after cmake is done configuring/generating. At the end,
  13. # analyze the diffs in the generated build trees. Expect no diffs.
  14. #
  15. message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
  16. set(N 7)
  17. # First setup source and binary trees:
  18. #
  19. execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory
  20. ${dir}/Source
  21. )
  22. execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory
  23. ${dir}/Build
  24. )
  25. execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory
  26. ${CMake_SOURCE_DIR}/Tests/CTestTest/SmallAndFast
  27. ${dir}/Source
  28. )
  29. execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory
  30. ${dir}/Build
  31. )
  32. # Patch SmallAndFast to build a .cxx executable too:
  33. #
  34. execute_process(COMMAND ${CMAKE_COMMAND} -E copy
  35. ${dir}/Source/echoargs.c
  36. ${dir}/Source/echoargs.cxx
  37. )
  38. file(APPEND "${dir}/Source/CMakeLists.txt" "\nadd_executable(echoargsCXX echoargs.cxx)\n")
  39. # Loop N times, saving a copy of the configured/generated build tree each time:
  40. #
  41. foreach(i RANGE 1 ${N})
  42. # Equivalent sequence of shell commands:
  43. #
  44. message(STATUS "${i}: cd Build && cmake -G \"${gen}\" ../Source && cd .. && cp -r Build b${i}")
  45. # Run cmake:
  46. #
  47. execute_process(COMMAND ${CMAKE_COMMAND} -G ${gen} ../Source
  48. RESULT_VARIABLE result
  49. OUTPUT_VARIABLE stdout
  50. ERROR_VARIABLE stderr
  51. WORKING_DIRECTORY ${dir}/Build
  52. )
  53. message(STATUS "result='${result}'")
  54. message(STATUS "stdout='${stdout}'")
  55. message(STATUS "stderr='${stderr}'")
  56. message(STATUS "")
  57. # Save this iteration of the Build directory:
  58. #
  59. execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory
  60. ${dir}/b${i}
  61. )
  62. execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory
  63. ${dir}/Build
  64. ${dir}/b${i}
  65. RESULT_VARIABLE result
  66. OUTPUT_VARIABLE stdout
  67. ERROR_VARIABLE stderr
  68. )
  69. message(STATUS "result='${result}'")
  70. message(STATUS "stdout='${stdout}'")
  71. message(STATUS "stderr='${stderr}'")
  72. message(STATUS "")
  73. endforeach()
  74. # Function to analyze diffs between two directories.
  75. # Set DIFF_EXECUTABLE before calling if 'diff' is available.
  76. #
  77. function(analyze_directory_diffs d1 d2 diff_count_var)
  78. set(diffs 0)
  79. message(STATUS "Analyzing directory diffs between:")
  80. message(STATUS " d1='${d1}'")
  81. message(STATUS " d2='${d2}'")
  82. if(NOT "${d1}" STREQUAL "" AND NOT "${d2}" STREQUAL "")
  83. message(STATUS "info: analyzing directories")
  84. file(GLOB_RECURSE files1 RELATIVE "${d1}" "${d1}/*")
  85. file(GLOB_RECURSE files2 RELATIVE "${d2}" "${d2}/*")
  86. if("${files1}" STREQUAL "${files2}")
  87. message(STATUS "info: file lists the same")
  88. #message(STATUS " files='${files1}'")
  89. foreach(f ${files1})
  90. execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files
  91. ${d1}/${f}
  92. ${d2}/${f}
  93. RESULT_VARIABLE result
  94. OUTPUT_VARIABLE stdout
  95. ERROR_VARIABLE stderr
  96. )
  97. if(result STREQUAL 0)
  98. #message(STATUS "info: file '${f}' the same")
  99. else()
  100. math(EXPR diffs "${diffs} + 1")
  101. message(STATUS "warning: file '${f}' differs from d1 to d2")
  102. file(READ "${d1}/${f}" f1contents)
  103. message(STATUS "contents of file '${d1}/${f}'
  104. [===[${f1contents}]===]")
  105. file(READ "${d2}/${f}" f2contents)
  106. message(STATUS "contents of file '${d2}/${f}'
  107. [===[${f2contents}]===]")
  108. if(DIFF_EXECUTABLE)
  109. message(STATUS "diff of files '${d1}/${f}' '${d2}/${f}'")
  110. message(STATUS "[====[")
  111. execute_process(COMMAND ${DIFF_EXECUTABLE} "${d1}/${f}" "${d2}/${f}")
  112. message(STATUS "]====]")
  113. endif()
  114. endif()
  115. endforeach()
  116. else()
  117. math(EXPR diffs "${diffs} + 1")
  118. message(STATUS "warning: file *lists* differ - some files exist in d1/not-d2 or not-d1/d2...")
  119. message(STATUS " files1='${files1}'")
  120. message(STATUS " files2='${files2}'")
  121. endif()
  122. endif()
  123. set(${diff_count_var} ${diffs} PARENT_SCOPE)
  124. endfunction()
  125. # Analyze diffs between b1:b2, b2:b3, b3:b4, b4:b5 ... bN-1:bN.
  126. # Expect no diffs.
  127. #
  128. find_program(DIFF_EXECUTABLE diff)
  129. set(total_diffs 0)
  130. foreach(i RANGE 2 ${N})
  131. math(EXPR prev "${i} - 1")
  132. set(count 0)
  133. analyze_directory_diffs(${dir}/b${prev} ${dir}/b${i} count)
  134. message(STATUS "diff count='${count}'")
  135. message(STATUS "")
  136. math(EXPR total_diffs "${total_diffs} + ${count}")
  137. endforeach()
  138. message(STATUS "CMAKE_COMMAND='${CMAKE_COMMAND}'")
  139. message(STATUS "total_diffs='${total_diffs}'")