CMake/Modules/ProcessorCount.cmake

238 lines
8.4 KiB
CMake
Raw Normal View History

Simplify CMake per-source license notices Per-source copyright/license notice headers that spell out copyright holder names and years are hard to maintain and often out-of-date or plain wrong. Precise contributor information is already maintained automatically by the version control tool. Ultimately it is the receiver of a file who is responsible for determining its licensing status, and per-source notices are merely a convenience. Therefore it is simpler and more accurate for each source to have a generic notice of the license name and references to more detailed information on copyright holders and full license terms. Our `Copyright.txt` file now contains a list of Contributors whose names appeared source-level copyright notices. It also references version control history for more precise information. Therefore we no longer need to spell out the list of Contributors in each source file notice. Replace CMake per-source copyright/license notice headers with a short description of the license and links to `Copyright.txt` and online information available from "https://cmake.org/licensing". The online URL also handles cases of modules being copied out of our source into other projects, so we can drop our notices about replacing links with full license text. Run the `Utilities/Scripts/filter-notices.bash` script to perform the majority of the replacements mechanically. Manually fix up shebang lines and trailing newlines in a few files. Manually update the notices in a few files that the script does not handle.
2016-09-27 19:01:08 +00:00
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
ProcessorCount
--------------
ProcessorCount(var)
Determine the number of processors/cores and save value in ${var}
Sets the variable named ${var} to the number of physical cores
available on the machine if the information can be determined.
Otherwise it is set to 0. Currently this functionality is implemented
for AIX, cygwin, FreeBSD, HPUX, Linux, macOS, QNX, Sun and
Windows.
This function is guaranteed to return a positive integer (>=1) if it
succeeds. It returns 0 if there's a problem determining the processor
count.
Example use, in a ctest -S dashboard script:
::
include(ProcessorCount)
ProcessorCount(N)
if(NOT N EQUAL 0)
set(CTEST_BUILD_FLAGS -j${N})
set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N})
endif()
This function is intended to offer an approximation of the value of
the number of compute cores available on the current machine, such
that you may use that value for parallel building and parallel
testing. It is meant to help utilize as much of the machine as seems
reasonable. Of course, knowledge of what else might be running on the
machine simultaneously should be used when deciding whether to request
a machine's full capacity all for yourself.
#]=======================================================================]
# A more reliable way might be to compile a small C program that uses the CPUID
# instruction, but that again requires compiler support or compiling assembler
# code.
function(ProcessorCount var)
# Unknown:
set(count 0)
if(WIN32)
# Windows:
set(count "$ENV{NUMBER_OF_PROCESSORS}")
#message("ProcessorCount: WIN32, trying environment variable")
endif()
if(NOT count)
# Mac, FreeBSD, OpenBSD (systems with sysctl):
find_program(ProcessorCount_cmd_sysctl sysctl
PATHS /usr/sbin /sbin)
mark_as_advanced(ProcessorCount_cmd_sysctl)
if(ProcessorCount_cmd_sysctl)
execute_process(COMMAND ${ProcessorCount_cmd_sysctl} -n hw.ncpu
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE count)
#message("ProcessorCount: trying sysctl '${ProcessorCount_cmd_sysctl}'")
endif()
endif()
if(NOT count)
# Linux (systems with nproc):
# Prefer nproc to getconf if available as getconf may return the host CPU count in Linux containers
find_program(ProcessorCount_cmd_nproc nproc)
mark_as_advanced(ProcessorCount_cmd_nproc)
if(ProcessorCount_cmd_nproc)
execute_process(COMMAND ${ProcessorCount_cmd_nproc}
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE count)
#message("ProcessorCount: trying nproc '${ProcessorCount_cmd_nproc}'")
endif()
endif()
if(NOT count)
# Linux (systems with getconf):
find_program(ProcessorCount_cmd_getconf getconf)
mark_as_advanced(ProcessorCount_cmd_getconf)
if(ProcessorCount_cmd_getconf)
execute_process(COMMAND ${ProcessorCount_cmd_getconf} _NPROCESSORS_ONLN
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE count)
#message("ProcessorCount: trying getconf '${ProcessorCount_cmd_getconf}'")
endif()
endif()
if(NOT count)
# HPUX (systems with machinfo):
find_program(ProcessorCount_cmd_machinfo machinfo
PATHS /usr/contrib/bin)
mark_as_advanced(ProcessorCount_cmd_machinfo)
if(ProcessorCount_cmd_machinfo)
execute_process(COMMAND ${ProcessorCount_cmd_machinfo}
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE machinfo_output)
string(REGEX MATCHALL "Number of CPUs = ([0-9]+)" procs "${machinfo_output}")
set(count "${CMAKE_MATCH_1}")
2014-06-10 15:26:24 +00:00
if(NOT count)
string(REGEX MATCHALL "([0-9]+) logical processors" procs "${machinfo_output}")
set(count "${CMAKE_MATCH_1}")
endif()
#message("ProcessorCount: trying machinfo '${ProcessorCount_cmd_machinfo}'")
else()
find_program(ProcessorCount_cmd_mpsched mpsched)
mark_as_advanced(ProcessorCount_cmd_mpsched)
if(ProcessorCount_cmd_mpsched)
execute_process(COMMAND ${ProcessorCount_cmd_mpsched} -s
OUTPUT_QUIET
ERROR_STRIP_TRAILING_WHITESPACE
ERROR_VARIABLE mpsched_output)
string(REGEX MATCHALL "Processor Count *: *([0-9]+)" procs "${mpsched_output}")
set(count "${CMAKE_MATCH_1}")
#message("ProcessorCount: trying mpsched -s '${ProcessorCount_cmd_mpsched}'")
endif()
endif()
endif()
if(NOT count)
# AIX (systems with lsconf):
find_program(ProcessorCount_cmd_lsconf lsconf
PATHS /usr/sbin)
mark_as_advanced(ProcessorCount_cmd_lsconf)
if(ProcessorCount_cmd_lsconf)
execute_process(COMMAND ${ProcessorCount_cmd_lsconf}
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE lsconf_output)
string(REGEX MATCHALL "Number Of Processors: ([0-9]+)" procs "${lsconf_output}")
set(count "${CMAKE_MATCH_1}")
#message("ProcessorCount: trying lsconf '${ProcessorCount_cmd_lsconf}'")
endif()
endif()
if(NOT count)
# QNX (systems with pidin):
find_program(ProcessorCount_cmd_pidin pidin)
mark_as_advanced(ProcessorCount_cmd_pidin)
if(ProcessorCount_cmd_pidin)
execute_process(COMMAND ${ProcessorCount_cmd_pidin} info
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE pidin_output)
string(REGEX MATCHALL "Processor[0-9]+: " procs "${pidin_output}")
list(LENGTH procs count)
#message("ProcessorCount: trying pidin '${ProcessorCount_cmd_pidin}'")
endif()
endif()
if(NOT count)
# Sun (systems where psrinfo tool is available)
find_program(ProcessorCount_cmd_psrinfo psrinfo PATHS /usr/sbin /sbin)
mark_as_advanced(ProcessorCount_cmd_psrinfo)
if (ProcessorCount_cmd_psrinfo)
execute_process(COMMAND ${ProcessorCount_cmd_psrinfo} -p -v
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE psrinfo_output)
string(REGEX MATCHALL "has [0-9]+ virtual processor" procs "${psrinfo_output}")
set(count "")
foreach(proc ${procs})
string(REGEX MATCH "has ([0-9]+) virtual" res ${proc})
math(EXPR count "${count} + ${CMAKE_MATCH_1}")
endforeach()
#message("ProcessorCount: trying '${ProcessorCount_cmd_psrinfo}' -p -v")
else()
# Sun (systems where uname -X emits "NumCPU" in its output):
find_program(ProcessorCount_cmd_uname uname)
mark_as_advanced(ProcessorCount_cmd_uname)
if(ProcessorCount_cmd_uname)
execute_process(COMMAND ${ProcessorCount_cmd_uname} -X
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE uname_X_output)
string(REGEX MATCHALL "NumCPU = ([0-9]+)" procs "${uname_X_output}")
set(count "${CMAKE_MATCH_1}")
#message("ProcessorCount: trying uname -X '${ProcessorCount_cmd_uname}'")
endif()
endif()
endif()
# Execute this code when all previously attempted methods return empty
# output:
#
if(NOT count)
# Systems with /proc/cpuinfo:
set(cpuinfo_file /proc/cpuinfo)
if(EXISTS "${cpuinfo_file}")
file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$")
list(LENGTH procs count)
#message("ProcessorCount: trying cpuinfo '${cpuinfo_file}'")
endif()
endif()
2013-12-01 15:53:46 +00:00
if(NOT count)
# Haiku
find_program(ProcessorCount_cmd_sysinfo sysinfo)
if(ProcessorCount_cmd_sysinfo)
execute_process(COMMAND ${ProcessorCount_cmd_sysinfo}
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE sysinfo_X_output)
string(REGEX MATCHALL "\nCPU #[0-9]+:" procs "\n${sysinfo_X_output}")
list(LENGTH procs count)
#message("ProcessorCount: trying sysinfo '${ProcessorCount_cmd_sysinfo}'")
endif()
endif()
# Since cygwin builds of CMake do not define WIN32 anymore, but they still
# run on Windows, and will still have this env var defined:
#
if(NOT count)
set(count "$ENV{NUMBER_OF_PROCESSORS}")
#message("ProcessorCount: last fallback, trying environment variable")
endif()
# Ensure an integer return (avoid inadvertently returning an empty string
# or an error string)... If it's not a decimal integer, return 0:
#
if(NOT count MATCHES "^[0-9]+$")
set(count 0)
endif()
set(${var} ${count} PARENT_SCOPE)
endfunction()