代码之家  ›  专栏  ›  技术社区  ›  Daniel Ryan

CMake生成错误-缺少虚拟方法错误的vtable

  •  0
  • Daniel Ryan  · 技术社区  · 7 年前

    我们的XCODE C++项目正在转换成CMAGE脚本。在构建CMake脚本时,如果我在虚拟main中使用具有虚拟函数的类,则会不断发生缺少vtable的错误。如果我只使用一个在我的main中没有虚拟函数的类,那么一切都可以正常构建。

    该项目为Xcode构建良好。我的CMake脚本缺少什么?

    CMake文件:

    cmake_minimum_required(VERSION 3.0)
    add_compile_options(-std=c++17)
    SET (PROJECT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/source")
    
    include_directories(
        "${PROJECT_SOURCE_DIR}/"
        "${PROJECT_SOURCE_DIR}/main/"
        "${PROJECT_SOURCE_DIR}/lib/hopscotch-map/"
        "${PROJECT_SOURCE_DIR}/lib/rapidjson/"
    )
    
    add_executable(TestProject "${PROJECT_SOURCE_DIR}/main/dummy-main.cpp")
    install(TARGETS TestProject DESTINATION bin) 
    

    主文件:

    #include <stdio.h>
    #include "Player.hpp"
    
    int main(int argc, char **argv) {
        auto player = Player{"John"};
        return 0;
    }
    

    jess$ gmake -j 8 VERBOSE=1
    /usr/local/Cellar/cmake/3.13.3/bin/cmake -S/Users/jess/TestProject -B/Users/jess/TestProject --check-build-system CMakeFiles/Makefile.cmake 0
    /usr/local/Cellar/cmake/3.13.3/bin/cmake -E cmake_progress_start /Users/jess/TestProject/CMakeFiles /Users/jess/TestProject/CMakeFiles/progress.marks
    gmake -f CMakeFiles/Makefile2 all
    gmake[1]: Entering directory '/Users/jess/TestProject'
    gmake -f CMakeFiles/TestProject.dir/build.make CMakeFiles/TestProject.dir/depend
    gmake[2]: Entering directory '/Users/jess/TestProject'
    cd /Users/jess/TestProject && /usr/local/Cellar/cmake/3.13.3/bin/cmake -E cmake_depends "Unix Makefiles" /Users/jess/TestProject /Users/jess/TestProject /Users/jess/TestProject /Users/jess/TestProject /Users/jess/TestProject/CMakeFiles/TestProject.dir/DependInfo.cmake --color=
    Dependee "source/BaseEntity.hpp" is newer than depends file "/Users/jess/TestProject/CMakeFiles/TestProject.dir/depend.internal".
    Clearing dependencies in "/Users/jess/TestProject/CMakeFiles/TestProject.dir/depend.make".
    Scanning dependencies of target TestProject
    gmake[2]: Leaving directory '/Users/jess/TestProject'
    gmake -f CMakeFiles/TestProject.dir/build.make CMakeFiles/TestProject.dir/build
    gmake[2]: Entering directory '/Users/jess/TestProject'
    [ 50%] Building CXX object CMakeFiles/TestProject.dir/source/main/dummy-main.cpp.o
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++   -I/Users/jess/TestProject -I/Users/jess/TestProject/source -I/Users/jess/TestProject/source/lib/hopscotch-map -I/Users/jess/TestProject/source/lib/rapidjson -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk   -std=c++17 -fPIC -fexceptions -g -O3 -o CMakeFiles/TestProject.dir/source/main/dummy-main.cpp.o -c /Users/jess/TestProject/source/main/dummy-main.cpp
    [100%] Linking CXX executable TestProject
    /usr/local/Cellar/cmake/3.13.3/bin/cmake -E cmake_link_script CMakeFiles/TestProject.dir/link.txt --verbose=1
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++   -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names  CMakeFiles/TestProject.dir/source/main/dummy-main.cpp.o  -o TestProject
    Undefined symbols for architecture x86_64:
      "Player::Player(std::__1::basic_string_view<char, std::__1::char_traits<char> >)", referenced from:
          _main in dummy-main.cpp.o
      "vtable for BaseEntity", referenced from:
          Player::~Player() in dummy-main.cpp.o
      NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
      "vtable for Player", referenced from:
          Player::~Player() in dummy-main.cpp.o
      NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    gmake[2]: *** [CMakeFiles/TestProject.dir/build.make:84: TestProject] Error 1
    gmake[2]: Leaving directory '/Users/jess/TestProject'
    gmake[1]: *** [CMakeFiles/Makefile2:73: CMakeFiles/TestProject.dir/all] Error 2
    gmake[1]: Leaving directory '/Users/jess/TestProject'
    gmake: *** [Makefile:130: all] Error 2
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Richard Hodges    7 年前

    线索隐藏在链接器输出中:

    Undefined symbols for architecture x86_64:
      "Player::Player(std::__1::basic_string_view<char, std::__1::char_traits<char> >)", referenced from:
      _main in dummy-main.cpp.o
      "vtable for BaseEntity", referenced from:
      Player::~Player() in dummy-main.cpp.o
      NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
      "vtable for Player", referenced from:
      Player::~Player() in dummy-main.cpp.o
      NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
    

    这会立即提醒我您忘记链接包含这些函数定义的编译单元。

    Player 定义于 player.hpp 和 player.cpp 并且它们在子目录中 src 那么我的建议是更新 add_executable 呼吁:

    add_executable(TestProject "${PROJECT_SOURCE_DIR}/main/dummy-main.cpp" src/player.hpp src/player.cpp)

    请注意,“当前源或二进制目录”在这里是假定的,不需要详细说明。

    还要注意,我已经将头文件作为目标文件的一部分包含在内。这样做有很多好处:

    • 为visual studio、xcode等生成项目文件时,这些文件将显示在项目树中。
    • 使用最新版本时 INSTALL
    推荐文章