Skip to content

Commit

Permalink
(#13739) CMake Conan 2.0 compatibility
Browse files Browse the repository at this point in the history
* CMake Conan 2.0 compatibility

* Fix lint errors

* Avoid lint error with Conan 2.0 argument name

* Avoid lint error with Conan 2.0 argument name

* Removed unused imports

* Handle Conan version disparities

* Use basic_layout with Autotools

Co-authored-by: Uilian Ries <[email protected]>

* Call AutotoolsDeps generate

Co-authored-by: Uilian Ries <[email protected]>

* Call CMakeDeps generate

Co-authored-by: Uilian Ries <[email protected]>

* Update imports per suggestioned changes

* Removed extra space

* Remove extraneous items

* Determine require_version in a version-agnostic manner

* Use Conan 1.53

* Handle @ in ref

* Fix lint errors

* Bigger hammer

* Remove PATH addition in package_id

Co-authored-by: Chris Mc <[email protected]>

* Use validate_build instead of validate

* Moved Mac x86 check to validate() method.

* Bump openssl version

Co-authored-by: Chris Mc <[email protected]>

* Add blank line to trigger CI build

* Eliminate use of validate_build()

* Restore use of validate_build()

* Removed blank line to trigger CI

* Add blank line to trigger CI

* Added boostrap options and removed unneeded env. vars

* Deal with Conan 1.x vs 2.0 inconsistencies

* Fixed lint issue

* Placate linter

* Apply suggestions from code review

Co-authored-by: SpaceIm <[email protected]>

* Use save & load for bootstrap args; Use tool_requires in test packages

* Eliminate use of validate_build; Add more settings to test recipes

* Set PATH in package_info() for v1.x; Lower req. ver. to 1.50

* Apply suggestions from code review

Co-authored-by: SpaceIm <[email protected]>

* Added AutotoolsDeps generator; Eliminated can_run() from tests

* Correct msvc version

Co-authored-by: SpaceIm <[email protected]>

* Use f-strings

* Replace VirtualRunEnv with VirtualBuildEnv

Co-authored-by: SpaceIm <[email protected]>

Co-authored-by: Uilian Ries <[email protected]>
Co-authored-by: Chris Mc <[email protected]>
Co-authored-by: SpaceIm <[email protected]>
  • Loading branch information
4 people authored Jan 14, 2023
1 parent e131876 commit a2bd965
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 91 deletions.
136 changes: 73 additions & 63 deletions recipes/cmake/3.x.x/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import os
from conan import ConanFile
from conan.tools.files import chdir, copy, rmdir, get, save, load
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
from conan.tools.gnu import Autotools, AutotoolsToolchain, AutotoolsDeps
from conan.tools.layout import basic_layout
from conan.tools.build import build_jobs, cross_building, check_min_cppstd
from conan.tools.scm import Version
from conan.tools.files import rmdir, get
from conans import tools, AutoToolsBuildEnvironment, CMake
from conan.errors import ConanInvalidConfiguration, ConanException
from conan.errors import ConanInvalidConfiguration
import os
import json

required_conan_version = ">=1.49.0"
required_conan_version = ">=1.50.0"

class CMakeConan(ConanFile):
name = "cmake"
package_type = "application"
description = "Conan installer for CMake"
topics = ("cmake", "build", "installer")
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://github.com/Kitware/CMake"
license = "BSD-3-Clause"
generators = "cmake"
settings = "os", "arch", "compiler", "build_type"

options = {
Expand All @@ -26,9 +30,6 @@ class CMakeConan(ConanFile):
"bootstrap": False,
}

_source_subfolder = "source_subfolder"
_cmake = None

def config_options(self):
if self.settings.os == "Windows":
self.options.with_openssl = False
Expand All @@ -38,103 +39,112 @@ def requirements(self):
self.requires("openssl/1.1.1s")

def validate(self):
if self.settings.os == "Macos" and self.settings.arch == "x86":
raise ConanInvalidConfiguration("CMake does not support x86 for macOS")

if self.settings.os == "Windows" and self.options.bootstrap:
raise ConanInvalidConfiguration("CMake does not support bootstrapping on Windows")

if self.settings.os == "Macos" and self.settings.arch == "x86":
raise ConanInvalidConfiguration("CMake does not support x86 for macOS")

minimal_cpp_standard = "11"
if self.settings.compiler.cppstd:
tools.check_min_cppstd(self, minimal_cpp_standard)
if self.settings.get_safe("compiler.cppstd"):
check_min_cppstd(self, minimal_cpp_standard)

minimal_version = {
"gcc": "4.8",
"clang": "3.3",
"apple-clang": "9",
"Visual Studio": "14",
"msvc": "190",
}

compiler = str(self.settings.compiler)
if compiler not in minimal_version:
self.output.warn(
"{} recipe lacks information about the {} compiler standard version support".format(self.name, compiler))
self.output.warn(
"{} requires a compiler that supports at least C++{}".format(self.name, minimal_cpp_standard))
self.output.warning(
f"{self.name} recipe lacks information about the {compiler} compiler standard version support")
self.output.warning(
f"{self.name} requires a compiler that supports at least C++{minimal_cpp_standard}")
return

version = Version(self.settings.compiler.version)
if version < minimal_version[compiler]:
raise ConanInvalidConfiguration(
"{} requires a compiler that supports at least C++{}".format(self.name, minimal_cpp_standard))
f"{self.name} requires a compiler that supports at least C++{minimal_cpp_standard}")

def layout(self):
if self.options.bootstrap:
basic_layout(self, src_folder="src")
else:
cmake_layout(self, src_folder="src")

def source(self):
get(self, **self.conan_data["sources"][self.version], strip_root=True, destination=self._source_subfolder)
rmdir(self, os.path.join(self._source_subfolder, "Tests", "RunCMake", "find_package"))
get(self, **self.conan_data["sources"][self.version],
destination=self.source_folder, strip_root=True)
rmdir(self, os.path.join(self.source_folder, "Tests", "RunCMake", "find_package"))

def _configure_cmake(self):
if not self._cmake:
self._cmake = CMake(self)
def generate(self):
if self.options.bootstrap:
tc = AutotoolsToolchain(self)
tc.generate()
tc = AutotoolsDeps(self)
tc.generate()
bootstrap_cmake_options = ["--"]
bootstrap_cmake_options.append(f'-DCMAKE_CXX_STANDARD={"11" if not self.settings.compiler.cppstd else self.settings.compiler.cppstd}')
if self.settings.os == "Linux":
if self.options.with_openssl:
openssl = self.dependencies["openssl"]
bootstrap_cmake_options.append("-DCMAKE_USE_OPENSSL=ON")
bootstrap_cmake_options.append(f'-DOPENSSL_USE_STATIC_LIBS={"FALSE" if openssl.options.shared else "TRUE"}')
else:
bootstrap_cmake_options.append("-DCMAKE_USE_OPENSSL=OFF")
save(self, "bootstrap_args", json.dumps({"bootstrap_cmake_options": ' '.join(arg for arg in bootstrap_cmake_options)}))
else:
tc = CMakeToolchain(self)
if not self.settings.compiler.cppstd:
self._cmake.definitions["CMAKE_CXX_STANDARD"] = 11
self._cmake.definitions["CMAKE_BOOTSTRAP"] = False
tc.variables["CMAKE_CXX_STANDARD"] = 11
tc.variables["CMAKE_BOOTSTRAP"] = False
if self.settings.os == "Linux":
self._cmake.definitions["CMAKE_USE_OPENSSL"] = self.options.with_openssl
tc.variables["CMAKE_USE_OPENSSL"] = self.options.with_openssl
if self.options.with_openssl:
self._cmake.definitions["OPENSSL_USE_STATIC_LIBS"] = not self.options["openssl"].shared
if tools.cross_building(self):
self._cmake.definitions["HAVE_POLL_FINE_EXITCODE"] = ''
self._cmake.definitions["HAVE_POLL_FINE_EXITCODE__TRYRUN_OUTPUT"] = ''
self._cmake.configure(source_folder=self._source_subfolder)

return self._cmake
openssl = self.dependencies["openssl"]
tc.variables["OPENSSL_USE_STATIC_LIBS"] = not openssl.options.shared
if cross_building(self):
tc.variables["HAVE_POLL_FINE_EXITCODE"] = ''
tc.variables["HAVE_POLL_FINE_EXITCODE__TRYRUN_OUTPUT"] = ''
tc.generate()

def build(self):
if self.options.bootstrap:
with tools.chdir(self._source_subfolder):
self.run(['./bootstrap', '--prefix={}'.format(self.package_folder), '--parallel={}'.format(tools.cpu_count())])
autotools = AutoToolsBuildEnvironment(self)
toolchain_file_content = json.loads(load(self, os.path.join(self.generators_folder, "bootstrap_args")))
bootstrap_cmake_options = toolchain_file_content.get("bootstrap_cmake_options")
with chdir(self, self.source_folder):
self.run(f'./bootstrap --prefix="" --parallel={build_jobs(self)} {bootstrap_cmake_options}')
autotools = Autotools(self)
autotools.make()
else:
tools.replace_in_file(os.path.join(self._source_subfolder, "CMakeLists.txt"),
"project(CMake)",
"project(CMake)\ninclude(\"{}/conanbuildinfo.cmake\")\nconan_basic_setup(NO_OUTPUT_DIRS)".format(
self.install_folder.replace("\\", "/")))
if self.settings.os == "Linux":
tools.replace_in_file(os.path.join(self._source_subfolder, "Utilities", "cmcurl", "CMakeLists.txt"),
"list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})",
"list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES} ${CMAKE_DL_LIBS} pthread)")

cmake = self._configure_cmake()
cmake = CMake(self)
cmake.configure()
cmake.build()

def package(self):
self.copy("Copyright.txt", dst="licenses", src=self._source_subfolder)
copy(self, "Copyright.txt", self.source_folder, os.path.join(self.package_folder, "licenses"), keep_path=False)
if self.options.bootstrap:
with tools.chdir(self._source_subfolder):
autotools = AutoToolsBuildEnvironment(self)
with chdir(self, self.source_folder):
autotools = Autotools(self)
autotools.install()
else:
cmake = self._configure_cmake()
cmake = CMake(self)
cmake.install()
rmdir(self, os.path.join(self.package_folder, "doc"))

def package_id(self):
del self.info.settings.compiler
del self.info.options.bootstrap

def package_info(self):
module_version = "{}.{}".format(Version(self.version).major, Version(self.version).minor)
self.cpp_info.includedirs = []
self.cpp_info.libdirs = []

# Needed for compatibility with v1.x - Remove when 2.0 becomes the default
bindir = os.path.join(self.package_folder, "bin")
self.output.info("Appending PATH environment variable: {}".format(bindir))
self.output.info(f"Appending PATH environment variable: {bindir}")
self.env_info.PATH.append(bindir)

self.buildenv_info.prepend_path("CMAKE_ROOT", self.package_folder)
self.env_info.CMAKE_ROOT = self.package_folder
mod_path = os.path.join(self.package_folder, "share", f"cmake-{module_version}", "Modules")
self.buildenv_info.prepend_path("CMAKE_MODULE_PATH", mod_path)
self.env_info.CMAKE_MODULE_PATH = mod_path
if not os.path.exists(mod_path):
raise ConanException("Module path not found: %s" % mod_path)

self.cpp_info.includedirs = []
31 changes: 16 additions & 15 deletions recipes/cmake/3.x.x/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import os
from six import StringIO
from conan import ConanFile
from conan.tools.build import can_run
import re


class TestPackageConan(ConanFile):
settings = "os", "arch"
generators = "VirtualRunEnv"
settings = "os", "arch", "compiler", "build_type"
generators = "VirtualBuildEnv"
test_type = "explicit"

def requirements(self):
self.requires(self.tested_reference_str)
def build_requirements(self):
self.tool_requires(self.tested_reference_str)

def test(self):
if can_run(self):
output = StringIO()
self.run("cmake --version", env="conanrun", output=output)
output_str = str(output.getvalue())
self.output.info("Installed version: {}".format(output_str))
require_version = str(self.deps_cpp_info["cmake"].version)
self.output.info("Expected version: {}".format(require_version))
assert_cmake_version = "cmake version %s" % require_version
assert(assert_cmake_version in output_str)
output = StringIO()
# Third arg to self.run renamed "stdout" in Conan 2.0 but 1.x linter doesn't like it
self.run("cmake --version", output)
output_str = str(output.getvalue())
self.output.info("Installed version: {}".format(output_str))
tokens = re.split('[@#]', self.tested_reference_str)
require_version = tokens[0].split("/", 1)[1]
self.output.info("Expected version: {}".format(require_version))
assert_cmake_version = "cmake version %s" % require_version
assert(assert_cmake_version in output_str)
26 changes: 13 additions & 13 deletions recipes/cmake/3.x.x/test_v1_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import os
from six import StringIO
from conan import ConanFile
from conan.tools.build import can_run
import re


class TestPackageConan(ConanFile):
settings = "os", "arch"
settings = "os", "arch", "compiler", "build_type"
test_type = "explicit"

def requirements(self):
self.requires(self.tested_reference_str)
def build_requirements(self):
self.tool_requires(self.tested_reference_str)

def test(self):
if can_run(self):
output = StringIO()
self.run("cmake --version", output=output, run_environment=True)
output_str = str(output.getvalue())
self.output.info("Installed version: {}".format(output_str))
require_version = str(self.deps_cpp_info["cmake"].version)
self.output.info("Expected version: {}".format(require_version))
assert_cmake_version = "cmake version %s" % require_version
assert(assert_cmake_version in output_str)
output = StringIO()
self.run("cmake --version", output=output, run_environment=False)
output_str = str(output.getvalue())
self.output.info("Installed version: {}".format(output_str))
tokens = re.split('[@#]', self.tested_reference_str)
require_version = tokens[0].split("/", 1)[1]
self.output.info("Expected version: {}".format(require_version))
assert_cmake_version = "cmake version %s" % require_version
assert(assert_cmake_version in output_str)

0 comments on commit a2bd965

Please sign in to comment.