Как использовать -v вызов, чтобы увидеть подробности об ошибке компоновщика cmake (неопределенные символы)? - PullRequest
3 голосов
/ 07 октября 2019

Как конкретно я использую вызов -v для просмотра подробностей об ошибке компоновщика cmake? Я нашел два существующих вопроса об использовании этой опции, но один для сборок Xcode, а другой для сборок NDK. Они здесь:

используйте -v, чтобы увидеть вызов?

Как использовать вызов cmake -v, чтобы помочь найти ошибку компоновщика

Я в OSX Mojave. Я использую стандартный подход cmakelists.txt, и ошибка такова:

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)

Комментарий в вопросе SO показывает, что я пытаюсь сделать:

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

(Iя новичок 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")

1 Ответ

5 голосов
/ 12 октября 2019

Самым простым является простой 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, вы увидите, что он покажет version информацию. Вы скорее хотите попросить компоновщика быть многословным. Это делается через -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 на шаге компоновщика. Обратите внимание, что clang все еще говорит вам добавить -v, даже если вы действительно это сделали. Это можно считать ошибкой ...

В вашем случае я бы проверил, какие файлы .o и .a вы используете. Похоже, они не для вашей архитектуры. Используйте file:

file object_file.o
file archive_file.a
...