CMake构建错误-虚拟方法错误缺少vtable

时间:2019-01-30 01:26:14

标签: c++ cmake

我们的Xcode C ++项目正在转换为CMake脚本。如果我在虚拟main中使用带有虚函数的类,则在构建CMake脚本时,始终会丢失vtable错误。如果我只在主目录中使用不带虚函数的类,那么一切都会很好。

该项目为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 个答案:

答案 0 :(得分:1)

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

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.

立即提醒我,您忘记了链接包含这些功能定义的编译单元。

假设Playerplayer.hppplayer.cpp中定义并且它们在子目录src中,那么我的建议是更新add_executable调用到:

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

请注意,此处假定使用“当前源目录或二进制目录”,无需进行拼写。

还请注意,我已将头文件包含在目标文件中。这样做有很多优点:

  • 为Visual Studio,xcode等生成项目文件时,这些文件将出现在项目树中。
  • 使用最新的INSTALL命令时,可以为这些文件赋予属性以确保正确处理它们(例如,库目标的公共或私有头文件)