【问题标题】:How to fix "ld: symbol(s) not found for architecture x86_64" using C++, CMake and Tensorflow?如何使用 C++、CMake 和 Tensorflow 修复“ld: symbol(s) not found for architecture x86_64”?
【发布时间】:2019-10-25 15:54:06
【问题描述】:

我使用带有 CMake 的 TensorFlow 在 C++ 中创建了一个测试项目。但我有一个错误:

ld: symbol(s) not found for architecture x86_64

我想,我的 CMake 文件中有错误。当我尝试使用gcc tensortest.cpp -ltensorflow -o tf 通过终端进行编译时,一切正常。

我有两个 CMake 文件。

查找TensorFlow.cmake:

# Locates the tensorFlow library and include directories.
include(FindPackageHandleStandardArgs)
unset(TENSORFLOW_FOUND)

find_path(TensorFlow_INCLUDE_DIR
        NAMES
        tensorflow
        HINTS

        /usr/local/include/tensorflow)

find_library(TensorFlow_LIBRARY
        NAMES
        libtensorflow_framework.1.14.0.dylib
        libtensorflow_framework.1.dylib
        libtensorflow_framework.dylib
        libtensorflow.1.14.0.dylib
        libtensorflow.1.dylib
        libtensorflow.dylib
        HINTS
        /usr/local/lib)

# set TensorFlow_FOUND
find_package_handle_standard_args(TensorFlow DEFAULT_MSG TensorFlow_INCLUDE_DIR TensorFlow_LIBRARY)

# set external variables for usage in CMakeLists.txt
if(TENSORFLOW_FOUND)
  set(TensorFlow_LIBRARIES ${TensorFlow_LIBRARY})
  set(TensorFlow_INCLUDE_DIRS ${TensorFlow_INCLUDE_DIR})
endif()

# hide locals from GUI
mark_as_advanced(TensorFlow_INCLUDE_DIR TensorFlow_LIBRARY)

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)
project(TensorFlowTest)

set(CMAKE_CXX_STANDARD 14)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/")

find_package(TensorFlow REQUIRED)
include_directories(${TensorFlow_INCLUDE_DIRS} ${TensorFlow_LIBRARIES})

add_executable(TensorFlowTest main.cpp)
target_link_libraries(TensorFlowTest ${TensorFlow_INCLUDE_DIRS} ${TensorFlow_LIBRARIES})

还有一个 main.cpp

#include <stdio.h>
#include <tensorflow/c/c_api.h>

int main() {
    printf("Hello from TensorFlow C library version %s\n", TF_Version());
    return 0;
}

重新加载项目时,我有一条 CMake 消息:

-- Found TensorFlow: /usr/local/include  
-- Configuring done
WARNING: Target "TensorFlowTest" requests linking to directory "/usr/local/include".  Targets may link only to libraries.  CMake is dropping the item.
-- Generating done
-- Build files have been written to: /Users/neikr/CLionProjects/TensorFlowTest/cmake-build-debug

编译时:

Scanning dependencies of target TensorFlowTest
[ 50%] Building CXX object CMakeFiles/TensorFlowTest.dir/main.cpp.o
[100%] Linking CXX executable TensorFlowTest
Undefined symbols for architecture x86_64:
  "_TF_Version", referenced from:
      _main in main.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)
make[3]: *** [TensorFlowTest] Error 1
make[2]: *** [CMakeFiles/TensorFlowTest.dir/all] Error 2
make[1]: *** [CMakeFiles/TensorFlowTest.dir/rule] Error 2
make: *** [TensorFlowTest] Error 2

更新

我用VERBOSE=1 尝试了make,我得到了这个输出:

/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -S/Users/neikr/CLionProjects/TensorFlowTest -B/Users/neikr/CLionProjects/TensorFlowTest --check-build-system CMakeFiles/Makefile.cmake 0
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -E cmake_progress_start /Users/neikr/CLionProjects/TensorFlowTest/CMakeFiles /Users/neikr/CLionProjects/TensorFlowTest/CMakeFiles/progress.marks
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/Makefile2 all
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/TensorFlowTest.dir/build.make CMakeFiles/TensorFlowTest.dir/depend
cd /Users/neikr/CLionProjects/TensorFlowTest && /Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -E cmake_depends "Unix Makefiles" /Users/neikr/CLionProjects/TensorFlowTest /Users/neikr/CLionProjects/TensorFlowTest /Users/neikr/CLionProjects/TensorFlowTest /Users/neikr/CLionProjects/TensorFlowTest /Users/neikr/CLionProjects/TensorFlowTest/CMakeFiles/TensorFlowTest.dir/DependInfo.cmake --color=
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/TensorFlowTest.dir/build.make CMakeFiles/TensorFlowTest.dir/build
[ 50%] Linking CXX executable TensorFlowTest
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -E cmake_link_script CMakeFiles/TensorFlowTest.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++  -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names  CMakeFiles/TensorFlowTest.dir/main.cpp.o  -o TensorFlowTest -Wl,-rpath,/usr/local/lib /usr/local/lib/libtensorflow_framework.1.14.0.dylib 
Undefined symbols for architecture x86_64:
  "_TF_Version", referenced from:
      _main in main.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)
make[2]: *** [TensorFlowTest] Error 1
make[1]: *** [CMakeFiles/TensorFlowTest.dir/all] Error 2
make: *** [all] Error 2

另外,我尝试将message("TensorFlow_LIBRARIES: ${TensorFlow_LIBRARIES}") 添加到我的 CMake 的末尾,我收到以下消息:

TensorFlow_LIBRARIES: /usr/local/lib/libtensorflow_framework.1.14.0.dylib

【问题讨论】:

  • 请在调用中包含详细标志以获取更详细的错误信息。检查您的 cmake 缓存或使用 ccmake 检查不正确的路径。
  • 欢迎来到 Stackoverflow,第一个问题很好!我认为您将 include 目录link library 混淆了。您应该只在此处包含头文件目录:include_directories(${TensorFlow_INCLUDE_DIRS})。同样,您只需在此处添加库 (_LIBRARIES):target_link_libraries(TensorFlowTest ${TensorFlow_LIBRARIES})
  • 查看 TensorFlow 库是否确实找到会很有帮助。考虑将 message("TensorFlow_LIBRARIES: ${TensorFlow_LIBRARIES}") 添加到 CMake 的末尾。或者,按照建议,请将make VERBOSE=1 的输出添加到您的问题帖子中。
  • @squareskittles 我更改了 include_directories(${TensorFlow_INCLUDE_DIRS} 上的包含目录。但是我不明白需要添加哪些库。
  • 根据您从message() 命令打印出来的结果,更加清晰。 find_library() 调用仅找到 onelibtensorflow_framework.1.14.0.dylib,这是预期的行为。一旦find_library() 找到one 库,它就会停止搜索。如果您还想找到可能有助于解决链接错误的libtensorflow.dylib,则必须使用不同的TensorFlow_ 变量指定另一个 find_library() 调用。

标签: c++ macos tensorflow cmake


【解决方案1】:

根据您从message() 命令的打印输出,可以更清楚地知道发生了什么。在您的 FindTensorFlow.cmake 文件中,find_library() 调用仅找到 one 库 (libtensorflow_framework.1.14.0.dylib),这是预期的行为:

一旦其中一个调用成功,结果变量将被设置并存储在缓存中,这样就不会再次搜索。

NAMES 选项有多个值时,默认情况下此命令将一次考虑一个名称并在每个目录中搜索它。

因此,一旦find_library() 找到libtensorflow_framework 库,搜索停止。如果您还想找到可能有助于解决链接错误的libtensorflow.dylib,则必须使用不同的TensorFlow_ 变量指定另一个find_library() 调用。因此,将您的 FindTensorFlow.cmake 的那部分更改为这样的内容应该会有所帮助:

find_library(TensorFlow_LIBRARY
        NAMES
        libtensorflow.1.14.0.dylib
        libtensorflow.1.dylib
        libtensorflow.dylib
        HINTS
        /usr/local/lib)

find_library(TensorFlow_FRAMEWORK_LIBRARY
        NAMES
        libtensorflow_framework.1.14.0.dylib
        libtensorflow_framework.1.dylib
        libtensorflow_framework.dylib
        HINTS
        /usr/local/lib)

# set TensorFlow_FOUND
find_package_handle_standard_args(TensorFlow DEFAULT_MSG 
    TensorFlow_INCLUDE_DIR 
    TensorFlow_LIBRARY 
    TensorFlow_FRAMEWORK_LIBRARY
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-31
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 2016-05-21
    相关资源
    最近更新 更多