我正在尝试从共享库在
QML
中注册一个命名空间,但是编译失败并出现未解决的外部符号错误:
failed (exit code 1120) with the following output:
main.cpp.obj : error LNK2019: unresolved external symbol "struct QMetaObject const EnumNamespace::staticMetaObject" (?staticMetaObject@EnumNamespace@@3UQMetaObject@@B) referenced in function "class QDebug __cdecl operator<<<enum EnumNamespace::MyEnum>(class QDebug,enum EnumNamespace::MyEnum)" (??$?6W4MyEnum@EnumNamespace@@@@YA?AVQDebug@@V0@W4MyEnum@EnumNamespace@@@Z)
StaticMetaObject.exe : fatal error LNK1120: 1 unresolved externals
我已经在构建目录中搜索了 moc 文件(
moc_enum.cpp
或类似文件),但找不到。我能找到的唯一moc相关文件是mocs_compilation.cpp
:
// This file is autogenerated. Changes will be overwritten.
// No files found that require moc or the moc files are included
enum some_compilers { need_more_than_nothing };
为什么
CMake
没有找到它需要 moc 的文件?
PS:如果我使用
CMake
而不是使用 qmake
,它编译得很好并且 moc_enum.cpp
文件存在于构建目录中。
PS2:关于这个问题或类似问题有几个问题,但不幸的是,他们要么没有答案,要么没有用(例如:this、this 或 this)
cmake_minimum_required(VERSION 3.23 FATAL_ERROR)
project(StaticMetaObject VERSION 1.0.0 LANGUAGES CXX DESCRIPTION "Static Meta Object Test")
set(BUILD_SHARED_LIBS ON)
set(CMAKE_DEBUG_POSTFIX d)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
find_package(QT NAMES Qt5 REQUIRED COMPONENTS Core)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Qml)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
add_subdirectory(enum)
add_executable(${PROJECT_NAME})
target_sources(${PROJECT_NAME} PUBLIC main.cpp)
target_link_libraries(${PROJECT_NAME} enumLib Qt${QT_VERSION_MAJOR}::Qml)
#include "enum/enum.h"
#include <QCoreApplication>
#include <QDebug>
#include <QQmlEngine>
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
int main(int argc, char * *argv)
{
QCoreApplication app{argc, argv};
qInfo() << EnumNamespace::TWO;
// Comenting this line out doesn't solve the problem.
qmlRegisterUncreatableMetaObject(EnumNamespace::staticMetaObject, "ABCDE", 1, 0, "EnumNamespace", "Error: only enums");
return app.exec();
}
cmake_minimum_required(VERSION "${CMAKE_MINIMUM_REQUIRED_VERSION}" FATAL_ERROR)
set(LIB_NAME enumLib)
add_library(${LIB_NAME} SHARED)
set_target_properties(${LIB_NAME} PROPERTIES LINKER_LANGUAGE CXX)
target_sources(${LIB_NAME} PUBLIC enum.h enumLib.h)
target_compile_definitions(${LIB_NAME} PUBLIC ENUMLIB_BUILD)
target_link_libraries(${LIB_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::Core)
#ifndef ENUM_H
#define ENUM_H
#include "enumLib.h"
#include <QObject>
namespace EnumNamespace {
ENUMLIB_EXPORT Q_NAMESPACE
enum MyEnum : unsigned int
{
ZERO = 0,
ONE,
TWO
};
Q_ENUM_NS(MyEnum);
}
#endif // ENUM_H
#ifndef ENUMLIB_H
#define ENUMLIB_H
#if defined(ENUMLIB_BUILD)
#define ENUMLIB_EXPORT Q_DECL_EXPORT
#else
#define ENUMLIB_EXPORT Q_DECL_IMPORT
#endif
#endif // ENUMLIB_H
QT = core
CONFIG += c++17 cmdline
QT += core qml
DEFINES += ENUMLIB_BUILD
HEADERS += \
enum/enum.h \
enum/enum.h \
enum/enumLib.h
SOURCES += \
main.cpp
16:00:30: Running steps for project StaticMetaObject...
16:00:30: Starting: "C:\Qt\Tools\CMake_64\bin\cmake.exe" --build C:/SRC/MyTests/StaticMetaObject/build_release --target all
[1/7 21.4/sec] Automatic MOC and UIC for target enumLib
[2/5 22.1/sec] Automatic MOC and UIC for target StaticMetaObject
[3/5 9.0/sec] Building CXX object CMakeFiles\StaticMetaObject.dir\StaticMetaObject_autogen\mocs_compilation.cpp.obj
[4/5 4.3/sec] Building CXX object CMakeFiles\StaticMetaObject.dir\main.cpp.obj
[5/5 4.8/sec] Linking CXX executable StaticMetaObject.exe
FAILED: StaticMetaObject.exe
cmd.exe /C "cd . && C:\Qt\Tools\CMake_64\bin\cmake.exe -E vs_link_exe --intdir=CMakeFiles\StaticMetaObject.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\mt.exe --manifests -- C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo CMakeFiles\StaticMetaObject.dir\StaticMetaObject_autogen\mocs_compilation.cpp.obj CMakeFiles\StaticMetaObject.dir\main.cpp.obj /out:StaticMetaObject.exe /implib:StaticMetaObject.lib /pdb:StaticMetaObject.pdb /version:0.0 /machine:x64 /INCREMENTAL:NO /subsystem:console enum\enumLib.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Qml.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Network.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Core.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
LINK: command "C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo CMakeFiles\StaticMetaObject.dir\StaticMetaObject_autogen\mocs_compilation.cpp.obj CMakeFiles\StaticMetaObject.dir\main.cpp.obj /out:StaticMetaObject.exe /implib:StaticMetaObject.lib /pdb:StaticMetaObject.pdb /version:0.0 /machine:x64 /INCREMENTAL:NO /subsystem:console enum\enumLib.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Qml.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Network.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Core.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:StaticMetaObject.exe.manifest" failed (exit code 1120) with the following output:
main.cpp.obj : error LNK2019: unresolved external symbol "struct QMetaObject const EnumNamespace::staticMetaObject" (?staticMetaObject@EnumNamespace@@3UQMetaObject@@B) referenced in function "class QDebug __cdecl operator<<<enum EnumNamespace::MyEnum>(class QDebug,enum EnumNamespace::MyEnum)" (??$?6W4MyEnum@EnumNamespace@@@@YA?AVQDebug@@V0@W4MyEnum@EnumNamespace@@@Z)
StaticMetaObject.exe : fatal error LNK1120: 1 unresolved externals
ninja: build stopped: subcommand failed.
16:00:32: The process "C:\Qt\Tools\CMake_64\bin\cmake.exe" exited with code 1.
Error while building/deploying project StaticMetaObject (kit: Desktop Qt 5.12.10 MSVC2017 64bit)
When executing step "Build"
16:00:32: Elapsed time: 00:01.
19:08:34: Running steps for project StaticMetaObject...
19:08:34: Starting: "C:\Qt\Tools\CMake_64\bin\cmake.exe" --build C:/SRC/MyTests/StaticMetaObject/build_release --target all --verbose
[1/7 25.6/sec] cmd.exe /C "cd /D C:\SRC\MyTests\StaticMetaObject\build_release\enum && C:\Qt\Tools\CMake_64\bin\cmake.exe -E cmake_autogen C:/SRC/MyTests/StaticMetaObject/build_release/enum/CMakeFiles/enumLib_autogen.dir/AutogenInfo.json Release"
[2/7 8.7/sec] C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1429~1.301\bin\HostX64\x64\cl.exe /nologo /TP -DENUMLIB_BUILD -DQT_CORE_LIB -DQT_NO_DEBUG -DenumLib_EXPORTS -IC:\SRC\MyTests\StaticMetaObject\build_release\enum\enumLib_autogen\include -external:IC:\Qt\5.12.10\msvc2017_64\include -external:IC:\Qt\5.12.10\msvc2017_64\include\QtCore -external:IC:\Qt\5.12.10\msvc2017_64\.\mkspecs\win32-msvc -external:W0 /DWIN32 /D_WINDOWS /EHsc /O2 /Ob2 /DNDEBUG -MD -std:c++17 /showIncludes /Foenum\CMakeFiles\enumLib.dir\enumLib_autogen\mocs_compilation.cpp.obj /Fdenum\CMakeFiles\enumLib.dir\ /FS -c C:\SRC\MyTests\StaticMetaObject\build_release\enum\enumLib_autogen\mocs_compilation.cpp
[3/7 7.6/sec] cmd.exe /C "cmd.exe /C "C:\Qt\Tools\CMake_64\bin\cmake.exe -E __create_def C:\SRC\MyTests\StaticMetaObject\build_release\enum\CMakeFiles\enumLib.dir\.\exports.def C:\SRC\MyTests\StaticMetaObject\build_release\enum\CMakeFiles\enumLib.dir\.\exports.def.objs && cd C:\SRC\MyTests\StaticMetaObject\build_release" && C:\Qt\Tools\CMake_64\bin\cmake.exe -E vs_link_dll --intdir=enum\CMakeFiles\enumLib.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\mt.exe --manifests -- C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo enum\CMakeFiles\enumLib.dir\enumLib_autogen\mocs_compilation.cpp.obj /out:enum\enumLib.dll /implib:enum\enumLib.lib /pdb:enum\enumLib.pdb /dll /version:0.0 /machine:x64 /INCREMENTAL:NO /DEF:enum\CMakeFiles\enumLib.dir\.\exports.def C:\Qt\5.12.10\msvc2017_64\lib\Qt5Core.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
[4/7 9.2/sec] cmd.exe /C "cd /D C:\SRC\MyTests\StaticMetaObject\build_release && C:\Qt\Tools\CMake_64\bin\cmake.exe -E cmake_autogen C:/SRC/MyTests/StaticMetaObject/build_release/CMakeFiles/StaticMetaObject_autogen.dir/AutogenInfo.json Release"
[5/7 10.5/sec] C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1429~1.301\bin\HostX64\x64\cl.exe /nologo /TP -DENUMLIB_BUILD -DQT_CORE_LIB -DQT_NETWORK_LIB -DQT_NO_DEBUG -DQT_QML_LIB -IC:\SRC\MyTests\StaticMetaObject\build_release\StaticMetaObject_autogen\include -external:IC:\Qt\5.12.10\msvc2017_64\include -external:IC:\Qt\5.12.10\msvc2017_64\include\QtCore -external:IC:\Qt\5.12.10\msvc2017_64\.\mkspecs\win32-msvc -external:IC:\Qt\5.12.10\msvc2017_64\include\QtQml -external:IC:\Qt\5.12.10\msvc2017_64\include\QtNetwork -external:W0 /DWIN32 /D_WINDOWS /EHsc /O2 /Ob2 /DNDEBUG -MD -std:c++17 /showIncludes /FoCMakeFiles\StaticMetaObject.dir\StaticMetaObject_autogen\mocs_compilation.cpp.obj /FdCMakeFiles\StaticMetaObject.dir\ /FS -c C:\SRC\MyTests\StaticMetaObject\build_release\StaticMetaObject_autogen\mocs_compilation.cpp
[6/7 5.4/sec] C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1429~1.301\bin\HostX64\x64\cl.exe /nologo /TP -DENUMLIB_BUILD -DQT_CORE_LIB -DQT_NETWORK_LIB -DQT_NO_DEBUG -DQT_QML_LIB -IC:\SRC\MyTests\StaticMetaObject\build_release\StaticMetaObject_autogen\include -external:IC:\Qt\5.12.10\msvc2017_64\include -external:IC:\Qt\5.12.10\msvc2017_64\include\QtCore -external:IC:\Qt\5.12.10\msvc2017_64\.\mkspecs\win32-msvc -external:IC:\Qt\5.12.10\msvc2017_64\include\QtQml -external:IC:\Qt\5.12.10\msvc2017_64\include\QtNetwork -external:W0 /DWIN32 /D_WINDOWS /EHsc /O2 /Ob2 /DNDEBUG -MD -std:c++17 /showIncludes /FoCMakeFiles\StaticMetaObject.dir\main.cpp.obj /FdCMakeFiles\StaticMetaObject.dir\ /FS -c C:\SRC\MyTests\StaticMetaObject\src\main.cpp
[7/7 5.9/sec] cmd.exe /C "cd . && C:\Qt\Tools\CMake_64\bin\cmake.exe -E vs_link_exe --intdir=CMakeFiles\StaticMetaObject.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\mt.exe --manifests -- C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo CMakeFiles\StaticMetaObject.dir\StaticMetaObject_autogen\mocs_compilation.cpp.obj CMakeFiles\StaticMetaObject.dir\main.cpp.obj /out:StaticMetaObject.exe /implib:StaticMetaObject.lib /pdb:StaticMetaObject.pdb /version:0.0 /machine:x64 /INCREMENTAL:NO /subsystem:console enum\enumLib.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Qml.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Network.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Core.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
FAILED: StaticMetaObject.exe
cmd.exe /C "cd . && C:\Qt\Tools\CMake_64\bin\cmake.exe -E vs_link_exe --intdir=CMakeFiles\StaticMetaObject.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\mt.exe --manifests -- C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo CMakeFiles\StaticMetaObject.dir\StaticMetaObject_autogen\mocs_compilation.cpp.obj CMakeFiles\StaticMetaObject.dir\main.cpp.obj /out:StaticMetaObject.exe /implib:StaticMetaObject.lib /pdb:StaticMetaObject.pdb /version:0.0 /machine:x64 /INCREMENTAL:NO /subsystem:console enum\enumLib.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Qml.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Network.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Core.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
LINK: command "C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo CMakeFiles\StaticMetaObject.dir\StaticMetaObject_autogen\mocs_compilation.cpp.obj CMakeFiles\StaticMetaObject.dir\main.cpp.obj /out:StaticMetaObject.exe /implib:StaticMetaObject.lib /pdb:StaticMetaObject.pdb /version:0.0 /machine:x64 /INCREMENTAL:NO /subsystem:console enum\enumLib.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Qml.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Network.lib C:\Qt\5.12.10\msvc2017_64\lib\Qt5Core.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:StaticMetaObject.exe.manifest" failed (exit code 1120) with the following output:
main.cpp.obj : error LNK2019: unresolved external symbol "struct QMetaObject const EnumNamespace::staticMetaObject" (?staticMetaObject@EnumNamespace@@3UQMetaObject@@B) referenced in function "class QDebug __cdecl operator<<<enum EnumNamespace::MyEnum>(class QDebug,enum EnumNamespace::MyEnum)" (??$?6W4MyEnum@EnumNamespace@@@@YA?AVQDebug@@V0@W4MyEnum@EnumNamespace@@@Z)
StaticMetaObject.exe : fatal error LNK1120: 1 unresolved externals
ninja: build stopped: subcommand failed.
19:08:36: The process "C:\Qt\Tools\CMake_64\bin\cmake.exe" exited with code 1.
Error while building/deploying project StaticMetaObject (kit: Desktop Qt 5.12.10 MSVC2017 64bit)
When executing step "Build"
19:08:36: Elapsed time: 00:01.
使用 CMake 生成的导出文件也不起作用。编译失败并出现相同的错误。
cmake_minimum_required(VERSION "${CMAKE_MINIMUM_REQUIRED_VERSION}" FATAL_ERROR)
set(LIB_NAME enumLib)
add_library(${LIB_NAME} SHARED)
set_target_properties(${LIB_NAME} PROPERTIES LINKER_LANGUAGE CXX)
target_sources(${LIB_NAME} PUBLIC enum.h)
include(GenerateExportHeader)
generate_export_header(${LIB_NAME} EXPORT_MACRO_NAME ENUMLIB_EXPORT)
target_compile_definitions(${LIB_NAME} PUBLIC enumLib_EXPORTS)
target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(${LIB_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::Core)