Skip to content

Commit

Permalink
CMakeDeps checks build profile + CMakeDeps check real targets (#9206)
Browse files Browse the repository at this point in the history
* CMakeDeps checks build profile + CMakeDeps check real targets

* Added test of a build module declaring component targets

* Default check False and introduced switch

* Moved test and removed duplicated ones

* Recover test
  • Loading branch information
lasote authored Jul 7, 2021
1 parent 5012375 commit 38bf9b7
Show file tree
Hide file tree
Showing 17 changed files with 262 additions and 59 deletions.
10 changes: 10 additions & 0 deletions conan/tools/_check_build_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

check_msg = "Using the new toolchains and generators without specifying " \
"a build profile (e.g: -pr:b=default) is discouraged and "\
"might cause failures and unexpected behavior"


def check_using_build_profile(conanfile):
"""FIXME: Remove this in Conan 2.0 where the two profiles are always applied"""
if not hasattr(conanfile, "settings_build"):
conanfile.output.warn(check_msg)
14 changes: 14 additions & 0 deletions conan/tools/cmake/cmakedeps/cmakedeps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os

from conan.tools._check_build_profile import check_using_build_profile
from conan.tools.cmake.cmakedeps.templates.config import ConfigTemplate
from conan.tools.cmake.cmakedeps.templates.config_version import ConfigVersionTemplate
from conan.tools.cmake.cmakedeps.templates.macros import MacrosTemplate
Expand All @@ -26,7 +27,20 @@ def __init__(self, conanfile):
# a suffix. It is necessary in case of same require and build_require and will cause an error
self.build_context_suffix = {}

check_using_build_profile(self._conanfile)

# Enable/Disable checking if a component target exists or not
self.check_components_exist = False

def generate(self):
# FIXME: Remove this in 2.0
if not hasattr(self._conanfile, "settings_build") and \
(self.build_context_activated or self.build_context_build_modules or
self.build_context_suffix):
raise ConanException("The 'build_context_activated' and 'build_context_build_modules' of"
" the CMakeDeps generator cannot be used without specifying a build"
" profile. e.g: -pr:b=default")

# Current directory is the generators_folder
generator_files = self.content
for generator_file, content in generator_files.items():
Expand Down
19 changes: 17 additions & 2 deletions conan/tools/cmake/cmakedeps/templates/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ def filename(self):
def context(self):
return {"file_name": self.file_name,
"pkg_name": self.pkg_name,
"config_suffix": self.config_suffix}
"config_suffix": self.config_suffix,
"target_namespace": self.target_namespace,
"check_components_exist": self.cmakedeps.check_components_exist}

@property
def template(self):
Expand All @@ -45,10 +47,23 @@ def template(self):
endif()
endforeach()
# Only the first installed configuration is included to avoid the collission
# Only the first installed configuration is included to avoid the collision
foreach(_BUILD_MODULE {{ '${' + pkg_name + '_BUILD_MODULES_PATHS' + config_suffix + '}' }} )
conan_message(STATUS "Conan: Including build module from '${_BUILD_MODULE}'")
include({{ '${_BUILD_MODULE}' }})
endforeach()
{% if check_components_exist %}
# Check that the specified components in the find_package(Foo COMPONENTS x y z) are there
# This is the variable filled by CMake with the requested components in find_package
if({{ target_namespace }}_FIND_COMPONENTS)
foreach(_FIND_COMPONENT {{ '${'+target_namespace+'_FIND_COMPONENTS}' }})
if (TARGET {{ target_namespace }}::${_FIND_COMPONENT})
conan_message(STATUS "Conan: Component '${_FIND_COMPONENT}' found in package '{{ pkg_name }}'")
else()
conan_message(FATAL_ERROR "Conan: Component '${_FIND_COMPONENT}' NOT found in package '{{ pkg_name }}'")
endif()
endforeach()
endif()
{% endif %}
""")
1 change: 0 additions & 1 deletion conan/tools/cmake/cmakedeps/templates/target_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,3 @@ def join_paths_single_var(values):

build_modules = cpp_info.get_property("cmake_build_modules", "CMakeDeps") or []
self.build_modules_paths = join_paths(build_modules)

12 changes: 0 additions & 12 deletions conan/tools/cmake/cmakedeps/templates/targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,4 @@ def template(self):
foreach(f ${CONFIG_FILES})
include(${f})
endforeach()
# This is the variable filled by CMake with the requested components in find_package
if({{ target_namespace }}_FIND_COMPONENTS)
foreach(_FIND_COMPONENT {{ '${'+target_namespace+'_FIND_COMPONENTS}' }})
list(FIND {{ pkg_name }}_COMPONENT_NAMES "${_FIND_COMPONENT}" _index)
if(${_index} EQUAL -1)
conan_message(FATAL_ERROR "Conan: Component '${_FIND_COMPONENT}' NOT found in package '{{ pkg_name }}'")
else()
conan_message(STATUS "Conan: Component '${_FIND_COMPONENT}' found in package '{{ pkg_name }}'")
endif()
endforeach()
endif()
""")
3 changes: 3 additions & 0 deletions conan/tools/cmake/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from jinja2 import Template

from conan.tools import CONAN_TOOLCHAIN_ARGS_FILE
from conan.tools._check_build_profile import check_using_build_profile
from conan.tools._compilers import architecture_flag, use_win_mingw
from conan.tools.cmake.utils import is_multi_configuration, get_file_name
from conan.tools.microsoft.toolchain import write_conanvcvars
Expand Down Expand Up @@ -699,6 +700,8 @@ def __init__(self, conanfile, generator=None):
("rpath", SkipRPath),
("shared", SharedLibBock)])

