Skip to content

Commit

Permalink
Split build & compilation verbosity control into two confs (#13729)
Browse files Browse the repository at this point in the history
Changelog: Feature: Split build & compilation verbosity control to two
confs
Docs: In progress

Adds verbosity confs for:


| tool name | `build:verbosity` | `compilation:verbosity` |
|------|-------|-------------|
| cmake      | ✔️ | ✔️ |
| xcodebuild*| ✔️ | ✔️ |
| msbuild    | ✔️ | - |
| meson      | ✔️ | ✔️ |
---------------------

* xcodebuild is not clear to me nor to @czoido what verbosity controls,
so both confs activate it! Probably want to change it

Closes #13703
Closes #12239
  • Loading branch information
AbrilRBS authored May 31, 2023
2 parents cb4c601 + 2e34d23 commit 401220b
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 83 deletions.
25 changes: 4 additions & 21 deletions conan/tools/apple/xcodebuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,10 @@ def __init__(self, conanfile):

@property
def _verbosity(self):
verbosity = self._conanfile.conf.get("tools.build:verbosity")
if verbosity:
if verbosity not in ("quiet", "error", "warning", "notice", "status", "verbose",
"normal", "debug", "v", "trace", "vv"):
raise ConanException(f"Value '{verbosity}' for 'tools.build:verbosity' is not valid")
else:
# quiet, nothing, verbose
verbosity = {"quiet": "quiet",
"error": "quiet",
"warning": "quiet",
"notice": "quiet",
"status": None,
"verbose": None,
"normal": None,
"debug": "verbose",
"v": "verbose",
"trace": "verbose",
"vv": "verbose"}.get(verbosity)
if verbosity is not None:
return "-{}".format(verbosity)
return ""
verbosity = self._conanfile.conf.get("tools.build:verbosity", choices=("quiet", "verbose")) \
or self._conanfile.conf.get("tools.compilation:verbosity",
choices=("quiet", "verbose"))
return "-" + verbosity if verbosity is not None else ""

@property
def _sdkroot(self):
Expand Down
27 changes: 27 additions & 0 deletions conan/tools/cmake/cmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ def configure(self, variables=None, build_script_folder=None, cli_args=None):
arg_list.extend(['-D{}="{}"'.format(k, v) for k, v in self._cache_variables.items()])
arg_list.append('"{}"'.format(cmakelist_folder))

if not cli_args or ("--log-level" not in cli_args and "--loglevel" not in cli_args):
arg_list.extend(self._cmake_log_levels_args)

if cli_args:
arg_list.extend(cli_args)

Expand Down Expand Up @@ -132,6 +135,9 @@ def _build(self, build_type=None, target=None, cli_args=None, build_tool_args=No
cmd_line_args = _cmake_cmd_line_args(self._conanfile, self._generator)
if build_tool_args:
cmd_line_args.extend(build_tool_args)

args.extend(self._compilation_verbosity_arg)

if cmd_line_args:
args += ['--'] + cmd_line_args

Expand Down Expand Up @@ -181,6 +187,7 @@ def install(self, build_type=None, component=None):
arg_list = ["--install", build_folder, build_config, "--prefix", pkg_folder]
if component:
arg_list.extend(["--component", component])
arg_list.extend(self._compilation_verbosity_arg)
arg_list = " ".join(filter(None, arg_list))
command = "%s %s" % (self._cmake_program, arg_list)
self._conanfile.run(command)
Expand Down Expand Up @@ -209,3 +216,23 @@ def test(self, build_type=None, target=None, cli_args=None, build_tool_args=None
env = ["conanbuild", "conanrun"] if env == "" else env
self._build(build_type=build_type, target=target, cli_args=cli_args,
build_tool_args=build_tool_args, env=env)

@property
def _compilation_verbosity_arg(self):
"""
Controls build tool verbosity, that is, those controlled by -DCMAKE_VERBOSE_MAKEFILE
See https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-build-v
"""
verbosity = self._conanfile.conf.get("tools.compilation:verbosity",
choices=("quiet", "verbose"))
return ["--verbose"] if verbosity == "verbose" else []

@property
def _cmake_log_levels_args(self):
"""
Controls CMake's own verbosity levels.
See https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-log-level
:return:
"""
log_level = self._conanfile.conf.get("tools.build:verbosity", choices=("quiet", "verbose"))
return ["--loglevel=" + log_level.upper()] if log_level is not None else []
23 changes: 23 additions & 0 deletions conan/tools/meson/meson.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from conan.tools.build import build_jobs
from conan.tools.meson.toolchain import MesonToolchain
from conans.errors import ConanException


class Meson(object):
Expand Down Expand Up @@ -67,6 +68,9 @@ def build(self, target=None):
cmd += " -j{}".format(njobs)
if target:
cmd += " {}".format(target)
verbosity = self._build_verbosity
if verbosity:
cmd += " " + verbosity
self._conanfile.output.info("Meson build cmd: {}".format(cmd))
self._conanfile.run(cmd)

Expand All @@ -78,6 +82,9 @@ def install(self):
self.configure(reconfigure=True) # To re-do the destination package-folder
meson_build_folder = self._conanfile.build_folder
cmd = 'meson install -C "{}"'.format(meson_build_folder)
verbosity = self._install_verbosity
if verbosity:
cmd += " " + verbosity
self._conanfile.run(cmd)

def test(self):
Expand All @@ -91,3 +98,19 @@ def test(self):
# TODO: Do we need vcvars for test?
# TODO: This should use conanrunenv, but what if meson itself is a build-require?
self._conanfile.run(cmd)

@property
def _build_verbosity(self):
# verbosity of build tools. This passes -v to ninja, for example.
# See https://github.com/mesonbuild/meson/blob/master/mesonbuild/mcompile.py#L156
verbosity = self._conanfile.conf.get("tools.compilation:verbosity",
choices=("quiet", "verbose"))
return "--verbose" if verbosity == "verbose" else ""

@property
def _install_verbosity(self):
# https://github.com/mesonbuild/meson/blob/master/mesonbuild/minstall.py#L81
# Errors are always logged, and status about installed files is controlled by this flag,
# so it's a bit backwards
verbosity = self._conanfile.conf.get("tools.build:verbosity", choices=("quiet", "verbose"))
return "--quiet" if verbosity else ""
34 changes: 13 additions & 21 deletions conan/tools/microsoft/msbuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,19 @@


def msbuild_verbosity_cmd_line_arg(conanfile):
verbosity = conanfile.conf.get("tools.build:verbosity")
if verbosity:
if verbosity not in ("quiet", "error", "warning", "notice", "status", "verbose",
"normal", "debug", "v", "trace", "vv"):
raise ConanException(f"Unknown value '{verbosity}' for 'tools.build:verbosity'")
else:
# "Quiet", "Minimal", "Normal", "Detailed", "Diagnostic"
verbosity = {
"quiet": "Quiet",
"error": "Minimal",
"warning": "Minimal",
"notice": "Minimal",
"status": "Normal",
"verbose": "Normal",
"normal": "Normal",
"debug": "Detailed",
"v": "Detailed",
"trace": "Diagnostic",
"vv": "Diagnostic"
}.get(verbosity)
return '/verbosity:{}'.format(verbosity)
"""
Controls msbuild verbosity.
See https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-command-line-reference
:return:
"""
verbosity = conanfile.conf.get("tools.build:verbosity", choices=("quiet", "verbose"))
if verbosity is not None:
verbosity = {
"quiet": "Quiet",
"verbose": "Detailed",
}.get(verbosity)
return f'/verbosity:{verbosity}'
return ""


def msbuild_arch(arch):
Expand Down
12 changes: 7 additions & 5 deletions conans/model/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
"tools.build:sysroot": "Pass the --sysroot=<tools.build:sysroot> flag if available. (None by default)",
"tools.build.cross_building:can_run": "Bool value that indicates whether is possible to run a non-native "
"app on the same architecture. It's used by 'can_run' tool",
"tools.build:verbosity": "Verbosity of MSBuild and XCodeBuild build systems. "
"Possible values are 'quiet', 'error', 'warning', 'notice', 'status', 'verbose', 'normal', 'debug', 'v', 'trace' and 'vv'",
"tools.build:verbosity": "Verbosity of build systems if set. Possible values are 'quiet' and 'verbose'",
"tools.compilation:verbosity": "Verbosity of compilation tools if set. Possible values are 'quiet' and 'verbose'",
"tools.cmake.cmaketoolchain:generator": "User defined CMake generator to use instead of default",
"tools.cmake.cmaketoolchain:find_package_prefer_config": "Argument for the CMAKE_FIND_PACKAGE_PREFER_CONFIG",
"tools.cmake.cmaketoolchain:toolchain_file": "Use other existing file rather than conan_toolchain.cmake one",
Expand Down Expand Up @@ -275,7 +275,7 @@ def items(self):
for k, v in self._values.items():
yield k, v.value

def get(self, conf_name, default=None, check_type=None):
def get(self, conf_name, default=None, check_type=None, choices=None):
"""
Get all the values of the given configuration name.
Expand All @@ -290,6 +290,8 @@ def get(self, conf_name, default=None, check_type=None):
conf_value = self._values.get(conf_name)
if conf_value:
v = conf_value.value
if choices is not None and v not in choices:
raise ConanException(f"Unknown value '{v}' for '{conf_name}'")
# Some smart conversions
if check_type is bool and not isinstance(v, bool):
# Perhaps, user has introduced a "false", "0" or even "off"
Expand Down Expand Up @@ -498,13 +500,13 @@ def __repr__(self):
def __bool__(self):
return bool(self._pattern_confs)

def get(self, conf_name, default=None, check_type=None):
def get(self, conf_name, default=None, check_type=None, choices=None):
"""
Get the value of the conf name requested and convert it to the [type]-like passed.
"""
pattern, name = self._split_pattern_name(conf_name)
return self._pattern_confs.get(pattern, Conf()).get(name, default=default,
check_type=check_type)
check_type=check_type, choices=choices)

def show(self, fnpattern):
"""
Expand Down
3 changes: 2 additions & 1 deletion conans/test/functional/toolchains/apple/test_xcodebuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ def package_info(self):
client.run("install . --build=missing")
client.run("install . -s build_type=Debug --build=missing")
client.run_command("xcodegen generate")
client.run("create . --build=missing")
client.run("create . --build=missing -c tools.build:verbosity=verbose -c tools.compilation:verbosity=verbose")
assert "xcodebuild: error: invalid option" not in client.out
assert "hello/0.1: Hello World Release!" in client.out
assert "App Release!" in client.out
client.run("create . -s build_type=Debug --build=missing")
Expand Down
6 changes: 5 additions & 1 deletion conans/test/functional/toolchains/cmake/test_cmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,10 @@ def package(self):
"header.h": "# my header file"})

# The create flow must work
client.run("create . --name=pkg --version=0.1")
client.run("create . --name=pkg --version=0.1 -c tools.build:verbosity=verbose -c tools.compilation:verbosity=verbose")
assert "--loglevel=VERBOSE" in client.out
assert "unrecognized option" not in client.out
assert "--verbose" in client.out
self.assertIn("pkg/0.1: package(): Packaged 1 '.h' file: header.h", client.out)
ref = RecipeReference.loads("pkg/0.1")
pref = client.get_latest_package_reference(ref)
Expand Down Expand Up @@ -730,3 +733,4 @@ def build(self):

client.run("build . --profile=profile_false")
assert "using FindComandante.cmake" in client.out

3 changes: 2 additions & 1 deletion conans/test/functional/toolchains/meson/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,6 @@ def test_install(self):
os.path.join("test_package", "CMakeLists.txt"): self._test_package_cmake_lists,
os.path.join("test_package", "src", "test_package.cpp"): test_package_cpp})

