我有一个C代码库,我试图与Bazel建立。这个代码库包含了使用fff库在C中生成函数模拟的单元测试。实际的库并不重要,我对函数模拟的整个概念有问题。
现在我有一个makefile,我在其中链接并运行我的测试。当我构建一个测试时,我编译并链接测试下的库和测试源代码本身。此测试还定义了库依赖项的模拟。链接后,模拟的符号被解析为模拟实现,一切都按预期工作。但它这样做的原因是我不链接实际的依赖库,我只链接测试源代码中定义的模拟符号。
主要问题是:我该怎么和Bazel合作?当链接cc_test
目标的二进制文件时,Bazel编译并链接所有传递依赖项。由于被测库依赖于(通过deps
)符号的真实实现,这个真实的定义与mock定义一起链接,自然会出现以下错误:multiple definition of XXX
的值。
示例如下:
cc_library(
name = "a",
# a.cc has the real version of "void some_function()".
srcs = ["a.cc"],
hdrs = ["a.h"],
)
# This test is working just fine.
cc_test(
name = "a_test",
srcs = ["a_test.cpp"],
deps = [":a"],
)
cc_library(
name = "b",
# b.cc includes a.h and uses "void some_function()".
srcs = ["b.cc"],
hdrs = ["b.h"],
deps = [":a"],
)
# This test has two definitions for "void some_function()":
# the real one and the mock one.
cc_test(
name = "b_test",
# b_test.cpp has the mock version of "void some_function()".
srcs = ["b_test.cpp"],
deps = [":b"],
)
字符串
我对Bazel并不陌生,但我也不是Maven,在花了很多时间尝试之后,我失败了。有什么建议吗?
3条答案
按热度按时间csbfibhn1#
您的问题可能是一个非常基本的问题,与名称空间和/或扩展类有关。
c没有命名空间的定义,但它们可以以某种方式模拟:
https://stackoverflow.com/a/28535585/1019850
但是你可能会使用c++而不是c,所以可以直接使用名称空间。
具体的问题是,你有两个相同的函数,它们将用名称空间
a.some_function()
和b.some_function()
表示。在Bazel中有几种解决方案,我只是发布了一些简短的复制片段,你必须在链接页面上阅读详细信息。
字符串
友情链接:https://docs.bazel.build/versions/master/cpp-use-cases.html
这里的代码片段也用于测试,但我认为这与您的问题无关。
然后在Bazel中存在工具链,这里是一个例子:
型
友情链接:https://docs.bazel.build/versions/master/toolchains.html
由于我不是用c或c++编程,通常我需要花相当长的时间来挖掘足够的解决方案,所以我不得不保留它,但没有真实的的解决方案,但我希望问题和解决它的方法变得更清晰。
我会先尝试第二个链接,在上面的第一个片段下面。
kupeojn62#
我在Bazel本身看不到任何好的解决方案。在C的情况下,Bazel试图创建一个简单而清晰的依赖管理系统来减少所有的诡计,这可以在C/C编译/链接系统中完成。你的情况很不寻常。
我看到的唯一解决方案是使用弱符号将负担转移到链接器。你可以使用
__attribute__((weak))
来注解你的“正常”函数。你的“假”函数应该选择在所有目标中的“正常”函数,其中函数的强符号(假函数)是存在的2sbarzqh3#
我也遇到了同样的问题,并编写了一个bazel规则来添加或删除CC目标的链接依赖项。它很粗糙,不处理任何非链接器依赖:
字符串
根据你的例子,你可以定义:
型