如何使用-v调用来查看cmake链接器错误(未定义的符号)的详细信息?

7
如何使用-v选项来查看cmake链接器错误的详细信息?我找到了两个现有问题,但一个是针对Xcode构建的,另一个是针对NDK构建的。它们在这里:use -v to see invocation?How to use cmake -v invocation to help find linker error。我正在使用标准的cmakelists.txt方法,我的系统是OSX Mojave。出现的错误如下:
Undefined symbols for architecture x86_64:
   "Image::createImage(int, int, int)", referenced from:
       _main in tutorial.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

有人在Stack Overflow的问题评论中展示了我正在尝试做的事情:

...you could use -v to see the linker invocation to see what's going wrong. It would show you this link line:

"/usr/bin/ld" -demangle -dynamic -arch x86_64 
    -macosx_version_min 10.6.8 -o a.out -lcrt1.10.6.o
    /var/folders/zl/zlZcj24WHvenScwjPFFFQE+++TI/-Tmp-/cc-hdOL8Z.o
    -lSystem /Developer/usr/bin/../lib/clang/3.0/lib/darwin/libclang_rt.osx.a

我是一个cmake新手,我已经尝试在我的CMakeLists.txt文件中使用以下所有内容,但它们都没有起作用:

add_link_options(-v)
add_link_options("-v")
target_link_options(myexec PUBLIC -v)
target_link_options(myexec PUBLIC "-v")
target_link_options(myexec PUBLIC "LINKER:-v")

你使用的CMAKE版本是什么?add_link_optionstarget_link_options是在CMAKE 3.13中添加的。 - JustinCB
我正在使用CMAKE 3.15.3。是的,看起来我一定是错误地使用了add_link_options和target_link_options。 - Alyoshak
你尝试过 add_link_options("LINKER:-v") 吗?根据 CMAKE 文档(https://cmake.org/cmake/help/latest/command/add_link_options.html),如果你的 CMAKE 设置使用编译器(gcc/clang)来链接内容,那么你需要这样做。此外,我会检查是否缺少库、32 位库或任何编译为 32 位的内容。 - JustinCB
尝试过了,但输出结果与不尝试时完全一样。我使用了你推荐的内容。 - Alyoshak
-v 只显示链接命令,它并不能使错误消息更清晰。很难猜测为什么它拒绝告诉你它找不到哪些符号,这似乎是一个 stderr 重定向问题。或者我们需要看一下链接命令 ;) - Hans Passant
它告诉我它找不到哪些符号,但我正在尝试按建议执行-v调用。 - Alyoshak
1个回答

12
最简单的方式是使用VERBOSE=1 make,而不是仅使用make(如果你使用的是make)。
输出结果大致如下:
VERBOSE=1 make      
[100%] Linking C executable example
/usr/bin/cmake -E cmake_link_script CMakeFiles/example.dir/link.txt --verbose=1
/usr/bin/cc   -rdynamic CMakeFiles/example.dir/main.c.o  -o example 
make[2]: Leaving directory '../c-examples/cmake/build'
[100%] Built target example
make[1]: Leaving directory '../c-examples/cmake/build'
/usr/bin/cmake -E cmake_progress_start ../c-examples/cmake/build/CMakeFiles 0

你看到这里调用了cc。在你的情况下,你使用的是clang(也可能是gcc)。

假设你已经执行了像sudo update-alternatives --config cc这样的命令 - 或者通过任何其他方式来组织操作系统上的符号链接 - 以将clang设置为默认编译器。现在,如果你只输入cc -v,你会看到它会显示版本信息。相反,你需要要求连接器详细说明。这可以通过-Wl-Xlinker来完成。

在你的情况下,像这个CMakeLists.txt这样的东西会提供充分的信息:

# Note that this is an older cmake version, use target_link_options if available
cmake_minimum_required (VERSION 2.6)

# Project name (in this case a simple C project where the math dep is "forgotten")
project(mathdep_example)

# Not your situation, but in case you have a different linker
# set(CMAKE_EXE_LINKER_FLAGS "-Wl,--verbose")

# Clang passes flags through to the linker (likely ld) by
# set(CMAKE_EXE_LINKER_FLAGS "-Xlinker -v")

# Clang passing flags to the linker (likely ld) AND using -v itself to show how it calls the linker
set(CMAKE_EXE_LINKER_FLAGS "-Xlinker -v -v")

# The final executable
add_executable(example main.c)

# In case you want also verbose compilation steps
target_compile_options(example PRIVATE -v)
观察链接器标志中的-v出现了两次。第一个在-Xlinker之前,将被传递给链接器(可能是ld)。第二个是在链接步骤中对clang本身的选项。请注意,即使您实际上已经添加了-vclang仍会告诉您要添加它。这可能被视为一个错误......

在您的情况下,我会检查您正在使用什么类型的.o.a文件。听起来它们不适用于您的架构。使用file命令检查:

file object_file.o
file archive_file.a

1
我会尽快尝试这个。不幸的是,有一个非常重要的问题需要我关注。是的,它是一个ld问题,所以不是编译器的问题。因此,我将尝试您的-Wl或-Xlinker建议,并启用verbose模式。 - Alyoshak
我只是在cmakelists.txt文件中按照你建议的位置添加了这行代码:set(CMAKE_EXE_LINKER_FLAGS "-Wl,--verbose"),然后进行了构建。结果,这行代码现在是新的:ld: unknown option: --verbose,并且这些行(原始链接错误信息)也已经消失:Undefined symbols for architecture x86_64: "Image::createImage(int, int, int)", referenced from: _main in tutorial.cpp.o ld: symbol(s) not found for architecture x86_64 - Alyoshak
VERBOSE=1 可以提供编译过程中详细的信息,但并不会提供关于链接过程的额外信息。 - Alyoshak
只需将 VERBOSE=1 make 的完整输出放在 gist 中。并返回 file *.ofile *.a 的结果。您将很快得到帮助! - Anne van Rossum
请注意,该消息来自clang clang: error: linker command failed with exit code 1 (use -v to see invocation)。然而,它抱怨的是链接器,这很可能只是ld。它说你可以通过将-v作为命令添加到clang中来查看它如何调用链接器。 - Anne van Rossum
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接