Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to instruct cmake/automoc to find external header

Tags:

cmake

qt

qt5

moc

I have a Qt widget C++ class that loads a ui file created in Qt Creator. The header and the source file for the class live in two separate directories. I have trouble instructing cmake/automoc to find the header for the class. cmake recognizes it needs to moc the C++ file but it cannot find the analogous header.

Is there something I can do to help cmake find the files?

Everything works fine if both the cpp and the header file are in the same directory. This only comes up when the headers are elsewhere.

My directory structure is

project
    src
        include
            Foo
                Bar.h
    lib
        Foo
            Bar.cpp
            forms
                Bar.ui           

In src/include/Foo/Bar.h I have:

// Bar.h
#include <QtWidgets/QWidget>

namespace Ui { class Bar; }

class Bar : public QWidget {
    Q_OBJECT
    ...
}

In src/Foo/Bar.cpp file:

#include "Foo/Bar.h"
#include "moc_Bar.cpp"
#include "ui_Bar.h"

My CMakeLists.txt in src/lib/Foo is set up as follows:

# there is a project() call at the root that defines PROJECT_SOURCE_DIR
set(PUBLIC_HEADERS_DIR ${PROJECT_SOURCE_DIR}/src/include)

# Pick up public library headers
include_directories(${PUBLIC_HEADERS_DIR})

# Pick up private headers in library dir    
include_directories(${CMAKE_CURRENT_SOURCE_DIR})

# Set up Qt
set(CMAKE_AUTOMOC ON)                    
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Widgets REQUIRED) 
include_directories(${Qt5Core_INCLUDE_DIRS})
include_directories(${Qt5Gui_INCLUDE_DIRS})
include_directories(${Qt5Widgets_INCLUDE_DIRS})
add_definitions(${Qt5Widgets_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")

# Set up Qt forms/resources
qt5_wrap_ui(UI_OUT_FILES forms/Bar.ui)
qt5_add_resources(RESOURCE_FILE resources.qrc)

# Library cpp and header files
set(CORE_CPP_FILES Bar.cpp)
set(LIB_CPP_FILES ${LIB_CPP_FILES} ${CORE_CPP_FILES} ${UI_OUT_FILES} ${RESOURCE_FILE}) 
set(LIB_HEADER_FILES ${PUBLIC_HEADERS_DIR}/Foo/Bar.h)

# Build library
add_library(Foo SHARED ${LIB_CPP_FILES} ${LIB_HEADER_FILES})
target_link_libraries(Foo ${Qt5Widgets_LIBRARIES})

When I run cmake, I get the following error:

AUTOGEN: error: /automoc/src/lib/Foo/Bar.cpp The file includes the moc file "moc_Bar.cpp", but could not find header "Bar{.h,.hh,.h++,.hm,.hpp,.hxx,.in,.txx}" in /automoc/src/lib/Foo/

like image 762
user2180977 Avatar asked Feb 13 '15 04:02

user2180977


1 Answers

You have to wrap your header files manually. Put it into your CMakeLists.txt:

file(GLOB HEADERS_TO_MOC src/include/Foo/ *.h)

qt5_wrap_cpp(PROCESSED_MOCS                                                                                                                                                                                                                                                                    
             ${HEADERS_TO_MOC}                                                   
             TARGET Foo
             OPTIONS --no-notes) # Don't display a note for the headers which don't produce a moc_*.cpp

target_sources(Foo PRIVATE ${PROCESSED_MOCS}) # This adds generated moc cpps to target

Real example of this approach https://github.com/paceholder/nodeeditor/blob/master/CMakeLists.txt#L133

like image 113
paceholder Avatar answered Nov 06 '22 08:11

paceholder