ProcessorCount.cmake 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. # A more reliable way might be to compile a small C program that uses the CPUID
  21. # instruction, but that again requires compiler support or compiling assembler
  22. # code.
  23. #=============================================================================
  24. # Copyright 2010-2011 Kitware, Inc.
  25. #
  26. # Distributed under the OSI-approved BSD License (the "License");
  27. # see accompanying file Copyright.txt for details.
  28. #
  29. # This software is distributed WITHOUT ANY WARRANTY; without even the
  30. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  31. # See the License for more information.
  32. #=============================================================================
  33. # (To distribute this file outside of CMake, substitute the full
  34. # License text for the above reference.)
  35. function(ProcessorCount var)
  36. # Unknown:
  37. set(count 0)
  38. if(WIN32)
  39. # Windows:
  40. set(count "$ENV{NUMBER_OF_PROCESSORS}")
  41. message("ProcessorCount: WIN32, trying environment variable")
  42. endif()
  43. if(NOT count)
  44. # Mac, FreeBSD, OpenBSD (systems with sysctl):
  45. find_program(ProcessorCount_cmd_sysctl sysctl
  46. PATHS /usr/sbin /sbin)
  47. if(ProcessorCount_cmd_sysctl)
  48. execute_process(COMMAND ${ProcessorCount_cmd_sysctl} -n hw.ncpu
  49. OUTPUT_STRIP_TRAILING_WHITESPACE
  50. OUTPUT_VARIABLE count)
  51. message("ProcessorCount: trying sysctl '${ProcessorCount_cmd_sysctl}'")
  52. endif()
  53. endif()
  54. if(NOT count)
  55. # Linux (systems with getconf):
  56. find_program(ProcessorCount_cmd_getconf getconf)
  57. if(ProcessorCount_cmd_getconf)
  58. execute_process(COMMAND ${ProcessorCount_cmd_getconf} _NPROCESSORS_ONLN
  59. OUTPUT_STRIP_TRAILING_WHITESPACE
  60. OUTPUT_VARIABLE count)
  61. message("ProcessorCount: trying getconf '${ProcessorCount_cmd_getconf}'")
  62. endif()
  63. endif()
  64. if(NOT count)
  65. # HPUX (systems with machinfo):
  66. find_program(ProcessorCount_cmd_machinfo machinfo
  67. PATHS /usr/contrib/bin)
  68. if(ProcessorCount_cmd_machinfo)
  69. execute_process(COMMAND ${ProcessorCount_cmd_machinfo}
  70. OUTPUT_STRIP_TRAILING_WHITESPACE
  71. OUTPUT_VARIABLE machinfo_output)
  72. string(REGEX MATCHALL "Number of CPUs = ([0-9]+)" procs "${machinfo_output}")
  73. set(count "${CMAKE_MATCH_1}")
  74. message("ProcessorCount: trying machinfo '${ProcessorCount_cmd_machinfo}'")
  75. endif()
  76. endif()
  77. if(NOT count)
  78. # IRIX (systems with hinv):
  79. find_program(ProcessorCount_cmd_hinv hinv
  80. PATHS /sbin)
  81. if(ProcessorCount_cmd_hinv)
  82. execute_process(COMMAND ${ProcessorCount_cmd_hinv}
  83. OUTPUT_STRIP_TRAILING_WHITESPACE
  84. OUTPUT_VARIABLE hinv_output)
  85. string(REGEX MATCHALL "([0-9]+) .* Processors" procs "${hinv_output}")
  86. set(count "${CMAKE_MATCH_1}")
  87. message("ProcessorCount: trying hinv '${ProcessorCount_cmd_hinv}'")
  88. endif()
  89. endif()
  90. if(NOT count)
  91. # AIX (systems with lsconf):
  92. find_program(ProcessorCount_cmd_lsconf lsconf
  93. PATHS /usr/sbin)
  94. if(ProcessorCount_cmd_lsconf)
  95. execute_process(COMMAND ${ProcessorCount_cmd_lsconf}
  96. OUTPUT_STRIP_TRAILING_WHITESPACE
  97. OUTPUT_VARIABLE lsconf_output)
  98. string(REGEX MATCHALL "Number Of Processors: ([0-9]+)" procs "${lsconf_output}")
  99. set(count "${CMAKE_MATCH_1}")
  100. message("ProcessorCount: trying lsconf '${ProcessorCount_cmd_lsconf}'")
  101. endif()
  102. endif()
  103. if(NOT count)
  104. # QNX (systems with pidin):
  105. find_program(ProcessorCount_cmd_pidin pidin)
  106. if(ProcessorCount_cmd_pidin)
  107. execute_process(COMMAND ${ProcessorCount_cmd_pidin} info
  108. OUTPUT_STRIP_TRAILING_WHITESPACE
  109. OUTPUT_VARIABLE pidin_output)
  110. string(REGEX MATCHALL "Processor[0-9]+: " procs "${pidin_output}")
  111. list(LENGTH procs count)
  112. message("ProcessorCount: trying pidin '${ProcessorCount_cmd_pidin}'")
  113. endif()
  114. endif()
  115. if(NOT count)
  116. # Sun (systems where uname -X emits "NumCPU" in its output):
  117. find_program(ProcessorCount_cmd_uname uname)
  118. if(ProcessorCount_cmd_uname)
  119. execute_process(COMMAND ${ProcessorCount_cmd_uname} -X
  120. OUTPUT_STRIP_TRAILING_WHITESPACE
  121. OUTPUT_VARIABLE uname_X_output)
  122. string(REGEX MATCHALL "NumCPU = ([0-9]+)" procs "${uname_X_output}")
  123. set(count "${CMAKE_MATCH_1}")
  124. message("ProcessorCount: trying uname -X '${ProcessorCount_cmd_uname}'")
  125. endif()
  126. endif()
  127. # Execute this code when all previously attempted methods return empty
  128. # output:
  129. #
  130. if(NOT count)
  131. # Systems with /proc/cpuinfo:
  132. set(cpuinfo_file /proc/cpuinfo)
  133. if(EXISTS "${cpuinfo_file}")
  134. file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$")
  135. list(LENGTH procs count)
  136. message("ProcessorCount: trying cpuinfo '${cpuinfo_file}'")
  137. endif()
  138. endif()
  139. # Since cygwin builds of CMake do not define WIN32 anymore, but they still
  140. # run on Windows, and will still have this env var defined:
  141. #
  142. if(NOT count)
  143. set(count "$ENV{NUMBER_OF_PROCESSORS}")
  144. message("ProcessorCount: last fallback, trying environment variable")
  145. endif()
  146. # Ensure an integer return (avoid inadvertently returning an empty string
  147. # or an error string)... If it's not a decimal integer, return 0:
  148. #
  149. if(NOT count MATCHES "^[0-9]+$")
  150. set(count 0)
  151. endif()
  152. set(${var} ${count} PARENT_SCOPE)
  153. endfunction()