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

Xmake is not dealing with Q_OBJECT moc properly #5236

Closed
HeavySnowJakarta opened this issue Jun 20, 2024 · 2 comments
Closed

Xmake is not dealing with Q_OBJECT moc properly #5236

HeavySnowJakarta opened this issue Jun 20, 2024 · 2 comments
Labels

Comments

@HeavySnowJakarta
Copy link

Xmake Version

v2.9.2+HEAD.6b6557c54

Operating System Version and Architecture

x86_64-windows11-msvc2022-ucrt

Describe Bug

error: startup.cpp.obj : error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const * __cdecl Startup::metaObject(void)const " (?metaObject@Startup@@UEBAPEBUQMetaObject@@XZ)
startup.cpp.obj : error LNK2001: 无法解析的外部符号 "public: virtual void * __cdecl Startup::qt_metacast(char const *)" (?qt_metacast@Startup@@UEAAPEAXPEBD@Z)
startup.cpp.obj : error LNK2001: 无法解析的外部符号 "public: virtual int __cdecl Startup::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Startup@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)
startup.cpp.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: static class QString __cdecl QFileDialog::getOpenFileName(class QWidget *,class QString const &,class QString const &,class QString const &,class QString *,class QFlags<enum QFileDialog::Option>)" (__imp_?getOpenFileName@QFileDialog@@SA?AVQString@@PEAVQWidget@@AEBV2@11PEAV2@V?$QFlags@W4Option@QFileDialog@@@@@Z),函数 "public: void __cdecl Startup::open(void)" (?open@Startup@@QEAAXXZ) 中引用了该符号
startup.cpp.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: static class QString __cdecl QFileDialog::getSaveFileName(class QWidget *,class QString const &,class QString const &,class QString const &,class QString *,class QFlags<enum QFileDialog::Option>)" (__imp_?getSaveFileName@QFileDialog@@SA?AVQString@@PEAVQWidget@@AEBV2@11PEAV2@V?$QFlags@W4Option@QFileDialog@@@@@Z),函数 "public: void __cdecl Startup::create(void)" (?create@Startup@@QEAAXXZ) 中引用了该符号
startup.cpp.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: static enum QMessageBox::StandardButton __cdecl QMessageBox::critical(class QWidget *,class QString const &,class QString const &,class QFlags<enum QMessageBox::StandardButton>,enum QMessageBox::StandardButton)" (__imp_?critical@QMessageBox@@SA?AW4StandardButton@1@PEAVQWidget@@AEBVQString@@1V?$QFlags@W4StandardButton@QMessageBox@@@@W421@@Z),函数 "private: void __cdecl Startup::openNewWindow(class QString)" (?openNewWindow@Startup@@AEAAXVQString@@@Z) 中引用了该符号
build\windows\x64\debug\CollegeHRM.exe : fatal error LNK1120: 6 个无法解析的外部命令

Due to the net it's because Qt generates moc_*.cpp files for ones that contain Q_OBJECT. So either the moc_*.cpp is not generated properly or it's not included.

Expected Behavior

Do as TBOOX's website's example like below does not work.

target("qt_widgetapp")
    add_rules("qt.application")
    add_files("src/*.cpp") 
    add_files("src/mainwindow.ui")
    add_files("src/mainwindow.h")  -- add files with Q_OBJECT meta (only for qt.moc)
    add_frameworks("QtWidgets")

Maybe I should list the files that contain Q_OBJECT one by one?

    add_packages("cjson")
    add_headerfiles("src/lib/backend/*.h")
    add_headerfiles("src/lib/frontend/startup.h")
    add_headerfiles("src/lib/frontend/*.h")
    add_files("src/lib/backend/*.cpp")
    add_files("src/lib/frontend/*.cpp")

Not working.

What if I add_rule("qt.moc") specifically?

    add_rules("qt.application")
    add_rules("qt.moc")
    add_files("src/*.cpp")
    add_files("src/qml.qrc")

    add_packages("cjson")
    add_headerfiles("src/lib/backend/*.h")
    add_headerfiles("src/lib/frontend/*.h")
    add_files("src/lib/backend/*.cpp")
    add_files("src/lib/frontend/*.cpp")

Still not working.

Project Configuration

Here is a part of the xmake.lua:

set_languages("cxx17")

-- Library dependencies.
add_requires("cjson")

-- Target building.
target("MyQtQuickProject")
    add_rules("qt.application")
    add_files("src/*.cpp")
    add_files("src/qml.qrc")

    add_packages("cjson")
    add_headerfiles("src/lib/backend/*.h")
    add_headerfiles("src/lib/frontend/*.h", {rule = "qt.moc"}) -- Where the macro `Q_OBJECT` is used.
    add_files("src/lib/backend/*.cpp")
    add_files("src/lib/frontend/*.cpp")

    -- Temp debug settings.
    add_defines("QT_DEBUG")
    set_symbols("debug")       -- Add debug symbols
    set_optimize("none") 
    add_ldflags("/SUBSYSTEM:CONSOLE") 

    -- Automatically generate `qml.qrc`.
    --[[
    before_build(function (target) 
        if os.host() == 'windows' then
            os.exec('cmd /C scripts\\generate_qrc.bat')
        else
            os.exec('./scripts/generate_qrc.sh')
        end
    end)
    ]]

    -- Without this command xmake won't find `QFileDialog.h`.
    add_includedirs("C:\\Qt\\6.7.1\\msvc2019_64\\include\\QtWidgets")

ChatGPT suggests me to add {rule = 'qt.moc'} which does not work.

Additional Information and Error Logs

checking for cl.exe ... C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.38.33130\bin\HostX64\x64\cl.exe
checking for Microsoft Visual Studio (x64) version ... 2022
checkinfo: cannot runv(zig.exe version), No such file or directory
checking for zig ... no
checkinfo: cannot runv(zig.exe version), No such file or directory
checking for zig ... no
checkinfo: cannot runv(nim.exe --version), No such file or directory
checking for nim ... no
checkinfo: cannot runv(nim.exe --version), No such file or directory
checking for nim ... no
checking for unzip ... ok
checking for git ... ok
checking for gzip ... ok
checking for tar ... ok
git rev-parse HEAD
checking for cmake ... no
checking for cmake ... no
checking for cmake ... no
checking for cmake ... ok
finding cjson from xmake ..
checking for xmake::cjson ... cjson 1.7.15
checking for link.exe ... C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.38.33130\bin\HostX64\x64\link.exe
checking for the linker (ld) ... link.exe
checking for Qt SDK directory ... C:/Qt/6.7.1/msvc2019_64
checking for Qt SDK version ... 6.7.1
checking for cl.exe ... C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.38.33130\bin\HostX64\x64\cl.exe
checking for the c++ compiler (cxx) ... cl.exe
checking for C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.38.33130\bin\HostX64\x64\cl.exe ... ok
checking for flags (-FS -Fd) ... ok
> cl.exe "-FS" "-FdC:\Users\bians\AppData\Local\Temp\.xmake\240620\_B4C261DB5A4A47208FF9563A84AA8640.pdb" "-nologo"
checking for flags (-Od) ... ok
> cl.exe "-Od" "-nologo"
checking for flags (cl_external_includedir) ... ok
> cl.exe "-external:W0" "-external:IC:\Qt\6.7.1\msvc2019_64\include\QtGui" "-nologo"
checking for the c++ compiler (cxx) ... cl.exe
checking for the c++ compiler (cxx) ... cl.exe
checking for the c++ compiler (cxx) ... cl.exe
checking for the c++ compiler (cxx) ... cl.exe
checking for the c++ compiler (cxx) ... cl.exe
checking for flags (/Zc:__cplusplus) ... ok
> cl.exe "/Zc:__cplusplus" "-nologo"
checking for flags (/permissive-) ... ok
> cl.exe "/permissive-" "-nologo"
checking for C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.38.33130\bin\HostX64\x64\link.exe ... ok
checking for flags (/SUBSYSTEM:CONSOLE) ... ok
> link.exe "/SUBSYSTEM:CONSOLE" "-nologo" "-dynamicbase" "-nxcompat" "-machine:x64"
[ 88%]: linking.debug CollegeHRM.exe
"C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Tools\\MSVC\\14.38.33130\\bin\\HostX64\\x64\\link.exe" -nologo -dynamicbase -nxcompat -machine:x64 -libpath:C:\Qt\6.7.1\msvc2019_64\lib -libpath:C:\Users\bians\AppData\Local\.xmake\packages\c\cjson\1.7.15\5d29b7ead93148bbac47aa2d02ef454d\lib -debug -pdb:build\windows\x64\debug\CollegeHRM.pdb cjson.lib Qt6Guid.lib Qt6Quickd.lib Qt6Qmld.lib Qt6Cored.lib Qt6Networkd.lib ws2_32.lib gdi32.lib ole32.lib advapi32.lib shell32.lib user32.lib opengl32.lib imm32.lib winmm.lib iphlpapi.lib /SUBSYSTEM:CONSOLE -out:build\windows\x64\debug\CollegeHRM.exe build\.objs\CollegeHRM\windows\x64\debug\src\main.cpp.obj build\.objs\CollegeHRM\windows\x64\debug\src\lib\backend\employee.cpp.obj build\.objs\CollegeHRM\windows\x64\debug\src\lib\backend\employees.cpp.obj build\.objs\CollegeHRM\windows\x64\debug\src\lib\frontend\lifeperiod.cpp.obj build\.objs\CollegeHRM\windows\x64\debug\src\lib\frontend\startup.cpp.obj build\.objs\CollegeHRM\windows\x64\debug\gens\rules\qt\qrc\qml_43BBE12C.cpp.obj
create ok!
compile_commands.json updated!
error: @programdir\core\main.lua:329: @programdir\actions\build\main.lua:148: @programdir\modules\async\runjobs.lua:322: @programdir\actions\build\kinds\binary.lua:53: @programdir\modules\core\tools\link.lua:175: startup.cpp.obj : error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const * __cdecl Startup::metaObject(void)const " (?metaObject@Startup@@UEBAPEBUQMetaObject@@XZ)
startup.cpp.obj : error LNK2001: 无法解析的外部符号 "public: virtual void * __cdecl Startup::qt_metacast(char const *)" (?qt_metacast@Startup@@UEAAPEAXPEBD@Z)
startup.cpp.obj : error LNK2001: 无法解析的外部符号 "public: virtual int __cdecl Startup::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Startup@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)
startup.cpp.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: static class QString __cdecl QFileDialog::getOpenFileName(class QWidget *,class QString const &,class QString const &,class QString const &,class QString *,class QFlags<enum QFileDialog::Option>)" (__imp_?getOpenFileName@QFileDialog@@SA?AVQString@@PEAVQWidget@@AEBV2@11PEAV2@V?$QFlags@W4Option@QFileDialog@@@@@Z),函数 "public: void __cdecl Startup::open(void)" (?open@Startup@@QEAAXXZ) 中引用了该符号
startup.cpp.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: static class QString __cdecl QFileDialog::getSaveFileName(class QWidget *,class QString const &,class QString const &,class QString const &,class QString *,class QFlags<enum QFileDialog::Option>)" (__imp_?getSaveFileName@QFileDialog@@SA?AVQString@@PEAVQWidget@@AEBV2@11PEAV2@V?$QFlags@W4Option@QFileDialog@@@@@Z),函数 "public: void __cdecl Startup::create(void)" (?create@Startup@@QEAAXXZ) 中引用了该符号
startup.cpp.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: static enum QMessageBox::StandardButton __cdecl QMessageBox::critical(class QWidget *,class QString const &,class QString const &,class QFlags<enum QMessageBox::StandardButton>,enum QMessageBox::StandardButton)" (__imp_?critical@QMessageBox@@SA?AW4StandardButton@1@PEAVQWidget@@AEBVQString@@1V?$QFlags@W4StandardButton@QMessageBox@@@@W421@@Z),函数 "private: void __cdecl Startup::openNewWindow(class QString)" (?openNewWindow@Startup@@AEAAXVQString@@@Z) 中引用了该符号
build\windows\x64\debug\CollegeHRM.exe : fatal error LNK1120: 6 个无法解析的外部命令

stack traceback:
    [C]: in function 'error'
    [@programdir\core\base\os.lua:973]:
    [@programdir\modules\core\tools\link.lua:175]: in function 'catch'
    [@programdir\core\sandbox\modules\try.lua:123]: in function 'try'
    [@programdir\modules\core\tools\link.lua:150]:
    [C]: in function 'xpcall'
    [@programdir\core\base\utils.lua:275]:
    [@programdir\core\tool\linker.lua:221]: in function 'link'
    [@programdir\actions\build\kinds\binary.lua:53]: in function 'callback'
    [@programdir\modules\core\project\depend.lua:217]: in function 'on_changed'
    [@programdir\actions\build\kinds\binary.lua:41]: in function '_do_link_target'
    [@programdir\actions\build\kinds\binary.lua:83]:
    [@programdir\actions\build\kinds\binary.lua:110]: in function '_link_target'
    [@programdir\actions\build\kinds\binary.lua:138]: in function 'jobfunc'
    [@programdir\modules\async\runjobs.lua:238]:
    [C]: in function 'xpcall'
    [@programdir\core\base\utils.lua:275]: in function 'trycall'
    [@programdir\core\sandbox\modules\try.lua:117]: in function 'try'
    [@programdir\modules\async\runjobs.lua:220]: in function 'cotask'
    [@programdir\core\base\scheduler.lua:406]:

stack traceback:
        [C]: in function 'error'
        @programdir\core\base\os.lua:973: in function 'os.raiselevel'
        (...tail calls...)
        @programdir\core\main.lua:329: in upvalue 'cotask'
        @programdir\core\base\scheduler.lua:406: in function <@programdir\core\base\scheduler.lua:399>
@star-hengxing
Copy link
Contributor

Please see the doc again.

add_files("src/mainwindow.h")  -- add files with Q_OBJECT meta (only for qt.moc)

https://xmake.io/#/manual/project_target?id=targetadd_headerfiles

@waruqi
Copy link
Member

waruqi commented Jun 20, 2024

use add_files, not add_headerfiles

@waruqi waruqi closed this as completed Jun 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants