diff --git a/conans/client/build/cmake.py b/conans/client/build/cmake.py index f6f2727ce9c..b9dc3c6e8c7 100644 --- a/conans/client/build/cmake.py +++ b/conans/client/build/cmake.py @@ -45,6 +45,8 @@ def __init__(self, conanfile, generator=None, cmake_system_name=True, self._cmake_program = os.getenv("CONAN_CMAKE_PROGRAM") or cmake_program or "cmake" self.generator = generator or get_generator(conanfile.settings) + if not self.generator: + self._conanfile.output.warn("CMake generator could not be deduced from settings") self.parallel = parallel # Initialize definitions (won't be updated if conanfile or any of these variables change) builder = CMakeDefinitionsBuilder(self._conanfile, diff --git a/conans/client/build/cmake_flags.py b/conans/client/build/cmake_flags.py index f3df58ec3e6..2bc7dbb0914 100644 --- a/conans/client/build/cmake_flags.py +++ b/conans/client/build/cmake_flags.py @@ -36,7 +36,8 @@ def get_generator(settings): if not compiler or not compiler_version or not arch: if os_build == "Windows": - return "MinGW Makefiles" + logger.warning("CMake generator could not be deduced from settings") + return None return "Unix Makefiles" if compiler == "Visual Studio": @@ -64,6 +65,8 @@ def get_generator(settings): def is_multi_configuration(generator): + if not generator: + return False return "Visual" in generator or "Xcode" in generator diff --git a/conans/test/functional/build_helpers/cmake_flags_test.py b/conans/test/functional/build_helpers/cmake_flags_test.py index 4254e085a40..dcb11c5a0f8 100644 --- a/conans/test/functional/build_helpers/cmake_flags_test.py +++ b/conans/test/functional/build_helpers/cmake_flags_test.py @@ -1,10 +1,12 @@ import os import platform import unittest +from textwrap import dedent from nose.plugins.attrib import attr from parameterized.parameterized import parameterized +from conans import load from conans.client.build.cmake import CMake from conans.model.version import Version from conans.test.utils.tools import TestClient @@ -431,3 +433,39 @@ def build(self): client.save({"CMakeLists.txt": tmp, "conanfile.py": conanfile}, clean_first=True) client.run("create . user/channel -o MyLib:fPIC=True") self.assertNotIn("Conan: Adjusting fPIC flag", client.out) + + def header_only_generator_test(self): + """ Test cmake.install() is possible although Generetaor could not be deduced from + settings + """ + conanfile = dedent(""" + from conans import ConanFile, CMake + + class TestConan(ConanFile): + name = "kk" + version = "1.0" + exports = "*" + + def package(self): + cmake = CMake(self) + self.output.info("Configure command: %s" % cmake.command_line) + cmake.configure() + cmake.install() + """) + cmakelists = dedent(""" + cmake_minimum_required(VERSION 3.3) + project(test) + + install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + """) + client = TestClient() + client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmakelists, "include/file.h": ""}) + client.run("create . danimtb/testing") + if platform.system() == "Windows": + self.assertIn("WARN: CMake generator could not be deduced from settings", client.out) + self.assertIn('Configure command: -DCONAN_EXPORTED="1" -DCONAN_IN_LOCAL_CACHE="ON" ' + '-DCMAKE_INSTALL_PREFIX=', client.out) + else: + self.assertIn('Configure command: -G "Unix Makefiles" -DCONAN_EXPORTED="1" ' + '-DCONAN_IN_LOCAL_CACHE="ON" -DCMAKE_INSTALL_PREFIX=', client.out) diff --git a/conans/test/functional/generators/cmake_generator_test.py b/conans/test/functional/generators/cmake_generator_test.py index 80b88bd6ff7..091b185123c 100644 --- a/conans/test/functional/generators/cmake_generator_test.py +++ b/conans/test/functional/generators/cmake_generator_test.py @@ -52,16 +52,20 @@ def _check_build_generator(self, os_build, generator): client.run("install . -p my_profile") client.run("build .") - self.assertIn('cmake -G "{}"'.format(generator), client.out) - self.assertTrue(os.path.isfile(os.path.join(client.current_folder, "Makefile"))) + if generator: + self.assertIn('cmake -G "{}"'.format(generator), client.out) + self.assertTrue(os.path.isfile(os.path.join(client.current_folder, "Makefile"))) + else: + self.assertNotIn("cmake -G", client.out) + self.assertFalse(os.path.isfile(os.path.join(client.current_folder, "Makefile"))) @unittest.skipUnless(tools.os_info.is_linux, "Compilation with real gcc needed") def test_cmake_default_generator_linux(self): self._check_build_generator("Linux", "Unix Makefiles") - @unittest.skipUnless(tools.os_info.is_windows, "MinGW is only supported on Windows") + @unittest.skipUnless(tools.os_info.is_windows, "Windows does not support default compiler") def test_cmake_default_generator_windows(self): - self._check_build_generator("Windows", "MinGW Makefiles") + self._check_build_generator("Windows", None) @unittest.skipUnless(tools.os_info.is_macos, "Compilation with real clang is needed") def test_cmake_default_generator_osx(self): diff --git a/conans/test/unittests/client/build/cmake_test.py b/conans/test/unittests/client/build/cmake_test.py index 478be45219a..0d179a86042 100644 --- a/conans/test/unittests/client/build/cmake_test.py +++ b/conans/test/unittests/client/build/cmake_test.py @@ -17,7 +17,7 @@ from conans.model.build_info import CppInfo, DepsCppInfo from conans.model.ref import ConanFileReference from conans.model.settings import Settings -from conans.test.utils.conanfile import ConanFileMock +from conans.test.utils.conanfile import ConanFileMock, MockSettings from conans.test.utils.test_files import temp_folder from conans.util.files import load, save @@ -1037,7 +1037,7 @@ def instance_with_os_build(os_build): self.assertEquals(cmake.generator, "Unix Makefiles") cmake = instance_with_os_build("Windows") - self.assertEquals(cmake.generator, "MinGW Makefiles") + self.assertEquals(cmake.generator, None) with tools.environment_append({"CONAN_CMAKE_GENERATOR": "MyCoolGenerator"}): cmake = instance_with_os_build("Windows") @@ -1231,3 +1231,14 @@ def test_ctest_variables(self): self.assertEquals(conanfile.captured_env["CTEST_OUTPUT_ON_FAILURE"], "1") self.assertEquals(conanfile.captured_env["CTEST_PARALLEL_LEVEL"], "666") + def test_unkown_generator_does_not_raise(self): + # https://github.com/conan-io/conan/issues/4265 + settings = MockSettings({"os_build": "Windows", "compiler": "random", + "compiler.version": "15", "build_type": "Release"}) + conanfile = ConanFileMock() + conanfile.settings = settings + cmake = CMake(conanfile) + self.assertIsNone(cmake.generator) + self.assertIn("WARN: CMake generator could not be deduced from settings", conanfile.output) + cmake.configure() + cmake.build()