Setup QMake for a Qt library



  • Hello guys

    I am enjoying developing programs in Qt.
    After almost 2 years improving my design and sending programs out to customers I feel the need to start developing a library for commonly used functions.
    Making and using a library is easy enough using the wizard in Qt Creator, but I wish something more advance.

    I am using Qwt for several projects and I wish something like that. Multiple libraries that is compiled into a single .dll file, but the whole setup of QMake files seems complicated and I hoped for a simpler solution.

    Anyone who has any tips/guide or code examples that I can work from?

    Regards
    Sebastian Aslund


  • Lifetime Qt Champion

    Hi,

    Do you mean you would like to have a Qt module for your common stuff to use like e.g. QtGui ?



  • Heĺlo SGaist

    Yes, that would be the ideal goal. :)



  • Hello everyone

    I followed the qmake files in Qwt and I managed, I think, to make what I want. The only issue I have right now is that it seems to be a pain to add new project folder to the setup.
    Is my setup okay or could it be done better?

    What I want to avoid compared to Qwt is to have all my source and header files in one folder. I prefer every class to has it own sub-folder.

    My eeqt.pro file:

    ################################################################
    # EEQT Widget Library
    ################################################################
    
    include( eeqtconfig.pri )
    
    TEMPLATE = subdirs
    CONFIG += ordered
    
    SUBDIRS = \
    	src \
    	
    eeqtspec.files = eeqtconfig.pri eeqtfunctions.pri eeqt.prf
    eeqtspec.path = $${EEQT_INSTALL_FEATURES}
    
    INSTALLS += eeqtspec
    

    eeqtconfig.pri:

    ################################################################
    # EEQT Widget Library
    ################################################################
    
    EEQT_VER_MAJ			= 0
    EEQT_VER_MIN			= 0
    EEQT_VER_PAT			= 1
    EEQT_VERSION			= $${EEQT_VER_MAJ}.$${EEQT_VER_MIN}.$${EEQT_VER_PAT}
    
    ######################################################################
    # Install paths
    ######################################################################
    
    EEQT_INSTALL_PREFIX		= $$[QT_INSTALL_PREFIX]
    
    win32 {
            EEQT_INSTALL_PREFIX	= C:/EEQT-$${EEQT_VERSION}
    }
    
    EEQT_INSTALL_DOCS		= $${EEQT_INSTALL_PREFIX}/doc
    EEQT_INSTALL_HEADERS            = $${EEQT_INSTALL_PREFIX}/include
    EEQT_INSTALL_LIBS		= $${EEQT_INSTALL_PREFIX}/lib
    
    ######################################################################
    # Add features
    ######################################################################
    
    EEQT_INSTALL_FEATURES	= $${EEQT_INSTALL_PREFIX}/features
    
    ######################################################################
    # Add dynamic linking
    ######################################################################
    
    EEQT_CONFIG				+= EEQtDLL
    
    ######################################################################
    # Add EEQwtWidget
    ######################################################################
    
    EEQT_CONFIG				+= EEQwtWidget
    

    eeqtfunctions.pri:

    ################################################################
    # EEQT Widget Library
    ################################################################
    
    # Copied and modified from qwtfunctions.pri
    
    defineReplace(eeqtLibraryTarget) {
    
        unset(LIBRARY_NAME)
        LIBRARY_NAME = $$1
    
        contains(TEMPLATE, .*lib):CONFIG(debug, debug|release) {
    
            !debug_and_release|build_pass {
    
                mac:RET = $$member(LIBRARY_NAME, 0)_debug
                win32:RET = $$member(LIBRARY_NAME, 0)d
            }
        }
    
        isEmpty(RET):RET = $$LIBRARY_NAME
        return($$RET)
    }
    
    defineTest(eeqtAddLibrary) {
    
        LIB_PATH = $$1
        LIB_NAME = $$2
    
        mac:contains(QWT_CONFIG, QwtFramework) {
    
            LIBS      *= -F$${LIB_PATH}
        }
        else {
    
            unix:lessThan(QT_MAJOR_VERSION, 5) {
    
                # Many Linux distributions install Qwt in the same directory
                # as the Qt libs and thus we need to prepend the path for the local build
                # to avoid conflicting with the installed version.
                # Qt5 qmake appends ( instead of prepending ) the path to the Qt libs
                # to LIBS, but for Qt4 we need to use the QMAKE_LIBDIR_FLAGS.
    
                QMAKE_LIBDIR_FLAGS *= -L$${LIB_PATH}
            }
            else {
                LIBS *= -L$${LIB_PATH}
            }
        }
    
        unset(LINKAGE)
    
        isEmpty(LINKAGE) {
    
            if(!debug_and_release|build_pass):CONFIG(debug, debug|release) {
    
                mac:LINKAGE = -l$${LIB_NAME}_debug
                win32:LINKAGE = -l$${LIB_NAME}d
            }
        }
    
        isEmpty(LINKAGE) {
    
            LINKAGE = -l$${LIB_NAME}
        }
    
        !isEmpty(QMAKE_LSB) {
    
            QMAKE_LFLAGS *= --lsb-shared-libs=$${LIB_NAME}
        }
    
        LIBS += $$LINKAGE
        export(LIBS)
        export(QMAKE_LFLAGS)
        export(QMAKE_LIBDIR_FLAGS)
    
        return(true)
    }
    

    eeqt.prf:

    ################################################################
    # EEQT Widget Library
    ################################################################
    
    include ( ./eeqtconfig.pri )
    include ( ./eeqtfunctions.pri )
    
    contains(EEQT_CONFIG, EEQtDll) {
    
        DEFINES *= EEQT_DLL
    }
    
    INCLUDEPATH *= $${EEQT_INSTALL_HEADERS}
    
    qwtAddLibrary($${EEQT_INSTALL_LIBS}, eeqt)
    

    src.pro

    ################################################################
    # EEQT Widget Library
    ################################################################
    
    EEQT_ROOT		= $${PWD}/..
    include($${EEQT_ROOT}/eeqtconfig.pri)
    include($${EEQT_ROOT}/eeqtbuild.pri)
    include($${EEQT_ROOT}/eeqtfunctions.pri)
    
    EEQT_OUT_ROOT = $${OUT_PWD}/..
    
    TEMPLATE		= lib
    TARGET			= $$eeqtLibraryTarget(eeqt)
    
    contains(EEQT_CONFIG, EEQtDLL) {
    
    	CONFIG += dll
    	win32: DEFINES += QT_DLL EEQT_DLL EEQT_MAKEDLL
    }
    
    contains(EEQT_CONFIG, EEQwtWidget) {
    
        include($${PWD}/EEQwtWidget/eeqwtwidget.pri)
    }
    
    target.path    = $${EEQT_INSTALL_LIBS}
    INSTALLS       = target 
    
    headers.files  = $${HEADERS}
    headers.path   = $${EEQT_INSTALL_HEADERS}
    INSTALLS += headers
    

    eeqwtwidget.pri:

    HEADERS += \
    		EEQwtWidget/eeqwtwidget.h \
            eeqt_global.h \
    		EEQwtWidget/customscaledraw.h
    		
    SOURCES += \
    		EEQwtWidget/eeqwtwidget.cpp \
    		EEQwtWidget/customscaledraw.cpp
    

  • Lifetime Qt Champion

    One subfolder by class ? Isn't that a bit too much ?

    Usually it's rather one subfolder per "logical block"



  • Hello SGaist

    Yea, I came to the same conclusion. To much work making all these separate folders.
    But how would you add these "logical blocks"?

    headers.files  = $${HEADERS}
    headers.path   = $${EEQT_INSTALL_HEADERS}
    INSTALLS += headers
    

    Here all headers will be installed at the same level. If the idea of logical blocks should work then different headers should go into different sub-folders. Whats the best approach here?


  • Moderators

    @Aslund

    HEADERS += \
    		module_1/class_1.h \
                    module_2/class_1.h \
                    ...
    		
    SOURCES += \
    		module_1/class_1.cpp \
                    module_2/class_1.cpp \
    

  • Lifetime Qt Champion

    Or add a .pri file per module that extends these variables and include them in your main .pro file.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.