diff --git a/conan/tools/cmake/cmake.py b/conan/tools/cmake/cmake.py index b4a2098a6f7..270c0c123f0 100644 --- a/conan/tools/cmake/cmake.py +++ b/conan/tools/cmake/cmake.py @@ -60,7 +60,7 @@ def __init__(self, conanfile, namespace=None): self._cmake_program = "cmake" # Path to CMake should be handled by environment - def configure(self, build_script_folder=None): + def configure(self, variables=None, build_script_folder=None): cmakelist_folder = self._conanfile.source_folder if build_script_folder: cmakelist_folder = os.path.join(self._conanfile.source_folder, build_script_folder) @@ -83,7 +83,10 @@ def configure(self, build_script_folder=None): pkg_folder = self._conanfile.package_folder.replace("\\", "/") arg_list.append('-DCMAKE_INSTALL_PREFIX="{}"'.format(pkg_folder)) if platform.system() == "Windows" and self._generator == "MinGW Makefiles": + # It seems this doesn't work in the toolchain file, it needs to be here in command line arg_list.append('-DCMAKE_SH="CMAKE_SH-NOTFOUND"') + if variables: + arg_list.extend(["-D{}={}".format(k, v) for k, v in variables.items()]) arg_list.append('"{}"'.format(cmakelist_folder)) command = " ".join(arg_list) @@ -91,7 +94,7 @@ def configure(self, build_script_folder=None): with chdir(self, build_folder): self._conanfile.run(command) - def _build(self, build_type=None, target=None): + def _build(self, build_type=None, target=None, cli_args=None, build_tool_args=None): bf = self._conanfile.build_folder is_multi = is_multi_configuration(self._generator) if build_type and not is_multi: @@ -106,8 +109,12 @@ def _build(self, build_type=None, target=None): args = [] if target is not None: args = ["--target", target] + if cli_args: + args.extend(cli_args) cmd_line_args = _cmake_cmd_line_args(self._conanfile, self._generator) + if build_tool_args: + cmd_line_args.extend(build_tool_args) if cmd_line_args: args += ['--'] + cmd_line_args @@ -117,8 +124,8 @@ def _build(self, build_type=None, target=None): self._conanfile.output.info("CMake command: %s" % command) self._conanfile.run(command) - def build(self, build_type=None, target=None): - self._build(build_type, target) + def build(self, build_type=None, target=None, cli_args=None, build_tool_args=None): + self._build(build_type, target, cli_args, build_tool_args) def install(self, build_type=None): mkdir(self._conanfile, self._conanfile.package_folder) @@ -137,11 +144,12 @@ def install(self, build_type=None): self._conanfile.output.info("CMake command: %s" % command) self._conanfile.run(command) - def test(self, build_type=None, target=None, output_on_failure=False): + def test(self, build_type=None, target=None, cli_args=None, build_tool_args=None): if self._conanfile.conf["tools.build:skip_test"]: return if not target: is_multi = is_multi_configuration(self._generator) target = "RUN_TESTS" if is_multi else "test" - self._build(build_type=build_type, target=target) + self._build(build_type=build_type, target=target, cli_args=cli_args, + build_tool_args=build_tool_args) diff --git a/conans/test/integration/toolchains/cmake/test_cmake.py b/conans/test/integration/toolchains/cmake/test_cmake.py new file mode 100644 index 00000000000..7687b6783b5 --- /dev/null +++ b/conans/test/integration/toolchains/cmake/test_cmake.py @@ -0,0 +1,34 @@ +import textwrap + +from conans.test.utils.tools import TestClient + + +def test_configure_args(): + client = TestClient() + + conanfile = textwrap.dedent(""" + from conan import ConanFile + from conan.tools.cmake import CMake + class Pkg(ConanFile): + name = "pkg" + version = "0.1" + settings = "os", "compiler", "build_type", "arch" + generators = "CMakeToolchain" + def build(self): + cmake = CMake(self) + cmake.configure(variables={"MYVAR": "MYVALUE"}) + cmake.build(cli_args=["--verbosebuild"], build_tool_args=["-something"]) + cmake.test(cli_args=["--testverbose"], build_tool_args=["-testok"]) + + def run(self, *args, **kwargs): + self.output.info("MYRUN: {}".format(*args)) + """) + client.save({"conanfile.py": conanfile}) + client.run("create . ") + # TODO: This check is ugly, because the command line is so different in each platform, + # and args_to_string() is doing crazy stuff + assert '-DMYVAR=MYVALUE' in client.out + assert "--verbosebuild" in client.out + assert "-something" in client.out + assert "--testverbose" in client.out + assert "-testok" in client.out