diff --git a/conans/client/generators/cmake_find_package.py b/conans/client/generators/cmake_find_package.py index c108a3c4bf7..6c1ff2def60 100644 --- a/conans/client/generators/cmake_find_package.py +++ b/conans/client/generators/cmake_find_package.py @@ -56,7 +56,8 @@ def _find_for_dep(self, name, cpp_info): lines = [] if cpp_info.public_deps: # Here we are generating FindXXX, so find_modules=True - lines = find_dependency_lines(name, cpp_info, find_modules=True) + public_deps_names = [self.deps_build_info[dep].name for dep in cpp_info.public_deps] + lines = find_dependency_lines(name, public_deps_names, find_modules=True) find_package_header_block = find_package_header.format(name=name, version=cpp_info.version) find_libraries_block = target_template.format(name=name, deps=deps, build_type_suffix="") target_props = assign_target_properties.format(name=name, deps=deps) @@ -69,26 +70,26 @@ def _find_for_dep(self, name, cpp_info): return tmp -def find_dependency_lines(name, cpp_info, find_modules): +def find_dependency_lines(name, public_deps_names, find_modules): lines = ["", "# Library dependencies", "include(CMakeFindDependencyMacro)"] - for dep in cpp_info.public_deps: + for dep_name in public_deps_names: def property_lines(prop): lib_t = "%s::%s" % (name, name) - dep_t = "%s::%s" % (dep, dep) + dep_t = "%s::%s" % (dep_name, dep_name) return ["get_target_property(tmp %s %s)" % (dep_t, prop), "if(tmp)", " set_property(TARGET %s APPEND PROPERTY %s ${tmp})" % (lib_t, prop), 'endif()'] if find_modules: - lines.append("find_dependency(%s REQUIRED)" % dep) + lines.append("find_dependency(%s REQUIRED)" % dep_name) else: # https://github.com/conan-io/conan/issues/4994 # https://github.com/conan-io/conan/issues/5040 lines.append('if(${CMAKE_VERSION} VERSION_LESS "3.9.0")') - lines.append(' find_package(%s REQUIRED NO_MODULE)' % dep) + lines.append(' find_package(%s REQUIRED NO_MODULE)' % dep_name) lines.append("else()") - lines.append(' find_dependency(%s REQUIRED NO_MODULE)' % dep) + lines.append(' find_dependency(%s REQUIRED NO_MODULE)' % dep_name) lines.append("endif()") lines.extend(property_lines("INTERFACE_LINK_LIBRARIES")) diff --git a/conans/client/generators/cmake_find_package_multi.py b/conans/client/generators/cmake_find_package_multi.py index aa126bc91af..5585b5163b0 100644 --- a/conans/client/generators/cmake_find_package_multi.py +++ b/conans/client/generators/cmake_find_package_multi.py @@ -88,7 +88,8 @@ def _find_for_dep(self, name, cpp_info): lines = [] if cpp_info.public_deps: # Here we are generating only Config files, so do not search for FindXXX modules - lines = find_dependency_lines(name, cpp_info, find_modules=False) + public_deps_names = [self.deps_build_info[dep].name for dep in cpp_info.public_deps] + lines = find_dependency_lines(name, public_deps_names, find_modules=False) targets_props = self.target_properties.format(name=name) diff --git a/conans/test/functional/generators/cmake_find_package_multi_test.py b/conans/test/functional/generators/cmake_find_package_multi_test.py index a2379bff13f..bac5cdacbee 100644 --- a/conans/test/functional/generators/cmake_find_package_multi_test.py +++ b/conans/test/functional/generators/cmake_find_package_multi_test.py @@ -5,6 +5,7 @@ from nose.plugins.attrib import attr +from conans.client.tools import replace_in_file from conans.test.utils.tools import TestClient from conans.util.files import load @@ -76,3 +77,55 @@ def test_native_export_multi(self): self.assertIn("Hello World {}!".format(bt), c.out) self.assertIn("bye World {}!".format(bt), c.out) os.remove(os.path.join(c.current_folder, "example")) + + def cpp_info_name_test(self): + client = TestClient() + client.run("new hello/1.0 -s") + replace_in_file(os.path.join(client.current_folder, "conanfile.py"), + 'self.cpp_info.libs = ["hello"]', + 'self.cpp_info.libs = ["hello"]\n self.cpp_info.name = "MYHELLO"', + output=client.out) + client.run("create .") + client.run("new hello2/1.0 -s") + replace_in_file(os.path.join(client.current_folder, "conanfile.py"), + 'self.cpp_info.libs = ["hello"]', + 'self.cpp_info.libs = ["hello"]\n self.cpp_info.name = "MYHELLO2"', + output=client.out) + replace_in_file(os.path.join(client.current_folder, "conanfile.py"), + 'exports_sources = "src/*"', + 'exports_sources = "src/*"\n requires = "hello/1.0"', + output=client.out) + client.run("create .") + cmakelists = """ +project(consumer) +cmake_minimum_required(VERSION 3.1) +find_package(MYHELLO2) + +get_target_property(tmp MYHELLO2::MYHELLO2 INTERFACE_LINK_LIBRARIES) +message("Target libs: ${tmp}") +""" + conanfile = """ +from conans import ConanFile, CMake + + +class Conan(ConanFile): + settings = "build_type" + requires = "hello2/1.0" + generators = "cmake_find_package_multi" + + def build(self): + cmake = CMake(self) + cmake.configure() + """ + client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmakelists}) + client.run("install .") + client.run("build .") + self.assertIn("Target libs: $<$:CONAN_LIB::MYHELLO2_hello_RELEASE;>;" + "$<$:;>;" + "$<$:;>;" + "$<$:;>;$" + "<$:CONAN_LIB::MYHELLO_hello_RELEASE;>;" + "$<$:;>;" + "$<$:;>;" + "$<$:;>", + client.out) diff --git a/conans/test/functional/generators/cmake_find_package_test.py b/conans/test/functional/generators/cmake_find_package_test.py index 97f0cb9b054..8b84ca74efc 100644 --- a/conans/test/functional/generators/cmake_find_package_test.py +++ b/conans/test/functional/generators/cmake_find_package_test.py @@ -1,9 +1,11 @@ +import os import platform import six import unittest from nose.plugins.attrib import attr +from conans.client.tools import replace_in_file from conans.test.utils.cpp_test_files import cpp_hello_conan_files from conans.test.utils.tools import TestClient @@ -250,3 +252,49 @@ def build(self): six.assertRegex(self, str(client.out), "Libraries to Link: .*Foundation\\.framework") six.assertRegex(self, str(client.out), "Target libs: .*Foundation\\.framework") self.assertIn("Version: 0.1", client.out) + + def cpp_info_name_test(self): + client = TestClient() + client.run("new hello/1.0 -s") + replace_in_file(os.path.join(client.current_folder, "conanfile.py"), + 'self.cpp_info.libs = ["hello"]', + 'self.cpp_info.libs = ["hello"]\n self.cpp_info.name = "MYHELLO"', + output=client.out) + client.run("create .") + client.run("new hello2/1.0 -s") + replace_in_file(os.path.join(client.current_folder, "conanfile.py"), + 'self.cpp_info.libs = ["hello"]', + 'self.cpp_info.libs = ["hello"]\n self.cpp_info.name = "MYHELLO2"', + output=client.out) + replace_in_file(os.path.join(client.current_folder, "conanfile.py"), + 'exports_sources = "src/*"', + 'exports_sources = "src/*"\n requires = "hello/1.0"', + output=client.out) + client.run("create .") + cmakelists = """ +project(consumer) +cmake_minimum_required(VERSION 3.1) +find_package(MYHELLO2) + +get_target_property(tmp MYHELLO2::MYHELLO2 INTERFACE_LINK_LIBRARIES) +message("Target libs: ${tmp}") +""" + conanfile = """ +from conans import ConanFile, CMake + + +class Conan(ConanFile): + requires = "hello2/1.0" + generators = "cmake_find_package" + + def build(self): + cmake = CMake(self) + cmake.configure() + """ + client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmakelists}) + client.run("install .") + client.run("build .") + self.assertIn('Found MYHELLO2: 1.0 (found version "1.0")', client.out) + self.assertIn('Found MYHELLO: 1.0 (found version "1.0")', client.out) + self.assertIn("Target libs: CONAN_LIB::MYHELLO2_hello;;;CONAN_LIB::MYHELLO_hello", + client.out) diff --git a/conans/test/unittests/client/generators/cmake_test.py b/conans/test/unittests/client/generators/cmake_test.py index 6679c2468f2..9a2f3b5724d 100644 --- a/conans/test/unittests/client/generators/cmake_test.py +++ b/conans/test/unittests/client/generators/cmake_test.py @@ -2,9 +2,11 @@ import re import unittest +import six + from conans.client.build.cmake_flags import CMakeDefinitionsBuilder from conans.client.conf import default_settings_yml -from conans.client.generators import CMakeFindPackageGenerator +from conans.client.generators import CMakeFindPackageGenerator, CMakeFindPackageMultiGenerator from conans.client.generators.cmake import CMakeGenerator from conans.client.generators.cmake_multi import CMakeMultiGenerator from conans.errors import ConanException @@ -34,7 +36,9 @@ def compiler(self): def constraint(self, _): return self - def get_safe(self, _): + def get_safe(self, name): + if name == "build_type": + return self.build_type return None def items(self): @@ -345,21 +349,29 @@ def apple_frameworks_test(self): self.assertIn('set(CONAN_LIBS ${CONAN_FRAMEWORK_OPENGL} ' '${CONAN_FRAMEWORK_OPENCL} ${CONAN_LIBS})', content) - def cpp_info_name_cmake_vars_test(self): - """ - Test cpp_info.names values are applied instead of the reference name - """ - conanfile = ConanFile(TestBufferConanOutput(), None) - conanfile.initialize(Settings({}), EnvValues()) + +class CMakeCppInfoNameTest(unittest.TestCase): + """ + Test cpp_info.name values are applied in generators instead of the reference name + """ + + def setUp(self): + self.conanfile = ConanFile(TestBufferConanOutput(), None) + settings = _MockSettings() + settings.build_type = "Debug" + self.conanfile.initialize(settings, EnvValues()) ref = ConanFileReference.loads("my_pkg/0.1@lasote/stables") cpp_info = CppInfo("dummy_root_folder1") cpp_info.name = "MyPkG" - conanfile.deps_cpp_info.update(cpp_info, ref.name) + self.conanfile.deps_cpp_info.update(cpp_info, ref.name) ref = ConanFileReference.loads("my_pkg2/0.1@lasote/stables") cpp_info = CppInfo("dummy_root_folder2") cpp_info.name = "MyPkG2" - conanfile.deps_cpp_info.update(cpp_info, ref.name) - generator = CMakeGenerator(conanfile) + cpp_info.public_deps = ["my_pkg"] + self.conanfile.deps_cpp_info.update(cpp_info, ref.name) + + def cmake_test(self): + generator = CMakeGenerator(self.conanfile) content = generator.content self.assertIn("set(CONAN_DEPENDENCIES my_pkg my_pkg2)", content) content = content.replace("set(CONAN_DEPENDENCIES my_pkg my_pkg2)", "") @@ -370,21 +382,22 @@ def cpp_info_name_cmake_vars_test(self): self.assertNotIn('CONAN_PKG::my_pkg', content) self.assertNotIn('CONAN_PKG::my_pkg2', content) - def cpp_info_name_cmake_find_package_test(self): - """ - Test cpp_info.names values are applied instead of the reference name - """ - conanfile = ConanFile(TestBufferConanOutput(), None) - conanfile.initialize(Settings({}), EnvValues()) - ref = ConanFileReference.loads("my_pkg/0.1@lasote/stables") - cpp_info = CppInfo("dummy_root_folder1") - cpp_info.name = "MyPkG" - conanfile.deps_cpp_info.update(cpp_info, ref.name) - ref = ConanFileReference.loads("my_pkg2/0.1@lasote/stables") - cpp_info = CppInfo("dummy_root_folder2") - cpp_info.name = "MyPkG2" - conanfile.deps_cpp_info.update(cpp_info, ref.name) - generator = CMakeFindPackageGenerator(conanfile) + def cmake_multi_test(self): + generator = CMakeMultiGenerator(self.conanfile) + content = generator.content + self.assertIn("set(CONAN_DEPENDENCIES_DEBUG my_pkg my_pkg2)", + content["conanbuildinfo_debug.cmake"]) + self.assertNotIn("my_pkg", content["conanbuildinfo_multi.cmake"]) + self.assertNotIn("MY_PKG", content["conanbuildinfo_multi.cmake"]) + self.assertIn('add_library(CONAN_PKG::MyPkG INTERFACE IMPORTED)', + content["conanbuildinfo_multi.cmake"]) + self.assertIn('add_library(CONAN_PKG::MyPkG2 INTERFACE IMPORTED)', + content["conanbuildinfo_multi.cmake"]) + self.assertNotIn('CONAN_PKG::my_pkg', content["conanbuildinfo_multi.cmake"]) + self.assertNotIn('CONAN_PKG::my_pkg2', content["conanbuildinfo_multi.cmake"]) + + def cmake_find_package_test(self): + generator = CMakeFindPackageGenerator(self.conanfile) content = generator.content self.assertIn("FindMyPkG.cmake", content.keys()) self.assertIn("FindMyPkG2.cmake", content.keys()) @@ -394,4 +407,20 @@ def cpp_info_name_cmake_find_package_test(self): self.assertNotIn("MY_PKG", content["FindMyPkG2.cmake"]) self.assertIn("add_library(MyPkG::MyPkG INTERFACE IMPORTED)", content["FindMyPkG.cmake"]) self.assertIn("add_library(MyPkG2::MyPkG2 INTERFACE IMPORTED)", content["FindMyPkG2.cmake"]) + self.assertIn("find_dependency(MyPkG REQUIRED)", content["FindMyPkG2.cmake"]) + def cmake_find_package_multi_test(self): + generator = CMakeFindPackageMultiGenerator(self.conanfile) + content = generator.content + six.assertCountEqual(self, ['MyPkG2Targets.cmake', 'MyPkGConfig.cmake', 'MyPkG2Config.cmake', + 'MyPkGTargets.cmake', 'MyPkGTarget-debug.cmake', + 'MyPkG2Target-debug.cmake'], content.keys()) + self.assertNotIn("my_pkg", content["MyPkGConfig.cmake"]) + self.assertNotIn("MY_PKG", content["MyPkGConfig.cmake"]) + self.assertNotIn("my_pkg", content["MyPkG2Config.cmake"]) + self.assertNotIn("MY_PKG", content["MyPkG2Config.cmake"]) + self.assertIn("add_library(MyPkG::MyPkG INTERFACE IMPORTED)", + content["MyPkGTargets.cmake"]) + self.assertIn("add_library(MyPkG2::MyPkG2 INTERFACE IMPORTED)", + content["MyPkG2Targets.cmake"]) + self.assertIn("find_dependency(MyPkG REQUIRED NO_MODULE)", content["MyPkG2Config.cmake"])