Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

不支持Qt d_ptr类型的头文件编译 #750

Closed
KellyGodLv opened this issue Apr 5, 2020 · 25 comments
Closed

不支持Qt d_ptr类型的头文件编译 #750

KellyGodLv opened this issue Apr 5, 2020 · 25 comments
Milestone

Comments

@KellyGodLv
Copy link

如果头文件出现类似
QtTreePropertyBrowserPrivate *d_ptr;
Q_DECLARE_PRIVATE(QtTreePropertyBrowser)
Q_DISABLE_COPY(QtTreePropertyBrowser)

Q_PRIVATE_SLOT(d_func(), void slotCollapsed(const QModelIndex &))

将无法编译通过,因为QtTreePropertyBrowserPrivate定义 在QtTreePropertyBrowser.cpp内

@waruqi
Copy link
Member

waruqi commented Apr 5, 2020

给个复现的demo我看下

@KellyGodLv
Copy link
Author

QT creator编译通过后提取的

target("test")
    add_rules("qt.application")
    set_kind("binary")

    add_frameworks("QtCore","QtGui","QtWidgets")
    add_includedirs("."
                    ,"$(buildir)")
    add_files("mainwindow.h")
    add_files("mainwindow.cpp")
    add_files("main.cpp")

target_end()

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#if QT_VERSION >= 0x040400
QT_BEGIN_NAMESPACE
#endif

class MainWindowPrivate;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    MainWindowPrivate *d_ptr;
    Q_DECLARE_PRIVATE(MainWindow)
    Q_DISABLE_COPY(MainWindow)

    Q_PRIVATE_SLOT(d_func(), void mainWindow_slot())
};
#if QT_VERSION >= 0x040400
QT_END_NAMESPACE
#endif
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include <qDebug>

class MainWindowPrivate
{
    MainWindow *q_ptr;
    Q_DECLARE_PUBLIC(MainWindow)
public:
    MainWindowPrivate(){}
    void mainWindow_slot(){qDebug()<<"mainWindow_slot";}
};

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    d_ptr = new MainWindowPrivate;
    d_ptr->q_ptr = this;
}

MainWindow::~MainWindow()
{

}

#include "moc_mainwindow.cpp"

@KellyGodLv
Copy link
Author

[ 33%]: compiling.debug mainwindow.cpp
[ 66%]: compiling.qt.moc mainwindow.h
error: mainwindow.cpp
mainwindow.cpp(25): fatal error C1083: 无法打开包括文件: “moc_mainwindow.cpp”:
No such file or directory

@waruqi
Copy link
Member

waruqi commented Apr 5, 2020

你发个完整的demo给我吧,我试下,最好qtcreater/xmake.lua的工程文件都带上。。

另外,建议用qt.widget_app/qt.quickapp rule,不要用qt.application rule,这个废弃了,

@waruqi
Copy link
Member

waruqi commented Apr 5, 2020

[ 33%]: compiling.debug mainwindow.cpp
[ 66%]: compiling.qt.moc mainwindow.h
error: mainwindow.cpp
mainwindow.cpp(25): fatal error C1083: 无法打开包括文件: “moc_mainwindow.cpp”:
No such file or directory

追加-vD编译,给我看下完整错误信息

@KellyGodLv
Copy link
Author

qt.widget_app我的xmake版本不能用

PS C:\Users\76441\Desktop\untitled> xmake -vD
checking for the Microsoft Visual Studio (x64) version ... 2017
checking for the Qt SDK directory ... E:\Qt\Qt5.12.7\5.12.7\msvc2017_64
checking for the Qt SDK version ... 5.12.7
configure
{
qt_sdkver = 5.12.7
arch = x64
ld = link.exe
plat = windows
cxx = cl.exe
mode = debug
host = windows
ndk_stdcxx = true
ccache = true
kind = static
buildir = build
vs = 2017
qt = E:\Qt\Qt5.12.7\5.12.7\msvc2017_64
}
checking for the cl.exe ... ok
checking for the flags (-std:c++11) ... no

