使用Bazel编译soplex时无法识别GMP依赖的问题求助
Bazel+rules_foreign_cc编译soplex时无法识别GMP依赖的解决方案
问题描述
我正在开发一个C项目,目标是用Bazel下载并编译所有外部依赖。借助rules_foreign_cc处理非Bazel构建的C库,但编译soplex时遇到问题:soplex依赖GMP和zlib,zlib能被cmake规则识别,但GMP完全被忽略,编译日志提示缺失GMP_INCLUDE_DIRS和GMP_LIBRARIES。
系统信息:Ubuntu,ldd 2.35,g++ 11.4.0,C++17标准。
现有BUILD文件如下:
soplex.BUILD.bazel
load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake") make( name = "soplex", lib_source = ":all_srcs", lib_name = "libsoplex", cache_entries = { "GMP": "on", }, deps = ["@zlib", "@gmp//:gmpxx"], visibility = ["//visibility:public"], ) filegroup( name = "all_srcs", srcs = glob(["**"]), visibility = ["//visibility:private"], )
zlib.BUILD.bazel
cc_library("zlib", # ... )
gmp.BUILD.bazel
load("@rules_foreign_cc//foreign_cc:defs.bzl", "configure_make") configure_make( name = "gmp", configure_options = ["--with-pic"], lib_name = "libgmp", lib_source = ":all_srcs", visibility = ["//visibility:public"], ) configure_make( name = "gmpxx", configure_options = ["--enable-cxx"], env = { "CXX": "g++", "CXXFLAGS": "-lstdc++", }, lib_name = "libgmpxx", lib_source = ":all_srcs", visibility = ["//visibility:public"], deps = [":gmp"], ) filegroup( name = "all_srcs", srcs = glob(["**"]), visibility = ["//visibility:private"], )
解决方案
1. 改用cmake规则适配soplex的CMake构建
soplex官方提供CMakeLists.txt,使用cmake规则替代make规则能更好地处理依赖检测,同时手动传递GMP的路径变量给CMake。
修改后的soplex.BUILD.bazel:
load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake") cmake( name = "soplex", lib_source = ":all_srcs", lib_name = "libsoplex", cache_entries = { "GMP": "ON", # 手动指定GMP的头文件目录和库文件 "GMP_INCLUDE_DIRS": "@gmp//:include", "GMP_LIBRARIES": "@gmp//:gmpxx;@gmp//:gmp", }, cmake_options = [ "-DCMAKE_BUILD_TYPE=Release", "-DCMAKE_CXX_STANDARD=17", ], deps = ["@zlib", "@gmp//:gmpxx", "@gmp//:gmp"], visibility = ["//visibility:public"], ) filegroup( name = "all_srcs", srcs = glob(["**"]), visibility = ["//visibility:private"], )
2. 完善GMP的BUILD配置,导出头文件
确保GMP构建时生成位置无关代码,并明确导出头文件目录,让Bazel和CMake能正确找到头文件:
修改后的gmp.BUILD.bazel:
load("@rules_foreign_cc//foreign_cc:defs.bzl", "configure_make") configure_make( name = "gmp", configure_options = ["--with-pic"], lib_name = "libgmp", lib_source = ":all_srcs", # 导出头文件目录,让依赖能找到gmp.h out_include_dirs = ["include"], visibility = ["//visibility:public"], ) configure_make( name = "gmpxx", configure_options = ["--enable-cxx", "--with-pic"], env = { "CXX": "g++", "CXXFLAGS": "-std=c++17 -lstdc++", }, lib_name = "libgmpxx", lib_source = ":all_srcs", out_include_dirs = ["include"], visibility = ["//visibility:public"], deps = [":gmp"], ) filegroup( name = "all_srcs", srcs = glob(["**"]), visibility = ["//visibility:private"], )
3. 关键注意点
- rules_foreign_cc的
deps仅控制Bazel的依赖构建顺序,不会自动将依赖的路径注入到外部构建系统(如CMake),必须手动通过cache_entries或cmake_options传递必要的变量。 - 手动指定
GMP_INCLUDE_DIRS和GMP_LIBRARIES可以绕过CMake的find_package(GMP)自动检测,直接强制使用Bazel构建的GMP库。 - 给GMP添加
--with-pic确保生成位置无关代码,避免链接soplex时出现重定位错误。
内容的提问来源于stack exchange,提问作者Tend
相关产品推荐
相关产品推荐

