def _common_cmake_on_install(self, context): # Figure out if there is a setup file to source prefix = self._get_command_prefix('install', context) if not IS_WINDOWS: if has_make_target(context.build_space, 'install') or context.dry_run: if MAKE_EXECUTABLE is None: raise VerbExecutionError( "Could not find 'make' executable") yield BuildAction(prefix + [MAKE_EXECUTABLE, 'install']) else: self.warn( 'Could not run installation for package because it has no ' "'install' target") else: install_project_file = project_file_exists_at( context.build_space, 'INSTALL') if install_project_file is not None: if MSBUILD_EXECUTABLE is None: raise VerbExecutionError( "Could not find 'msbuild' executable") yield BuildAction(prefix + [ MSBUILD_EXECUTABLE, '/p:Configuration=' + self._get_visual_studio_configuration(context), install_project_file ]) else: self.warn( "Could not find Visual Studio project file 'INSTALL.vcxproj'" )
def _common_cmake_on_uninstall(self, context, build_type): # Figure out if there is a setup file to source prefix = self._get_command_prefix('uninstall', context) if not IS_WINDOWS: if has_make_target(context.build_space, 'uninstall'): if MAKE_EXECUTABLE is None: raise VerbExecutionError( "Could not find 'make' executable") cmd = prefix + [MAKE_EXECUTABLE, 'uninstall'] yield BuildAction(cmd) else: self.warn( "Could not run uninstall for '{0}' package because it has no " "'uninstall' target".format(build_type)) else: if MSBUILD_EXECUTABLE is None: raise VerbExecutionError("Could not find 'msbuild' executable") uninstall_project_file = project_file_exists_at( context.build_space, 'UNINSTALL') if uninstall_project_file is not None: yield BuildAction(prefix + [MSBUILD_EXECUTABLE, uninstall_project_file]) else: self.warn( "Could not find Visual Studio project file 'UNINSTALL.vcxproj'" )
def _common_cmake_on_uninstall(self, context, build_type): # Figure out if there is a setup file to source prefix = self._get_command_prefix('uninstall', context) if IS_LINUX: build_action = self._make_uninstall(context, build_type, prefix) if build_action: yield build_action elif IS_WINDOWS: if MSBUILD_EXECUTABLE is None: raise VerbExecutionError("Could not find 'msbuild' executable") uninstall_project_file = project_file_exists_at( context.build_space, 'UNINSTALL') if uninstall_project_file is not None: yield BuildAction(prefix + [MSBUILD_EXECUTABLE, uninstall_project_file]) else: self.warn( "Could not find Visual Studio project file 'UNINSTALL.vcxproj'" ) elif IS_MACOSX: if self._using_xcode_generator(context): if XCODEBUILD_EXECUTABLE is None: raise VerbExecutionError( "Could not find 'xcodebuild' executable") cmd = prefix + [XCODEBUILD_EXECUTABLE] cmd += ['-target', 'uninstall'] yield BuildAction(cmd) else: build_action = self._make_uninstall(context, build_type, prefix) if build_action: yield build_action else: raise VerbExecutionError('Could not determine operating system')
def _make_or_ninja_build(self, context, prefix): if context.use_ninja: if NINJA_EXECUTABLE is None: raise VerbExecutionError("Could not find 'make' executable") return BuildAction(prefix + [NINJA_EXECUTABLE] + context.make_flags) else: if MAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'make' executable") return BuildAction(prefix + [MAKE_EXECUTABLE] + context.make_flags)
def _common_cmake_on_test(self, context, build_type): assert context.build_tests # Figure out if there is a setup file to source # also pass the exec dependencies into the command prefix file prefix = self._get_command_prefix( 'test', context, additional_dependencies=context.exec_dependency_paths_in_workspace) if not IS_WINDOWS: if has_make_target(context.build_space, 'test') or context.dry_run: if MAKE_EXECUTABLE is None: raise VerbExecutionError( "Could not find 'make' executable") cmd = prefix + [MAKE_EXECUTABLE, 'test'] if 'ARGS' not in os.environ: args = [ '-V', # verbose output and generate xml of test summary '-D', 'ExperimentalTest', '--no-compress-output' ] elif os.environ['ARGS']: args = [os.environ['ARGS']] else: args = [] args += context.ctest_args if context.retest_until_pass and context.test_iteration: args += ['--rerun-failed'] if args: # the valus is not quoted here # since each item will be quoted by shlex.quote later if necessary cmd.append('ARGS=%s' % ' '.join(args)) yield BuildAction(cmd) else: self.warn( "Could not run tests for '{0}' package because it has no " "'test' target".format(build_type)) else: if CTEST_EXECUTABLE is None: raise VerbExecutionError("Could not find 'ctest' executable") # invoke CTest directly in order to pass arguments # it needs a specific configuration and currently there are no conf. specific tests cmd = prefix + [ CTEST_EXECUTABLE, # choose configuration on e.g. Windows '-C', self._get_visual_studio_configuration(context), # generate xml of test summary '-D', 'ExperimentalTest', '--no-compress-output', # show all test output '-V', '--force-new-ctest-process'] + \ context.ctest_args if context.retest_until_pass and context.test_iteration: cmd += ['--rerun-failed'] yield BuildAction(cmd)
def _common_cmake_on_install(self, context): # Figure out if there is a setup file to source prefix = self._get_command_prefix('install', context) if IS_LINUX: build_action = self._make_or_ninja_install(context, prefix) if build_action: yield build_action elif IS_WINDOWS: install_project_file = project_file_exists_at( context.build_space, 'INSTALL') if install_project_file is not None: if MSBUILD_EXECUTABLE is None: raise VerbExecutionError( "Could not find 'msbuild' executable") yield BuildAction(prefix + [ MSBUILD_EXECUTABLE, '/p:Configuration=' + self._get_configuration_from_cmake(context), install_project_file ]) else: self.warn( "Could not find Visual Studio project file 'INSTALL.vcxproj'" ) elif IS_MACOSX: if self._using_xcode_generator(context): # The Xcode CMake generator will produce a file named # install_postBuildPhase.makeRelease in the CMakeScripts directory if there is an # install command in the CMakeLists.txt file of the package. We use that to only # call xcodebuild's install target if there is anything to install install_cmake_file_path = os.path.join( context.build_space, 'CMakeScripts', 'install_postBuildPhase.makeRelease') install_cmake_file = os.path.isfile(install_cmake_file_path) if install_cmake_file: if XCODEBUILD_EXECUTABLE is None: raise VerbExecutionError( "Could not find 'xcodebuild' executable") cmd = prefix + [XCODEBUILD_EXECUTABLE] cmd += ['-target', 'install'] cmd += [ '-configuration', self._get_configuration_from_cmake(context) ] if self._get_sdk_from_cmake(context) != "": cmd += ['-sdk', self._get_sdk_from_cmake(context)] cmd += ['EFFECTIVE_PLATFORM_NAME='] yield BuildAction(cmd) else: build_action = self._make_or_ninja_install(context, prefix) if build_action: yield build_action else: raise VerbExecutionError('Could not determine operating system')
def _make_or_ninja_install(self, context, prefix): if context.use_ninja: if NINJA_EXECUTABLE is None: raise VerbExecutionError("Could not find 'ninja' executable") return BuildAction(prefix + [NINJA_EXECUTABLE, 'install']) else: if has_make_target(context.build_space, 'install') or context.dry_run: if MAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'make' executable") return BuildAction(prefix + [MAKE_EXECUTABLE, 'install']) else: self.warn("Could not run installation for package '{0}' because it has no " "'install' target".format(context.package_manifest.name))
def _common_cmake_on_test(self, context, build_type): assert context.build_tests # Figure out if there is a setup file to source # also pass the exec dependencies into the command prefix file prefix = self._get_command_prefix( 'test', context, additional_dependencies=context.exec_dependency_paths_in_workspace) if IS_LINUX: build_action = self._make_test(context, build_type, prefix) if build_action: yield build_action elif IS_WINDOWS: if CTEST_EXECUTABLE is None: raise VerbExecutionError( "Could not find 'ctest' executable, try setting the " 'environment variable ' + CTEST_EXECUTABLE_ENV) # invoke CTest directly in order to pass arguments # it needs a specific configuration and currently there are no conf. specific tests cmd = prefix + [ CTEST_EXECUTABLE, # choose configuration on e.g. Windows '-C', self._get_configuration_from_cmake(context), # generate xml of test summary '-D', 'ExperimentalTest', '--no-compress-output', # show all test output '-V', '--force-new-ctest-process'] + \ context.ctest_args if context.retest_until_pass and context.test_iteration: cmd += ['--rerun-failed'] yield BuildAction(cmd) elif IS_MACOSX: if self._using_xcode_generator(context): if XCODEBUILD_EXECUTABLE is None: raise VerbExecutionError( "Could not find 'xcodebuild' executable") xcodebuild_args = ['build'] xcodebuild_args += ['-configuration'] xcodebuild_args += [ self._get_configuration_from_cmake(context) ] xcodebuild_args += ['-target', 'RUN_TESTS'] yield BuildAction(prefix + [XCODEBUILD_EXECUTABLE] + xcodebuild_args) else: build_action = self._make_test(context, build_type, prefix) if build_action: yield build_action else: raise VerbExecutionError('Could not determine operating system')
def _common_cmake_on_test(self, context, build_type): assert context.build_tests # Figure out if there is a setup file to source prefix = self._get_command_prefix('test', context) if not IS_WINDOWS: if has_make_target(context.build_space, 'test') or context.dry_run: cmd = prefix + [MAKE_EXECUTABLE, 'test'] if 'ARGS' not in os.environ: cmd.append('ARGS="-V"') yield BuildAction(cmd) else: self.warn( "Could not run tests for '{0}' package because it has no " "'test' target".format(build_type)) else: if MSBUILD_EXECUTABLE is None: raise VerbExecutionError("Could not find 'msbuild' executable") run_tests_project_file = project_file_exists_at( context.build_space, 'RUN_TESTS') if run_tests_project_file is not None or context.dry_run: yield BuildAction(prefix + [MSBUILD_EXECUTABLE, run_tests_project_file]) else: self.warn( "Could not find Visual Studio project file 'RUN_TESTS.vcxproj'" )
def main(opts, per_package_main=build_pkg_main): # use PWD in order to work when being invoked in a symlinked location cwd = os.getenv('PWD', os.curdir) opts.directory = os.path.abspath(os.path.join(cwd, opts.directory)) if not os.path.exists(opts.basepath): raise RuntimeError("The specified base path '%s' does not exist" % opts.basepath) opts.build_space = determine_path_argument( cwd, opts.directory, opts.build_space, 'build' if not opts.isolated else 'build_isolated') opts.install_space = determine_path_argument( cwd, opts.directory, opts.install_space, 'install' if not opts.isolated else 'install_isolated') packages = topological_order(opts.basepath) circular_dependencies = [ package_names for path, package_names, _ in packages if path is None ] if circular_dependencies: raise VerbExecutionError('Circular dependency within the following ' 'packages: %s' % circular_dependencies[0]) print_topological_order(opts, packages) iterate_packages(opts, packages, per_package_main)
def main(opts, per_package_main=build_pkg_main): # use PWD in order to work when being invoked in a symlinked location cwd = os.getenv('PWD', os.curdir) opts.directory = os.path.abspath(os.path.join(cwd, opts.directory)) if not os.path.exists(opts.basepath): raise RuntimeError("The specified base path '%s' does not exist" % opts.basepath) opts.build_space = determine_path_argument( cwd, opts.directory, opts.build_space, 'build' if not opts.isolated else 'build_isolated') opts.install_space = determine_path_argument( cwd, opts.directory, opts.install_space, 'install' if not opts.isolated else 'install_isolated') packages = topological_order(opts.basepath) circular_dependencies = [ package_names for path, package_names, _ in packages if path is None ] if circular_dependencies: raise VerbExecutionError('Circular dependency within the following ' 'packages: %s' % circular_dependencies[0]) pkg_names = [p.name for _, p, _ in packages] check_opts(opts, pkg_names) consolidate_package_selection(opts, pkg_names) print_topological_order(opts, pkg_names) if set(pkg_names) <= set(opts.skip_packages): print('All selected packages are being skipped. Nothing to do.', file=sys.stderr) return 0 return iterate_packages(opts, packages, per_package_main)
def _make_test(self, context, build_type, prefix): if has_make_target(context.build_space, 'test') or context.dry_run: if MAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'make' executable") cmd = prefix + [MAKE_EXECUTABLE, 'test'] if 'ARGS' not in os.environ: args = [ '-V', # verbose output and generate xml of test summary '-D', 'ExperimentalTest', '--no-compress-output' ] elif os.environ['ARGS']: args = [os.environ['ARGS']] else: args = [] args += context.ctest_args if context.retest_until_pass and context.test_iteration: args += ['--rerun-failed'] if args: # the valus is not quoted here # since each item will be quoted by shlex.quote later if necessary cmd.append('ARGS=%s' % ' '.join(args)) return BuildAction(cmd) else: self.warn( "Could not run tests for package '{0}' because it has no " "'test' target".format(context.package_manifest.name))
def _make_uninstall(self, context, build_type, prefix): if has_make_target(context.build_space, 'uninstall'): if MAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'make' executable") cmd = prefix + [MAKE_EXECUTABLE, 'uninstall'] return BuildAction(cmd) else: self.warn("Could not run uninstall for package '{0}' because it has no " "'uninstall' target".format(context.package_manifest.name))
def _common_cmake_on_build(self, should_run_configure, context, prefix, extra_cmake_args): # Execute the configure step # (either cmake or the cmake_check_build_system make target) if should_run_configure: cmake_args = [context.source_space] cmake_args.extend(extra_cmake_args) cmake_args += ["-DCMAKE_INSTALL_PREFIX=" + context.install_space] if IS_WINDOWS: vsv = get_visual_studio_version() if vsv is None: print("VisualStudioVersion is not set, please run within " "a VS2013 or VS2015 Command Prompt.") raise VerbExecutionError( "Could not determine Visual Studio Version.") generator = None if vsv == '12.0': generator = 'Visual Studio 12 2013 Win64' elif vsv == '14.0': generator = 'Visual Studio 14 2015 Win64' else: raise VerbExecutionError("Unknown VS version: " + vsv) cmake_args += ['-G', generator] if CMAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'cmake' executable") yield BuildAction(prefix + [CMAKE_EXECUTABLE] + cmake_args) elif not IS_WINDOWS: # Check for reconfigure if available. cmd = prefix + [MAKE_EXECUTABLE, 'cmake_check_build_system'] yield BuildAction(cmd) # Now execute the build step if not IS_WINDOWS: if MAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'make' executable") yield BuildAction(prefix + [MAKE_EXECUTABLE] + context.make_flags) else: if MSBUILD_EXECUTABLE is None: raise VerbExecutionError("Could not find 'msbuild' executable") solution_file = solution_file_exists_at( context.build_space, context.package_manifest.name) if '-j1' in context.make_flags: yield BuildAction(prefix + [MSBUILD_EXECUTABLE, solution_file]) else: yield BuildAction(prefix + [MSBUILD_EXECUTABLE, '/m', solution_file])
def _common_cmake_on_install(self, context): # Figure out if there is a setup file to source prefix = self._get_command_prefix('install', context) if not IS_WINDOWS: # Assumption: install target exists if MAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'make' executable") yield BuildAction(prefix + [MAKE_EXECUTABLE, 'install']) else: if MSBUILD_EXECUTABLE is None: raise VerbExecutionError("Could not find 'msbuild' executable") install_project_file = project_file_exists_at( context.build_space, 'INSTALL') if install_project_file is None: raise VerbExecutionError( "Could not find Visual Studio project file 'INSTALL.vcxproj'" ) yield BuildAction(prefix + [MSBUILD_EXECUTABLE, install_project_file])
def _get_gradle_executable(self, context): gradlew_path = self._get_gradle_wrapper(context) if gradlew_path: return gradlew_path gradle_script = 'gradle.bat' if IS_WINDOWS else 'gradle' if 'GRADLE_HOME' in os.environ: gradle_home = os.environ['GRADLE_HOME'] gradle_path = os.path.join(gradle_home, 'bin', gradle_script) if os.path.isfile(gradle_path): return gradle_path gradle_path = shutil.which(gradle_script) if gradle_path: return gradle_path raise VerbExecutionError("Could not find 'gradle' executable")
def _common_cmake_on_build(self, should_run_configure, context, prefix, extra_cmake_args): # Execute the configure step # (either cmake or the cmake_check_build_system make target) if should_run_configure: cmake_args = [context.source_space] cmake_args.extend(extra_cmake_args) cmake_args += ["-DCMAKE_INSTALL_PREFIX=" + context.install_space] if IS_WINDOWS: vsv = get_visual_studio_version() if vsv is None: sys.stderr.write( 'VisualStudioVersion is not set, ' 'please run within a Visual Studio Command Prompt.\n') raise VerbExecutionError('Could not determine Visual Studio Version') supported_vsv = { '14.0': 'Visual Studio 14 2015 Win64', } if vsv not in supported_vsv: raise VerbExecutionError('Unknown / unsupported VS version: ' + vsv) cmake_args += ['-G', supported_vsv[vsv]] if CMAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'cmake' executable") yield BuildAction(prefix + [CMAKE_EXECUTABLE] + cmake_args) elif not IS_WINDOWS: # Check for reconfigure if available. if MAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'make' executable") cmd = prefix + [MAKE_EXECUTABLE, 'cmake_check_build_system'] yield BuildAction(cmd) # Now execute the build step if not IS_WINDOWS: if MAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'make' executable") yield BuildAction(prefix + [MAKE_EXECUTABLE] + context.make_flags) else: if MSBUILD_EXECUTABLE is None: raise VerbExecutionError("Could not find 'msbuild' executable") solution_file = solution_file_exists_at( context.build_space, context.package_manifest.name) cmd = prefix + [MSBUILD_EXECUTABLE] if '-j1' in context.make_flags: cmd += ['/m'] cmd += [ '/p:Configuration=%s' % self._get_visual_studio_configuration(context), solution_file] yield BuildAction(cmd)
def _common_cmake_on_build(self, should_run_configure, context, prefix, extra_cmake_args): # Execute the configure step # (either cmake or the cmake_check_build_system make target) if should_run_configure: cmake_args = [context.source_space] cmake_args.extend(extra_cmake_args) cmake_args += ['-DCMAKE_INSTALL_PREFIX=' + context.install_space] if IS_WINDOWS: vsv = get_visual_studio_version() if vsv is None: sys.stderr.write( 'VisualStudioVersion is not set, ' 'please run within a Visual Studio Command Prompt.\n') raise VerbExecutionError( 'Could not determine Visual Studio Version') supported_vsv = { '14.0': 'Visual Studio 14 2015 Win64', '15.0': 'Visual Studio 15 2017 Win64', } if vsv not in supported_vsv: raise VerbExecutionError( 'Unknown / unsupported VS version: ' + vsv) cmake_args += ['-G', supported_vsv[vsv]] elif IS_MACOSX: if context.use_xcode or self._using_xcode_generator(context): cmake_args += ['-G', 'Xcode'] else: cmake_args += ['-G', 'Unix Makefiles'] if CMAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'cmake' executable") yield BuildAction(prefix + [CMAKE_EXECUTABLE] + cmake_args) elif IS_LINUX: # Check for reconfigure if available. if MAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'make' executable") cmd = prefix + [MAKE_EXECUTABLE, 'cmake_check_build_system'] yield BuildAction(cmd) # Now execute the build step if IS_LINUX: yield self._make_or_ninja_build(context, prefix) elif IS_WINDOWS: if MSBUILD_EXECUTABLE is None: raise VerbExecutionError("Could not find 'msbuild' executable") solution_file = solution_file_exists_at( context.build_space, context.package_manifest.name) cmd = prefix + [MSBUILD_EXECUTABLE] env = None # Convert make parallelism flags into msbuild flags msbuild_flags = [ x.replace('-j', '/m:') for x in context.make_flags if x.startswith('-j') ] if msbuild_flags: cmd += msbuild_flags # If there is a parallelism flag in msbuild_flags and it's not /m1, # then turn on /MP for the compiler (intra-project parallelism) if any(x.startswith('/m') for x in msbuild_flags) and \ '/m:1' not in msbuild_flags: env = dict(os.environ) if 'CL' in env: # make sure env['CL'] doesn't include an /MP already if not any( x.startswith('/MP') for x in env['CL'].split(' ')): env['CL'] += ' /MP' else: # CL not in environment; let's add it with our flag env['CL'] = '/MP' cmd += [ '/p:Configuration=%s' % self._get_configuration_from_cmake(context), solution_file ] yield BuildAction(cmd, env=env) elif IS_MACOSX: if self._using_xcode_generator(context): if XCODEBUILD_EXECUTABLE is None: raise VerbExecutionError( "Could not find 'xcodebuild' executable") cmd = prefix + [XCODEBUILD_EXECUTABLE] cmd += ['build'] xcodebuild_flags = [] for flag in context.make_flags: if flag.startswith('-j'): xcodebuild_flags.append( flag.replace( '-j', '-IDEBuildOperationMaxNumberOfConcurrentCompileTasks=' )) elif not flag.startswith('-l'): xcodebuild_flags.append(flag) xcodebuild_flags += ['-configuration'] xcodebuild_flags += [ self._get_configuration_from_cmake(context) ] cmd.extend(xcodebuild_flags) yield BuildAction(cmd) else: yield self._make_or_ninja_build(context, prefix) else: raise VerbExecutionError('Could not determine operating system')
def _common_cmake_on_build(self, should_run_configure, context, prefix, extra_cmake_args): # Execute the configure step # (either cmake or the cmake_check_build_system make target) if should_run_configure: cmake_args = [context.source_space] cmake_args.extend(extra_cmake_args) cmake_args += ["-DCMAKE_INSTALL_PREFIX=" + context.install_space] if IS_WINDOWS: vsv = get_visual_studio_version() if vsv is None: sys.stderr.write( 'VisualStudioVersion is not set, ' 'please run within a Visual Studio Command Prompt.\n') raise VerbExecutionError( 'Could not determine Visual Studio Version') supported_vsv = { '14.0': 'Visual Studio 14 2015 Win64', } if vsv not in supported_vsv: raise VerbExecutionError( 'Unknown / unsupported VS version: ' + vsv) cmake_args += ['-G', supported_vsv[vsv]] if CMAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'cmake' executable") yield BuildAction(prefix + [CMAKE_EXECUTABLE] + cmake_args) elif not IS_WINDOWS: # Check for reconfigure if available. if MAKE_EXECUTABLE is None: raise VerbExecutionError("Could not find 'make' executable") cmd = prefix + [MAKE_EXECUTABLE, 'cmake_check_build_system'] yield BuildAction(cmd) # Now execute the build step if not IS_WINDOWS: if context.use_ninja: if NINJA_EXECUTABLE is None: raise VerbExecutionError( "Could not find 'make' executable") yield BuildAction(prefix + [NINJA_EXECUTABLE] + context.make_flags) else: if MAKE_EXECUTABLE is None: raise VerbExecutionError( "Could not find 'make' executable") yield BuildAction(prefix + [MAKE_EXECUTABLE] + context.make_flags) else: if MSBUILD_EXECUTABLE is None: raise VerbExecutionError("Could not find 'msbuild' executable") solution_file = solution_file_exists_at( context.build_space, context.package_manifest.name) cmd = prefix + [MSBUILD_EXECUTABLE] env = None # Convert make parallelism flags into msbuild flags msbuild_flags = [ x.replace('-j', '/m:') for x in context.make_flags if x.startswith('-j') ] if msbuild_flags: cmd += msbuild_flags # If there is a parallelism flag in msbuild_flags and it's not /m1, # then turn on /MP for the compiler (intra-project parallelism) if any([x.startswith('/m') for x in msbuild_flags]) and \ '/m:1' not in msbuild_flags: env = dict(os.environ) if 'CL' in env: # make sure env['CL'] doesn't include an /MP already if not any([ x.startswith('/MP') for x in env['CL'].split(' ') ]): env['CL'] += ' /MP' else: # CL not in environment; let's add it with our flag env['CL'] = '/MP' cmd += [ '/p:Configuration=%s' % self._get_visual_studio_configuration(context), solution_file ] yield BuildAction(cmd, env=env)