Search code examples
c++cmakeqt5

CMake Qt5 can't generate header file for ui file AUTOUIC


I can't generate the header for my ui files with cmake 3.5.2 and Qt 5.9.

My CMakeFileLists.txt:

cmake_minimum_required(VERSION 3.5)
project( fc_app )
message( STATUS "Configuring project")


set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

message( STATUS "search OpenCV")
find_package(
    OpenCV
    3.2.0
    REQUIRED
)

message( STATUS "search Qt")
find_package(
    Qt5
    5.5.1
    REQUIRED
        Core
        Gui
        Widgets
        Multimedia
)

message( STATUS "search Boost")
find_package(
    Boost
    1.58.0
    REQUIRED
)


file( GLOB_RECURSE source_files src/* )
file( GLOB_RECURSE header_files include/* )
file( GLOB_RECURSE ui_files ui/* )
file( GLOB_RECURSE res_files res/* )

add_executable(
    fc_app
    ${source_files}
    ${header_files}
    ${ui_files}
)

target_link_libraries(
    fc_app
    ${OpenCV_LIBS}
    Qt5::Widgets
    Qt5::Multimedia
    ${Boost_LIBRARIES}
)

I get the following error (in make) when I run cmake .. & make in the root/build/ directory. The ui file is a simple QMainWindow with 2 buttons in it, so I don't unterstand why the generation of ui_mainwindow.h failed. I tried to remake the ui file with an other version of Qt5 Designer too.

File '/blablablabla/mainwindow.ui' is not valid
AUTOUIC: error: process for ui_mainwindow.h needed by
 "/blablablabla/mainwindow.cpp"
failed:
File '/blablablabla/mainwindow.ui' is not valid

Solution

  • There's a quirk with CMake and QT for AUTOUIC. It is claimed that CMake will automatically scan files for ui file includes though it does not work if the ui include is on the first line of the source file.

    So following setup:

    CMakeLists.txt:

    project("proj")
    
    set(CMAKE_PREFIX_PATH "$ENV{QTDIR}")
    find_package(Qt5Core REQUIRED)
    find_package(Qt5Widgets REQUIRED)
    
    set(CMAKE_INCLUDE_CURRENT_DIR "YES")
    set(CMAKE_AUTOMOC "YES")
    set(CMAKE_AUTOUIC "YES")
    
    add_executable("proj" MACOSX_BUNDLE main.cpp)
    target_link_libraries("proj" Qt5::Core Qt5::Widgets)
    

    form.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Form</class>
     <widget class="QWidget" name="Form">
     </widget>
     <resources/>
     <connections/>
    </ui>
    

    Will fail to compile with main.cpp having:

    1. #include "ui_form.h"
    2.
    3. int main() {
    4. }
    
    $ cmake --build .
    Scanning dependencies of target proj_automoc
    [ 25%] Automatic moc and uic for target proj
    Generating moc compilation proj_automoc.cpp
    [ 25%] Built target proj_automoc
    Scanning dependencies of target proj
    [ 50%] Building CXX object CMakeFiles/proj.dir/main.cpp.o
    main.cpp:1:10: fatal error: 'ui_form.h' file not found
    #include "ui_form.h"
             ^
    1 error generated.
    make[2]: *** [CMakeFiles/proj.dir/main.cpp.o] Error 1
    make[1]: *** [CMakeFiles/proj.dir/all] Error 2
    make: *** [all] Error 2
    

    However if your ui include is not on the first line:

    1. 
    2. #include "ui_form.h"
    3. int main() {
    4. }
    
    $ cmake --build .
    [ 25%] Automatic moc and uic for target proj
    Generating ui header ui_form.h
    [ 25%] Built target proj_automoc
    Scanning dependencies of target proj
    [ 50%] Building CXX object CMakeFiles/proj.dir/main.cpp.o
    [ 75%] Building CXX object CMakeFiles/proj.dir/proj_automoc.cpp.o
    [100%] Linking CXX executable proj.app/Contents/MacOS/proj
    [100%] Built target proj
    

    UPD. This regular expression used to scan for include is the culprit:

    this->UicRegExpInclude.compile("[\n][ \t]*#[ \t]*include[ \t]+"
                                   "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
    

    It is still there in latest release 3.10.2 but already fixed in 3.11:

    Uic_.RegExpInclude.compile("(^|\n)[ \t]*#[ \t]*include[ \t]+"
                               "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");