From db343feac208a000bc6546556104a8511a584f1e Mon Sep 17 00:00:00 2001 From: Carlos Zoido Date: Mon, 23 May 2022 17:46:45 +0200 Subject: [PATCH] Add error if missing CMAKE_BUILD_TYPE when invoking CMake (#11294) * add error if missing build type in CMake * update test * fix tesst * use macro * update test * wip * fix test * minor changes * fix tests and force cmake version * minor changes * wip * green --- .../tools/cmake/cmakedeps/templates/config.py | 2 + .../tools/cmake/cmakedeps/templates/macros.py | 10 +++ .../test_build_context_transitive_build.py | 2 +- .../cmake/cmakedeps/test_cmakedeps.py | 62 +++++++++++++++++++ .../toolchains/cmake/test_cmake_toolchain.py | 5 +- .../cmake/test_cmaketoolchain_paths.py | 3 +- 6 files changed, 80 insertions(+), 4 deletions(-) diff --git a/conan/tools/cmake/cmakedeps/templates/config.py b/conan/tools/cmake/cmakedeps/templates/config.py index 1279fce7d59..5373b9f4c6b 100644 --- a/conan/tools/cmake/cmakedeps/templates/config.py +++ b/conan/tools/cmake/cmakedeps/templates/config.py @@ -60,6 +60,8 @@ def template(self): include(${CMAKE_CURRENT_LIST_DIR}/{{ targets_include_file }}) include(CMakeFindDependencyMacro) + check_build_type_defined() + foreach(_DEPENDENCY {{ '${' + pkg_name + '_FIND_DEPENDENCY_NAMES' + '}' }} ) # Check that we have not already called a find_package with the transitive dependency if(NOT {{ '${_DEPENDENCY}' }}_FOUND) diff --git a/conan/tools/cmake/cmakedeps/templates/macros.py b/conan/tools/cmake/cmakedeps/templates/macros.py index e79655e457d..8888535a009 100644 --- a/conan/tools/cmake/cmakedeps/templates/macros.py +++ b/conan/tools/cmake/cmakedeps/templates/macros.py @@ -88,4 +88,14 @@ def template(self): set(${out_libraries} ${_out_libraries} PARENT_SCOPE) set(${out_libraries_target} ${_out_libraries_target} PARENT_SCOPE) endfunction() + + macro(check_build_type_defined) + # Check that the -DCMAKE_BUILD_TYPE argument is always present + get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(NOT isMultiConfig AND NOT CMAKE_BUILD_TYPE) + message(FATAL_ERROR "Please, set the CMAKE_BUILD_TYPE variable when calling to CMake " + "adding the '-DCMAKE_BUILD_TYPE=' argument.") + endif() + endmacro() + """) diff --git a/conans/test/functional/toolchains/cmake/cmakedeps/test_build_context_transitive_build.py b/conans/test/functional/toolchains/cmake/cmakedeps/test_build_context_transitive_build.py index 110fe792d97..875bbf9cbad 100644 --- a/conans/test/functional/toolchains/cmake/cmakedeps/test_build_context_transitive_build.py +++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_build_context_transitive_build.py @@ -72,7 +72,7 @@ def generate(self): clean_first=True) client.run("install . -pr:h=default -pr:b=default") # The compilation works, so it finds the doxygen without transitive failures - client.run_command("cmake . -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake") + client.run_command("cmake . -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release") # Assert there is no zlib target assert "Target declared 'zlib::zlib'" not in client.out diff --git a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py index e165bac75d7..feb8353b5cd 100644 --- a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py +++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py @@ -378,3 +378,65 @@ def package_info(self): data = os.path.join("consumer/build/generators/mylib-release-x86_64-data.cmake") contents = client.load(data) assert 'set(ZLIB_FIND_MODE "")' in contents + + +@pytest.mark.tool_cmake(version="3.19") +def test_error_missing_build_type(): + # https://github.com/conan-io/conan/issues/11168 + client = TestClient() + + client.run("new hello/1.0 -m=cmake_lib") + client.run("create . -tf=None") + + conanfile = textwrap.dedent(""" + [requires] + hello/1.0 + [generators] + CMakeDeps + CMakeToolchain + """) + + main = textwrap.dedent(""" + #include + int main() {hello();return 0;} + """) + + cmakelists = textwrap.dedent(""" + cmake_minimum_required(VERSION 3.15) + project(app) + find_package(hello REQUIRED) + add_executable(app) + target_link_libraries(app hello::hello) + target_sources(app PRIVATE main.cpp) + """) + + if platform.system() != "Windows": + client.save({ + "conanfile.txt": conanfile, + "main.cpp": main, + "CMakeLists.txt": cmakelists + }, clean_first=True) + + client.run("install .") + client.run_command("cmake . -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -G 'Unix Makefiles'", assert_error=True) + assert "Please, set the CMAKE_BUILD_TYPE variable when calling to CMake" in client.out + + client.save({ + "conanfile.txt": conanfile, + "main.cpp": main, + "CMakeLists.txt": cmakelists + }, clean_first=True) + + client.run("install .") + + generator = { + "Windows": '-G "Visual Studio 15 2017"', + "Darwin": '-G "Xcode"', + "Linux": '-G "Ninja Multi-Config"' + }.get(platform.system()) + + client.run_command("cmake . -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake {}".format(generator)) + client.run_command("cmake --build . --config Release") + run_app = r".\Release\app.exe" if platform.system() == "Windows" else "./Release/app" + client.run_command(run_app) + assert "Hello World Release!" in client.out diff --git a/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py b/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py index 83f9461bd05..3bbe5ac5173 100644 --- a/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py +++ b/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py @@ -241,8 +241,9 @@ class Conan(ConanFile): client.run("create dep") client.run("install .") - client.run_command("cmake . -DCMAKE_TOOLCHAIN_FILE=./conan_toolchain.cmake " - "-Werror=dev --warn-uninitialized") + build_type = "-DCMAKE_BUILD_TYPE=Release" if platform.system() != "Windows" else "" + client.run_command("cmake . -DCMAKE_TOOLCHAIN_FILE=./conan_toolchain.cmake {}" + "-Werror=dev --warn-uninitialized".format(build_type)) assert "Using Conan toolchain" in client.out # The real test is that there are no errors, it returns successfully diff --git a/conans/test/functional/toolchains/cmake/test_cmaketoolchain_paths.py b/conans/test/functional/toolchains/cmake/test_cmaketoolchain_paths.py index fb09c3c4b53..eb2ca27d8cf 100644 --- a/conans/test/functional/toolchains/cmake/test_cmaketoolchain_paths.py +++ b/conans/test/functional/toolchains/cmake/test_cmaketoolchain_paths.py @@ -29,7 +29,8 @@ def __init__(self, package=None, library=None, framework=None, include=None, pro def _cmake_command_toolchain(find_root_path_modes): - cmake_command = "cmake .. -DCMAKE_TOOLCHAIN_FILE=../conan_toolchain.cmake" + build_type = "-DCMAKE_BUILD_TYPE=Release" if platform.system() != "Windows" else "" + cmake_command = "cmake .. -DCMAKE_TOOLCHAIN_FILE=../conan_toolchain.cmake {}".format(build_type) if find_root_path_modes.package: cmake_command += " -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE={}".format(find_root_path_modes.package) if find_root_path_modes.library: