from .env import build_type
- max_jobs = os.getenv('MAX_JOBS', str(multiprocessing.cpu_count()))
build_args = ['--build', '.', '--target', 'install', '--config', build_type.build_type_string]
- # This ``if-else'' clause would be unnecessary when cmake 3.12 becomes
- # minimum, which provides a '-j' option: build_args += ['-j', max_jobs]
- # would be sufficient by then.
- if IS_WINDOWS and not USE_NINJA: # We are likely using msbuild here
- build_args += ['--', '/p:CL_MPCount={}'.format(max_jobs)]
- else:
- build_args += ['--', '-j', max_jobs]
+
+ # Determine the parallelism according to the following
+ # priorities:
+ # 1) MAX_JOBS environment variable
+ # 2) If using the Ninja build system, delegate decision to it.
+ # 3) Otherwise, fall back to the number of processors.
+
+ # Allow the user to set parallelism explicitly. If unset,
+ # we'll try to figure it out.
+ max_jobs = os.getenv('MAX_JOBS')
+
+ if max_jobs is not None or not USE_NINJA:
+ # Ninja is capable of figuring out the parallelism on its
+ # own: only specify it explicitly if we are not using
+ # Ninja.
+
+ # This lists the number of processors available on the
+ # machine. This may be an overestimate of the usable
+ # processors if CPU scheduling affinity limits it
+ # further. In the future, we should check for that with
+ # os.sched_getaffinity(0) on platforms that support it.
+ max_jobs = max_jobs or str(multiprocessing.cpu_count())
+
+ # This ``if-else'' clause would be unnecessary when cmake
+ # 3.12 becomes minimum, which provides a '-j' option:
+ # build_args += ['-j', max_jobs] would be sufficient by
+ # then. Until then, we use "--" to pass parameters to the
+ # underlying build system.
+ build_args += ['--']
+ if IS_WINDOWS:
+ # We are likely using msbuild here
+ build_args += ['/p:CL_MPCount={}'.format(max_jobs)]
+ else:
+ build_args += ['-j', max_jobs]
self.run(build_args, my_env)
mock_cpu_count.return_value = 13
cases = [
# MAX_JOBS, USE_NINJA, IS_WINDOWS, want
- (( '8', True, False), ['-j', '8']), # noqa: E201,E241
- (( None, True, False), ['-j', '13']), # noqa: E201,E241
- (( None, True, True), ['-j', '13']), # noqa: E201,E241
+ (( '8', True, False), ['-j', '8']), # noqa: E201,E241
+ (( None, True, False), None), # noqa: E201,E241
+ (( None, True, True), None), # noqa: E201,E241
(( None, False, True), ['/p:CL_MPCount=13']), # noqa: E201,E241
]
for (max_jobs, use_ninja, is_windows), want in cases:
call, = cmake_run.mock_calls
build_args, _ = call.args
- self.assert_contains_sequence(build_args, want)
+ if want is None:
+ self.assertNotIn('-j', build_args)
+ else:
+ self.assert_contains_sequence(build_args, want)
@staticmethod
def assert_contains_sequence(sequence: Sequence[T], subsequence: Sequence[T]) -> None: