import os
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
from conan.tools.files import copy
def cmake_project_version(recipe_folder):
"""The single source of truth for this repo's version: the number on the
``project(... VERSION x.y.z[.w] ...)`` line in CMakeLists.txt. Bump it
there — and only there — and this package's version follows. Set
``CI_PROJECT_VERSION`` in the environment to override (for CI that stamps
its own)."""
import os
import re
text = open(os.path.join(recipe_folder, "CMakeLists.txt"),
encoding="utf-8").read()
m = re.search(r"\bproject\s*\((?:[^)]*?\s)?VERSION\s+"
r"([0-9]+(?:\.[0-9]+){0,3})\b",
text, re.IGNORECASE | re.DOTALL)
if not m:
raise Exception("conanfile: no literal 'project(... VERSION ...)' "
"found in CMakeLists.txt")
return os.getenv("CI_PROJECT_VERSION") or m.group(1)
class CParseRecipe(ConanFile):
name = "cparse"
package_type = "shared-library"
license = "MIT"
author = "Fehmi Demiralp <demiralp@fedem.eu>"
url = "https://cparse.fedem.tr"
description = ("cparse - small hand-written recursive-descent parser core "
"(Cursor / Parser / Generator)")
topics = ("parser", "parsing", "recursive-descent", "cpp")
settings = "os", "compiler", "build_type", "arch"
# libcparse is always built SHARED by the CMakeLists; only fPIC is a knob.
#
# with_docs: also run the CMake `docs` target (Doxygen → build/<cfg>/docs/
# html/) during `conan build`. Off by default. Requires system Doxygen
# (and Graphviz `dot` for the class / call / include graphs).
options = {"fPIC": [True, False], "with_tests": [True, False],
"with_docs": [True, False]}
default_options = {"fPIC": True, "with_tests": True, "with_docs": False}
exports_sources = (
"CMakeLists.txt",
"CMakePresets.json",
"LICENSE",
"cparse.pc.in",
"Doxyfile.in",
"src/*",
"test/*",
)
def set_version(self):
self.version = self.version or cmake_project_version(self.recipe_folder)
def config_options(self):
if self.settings.os == "Windows":
self.options.rm_safe("fPIC")
def layout(self):
cmake_layout(self)
def generate(self):
tc = CMakeToolchain(self)
tc.cache_variables["TESTING"] = bool(self.options.with_tests)
tc.cache_variables["EXAMPLE"] = False
tc.generate()
CMakeDeps(self).generate()
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
if self.options.with_tests and not self.conf.get(
"tools.build:skip_test", default=False):
cmake.test()
if self.options.with_docs:
cmake.build(target="docs")
html = os.path.join(self.build_folder, "docs", "html", "index.html")
self.output.success("Doxygen HTML tree: " + html)
def package(self):
CMake(self).install()
copy(self, "LICENSE", self.source_folder,
os.path.join(self.package_folder, "licenses"))
def package_info(self):
self.cpp_info.libs = ["cparse"]
self.cpp_info.set_property("cmake_file_name", "cparse")
self.cpp_info.set_property("cmake_target_name", "cparse::cparse")
self.cpp_info.set_property("pkg_config_name", "cparse")