Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-62918

MinGW windres compilation fails due to spaces in path

    XMLWordPrintable

Details

    • Bug
    • Resolution: Out of scope
    • P4: Low
    • None
    • 5.8.0
    • Build tools: qmake
    • None

    Description

      qmake with MinGW totally fails if you a) have `RC_FILE` set, and b) have your project in a path containing spaces.

      To reproduce:

      1. Create a folder ~/path with spaces
      2. Create a Qt qmake project in that folder.
      3. Add `RC_FILE = WindowsResources.rc` to the qmake
      4. Create the `WindowsResource.rc` file containing `IDI_ICON1 ICON DISCARDABLE "this_doesnt_need_to_exist.ico"`
      5. Try and build it.

      It runs this command:

      windres -i "..\..\Docs\path with spaces\TestProject\WindowsResources.rc" -o debug\WindowsResources_res.o --include-dir=./"../../Docs/path with spaces/TestProject" -DUNICODE -DQT_DEPRECATED_WARNINGS -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN

      Unfortunately any other quoting I tried didn't work either. It seems that the problem may be that windres was written by one of those ancient Unix people who don't know what spaces or GUIs are.

      ... investigates ...

      Ah windres is written by GNU, I knew it! Can't get more ancient than that. Here is the offending file:

      https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=binutils/windres.c;h=7725f59105014eacc5470ee5f37ebbc794e3210e;hb=HEAD

      That is some seriously old-school code. And after a few minutes I found the problem:

      /* Quote characters that will confuse the shell when we run the preprocessor.  */
      
      static const char *
      quot (const char *string)
      {
        static char *buf = 0;
        static int buflen = 0;
        int slen = strlen (string);
        const char *src;
        char *dest;
      
        if ((buflen < slen * 2 + 2) || ! buf)
          {
            buflen = slen * 2 + 2;
            if (buf)
      	free (buf);
            buf = (char *) xmalloc (buflen);
          }
      
        for (src=string, dest=buf; *src; src++, dest++)
          {
            if (*src == '(' || *src == ')' || *src == ' ')
      	*dest++ = '\\';
            *dest = *src;
          }
        *dest = 0;
        return buf;
      }
      

      "Let's just call system()" ancient Unix-guy says. What could go wrong? "Do it right dammit!"... is what I would have said if I had been there at the time. Apparently this code was written in 1997 by Ian Lance Taylor at Cygnus. The quoting code was added by DJ Delorie, also at Cygnus in 1999. But I feel like the blame really lies with Ian, who did all this program calling as strings instead of proper arrays of strings.

      The whole thing needs a proper rewrite in modern C++. Look at this nonsense:

      https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=binutils/resrc.c;h=26ac848c50b55e431ede43cbc8bdc068b88ff70f;hb=HEAD#l484

      Sorry this isn't strictly a Qt bug but it affects Qt and I've ranted so much now I can't just delete it!

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            buddenha Oswald Buddenhagen
            timmmm Tim
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes