Important: Please read the Qt Code of Conduct -

Not sure about how to use the INSTALLS functionality of the project file

  • I hope this question has to do with Qt.
    So, in my project file I have for example:

    @configfiles.files += data/to_usr_share/*
    configfiles.path = /usr/share/
    unix:configfiles.extra = make clean; update-desktop-database;
    docfiles.files += data/doc/*
    docfiles.path = /usr/share/doc/
    shortcutfiles.files += data/wallch.desktop
    shortcutfiles.path = /usr/share/applications/
    helpfiles.files += data/help/*
    helpfiles.path = /usr/share/gnome/help
    INSTALLS += configfiles
    INSTALLS += docfiles
    INSTALLS += shortcutfiles
    INSTALLS += helpfiles@

    When I run
    qmake *.pro
    My created makefile includes the hardcored paths of the files ( *.files += etc)

    @install_docfiles: first FORCE
    @$(CHK_DIR_EXISTS) $(INSTALL_ROOT)/usr/share/doc/ || $(MKDIR) $(INSTALL_ROOT)/usr/share/doc/
    -$(INSTALL_DIR) /home/alex/Desktop/ALL/REAL64/wallch-2.0/data/doc/wallch $(INSTALL_ROOT)/usr/share/doc/@

    How can I avoid this? I mean to make makefile just take the current path (.) as the root for the .files entries?

    Or everybody that I give them the source have to run @qmake so as to work?

  • You can basically use any of "qmake's variables": like "$$PWD": or "$$OUT_PWD": or reference environment variables.
    documentation.path = $$[QMAKE_MKSPECS]/$(SOME_ENV_VARIABLE)/features
    install_features: FORCE
    @$(CHK_DIR_EXISTS) ... /mkspecs/$(SOME_ENV_VARIABLE)/features/

    Having the user to run qmake is absolutely valid.

    Be aware that INSTALLS does not create copy instructions for files that do not exist at the time qmake is invoked even though they are listed in the .files member or are covered by wildcards listed there.

    You can prohibit this behaviour by adding the no_check_exist value to the .CONFIG member.
    documentation.CONFIG = no_check_exist

  • Thanks for this, I'm not familiar with qmake's variables... How would I use them in my case?
    Thanks again

  • @docfiles.files += data/doc/*
    docfiles.path = $(PWD)/usr/share/doc/
    should generate
    @install_docfiles: first FORCE
    @$(CHK_DIR_EXISTS) $(INSTALL_ROOT)/usr/share/doc/ || $(MKDIR) $(INSTALL_ROOT)/usr/share/doc/
    -$(INSTALL_DIR) $(PWD)/data/doc/wallch $(INSTALL_ROOT)/usr/share/doc/@
    and $(PWD) should be replaced by the working directory at the time make install is called.

    However distributing the .pro file and having the user call qmake on their specific platform and build system is absolutely valid. qmake was created for exactly that purpose.

  • Are you sure about this?
    docfiles.path = $(PWD)/usr/share/doc/

    -$(INSTALL_DIR) $(PWD)/data/doc/wallch $(INSTALL_ROOT)/usr/share/doc/

  • Actually you'll need to add a preceding slash to make it an absolute path, otherwise qmake will append the working directory and as long as you guarantee that INSTALL_ROOT is empty it will expand to the correct path.

  • So has it to be
    docfiles.path = /$(PWD)/usr/share/doc/ ?

  • Yes. Is there a reason you do not want to distribute the .pro file along with your application?

  • What make you believe I DO NOT want to do so?

  • Because all this stuff isn't needed if you use "qmake's variables": directly and the user just runs qmake to generate proper makefiles.

    I probably misunderstood your inital question which led to the slightly confusing response.

    There are two types of variables you can use with qmake

    • qmake variables, which are processed when qmake is run, like $$PWD
    • environment variables, which are processed when make is run, like $(PWD)

    As qmake creates makefiles with absolute pathes (relative ones are automatically expanded by $PWD) you will have to either re-run qmake if your pathes change or you will have to rely on environment variables (which can be a bit tricky as you can see).

    So the most simple answer to your question is: Yes. Everybody will have to run qmake.
    At least there is no option to qmake I know of which prohibits the generation of absolute pathes.

    When talking about INSTALLS one should further mention that if you want to install files which are generated during build (for example generated help files or such) you will have to prepend your relative pathes with $$OUT_PWD to support out of source builds.

  • Ok, thanks for this.
    Something else, because it is similar and I don't want to start another thread...
    In my project file I have:
    @DEFINES +="PREFIX="/usr/local""@
    How do I use this definition in my program?
    For example:
    @ cout << PREFIX;@
    gives error:
    @ /usr/local was not declared in this scope@
    and when I use:
    @ cout << "PREFIX";@
    of course it outputs
    @ PREFIX@

    I don't know what to do :/

  • Just add an escaped backslash to DEFINES so the quotation marks correctly pass through
    DEFINES += "PREFIX=\"/usr/local\""
    std::cout << PREFIX;
    or quote the preprocessor macro in your code correctly.
    DEFINES +="PREFIX="/usr/local""
    #define QUOTE(string) _QUOTE(string)
    #define _QUOTE(string) #string
    std::cout << QUOTE(PREFIX);

  • Thanks Lukas, the former worked OK!
    Something else, can I use the definition PREFIX on my INSTALLS rules inside the project file?
    For example, can I say
    @configfiles.path = $$PREFIX@ (meaning configfiles.path = /usr/local)
    and if yes, how?

  • For sure.
    PREFIX = /usr/local
    configfiles.path = $$PREFIX

  • Good ;)

Log in to reply