chen3feng / blade-build

Blade is a powerful build system from Tencent, supports many mainstream programming languages, such as C/C++, java, scala, python, protobuf...
Other
2.05k stars 500 forks source link

如何引用只包含 lib 和 include 的第三方库 #1007

Closed TOMO-CAT closed 1 year ago

TOMO-CAT commented 1 year ago

背景

一般情况下第三方库是安装到系统库的,此时直接使用第三方库的代码 BUILD 文件可以写成这样(比如使用 pthread):

cc_binary(
    name='main',
    srcs=['main.cc'],
    deps=['#pthread']
)

但是我们项目由于历史原因,需要将 thirdparty 库上传到代码库中,例如 thirdparty 下面放了 poco、log4cpp、rapidjson 等第三方库的头文件和库文件:

image

这种背景下我们想接入 blade-build。

尝试

根据 blade-build 的项目文档,我写了一个 demo 尝试引入第三方库:

https://github.com/TOMO-CAT/BladeBuildExample

在 demo 中我用了 poco 库,因此在 thirdparty 目录中增加了一个 BUILD 文件:

image

内容如下:

cc_library(
    name='poco',
    # Similar to `incs`, but it is transitive for all targets depends on it, even if indirect depends on it.
    export_incs=['poco/include'],
    srcs=[],
    hdrs=['poco/include/Poco/DateTimeFormatter.h'],
    visibility=['PUBLIC'],
)

会报错找不到定义:

image

一种取巧的方式是我在 BLADE_ROOT 中加入编译选项:

cc_config(
    cxxflags=['-std=c++17'],
    optimize='-O2',
    linkflags=["-Lthirdparty/poco/lib", "-lPocoFoundation"],
)

依然报错:

image

但是我直接 g++ 编译是可以通过的:

$g++ -g ./main/main.cc -Lthirdparty/poco/lib -lPocoFoundation -Ithirdparty/poco/include

问题

1. export_incs 和 hdrs 有什么不同?

issue 568 中看到可以使用 export_incs 导出只包含头文件的 thirdparty,但是根据我的实际操作发现 export_incs 像是编译期的 -I 参数提供头文件目录,hdrs 像是 BLADE 的头文件约束,必须要显示写出来 hdrs 才能使用 BLADE 编译,否则会报错:

image

有一个问题是一般的 thirdparty 的 include 文件里面头文件特别多,是不是提供类似 export_incs 这种目录写法?

有一种替代写法好像是 hdrs = glob("./**/*.h") ,但是感觉不够优雅。

2. 如何优雅地引用这种类似系统库的只包含 include 和 lib 文件夹的第三方库?

我希望是在 thirdparty/BUILD 文件中可以填写 include 文件夹路径和 lib 库文件夹路径就可以直接包含一个第三方库,例如:

cc_library(
    name='poco',
    export_incs=['poco/include'],
    export_libs=['poco/lib'],
    visibility=['PUBLIC'],
)

然后用到的地方可以直接写 deps=['//thirdparty:poco']

辛苦解答,万分感谢~

TOMO-CAT commented 1 year ago

按照文档找到了一种解决方法:

prebuilt_cc_library(
    name='PocoFoundation',
    export_incs=['poco/include'],
    libpath_pattern='poco/lib',
    hdrs=['poco/include/Poco/DateTimeFormatter.h'],
    visibility=['PUBLIC'],
)

但是需要每个 so 库都写一次

TOMO-CAT commented 1 year ago

搞定了:

# 所需要的库的列表
_DEPS = [
    'PocoFoundation',
]

# 生成 poco 包中各个库的 blade 描述
[prebuilt_cc_library(
    name=name,
    libpath_pattern = 'lib',
    hdrs=[],
    export_incs = 'include') for name in _DEPS
]

# 对外接口
cc_library(
    name = 'poco',
    export_incs=['include'],
    deps = [':' + dep for dep in _DEPS],
    hdrs=['include/Poco/DateTimeFormatter.h'],
    # hdrs=glob("./**/*.h"),
    # hdrs=glob("./include/Poco/*.h"),
    visibility=['PUBLIC'],
)