CMAKE QT6:未解决的外部符号“ public:虚拟struct qmetaObject”

发布于 2025-02-11 19:32:31 字数 1546 浏览 2 评论 0原文

我正在使用CMAKE构建QT6项目。我想生成一个带有Qwidget的库,并且代码是:

    #ifndef GLOBAL_EXPORTS
        #define GLOBAL_EXPORT __declspec(dllexport)
    #else
        #define GLOBAL_EXPORT __declspec(dllimport)
    #endif // !GLOBAL_EXPORTS

class GLOBAL_EXPORT SWidgets : public QWidget
{
    Q_OBJECT
public:
    SWidgets();
};

在编译时,VS报告:

 unresolved external symbol "public: virtual struct QMetaObject const SWidgets::staticMetaObject"

该错误可以通过复制MOC文件来解决。但是,这是不方便的,因为我有许多QT相对库。

此外,我还添加了set(cmake_automoc 1),并且不起作用。

我已经在github中上传了代码( https://github.com/zhang-qiang-github/ cmake_qt )。

如何通过CMAKE解决此错误?任何建议都对~~~


更新表示赞赏:对不起,将代码上传到GitHub。

  1. 首先,我在global.h文件中定义我的global_exports
#ifndef GLOBAL_EXPORTS_H
#define GLOBAL_EXPORTS_H


#if (WIN32)
    #ifndef GLOBAL_EXPORTS
        #define GLOBAL_EXPORT __declspec(dllexport)
    #else
        #define GLOBAL_EXPORT __declspec(dllimport)
    #endif // !GLOBAL_EXPORTS

#else
    #define GLOBAL_EXPORT 
#endif


#endif

  1. 然后,我将自定义窗口定义为:
#ifndef swidget_header_h
#define swidget_header_h

#include "Global.h"

#include <qwidget.h>
#include "qpushbutton.h"

class GLOBAL_EXPORT SWidgets : public QWidget
{
    Q_OBJECT
public:
    SWidgets();
};

#endif // !swidget_header_h

I am building qt6 project with cmake. I want to generate a library with QWidget, and the code is:

    #ifndef GLOBAL_EXPORTS
        #define GLOBAL_EXPORT __declspec(dllexport)
    #else
        #define GLOBAL_EXPORT __declspec(dllimport)
    #endif // !GLOBAL_EXPORTS

class GLOBAL_EXPORT SWidgets : public QWidget
{
    Q_OBJECT
public:
    SWidgets();
};

In compiling, the vs reports:

 unresolved external symbol "public: virtual struct QMetaObject const SWidgets::staticMetaObject"

The bug can be solved by copy moc file. But, it is inconvenient because I have many qt relative library.

In addition, I have add set(CMAKE_AUTOMOC 1), and it do not work.

I have upload the code in github (https://github.com/zhang-qiang-github/cmake_qt).

How to solve this bug by cmake? Any suggestion is appreciated~~~


Update: sorry for uploading code to github.

  1. First, I define my GLOBAL_EXPORTS in a Global.h file:
#ifndef GLOBAL_EXPORTS_H
#define GLOBAL_EXPORTS_H


#if (WIN32)
    #ifndef GLOBAL_EXPORTS
        #define GLOBAL_EXPORT __declspec(dllexport)
    #else
        #define GLOBAL_EXPORT __declspec(dllimport)
    #endif // !GLOBAL_EXPORTS

#else
    #define GLOBAL_EXPORT 
#endif


#endif

  1. Then I define my custom widget as:
#ifndef swidget_header_h
#define swidget_header_h

#include "Global.h"

#include <qwidget.h>
#include "qpushbutton.h"

class GLOBAL_EXPORT SWidgets : public QWidget
{
    Q_OBJECT
public:
    SWidgets();
};

#endif // !swidget_header_h

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独﹏钓一江月 2025-02-18 19:32:31

正如@tsyvarev所指出的那样,您对global_exports定义的处理是错误的。

如果设置了global_exports定义,则应导出符号,因此应该读取(注意:我更改#ifndef #ifdef):

#ifdef GLOBAL_EXPORTS
    #define GLOBAL_EXPORT __declspec(dllexport)
#else
    #define GLOBAL_EXPORT __declspec(dllimport)
#endif // !GLOBAL_EXPORTS

然后在export_dll项目的cmakelists.txt中,您应该添加一行定义global_exports

set(CMAKE_AUTOMOC 1)
add_library(export_dll SHARED ${SOURCES} ${HEADERS})
set_target_properties(export_dll PROPERTIES COMPILE_DEFINITIONS GLOBAL_EXPORTS)
find_package(Qt6 REQUIRED COMPONENTS Widgets Core Gui)
target_link_libraries(export_dll PRIVATE Qt6::Widgets Qt6::Core Qt6::Gui)

通过执行此__ expspec(dllexport)(dllexport)将添加到创建DLL和DLL的每个消费者时的符号将自动获得具有正确的__ extspec(dllimport)设置的符号。

As @Tsyvarev has pointed out, your handling of the GLOBAL_EXPORTS definition is wrong.

You should export the symbols if the GLOBAL_EXPORTS definition is set, therefore it should read (note: I changed #ifndef to #ifdef):

#ifdef GLOBAL_EXPORTS
    #define GLOBAL_EXPORT __declspec(dllexport)
#else
    #define GLOBAL_EXPORT __declspec(dllimport)
#endif // !GLOBAL_EXPORTS

Then in your CMakeLists.txt of the export_dll project you should add a line defining GLOBAL_EXPORTS:

set(CMAKE_AUTOMOC 1)
add_library(export_dll SHARED ${SOURCES} ${HEADERS})
set_target_properties(export_dll PROPERTIES COMPILE_DEFINITIONS GLOBAL_EXPORTS)
find_package(Qt6 REQUIRED COMPONENTS Widgets Core Gui)
target_link_libraries(export_dll PRIVATE Qt6::Widgets Qt6::Core Qt6::Gui)

By doing this __declspec(dllexport) will be added to the symbols when creating the DLL and every consumer of the DLL will automatically get the symbols with a proper __declspec(dllimport) set.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文