提问人:Adri C.S. 提问时间:5/9/2023 最后编辑:Adri C.S. 更新时间:5/12/2023 访问量:167
CMake 不会为共享库中的Q_NAMESPACE运行 moc
CMake does not run moc for a Q_NAMESPACE in a shared library
问:
问题
我正在尝试从共享库中注册命名空间,但编译失败并显示未解决的外部符号错误: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相关的文件是:moc_enum.cpp
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 };
为什么找不到需要 moc 的文件?CMake
PS:如果不是使用我使用,它可以编译良好,并且该文件存在于构建目录中。CMake
qmake
moc_enum.cpp
PS2:关于这个问题或类似的问题有几个问题,但不幸的是,要么他们没有答案,要么不起作用(例如:这个、这个或这个 )
设置
- Qt 5.12.10 和 Qt Creator 10.0.0
- CMake 3.23(集成在Qt Creator中)
- Visual Studio 2017 64 位编译器。
法典
主 CMakeLists.txt
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)
main.cpp
#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();
}
枚举库
CMakeLists.txt
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)
枚举.h
#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
枚举Lib.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
Pro 文件
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
完整的 CMake 构建日志
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.
详细 CMake 日志
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 生成的导出文件也不起作用。编译失败,出现相同的错误。
使用自动生成的导出文件的枚举/CMakeLists.txt
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)
答:
2赞
Adri C.S.
5/12/2023
#1
是一个变量,用于告诉在以下文件上运行AUTOMOC_MACRO_NAMES
CMake
moc
包含某些关键字作为新行上的第一个非空格字符串,或者 作为新行 A 之后的第一个非空格字符串。
默认值为 Q_OBJECT;Q_GADGET;Q_NAMESPACE;Q_NAMESPACE_EXPORT{
因为在前面有 ,所以没有被注意到 作为 moc 的关键字之一。
解决方案是放在自己的生产线上:Q_NAMESPACE
ENUMLIB_EXPORT
CMake
Q_NAMESPACE
namespace EnumNamespace {
ENUMLIB_EXPORT
Q_NAMESPACE
// Rest of the code
}
评论
0赞
starball
5/14/2023
相关问题工单: gitlab.kitware.com/cmake/cmake/-/issues/24905
评论
cmake --build ... --verbose
ENUMLIB_BUILD
moc
moc
mocs_compilation.cpp
C:\SRC\MyTests\StaticMetaObject\build_release\enum\enumLib_autogen\mocs_compilation.cpp