ProcessorCount.cmake 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. # - ProcessorCount(var)
  2. # Determine the number of processors/cores and save value in ${var}
  3. #
  4. # Sets the variable named ${var} to the number of physical cores available on
  5. # the machine if the information can be determined. Otherwise it is set to 0.
  6. # Currently this functionality is implemented for AIX, cygwin, FreeBSD, HPUX,
  7. # IRIX, Linux, Mac OS X, QNX, Sun and Windows.
  8. #
  9. # This function is guaranteed to return a positive integer (>=1) if it
  10. # succeeds. It returns 0 if there's a problem determining the processor count.
  11. #
  12. # Example use, in a ctest -S dashboard script:
  13. #
  14. # include(ProcessorCount)
  15. # ProcessorCount(N)
  16. # if(NOT N EQUAL 0)
  17. # set(CTEST_BUILD_FLAGS -j${N})
  18. # set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N})
  19. # endif()
  20. #
  21. # This function is intended to offer an approximation of the value of the
  22. # number of compute cores available on the current machine, such that you
  23. # may use that value for parallel building and parallel testing. It is meant
  24. # to help utilize as much of the machine as seems reasonable. Of course,
  25. # knowledge of what else might be running on the machine simultaneously
  26. # should be used when deciding whether to request a machine's full capacity
  27. # all for yourself.
  28. # A more reliable way might be to compile a small C program that uses the CPUID
  29. # instruction, but that again requires compiler support or compiling assembler
  30. # code.
  31. #=============================================================================
  32. # Copyright 2010-2011 Kitware, Inc.
  33. #
  34. # Distributed under the OSI-approved BSD License (the "License");
  35. # see accompanying file Copyright.txt for details.
  36. #
  37. # This software is distributed WITHOUT ANY WARRANTY; without even the
  38. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  39. # See the License for more information.
  40. #=============================================================================
  41. # (To distribute this file outside of CMake, substitute the full
  42. # License text for the above reference.)
  43. function(ProcessorCount var)
  44. # Unknown:
  45. set(count 0)
  46. if(WIN32)
  47. # Windows:
  48. set(count "$ENV{NUMBER_OF_PROCESSORS}")
  49. #message("ProcessorCount: WIN32, trying environment variable")
  50. endif()
  51. if(NOT count)
  52. # Mac, FreeBSD, OpenBSD (systems with sysctl):
  53. find_program(ProcessorCount_cmd_sysctl sysctl
  54. PATHS /usr/sbin /sbin)
  55. if(ProcessorCount_cmd_sysctl)
  56. execute_process(COMMAND ${ProcessorCount_cmd_sysctl} -n hw.ncpu
  57. ERROR_QUIET
  58. OUTPUT_STRIP_TRAILING_WHITESPACE
  59. OUTPUT_VARIABLE count)
  60. #message("ProcessorCount: trying sysctl '${ProcessorCount_cmd_sysctl}'")
  61. endif()
  62. endif()
  63. if(NOT count)
  64. # Linux (systems with getconf):
  65. find_program(ProcessorCount_cmd_getconf getconf)
  66. if(ProcessorCount_cmd_getconf)
  67. execute_process(COMMAND ${ProcessorCount_cmd_getconf} _NPROCESSORS_ONLN
  68. ERROR_QUIET
  69. OUTPUT_STRIP_TRAILING_WHITESPACE
  70. OUTPUT_VARIABLE count)
  71. #message("ProcessorCount: trying getconf '${ProcessorCount_cmd_getconf}'")
  72. endif()
  73. endif()
  74. if(NOT count)
  75. # HPUX (systems with machinfo):
  76. find_program(ProcessorCount_cmd_machinfo machinfo
  77. PATHS /usr/contrib/bin)
  78. if(ProcessorCount_cmd_machinfo)
  79. execute_process(COMMAND ${ProcessorCount_cmd_machinfo}
  80. ERROR_QUIET
  81. OUTPUT_STRIP_TRAILING_WHITESPACE
  82. OUTPUT_VARIABLE machinfo_output)
  83. string(REGEX MATCHALL "Number of CPUs = ([0-9]+)" procs "${machinfo_output}")
  84. set(count "${CMAKE_MATCH_1}")
  85. #message("ProcessorCount: trying machinfo '${ProcessorCount_cmd_machinfo}'")
  86. endif()
  87. endif()
  88. if(NOT count)
  89. # IRIX (systems with hinv):
  90. find_program(ProcessorCount_cmd_hinv hinv
  91. PATHS /sbin)
  92. if(ProcessorCount_cmd_hinv)
  93. execute_process(COMMAND ${ProcessorCount_cmd_hinv}
  94. ERROR_QUIET
  95. OUTPUT_STRIP_TRAILING_WHITESPACE
  96. OUTPUT_VARIABLE hinv_output)
  97. string(REGEX MATCHALL "([0-9]+) .* Processors" procs "${hinv_output}")
  98. set(count "${CMAKE_MATCH_1}")
  99. #message("ProcessorCount: trying hinv '${ProcessorCount_cmd_hinv}'")
  100. endif()
  101. endif()
  102. if(NOT count)
  103. # AIX (systems with lsconf):
  104. find_program(ProcessorCount_cmd_lsconf lsconf
  105. PATHS /usr/sbin)
  106. if(ProcessorCount_cmd_lsconf)
  107. execute_process(COMMAND ${ProcessorCount_cmd_lsconf}
  108. ERROR_QUIET
  109. OUTPUT_STRIP_TRAILING_WHITESPACE
  110. OUTPUT_VARIABLE lsconf_output)
  111. string(REGEX MATCHALL "Number Of Processors: ([0-9]+)" procs "${lsconf_output}")
  112. set(count "${CMAKE_MATCH_1}")
  113. #message("ProcessorCount: trying lsconf '${ProcessorCount_cmd_lsconf}'")
  114. endif()
  115. endif()
  116. if(NOT count)
  117. # QNX (systems with pidin):
  118. find_program(ProcessorCount_cmd_pidin pidin)
  119. if(ProcessorCount_cmd_pidin)
  120. execute_process(COMMAND ${ProcessorCount_cmd_pidin} info
  121. ERROR_QUIET
  122. OUTPUT_STRIP_TRAILING_WHITESPACE
  123. OUTPUT_VARIABLE pidin_output)
  124. string(REGEX MATCHALL "Processor[0-9]+: " procs "${pidin_output}")
  125. list(LENGTH procs count)
  126. #message("ProcessorCount: trying pidin '${ProcessorCount_cmd_pidin}'")
  127. endif()
  128. endif()
  129. if(NOT count)
  130. # Sun (systems where uname -X emits "NumCPU" in its output):
  131. find_program(ProcessorCount_cmd_uname uname)
  132. if(ProcessorCount_cmd_uname)
  133. execute_process(COMMAND ${ProcessorCount_cmd_uname} -X
  134. ERROR_QUIET
  135. OUTPUT_STRIP_TRAILING_WHITESPACE
  136. OUTPUT_VARIABLE uname_X_output)
  137. string(REGEX MATCHALL "NumCPU = ([0-9]+)" procs "${uname_X_output}")
  138. set(count "${CMAKE_MATCH_1}")
  139. #message("ProcessorCount: trying uname -X '${ProcessorCount_cmd_uname}'")
  140. endif()
  141. endif()
  142. # Execute this code when all previously attempted methods return empty
  143. # output:
  144. #
  145. if(NOT count)
  146. # Systems with /proc/cpuinfo:
  147. set(cpuinfo_file /proc/cpuinfo)
  148. if(EXISTS "${cpuinfo_file}")
  149. file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$")
  150. list(LENGTH procs count)
  151. #message("ProcessorCount: trying cpuinfo '${cpuinfo_file}'")
  152. endif()
  153. endif()
  154. # Since cygwin builds of CMake do not define WIN32 anymore, but they still
  155. # run on Windows, and will still have this env var defined:
  156. #
  157. if(NOT count)
  158. set(count "$ENV{NUMBER_OF_PROCESSORS}")
  159. #message("ProcessorCount: last fallback, trying environment variable")
  160. endif()
  161. # Ensure an integer return (avoid inadvertently returning an empty string
  162. # or an error string)... If it's not a decimal integer, return 0:
  163. #
  164. if(NOT count MATCHES "^[0-9]+$")
  165. set(count 0)
  166. endif()
  167. set(${var} ${count} PARENT_SCOPE)
  168. endfunction()