【问题标题】:"Undefined symbols for x86_64" link error for Kafka C++ in MacOSMacOS 中 Kafka C++ 的“x86_64 的未定义符号”链接错误
【发布时间】:2021-10-05 02:54:37
【问题描述】:

我一直在尝试使用 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 安装了它们,输出如下(Ref 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 使用 brew 安装 Kafka
{
    "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

【问题讨论】:

    标签: c++ macos apache-kafka librdkafka


    【解决方案1】:

    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++
    

    【讨论】:

      【解决方案2】:

      终于搞定了,所以我会写在这里,以防它帮助别人。

      解决这个问题的方法是使用第二个选项,从源代码编译 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++", 的更改。 我希望这可以帮助其他遇到我遇到同样问题的人。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-14
        • 2013-04-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多