Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More fine-grained control (using [conf]) for build parallelization #8665

Merged
merged 11 commits into from Mar 26, 2021
30 changes: 19 additions & 11 deletions conan/tools/cmake/cmake.py
Expand Up @@ -3,15 +3,17 @@

from conan.tools.cmake.base import CMakeToolchainBase
from conan.tools.cmake.utils import get_generator, is_multi_configuration
from conan.tools.microsoft.msbuild import msbuild_verbosity_cmd_line_arg
from conan.tools.meson.meson import ninja_jobs_cmd_line_arg
from conan.tools.microsoft.msbuild import msbuild_verbosity_cmd_line_arg, \
msbuild_max_cpu_count_cmd_line_arg
from conans.client import tools
from conans.client.build import join_arguments
from conans.client.tools.files import chdir
from conans.client.tools.oss import cpu_count, args_to_string
from conans.errors import ConanException
from conans.model.version import Version
from conans.util.conan_v2_mode import conan_v2_error
from conans.util.files import mkdir
from conan.tools.gnu.make import make_jobs_cmd_line_arg


def _validate_recipe(conanfile):
Expand All @@ -23,15 +25,21 @@ def _validate_recipe(conanfile):

def _cmake_cmd_line_args(conanfile, generator, parallel):
args = []
compiler_version = conanfile.settings.get_safe("compiler.version")
if generator and parallel:
if ("Makefiles" in generator or "Ninja" in generator) and "NMake" not in generator:
args.append("-j%i" % cpu_count(conanfile.output))
elif "Visual Studio" in generator and compiler_version and Version(compiler_version) >= "10":
# Parallel for building projects in the solution
args.append("/m:%i" % cpu_count(output=conanfile.output))

if generator and "Visual Studio" in generator:
if not generator:
return args

# Arguments related to parallel
if "MakeFiles" in generator and "NMake" not in generator and parallel:
args.append(make_jobs_cmd_line_arg(conanfile))

if "Ninja" in generator and "NMake" not in generator:
args.append(ninja_jobs_cmd_line_arg(conanfile, parallel=parallel))

if "Visual Studio" in generator and parallel:
args.append(msbuild_max_cpu_count_cmd_line_arg(conanfile))

# Arguments for verbosity
if "Visual Studio" in generator:
verbosity = msbuild_verbosity_cmd_line_arg(conanfile)
if verbosity:
args.append(verbosity)
Expand Down
9 changes: 9 additions & 0 deletions conan/tools/gnu/make.py
Expand Up @@ -3,11 +3,20 @@
from collections import OrderedDict

from jinja2 import Template

from conans.client.build.compiler_flags import build_type_define, libcxx_define
from conans.client.tools.oss import cpu_count
from conans.client.tools.oss import detected_architecture, detected_os, get_build_os_arch
from conans.util.files import save


def make_jobs_cmd_line_arg(conanfile):
njobs = conanfile.conf["tools.gnu.make"].jobs or \
conanfile.conf["core.build"].processes or \
jgsogo marked this conversation as resolved.
Show resolved Hide resolved
cpu_count(output=conanfile.output)
return "-j{}".format(njobs)


class MakeToolchain(object):
filename = "conan_toolchain.mak"

Expand Down
18 changes: 15 additions & 3 deletions conan/tools/meson/meson.py
Expand Up @@ -5,9 +5,20 @@
from conans.client.tools.oss import cross_building, cpu_count


def ninja_jobs_cmd_line_arg(conanfile, parallel):
if parallel:
njobs = conanfile.conf["tools.ninja"].jobs or \
conanfile.conf["core.build"].processes or \
jgsogo marked this conversation as resolved.
Show resolved Hide resolved
cpu_count(output=conanfile.output)
else:
njobs = 1
return "-j{}".format(njobs)


class Meson(object):
def __init__(self, conanfile, build_folder='build'):
def __init__(self, conanfile, build_folder='build', parallel=True):
self._conanfile = conanfile
self._parallel = parallel
self._build_folder = build_folder

def _run(self, cmd):
Expand All @@ -33,14 +44,15 @@ def configure(self, source_folder=None):
if cross_building(self._conanfile):
cmd += ' --cross-file "{}"'.format(MesonToolchain.cross_filename)
else:
cmd += ' --native-file "{}"'. format(MesonToolchain.native_filename)
cmd += ' --native-file "{}"'.format(MesonToolchain.native_filename)
cmd += ' "{}" "{}"'.format(self._build_dir, source)
if self._conanfile.package_folder:
cmd += ' -Dprefix="{}"'.format(self._conanfile.package_folder)
self._run(cmd)

def build(self, target=None):
cmd = 'meson compile -C "{}" -j {}'.format(self._build_dir, cpu_count())
njobs = ninja_jobs_cmd_line_arg(self._conanfile, parallel=self._parallel)
cmd = 'meson compile -C "{}" {}'.format(self._build_dir, njobs)
if target:
cmd += " {}".format(target)
self._run(cmd)
Expand Down
16 changes: 14 additions & 2 deletions conan/tools/microsoft/msbuild.py
@@ -1,17 +1,26 @@
from conans.client.tools.oss import cpu_count
from conans.errors import ConanException


def msbuild_verbosity_cmd_line_arg(conanfile):
verbosity = conanfile.conf["tools.microsoft"].msbuild_verbosity
verbosity = conanfile.conf["tools.microsoft.msbuild"].verbosity
jgsogo marked this conversation as resolved.
Show resolved Hide resolved
if verbosity:
if verbosity not in ("Quiet", "Minimal", "Normal", "Detailed", "Diagnostic"):
raise ConanException("Unknown msbuild verbosity: {}".format(verbosity))
return '/verbosity:{}'.format(verbosity)


def msbuild_max_cpu_count_cmd_line_arg(conanfile):
max_cpu_count = conanfile.conf["tools.microsoft.msbuild"].maxCpuCount or \
jgsogo marked this conversation as resolved.
Show resolved Hide resolved
conanfile.conf["core.build"].processes or \
cpu_count(output=conanfile.output)
return "/m:{}".format(max_cpu_count)


class MSBuild(object):
def __init__(self, conanfile):
def __init__(self, conanfile, parallel=True):
jgsogo marked this conversation as resolved.
Show resolved Hide resolved
self._conanfile = conanfile
self._parallel = parallel
self.build_type = conanfile.settings.get_safe("build_type")
msvc_arch = {'x86': 'x86',
'x86_64': 'x64',
Expand All @@ -34,6 +43,9 @@ def command(self, sln):
if verbosity:
cmd += " {}".format(verbosity)

if self._parallel:
cmd += " {}".format(msbuild_max_cpu_count_cmd_line_arg(self._conanfile))

return cmd

def build(self, sln):
Expand Down
Expand Up @@ -22,13 +22,13 @@ def package_id(self):
def test_package_id(client):
profile1 = textwrap.dedent("""\
[conf]
tools.microsoft:msbuild_verbosity=Quiet""")
tools.microsoft.msbuild:verbosity=Quiet""")
profile2 = textwrap.dedent("""\
[conf]
tools.microsoft:msbuild_verbosity=Minimal""")
tools.microsoft.msbuild:verbosity=Minimal""")
client.save({"profile1": profile1,
"profile2": profile2})
client.run("create . pkg/0.1@ -pr=profile1")
assert "pkg/0.1:b40df771e875672867408f9edf54bec0c2c361a7 - Build" in client.out
assert "pkg/0.1:b85ef030da903577bd87d1c92c0524c9c96212b5 - Build" in client.out
client.run("create . pkg/0.1@ -pr=profile2")
assert "pkg/0.1:017c055fc7833bf6a7836211a26727533237071d - Build" in client.out
assert "pkg/0.1:7d2f1590113db99bcd08a4ebd4c841cc0a2e7020 - Build" in client.out
10 changes: 5 additions & 5 deletions conans/test/integration/configuration/conf/test_conf_profile.py
Expand Up @@ -52,11 +52,11 @@ def test_cmake_config(client):
compiler.runtime=MD
build_type=Release
[conf]
tools.microsoft:msbuild_verbosity=Minimal
tools.microsoft.msbuild:verbosity=Minimal
""")
client.save({"myprofile": profile})
client.run("create . pkg/0.1@ -pr=myprofile")
assert "/verbosity:Minimal" in client.out
assert "/verbosity:Minimal" in str(client.out)


def test_cmake_config_error(client):
Expand All @@ -69,7 +69,7 @@ def test_cmake_config_error(client):
compiler.runtime=MD
build_type=Release
[conf]
tools.microsoft:msbuild_verbosity=non-existing
tools.microsoft.msbuild:verbosity=non-existing
""")
client.save({"myprofile": profile})
client.run("create . pkg/0.1@ -pr=myprofile", assert_error=True)
Expand All @@ -86,7 +86,7 @@ def test_cmake_config_package(client):
compiler.runtime=MD
build_type=Release
[conf]
dep*:tools.microsoft:msbuild_verbosity=Minimal
dep*:tools.microsoft.msbuild:verbosity=Minimal
""")
client.save({"myprofile": profile})
client.run("create . pkg/0.1@ -pr=myprofile")
Expand Down Expand Up @@ -128,7 +128,7 @@ def build(self):
compiler.runtime=MD
build_type=Release
[conf]
tools.microsoft:msbuild_verbosity=Minimal
tools.microsoft.msbuild:verbosity=Minimal
""")
client.save({"myprofile": profile})
client.run("create . pkg/0.1@ -pr=myprofile")
Expand Down