ProcessorCount.cmake 8.7 KB

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