MacOS 中 Kafka C++ 的“x86_64 的未定义符号”链接错误

问题描述

我一直在尝试使用 MacOS 中的 VsCode(Catalina 版本 10.15.7)在 C++ 中为 Kafka 构建一个简单的使用者,但我遇到了相同的链接错误。我试图在这里找到一些答案,但我发现的那些对我来说没有用(例如as this one),因为我可以正确构建 Kafka。

以下是我到目前为止尝试的步骤以及每种情况下编译器/链接器的输出。我没有包含代码,因为它是一个简单的代码错误来自链接器,尽管如果有人认为它有帮助,我会添加它。让我知道是否应该包含其他内容

使用 brew 安装

首先,我使用 brew 和以下命令安装了 kafka 库: brew install librdkafka 安装后,库位于 /usr/local/Cellar/librdkafka/1.7.0/lib//usr/local/Cellar/librdkafka/1.7.0/include/,这是我在 task.json 中用于 VsCode 中认构建的路径。

我得到的错误是:

Undefined symbols for architecture x86_64:
  "RdKafka::get_debug_contexts()",referenced from:
      _main in read-topics-d64669.o
  "RdKafka::Conf::create(RdKafka::Conf::ConfType)",referenced from:
      _main in read-topics-d64669.o
  "RdKafka::Topic::OFFSET_BEGINNING",referenced from:
      _main in read-topics-d64669.o
  "RdKafka::Consumer::create(RdKafka::Conf const*,std::__1::basic_string<char,std::__1::char_traits<char>,std::__1::allocator<char> >&)",referenced from:
      _main in read-topics-d64669.o
...

(为清楚起见缩短)。 如果我使用 IntelliSense 查找我的代码中使用的任何 Kafka 函数的定义,它会发现它正确打开了在 tasks.json添加的正确文件夹 ('/usr/local/Cellar/librdkafka/1.7.0/include/librdkafka/rdkafkacpp.h' ) 中的库文件参考文献 1)。但是,链接器似乎在查找也添加链接器参数中的库文件时遇到问题。

从源代码编译

然后我尝试按照存储库文档中提供的说明直接从 sources 编译 Kafka。为了确保我没有遗漏任何东西,我添加自动安装所需依赖项的选项:./configure --install-deps

来自该命令的唯一可疑消息是这个

警告:librdkafka-static.a:未创建自包含静态库 librdkafka-static.a:没有可用/启用的静态库

但一切看起来都不错,我认为这不是真正的问题。它们,我用 make install 安装它们,输出如下(参考 3)。

然后我修改tasks.json 以获得包含和 lib 文件夹的正确路径(参考文献 2)。但是,由于链接器,构建仍然失败,并且我遇到了与以前相同的错误

Undefined symbols for architecture x86_64:
  "RdKafka::get_debug_contexts()",referenced from:
      _main in read-topics-991879.o
  "RdKafka::Conf::create(RdKafka::Conf::ConfType)",referenced from:
      _main in read-topics-991879.o
  "RdKafka::Topic::OFFSET_BEGINNING",referenced from:
      _main in read-topics-991879.o
 ...

知道我可以尝试解决什么错误吗? 我做错了什么或我错过了什么? 任何帮助或建议将不胜感激。


参考文献

  1. tasks.json 与 Kafka 一起安装 brew
{
    "version": "2.0.0","tasks": [
        {
            "type": "shell","label": "C/C++: clang build active file","command": "/usr/bin/clang","args": [
                "-std=c++17","-stdlib=libc++","-g","-v","-I/usr/local/Cellar/librdkafka/1.7.0/include/librdkafka","-L/usr/local/Cellar/librdkafka/1.7.0/lib/","${file}","-o","${fileDirname}/${fileBasenameNoExtension}"
            ],"options": {
                "cwd": "${workspaceFolder}"
            },"problemmatcher": [
                "$gcc"
            ],"group": {
                "kind": "build","isDefault": true
            }
        }
    ]
}
  1. tasks.json 使用从源代码编译的 Kafka(仅更改的部分,其他一切都相同)
