Skip to content

Commit

Permalink
Fix cmake build --config XXXX for multi-config with hardcoded configu…
Browse files Browse the repository at this point in the history
…rations (#14780)

* cmake build --config XXXX

* fix
  • Loading branch information
memsharded authored Feb 15, 2024
1 parent bdd05c5 commit 2111d5a
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 12 deletions.
34 changes: 22 additions & 12 deletions conan/tools/cmake/cmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ def __init__(self, conanfile):

self._cmake_program = conanfile.conf.get("tools.cmake:cmake_program", default="cmake")

@property
def is_multi_configuration(self):
return is_multi_configuration(self._generator)

def configure(self, variables=None, build_script_folder=None, cli_args=None,
stdout=None, stderr=None):
"""
Expand Down Expand Up @@ -117,18 +121,28 @@ def configure(self, variables=None, build_script_folder=None, cli_args=None,
with chdir(self, build_folder):
self._conanfile.run(command, stdout=stdout, stderr=stderr)

def _build(self, build_type=None, target=None, cli_args=None, build_tool_args=None, env="",
stdout=None, stderr=None):
bf = self._conanfile.build_folder
def _config_arg(self, build_type):
""" computes the '--config Release' arg when necessary, or warn or error if wrong
"""
is_multi = is_multi_configuration(self._generator)
if build_type and not is_multi:
self._conanfile.output.error("Don't specify 'build_type' at build time for "
"single-config build systems")
if not build_type:
try:
build_type = self._conanfile.settings.build_type # declared, but can be None
if not build_type:
raise ConanException("CMake: build_type setting should be defined.")
except ConanException:
if is_multi:
raise ConanException("CMake: build_type setting should be defined.")
build_config = "--config {}".format(build_type) if build_type and is_multi else ""
return build_config

bt = build_type or self._conanfile.settings.get_safe("build_type")
if not bt:
raise ConanException("build_type setting should be defined.")
build_config = "--config {}".format(bt) if bt and is_multi else ""
def _build(self, build_type=None, target=None, cli_args=None, build_tool_args=None, env="",
stdout=None, stderr=None):
bf = self._conanfile.build_folder
build_config = self._config_arg(build_type)

args = []
if target is not None:
Expand Down Expand Up @@ -191,11 +205,7 @@ def install(self, build_type=None, component=None, cli_args=None, stdout=None, s
self._conanfile.output.info("Running CMake.install()")
mkdir(self._conanfile, self._conanfile.package_folder)

bt = build_type or self._conanfile.settings.get_safe("build_type")
if not bt:
raise ConanException("build_type setting should be defined.")
is_multi = is_multi_configuration(self._generator)
build_config = "--config {}".format(bt) if bt and is_multi else ""
build_config = self._config_arg(build_type)

pkg_folder = '"{}"'.format(self._conanfile.package_folder.replace("\\", "/"))
build_folder = '"{}"'.format(self._conanfile.build_folder)
Expand Down
5 changes: 5 additions & 0 deletions conan/tools/cmake/toolchain/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
AndroidSystemBlock, AppleSystemBlock, FPicBlock, ArchitectureBlock, GLibCXXBlock, VSRuntimeBlock, \
CppStdBlock, ParallelBlock, CMakeFlagsInitBlock, TryCompileBlock, FindFiles, PkgConfigBlock, \
SkipRPath, SharedLibBock, OutputDirsBlock, ExtraFlagsBlock, CompilersBlock, LinkerScriptsBlock
from conan.tools.cmake.utils import is_multi_configuration
from conan.tools.env import VirtualBuildEnv, VirtualRunEnv
from conan.tools.intel import IntelCC
from conan.tools.microsoft import VCVars
Expand Down Expand Up @@ -190,6 +191,10 @@ def content(self):
content = relativize_generated_file(content, self._conanfile, "${CMAKE_CURRENT_LIST_DIR}")
return content

@property
def is_multi_configuration(self):
return is_multi_configuration(self.generator)

def _find_cmake_exe(self):
for req in self._conanfile.dependencies.direct_build.values():
if req.ref.name == "cmake":
Expand Down
45 changes: 45 additions & 0 deletions conans/test/functional/toolchains/cmake/test_cmake_toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,51 @@ def build(self):
assert "-- MYVAR1 MYVALUE1!!" in client.out


def test_no_build_type():
client = TestClient()

conanfile = textwrap.dedent("""
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain
class AppConan(ConanFile):
name = "pkg"
version = "1.0"
settings = "os", "compiler", "arch"
exports_sources = "CMakeLists.txt"
def layout(self):
self.folders.build = "build"
def generate(self):
tc = CMakeToolchain(self)
if not tc.is_multi_configuration:
tc.cache_variables["CMAKE_BUILD_TYPE"] = "Release"
tc.generate()
def build(self):
cmake = CMake(self)
cmake.configure()
build_type = "Release" if cmake.is_multi_configuration else None
cmake.build(build_type=build_type)
def package(self):
cmake = CMake(self)
build_type = "Release" if cmake.is_multi_configuration else None
cmake.install(build_type=build_type)
""")

cmake = """
cmake_minimum_required(VERSION 3.15)
project(pkg LANGUAGES NONE)
"""

client.save({"conanfile.py": conanfile,
"CMakeLists.txt": cmake})
client.run("create .")
assert "Don't specify 'build_type' at build time" not in client.out


@pytest.mark.tool("cmake", "3.19")
def test_redirect_stdout():
client = TestClient()
Expand Down

0 comments on commit 2111d5a

Please sign in to comment.