ProcessorCount.cmake 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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. mark_as_advanced(ProcessorCount_cmd_sysctl)
  56. if(ProcessorCount_cmd_sysctl)
  57. execute_process(COMMAND ${ProcessorCount_cmd_sysctl} -n hw.ncpu
  58. ERROR_QUIET
  59. OUTPUT_STRIP_TRAILING_WHITESPACE
  60. OUTPUT_VARIABLE count)
  61. #message("ProcessorCount: trying sysctl '${ProcessorCount_cmd_sysctl}'")
  62. endif()
  63. endif()
  64. if(NOT count)
  65. # Linux (systems with getconf):
  66. find_program(ProcessorCount_cmd_getconf getconf)
  67. mark_as_advanced(ProcessorCount_cmd_getconf)
  68. if(ProcessorCount_cmd_getconf)
  69. execute_process(COMMAND ${ProcessorCount_cmd_getconf} _NPROCESSORS_ONLN
  70. ERROR_QUIET
  71. OUTPUT_STRIP_TRAILING_WHITESPACE
  72. OUTPUT_VARIABLE count)
  73. #message("ProcessorCount: trying getconf '${ProcessorCount_cmd_getconf}'")
  74. endif()
  75. endif()
  76. if(NOT count)
  77. # HPUX (systems with machinfo):
  78. find_program(ProcessorCount_cmd_machinfo machinfo
  79. PATHS /usr/contrib/bin)
  80. mark_as_advanced(ProcessorCount_cmd_machinfo)
  81. if(ProcessorCount_cmd_machinfo)
  82. execute_process(COMMAND ${ProcessorCount_cmd_machinfo}
  83. ERROR_QUIET
  84. OUTPUT_STRIP_TRAILING_WHITESPACE
  85. OUTPUT_VARIABLE machinfo_output)
  86. string(REGEX MATCHALL "Number of CPUs = ([0-9]+)" procs "${machinfo_output}")
  87. set(count "${CMAKE_MATCH_1}")
  88. #message("ProcessorCount: trying machinfo '${ProcessorCount_cmd_machinfo}'")
  89. endif()
  90. endif()
  91. if(NOT count)
  92. # IRIX (systems with hinv):
  93. find_program(ProcessorCount_cmd_hinv hinv
  94. PATHS /sbin)
  95. mark_as_advanced(ProcessorCount_cmd_hinv)
  96. if(ProcessorCount_cmd_hinv)
  97. execute_process(COMMAND ${ProcessorCount_cmd_hinv}
  98. ERROR_QUIET
  99. OUTPUT_STRIP_TRAILING_WHITESPACE
  100. OUTPUT_VARIABLE hinv_output)
  101. string(REGEX MATCHALL "([0-9]+) .* Processors" procs "${hinv_output}")
  102. set(count "${CMAKE_MATCH_1}")
  103. #message("ProcessorCount: trying hinv '${ProcessorCount_cmd_hinv}'")
  104. endif()
  105. endif()
  106. if(NOT count)
  107. # AIX (systems with lsconf):
  108. find_program(ProcessorCount_cmd_lsconf lsconf
  109. PATHS /usr/sbin)
  110. mark_as_advanced(ProcessorCount_cmd_lsconf)
  111. if(ProcessorCount_cmd_lsconf)
  112. execute_process(COMMAND ${ProcessorCount_cmd_lsconf}
  113. ERROR_QUIET
  114. OUTPUT_STRIP_TRAILING_WHITESPACE
  115. OUTPUT_VARIABLE lsconf_output)
  116. string(REGEX MATCHALL "Number Of Processors: ([0-9]+)" procs "${lsconf_output}")
  117. set(count "${CMAKE_MATCH_1}")
  118. #message("ProcessorCount: trying lsconf '${ProcessorCount_cmd_lsconf}'")
  119. endif()
  120. endif()
  121. if(NOT count)
  122. # QNX (systems with pidin):
  123. find_program(ProcessorCount_cmd_pidin pidin)
  124. mark_as_advanced(ProcessorCount_cmd_pidin)
  125. if(ProcessorCount_cmd_pidin)
  126. execute_process(COMMAND ${ProcessorCount_cmd_pidin} info
  127. ERROR_QUIET
  128. OUTPUT_STRIP_TRAILING_WHITESPACE
  129. OUTPUT_VARIABLE pidin_output)
  130. string(REGEX MATCHALL "Processor[0-9]+: " procs "${pidin_output}")
  131. list(LENGTH procs count)
  132. #message("ProcessorCount: trying pidin '${ProcessorCount_cmd_pidin}'")
  133. endif()
  134. endif()
  135. if(NOT count)
  136. # Sun (systems where uname -X emits "NumCPU" in its output):
  137. find_program(ProcessorCount_cmd_uname uname)
  138. mark_as_advanced(ProcessorCount_cmd_uname)
  139. if(ProcessorCount_cmd_uname)
  140. execute_process(COMMAND ${ProcessorCount_cmd_uname} -X
  141. ERROR_QUIET
  142. OUTPUT_STRIP_TRAILING_WHITESPACE
  143. OUTPUT_VARIABLE uname_X_output)
  144. string(REGEX MATCHALL "NumCPU = ([0-9]+)" procs "${uname_X_output}")
  145. set(count "${CMAKE_MATCH_1}")
  146. #message("ProcessorCount: trying uname -X '${ProcessorCount_cmd_uname}'")
  147. endif()
  148. endif()
  149. # Execute this code when all previously attempted methods return empty
  150. # output:
  151. #
  152. if(NOT count)
  153. # Systems with /proc/cpuinfo:
  154. set(cpuinfo_file /proc/cpuinfo)
  155. if(EXISTS "${cpuinfo_file}")
  156. file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$")
  157. list(LENGTH procs count)
  158. #message("ProcessorCount: trying cpuinfo '${cpuinfo_file}'")
  159. endif()
  160. endif()
  161. # Since cygwin builds of CMake do not define WIN32 anymore, but they still
  162. # run on Windows, and will still have this env var defined:
  163. #
  164. if(NOT count)
  165. set(count "$ENV{NUMBER_OF_PROCESSORS}")
  166. #message("ProcessorCount: last fallback, trying environment variable")
  167. endif()
  168. # Ensure an integer return (avoid inadvertently returning an empty string
  169. # or an error string)... If it's not a decimal integer, return 0:
  170. #
  171. if(NOT count MATCHES "^[0-9]+$")
  172. set(count 0)
  173. endif()
  174. set(${var} ${count} PARENT_SCOPE)
  175. endfunction()