"Undefined symbols for x86_64" link MacOS 中的 Kafka C++ 错误

"Undefined symbols for x86_64" link error for Kafka C++ in MacOS

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

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

安装 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.

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

WARNING: librdkafka-static.a: Not creating self-contained static library librdkafka-static.a: no static libraries available/enabled

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

然后我修改了tasks.json,使include 和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",
                "-stdlib=libc++",
                "-g",
                "-v",
                "-I/usr/local/include/librdkafka/",
                "-L/usr/local/lib",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
...
  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库。缺少的是为库添加 link 选项。我的意思是我添加了查找包含和二进制库文件的选项

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

但那是为了让编译器找到它们。它需要命令告诉 linker 使用 "-lrdkafka++",.

的库

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

cmake解决方案 CMakeLists.txt

include_directories(/usr/local/Cellar/librdkafka/1.8.2/include/) 

link_directories(/usr/local/Cellar/librdkafka/1.8.2/lib/) 

set(CMAKE_EXE_LINKER_FLAGS "-lrdkafka++ -lrdkafka")

选项

$ pkg-config --libs rdkafka
$ pkg-config --libs rdkafka++