check_using_build_profile(self._conanfile)

def _context(self):
""" Returns dict, the context for the template
"""
Expand Down
2 changes: 2 additions & 0 deletions conan/tools/gnu/autotoolsdeps.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from conan.tools._check_build_profile import check_using_build_profile
from conan.tools.env import Environment
from conan.tools.gnu.gnudeps_flags import GnuDepsFlags
from conans.model.new_build_info import NewCppInfo
Expand All @@ -9,6 +10,7 @@ def __init__(self, conanfile):
# alter some value
self._conanfile = conanfile
self._cpp_info = None
check_using_build_profile(self._conanfile)

@property
def cpp_info(self):
Expand Down
3 changes: 3 additions & 0 deletions conan/tools/gnu/autotoolstoolchain.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json

from conan.tools import CONAN_TOOLCHAIN_ARGS_FILE
from conan.tools._check_build_profile import check_using_build_profile
from conan.tools._compilers import architecture_flag, build_type_flags, cppstd_flag
from conan.tools.apple.apple import apple_min_version_flag, to_apple_arch, \
apple_sdk_path
Expand Down Expand Up @@ -62,6 +63,8 @@ def __init__(self, conanfile):
# -isysroot makes all includes for your library relative to the build directory
self.apple_isysroot_flag = "-isysroot {}".format(sdk_path) if sdk_path else None

check_using_build_profile(self._conanfile)

def _cxx11_abi_define(self):
# https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
# The default is libstdc++11, only specify the contrary '_GLIBCXX_USE_CXX11_ABI=0'
Expand Down
2 changes: 2 additions & 0 deletions conan/tools/google/bazeldeps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

from jinja2 import Template

from conan.tools._check_build_profile import check_using_build_profile
from conans.util.files import save


class BazelDeps(object):
def __init__(self, conanfile):
self._conanfile = conanfile
check_using_build_profile(self._conanfile)

def generate(self):
local_repositories = []
Expand Down
2 changes: 2 additions & 0 deletions conan/tools/google/toolchain.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import json

from conan.tools import CONAN_TOOLCHAIN_ARGS_FILE
from conan.tools._check_build_profile import check_using_build_profile
from conans.util.files import save


class BazelToolchain(object):

def __init__(self, conanfile):
self._conanfile = conanfile
check_using_build_profile(self._conanfile)

def generate(self):
bazel_config = self._conanfile.conf["tools.google.bazel:config"]
Expand Down
3 changes: 3 additions & 0 deletions conan/tools/meson/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from jinja2 import Template

from conan.tools._check_build_profile import check_using_build_profile
from conan.tools.env import VirtualBuildEnv
from conan.tools.microsoft.toolchain import write_conanvcvars
from conans.client.build.cppstd_flags import cppstd_from_settings
Expand Down Expand Up @@ -112,6 +113,8 @@ def from_build_env(name):
self.cpp_link_args = self._to_meson_value(self._env_array('LDFLAGS'))
self.pkg_config_path = "'%s'" % self._conanfile.generators_folder

check_using_build_profile(self._conanfile)

@staticmethod
def _to_meson_value(value):
# https://mesonbuild.com/Machine-files.html#data-types
Expand Down
3 changes: 3 additions & 0 deletions conan/tools/microsoft/msbuilddeps.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from jinja2 import Template

from conan.tools._check_build_profile import check_using_build_profile
from conans.errors import ConanException
from conans.model.build_info import DepCppInfo
from conans.util.files import load, save
Expand Down Expand Up @@ -109,6 +110,8 @@ def __init__(self, conanfile):
raise ConanException("tools.microsoft.msbuilddeps:exclude_code_analysis must be a"
" list of package names patterns like ['pkga*']")

check_using_build_profile(self._conanfile)

def generate(self):
# TODO: Apply config from command line, something like
# configuration = self.conanfile.config.generators["msbuild"].configuration
Expand Down
2 changes: 2 additions & 0 deletions conan/tools/microsoft/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import textwrap
from xml.dom import minidom

from conan.tools._check_build_profile import check_using_build_profile
from conan.tools.env.environment import register_environment_script
from conan.tools.microsoft.visual import vcvars_command, vcvars_arch
from conans.client.tools import intel_compilervars_command
Expand Down Expand Up @@ -87,6 +88,7 @@ def __init__(self, conanfile):
self.runtime_library = self._runtime_library(conanfile.settings)
self.cppstd = conanfile.settings.get_safe("compiler.cppstd")
self.toolset = self._msvs_toolset(conanfile.settings)
check_using_build_profile(self._conanfile)

def _name_condition(self, settings):
props = [("Configuration", self.configuration),
Expand Down
1 change: 1 addition & 0 deletions conans/test/assets/genconanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ def with_cmake_build(self):
self._generators = self._generators or []
self._generators.append("CMakeDeps")
self._generators.append("CMakeToolchain")
self.with_settings("os", "compiler", "arch", "build_type")
self._cmake_build = True
return self

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pytest

from conans.model.ref import ConanFileReference, PackageReference
from conans.test.assets.genconanfile import GenConanfile
from conans.test.utils.tools import TestClient, NO_SETTINGS_PACKAGE_ID


Expand Down Expand Up @@ -266,3 +267,4 @@ def test_multi_generator_macos(self):
assert str(t.out).count('>> Build-module is included') == 2 # FIXME: Known bug
assert '>> nonamespace libs: library::library' in t.out
t.run_command('cmake --build . --config Release') # Compiles and links.

Loading

0 comments on commit 38bf9b7

Please sign in to comment.