【问题标题】:Why is cmake not mocing my Q_OBJECT headers?为什么 cmake 不模仿我的 Q_OBJECT 标头?
【发布时间】:2018-09-19 19:56:13
【问题描述】:

我目前有一个这样的项目:

- project/
--- include/
--- src/
--- qml/
--- CMakeLists.txt
--- qml.qrc

还有一个像这样的CMakeLists.txt

cmake_minimum_required(VERSION 3.1)

cmake_policy(SET CMP0071 NEW)

include_directories(${Qt5Widgets_INCLUDE_DIRS} ${QtQml_INCLUDE_DIRS})
add_definitions(${Qt5Widgets_DEFINITIONS} ${QtQml_DEFINITIONS} ${${Qt5Quick_DEFINITIONS}})

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

project(wormhole_qt)

find_package(Qt5 COMPONENTS Core Quick Qml OpenGL REQUIRED)
find_package(Qt5QuickCompiler)

find_package(VTK REQUIRED)
include(${VTK_USE_FILE})

include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})

MACRO(HEADER_DIRECTORIES sub_dir return_list)
    FILE(GLOB_RECURSE new_list ${sub_dir}/*.h)
    SET(dir_list "")
    FOREACH(file_path ${new_list})
        GET_FILENAME_COMPONENT(dir_path ${file_path} PATH)
        SET(dir_list ${dir_list} ${dir_path})
    ENDFOREACH()
    LIST(REMOVE_DUPLICATES dir_list)
    SET(${return_list} ${dir_list})
ENDMACRO()

HEADER_DIRECTORIES(include mylist)
include_directories(include)
include_directories(lib)
include_directories(${mylist})

file(GLOB INCLUDES *.h)
file(GLOB_RECURSE CPP_FILES src/*.cpp)

qtquick_compiler_add_resources(QT_RESOURCES qml.qrc)
qt5_wrap_cpp(MOC_SOURCE ${INCLUDES})
add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${MOC_SOURCE} ${CPP_FILES} ${QT_RESOURCES})

target_link_libraries(${PROJECT_NAME} ${VTK_LIBRARIES})
qt5_use_modules(${PROJECT_NAME} Quick Core Qml OpenGL)

问题在于,在实际的构建步骤中,moc 没有找到我的任何标有 Q_OBJECT 的标头。我可以说,因为这是我的构建的样子:

14:18:45: Running steps for project wormhole_qt...
14:18:45: Starting: "/usr/local/bin/cmake" --build . --target all
[  1%] Generating qmlcache_loader.cpp
[  2%] Generating qml_Empty_qml.cpp
[  4%] Generating qml_Style_qml.cpp
[  5%] Generating qml_main_qml.cpp
[  7%] Generating qml_setup_NewProject_qml.cpp
[  8%] Generating qml_setup_Setup_qml.cpp
[  9%] Generating qml_setup_Startup_qml.cpp
[ 11%] Generating qml_workspace_AnimationWindow_qml.cpp
[ 12%] Generating qml_workspace_DepthChartControls_qml.cpp
[ 14%] Generating qml_workspace_NewAnimationWindow_qml.cpp
[ 15%] Generating qml_workspace_TraceWindow_qml.cpp
[ 16%] Generating qml_workspace_WorkspaceMenuBar_qml.cpp
[ 18%] Generating qml_workspace_Workspace_qml.cpp
[ 19%] Automatic MOC for target wormhole_qt
[ 19%] Built target wormhole_qt_autogen
[ 21%] Generating qrc_qml_qmlcache.cpp
Scanning dependencies of target wormhole_qt
[ 22%] Building CXX object CMakeFiles/wormhole_qt.dir/src/controllers/AnimationsController.cpp.o
[ 23%] Building CXX object CMakeFiles/wormhole_qt.dir/src/controllers/ApplicationController.cpp.o

如果您查看显示 19% 的位置,它表示它正在自动搜索,但它没有列出任何文件,这意味着它没有找到任何文件。此外,由于没有发生moccing,因此存在链接错误,因为信号不存在。我的CMakeLists.txt 中是否缺少某些内容,或者我是否需要更改我的项目结构?如何让 MOC 找到我的头文件?

【问题讨论】:

  • 重写此评论,因为编辑窗口已通过:使用message(...) 调用验证${INCLUDES} 的内容。此外,如果 AUTOMOC 正常运行,qt5_wrap_cpp 不应该存在。你能展示一个标题(带有Q_OBJECT)和cpp文件对的例子吗?

标签: qt cmake qt5 qtquick2 moc


【解决方案1】:

AUTOMOC 属性告诉 CMake 扫描头文件并在必要时生成 moc 命令。如果 CMake 不知道头文件,它不会扫描它。因此,您需要做的就是将标头与源一起传递给add_executable 函数。

之后删除qt5_wrap_cpp 函数。只要你用AUTOMOC就不需要。

并删除qt5_use_modules 函数。现代 CMake 可以通过简单的 target_link_libraries(${PROJECT_NAME} Qt5Quick Qt5Core Qt5Qml Qt5OpenGL) 为您完成所有这些工作

【讨论】:

  • "将标头与源一起传递给add_executable":当有一个.cpp 文件和对应的.h 文件时,只传递.cpp 就可以了,MOC 将知道。但是对于单独的 .h 带有枚举、结构或类似文件的文件,.h 必须在这里传递!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-30
  • 2012-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-01
相关资源
最近更新 更多