...
"args": [
                "-std=c++17","-I/usr/local/include/librdkafka/","-L/usr/local/lib",...
  1. Kafka 构建输出
Install librdkafka to /usr/local
install -d $DESTDIR/usr/local/include/librdkafka
install -d $DESTDIR/usr/local/lib
install rdkafka.h rdkafka_mock.h $DESTDIR/usr/local/include/librdkafka
install librdkafka.a $DESTDIR/usr/local/lib
[ ! -f librdkafka-static.a ] || install librdkafka-static.a $DESTDIR/usr/local/lib
install librdkafka.1.dylib $DESTDIR/usr/local/lib
[ -f "rdkafka.pc" ] && ( \
        install -d $DESTDIR/usr/local/lib/pkgconfig && \
        install -m 0644 rdkafka.pc $DESTDIR/usr/local/lib/pkgconfig \
    )
[ -f "rdkafka-static.pc" ] && ( \
        install -d $DESTDIR/usr/local/lib/pkgconfig && \
        install -m 0644 rdkafka-static.pc $DESTDIR/usr/local/lib/pkgconfig \
    )
(cd $DESTDIR/usr/local/lib && ln -sf librdkafka.1.dylib librdkafka.dylib)
Install librdkafka++ to /usr/local
install -d $DESTDIR/usr/local/include/librdkafka
install -d $DESTDIR/usr/local/lib
install rdkafkacpp.h $DESTDIR/usr/local/include/librdkafka
install librdkafka++.a $DESTDIR/usr/local/lib
[ ! -f librdkafka++-static.a ] || install librdkafka++-static.a $DESTDIR/usr/local/lib
install librdkafka++.1.dylib $DESTDIR/usr/local/lib
[ -f "rdkafka++.pc" ] && ( \
        install -d $DESTDIR/usr/local/lib/pkgconfig && \
        install -m 0644 rdkafka++.pc $DESTDIR/usr/local/lib/pkgconfig \
    )
[ -f "rdkafka++-static.pc" ] && ( \
        install -d $DESTDIR/usr/local/lib/pkgconfig && \
        install -m 0644 rdkafka++-static.pc $DESTDIR/usr/local/lib/pkgconfig \
    )
(cd $DESTDIR/usr/local/lib && ln -sf librdkafka++.1.dylib librdkafka++.dylib)
WARNING: librdkafka-static.a: Not creating self-contained static library librdkafka-static.a: no static libraries available/enabled
Generating pkg-config file rdkafka-static.pc
Checking librdkafka integrity
librdkafka.1.dylib             OK
librdkafka.a                   OK
Symbol visibility              OK
Generating pkg-config file rdkafka++-static.pc
Checking librdkafka++ integrity
librdkafka++.1.dylib           OK
librdkafka++.a                 OK
/Library/Developer/CommandLinetools/usr/bin/make -C examples
make[1]: nothing to be done for `all'.
Updating CONfigURATION.md
Installing documentation to /usr/local
install -d $DESTDIR/usr/local/share/doc/librdkafka
install LICENSE LICENSES.txt INTRODUCTION.md README.md CONfigURATION.md STATISTICS.md CHANGELOG.md $DESTDIR/usr/local/share/doc/librdkafka

解决方法

最后我让它工作了,所以我会写在这里,以防它对其他人有帮助。

解决方法是使用第二个选项,从源代码编译 Kafka 库。缺少的是为库添加链接选项。我的意思是我添加了查找包含和二进制库文件的选项

"-I/usr/local/Cellar/librdkafka/1.7.0/include/librdkafka","-L/usr/local/Cellar/librdkafka/1.7.0/lib/",

但那是为了让编译器找到那些。它需要命令来告诉链接器使用 "-lrdkafka++", 库。

我最后做错的事情是指定 Clang 应该编译 C++ 代码,这已经完成了对 "command": "/usr/bin/clang++", 的更改。 我希望这能帮助其他和我遇到同样问题的人。