Skip to content

Commit

Permalink
[develop2] improve build_folder_vars, only affecting in user space (#…
Browse files Browse the repository at this point in the history
…13109)

* [develop2] improve build_folder_vars, only affecting in user space

* fix test
  • Loading branch information
memsharded authored Feb 13, 2023
1 parent ca97205 commit 0a21fc1
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 23 deletions.
23 changes: 18 additions & 5 deletions conan/tools/cmake/layout.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os

from conans.client.graph.graph import RECIPE_CONSUMER
from conans.errors import ConanException


Expand Down Expand Up @@ -50,13 +51,22 @@ def cmake_layout(conanfile, generator=None, src_folder=".", build_folder="build"


def get_build_folder_custom_vars(conanfile):

conanfile_vars = conanfile.folders.build_folder_vars
build_vars = conanfile.conf.get("tools.cmake.cmake_layout:build_folder_vars", check_type=list)
if conanfile.tested_reference_str:
build_vars = ["settings.compiler", "settings.compiler.version", "settings.arch",
build_vars = build_vars or conanfile_vars or \
["settings.compiler", "settings.compiler.version", "settings.arch",
"settings.compiler.cppstd", "settings.build_type", "options.shared"]
else:
build_vars = conanfile.conf.get("tools.cmake.cmake_layout:build_folder_vars",
default=[], check_type=list)
try:
is_consumer = conanfile._conan_node.recipe == RECIPE_CONSUMER
except AttributeError:
is_consumer = False
if is_consumer:
build_vars = build_vars or conanfile_vars or []
else:
build_vars = conanfile_vars or []

ret = []
for s in build_vars:
group, var = s.split(".", 1)
Expand All @@ -66,7 +76,10 @@ def get_build_folder_custom_vars(conanfile):
elif group == "options":
value = conanfile.options.get_safe(var)
if value is not None:
tmp = "{}_{}".format(var, value)
if var == "shared":
tmp = "shared" if value else "static"
else:
tmp = "{}_{}".format(var, value)
else:
raise ConanException("Invalid 'tools.cmake.cmake_layout:build_folder_vars' value, it has"
" to start with 'settings.' or 'options.': {}".format(s))
Expand Down
1 change: 1 addition & 0 deletions conans/model/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(self):
# conanfile.py, that makes most of the output folders defined in layouts (cmake_layout, etc)
# start from the subproject again
self.subproject = None
self.build_folder_vars = None

def __repr__(self):
return str(self.__dict__)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -744,14 +744,14 @@ def test_cmake_presets_options_single_config():

for shared in (True, False):
client.run("install . {} -o shared={}".format(conf_layout, shared))
shared_str = "shared_true" if shared else "shared_false"
shared_str = "shared" if shared else "static"
assert os.path.exists(os.path.join(client.current_folder,
"build", "{}-release-{}".format(default_compiler, shared_str),
"generators"))

client.run("install . {}".format(conf_layout))
assert os.path.exists(os.path.join(client.current_folder,
"build", "{}-release-shared_false".format(default_compiler),
"build", "{}-release-static".format(default_compiler),
"generators"))

user_presets_path = os.path.join(client.current_folder, "CMakeUserPresets.json")
Expand All @@ -760,7 +760,7 @@ def test_cmake_presets_options_single_config():
# We can build with cmake manually
if platform.system() == "Darwin":
for shared in (True, False):
shared_str = "shared_true" if shared else "shared_false"
shared_str = "shared" if shared else "static"
client.run_command("cmake . --preset conan-apple-clang-release-{}".format(shared_str))
client.run_command("cmake --build --preset conan-apple-clang-release-{}".format(shared_str))
client.run_command("ctest --preset conan-apple-clang-release-{}".format(shared_str))
Expand Down
71 changes: 56 additions & 15 deletions conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from conan.tools.cmake.presets import load_cmake_presets
from conans.test.assets.genconanfile import GenConanfile
from conans.test.utils.tools import TestClient
from conans.util.files import rmdir
from conans.util.files import rmdir, load


def test_cross_build():
Expand Down Expand Up @@ -957,7 +957,6 @@ def test_test_package_layout():
class Conan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "CMakeToolchain"
test_type = "explicit"
def requirements(self):
self.requires(self.tested_reference_str)
Expand All @@ -982,27 +981,69 @@ def test(self):

def test_presets_not_found_error_msg():
client = TestClient()
test_conanfile = textwrap.dedent("""
conanfile = textwrap.dedent("""
from conan import ConanFile
from conan.tools.cmake import cmake_layout, CMake
from conan.tools.cmake import CMake
class Conan(ConanFile):
settings = "build_type"
generators = "CMakeDeps"
test_type = "explicit"
def requirements(self):
self.requires(self.tested_reference_str)
def build(self):
CMake(self).configure()
def test(self):
pass
""")
client.save({"conanfile.py": GenConanfile("pkg", "0.1"),
"test_package/conanfile.py": test_conanfile})
client.run("create .", assert_error=True)
client.save({"conanfile.py": conanfile})
client.run("build .", assert_error=True)
assert "CMakePresets.json was not found" in client.out
assert "Check that you are using CMakeToolchain as generator " \
"to ensure its correct initialization." in client.out


def test_recipe_build_folders_vars():
client = TestClient()
conanfile = textwrap.dedent("""
from conan import ConanFile
from conan.tools.cmake import cmake_layout
class Conan(ConanFile):
name = "pkg"
version = "0.1"
settings = "os", "arch", "build_type"
options = {"shared": [True, False]}
generators = "CMakeToolchain"
def layout(self):
self.folders.build_folder_vars = ["settings.os", "options.shared"]
cmake_layout(self)
""")
client.save({"conanfile.py": conanfile})
client.run("install . -s os=Windows -s arch=armv8 -s build_type=Debug -o shared=True")
presets = client.load("build/windows-shared/Debug/generators/CMakePresets.json")
assert "conan-windows-shared-debug" in presets
client.run("install . -s os=Linux -s arch=x86 -s build_type=Release -o shared=False")
presets = client.load("build/linux-static/Release/generators/CMakePresets.json")
assert "linux-static-release" in presets

# CLI override has priority
client.run("install . -s os=Linux -s arch=x86 -s build_type=Release -o shared=False "
"-c tools.cmake.cmake_layout:build_folder_vars='[\"settings.os\"]'")
presets = client.load("build/linux/Release/generators/CMakePresets.json")
assert "conan-linux-release" in presets

# Now we do the build in the cache, the recipe folders are still used
client.run("create . -s os=Windows -s arch=armv8 -s build_type=Debug -o shared=True")
ref = client.created_package_reference("pkg/0.1")
layout = client.get_latest_pkg_layout(ref)
build_folder = layout.build()
presets = load(os.path.join(build_folder,
"build/windows-shared/Debug/generators/CMakePresets.json"))
assert "conan-windows-shared-debug" in presets

# If we change the conf ``build_folder_vars``, it doesn't affect the cache build
client.run("create . -s os=Windows -s arch=armv8 -s build_type=Debug -o shared=True "
"-c tools.cmake.cmake_layout:build_folder_vars='[\"settings.os\"]'")
ref = client.created_package_reference("pkg/0.1")
layout = client.get_latest_pkg_layout(ref)
build_folder = layout.build()
presets = load(os.path.join(build_folder,
"build/windows-shared/Debug/generators/CMakePresets.json"))
assert "conan-windows-shared-debug" in presets

0 comments on commit 0a21fc1

Please sign in to comment.