conanfile.py
Rama master · réplica de lectura del repositorio original.
import json
import os
from conan import ConanFile
from conan.errors import ConanException, ConanInvalidConfiguration
from conan.tools.build import can_run, check_min_cppstd
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain
from conan.tools.sbom import cyclonedx_1_6
required_conan_version = ">=2.26.0"
class Memgraph(ConanFile):
name = "memgraph"
version = "0.0.1"
package_type = "application"
license = "https://memgraph.com/legal"
url = "https://github.com/memgraph/memgraph"
homepage = "https://memgraph.com"
description = "In-memory graph database"
settings = "os", "compiler", "build_type", "arch"
options = {
# Build only the MAGE query modules: trims the dependency graph to
# what src/mage/ links against (fmt, boost, gtest) and configures
# CMake with MG_BUILD_MEMGRAPH=OFF / MG_BUILD_MAGE=ON. Used by
# `./build.sh --mage only`.
"mage_only": [True, False],
# Build against the toolchain produced by environment/toolchain and ship its
# C++ runtime. Hosts that build with their own compiler turn this off, and the
# profile that describes such a host is where it belongs.
"bundled_toolchain": [True, False],
}
exports_sources = (
"CMakeLists.txt",
"cmake/*",
"src/*",
"libs/*",
"include/*",
"tests/*",
"query_modules/*",
"release/*",
"tools/*",
"licenses/*",
"config/*",
"import/*",
)
default_options = {
"mage_only": False,
"bundled_toolchain": True,
"aws-sdk-cpp/*:config": True,
"aws-sdk-cpp/*:s3": True,
"aws-sdk-cpp/*:monitoring": False,
"aws-sdk-cpp/*:text-to-speech": False,
"aws-sdk-cpp/*:queues": False,
"aws-sdk-cpp/*:sqs": False,
"aws-sdk-cpp/*:access-management": False,
"aws-sdk-cpp/*:cognito-identity": True,
"aws-sdk-cpp/*:iam": False,
"aws-sdk-cpp/*:identity-management": True,
"aws-sdk-cpp/*:transfer": True,
# Disable saslauthd in cyrus-sasl — it adds -lcrypt (system libcrypt.so)
# whose crypt_rn symbol collides with our vendored libbcrypt's crypt_rn,
# causing bcrypt's self-test to fail. saslauthd is a Unix auth daemon
# irrelevant to Kafka SASL client usage.
"cyrus-sasl/*:with_saslauthd": False,
"boost/*:without_stacktrace": True,
"boost/*:without_locale": True,
"arrow/*:with_s3": True,
"arrow/*:with_snappy": True,
"arrow/*:with_mimalloc": False,
"librdkafka/*:ssl": True,
"librdkafka/*:sasl": True,
"mgclient/*:with_cpp": True,
"jemalloc/*:prefix": "je_",
"jemalloc/*:enable_cxx": False,
"jemalloc/*:enable_fill": False,
"jemalloc/*:lg_page": "12",
"jemalloc/*:lg_hugepage": "21",
# NOTE: percpu_arena can bind threads to per-DB arenas on hosts with sparse CPU
# sets (jemalloc#2054); guarded at runtime by EnsureCpuArenaCoverage() (db_arena.hpp).
"jemalloc/*:malloc_conf": "retain:false,percpu_arena:percpu,oversize_threshold:0,muzzy_decay_ms:5000,dirty_decay_ms:5000",
"rapidcheck/*:enable_gtest": True,
"rapidcheck/*:enable_gmock": True,
"gflags/*:nothreads": False,
"gflags/*:namespace": "google;gflags",
"nuraft/*:asio": "standalone",
"rocksdb/*:with_gflags": True,
"rocksdb/*:use_rtti": True,
# Disable io_uring async I/O path in rocksdb's POSIX env. Avoids
# pulling liburing into the static link; flip to True (pulls
# liburing via Conan) to opt back in.
"rocksdb/*:with_liburing": False,
"openssl/*:shared": True,
"zlib/*:shared": True,
}
def requirements(self):
# Dependencies MAGE links against; everything below the mage_only
# early-return is memgraph-only.
# force=True makes boost both a direct require (so CMakeDeps generates
# full Boost::headers config) and overrides transitive boost ranges
self.requires("boost/1.91.0-memgraph", force=True)
self.requires("fmt/12.2.0", force=True)
self.requires("nlohmann_json/3.11.3-memgraph")
self.requires("libuuid/1.0.3")
if self.options.mage_only:
return
# Direct dependencies — packages we #include or link against directly
self.requires("abseil/20250512.1")
self.requires("antlr4-cppruntime/4.13.2")
self.requires("arrow/22.0.0")
self.requires("asio/1.36.0")
self.requires("aws-sdk-cpp/1.11.692")
self.requires("bzip2/1.0.8")
self.requires("cppitertools/2.2")
self.requires("croncpp/2023.03.30")
self.requires("ctre/3.10.0")
self.requires("gflags/2.2.0-memgraph", force=True)
self.requires("jemalloc/5.2.1-memgraph")
self.requires("libbcrypt/1.0-memgraph")
self.requires("librdkafka/2.14.2")
self.requires("librdtsc/0.3-memgraph")
if self.settings.os == "Linux":
# seccomp is a Linux kernel interface and its recipe only supports Linux, so the
# dependency cannot be resolved elsewhere. src/auth still calls into it
# unconditionally, so a non-Linux build gets as far as compiling and then fails
# there; making that optional is separate work.
self.requires("libseccomp/2.6.0", options={"shared": True})
self.requires("mgclient/1.8.0")
self.requires("nuraft/2.1.0-memgraph")
# Whether this is shared is set by "openssl/*:shared" in default_options, not here.
# Do not remove `override=True`: it pins one OpenSSL version across the graph.
self.requires("openssl/3.0.18", override=True)
self.requires("protobuf/3.21.12")
self.requires("pulsar-client-cpp/4.0.0-memgraph")
self.requires("range-v3/0.12.0")
self.requires("rocksdb/8.1.1-memgraph")
self.requires("simdjson/4.2.2")
self.requires("spdlog/1.17.0")
self.requires("strong_type/v15")
self.requires("usearch/2.21.4")
self.requires("zlib/1.3.1", override=True)
self.requires("prometheus-cpp/1.3.0")
# Version overrides — pin transitive dependency versions
self.requires("libcurl/8.17.0", override=True)
self.requires("snappy/1.2.1", override=True)
def build_requirements(self):
self.tool_requires("cmake/4.3.3") # cmake >= 4.4.0 shows scary errors about modules - TODO(matt): fix
self.tool_requires("ninja/[>=1.13 <2]")
self.tool_requires("ccache/4.12.3-memgraph")
# force=True overrides older gtest pinned by transitive dependencies
self.test_requires("gtest/[>=1.17 <2]", force=True)
if self.options.mage_only:
return
self.tool_requires("antlr4/4.13.1")
self.test_requires("benchmark/[>=1.9 <2]")
self.test_requires("rapidcheck/cci.20231215")
self.test_requires("approvaltests.cpp/10.13.0")
def validate(self):
"""Validate configuration before generation"""
if self.settings.os not in ("Linux", "FreeBSD"):
raise ConanInvalidConfiguration(
f"Unsupported OS: {self.settings.os}. Only Linux and FreeBSD are supported."
)
user_toolchain = self.conf.get("tools.cmake.cmaketoolchain:user_toolchain")
if user_toolchain:
# user_toolchain can be a list or a single path
toolchains = user_toolchain if isinstance(user_toolchain, list) else [user_toolchain]
for toolchain_path in toolchains:
if not os.path.exists(toolchain_path):
raise ConanException(
f"CMake user toolchain file does not exist: {toolchain_path}\n"
f"This is typically configured via the profile. "
f"Make sure MG_TOOLCHAIN_ROOT environment variable is set correctly."
)
def validate_build(self):
"""Validate build configuration"""
# Memgraph requires C++20 or higher
check_min_cppstd(self, "20")
def package_id(self):
# Remove compiler version from package_id for applications
# Keep build_type to maintain separate Debug/Release binaries
del self.info.settings.compiler
# TODO(matt): remove this hack so that builds end up in the subdirectory named after the build type
# This will require fixing a bunch of the hard-coded paths in the testing code.
def layout(self):
# Custom layout to put everything in build/ instead of build/Release or build/RelWithDebInfo
self.folders.build = "build"
self.folders.generators = "build/generators"
self.folders.package = "build/package"
def generate(self):
deps = CMakeDeps(self)
deps.generate()
tc = CMakeToolchain(self)
# Automatically set sanitizer CMake flags based on compiler settings
if self.settings.get_safe("compiler.asan"):
tc.cache_variables["ASAN"] = "ON"
if self.settings.get_safe("compiler.ubsan"):
tc.cache_variables["UBSAN"] = "ON"
if self.settings.get_safe("compiler.tsan"):
tc.cache_variables["TSAN"] = "ON"
if self.options.mage_only:
tc.cache_variables["MG_BUILD_MEMGRAPH"] = "OFF"
tc.cache_variables["MG_BUILD_MAGE"] = "ON"
tc.cache_variables["MG_BUNDLED_TOOLCHAIN"] = "ON" if self.options.bundled_toolchain else "OFF"
tc.generate()
# SBOM generation
sbom = cyclonedx_1_6(self, name="memgraph", add_build=False, add_tests=False)
out_dir = os.path.join(self.generators_folder, "sbom")
os.makedirs(out_dir, exist_ok=True)
out_path = os.path.join(out_dir, "memgraph-sbom.cdx.json")
with open(out_path, "w") as f:
json.dump(sbom, f, indent=2)
self.output.success(f"CYCLONEDX SBOM CREATED -> {out_path}")
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
# Only run unit tests if we can run them (not cross-compiling)
if can_run(self) and not self.options.mage_only:
cmake.ctest(cli_args=["-R", "memgraph__unit", "--output-on-failure"])
def package(self):
# NOTE we still can't package because ATM we exports_sources which means:
# - we are not a git repo
# - releases/get_version.py will fail
cmake = CMake(self)
cmake.install()
def package_info(self):
# Memgraph is an application, so we declare the bin directory
# This allows tool_requires consumers to find memgraph in PATH
self.cpp_info.bindirs = ["bin"]