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

moc resolves symlinks using canonicalFilePath(), breaking relative includes

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 5.12.2
    • Build tools: moc
    • None

    Description

      Our build system uses symlinks to create a copy of the directory structure to build, but places all the actual files it wants to use in a flat directory (all file names are hashed). This causes troubles for moc when it is resolving includes, since it removes the symlink info by calling canonicalFilePath() in preprocessor.cpp.

      For example:

      ls -l ./**:
      lrwxrwxrw 1   33 Jul 11 12:20 dir_a/dir_b/file_with_redirect.h -> ../../hashed_file_with_redirect.h
      -rw-r----- 1   23 Jul 11 12:18 dir_a/file_with_symbol.h
      -rw-r----- 1  186 Jul 11 12:18 dir_a/header_to_moc.h
      -rw-r----- 1   33 Jul 11 12:19 hashed_file_with_redirect.h
      

      file_with_redirect.h

      #include "../file_with_symbol.h"
      

      file_with_symbol.h

      #define SYMBOL_DEFINED
      

      header_to_moc.h

      #include <QObject>
      #include "dir_b/file_with_redirect.h"
      
      #ifdef SYMBOL_DEFINED
      
      class TestClass : public QObject {
        Q_OBJECT
        Q_PROPERTY(bool test READ test WRITE setTest)
      };
      
      #endif
      

      And trying to invoke moc:

      moc dir_a/header_to_moc.h -o /tmp/header_to_moc.h
      dir_a/header_to_moc.h:0: Note: No relevant classes found. No output generated.
      

      But if you were to patch preprocessor.cpp:

      @@ -1030,7 +1030,7 @@
      
           if (!fi.exists() || fi.isDir())
               return QByteArray();
      -    return fi.canonicalFilePath().toLocal8Bit();
      +    return fi.filePath().toLocal8Bit();
       }
      
       QByteArray Preprocessor::resolveInclude(const QByteArray &include, const QByteArray &relativeTo)
      @@ -1039,7 +1039,7 @@
               QFileInfo fi;
               fi.setFile(QFileInfo(QString::fromLocal8Bit(relativeTo)).dir(), QString::fromLocal8Bit(include));
               if (fi.exists() && !fi.isDir())
      -            return fi.canonicalFilePath().toLocal8Bit();
      +            return fi.filePath().toLocal8Bit();
           }
      
           auto it = nonlocalIncludePathResolutionCache.find(include);
      

      It picks up the symbol and the class.

      This seems like a similar issue to https://bugreports.qt.io/browse/QTBUG-22655, not sure if there should be some more general cleanup or policy on what to do with symlinks in the build tools.

      Attachments

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

        Activity

          People

            Unassigned Unassigned
            cwgthornton Chris Thornton
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes