Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

From QMake to CMake. (Different path levels)



  • Hi evereyone,

    I'm trying to port a multilevel project from QMake to CMake.

    Below show I the desired structure:

    The location of the root CMakeLists.txt a path level before than the main and the lib is a requirement

    ├── CMakeLists.txt
    ├── app02
    │   ├── CMakeLists.txt
    │   └── main.cpp
    └── lib
        ├── CMakeLists.txt
        ├── myprint.cpp
        └── myprint.h
    

    The root CMakeLists.txt is so written:

    cmake_minimum_required(VERSION 3.13)
    
    set(CMAKE_PROJECT_NAME "testProject")
    project(${CMAKE_PROJECT_NAME})
    
    list(APPEND CMAKE_PREFIX_PATH "/home/enigma/Qt/5.15.2/gcc_64")
    
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    find_package(Qt5Core REQUIRED)
    find_package(Qt5Widgets REQUIRED)
    
    add_subdirectory(lib app02)
    
    set(TARGET "app02Build")
    add_executable(${TARGET} ${SOURCES})
    
    target_link_libraries(${TARGET} thePrintLibrary Qt5::Core Qt5::Widgets)
    

    The main.cpp in app002 path is written so:

    #include "../lib/myprint.h"
    
    int main(int argc, char *argv[])
    {
        myPrint::print("This the second App");
    }
    

    And here is its correspondig CMakeLists.txt:

    cmake_minimum_required(VERSION 3.13)
    
    set(SOURCES
        main.cpp
    )
    

    The lib path contains the next files:

    myprint.h

    #ifndef MYPRINT_H
    #define MYPRINT_H
    
    #include <QDebug>
    #include <string>
    
    class myPrint
    {
    public:
        static void print(std::string toPrint) {
            qDebug() << toPrint.c_str();
        }
    };
    
    #endif // MYPRINT_H
    

    myPrint.cpp

    #include "myprint.h"
    //yes, there is no more code :-)
    

    and the corresponding CMakeLists.txt

    cmake_minimum_required(VERSION 3.13)
    
    
    add_library( 
    	thePrintLibrary
    	myprint.h
    	myprint.cpp
    )
    

    The CMake prescan runs fine, but when I compile I become the next error:

    [ 28%] Building CXX object app02/CMakeFiles/thePrintLibrary.dir/myprint.cpp.o
    In file included from /home/enigma/APD_Programas/Port/test/lib/myprint.cpp:1:
    /home/enigma/APD_Programas/Port/test/lib/myprint.h:4:10: fatal error: QDebug: No such file or directory
     #include <QDebug>
              ^~~~~~~~
    compilation terminated.
    gmake[2]: *** [app02/CMakeFiles/thePrintLibrary.dir/build.make:63: app02/CMakeFiles/thePrintLibrary.dir/myprint.cpp.o] Error 1
    gmake[1]: *** [CMakeFiles/Makefile2:162: app02/CMakeFiles/thePrintLibrary.dir/all] Error 2
    gmake: *** [Makefile:84: all] Error 2
    

    Someone so kind to help me?

    Thanks in advance



  • Thank you all,
    I found the last fail, with your help.

    In that path distribution, I must supply the complete main path in add_executable.

    add_executable(${TARGET} app02/main.cpp)
    

    Perhaps is there a better solution, so, if somebody want add something,
    please, you're welcomed


  • Lifetime Qt Champion

    When you want to use a library you have to link against them. Since QDebug is in QtCore you have to link against QtCore. And since it's in a public header of your lib you have to link use the PUBLIC keyword in target_link_libraries: target_link_libraries(thePrintLibrary PUBLIC Qt5::Core)
    See for example the Qt documentation: https://doc.qt.io/qt-6/cmake-manual.html
    You also should avoid relative includes but use target_include_directories() instead



  • @Christian-Ehrlicher said in From QMake to CMake. (Different path levels):

    target_link_libraries(thePrintLibrary PUBLIC Qt5::Core)

    Thank you Christian, I did it. I added

    target_link_libraries(thePrintLibrary PUBLIC Qt5::Core)
    

    And now I get another error at the end of the link process:

    [ 85%] Building CXX object CMakeFiles/app02Build.dir/app02Build_autogen/mocs_compilation.cpp.o
    [100%] Linking CXX executable app02Build
    /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
    (.text+0x20): undefined reference to `main'
    collect2: error: ld returned 1 exit status
    gmake[2]: *** [CMakeFiles/app02Build.dir/build.make:88: app02Build] Error 1
    gmake[1]: *** [CMakeFiles/Makefile2:74: CMakeFiles/app02Build.dir/all] Error 2
    gmake: *** [Makefile:84: all] Error 2
    

    How could I correctly link the main?

    Thanks in advance


  • Moderators

    @Josz said in From QMake to CMake. (Different path levels):

    How could I correctly link the main?

    I believe that's because you don't list app02/main.cpp in the top-level CMakeLists.txt, but in app02/CMakeLists.txt.

    I assume you're trying to mimic qmake's include() behavior here, and expect that set(SOURCES main.cpp) in app02/CMakeLists.txt changes the top-level SOURCES variable. Anyhow, you're using add_subdirectory(), which matches a SUBDIR setup in qmake. If you want _one_project/binary, but want to keep the sources organized in subfolders, use CMake's include().



  • Thank you all,
    I found the last fail, with your help.

    In that path distribution, I must supply the complete main path in add_executable.

    add_executable(${TARGET} app02/main.cpp)
    

    Perhaps is there a better solution, so, if somebody want add something,
    please, you're welcomed


Log in to reply