self.t.run("create . --name=hello --version=0.1")
self.t.run("create . --name=hello --version=0.1 -c tools.compilation:verbosity=verbose")
assert "--verbose" in self.t.out
self._check_binary()
7 changes: 6 additions & 1 deletion conans/test/functional/toolchains/meson/test_meson.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,12 @@ def test(self):
"conanfile.py": conanfile,
"test_package/conanfile.py": test_conanfile,
"src/file1.txt": "", "src/file2.txt": ""})
self.t.run("create .")
self.t.run("create . -c tools.build:verbosity=quiet -c tools.compilation:verbosity=verbose")
# Check verbosity control
assert "unrecognized arguments" not in self.t.out
assert re.search("meson compile .*? --verbose", self.t.out)
assert re.search("meson install .*? --quiet", self.t.out)

# Check if all the files are in the final directories
ref = RecipeReference.loads("hello/1.0")
pref = self.t.get_latest_package_reference(ref)
Expand Down
5 changes: 4 additions & 1 deletion conans/test/functional/toolchains/microsoft/test_msbuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,10 @@ def check_toolchain_win(self, compiler, version, runtime, cppstd, ide_version):
settings_b = " ".join('-s:b %s="%s"' % (k, v) for k, v in settings if v)

client.run("new cmake_lib -d name=hello -d version=0.1")
client.run(f"create . {settings_h} -c tools.microsoft.msbuild:vs_version={ide_version}")
client.run(f"create . {settings_h} -c tools.microsoft.msbuild:vs_version={ide_version} -c tools.build:verbosity=verbose -c tools.compilation:verbosity=verbose")

assert "MSBUILD : error MSB1001: Unknown switch" not in client.out
assert "/verbosity:Detailed" in client.out

# Prepare the actual consumer package
client.save({"conanfile.py": self.conanfile,
Expand Down
22 changes: 11 additions & 11 deletions conans/test/integration/configuration/conf/test_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def test_basic_composition(client):
""")
profile2 = textwrap.dedent("""\
[conf]
tools.build:verbosity=notice
tools.build:verbosity=quiet
tools.microsoft.msbuild:max_cpu_count=High
tools.meson.mesontoolchain:backend=Super
""")
Expand All @@ -47,7 +47,7 @@ def test_basic_composition(client):
assert "tools.cmake.cmaketoolchain:generator$Extra" in client.out

client.run("install . -pr=profile1 -pr=profile2")
assert "tools.build:verbosity$notice" in client.out
assert "tools.build:verbosity$quiet" in client.out
assert "tools.microsoft.msbuild:vs_version$Slow" in client.out
assert "tools.microsoft.msbuild:max_cpu_count$High" in client.out
assert "tools.cmake.cmaketoolchain:generator$Extra" in client.out
Expand All @@ -71,15 +71,15 @@ def test_basic_inclusion(client):
profile2 = textwrap.dedent("""\
include(profile1)
[conf]
tools.build:verbosity=notice
tools.build:verbosity=quiet
tools.microsoft.msbuild:max_cpu_count=High
tools.meson.mesontoolchain:backend=Super
""")
client.save({"profile1": profile1,
"profile2": profile2})

client.run("install . -pr=profile2")
assert "tools.build:verbosity$notice" in client.out
assert "tools.build:verbosity$quiet" in client.out
assert "tools.microsoft.msbuild:vs_version$Slow" in client.out
assert "tools.microsoft.msbuild:max_cpu_count$High" in client.out
assert "tools.cmake.cmaketoolchain:generator$Extra" in client.out
Expand All @@ -95,13 +95,13 @@ def test_composition_conan_conf(client):
save(client.cache.new_config_path, conf)
profile = textwrap.dedent("""\
[conf]
tools.build:verbosity=notice
tools.build:verbosity=quiet
tools.microsoft.msbuild:max_cpu_count=High
tools.meson.mesontoolchain:backend=Super
""")
client.save({"profile": profile})
client.run("install . -pr=profile")
assert "tools.build:verbosity$notice" in client.out
assert "tools.build:verbosity$quiet" in client.out
assert "tools.microsoft.msbuild:vs_version$Slow" in client.out
assert "tools.microsoft.msbuild:max_cpu_count$High" in client.out
assert "tools.cmake.cmaketoolchain:generator$Extra" in client.out
Expand All @@ -110,13 +110,13 @@ def test_composition_conan_conf(client):

def test_new_config_file(client):
conf = textwrap.dedent("""\
tools.build:verbosity=notice
tools.build:verbosity=quiet
user.mycompany.myhelper:myconfig=myvalue
*:tools.cmake.cmaketoolchain:generator=X
""")
save(client.cache.new_config_path, conf)
client.run("install .")
assert "tools.build:verbosity$notice" in client.out
assert "tools.build:verbosity$quiet" in client.out
assert "user.mycompany.myhelper:myconfig$myvalue" in client.out
assert "tools.cmake.cmaketoolchain:generator$X" in client.out
assert "read_only" not in client.out
Expand Down Expand Up @@ -153,13 +153,13 @@ def test_composition_conan_conf_overwritten_by_cli_arg(client):
save(client.cache.new_config_path, conf)
profile = textwrap.dedent("""\
[conf]
tools.build:verbosity=notice
tools.build:verbosity=quiet
tools.microsoft.msbuild:vs_version=High
""")
client.save({"profile": profile})
client.run("install . -pr=profile -c tools.build:verbosity=debug "
client.run("install . -pr=profile -c tools.build:verbosity=verbose "
"-c tools.meson.mesontoolchain:backend=Super")
assert "tools.build:verbosity$debug" in client.out
assert "tools.build:verbosity$verbose" in client.out
assert "tools.microsoft.msbuild:max_cpu_count$Slow" in client.out
assert "tools.microsoft.msbuild:vs_version$High" in client.out
assert "tools.meson.mesontoolchain:backend$Super" in client.out
Expand Down
Loading

0 comments on commit 401220b

Please sign in to comment.