make non-bootstrapped non-installed prefix-built executables runnable
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>
Tue, 3 Jul 2012 17:26:36 +0000 (19:26 +0200)
committerQt by Nokia <qt-info@nokia.com>
Thu, 5 Jul 2012 19:11:08 +0000 (21:11 +0200)
tools like idc and lrelease are outside qtbase/bin and depend on libraries
which are not in any search path, so we need some way to let the modules
announce the locations (qt_tool.prf) and use it (in qtPrepareTool()).

Change-Id: I98d5109cbee5e745d86dde94e3dc791d42edc3ec
Reviewed-by: Marius Storm-Olsen <marius.storm-olsen@nokia.com>
mkspecs/features/qt_functions.prf
mkspecs/features/qt_tool.prf [new file with mode: 0644]

index e51a3c9..fe7b29a 100644 (file)
@@ -118,23 +118,46 @@ defineTest(qtAddModule) {
 
 # variable, default
 defineTest(qtPrepareTool) {
-    MODBASE = $$[QT_HOST_BINS/get]
-    count(ARGS, 2, greaterThan) {
-        isEmpty(QT.$${3}.bins):warning("No QT.$${3}.bins, module path ignored for qtPrepareTool($$1, $$2, $$3)")
-        else:MODBASE = $$eval(QT.$${3}.bins)
+    $$1 = $$eval(QT_TOOL.$${2}.binary)
+    isEmpty($$1) {
+        MODBASE = $$[QT_HOST_BINS/get]
+        count(ARGS, 2, greaterThan) {
+            isEmpty(QT.$${3}.bins):warning("No QT.$${3}.bins, module path ignored for qtPrepareTool($$1, $$2, $$3)")
+            else:MODBASE = $$eval(QT.$${3}.bins)
+        }
+        isEmpty($$1):$$1 = $$MODBASE/$$2
+        contains(QMAKE_HOST.os, Windows):!contains($$1, .*\\.(exe|bat)$) {
+            exists($$eval($$1).bat) {
+                $$1 = $$eval($$1).bat
+            } else {
+                $$1 = $$eval($$1).exe
+            }
+        } else:contains(QMAKE_HOST.os, Darwin) {
+            BUNDLENAME = $$eval($$1).app/Contents/MacOS/$$2
+            exists($$BUNDLENAME) {
+                $$1 = $$BUNDLENAME
+            }
+        }
     }
-    isEmpty($$1):$$1 = $$MODBASE/$$2
-    $$1 ~= s,[/\\\\],$$QMAKE_DIR_SEP,
-    contains(QMAKE_HOST.os, Windows):!contains($$1, .*\\.(exe|bat)$) {
-        exists($$eval($$1).bat) {
-            $$1 = $$eval($$1).bat
+    $$1 = $$native_path($$eval($$1))
+
+    deps = $$resolve_depends(QT_TOOL.$${2}.depends, "QT.")
+    !isEmpty(deps) {
+        for(dep, deps): \
+            deppath += $$native_path($$eval(QT.$${dep}.libs))
+        deppath = $$unique(deppath)
+        equals(QMAKE_DIR_SEP, /) {
+            equals(QMAKE_HOST.os, Windows): \
+                var = PATH
+            else:contains(QMAKE_HOST.os, Linux): \
+                var = LD_LIBRARY_PATH
+            else:equals(QMAKE_HOST.os, Darwin): \
+                var = DYLD_LIBRARY_PATH
+            else: \
+                error("Operating system not supported.")
+            $$1 = "$$var=$$join(deppath, :)${$$var:+:\$$$var} $$eval($$1)"
         } else {
-            $$1 = $$eval($$1).exe
-        }
-    } else:contains(QMAKE_HOST.os, Darwin) {
-        BUNDLENAME = $$eval($$1).app/Contents/MacOS/$$2
-        exists($$BUNDLENAME) {
-            $$1 = $$BUNDLENAME
+            $$1 = "(set PATH=$$join(deppath, ;);%PATH%) & $$eval($$1)"
         }
     }
 
diff --git a/mkspecs/features/qt_tool.prf b/mkspecs/features/qt_tool.prf
new file mode 100644 (file)
index 0000000..134cb4b
--- /dev/null
@@ -0,0 +1,55 @@
+TEMPLATE = app
+
+CONFIG += qt warn_on console
+CONFIG -= app_bundle
+
+build_all:!build_pass {
+    CONFIG -= build_all
+    CONFIG += release
+}
+
+target.path = $$[QT_INSTALL_BINS]
+INSTALLS += target
+
+# If we are doing a prefix build, create a "module" pri which enables
+# qtPrepareTool() to work with the non-installed build.
+!build_pass:!exists($$[QT_INSTALL_PREFIX]/.qmake.cache) {
+
+    isEmpty(TARGET):TARGET = $$section($$list($$basename(_PRO_FILE_)), ., 0, 0)
+    isEmpty(MODULE):MODULE = $$TARGET
+
+    MODULE_DEPENDS = $$replace(QT, -private$, )
+
+    # Find the module's source root dir.
+    MODULE_PROFILE_DIR = $$_PRO_FILE_PWD_
+    for(ever) {
+        exists($$MODULE_PROFILE_DIR/sync.profile):break()
+        nmpri = $$dirname(MODULE_PROFILE_DIR)
+        equals(nmpri, $$MODULE_PROFILE_DIR): \
+            error("No sync.profile found. This does not look like a Qt module source tree.")
+        MODULE_PROFILE_DIR = $$nmpri
+        unset(nmpri)
+    }
+
+    isEmpty(MODULE_BASE_DIR): MODULE_BASE_DIR = $$MODULE_PROFILE_DIR
+    MODULE_BASE_OUTDIR = $$shadowed($$MODULE_BASE_DIR)
+    isEmpty(MODULE_QMAKE_OUTDIR): MODULE_QMAKE_OUTDIR = $$MODULE_BASE_OUTDIR
+
+    TOOL_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_$${MODULE}.pri
+
+    TOOL_PRI_CONT = \
+        "QT_TOOL.$${MODULE}.binary = $$absolute_path($$DESTDIR, $$OUT_PWD)/$$TARGET" \
+        "QT_TOOL.$${MODULE}.depends =$$join(MODULE_DEPENDS, " ", " ")"
+    write_file($$TOOL_PRI, TOOL_PRI_CONT)|error("Aborting.")
+
+    # Then, inject the new tool into the current cache state
+    !contains(QMAKE_INTERNAL_INCLUDED_FILES, $$TOOL_PRI) { # before the actual include()!
+        added = $$TOOL_PRI
+        cache(QMAKE_INTERNAL_INCLUDED_FILES, add transient, added)
+        unset(added)
+    }
+    include($$TOOL_PRI)
+    for(var, $$list(binary depends)): \
+        cache(QT_TOOL.$${MODULE}.$$var, transient)
+
+}