cl.exe "-std:c++11"
checking for the flags (-fPIC) ... no
cl.exe "-fPIC"
checking for the ccache ... no
[ 33%]: compiling.debug mainwindow.cpp
cl.exe -c -I. -Ibuild -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtCore -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtGui -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtWidgets -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtQuick -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtQml -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\mkspecs\win32-msvc -DQT_QML_DEBUG -DQT_DEPRECATED_WARNINGS -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_QML_LIB -D_WINDOWS -nologo -Fobuild.objs\test\windows\x64\debug.\mainwindow.cpp.obj mainwindow.cpp
[ 66%]: compiling.qt.moc mainwindow.h
E:\Qt\Qt5.12.7\5.12.7\msvc2017_64\bin\moc.exe -DQT_QML_DEBUG -DQT_DEPRECATED_WARNINGS -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_QML_LIB
-D_WINDOWS -I. -Ibuild -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtCore -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtGui -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtWidgets -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtQuick -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtQml -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\mkspecs\win32-msvc mainwindow.h -o
build.gens\test\windows\x64\debug\rules\qt\moc\moc_mainwindow.cpp
cl.exe -c -I. -Ibuild -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtCore -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtGui -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtWidgets -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtQuick -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include\QtQml -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\include -IE:\Qt\Qt5.12.7\5.12.7\msvc2017_64\mkspecs\win32-msvc -DQT_QML_DEBUG -DQT_DEPRECATED_WARNINGS -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_QML_LIB -D_WINDOWS -nologo -Fobuild.objs\test\windows\x64\debug\gens\rules\qt\moc\moc_mainwindow.cpp.obj build.gens\test\windows\x64\debug\rules\qt\moc\moc_mainwindow.cpp
error: @programdir\modules\private\async\runjobs.lua:213: @programdir\modules\private\action\build\object.lua:77: @programdir\modules\core\tools\cl.lua:377: mainwindow.cpp
mainwindow.cpp(25): fatal error C1083: 无法打开包括文件: “moc_mainwindow.cpp”:
No such file or directory

stack traceback:
[C]: in function 'error'
[@programdir\core\base\os.lua:787]: in function 'raise'
[@programdir\modules\core\tools\cl.lua:377]: in function 'catch'
[@programdir\core\sandbox\modules\try.lua:127]: in function 'try'
[@programdir\modules\core\tools\cl.lua:341]:
[C]: in function 'compile'
[@programdir\modules\private\action\build\object.lua:77]: in function 'script'
[@programdir\modules\private\action\build\object.lua:90]: in function '_build_object'
[@programdir\modules\private\action\build\object.lua:115]: in function 'jobfunc'
[@programdir\modules\private\async\runjobs.lua:190]:
[C]: in function 'trycall'
[@programdir\core\sandbox\modules\try.lua:121]: in function 'try'
[@programdir\modules\private\async\runjobs.lua:187]: in function 'cotask'
[@programdir\core\base\scheduler.lua:317]:

stack traceback:
[C]: in function 'error'
@programdir\core\base\os.lua:787: in function 'raise'
@programdir\modules\private\async\runjobs.lua:213: in function 'catch'
@programdir\core\sandbox\modules\try.lua:127: in function 'try'
@programdir\modules\private\async\runjobs.lua:187: in function 'cotask' @programdir\core\base\scheduler.lua:317: in function <@programdir\core\base\scheduler.lua:315>

@KellyGodLv
Copy link
Author

KellyGodLv commented Apr 5, 2020 via email

@waruqi
Copy link
Member

waruqi commented Apr 5, 2020

demo在附件  qt.widget_app我的xmake版本没法使用

github上没看到附件,为什么不能用?你用的是老版本xmake?

@KellyGodLv
Copy link
Author

附件已发到gmail中
xmake版本
xmake v2.3.2+202004020133, A cross-platform build utility based on Lua
Copyright (C) 2015-2020 Ruki Wang, tboox.org, xmake.io
_
__ ___ __ __ __ | | ______
\ / / | / |/ _ | |/ / __
> < | _
/ | /| | < /
/
/__|
| |
|_
||____|
by ruki, tboox.org

👉  Manual: https://xmake.io/#/getting_started
🙏  Donate: https://xmake.io/#/sponsor

@waruqi
Copy link
Member

waruqi commented Apr 6, 2020

收到 我回头看下,新版本为什么qt.widget_app不能用?报什么错?

@waruqi
Copy link
Member

waruqi commented Apr 6, 2020

demo在附件 qt.widget_app我的xmake版本没法使用

这我我之前说错了,应该是 qt.widgetapp 。。你再试试,肯定可以用的。。

至于你那个demo我看了,确实目前还不支持,这块比较蛋疼,qt对这这块处理有点那个,得分两种情况

  1. mainwindows.cpp 里面如果没include moc_mainwindow.cpp,那么这两cpp会单独编译成.o来link (xmake目前只处理这种情况)
  2. mainwindows.cpp 里面如果include了moc_mainwindow.cpp,那么moc_mainwindow.cpp自动生成后,不会再单独参与编译,而是仅编译mainwindows.cpp(这块逻辑xmake还不支持,我需要想想怎么处理下才行)

@waruqi waruqi added this to the v2.3.3 milestone Apr 6, 2020
@KellyGodLv
Copy link
Author

是否可以通过头文件中的类内部的 Q_PRIVATE_SLOT来判断是否需要编译moc_xxx.cpp文件,QT中不需要编译moc_xxx.cpp是因为头文件出现了Q_PRIVATE_SLOT

@waruqi
Copy link
Member

waruqi commented Apr 6, 2020

嗯 可以尝试下

@waruqi
Copy link
Member

waruqi commented Apr 7, 2020

我dev上处理过了,应该支持了,你更新下试试 xmake update dev

另外你的配置有点冗余了,只需要这样就行了:

target("test")
    add_rules("qt.widgetapp")
    add_files("mainwindow.h")
    add_files("*.cpp")
    add_frameworks("QtCore", "QtGui")

@waruqi
Copy link
Member

waruqi commented Apr 9, 2020

可以了么

@KellyGodLv
Copy link
Author

可以了

@KellyGodLv
Copy link
Author

但是 好像.cpp中如果有Q_OBJECT 宏 生成的文件似乎是xxx.moc ,一样要做Q_PRIVATE_SLOT处理!之前忘记说了,

@KellyGodLv
Copy link
Author

class MainWindowPrivate:public QObject
{
    Q_OBJECT
public:
    MainWindow *q_ptr;
    Q_DECLARE_PUBLIC(MainWindow)
public:
    MainWindowPrivate(){}
    void mainWindow_slot(){qDebug()<<"mainWindow_slot";}
private:
     Q_PRIVATE_SLOT(q_ptr, void test())
};

@waruqi
Copy link
Member

waruqi commented Apr 10, 2020

目前仅支持从.h生成moc,.cpp都会作为正常cpp代码来编译

@KellyGodLv
Copy link
Author

有没有支持的计划,现在在做qt一些QtPropertyBrower开源库的xmake构建,跟QT源码大量的使用Q D指针模式,cpp不支持moc,这些工程都编译不了,只能自己修改cpp提取类

@waruqi
Copy link
Member

waruqi commented Apr 11, 2020

你给个 带qtcreator工程的demo 我先看下

@waruqi
Copy link
Member

waruqi commented Apr 12, 2020

我支持上了,不过需要对带有private slot的cpp文件,自己额外附带qt.moc规则。

target("test")
    add_rules("qt.widgetapp")
    add_files("main.cpp")
    add_files("mainwindow.cpp", {rules = "qt.moc"}) <---- 此处
    add_files("*.h")
    add_files("*.ui")

因为cpp有自己内置的构建规则,不能全局改这块,只能通过用户手动指定作为moc规则来处理,而.h因为专属只对qt rule生效,所以内部自动加了qt.moc,不指定也没关系

你更新下dev试试

@KellyGodLv
Copy link
Author

好的

@waruqi
Copy link
Member

waruqi commented Apr 13, 2020

这个可以了么

@KellyGodLv
Copy link
Author

可以了 感谢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants