You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Conan构建时无法生成libarrow_bundled_dependencies.a的问题

问题

我们的项目使用Arrow 10.0.0,此前自行构建时可通过arrow.cmake指定组件采用Bundled方式,生成并链接libarrow_bundled_dependencies.a;改用Conan加速构建后,无法生成该库文件。执行conan install . --build=missing后,运行find ~/.conan -name "*bundle*"也未找到相关内容。附上当前Conan配置代码,请问问题出在哪里?

import os

from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.build import check_min_cppstd, cross_building
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get, rmdir
from conan.tools.microsoft import is_msvc, is_msvc_static_runtime
from conan.tools.scm import Version


class ConanUTest(ConanFile):

    exports = 'VERSION', 'LICENSE', 'README.md'
    exports_sources = 'CMakeLists.txt', 'src/*', 'include/*', 'cmake/*', 'VERSION'
    name = 'mypackage'
    version = '0.1.1'
    # Take just the first line
    license = open('LICENSE').read().split('\n', 1)[0]
    description = open('README.md').read()
    settings = {
        'os': ['Linux'],
        'compiler': [
            'gcc', 'clang', 'intel',
        ],
        'build_type': ['Release'],
        'arch': ['x86', 'x86_64', 'armv8', 'armv8_32', 'armv8.3'],
    }
    generators = 'CMakeDeps', 'deploy'
    options = {'with_arrow': [True, False]}
    default_options = {
        'with_arrow': False,
    }

    def layout(self):
        cmake_layout(self)

    def generate(self):
        tc = CMakeToolchain(self)
        if cross_building(self):
            cmake_system_processor = {
                "armv8": "aarch64",
                "armv8.3": "aarch64",
            }.get(str(self.settings.arch), str(self.settings.arch))
            if cmake_system_processor == "aarch64":
                tc.variables["ARROW_CPU_FLAG"] = "armv8"

        tc.variables["ARROW_DEPENDENCY_SOURCE"] = "AUTO"
        tc.variables['ARROW_BUILD_STATIC'] = True
        tc.variables['ARROW_BUILD_SHARED'] = False
        tc.variables['ARROW_SIMD_LEVEL'] = "AVX2"
        tc.variables["ARROW_DEPENDENCY_USE_SHARED"] = False
        tc.variables["ARROW_OPENSSL_USE_SHARED"] = True

        tc.variables["ARROW_BUILD_TESTS"] = False
        tc.variables["ARROW_ENABLE_TIMING_TESTS"] = False
        tc.variables["ARROW_BUILD_EXAMPLES"] = False
        tc.variables["ARROW_BUILD_BENCHMARKS"] = False
        tc.variables["ARROW_BUILD_INTEGRATION"] = False
        tc.variables["ARROW_EXTRA_ERROR_CONTEXT"] = False

        tc.variables['ARROW_DATASET'] = True
        tc.variables['ARROW_PARQUET'] = True
        tc.variables['ARROW_WITH_RE2'] = True
        tc.variables['ARROW_COMPUTE'] = True
        tc.variables['ARROW_FLIGHT'] = True
        tc.variables['ARROW_WITH_UTF8PROC'] = True

        tc.variables["PARQUET_REQUIRE_ENCRYPTION"] = bool(
            self.options['arrow:encryption'])  # False
        tc.variables["ARROW_CUDA"] = False
        tc.variables["ARROW_JEMALLOC"] = False
        tc.variables["ARROW_IPC"] = False
        tc.variables["ARROW_JSON"] = False
        tc.variables["ARROW_CSV"] = True
        tc.variables["ARROW_FLIGHT_SQL"] = False
        tc.variables["ARROW_WITH_UCX"] = False
        tc.variables["ARROW_WITH_SNAPPY"] = True
        tc.variables["ARROW_BUILD_UTILITIES"] = bool(
            self.options['arrow:cli'])  # False
        tc.variables["ARROW_GANDIVA"] = False
        tc.variables["ARROW_S3"] = False

        tc.variables["ABS_VENDORED"] = True

        tc.variables["ARROW_DEPENDENCY_SOURCE"] = "BUNDLED"
        tc.variables["c-ares_SOURCE"] = "BUNDLED"
        tc.variables["re2_SOURCE"] = "BUNDLED"
        tc.variables["absl_SOURCE"] = "BUNDLED"
        tc.variables["Protobuf_SOURCE"] = "BUNDLED"
        tc.variables["Snappy_SOURCE"] = "BUNDLED"
        tc.variables["gRPC_SOURCE"] = "BUNDLED"
        tc.variables["ZLIB_SOURCE"] = "BUNDLED"
        tc.variables["Thrift_SOURCE"] = "BUNDLED"
        tc.variables["utf8proc_SOURCE"] = "BUNDLED"

        tc.variables["ARROW_INCLUDE_DIR"] = True
        tc.variables["ARROW_WITH_THRIFT"] = self._with_thrift()
        tc.variables["ARROW_UTF8PROC_USE_SHARED"] = False
        tc.variables["Thrift_SOURCE"] = "BUNDLED"
        if self._with_thrift():
            # a recent thrift does not require boost
            tc.variables["THRIFT_VERSION"] = bool(
                self.dependencies["thrift"].ref.version)
            tc.variables["ARROW_THRIFT_USE_SHARED"] = bool(
                self.dependencies["thrift"].options.shared)

        tc.cache_variables["ENABLE_STATIC"] = "ON"
        tc.cache_variables["ENABLE_BSON"] = "ON"
        tc.cache_variables["ENABLE_TESTS"] = "OFF"
        tc.cache_variables["ENABLE_EXAMPLES"] = "OFF"
        tc.cache_variables["ENABLE_TRACING"] = "OFF"
        tc.cache_variables["ENABLE_COVERAGE"] = "OFF"
        tc.cache_variables["ENABLE_SHM_COUNTERS"] = "OFF"
        tc.cache_variables["ENABLE_MONGOC"] = "OFF"
        tc.cache_variables["ENABLE_MAN_PAGES"] = "OFF"
        tc.cache_variables["ENABLE_HTML_DOCS"] = "OFF"
        tc.generate()

    def configure(self):
        self.options["openssl"].shared = False

        self.options["pcre2"].fPIC = True
        self.options["pcre2"].support_jit = True
        self.options["pcre2"].build_pcre2grep = True

        self.options["arrow"].shared = True
        self.options["arrow"].with_orc = False
        self.options["arrow"].parquet = True
        self.options["arrow"].dataset_modules = True
        self.options["arrow"].with_re2 = True
        self.options["arrow"].compute = True
        self.options["arrow"].with_flight_rpc = True
        self.options["arrow"].with_utf8proc = True
        self.options["arrow"].with_openssl = True
        self.options["arrow"].encryption = False
        self.options["arrow"].with_cuda = False
        self.options["arrow"].with_jemalloc = False
        self.options["arrow"].with_json = False
        self.options["arrow"].with_csv = True
        self.options["arrow"].simd_level = 'avx2'
        self.options["arrow"].with_flight_sql = False
        self.options["arrow"].with_snappy = True
        self.options["arrow"].cli = True
        self.options["arrow"].gandiva = False
        self.options["arrow"].with_s3 = False

        self.options["mongo-c-driver"].with_ssl = False
        self.options["mongo-c-driver"].with_sasl = False
        self.options["mongo-c-driver"].srv = False
        self.options["mongo-c-driver"].with_snappy = False
        self.options["mongo-c-driver"].with_zlib = False
        self.options["mongo-c-driver"].with_zstd = False

        # self.options["gtest"].shared = False

    def requirements(self):
        self.requires('arrow/10.0.0')
        self.requires('openssl/1.1.1t')
        self.requires('pcre2/10.42')
        self.requires('fmt/9.1.0')
        self.requires('mongo-c-driver/1.23.2')
        self.requires('nlohmann_json/3.11.2')
        self.requires('yyjson/0.6.0')
        self.requires('simdjson/3.1.7')
        self.requires('jemalloc/5.3.0')
        self.requires('clipp/1.2.3')
        # self.requires('gtest/1.13.0')
        self.requires('benchmark/1.7.1')
        self.requires('argparse/2.9')
        self.requires('re2/20220601')
        self.requires('xsimd/9.0.1')
        # https://conan.io/center/openssl

    # def build(self):
    #     cmake = CMake(self)
    #     cmake.configure()
    #     cmake.build()

    def system_requirements(self):
        pass

    def package_info(self):

        self.cpp_info.components["libarrow_flight.a"].set_property(
            "pkg_config_name", "flight_rpc")
        self.cpp_info.components["libarrow_flight.a"].libs = [
            f"arrow_flight.a"]

    def package(self):
        if self.options['arrow'].shared:
            self.copy(pattern="*.dll", dst="bin", keep_path=False)
            self.copy(pattern="*.dylib", dst="lib", keep_path=False)
        self.copy(pattern="*.a", dst="lib", keep_path=False)
        self.copy(pattern="*.h", dst="lib", keep_path=False)
        self.copy(pattern="*.hpp", dst="lib", keep_path=False)

    def _with_thrift(self, required=False):
        # No self.options.with_thift exists
        return bool(required or self._parquet())

    def _parquet(self, required=False):
        if required or self.options['arrow'].parquet == "auto":
            return bool(self.options.get_safe("substrait", False))
        else:
            return bool(self.options['arrow'].parquet)

问题分析与解决方案

核心问题:Conan依赖包的构建逻辑与本地自行编译完全独立

你在项目CMakeToolchain中设置的ARROW_DEPENDENCY_SOURCE、re2_SOURCE等Bundled相关变量完全无效,原因如下:

  1. Arrow包的构建不受项目CMake变量控制:Conan安装的arrow/10.0.0是独立的预编译包(或按Conan官方recipe构建的包),其构建参数由Arrow的Conan recipe定义,而非你项目中的CMake变量。你在generate函数里设置的这些ARROW_*变量只会作用于自身项目,无法影响Arrow依赖包的构建过程。
  2. 依赖管理逻辑冲突:你的requirements中单独声明了re2/20220601、openssl/1.1.1t等依赖,但又试图让Arrow使用Bundled版本的这些库。Conan的Arrow包默认优先使用Conan中心提供的独立依赖包,而非Arrow源码中Bundled的子模块,因此不会生成libarrow_bundled_dependencies.a。
  3. 配置参数矛盾:你在configure中设置self.options["arrow"].shared = True,但在generate里又设置ARROW_BUILD_STATIC=True,两者完全冲突。Arrow的静态/动态库模式由其Conan包的shared选项控制,而非你项目中的CMake变量。

解决办法

方案1:自定义Arrow Conan包,强制使用Bundled依赖

如果必须生成libarrow_bundled_dependencies.a,需要自行构建Arrow的Conan包:

  • 编写自定义的Arrow Conan recipe,在recipe的build阶段设置ARROW_DEPENDENCY_SOURCE="BUNDLED"、re2_SOURCE="BUNDLED"等CMake变量,强制Arrow使用源码中Bundled的依赖。
  • 执行conan create将自定义包上传到本地或私有仓库,然后在项目中依赖这个自定义包。

方案2:通过Conan参数强制构建Arrow并传递Bundled配置

如果不想编写自定义recipe,可在安装时强制构建Arrow,并通过cmake_args传递构建参数:

conan install . --build=arrow \
  -o arrow:shared=False \
  -c tools.build:cmake_args="-DARROW_DEPENDENCY_SOURCE=BUNDLED -Dre2_SOURCE=BUNDLED -Dabsl_SOURCE=BUNDLED -DProtobuf_SOURCE=BUNDLED -DSnappy_SOURCE=BUNDLED"

注意:需根据Arrow 10.0.0的CMake参数,补充所有需要设置为Bundled的依赖项。

方案3:放弃Bundled模式,统一使用Conan依赖

如果不需要强制使用Bundled依赖,可简化配置:

  • 删除generate函数中所有ARROW_*相关的变量设置,这些变量对Conan安装的Arrow包无意义。
  • 确保项目的依赖与Arrow的依赖版本兼容,直接通过Conan管理所有依赖,无需手动链接libarrow_bundled_dependencies.a(Conan会自动处理依赖链接)。

额外优化点

  • 移除package函数中不合理的拷贝逻辑:你当前的package函数会拷贝所有.a、.h文件到包目录,但这是Arrow包的工作,你的项目包不需要拷贝Arrow的头文件和库文件。
  • 修正package_info中的组件定义:libarrow_flight.a是Arrow包提供的组件,你的项目不需要重新定义,Conan会自动导入Arrow的组件信息。

内容的提问来源于stack exchange,提问作者Gurgen Yegoryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 07:24:53