diff options
1054 files changed, 7681 insertions, 6388 deletions
@@ -1 +1 @@ -1.12.3 +1.13.0 diff --git a/doc/external-resources.qdoc b/doc/external-resources.qdoc index 4a98f9d8d..c66d9633c 100644 --- a/doc/external-resources.qdoc +++ b/doc/external-resources.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qbs. @@ -116,7 +116,13 @@ */ /*! + \externalpage https://github.com/protocolbuffers/protobuf + \title protoc +*/ + +/*! \externalpage nolink \title macOS \internal */ + diff --git a/doc/howtos.qdoc b/doc/howtos.qdoc index 6039a23fb..7ef1fc086 100644 --- a/doc/howtos.qdoc +++ b/doc/howtos.qdoc @@ -38,11 +38,14 @@ \li \l{How do I build a Qt-based project?} \li \l{How do I make my app build against my library?} \li \l{How do I use precompiled headers?} + \li \l{How do I make sure my generated sources are getting compiled?} \li \l{How do I run my autotests?} \li \l{How do I create a module for a third-party library?} \li \l{How do I create application bundles and frameworks on iOS, macOS, tvOS, and watchOS?} \li \l{How do I apply C/C++ preprocessor macros to only a subset of the files in my product?} \li \l{How do I make the state of my Git repository available to my source files?} + \li \l{How do I limit the number of concurrent jobs for the linker only?} + \li \l{How do I add QML files to a project?} \endlist \section1 How do I build a Qt-based project? @@ -72,7 +75,6 @@ This is achieved by introducing a \e dependency between the two products using the \l{Depends} item. Here is a simple, but complete example: \code - import qbs Project { CppApplication { name : "the-app" @@ -108,6 +110,21 @@ The product definitions would stay exactly the same. In particular, their location in the project tree is irrelevant to the relationship between them. + \section2 Choosing Between Dynamic and Statically-built Qt Projects + + To build \c "the-lib" as either a dynamic or static library, depending on + how Qt was built, you can use the following code: + + \code + Product { + name: "the-lib" + type: Qt.core.staticBuild ? "staticlibrary" : "dynamiclibrary" + + Depends { name: "Qt.core" } + // ... + } + \endcode + \section1 How do I use precompiled headers? If you use a \l Group item to add a precompiled header file to a product @@ -120,8 +137,6 @@ For example: \code - import qbs - CppApplication { name: "the-app" files: ["main.cpp"] @@ -133,6 +148,42 @@ } \endcode + \section1 How do I make sure my generated sources are getting compiled? + + The rules in a \QBS project do not care whether its inputs are actual source files + listed on the right-hand side of a \l{Product::files}{files} property or artifacts + that were generated by another rule. For instance, the C++ compiler rule considers + all input files of type "cpp", no matter how they got into the product. The following + example project demonstrates this. One of its source files exists in the repository, + the other one is generated at build time. Both are getting compiled the same way. + \note Do not try to add the generated files to a \c files property. Declaring them + as rule outputs is all that is needed to make \QBS know about them. + \code + import qbs.TextFile + CppApplication { + files: ["impl.cpp", "impl.h"] + cpp.includePaths: sourceDirectory + Rule { + multiplex: true + Artifact { filePath: "main.cpp"; fileTags: "cpp" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { + var f = new TextFile(output.filePath, TextFile.WriteOnly); + f.writeLine("#include <impl.h>"); + f.writeLine("int main()"); + f.writeLine("{"); + f.writeLine(" return functionFromImpl();"); + f.writeLine("}"); + f.close(); + }; + return cmd; + } + } + } + \endcode + \section1 How do I run my autotests? There are two simple things you need to do in your project. Firstly, you @@ -210,7 +261,6 @@ Finally, declare dependencies on \c ThirdParty in your project: \code - import qbs CppApplication { name: "the-app" files: ["main.cpp"] @@ -227,8 +277,6 @@ Here is a simple example for an application: \code - import qbs - Application { Depends { name: "cpp" } Depends { name: "bundle" } @@ -241,8 +289,6 @@ and for a framework: \code - import qbs - DynamicLibrary { Depends { name: "cpp" } Depends { name: "bundle" } @@ -337,4 +383,75 @@ This value is also available via the \l{vcs::repoState}{vcs.repoState} property. + + \section1 How do I limit the number of concurrent jobs for the linker only? + \target job-pool-howto + + While it is usually desirable to run as many compiler jobs as there are CPU cores, + the same is not true for linker jobs. The reason is that linkers are typically + I/O bound rather than CPU bound. When building large libraries, they also tend + to use up enormous amounts of memory. Therefore, we'd like to make sure that + only a few linkers are running at the same time without limiting other types + of jobs. In \QBS, this is achieved via \e{job pools}. There are several ways + to make use of them. + + Firstly, you can provide a limit via the command line: + \code + $ qbs --job-limits linker:4 + \endcode + The above call instructs \QBS to run at most four linker instances at the same + time, while leaving the general number of concurrent jobs at the default + value, which is derived from the number of CPU cores. + The \c linker string on the command line refers to the job pool of the same + name, which the \l{cpp-job-pools}{cpp module} assigns to all its commands that + invoke a linker. + + Secondly, you can set a limit via the settings, either generally + or for a specific profile: + \code + $ qbs config preferences.jobLimit.linker 4 + $ qbs config profiles.myprofile.preferences.jobLimit.linker 2 + \endcode + + And finally, you can also set the limit per project or per product, using a + \l JobLimit item: + \code + Product { + name: "my_huge_library" + JobLimit { + jobPool: "linker" + jobCount: 1 + } + // ... + } + \endcode + The above construct ensures that this specific library is never linked at + the same time as any other binary in the project. + + Job limits set on the command line override those from the settings, which in turn + override the ones defined within a project. Use the \c{--enforce-project-job-limits} + option to give the job limits defined via \c JobLimit items maximum precedence. + + \section1 How do I add QML files to a project? + + The simplest way to add QML files to a project is to add them to a + \l {The Qt Resource System}{resource file}: + + \code + QtGuiApplication { + // ... + + files: "main.cpp" + + Group { + prefix: "qml/" + files: ["main.qml", "HomePage.qml"] + fileTags: ["qt.qml.qml", "qt.core.resource_data"] + } + } + \endcode + + In the example above, we declare each QML file as having the + \l {filetags-qtcore}{"qt.core.resource_data"} file tag. This ensures + that it is added to a generated resource file. */ diff --git a/doc/qbs.qdoc b/doc/qbs.qdoc index bfeda503a..c73b3f148 100644 --- a/doc/qbs.qdoc +++ b/doc/qbs.qdoc @@ -170,8 +170,6 @@ \l{cpp} module: \code - import qbs - Application { name: "helloworld" files: "main.cpp" @@ -330,8 +328,6 @@ The following example product contains one file tag, \e application: \code - import qbs - Product { Depends { name: "cpp" } type: ["application"] @@ -350,7 +346,6 @@ artifacts that takes \c .cpp artifacts as input. \code - import qbs Module { // ... Rule { @@ -819,8 +814,6 @@ A very simple C++ hello world project looks like this: \code ---helloworld.qbs--- - import qbs 1.0 - Application { name: "helloworld" files: "main.cpp" @@ -862,8 +855,6 @@ \code ---CrazyProduct.qbs--- - import qbs 1.0 - Product { property string craziness: "low" } @@ -887,7 +878,6 @@ } ---myproject.qbs--- - import qbs 1.0 import "helpers.js" as Helpers Product { @@ -934,8 +924,6 @@ module. You specify the optimization level for your product (and all build variants) like this: \code ---helloworld.qbs--- - import qbs 1.0 - Application { name: "helloworld" files: ["main.cpp"] diff --git a/doc/reference/cli/builtin/cli-build.qdoc b/doc/reference/cli/builtin/cli-build.qdoc index 8e4b8ed44..cffb19d49 100644 --- a/doc/reference/cli/builtin/cli-build.qdoc +++ b/doc/reference/cli/builtin/cli-build.qdoc @@ -68,6 +68,7 @@ \target build-force-probe-execution \include cli-options.qdocinc force-probe-execution \include cli-options.qdocinc jobs + \include cli-options.qdocinc job-limits \include cli-options.qdocinc keep-going \include cli-options.qdocinc less-verbose \include cli-options.qdocinc log-level diff --git a/doc/reference/cli/cli-options.qdocinc b/doc/reference/cli/cli-options.qdocinc index 189a3526a..254444dcb 100644 --- a/doc/reference/cli/cli-options.qdocinc +++ b/doc/reference/cli/cli-options.qdocinc @@ -249,6 +249,22 @@ //! [jobs] +//! [job-limits] + + \section2 \c {--job-limits <pool1>:<limit1>[,<pool2>:<limit2>...]} + + Sets pool-specific job limits. See \l{job-pool-howto}{here} for more information on + job pools. + + \section2 \c {--enforce-project-job-limits} + + Normally, job limits defined in project files via the \l JobLimit item get overridden + by those set on the command line. If this option is passed, they get maximum priority + instead. Use it if there are product-specific limits that make more sense for + that part of the code base than the generic ones you'd like to apply globally. + +//! [job-limits] + //! [keep-going] \section2 \c --keep-going|-k @@ -441,8 +457,6 @@ This option is mutually exclusive with \c --log-time. - \note This option is not available on a Windows host. - //! [show-progress] //! [setup-tools-system] diff --git a/doc/reference/commands.qdoc b/doc/reference/commands.qdoc index 8f0392c32..eb93e8f7a 100644 --- a/doc/reference/commands.qdoc +++ b/doc/reference/commands.qdoc @@ -103,6 +103,13 @@ \endlist All other values are mapped to the default color. \row + \li \c jobPool + \li string + \li empty + \li Determines which job pool the command will use. An empty + string, which is the default, stands for the global job pool. + See \l{JobLimit}{here} and \l{job-pool-howto}{here} for more information on job pools. + \row \li \c silent \li bool \li false diff --git a/doc/reference/items/convenience/androidapk.qdoc b/doc/reference/items/convenience/androidapk.qdoc deleted file mode 100644 index 89a4112b6..000000000 --- a/doc/reference/items/convenience/androidapk.qdoc +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qbs. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ -/*! - \contentspage list-of-convenience-items.html - \nextpage AppleApplicationDiskImage - \qmltype AndroidApk - \inherits Product - \inqmlmodule QbsConvenienceItems - \ingroup list-of-items - \keyword QML.AndroidApk - - \brief Android application package. - - An AndroidApk item is a \l{Product}{product} of the \l{Product::}{type} - \c android.apk that has a \l{Depends}{dependency} on the \l{Android.sdk} - module. The final build result is an Android application package (APK) file. - - Here is what the project file could look like for the BasicMediaDecoder - example that comes with the Android SDK: - - \code - import qbs - - AndroidApk { - name: "Basic Media Decoder" - packageName: "com.example.android.basicmediadecoder" - - property string sourcesPrefix: "Application/src/main/" - - resourcesDir: sourcesPrefix + "/res" - sourcesDir: sourcesPrefix + "/java" - manifestFile: sourcesPrefix + "/AndroidManifest.xml" - } - \endcode -*/ - -/*! - \qmlproperty path AndroidApk::assetsDir - - The base directory for Android assets. - - \note Android requires that the file name of this directory is always - \c "assets". - - \defaultvalue \c "assets" -*/ - -/*! - \qmlproperty bool AndroidApk::automaticSources - - If \c true, Java sources as well as Android resources, assets, and the - manifest file will be automatically included in the product via wildcards. - Set this property to \c false if you want to specify these files manually. - - \defaultvalue \c true -*/ - -/*! - \qmlproperty path AndroidApk::manifestFile - - The file path to the Android manifest file. - - \note Android requires that the file name is always "AndroidManifest.xml". - - \defaultvalue \c "AndroidManifest.xml" -*/ - -/*! - \qmlproperty string AndroidApk::packageName - - The package name as given in the manifest file. - - \defaultvalue \c name -*/ - -/*! - \qmlproperty path AndroidApk::resourcesDir - - The base directory for Android resources. - - \note Android requires that the file name of this directory is always - \c "res". - - \defaultvalue \c "res" -*/ - -/*! - \qmlproperty path AndroidApk::sourcesDir - - The base directory for Java sources. This property is only relevant if - \l automaticSources is enabled. - - \defaultvalue \c "src" -*/ diff --git a/doc/reference/items/convenience/appleapplicationdiskimage.qdoc b/doc/reference/items/convenience/appleapplicationdiskimage.qdoc index d8011d66a..69a10c797 100644 --- a/doc/reference/items/convenience/appleapplicationdiskimage.qdoc +++ b/doc/reference/items/convenience/appleapplicationdiskimage.qdoc @@ -26,7 +26,6 @@ ****************************************************************************/ /*! \contentspage list-of-convenience-items.html - \previouspage AndroidApk \nextpage AppleDiskImage \qmltype AppleApplicationDiskImage \since Qbs 1.9 @@ -51,8 +50,6 @@ Here is what the project file could look like for a simple DMG installer: \code - import qbs - AppleApplicationDiskImage { Depends { name: "myapp" } name: "My App" diff --git a/doc/reference/items/convenience/application.qdoc b/doc/reference/items/convenience/application.qdoc index de2bbae48..c09d15918 100644 --- a/doc/reference/items/convenience/application.qdoc +++ b/doc/reference/items/convenience/application.qdoc @@ -36,12 +36,34 @@ \brief Product of the type application. - An Application item is a \l{Product} of the \l{Product::}{type} - \c "application". + An Application item is a \l{Product} representing an application. - It exists for the convenience of project file authors. + The target artifact of this type of product is usually an executable binary + tagged \c "application". + However, on Android, unless you set \l{Product::}{consoleApplication} to \c true, + the application target will be an APK package tagged \c "android.apk", and a + dependency to the \l{Android.sdk} module is automatically added to the product. +*/ + +/*! + \qmlproperty bool Application::install + + If \c{true}, the executable that is produced when building the application will be installed + to \l installDir. + + \defaultvalue \c false + \since Qbs 1.13 +*/ + +/*! + \qmlproperty string Application::installDir + + Where to install the executable that is produced when building the application, if \l install + is enabled. + + The value is appended to \l{qbs::installPrefix}{qbs.installPrefix} + when constructing the actual installation directory. - \note On Android, an Application item instead builds a shared library for - products whose \l{Product::}{consoleApplication} property is set to - \c false. + \defaultvalue \c Applications if the app is a \l{bundle::isBundle}{bundle}, \c bin otherwise. + \since Qbs 1.13 */ diff --git a/doc/reference/items/convenience/autotestrunner.qdoc b/doc/reference/items/convenience/autotestrunner.qdoc index f4861835b..defb2814e 100644 --- a/doc/reference/items/convenience/autotestrunner.qdoc +++ b/doc/reference/items/convenience/autotestrunner.qdoc @@ -73,6 +73,8 @@ \qmlproperty stringList AutotestRunner::arguments The list of arguments to invoke the autotest with. + A test can override this by setting the \l{autotest::arguments}{arguments} property + of the \l autotest module. \defaultvalue \c [] */ @@ -114,6 +116,8 @@ If this property is set, it will be the working directory for all invoked test executables. Otherwise, the working directory will the the parent directory of the respective executable. + A test can override this by setting the \l{autotest::workingDir}{workingDir} property + of the \l autotest module. \nodefaultvalue \since Qbs 1.12 diff --git a/doc/reference/items/convenience/dynamiclibrary.qdoc b/doc/reference/items/convenience/dynamiclibrary.qdoc index 27aa978d1..488aef3eb 100644 --- a/doc/reference/items/convenience/dynamiclibrary.qdoc +++ b/doc/reference/items/convenience/dynamiclibrary.qdoc @@ -38,7 +38,7 @@ \brief Dynamic library. A DynamicLibrary item is a \l{Product} of the \l{Product::}{type} - \c "dynamiclibrary". It exists for the convenience of project file authors. + \c "dynamiclibrary". For Android targets, the following applies: \list @@ -48,3 +48,50 @@ \endlist */ +/*! + \qmlproperty bool DynamicLibrary::install + + If \c{true}, the library will be installed to \l installDir. + + \defaultvalue \c false + \since Qbs 1.13 +*/ + +/*! + \qmlproperty string DynamicLibrary::installDir + + Where to install the library, if \l install is enabled. On Unix, the symbolic links + are also installed to this location. + + The value is appended to \l{qbs::installPrefix}{qbs.installPrefix} + when constructing the actual installation directory. + + \defaultvalue \c Library/Frameworks if the library is a \l{bundle::isBundle}{bundle}, + otherwise \c bin for Windows and \c lib for Unix-like targets. + \since Qbs 1.13 +*/ + +/*! + \qmlproperty bool DynamicLibrary::installImportLib + + If \c{true}, the import library will be installed to \l importLibInstallDir. + This property is only relevant for Windows targets. + Enable it if you want to create a development package. + + \defaultvalue \c false + \since Qbs 1.13 +*/ + +/*! + \qmlproperty string DynamicLibrary::importLibInstallDir + + Where to install the import library, if \l installImportLib is enabled. + + The value is appended to \l{qbs::installPrefix}{qbs.installPrefix} + when constructing the actual installation directory. + + This property is only relevant for Windows targets. + + \defaultvalue \c lib + \since Qbs 1.13 +*/ diff --git a/doc/reference/items/convenience/qtguiapplication.qdoc b/doc/reference/items/convenience/qtguiapplication.qdoc index 09b8514f5..e69b9214c 100644 --- a/doc/reference/items/convenience/qtguiapplication.qdoc +++ b/doc/reference/items/convenience/qtguiapplication.qdoc @@ -37,15 +37,5 @@ \brief Application with a dependency on the Qt GUI module. A QtGuiApplication is an application that extends the \l{QtApplication} item - by loading the \l{Qt.gui} module and possibly also the default - QPA plugin. -*/ - -/*! - \qmlproperty bool QtGuiApplication::linkDefaultQpaPlugin - - Whether or not to add a depencency to the default QPA plugin. The default is - to do that in the case of a static build, where it is normally required. - - \defaultvalue \l{Qt.core::staticBuild}{Qt.core.staticBuild} + by loading the \l{Qt.gui} module. */ diff --git a/doc/reference/items/convenience/staticlibrary.qdoc b/doc/reference/items/convenience/staticlibrary.qdoc index a7a94cc43..cd459cf6e 100644 --- a/doc/reference/items/convenience/staticlibrary.qdoc +++ b/doc/reference/items/convenience/staticlibrary.qdoc @@ -37,11 +37,27 @@ \brief Static library. A StaticLibrary item is a \l{Product}{product} of the \l{Product::}{type} - \c "staticlibrary" that is normally entirely equivalent to the following: + \c "staticlibrary". +*/ + +/*! + \qmlproperty bool StaticLibrary::install + + If \c{true}, the library will be installed to \l installDir. + + \defaultvalue \c false + \since Qbs 1.13 +*/ + +/*! + \qmlproperty string StaticLibrary::installDir + + Where to install the library, if \l install is enabled. + + The value is appended to \l{qbs::installPrefix}{qbs.installPrefix} + when constructing the actual installation directory. - \code - Product { - type: "staticlibrary" - } - \endcode + \defaultvalue \c Library/Frameworks if the library is a \l{bundle::isBundle}{bundle}, + \c lib otherwise. + \since Qbs 1.13 */ diff --git a/doc/reference/items/language/group.qbs b/doc/reference/items/language/group.qbs index 4b478bfa5..c6bbae875 100644 --- a/doc/reference/items/language/group.qbs +++ b/doc/reference/items/language/group.qbs @@ -28,8 +28,6 @@ ** ****************************************************************************/ -import qbs 1.0 - Project { Product { //! [0] diff --git a/doc/reference/items/language/group.qdoc b/doc/reference/items/language/group.qdoc index dae647060..caeffcfaa 100644 --- a/doc/reference/items/language/group.qdoc +++ b/doc/reference/items/language/group.qdoc @@ -28,7 +28,7 @@ /*! \contentspage list-of-language-items.html \previouspage FileTagger - \nextpage Module + \nextpage JobLimit \qmltype Group \inqmlmodule QbsLanguageItems \ingroup list-of-items diff --git a/doc/reference/items/language/joblimit.qdoc b/doc/reference/items/language/joblimit.qdoc new file mode 100644 index 000000000..66697ba3e --- /dev/null +++ b/doc/reference/items/language/joblimit.qdoc @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ +/*! + \contentspage list-of-language-items.html + \previouspage Group + \nextpage Module + \qmltype JobLimit + \inqmlmodule QbsLanguageItems + \ingroup list-of-items + \keyword QML.JobLimit + + \brief Restricts concurrent execution of jobs in a given pool. + + In addition to the global limit on concurrently running commands, a project might + want to restrict concurrent execution of certain types of commands even further, + for instance because they are not well-suited to share certain types of resources. + + In the following example, we define a rule that runs a tool of which at most one + instance can be running for the same project at any given time: + \code + Rule { + // ... + prepare: { + var cmd = new Command("my-exclusive-tool", [project.buildDirectory]); + cmd.description = "running the exclusive tool"; + cmd.jobPool = "exclusive_tool"; + return cmd; + } + } + JobLimit { + jobPool: "exclusive_tool" + jobCount: 1 + } + \endcode + + \c JobLimit items can appear inside \l Product, \l Project and \l Module items. + In the case of collisions, that is, items matching the same job pool but setting + different values, the ones defined inside products have the highest precedence, + and the ones inside modules have the lowest. Items defined in sub-projects have + higher precedence than those defined in parent projects. For items with the same + precedence level, the most restrictive one is chosen, that is, the one with the + lowest job number greater than zero. + + \see {How do I limit the number of concurrent jobs for the linker only?} +*/ + +/*! + \qmlproperty bool JobLimit::condition + + Determines whether the job limit is active. + + If this property is set to \c false, the job limit is ignored. + + \defaultvalue \c true +*/ + +/*! + \qmlproperty string JobLimit::jobCount + + The maximum number of commands in the given \l{jobPool}{job pool} that can run + concurrently. + + A value of zero means "unlimited", negative values are not allowed. + + \note The global job limit always applies: For instance, if you set this + property to 100 for some job pool, and "-j 8" was given on the + command line, then no more than eight instances of commands from + the respective job pool will run at any time. + + This property must always be set. + + \nodefaultvalue +*/ + +/*! + \qmlproperty string JobLimit::jobPool + + The job pool to which apply the limit. + + This property must always be set to a non-empty value. + + \nodefaultvalue +*/ diff --git a/doc/reference/items/language/module.qdoc b/doc/reference/items/language/module.qdoc index fb2238e0c..e5472983f 100644 --- a/doc/reference/items/language/module.qdoc +++ b/doc/reference/items/language/module.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! \contentspage list-of-language-items.html - \previouspage Group + \previouspage JobLimit \nextpage Parameter \qmltype Module \inqmlmodule QbsLanguageItems @@ -41,7 +41,6 @@ characters from them. The module's name is \c{txt_processor}. \code - import qbs import qbs.FileInfo import qbs.TextFile diff --git a/doc/reference/modules/android-ndk-module.qdoc b/doc/reference/modules/android-ndk-module.qdoc index 529f2fb4d..8113a7c68 100644 --- a/doc/reference/modules/android-ndk-module.qdoc +++ b/doc/reference/modules/android-ndk-module.qdoc @@ -34,29 +34,21 @@ \brief Provides support for building native Android libraries. The \c Android.ndk module contains the properties and rules to create native libraries - for use in \l{AndroidApk}{Android application packages}. + for use in Android applications. Normally, you will not use this module directly, but instead work - with the \l{DynamicLibrary} and \l{StaticLibrary} items that \QBS provides. + with the \l{DynamicLibrary}, \l{StaticLibrary} and \l Application items + that \QBS provides. Here is what the project file for the \c hello-jni example that comes with the NDK could look like: \code - import qbs - - Project { - DynamicLibrary { - name: "hello-jni" - qbs.architectures: ["mips", "x86"] - files: ["jni/hello-jni.c"] - } - - AndroidApk { - name: "HelloJni" - packageName: "com.example.hellojni" - Depends { productTypes: ["android.nativelibrary"] } - } + CppApplication { + name: "HelloJni" + Android.sdk.packageName: "com.example.hellojni" + qbs.architectures: ["mips", "x86"] + files: "app/src/main/jni/hello-jni.c" } \endcode diff --git a/doc/reference/modules/android-sdk-module.qdoc b/doc/reference/modules/android-sdk-module.qdoc index bad547311..a9e06ae17 100644 --- a/doc/reference/modules/android-sdk-module.qdoc +++ b/doc/reference/modules/android-sdk-module.qdoc @@ -35,9 +35,7 @@ The Android.sdk module contains the properties and rules to create Android application packages from Java sources, resources, and so on. - - Normally, you will not use this module directly, but instead work - with the \l{AndroidApk} item that \QBS provides. + It is usually pulled in indirectly by declaring an \l Application product. \section2 Relevant File Tags \target filetags-android-sdk @@ -59,14 +57,8 @@ \li - \li 1.4.0 \li Attached to Android assets, which are typically located in an - \c{assets/} subdirectory. Using the \l{AndroidApk} item takes care - of tagging these files for you. - \row - \li \c{"android.apk"} - \li n/a - \li 1.4.0 - \li Attached to the output artifact of the rule that creates an APK - package. It is the default type of the \l{AndroidApk} item. + \c{assets/} subdirectory. These files are tagged automatically + if the \l automaticSources property is enabled. \row \li \c{"android.manifest"} \li \c{AndroidManifest.xml} @@ -78,8 +70,8 @@ \li - \li 1.4.0 \li Attached to Android resources, which are typically located in a - \c{res/} subdirectory. Using the \l{AndroidApk} item takes care of - tagging these files for you. + \c{res/} subdirectory. These files are tagged automatically + if the \l automaticSources property is enabled. \endtable */ @@ -125,3 +117,79 @@ \defaultvalue \c{true} */ + +/*! + \qmlproperty string Android.sdk::assetsDir + + The base directory for Android assets in the respective product. + + \note Android requires that the file name of this directory is always + \c "assets". + + \defaultvalue \c "src/main/assets" in the product source directory +*/ + +/*! + \qmlproperty bool Android.sdk::automaticSources + + If \c true, Java sources as well as Android resources, assets, and the + manifest file will be automatically included in the respective product + via wildcards. Set this property to \c false if you want to specify + these files manually. + + \defaultvalue \c true +*/ + +/*! + \qmlproperty string Android.sdk::manifestFile + + The file path to the Android manifest file. + This property is only relevant if \l automaticSources is enabled. + + \note Android requires that the file name is always "AndroidManifest.xml". + + \defaultvalue \c "src/main/AndroidManifest.xml" in the product source directory +*/ + +/*! + \qmlproperty string Android.sdk::packageName + + The package name of the respective product. The \c package attribute in the manifest file + will be set to this value automatically. + + \defaultvalue \c name +*/ + +/*! + \qmlproperty string Android.sdk::resourcesDir + + The base directory for Android resources in the respective product. + + \note Android requires that the file name of this directory is always + \c "res". + + \defaultvalue \c "src/main/res" in the product source directory +*/ + +/*! + \qmlproperty path Android.sdk::sourcesDir + + The base directory for Java sources. This property is only relevant if + \l automaticSources is enabled. + + \defaultvalue \c "src/main/java" in the product source directory +*/ + +/*! + \qmlproperty string Android.sdk::apkBaseName + + The base name of the APK file to to be built, that is, the file name + without the ".apk" extension. + + \defaultvalue \l packageName +*/ + +/*! + \qmlproperty stringList Android.sdk::aidlSearchPaths + Search paths for import statements to pass to the \c aidl tool via the \c{-I} option. +*/ diff --git a/doc/reference/modules/autotest-module.qdoc b/doc/reference/modules/autotest-module.qdoc new file mode 100644 index 000000000..ddd9e0078 --- /dev/null +++ b/doc/reference/modules/autotest-module.qdoc @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \contentspage index.html + \qmltype autotest + \inqmlmodule QbsModules + \since Qbs 1.13 + + \brief Allows to fine-tune autotest execution. + + The \c autotest module provides properties that allow autotest applications to specify + how exactly they should be run. +*/ + +/*! + \qmlproperty bool autotest::allowFailure + + Autotests for which this property is \c true can return a non-zero exit code without + causing the entire \l AutotestRunner to fail. Use this for tests that are known + to be unreliable. + + \defaultvalue \c false +*/ + +/*! + \qmlproperty stringList autotest::arguments + + The list of arguments to invoke the autotest with. If not specified, then + the \l{AutotestRunner::arguments}{arguments} property of the + \l AutotestRunner that invokes the autotest is used. + + \nodefaultvalue +*/ + +/*! + \qmlproperty string autotest::workingDir + + The working directory for running the autotest. If not specified, then + the \l{AutotestRunner::workingDir}{workingDir} property of the + \l AutotestRunner that invokes the autotest is used. + + \nodefaultvalue +*/ + diff --git a/doc/reference/modules/cpp-module.qdoc b/doc/reference/modules/cpp-module.qdoc index 0818af28d..bf1080dd7 100644 --- a/doc/reference/modules/cpp-module.qdoc +++ b/doc/reference/modules/cpp-module.qdoc @@ -150,6 +150,14 @@ \li The rule that creates dynamic libraries (typically via a linker) attaches this tag to its output artifact. \row + \li \c{"dynamiclibrary_import"} + \li n/a + \li 1.0.0 + \li This tag is used for import libraries of dynamic libraries. For + example, the MSVC linker rule creates a \c{dynamiclibrary_import} + artifact \c{foo.lib} in addition to a \c{dynamiclibrary} artifact + \c{foo.dll}. + \row \li \c{"hpp"} \li \c{*.h}, \c{*.H}, \c{*.hpp}, \c{*.hxx}, \c{*.h++} \li 1.0.1 @@ -217,6 +225,31 @@ This file tag only has an effect with GCC-like toolchains. The linker needs to be \c{ld}-compatible. \endtable + + \section2 Relevant Job Pools + \target cpp-job-pools + + \table + \header + \li Pool + \li Since + \li Description + \row + \li \c{"assembler"} + \li 1.13 + \li The job pool used by rules that run the toolchain's assembler. This is only + relevant for direct invocations of the assembler binary, not for running it + indirectly via the compiler. + \row + \li \c{"compiler"} + \li 1.13 + \li The job pool used by rules that run a compiler. All language variants use + the same pool. + \row + \li \c{"linker"} + \li 1.13 + \li The job pool used by rules that run a linker. + \endtable */ /*! diff --git a/doc/reference/modules/protobufcpp-module.qdoc b/doc/reference/modules/protobufcpp-module.qdoc new file mode 100644 index 000000000..688f1d9e2 --- /dev/null +++ b/doc/reference/modules/protobufcpp-module.qdoc @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \contentspage index.html + \qmltype protobuf.cpp + \inqmlmodule QbsModules + \since Qbs 1.13 + + \brief Provides support for protocol buffers for the C++ language. + + The \c protobuf.cpp module provides support for generating C++ headers + and sources from proto definition files using the \l protoc tool. + + \section2 Relevant File Tags + + \table + \header + \li Tag + \li Auto-tagged File Names + \li Since + \li Description + \row + \li \c{"protobuf.input"} + \li \c{*.proto} + \li 1.13.0 + \li Source files with this tag are considered inputs to the \c protoc compiler. + \endtable +*/ + +/*! + \qmlproperty string protobuf.cpp::protocBinary + + The command to invoke when compiling proto definition files. + + \defaultvalue \c auto-detected +*/ + +/*! + \qmlproperty pathList protobuf.cpp::importPaths + + The list of imports that are passed to the \c protoc tool via the \c --proto_path option. + These imports should contain the proto files. They are used to determine + the relative structure of the generated files. + \note The paths are passed to \c protoc in the same order as specified in this property and + \c protoc output may differ depending on that order. + + \defaultvalue \c [] +*/ + +/*! + \qmlproperty string protobuf.cpp::includePath + + The path where protobuf C++ headers are located. Set this property to override the + default location. + + \defaultvalue \c auto-detected +*/ + +/*! + \qmlproperty string protobuf.cpp::libraryPath + + The path where the protobuf C++ library is located. Set this property to override the + default location. + + \defaultvalue \c auto-detected +*/ diff --git a/doc/reference/modules/protobufobjc-module.qdoc b/doc/reference/modules/protobufobjc-module.qdoc new file mode 100644 index 000000000..07e6db759 --- /dev/null +++ b/doc/reference/modules/protobufobjc-module.qdoc @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \contentspage index.html + \qmltype protobuf.objc + \inqmlmodule QbsModules + \since Qbs 1.13 + + \brief Provides support for protocol buffers for the Objective-C language. + + The \c protobuf.objc module provides support for generating Objective-C + headers and sources from proto definition files using the \l protoc tool. + + \section2 Relevant File Tags + + \table + \header + \li Tag + \li Auto-tagged File Names + \li Since + \li Description + \row + \li \c{"protobuf.input"} + \li \c{*.proto} + \li 1.13.0 + \li Source files with this tag are considered inputs to the \c protoc compiler. + \endtable +*/ + +/*! + \qmlproperty string protobuf.objc::protocBinary + + The command to invoke when compiling proto definition files. + + \defaultvalue \c auto-detected +*/ + +/*! + \qmlproperty pathList protobuf.objc::importPaths + + The list of imports that are passed to the \c protoc tool via the \c --proto_path option. + These imports should contain the proto files. They are used to determine + the relative structure of the generated files. + \note The paths are passed to \c protoc in the same order as specified in this property and + \c protoc output may differ depending on that order. + + \defaultvalue \c [] +*/ + +/*! + \qmlproperty string protobuf.objc::includePath + + The path where protobuf Objective-C headers are located. Set this property + to override the default location. + + \note If frameworkPath is specified, this property has no effect. + + \defaultvalue \c auto-detected +*/ + +/*! + \qmlproperty string protobuf.objc::libraryPath + + \note If frameworkPath is specified, this property has no effect. + + \defaultvalue \c auto-detected +*/ + +/*! + \qmlproperty string protobuf.objc::frameworkPath + + The path where \c Protobuf.framework is located. Set this property to override the + default location. + + \defaultvalue \c auto-detected +*/ diff --git a/doc/reference/modules/qt-android_support-module.qdoc b/doc/reference/modules/qt-android_support-module.qdoc new file mode 100644 index 000000000..f7ec595e3 --- /dev/null +++ b/doc/reference/modules/qt-android_support-module.qdoc @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \contentspage index.html + \qmltype Qt.android_support + \inqmlmodule QbsModules + \brief Provides Qt support for the Android platform. + + The \c Qt.android_support module provides the glue for \QBS' + Qt and Android support. + It is automatically pulled in by \c Qt.core, so you do not need to + add an explicit dependency to it in your product, unless you want + to set one of its properties. +*/ + +/*! + \qmlproperty bool Qt.android_support::useMinistro + + Whether or not to use the Ministro service. If this property is enabled, then + the Qt libraries required by your application as well as some other resources + will not be packaged into the APK file, but are expected to be present on the + device at run time. + + \defaultvalue \c false +*/ + +/*! + \qmlproperty string Qt.android_support::qmlRootDir + + The root directory of the product's QML files. This information is passed to + the \c androiddeployqt tool, which will use it to decide which resources to + include in the APK file. + + \defaultvalue \c product.sourceDirectory +*/ + +/*! + \qmlproperty stringList Qt.android_support::deploymentDependencies + + Use this property to completely override the Qt deployment dependencies + of your app. Corresponds to qmake's ANDROID_DEPLOYMENT_DEPENDENCIES. + + \defaultvalue \c undefined +*/ + +/*! + \qmlproperty stringList Qt.android_support::extraPlugins + + Additional non-asset files to be packaged. Corresponds to qmake's ANDROID_EXTRA_PLUGINS. + + \defaultvalue \c undefined +*/ + +/*! + \qmlproperty bool Qt.android_support::verboseAndroidDeployQt + + Enable this property if you want verbose output from the + \c androiddeployqt tool. + + \defaultvalue \c false +*/ diff --git a/doc/reference/modules/qt-core-module.qdoc b/doc/reference/modules/qt-core-module.qdoc index 6bfa67f19..922b1889b 100644 --- a/doc/reference/modules/qt-core-module.qdoc +++ b/doc/reference/modules/qt-core-module.qdoc @@ -140,6 +140,15 @@ */ /*! + \qmlproperty bool Qt.core::enableBigResources + + Whether the Qt resource compiler is run in a two-pass fashion that supports + the creation of big resources. + + \defaultvalue \c{false} +*/ + +/*! \qmlproperty stringList Qt.core::config Corresponds to the default value of qmake's \c CONFIG variable. diff --git a/doc/reference/modules/qt-modules.qdoc b/doc/reference/modules/qt-modules.qdoc index c86c9cca6..638160104 100644 --- a/doc/reference/modules/qt-modules.qdoc +++ b/doc/reference/modules/qt-modules.qdoc @@ -98,7 +98,7 @@ \row \li \l{Qt.gui}{gui} \li Qt GUI - \li For more information , see \l {Qt.gui}. + \li For more information, see \l {Qt.gui}. \row \li help \li Qt Help @@ -139,6 +139,10 @@ \li Qt QML \li For more information, see \l{Qt.qml}. \row + \li qmltest + \li Qt Quick Test + \li + \row \li script \li Qt Script \li diff --git a/doc/reference/modules/qt-plugin_support-module.qdoc b/doc/reference/modules/qt-plugin_support-module.qdoc new file mode 100644 index 000000000..fe28ee907 --- /dev/null +++ b/doc/reference/modules/qt-plugin_support-module.qdoc @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \contentspage index.html + \qmltype Qt.plugin_support + \inqmlmodule QbsModules + \since Qbs 1.13.0 + \brief Allows to fine-tune which Qt plugins get pulled in. + + The \c Qt.plugin_support module provides properties that allow users to control + which Qt plugins to pull into a product. + This is mostly relevant if Qt was built statically, in which case the respective + plugins are static libraries that get linked into your application or library. +*/ + +/*! + \qmlproperty varList Qt.plugin_support::pluginsByType + + Set this property if you want to override the set of plugins for a certain + plugin type. For instance, to disable all image plugins except the JPEG + one: + \code + Qt.plugin_support.pluginsByType: ({imageformats: "qjpeg"}) + \endcode + For plugin types that are not specifically overridden like this, the value in + defaultPluginsByType is used. + + \nodefaultvalue +*/ + +/*! + \qmlproperty var Qt.plugin_support::allPluginsByType + + Provides the complete set of plugins in a statically built Qt. + The value is a map. The keys are the plugin types, and the values + are lists of plugin names. + + \readonly +*/ + +/*! + \qmlproperty var Qt.plugin_support::defaultPluginsByType + + Provides the set of plugins that your application or library will + link to if you do not set pluginsByType. + The value is a map. The keys are the plugin types, and the values + are lists of plugin names. + The value depends on the Qt modules your product pulls in. + + \readonly +*/ + diff --git a/doc/reference/modules/texttemplate-module.qdoc b/doc/reference/modules/texttemplate-module.qdoc new file mode 100644 index 000000000..7d0c47a6d --- /dev/null +++ b/doc/reference/modules/texttemplate-module.qdoc @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \contentspage index.html + \qmltype texttemplate + \inqmlmodule QbsModules + \since Qbs 1.13 + + \brief Provides support for text template files + + The \c texttemplate module provides support for text template files. + + \section2 Example + + Consider the following text file \e{greeting.txt.in}. + + \code + ${greeting} ${name}! + \endcode + + This can be used in a project like this: + + \code + Product { + type: ["text"] + files: ["greeting.txt.in"] + Depends { name: "texttemplate" } + texttemplate.dict: ({ + greeting: "Hello", + name: "World" + }) + } + \endcode + + Which will create the file \e{greeting.txt}. + + \code + Hello World! + \endcode + + + \section2 Placeholder Syntax + + A placeholder \c{${foo}} is replaced by its corresponding value in + \e{texttemplate.dict}. + Placeholder names consist of alphanumeric characters only. + + The placeholder \c{${$}} is always replaced with \c{$}. + If you need a literal \c{${foo}} in your template, use \c{${$}{foo}}. + + Placeholders that are not defined in the dictionary will produce an error. + + + \section2 Relevant File Tags + \target filetags-texttemplate + + \table + \header + \li Tag + \li Auto-tagged File Names + \li Since + \li Description + \row + \li \c{"texttemplate.input"} + \li \c{*.in} + \li 1.13.0 + \li Source files with this tag serve as inputs for the text template rule. + \endtable +*/ + +/*! + \qmlproperty var texttemplate::dict + + The dictionary containing values for all keys used in the template file. + + \defaultvalue \c{{}} +*/ + +/*! + \qmlproperty string texttemplate::outputFileName + + The output file name that is assigned to produced artifacts. + + \defaultvalue Complete base name of the input file +*/ + +/*! + \qmlproperty string texttemplate::outputTag + + The output tag that is assigned to produced artifacts. + + \defaultvalue \c{"text"} +*/ diff --git a/doc/targets/qbs-target-android.qdoc b/doc/targets/qbs-target-android.qdoc index e5d52337f..46081db0d 100644 --- a/doc/targets/qbs-target-android.qdoc +++ b/doc/targets/qbs-target-android.qdoc @@ -55,11 +55,11 @@ \li Shared libraries containing native code. \endlist - You can use the \l{AndroidApk} item to build application - packages for Android. The properties of the AndroidApk item specify the - locations of the APK source files. + You can use the \l{Application} item to build application + packages for Android. - The AndroidApk item has a dependency on the \l{Android.sdk} module, which + If the \l{qbs::targetPlatform}{target platform} is \c{"android"}, then the Application item has + a dependency on the \l{Android.sdk} module, which contains the properties and rules to create Android application packages from source files. @@ -67,7 +67,11 @@ Android libraries that are bundled into the APK. The \c qbs.architectures property specifies the architectures to build for, with the default value \c armv7a. + If you have only one native library, you can simply list its sources + within the main Application item, and it will get built and packaged + automatically. - The \l{DynamicLibrary} item has a dependency on the \l{Android.ndk} module, + The \l{DynamicLibrary} item, as well as the \l CppApplication item, + has a dependency on the \l{Android.ndk} module, and contains the properties and rules to create native libraries. */ diff --git a/doc/targets/qbs-target-qnx.qdoc b/doc/targets/qbs-target-qnx.qdoc index fc03ce677..c7e28d905 100644 --- a/doc/targets/qbs-target-qnx.qdoc +++ b/doc/targets/qbs-target-qnx.qdoc @@ -48,8 +48,6 @@ \l{qnx::sdkDir}{qnx.sdkDir} property: \code - import qbs - Application { name: "helloworld" files: "main.cpp" diff --git a/doc/templates/images/arrow.png b/doc/templates/images/arrow.png Binary files differdeleted file mode 100644 index f2a83a574..000000000 --- a/doc/templates/images/arrow.png +++ /dev/null diff --git a/doc/templates/images/arrow_down.png b/doc/templates/images/arrow_down.png Binary files differdeleted file mode 100644 index 9d01e97f6..000000000 --- a/doc/templates/images/arrow_down.png +++ /dev/null diff --git a/doc/templates/images/bg_l.png b/doc/templates/images/bg_l.png Binary files differdeleted file mode 100644 index 90b1da10b..000000000 --- a/doc/templates/images/bg_l.png +++ /dev/null diff --git a/doc/templates/images/bg_l_blank.png b/doc/templates/images/bg_l_blank.png Binary files differdeleted file mode 100644 index 5a9673d81..000000000 --- a/doc/templates/images/bg_l_blank.png +++ /dev/null diff --git a/doc/templates/images/bg_ll_blank.png b/doc/templates/images/bg_ll_blank.png Binary files differdeleted file mode 100644 index 95a1c45e0..000000000 --- a/doc/templates/images/bg_ll_blank.png +++ /dev/null diff --git a/doc/templates/images/bg_r.png b/doc/templates/images/bg_r.png Binary files differdeleted file mode 100644 index f0fb121de..000000000 --- a/doc/templates/images/bg_r.png +++ /dev/null diff --git a/doc/templates/images/bg_ul_blank.png b/doc/templates/images/bg_ul_blank.png Binary files differdeleted file mode 100644 index 70512614c..000000000 --- a/doc/templates/images/bg_ul_blank.png +++ /dev/null diff --git a/doc/templates/images/bgrContent.png b/doc/templates/images/bgrContent.png Binary files differdeleted file mode 100644 index 1a81b0308..000000000 --- a/doc/templates/images/bgrContent.png +++ /dev/null diff --git a/doc/templates/images/blu_dot.png b/doc/templates/images/blu_dot.png Binary files differdeleted file mode 100644 index c332148f7..000000000 --- a/doc/templates/images/blu_dot.png +++ /dev/null diff --git a/doc/templates/images/box_bg.png b/doc/templates/images/box_bg.png Binary files differdeleted file mode 100644 index 3322f923f..000000000 --- a/doc/templates/images/box_bg.png +++ /dev/null diff --git a/doc/templates/images/breadcrumb.png b/doc/templates/images/breadcrumb.png Binary files differdeleted file mode 100644 index 0ded5514d..000000000 --- a/doc/templates/images/breadcrumb.png +++ /dev/null diff --git a/doc/templates/images/btn_next.png b/doc/templates/images/btn_next.png Binary files differdeleted file mode 100644 index f7bc2b717..000000000 --- a/doc/templates/images/btn_next.png +++ /dev/null diff --git a/doc/templates/images/btn_prev.png b/doc/templates/images/btn_prev.png Binary files differdeleted file mode 100644 index 10a620c51..000000000 --- a/doc/templates/images/btn_prev.png +++ /dev/null diff --git a/doc/templates/images/bullet_dn.png b/doc/templates/images/bullet_dn.png Binary files differdeleted file mode 100644 index f7762472e..000000000 --- a/doc/templates/images/bullet_dn.png +++ /dev/null diff --git a/doc/templates/images/bullet_gt.png b/doc/templates/images/bullet_gt.png Binary files differdeleted file mode 100644 index 7561b4edc..000000000 --- a/doc/templates/images/bullet_gt.png +++ /dev/null diff --git a/doc/templates/images/bullet_sq.png b/doc/templates/images/bullet_sq.png Binary files differdeleted file mode 100644 index a84845e3c..000000000 --- a/doc/templates/images/bullet_sq.png +++ /dev/null diff --git a/doc/templates/images/bullet_up.png b/doc/templates/images/bullet_up.png Binary files differdeleted file mode 100644 index 7de2f0695..000000000 --- a/doc/templates/images/bullet_up.png +++ /dev/null diff --git a/doc/templates/images/feedbackground.png b/doc/templates/images/feedbackground.png Binary files differdeleted file mode 100644 index 3a38d995d..000000000 --- a/doc/templates/images/feedbackground.png +++ /dev/null diff --git a/doc/templates/images/header.png b/doc/templates/images/header.png Binary files differdeleted file mode 100644 index 3c68d9c52..000000000 --- a/doc/templates/images/header.png +++ /dev/null diff --git a/doc/templates/images/header_bg.png b/doc/templates/images/header_bg.png Binary files differdeleted file mode 100644 index a436aa61e..000000000 --- a/doc/templates/images/header_bg.png +++ /dev/null diff --git a/doc/templates/images/home.png b/doc/templates/images/home.png Binary files differdeleted file mode 100644 index 8de6d0c81..000000000 --- a/doc/templates/images/home.png +++ /dev/null diff --git a/doc/templates/images/horBar.png b/doc/templates/images/horBar.png Binary files differdeleted file mode 100644 index 100fe91c6..000000000 --- a/doc/templates/images/horBar.png +++ /dev/null diff --git a/doc/templates/images/ico_note.png b/doc/templates/images/ico_note.png Binary files differdeleted file mode 100644 index 13794046c..000000000 --- a/doc/templates/images/ico_note.png +++ /dev/null diff --git a/doc/templates/images/ico_note_attention.png b/doc/templates/images/ico_note_attention.png Binary files differdeleted file mode 100644 index b85b696b1..000000000 --- a/doc/templates/images/ico_note_attention.png +++ /dev/null diff --git a/doc/templates/images/ico_out.png b/doc/templates/images/ico_out.png Binary files differdeleted file mode 100644 index ff6e458fb..000000000 --- a/doc/templates/images/ico_out.png +++ /dev/null diff --git a/doc/templates/images/page.png b/doc/templates/images/page.png Binary files differdeleted file mode 100644 index 1db151bd3..000000000 --- a/doc/templates/images/page.png +++ /dev/null diff --git a/doc/templates/images/page_bg.png b/doc/templates/images/page_bg.png Binary files differdeleted file mode 100644 index 9b3bd999d..000000000 --- a/doc/templates/images/page_bg.png +++ /dev/null diff --git a/doc/templates/images/qt_icon.png b/doc/templates/images/qt_icon.png Binary files differdeleted file mode 100644 index fbaee3584..000000000 --- a/doc/templates/images/qt_icon.png +++ /dev/null diff --git a/doc/templates/images/spinner.gif b/doc/templates/images/spinner.gif Binary files differdeleted file mode 100644 index 1ed786f2e..000000000 --- a/doc/templates/images/spinner.gif +++ /dev/null diff --git a/doc/templates/images/sprites-combined.png b/doc/templates/images/sprites-combined.png Binary files differdeleted file mode 100644 index 3a48b21f6..000000000 --- a/doc/templates/images/sprites-combined.png +++ /dev/null diff --git a/doc/templates/scripts/functions.js b/doc/templates/scripts/functions.js deleted file mode 100644 index 1d3c153f8..000000000 --- a/doc/templates/scripts/functions.js +++ /dev/null @@ -1,194 +0,0 @@ -/* START non link areas where cursor should change to pointing hand */ -$('.t_button').mouseover(function() { - $('.t_button').css('cursor','pointer'); - /*document.getElementById(this.id).style.cursor='pointer';*/ -}); -/* END non link areas */ -$('#smallA').click(function() { - $('.content .heading,.content h1, .content h2, .content h3, .content p, .content li, .content table').css('font-size','smaller'); - $('.t_button').removeClass('active') - $(this).addClass('active') -}); - -$('#medA').click(function() { - $('.content .heading').css('font','600 16px/1 Arial'); - $('.content h1').css('font','600 18px/1.2 Arial'); - $('.content h2').css('font','600 16px/1.2 Arial'); - $('.content h3').css('font','600 14px/1.2 Arial'); - $('.content p').css('font','13px/20px Verdana'); - $('.content li').css('font','400 13px/1 Verdana'); - $('.content li').css('line-height','14px'); - $('.content .toc li').css('font', 'normal 10px/1.2 Verdana'); - $('.content table').css('font','13px/1.2 Verdana'); - $('.content .heading').css('font','600 16px/1 Arial'); - $('.content .indexboxcont li').css('font','600 13px/1 Verdana'); - $('.t_button').removeClass('active') - $(this).addClass('active') -}); - -$('#bigA').click(function() { - $('.content .heading,.content h1, .content h2, .content h3, .content p, .content li, .content table').css('font-size','large'); - $('.content .heading,.content h1, .content h2, .content h3, .content p, .content li, .content table').css('line-height','25px'); - $('.t_button').removeClass('active') - $(this).addClass('active') -}); - -$('.feedclose').click(function() { - $('.bd').show(); - $('.hd').show(); - $('.footer').show(); - $('#feedbackBox').hide(); - $('#blurpage').hide(); -}); - -$('.feedback').click(function() { - $('.bd').hide(); - $('.hd').hide(); - $('.footer').hide(); - $('#feedbackBox').show(); - $('#blurpage').show(); -}); -var lookupCount = 0; -var articleCount = 0; -var exampleCount = 0; -var qturl = ""; // change from "http://doc.qt.nokia.com/4.6/" to 0 so we can have relative links - -function processDigiaData(response){ - var propertyTags = response.getElementsByTagName('page'); - - for (var i=0; i< propertyTags.length; i++) { - var linkStart = "<li class=\"liveResult\"><a href='"+qturl+""; - var linkEnd = "</a></li>"; - - if(propertyTags[i].getElementsByTagName('pageType')[0].firstChild.nodeValue == 'APIPage'){ - lookupCount++; - - for (var j=0; j< propertyTags[i].getElementsByTagName('pageWords').length; j++){ - full_li_element = linkStart + propertyTags[i].getElementsByTagName('pageUrl')[j].firstChild.nodeValue; - full_li_element = full_li_element + "'>" + propertyTags[i].getElementsByTagName('pageTitle')[0].firstChild.nodeValue + linkEnd; - $('#ul001').append(full_li_element); - $('#ul001 .defaultLink').css('display','none'); - - } - } - - if(propertyTags[i].getElementsByTagName('pageType')[0].firstChild.nodeValue == 'Article'){ - articleCount++; - - for (var j=0; j< propertyTags[i].getElementsByTagName('pageWords').length; j++){ - full_li_element = linkStart + propertyTags[i].getElementsByTagName('pageUrl')[j].firstChild.nodeValue; - full_li_element =full_li_element + "'>" + propertyTags[i].getElementsByTagName('pageTitle')[0].firstChild.nodeValue + linkEnd ; - - $('#ul002').append(full_li_element); - $('#ul002 .defaultLink').css('display','none'); - - } - } - if(propertyTags[i].getElementsByTagName('pageType')[0].firstChild.nodeValue == 'Example'){ - exampleCount++; - - - for (var j=0; j< propertyTags[i].getElementsByTagName('pageWords').length; j++){ - full_li_element = linkStart + propertyTags[i].getElementsByTagName('pageUrl')[j].firstChild.nodeValue; - full_li_element =full_li_element + "'>" + propertyTags[i].getElementsByTagName('pageTitle')[0].firstChild.nodeValue + linkEnd ; - - $('#ul003').append(full_li_element); - $('#ul003 .defaultLink').css('display','none'); - - } - } - if(i==propertyTags.length){$('#pageType').removeClass('loading');} - - } - if(lookupCount > 0){$('#ul001 .menuAlert').remove();$('#ul001').prepend('<li class=\"menuAlert liveResult hit\">Found ' + lookupCount + ' hits</li>');$('#ul001 li').css('display','block');$('.sidebar .search form input').removeClass('loading');} - if(articleCount > 0){$('#ul002 .menuAlert').remove();$('#ul002').prepend('<li class=\"menuAlert liveResult hit\">Found ' + articleCount + ' hits</li>');$('#ul002 li').css('display','block');} - if(exampleCount > 0){$('#ul003 .menuAlert').remove();$('#ul003').prepend('<li class=\"menuAlert liveResult hit\">Found ' + articleCount + ' hits</li>');$('#ul003 li').css('display','block');} - - if(lookupCount == 0){$('#ul001 .menuAlert').remove();$('#ul001').prepend('<li class=\"menuAlert liveResult noMatch\">Found no result</li>');$('#ul001 li').css('display','block');$('.sidebar .search form input').removeClass('loading');} - if(articleCount == 0){$('#ul002 .menuAlert').remove();$('#ul002').prepend('<li class=\"menuAlert liveResult noMatch\">Found no result</li>');$('#ul002 li').css('display','block');} - if(exampleCount == 0){$('#ul003 .menuAlert').remove();$('#ul003').prepend('<li class=\"menuAlert liveResult noMatch\">Found no result</li>');$('#ul003 li').css('display','block');} - // reset count variables; - lookupCount=0; - articleCount = 0; - exampleCount = 0; - -} -//build regular expression object to find empty string or any number of blank -var blankRE=/^\s*$/; -function CheckEmptyAndLoadList() -{ - var pageUrl = window.location.href; - var pageVal = $('title').html(); - $('#feedUrl').remove(); - $('#pageVal').remove(); - $('.menuAlert').remove(); - $('#feedform').append('<input id="feedUrl" name="feedUrl" value="'+pageUrl+'" style="display:none;">'); - $('#feedform').append('<input id="pageVal" name="pageVal" value="'+pageVal+'" style="display:none;">'); - $('.liveResult').remove(); - $('.defaultLink').css('display','block'); - var value = document.getElementById('pageType').value; - if((blankRE.test(value)) || (value.length < 3)) - { - //empty inputbox - // load default li elements into the ul if empty - // loadAllList(); // replaced - $('.defaultLink').css('display','block'); - // $('.liveResult').css('display','none'); - }else{ - $('.defaultLink').css('display','none'); - } -} -/* -$(window).resize(function(){ -if($(window).width()<400) - $('body').addClass('offline'); -else - $('body').removeClass('offline'); - }); - */ -// Loads on doc ready - $(document).ready(function () { - //alert(pageUrl); - //$('#pageUrl').attr('foo',pageUrl); - var pageTitle = $('title').html(); - var currentString = $('#pageType').val() ; - if(currentString.length < 1){ - $('.defaultLink').css('display','block'); - CheckEmptyAndLoadList(); - } - - $('#pageType').keyup(function () { - var searchString = $('#pageType').val() ; - if ((searchString == null) || (searchString.length < 3)) { - $('#pageType').removeClass('loading'); - $('.liveResult').remove(); - $('.searching').remove(); - CheckEmptyAndLoadList(); - $('.report').remove(); - // debug$('.content').prepend('<li>too short or blank</li>'); // debug - return; - } - if (this.timer) clearTimeout(this.timer); - this.timer = setTimeout(function () { - $('#pageType').addClass('loading'); - $('.searching').remove(); - $('.list ul').prepend('<li class="menuAlert searching">Searching...</li>'); - $.ajax({ - contentType: "application/x-www-form-urlencoded", - url: 'http://' + location.host + '/nokiasearch/GetDataServlet', - data: 'searchString='+searchString, - dataType:'xml', - type: 'post', - success: function (response, textStatus) { - - $('.liveResult').remove(); - $('.searching').remove(); - $('#pageType').removeClass('loading'); - $('.list ul').prepend('<li class="menuAlert searching">Searching...</li>'); - processDigiaData(response); - - } - }); - }, 500); - }); - }); diff --git a/doc/templates/scripts/jquery.js b/doc/templates/scripts/jquery.js deleted file mode 100644 index 0c7294c90..000000000 --- a/doc/templates/scripts/jquery.js +++ /dev/null @@ -1,152 +0,0 @@ -/*! - * jQuery JavaScript Library v1.4.1 - * http://jquery.com/ - * - * Copyright 2010, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2010, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Mon Jan 25 19:43:33 2010 -0500 - */ -(function(z,v){function la(){if(!c.isReady){try{r.documentElement.doScroll("left")}catch(a){setTimeout(la,1);return}c.ready()}}function Ma(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var n in b)X(a,n,b[n],f,e,d);return a}if(d!==v){f=!i&&f&&c.isFunction(d);for(n=0;n<j;n++)e(a[n],b,f?d.call(a[n],n,e(a[n],b)):d,i);return a}return j? -e(a[0],b):null}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function ma(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function na(a){var b,d=[],f=[],e=arguments,i,j,n,o,m,s,x=c.extend({},c.data(this,"events").live);if(!(a.button&&a.type==="click")){for(o in x){j=x[o];if(j.live===a.type||j.altLive&&c.inArray(a.type,j.altLive)>-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete x[o]}i=c(a.target).closest(f, -a.currentTarget);m=0;for(s=i.length;m<s;m++)for(o in x){j=x[o];n=i[m].elem;f=null;if(i[m].selector===j.selector){if(j.live==="mouseenter"||j.live==="mouseleave")f=c(a.relatedTarget).closest(j.selector)[0];if(!f||f!==n)d.push({elem:n,fn:j})}}m=0;for(s=d.length;m<s;m++){i=d[m];a.currentTarget=i.elem;a.data=i.fn.data;if(i.fn.apply(i.elem,e)===false){b=false;break}}return b}}function oa(a,b){return"live."+(a?a+".":"")+b.replace(/\./g,"`").replace(/ /g,"&")}function pa(a){return!a||!a.parentNode||a.parentNode.nodeType=== -11}function qa(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var i in f)for(var j in f[i])c.event.add(this,i,f[i][j],f[i][j].data)}}})}function ra(a,b,d){var f,e,i;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&a[0].indexOf("<option")<0&&(c.support.checkClone||!sa.test(a[0]))){e=true;if(i=c.fragments[a[0]])if(i!==1)f=i}if(!f){b=b&&b[0]?b[0].ownerDocument||b[0]:r;f=b.createDocumentFragment(); -c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=i?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(ta.concat.apply([],ta.slice(0,b)),function(){d[this]=a});return d}function ua(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Na=z.jQuery,Oa=z.$,r=z.document,S,Pa=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Qa=/^.[^:#\[\.,]*$/,Ra=/\S/,Sa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Ta=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,O=navigator.userAgent, -va=false,P=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,Q=Array.prototype.slice,wa=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Pa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:r;if(a=Ta.exec(a))if(c.isPlainObject(b)){a=[r.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ra([d[1]], -[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=r.getElementById(d[2])){if(b.id!==d[2])return S.find(a);this.length=1;this[0]=b}this.context=r;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=r;a=r.getElementsByTagName(a)}else return!b||b.jquery?(b||S).find(a):c(b).find(a);else if(c.isFunction(a))return S.ready(a);if(a.selector!==v){this.selector=a.selector;this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a, -this)},selector:"",jquery:"1.4.1",length:0,size:function(){return this.length},toArray:function(){return Q.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=0;ba.apply(this,a);return this},each:function(a,b){return c.each(this, -a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(r,c);else P&&P.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(Q.apply(this,arguments),"slice",Q.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice}; -c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,n;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(i in e){j=a[i];n=e[i];if(a!==n)if(f&&n&&(c.isPlainObject(n)||c.isArray(n))){j=j&&(c.isPlainObject(j)||c.isArray(j))?j:c.isArray(n)?[]:{};a[i]=c.extend(f,j,n)}else if(n!==v)a[i]=n}return a};c.extend({noConflict:function(a){z.$= -Oa;if(a)z.jQuery=Na;return c},isReady:false,ready:function(){if(!c.isReady){if(!r.body)return setTimeout(c.ready,13);c.isReady=true;if(P){for(var a,b=0;a=P[b++];)a.call(r,c);P=null}c.fn.triggerHandler&&c(r).triggerHandler("ready")}},bindReady:function(){if(!va){va=true;if(r.readyState==="complete")return c.ready();if(r.addEventListener){r.addEventListener("DOMContentLoaded",L,false);z.addEventListener("load",c.ready,false)}else if(r.attachEvent){r.attachEvent("onreadystatechange",L);z.attachEvent("onload", -c.ready);var a=false;try{a=z.frameElement==null}catch(b){}r.documentElement.doScroll&&a&&la()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===v||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false; -return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return z.JSON&&z.JSON.parse?z.JSON.parse(a):(new Function("return "+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Ra.test(a)){var b=r.getElementsByTagName("head")[0]|| -r.documentElement,d=r.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(r.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,i=a.length,j=i===v||c.isFunction(a);if(d)if(j)for(f in a){if(b.apply(a[f],d)===false)break}else for(;e<i;){if(b.apply(a[e++],d)===false)break}else if(j)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d= -a[0];e<i&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Sa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!== -v;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,i=a.length;e<i;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,i=0,j=a.length;i<j;i++){e=b(a[i],i,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=v}else if(b&&!c.isFunction(b)){d=b;b=v}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b}, -uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});O=c.uaMatch(O);if(O.browser){c.browser[O.browser]=true;c.browser.version=O.version}if(c.browser.webkit)c.browser.safari=true;if(wa)c.inArray=function(a,b){return wa.call(b,a)};S=c(r);if(r.addEventListener)L=function(){r.removeEventListener("DOMContentLoaded", -L,false);c.ready()};else if(r.attachEvent)L=function(){if(r.readyState==="complete"){r.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=r.documentElement,b=r.createElement("script"),d=r.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support= -{leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:r.createElement("select").appendChild(r.createElement("option")).selected,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null}; -b.type="text/javascript";try{b.appendChild(r.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,a.firstChild);if(z[f]){c.support.scriptEval=true;delete z[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function n(){c.support.noCloneEvent=false;d.detachEvent("onclick",n)});d.cloneNode(true).fireEvent("onclick")}d=r.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=r.createDocumentFragment();a.appendChild(d.firstChild); -c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var n=r.createElement("div");n.style.width=n.style.paddingLeft="1px";r.body.appendChild(n);c.boxModel=c.support.boxModel=n.offsetWidth===2;r.body.removeChild(n).style.display="none"});a=function(n){var o=r.createElement("div");n="on"+n;var m=n in o;if(!m){o.setAttribute(n,"return;");m=typeof o[n]==="function"}return m};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props= -{"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ua=0,xa={},Va={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var f=a[G],e=c.cache;if(!b&&!f)return null;f||(f=++Ua);if(typeof b==="object"){a[G]=f;e=e[f]=c.extend(true, -{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Va:(e[f]={});if(d!==v){a[G]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[G]}catch(i){a.removeAttribute&&a.removeAttribute(G)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this, -a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===v){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===v&&this.length)f=c.data(this[0],a);return f===v&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d); -return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===v)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]|| -a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var ya=/[\n\t]/g,ca=/\s+/,Wa=/\r/g,Xa=/href|src|style/,Ya=/(button|input)/i,Za=/(button|input|object|select|textarea)/i,$a=/^(a|area)$/i,za=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(o){var m= -c(this);m.addClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className)for(var i=" "+e.className+" ",j=0,n=b.length;j<n;j++){if(i.indexOf(" "+b[j]+" ")<0)e.className+=" "+b[j]}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=c(this);m.removeClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string"||a===v)for(var b=(a||"").split(ca), -d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var i=(" "+e.className+" ").replace(ya," "),j=0,n=b.length;j<n;j++)i=i.replace(" "+b[j]+" "," ");e.className=i.substring(1,i.length-1)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var i=c(this);i.toggleClass(a.call(this,e,i.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,i=0,j=c(this),n=b,o= -a.split(ca);e=o[i++];){n=f?n:!j.hasClass(e);j[n?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(ya," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===v){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value|| -{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i<d;i++){var j=e[i];if(j.selected){a=c(j).val();if(b)return a;f.push(a)}}return f}if(za.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Wa,"")}return v}var n=c.isFunction(a);return this.each(function(o){var m=c(this),s=a;if(this.nodeType===1){if(n)s=a.call(this,o,m.val()); -if(typeof s==="number")s+="";if(c.isArray(s)&&za.test(this.type))this.checked=c.inArray(m.val(),s)>=0;else if(c.nodeName(this,"select")){var x=c.makeArray(s);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),x)>=0});if(!x.length)this.selectedIndex=-1}else this.value=s}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return v;if(f&&b in c.attrFn)return c(a)[b](d); -f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==v;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Xa.test(b);if(b in a&&f&&!i){if(e){b==="type"&&Ya.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Za.test(a.nodeName)||$a.test(a.nodeName)&&a.href?0:v;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText= -""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?v:a}return c.style(a,b,d)}});var ab=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==z&&!a.frameElement)a=z;if(!d.guid)d.guid=c.guid++;if(f!==v){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j= -function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):v};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var n,o=0;n=b[o++];){var m=n.split(".");n=m.shift();if(o>1){d=c.proxy(d);if(f!==v)d.data=f}d.type=m.slice(0).sort().join(".");var s=e[n],x=this.special[n]||{};if(!s){s=e[n]={};if(!x.setup||x.setup.call(a,f,m,d)===false)if(a.addEventListener)a.addEventListener(n,i,false);else a.attachEvent&&a.attachEvent("on"+n,i)}if(x.add)if((m=x.add.call(a, -d,f,m,s))&&c.isFunction(m)){m.guid=m.guid||d.guid;m.data=m.data||d.data;m.type=m.type||d.type;d=m}s[d.guid]=d;this.global[n]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===v||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);for(var n=0;i=b[n++];){var o=i.split(".");i=o.shift();var m=!o.length,s=c.map(o.slice(0).sort(),ab);s=new RegExp("(^|\\.)"+ -s.join("\\.(?:.*\\.)?")+"(\\.|$)");var x=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var A in f[i])if(m||s.test(f[i][A].type))delete f[i][A];x.remove&&x.remove.call(a,o,j);for(e in f[i])break;if(!e){if(!x.teardown||x.teardown.call(a,o)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(A=c.data(a,"handle"))A.elem=null;c.removeData(a, -"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return v;a.result=v;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d, -b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(i){}if(!a.isPropagationStopped()&&f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){d=a.target;var j;if(!(c.nodeName(d,"a")&&e==="click")&&!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){try{if(d[e]){if(j=d["on"+e])d["on"+e]=null;this.triggered=true;d[e]()}}catch(n){}if(j)d["on"+e]=j;this.triggered=false}}},handle:function(a){var b, -d;a=arguments[0]=c.event.fix(a||z.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==v){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), -fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||r;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=r.documentElement;d=r.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop|| -d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==v)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;b.liveProxy=a;c.event.add(this,b.live,na,b)},remove:function(a){if(a.length){var b= -0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],na)}},special:{}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true}; -c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y};var Aa=function(a){for(var b= -a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ba=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ba:Aa,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ba:Aa)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!== -"form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return ma("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return ma("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this, -"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var da=/textarea|input|select/i;function Ca(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ea(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Ca(d);if(a.type!=="focusout"|| -d.type!=="radio")c.data(d,"_change_data",e);if(!(f===v||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}}c.event.special.change={filters:{focusout:ea,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ea.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ea.call(this,a)},beforeactivate:function(a){a= -a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Ca(a))}},setup:function(a,b,d){for(var f in T)c.event.add(this,f+".specialChange."+d.guid,T[f]);return da.test(this.nodeName)},remove:function(a,b){for(var d in T)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),T[d]);return da.test(this.nodeName)}};var T=c.event.special.change.filters}r.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this, -f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){e=f;f=v}var j=b==="one"?c.proxy(e,function(n){c(this).unbind(n,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a, -b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+ -a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e){var i,j=0;if(c.isFunction(f)){e=f;f=v}for(d=(d||"").split(/\s+/);(i=d[j++])!=null;){i=i==="focus"?"focusin":i==="blur"?"focusout":i==="hover"?d.push("mouseleave")&&"mouseenter":i;b==="live"?c(this.context).bind(oa(i,this.selector),{data:f,selector:this.selector, -live:i},e):c(this.context).unbind(oa(i,this.selector),e?{guid:e.guid+this.selector+i}:null)}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});z.attachEvent&&!z.addEventListener&&z.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}}); -(function(){function a(g){for(var h="",k,l=0;g[l];l++){k=g[l];if(k.nodeType===3||k.nodeType===4)h+=k.nodeValue;else if(k.nodeType!==8)h+=a(k.childNodes)}return h}function b(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===k){y=l[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=k;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}l[q]=y}}}function d(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache=== -k){y=l[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=k;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(o.filter(h,[t]).length>0){y=t;break}}t=t[g]}l[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,i=Object.prototype.toString,j=false,n=true;[0,0].sort(function(){n=false;return 0});var o=function(g,h,k,l){k=k||[];var q=h=h||r;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g|| -typeof g!=="string")return k;for(var p=[],u,t,y,R,H=true,M=w(h),I=g;(f.exec(""),u=f.exec(I))!==null;){I=u[3];p.push(u[1]);if(u[2]){R=u[3];break}}if(p.length>1&&s.exec(g))if(p.length===2&&m.relative[p[0]])t=fa(p[0]+p[1],h);else for(t=m.relative[p[0]]?[h]:o(p.shift(),h);p.length;){g=p.shift();if(m.relative[g])g+=p.shift();t=fa(g,t)}else{if(!l&&p.length>1&&h.nodeType===9&&!M&&m.match.ID.test(p[0])&&!m.match.ID.test(p[p.length-1])){u=o.find(p.shift(),h,M);h=u.expr?o.filter(u.expr,u.set)[0]:u.set[0]}if(h){u= -l?{expr:p.pop(),set:A(l)}:o.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=u.expr?o.filter(u.expr,u.set):u.set;if(p.length>0)y=A(t);else H=false;for(;p.length;){var D=p.pop();u=D;if(m.relative[D])u=p.pop();else D="";if(u==null)u=h;m.relative[D](y,u,M)}}else y=[]}y||(y=t);y||o.error(D||g);if(i.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))k.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&& -y[g].nodeType===1&&k.push(t[g]);else k.push.apply(k,y);else A(y,k);if(R){o(R,q,k,l);o.uniqueSort(k)}return k};o.uniqueSort=function(g){if(C){j=n;g.sort(C);if(j)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};o.matches=function(g,h){return o(g,null,null,h)};o.find=function(g,h,k){var l,q;if(!g)return[];for(var p=0,u=m.order.length;p<u;p++){var t=m.order[p];if(q=m.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");l=m.find[t](q, -h,k);if(l!=null){g=g.replace(m.match[t],"");break}}}}l||(l=h.getElementsByTagName("*"));return{set:l,expr:g}};o.filter=function(g,h,k,l){for(var q=g,p=[],u=h,t,y,R=h&&h[0]&&w(h[0]);g&&h.length;){for(var H in m.filter)if((t=m.leftMatch[H].exec(g))!=null&&t[2]){var M=m.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(u===p)p=[];if(m.preFilter[H])if(t=m.preFilter[H](t,u,k,p,l,R)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=u[U])!=null;U++)if(D){I=M(D,t,U,u);var Da= -l^!!I;if(k&&I!=null)if(Da)y=true;else u[U]=false;else if(Da){p.push(D);y=true}}if(I!==v){k||(u=p);g=g.replace(m.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)o.error(g);else break;q=g}return u};o.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var m=o.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, -TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,h){var k=typeof h==="string",l=k&&!/\W/.test(h);k=k&&!l;if(l)h=h.toLowerCase();l=0;for(var q=g.length, -p;l<q;l++)if(p=g[l]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[l]=k||p&&p.nodeName.toLowerCase()===h?p||false:p===h}k&&o.filter(h,g,true)},">":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var l=0,q=g.length;l<q;l++){var p=g[l];if(p){k=p.parentNode;g[l]=k.nodeName.toLowerCase()===h?k:false}}}else{l=0;for(q=g.length;l<q;l++)if(p=g[l])g[l]=k?p.parentNode:p.parentNode===h;k&&o.filter(h,g,true)}},"":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p= -h=h.toLowerCase();q=b}q("parentNode",h,l,g,p,k)},"~":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,l,g,p,k)}},find:{ID:function(g,h,k){if(typeof h.getElementById!=="undefined"&&!k)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var k=[];h=h.getElementsByName(g[1]);for(var l=0,q=h.length;l<q;l++)h[l].getAttribute("name")===g[1]&&k.push(h[l]);return k.length===0?null:k}}, -TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,k,l,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var u;(u=h[p])!=null;p++)if(u)if(q^(u.className&&(" "+u.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))k||l.push(u);else if(k)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&& -"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,l,q,p){h=g[1].replace(/\\/g,"");if(!p&&m.attrMap[h])g[1]=m.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,l,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=o(g[3],null,null,h);else{g=o.filter(g[3],h,k,true^q);k||l.push.apply(l,g);return false}else if(m.match.POS.test(g[0])||m.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true); -return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!o(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"=== -g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,h){return h===0},last:function(g,h,k,l){return h===l.length-1},even:function(g,h){return h%2=== -0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return h<k[3]-0},gt:function(g,h,k){return h>k[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,l){var q=h[1],p=m.filters[q];if(p)return p(g,k,h,l);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=h[3];k=0;for(l=h.length;k<l;k++)if(h[k]===g)return false;return true}else o.error("Syntax error, unrecognized expression: "+ -q)},CHILD:function(g,h){var k=h[1],l=g;switch(k){case "only":case "first":for(;l=l.previousSibling;)if(l.nodeType===1)return false;if(k==="first")return true;l=g;case "last":for(;l=l.nextSibling;)if(l.nodeType===1)return false;return true;case "nth":k=h[2];var q=h[3];if(k===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var u=0;for(l=p.firstChild;l;l=l.nextSibling)if(l.nodeType===1)l.nodeIndex=++u;p.sizcache=h}g=g.nodeIndex-q;return k===0?g===0:g%k===0&&g/k>= -0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=m.attrHandle[k]?m.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var l=h[2];h=h[4];return g==null?l==="!=":l==="="?k===h:l==="*="?k.indexOf(h)>=0:l==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:l==="!="?k!==h:l==="^="? -k.indexOf(h)===0:l==="$="?k.substr(k.length-h.length)===h:l==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,l){var q=m.setFilters[h[2]];if(q)return q(g,k,h,l)}}},s=m.match.POS;for(var x in m.match){m.match[x]=new RegExp(m.match[x].source+/(?![^\[]*\])(?![^\(]*\))/.source);m.leftMatch[x]=new RegExp(/(^(?:.|\r|\n)*?)/.source+m.match[x].source.replace(/\\(\d+)/g,function(g,h){return"\\"+(h-0+1)}))}var A=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g}; -try{Array.prototype.slice.call(r.documentElement.childNodes,0)}catch(B){A=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,l=g.length;k<l;k++)h.push(g[k]);else for(k=0;g[k];k++)h.push(g[k]);return h}}var C;if(r.documentElement.compareDocumentPosition)C=function(g,h){if(!g.compareDocumentPosition||!h.compareDocumentPosition){if(g==h)j=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g=== -h?0:1;if(g===0)j=true;return g};else if("sourceIndex"in r.documentElement)C=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)j=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)j=true;return g};else if(r.createRange)C=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)j=true;return g.ownerDocument?-1:1}var k=g.ownerDocument.createRange(),l=h.ownerDocument.createRange();k.setStart(g,0);k.setEnd(g,0);l.setStart(h,0);l.setEnd(h,0);g=k.compareBoundaryPoints(Range.START_TO_END, -l);if(g===0)j=true;return g};(function(){var g=r.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var k=r.documentElement;k.insertBefore(g,k.firstChild);if(r.getElementById(h)){m.find.ID=function(l,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(l[1]))?q.id===l[1]||typeof q.getAttributeNode!=="undefined"&&q.getAttributeNode("id").nodeValue===l[1]?[q]:v:[]};m.filter.ID=function(l,q){var p=typeof l.getAttributeNode!=="undefined"&&l.getAttributeNode("id"); -return l.nodeType===1&&p&&p.nodeValue===q}}k.removeChild(g);k=g=null})();(function(){var g=r.createElement("div");g.appendChild(r.createComment(""));if(g.getElementsByTagName("*").length>0)m.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var l=0;k[l];l++)k[l].nodeType===1&&h.push(k[l]);k=h}return k};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")m.attrHandle.href=function(h){return h.getAttribute("href", -2)};g=null})();r.querySelectorAll&&function(){var g=o,h=r.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){o=function(l,q,p,u){q=q||r;if(!u&&q.nodeType===9&&!w(q))try{return A(q.querySelectorAll(l),p)}catch(t){}return g(l,q,p,u)};for(var k in g)o[k]=g[k];h=null}}();(function(){var g=r.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length=== -0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){m.order.splice(1,0,"CLASS");m.find.CLASS=function(h,k,l){if(typeof k.getElementsByClassName!=="undefined"&&!l)return k.getElementsByClassName(h[1])};g=null}}})();var E=r.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,h){return g!==h&&(g.contains?g.contains(h):true)},w=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},fa=function(g,h){var k=[], -l="",q;for(h=h.nodeType?[h]:h;q=m.match.PSEUDO.exec(g);){l+=q[0];g=g.replace(m.match.PSEUDO,"")}g=m.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)o(g,h[q],k);return o.filter(l,k)};c.find=o;c.expr=o.selectors;c.expr[":"]=c.expr.filters;c.unique=o.uniqueSort;c.getText=a;c.isXMLDoc=w;c.contains=E})();var bb=/Until$/,cb=/^(?:parents|prevUntil|prevAll)/,db=/,/;Q=Array.prototype.slice;var Ea=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,i){return!!b.call(e,i,e)===d});else if(b.nodeType)return c.grep(a, -function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Qa.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;c.find(a,this[f],b);if(f>0)for(var i=d;i<b.length;i++)for(var j=0;j<d;j++)if(b[j]===b[i]){b.splice(i--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d= -0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ea(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ea(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i={},j;if(f&&a.length){e=0;for(var n=a.length;e<n;e++){j=a[e];i[j]||(i[j]=c.expr.match.POS.test(j)?c(j,b||this.context):j)}for(;f&&f.ownerDocument&&f!==b;){for(j in i){e=i[j];if(e.jquery?e.index(f)> --1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var o=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(m,s){for(;s&&s.ownerDocument&&s!==b;){if(o?o.index(s)>-1:c(s).is(a))return s;s=s.parentNode}return null})},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(), -a);return this.pushStack(pa(a[0])||pa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")}, -nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);bb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e): -e;if((this.length>1||db.test(f))&&cb.test(a))e=e.reverse();return this.pushStack(e,a,Q.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===v||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!== -b&&d.push(a);return d}});var Fa=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ga=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/<tbody/i,gb=/<|&\w+;/,sa=/checked\s*(?:[^=]|=\s*.checked.)/i,Ia=function(a,b,d){return eb.test(d)?a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"], -col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==v)return this.empty().append((this[0]&&this[0].ownerDocument||r).createTextNode(a));return c.getText(this)}, -wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length? -d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments, -false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&& -!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Fa,"").replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){qa(this,b);qa(this.find("*"),b.find("*"))}return b},html:function(a){if(a===v)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Fa,""):null;else if(typeof a==="string"&&!/<script/i.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(Ha.exec(a)|| -["",""])[1].toLowerCase()]){a=a.replace(Ga,Ia);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var i=c(this),j=i.html();i.empty().append(function(){return a.call(this,e,j)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this, -b,f))});else a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(s){return c.nodeName(s,"table")?s.getElementsByTagName("tbody")[0]||s.appendChild(s.ownerDocument.createElement("tbody")):s}var e,i,j=a[0],n=[];if(!c.support.checkClone&&arguments.length===3&&typeof j=== -"string"&&sa.test(j))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(j))return this.each(function(s){var x=c(this);a[0]=j.call(this,s,b?x.html():v);x.domManip(a,b,d)});if(this[0]){e=a[0]&&a[0].parentNode&&a[0].parentNode.nodeType===11?{fragment:a[0].parentNode}:ra(a,this,n);if(i=e.fragment.firstChild){b=b&&c.nodeName(i,"tr");for(var o=0,m=this.length;o<m;o++)d.call(b?f(this[o],i):this[o],e.cacheable||this.length>1||o>0?e.fragment.cloneNode(true):e.fragment)}n&&c.each(n, -Ma)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);for(var e=0,i=d.length;e<i;e++){var j=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),j);f=f.concat(j)}return this.pushStack(f,a,d.selector)}});c.each({remove:function(a,b){if(!a||c.filter(a,[this]).length){if(!b&&this.nodeType===1){c.cleanData(this.getElementsByTagName("*"));c.cleanData([this])}this.parentNode&& -this.parentNode.removeChild(this)}},empty:function(){for(this.nodeType===1&&c.cleanData(this.getElementsByTagName("*"));this.firstChild;)this.removeChild(this.firstChild)}},function(a,b){c.fn[a]=function(){return this.each(b,arguments)}});c.extend({clean:function(a,b,d,f){b=b||r;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||r;var e=[];c.each(a,function(i,j){if(typeof j==="number")j+="";if(j){if(typeof j==="string"&&!gb.test(j))j=b.createTextNode(j);else if(typeof j=== -"string"){j=j.replace(Ga,Ia);var n=(Ha.exec(j)||["",""])[1].toLowerCase(),o=F[n]||F._default,m=o[0];i=b.createElement("div");for(i.innerHTML=o[1]+j+o[2];m--;)i=i.lastChild;if(!c.support.tbody){m=fb.test(j);n=n==="table"&&!m?i.firstChild&&i.firstChild.childNodes:o[1]==="<table>"&&!m?i.childNodes:[];for(o=n.length-1;o>=0;--o)c.nodeName(n[o],"tbody")&&!n[o].childNodes.length&&n[o].parentNode.removeChild(n[o])}!c.support.leadingWhitespace&&V.test(j)&&i.insertBefore(b.createTextNode(V.exec(j)[0]),i.firstChild); -j=c.makeArray(i.childNodes)}if(j.nodeType)e.push(j);else e=c.merge(e,j)}});if(d)for(a=0;e[a];a++)if(f&&c.nodeName(e[a],"script")&&(!e[a].type||e[a].type.toLowerCase()==="text/javascript"))f.push(e[a].parentNode?e[a].parentNode.removeChild(e[a]):e[a]);else{e[a].nodeType===1&&e.splice.apply(e,[a+1,0].concat(c.makeArray(e[a].getElementsByTagName("script"))));d.appendChild(e[a])}return e},cleanData:function(a){for(var b=0,d;(d=a[b])!=null;b++){c.event.remove(d);c.removeData(d)}}});var hb=/z-?index|font-?weight|opacity|zoom|line-?height/i, -Ja=/alpha\([^)]*\)/,Ka=/opacity=([^)]*)/,ga=/float/i,ha=/-([a-z])/ig,ib=/([A-Z])/g,jb=/^-?\d+(?:px)?$/i,kb=/^-?\d/,lb={position:"absolute",visibility:"hidden",display:"block"},mb=["Left","Right"],nb=["Top","Bottom"],ob=r.defaultView&&r.defaultView.getComputedStyle,La=c.support.cssFloat?"cssFloat":"styleFloat",ia=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===v)return c.curCSS(d,f);if(typeof e==="number"&&!hb.test(f))e+="px";c.style(d,f,e)})}; -c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return v;if((b==="width"||b==="height")&&parseFloat(d)<0)d=v;var f=a.style||a,e=d!==v;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=Ja.test(a)?a.replace(Ja,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Ka.exec(f.filter)[1])/100+"":""}if(ga.test(b))b=La;b=b.replace(ha,ia);if(e)f[b]=d;return f[b]},css:function(a, -b,d,f){if(b==="width"||b==="height"){var e,i=b==="width"?mb:nb;function j(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(i,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,"border"+this+"Width",true))||0})}a.offsetWidth!==0?j():c.swap(a,lb,j);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&& -a.currentStyle){f=Ka.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ga.test(b))b=La;if(!d&&e&&e[b])f=e[b];else if(ob){if(ga.test(b))b="float";b=b.replace(ib,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ha,ia);f=a.currentStyle[b]||a.currentStyle[d];if(!jb.test(f)&&kb.test(f)){b=e.left;var i=a.runtimeStyle.left;a.runtimeStyle.left= -a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=i}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var pb= -J(),qb=/<script(.|\s)*?\/script>/gi,rb=/select|textarea/i,sb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ja=/\?/,tb=/(\?|&)_=.*?(&|$)/,ub=/^(\w+:)?\/\/([^\/?#]+)/,vb=/%20/g;c.fn.extend({_load:c.fn.load,load:function(a,b,d){if(typeof a!=="string")return this._load(a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b= -c.param(b,c.ajaxSettings.traditional);f="POST"}var i=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(j,n){if(n==="success"||n==="notmodified")i.html(e?c("<div />").append(j.responseText.replace(qb,"")).find(e):j.responseText);d&&i.each(d,[j.responseText,n,j])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&& -(this.checked||rb.test(this.nodeName)||sb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a, -b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:z.XMLHttpRequest&&(z.location.protocol!=="file:"||!z.ActiveXObject)?function(){return new z.XMLHttpRequest}: -function(){try{return new z.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&e.success.call(o,n,j,w);e.global&&f("ajaxSuccess",[w,e])}function d(){e.complete&&e.complete.call(o,w,j);e.global&&f("ajaxComplete",[w,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")} -function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),i,j,n,o=a&&a.context||e,m=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(m==="GET")N.test(e.url)||(e.url+=(ja.test(e.url)?"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)|| -N.test(e.url))){i=e.jsonpCallback||"jsonp"+pb++;if(e.data)e.data=(e.data+"").replace(N,"="+i+"$1");e.url=e.url.replace(N,"="+i+"$1");e.dataType="script";z[i]=z[i]||function(q){n=q;b();d();z[i]=v;try{delete z[i]}catch(p){}A&&A.removeChild(B)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===false&&m==="GET"){var s=J(),x=e.url.replace(tb,"$1_="+s+"$2");e.url=x+(x===e.url?(ja.test(e.url)?"&":"?")+"_="+s:"")}if(e.data&&m==="GET")e.url+=(ja.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&& -c.event.trigger("ajaxStart");s=(s=ub.exec(e.url))&&(s[1]&&s[1]!==location.protocol||s[2]!==location.host);if(e.dataType==="script"&&m==="GET"&&s){var A=r.getElementsByTagName("head")[0]||r.documentElement,B=r.createElement("script");B.src=e.url;if(e.scriptCharset)B.charset=e.scriptCharset;if(!i){var C=false;B.onload=B.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;b();d();B.onload=B.onreadystatechange=null;A&&B.parentNode&& -A.removeChild(B)}}}A.insertBefore(B,A.firstChild);return v}var E=false,w=e.xhr();if(w){e.username?w.open(m,e.url,e.async,e.username,e.password):w.open(m,e.url,e.async);try{if(e.data||a&&a.contentType)w.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[e.url]);c.etag[e.url]&&w.setRequestHeader("If-None-Match",c.etag[e.url])}s||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept", -e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(fa){}if(e.beforeSend&&e.beforeSend.call(o,w,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");w.abort();return false}e.global&&f("ajaxSend",[w,e]);var g=w.onreadystatechange=function(q){if(!w||w.readyState===0||q==="abort"){E||d();E=true;if(w)w.onreadystatechange=c.noop}else if(!E&&w&&(w.readyState===4||q==="timeout")){E=true;w.onreadystatechange=c.noop;j=q==="timeout"?"timeout":!c.httpSuccess(w)? -"error":e.ifModified&&c.httpNotModified(w,e.url)?"notmodified":"success";var p;if(j==="success")try{n=c.httpData(w,e.dataType,e)}catch(u){j="parsererror";p=u}if(j==="success"||j==="notmodified")i||b();else c.handleError(e,w,j,p);d();q==="timeout"&&w.abort();if(e.async)w=null}};try{var h=w.abort;w.abort=function(){w&&h.call(w);g("abort")}}catch(k){}e.async&&e.timeout>0&&setTimeout(function(){w&&!E&&g("timeout")},e.timeout);try{w.send(m==="POST"||m==="PUT"||m==="DELETE"?e.data:null)}catch(l){c.handleError(e, -w,null,l);d()}e.async||g();return w}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]= -f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(j,n){if(c.isArray(n))c.each(n, -function(o,m){b?f(j,m):d(j+"["+(typeof m==="object"||c.isArray(m)?o:"")+"]",m)});else!b&&n!=null&&typeof n==="object"?c.each(n,function(o,m){d(j+"["+o+"]",m)}):f(j,n)}function f(j,n){n=c.isFunction(n)?n():n;e[e.length]=encodeURIComponent(j)+"="+encodeURIComponent(n)}var e=[];if(b===v)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var i in a)d(i,a[i]);return e.join("&").replace(vb,"+")}});var ka={},wb=/toggle|show|hide/,xb=/^([+-]=)?([\d+-.]+)(.*)$/, -W,ta=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(ka[d])f=ka[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove(); -ka[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&& -c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var i=c.extend({},e),j,n=this.nodeType===1&&c(this).is(":hidden"), -o=this;for(j in a){var m=j.replace(ha,ia);if(j!==m){a[m]=a[j];delete a[j];j=m}if(a[j]==="hide"&&n||a[j]==="show"&&!n)return i.complete.call(this);if((j==="height"||j==="width")&&this.style){i.display=c.css(this,"display");i.overflow=this.style.overflow}if(c.isArray(a[j])){(i.specialEasing=i.specialEasing||{})[j]=a[j][1];a[j]=a[j][0]}}if(i.overflow!=null)this.style.overflow="hidden";i.curAnim=c.extend({},a);c.each(a,function(s,x){var A=new c.fx(o,i,s);if(wb.test(x))A[x==="toggle"?n?"show":"hide":x](a); -else{var B=xb.exec(x),C=A.cur(true)||0;if(B){x=parseFloat(B[2]);var E=B[3]||"px";if(E!=="px"){o.style[s]=(x||1)+E;C=(x||1)/A.cur(true)*C;o.style[s]=C+E}if(B[1])x=(B[1]==="-="?-1:1)*x+C;A.custom(C,x,E)}else A.custom(C,x,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle", -1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration==="number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a, -b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]== -null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(i){return e.step(i)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop=== -"width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow= -this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos= -c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!= -null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in r.documentElement?function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(), -f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(s){c.offset.setOffset(this,a,s)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f= -b,e=b.ownerDocument,i,j=e.documentElement,n=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var o=b.offsetTop,m=b.offsetLeft;(b=b.parentNode)&&b!==n&&b!==j;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;i=e?e.getComputedStyle(b,null):b.currentStyle;o-=b.scrollTop;m-=b.scrollLeft;if(b===d){o+=b.offsetTop;m+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){o+=parseFloat(i.borderTopWidth)|| -0;m+=parseFloat(i.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&i.overflow!=="visible"){o+=parseFloat(i.borderTopWidth)||0;m+=parseFloat(i.borderLeftWidth)||0}f=i}if(f.position==="relative"||f.position==="static"){o+=n.offsetTop;m+=n.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){o+=Math.max(j.scrollTop,n.scrollTop);m+=Math.max(j.scrollLeft,n.scrollLeft)}return{top:o,left:m}};c.offset={initialize:function(){var a=r.body,b=r.createElement("div"), -d,f,e,i=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild); -d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i;a.removeChild(b);c.offset.initialize=c.noop}, -bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),i=parseInt(c.curCSS(a,"top",true),10)||0,j=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,d,e);d={top:b.top-e.top+i,left:b.left- -e.left+j};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a= -this.offsetParent||r.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],i;if(!e)return null;if(f!==v)return this.each(function(){if(i=ua(this))i.scrollTo(!a?f:c(i).scrollLeft(),a?f:c(i).scrollTop());else this[d]=f});else return(i=ua(e))?"pageXOffset"in i?i[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&i.document.documentElement[d]||i.document.body[d]:e[d]}}); -c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(i){var j=c(this);j[d](f.call(this,i,j[d]()))});return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]|| -e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===v?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});z.jQuery=z.$=c})(window); diff --git a/doc/templates/scripts/narrow.js b/doc/templates/scripts/narrow.js deleted file mode 100644 index 35c81bf4a..000000000 --- a/doc/templates/scripts/narrow.js +++ /dev/null @@ -1,89 +0,0 @@ -var narrowInit = function() { - /* TODO: - Could probably be more efficient, not hardcoding each element to be created - */ - // 1: Create search form - var narrowSearch = $('<div id="narrowsearch"></div>'); - var searchform = $("#qtdocsearch"); - narrowSearch.append(searchform); - $("#qtdocheader .content .qtref").after(narrowSearch); - - // 2: Create dropdowns - var narrowmenu = $('<ul id="narrowmenu" class="sf-menu"></ul>'); - - // Lookup - var lookuptext = $("#lookup h2").attr("title"); - $("#lookup ul").removeAttr("id"); - $("#lookup ul li").removeAttr("class"); - $("#lookup ul li").removeAttr("style"); - var lookupul = $("#lookup ul"); - var lookuplist = $('<li></li>'); - var lookuplink = $('<a href="#"></a>'); - lookuplink.append(lookuptext); - lookuplist.append(lookuplink); - lookuplist.append(lookupul); - narrowmenu.append(lookuplist); - - // Topics - var topicstext = $("#topics h2").attr("title"); - $("#topics ul").removeAttr("id"); - $("#topics ul li").removeAttr("class"); - $("#topics ul li").removeAttr("style"); - var topicsul = $("#topics ul"); - var topicslist = $('<li></li>'); - var topicslink = $('<a href="#"></a>'); - topicslink.append(topicstext); - topicslist.append(topicslink); - topicslist.append(topicsul); - narrowmenu.append(topicslist); - - // Examples - var examplestext = $("#examples h2").attr("title"); - $("#examples ul").removeAttr("id"); - $("#examples ul li").removeAttr("class"); - $("#examples ul li").removeAttr("style"); - var examplesul = $("#examples ul"); - var exampleslist = $('<li></li>'); - var exampleslink = $('<a href="#"></a>'); - exampleslink.append(examplestext); - exampleslist.append(exampleslink); - exampleslist.append(examplesul); - narrowmenu.append(exampleslist); - - $("#shortCut").after(narrowmenu); - $('ul#narrowmenu').superfish({ - delay: 100, - autoArrows: false, - disableHI: true - }); -} - -$(document).ready(function(){ -/* if ($('body').hasClass('narrow')) { - narrowInit(); - } - */ - if($(window).width()<600) { - $('body').addClass('narrow'); - - if ($("#narrowsearch").length == 0) { - narrowInit(); - } - } - else { - $('body').removeClass('narrow'); - } -}); - -$(window).bind('resize', function () { - if($(window).width()<600) { - $('body').addClass('narrow'); - - if ($("#narrowsearch").length == 0) { - narrowInit(); - } - } - else { - $('body').removeClass('narrow'); - } -});
\ No newline at end of file diff --git a/doc/templates/scripts/superfish.js b/doc/templates/scripts/superfish.js deleted file mode 100644 index c6a9c7de0..000000000 --- a/doc/templates/scripts/superfish.js +++ /dev/null @@ -1,121 +0,0 @@ - -/* - * Superfish v1.4.8 - jQuery menu widget - * Copyright (c) 2008 Joel Birch - * - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - * CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt - */ - -;(function($){ - $.fn.superfish = function(op){ - - var sf = $.fn.superfish, - c = sf.c, - $arrow = $(['<span class="',c.arrowClass,'"> »</span>'].join('')), - over = function(){ - var $$ = $(this), menu = getMenu($$); - clearTimeout(menu.sfTimer); - $$.showSuperfishUl().siblings().hideSuperfishUl(); - }, - out = function(){ - var $$ = $(this), menu = getMenu($$), o = sf.op; - clearTimeout(menu.sfTimer); - menu.sfTimer=setTimeout(function(){ - o.retainPath=($.inArray($$[0],o.$path)>-1); - $$.hideSuperfishUl(); - if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);} - },o.delay); - }, - getMenu = function($menu){ - var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0]; - sf.op = sf.o[menu.serial]; - return menu; - }, - addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); }; - - return this.each(function() { - var s = this.serial = sf.o.length; - var o = $.extend({},sf.defaults,op); - o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){ - $(this).addClass([o.hoverClass,c.bcClass].join(' ')) - .filter('li:has(ul)').removeClass(o.pathClass); - }); - sf.o[s] = sf.op = o; - - $('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() { - if (o.autoArrows) addArrow( $('>a:first-child',this) ); - }) - .not('.'+c.bcClass) - .hideSuperfishUl(); - - var $a = $('a',this); - $a.each(function(i){ - var $li = $a.eq(i).parents('li'); - $a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);}); - }); - o.onInit.call(this); - - }).each(function() { - var menuClasses = [c.menuClass]; - if (sf.op.dropShadows && !($.browser.msie && $.browser.version < 7)) menuClasses.push(c.shadowClass); - $(this).addClass(menuClasses.join(' ')); - }); - }; - - var sf = $.fn.superfish; - sf.o = []; - sf.op = {}; - sf.IE7fix = function(){ - var o = sf.op; - if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity!=undefined) - this.toggleClass(sf.c.shadowClass+'-off'); - }; - sf.c = { - bcClass : 'sf-breadcrumb', - menuClass : 'sf-js-enabled', - anchorClass : 'sf-with-ul', - arrowClass : 'sf-sub-indicator', - shadowClass : 'sf-shadow' - }; - sf.defaults = { - hoverClass : 'sfHover', - pathClass : 'overideThisToUse', - pathLevels : 1, - delay : 800, - animation : {opacity:'show'}, - speed : 'normal', - autoArrows : true, - dropShadows : true, - disableHI : false, // true disables hoverIntent detection - onInit : function(){}, // callback functions - onBeforeShow: function(){}, - onShow : function(){}, - onHide : function(){} - }; - $.fn.extend({ - hideSuperfishUl : function(){ - var o = sf.op, - not = (o.retainPath===true) ? o.$path : ''; - o.retainPath = false; - var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass) - .find('>ul').hide().css('visibility','hidden'); - o.onHide.call($ul); - return this; - }, - showSuperfishUl : function(){ - var o = sf.op, - sh = sf.c.shadowClass+'-off', - $ul = this.addClass(o.hoverClass) - .find('>ul:hidden').css('visibility','visible'); - sf.IE7fix.call($ul); - o.onBeforeShow.call($ul); - $ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); }); - return this; - } - }); - -})(jQuery); diff --git a/doc/templates/style/narrow.css b/doc/templates/style/narrow.css deleted file mode 100644 index de5b0a09f..000000000 --- a/doc/templates/style/narrow.css +++ /dev/null @@ -1,270 +0,0 @@ - /* start narrow mode */ - - body.narrow - { - background-image: none; - } - - .narrow a { - color: #44a51c; - } - - .narrow .header, .narrow .header .content, .narrow .footer, .narrow .wrapper { - margin: 0 7px; - min-width: 300px; - } - - .narrow .footer { - margin: 0px; - } - - .creator .header, .creator .header .content, .creator .footer, .creator .wrapper { - margin: 0px; - min-width: 300px; - } - .narrow .header - { - width: 100%; - margin: 0; - height: auto; - background: #fff url(../images/header_bg.png) repeat-x 0 100%; - padding: 10px 0 5px 0; - overflow: visible; - } - - .narrow .header .content - { - } - - .narrow .header #nav-logo - { - display: none; - } - - .narrow .header .qtref - { - width: auto; - height: auto; - color: #363534; - position: static; - float: left; - margin-left: 25px; - font: bold 18px/1 Arial; - } - - .narrow .header .qtref a - { - color: #00732F; - } - - .narrow .header .qtref span - { - background-image: none; - text-indent: 0; - } - - .narrow .header #nav-topright - { - display: none; - } - - .narrow .header #shortCut - { - clear: both; - font-weight: normal; - position: static; - float: left; - margin: 15px 0 0 25px; - overflow: hidden; - padding: 0; - height: auto; - } - - .narrow .header #shortCut ul - { - float: none; - margin: 0; - width: auto; - font-size: 11px; - } - - .narrow .header #shortCut ul li - { - background-image: none; - } - - .narrow .header #shortCut ul .shortCut-topleft-active, - .narrow .header #shortCut ul .shortCut-topleft-inactive - { - background-image: none; - height: auto; - padding: 0; - width: auto; - } - .narrow .header #shortCut ul li a - { - color: #00732F; - } - - .narrow .wrapper .hd - { - background: url(../images/bg_ul_blank.png) no-repeat 0 0; - } - - .narrow .wrapper .bd - { - background: url(../images/bg_l_blank.png) repeat-y 0 0; - } - - .narrow .wrapper .ft - { - background: url(../images/bg_ll_blank.png) no-repeat 0 0; - } - - .narrow .sidebar - { - display: none; - } - - .narrow .wrap - { - margin: 0 5px 0 5px; - } - - .creator .wrap - { - margin: 0px; - background:#FFFFFF; - } - .narrow .wrap .toolbar - { - border-bottom: none; - } - - .narrow .wrap .content - { - padding-top: 15px; - } - .creator .wrap .content - { - padding-top: 10px; - } - .creator .wrap .content .guide - { - padding-top: 15px; - } - .narrow .wrap .feedback - { - display: none; - } - - .narrow .wrap .breadcrumb ul li { - font-weight: normal; - } - - .narrow .wrap .breadcrumb ul li a { - color: #44a51c; - } - - .narrow .wrap .breadcrumb ul li.last a { - color: #363534; - } - - #narrowsearch { - display: none; - } - - .narrow #narrowsearch { - display: block; - float: right; - margin-right: 25px; - _position: relative; - } - - .narrow #narrowsearch fieldset { - _position: absolute; - _margin-top: -1px; - } - - .narrow #narrowsearch { - background: url("http://doc.qt.nokia.com/prototype/html/images/sprites-combined.png") no-repeat scroll -6px -348px transparent; - height: 21px; - padding: 2px 0 0 5px; - width: 167px; - } - - .narrow #narrowsearch input { - border: none; - font: 13px/1.2 Verdana; - height: 19px; - outline: none; - padding: 0; - width: 158px; - *border: 1px solid #fff; - *height: 17px; - _height: 18px; - /* to be fixed */ - display: none; - /* to be fixed */ - } - - .narrow .indexbox .indexIcon { - display: none; - } - - .narrow .indexboxcont .section { - width: 64%; - padding-left: 0; - } - - .narrow .indexboxcont .sectionlist { - width: 32.5%; - } - - #narrowmenu { - display: none; - float: right; - margin: 15px 40px 0 0; - font-size: 11px; - } - - .narrow #narrowmenu { - display: block; - } - - #narrowmenu a { - line-height: 1.1; - background: url(../images/arrow_down.png) no-repeat 100% 50%; - white-space: nowrap; - padding: 0 16px 0 5px; - } - - #narrowmenu li { - margin-left: 20px; - } - - #narrowmenu li li { - margin: 0 0 5px 0; - } - - #narrowmenu li li a { - padding: 0; - background-image: none; - } - - #narrowmenu li, - #narrowmenu li ul { - background-color: #fff; - margin-top:-1px; - } - - #narrowmenu li ul { - width: auto; - padding: 5px; - } - - .sf-menu li:hover ul, .sf-menu li.sfHover ul { - top: 1.2em; - } - - /* end narrow mode */ diff --git a/doc/templates/style/offline.css b/doc/templates/style/offline.css deleted file mode 100644 index 731f9a079..000000000 --- a/doc/templates/style/offline.css +++ /dev/null @@ -1,632 +0,0 @@ -body{ -font: normal 400 14px/1.2 Arial; -margin-top:85px; -font-family: Arial, Helvetica; -color:#313131; -text-align:justify; -margin-left:5px; -margin-right:5px; -} - -img{ --moz-box-shadow: 3px 3px 3px #ccc; --webkit-box-shadow: 3px 3px 3px #ccc; -box-shadow: 3px 3px 3px #ccc; -border:#8E8D8D 2px solid; -margin-left:0px; -max-width: 800px; -height: auto -} - -b{ -font-weight:600; -} - -.content{} - -.descr{ -margin-top:35px; -/*max-width: 75%;*/ -margin-left:5px; -text-align:justify; -min-height:700px; -vertical-align:top; -} - -.name{ -max-width: 75%; -font-weight:100; -} - -tt{ -text-align:left;} - -/* ------------ -links ------------ -*/ - -a:link{ -color: #2C418D; -text-decoration: none; -text-align:left; -} - -a:hover{ -color: #869CD1; -text-decoration:underline; -text-align:left; -} - -a:visited{ -color: #869CD1; -text-decoration: none; -text-align:left; -} - -a:visited:hover{ -text-decoration:underline; -text-align:left; -} - -a[href*="http://"], a[href*="ftp://"],a[href*="https://"] -{ -text-decoration: none; -background-image:url(../images/ico_out.png); -background-repeat:no-repeat; -background-position:left; -padding-left:20px; -text-align:left; -} - -/*a[href*="http://qt.nokia.com/doc/"], a[href*="http://doc.qt.nokia.com/"] -{ -background: none; -padding-left: 0px; -text-align:left; -}*/ - -.flags{ -text-decoration:none; -text-height:24px; -} - -/* -------------------------------- -NOTE styles -------------------------------- -*/ -.notetitle, .tiptitle, .fastpathtitle{ -font-weight:bold; -} - -.attentiontitle,.cautiontitle,.dangertitle,.importanttitle,.remembertitle,.restrictiontitle{ -font-weight:bold; -} - -.note,.tip,.fastpath{ -background: #F2F2F2 url(../images/ico_note.png); -background-repeat: no-repeat; -background-position: top left; -padding:5px; -padding-left:40px; -padding-bottom:10px; -border:#999 1px dotted; -color:#666666; -margin:5px; -} - -.attention,.caution,.danger,.important,.remember,.restriction{ -background: #F2F2F2 url(../images/ico_note_attention.png); -background-repeat:no-repeat; -background-position:top left; -padding:5px; -padding-left:40px; -padding-bottom:10px; -border:#999 1px dotted; -color:#666666; -margin:5px; -} - -/* -------------------------------- -Top navigation -------------------------------- -*/ - -.header{ - -height:1px; -padding:0px; -margin:0px; -} - -.qtref{ -display: block; -position: relative; -top: -76px; -height:15px; -z-index: 1; -font-size:11px; -padding-right:10px; -float:right; -} - -.naviNextPrevious{ -display: block; -position: relative; -text-align: right; -top: -53px; -float:right; -height:20px; -z-index:1; -padding-right:10px; -padding-top:2px; -vertical-align:top; -margin:0px; -} - - -.naviNextPrevious > a:first-child{ -background-image:url(../images/btn_prev.png); -background-repeat:no-repeat; -background-position:left; -padding-left:20px; -height:20px; -padding-left:20px; -} - -.naviNextPrevious > a:last-child{ -background-image:url(../images/btn_next.png); -background-repeat:no-repeat; -background-position:right; -padding-right:20px; -height:20px; -margin-left:30px; -} - -.breadcrumb{ -display: block; -position: relative; -top:-20px; -/*border-top:2px solid #ffffff;*/ -border-bottom: 1px solid #cecece; -background-color:#F2F2F2; -z-index:1; -height:20px; -padding:0px; -margin:0px; -padding-left:10px; -padding-top:2px; -margin-left:-5px; -margin-right:-5px; -} - -.breadcrumb ul{ - margin:0px; - padding:0px; -} - -.breadcrumb ul li{ -background-color:#F2F2F2; -list-style-type:none; -padding:0; -margin:0; -height:20px; -} - -.breadcrumb li{ -float:left; -} - -.breadcrumb .first { -background:url(../images/home.png); -background-position:left; -background-repeat:no-repeat; -padding-left:20px; -} - - -.breadcrumb li a{ -color:#2C418D; -display:block; -text-decoration:none; -background:url(../images/arrow.png); -background-repeat:no-repeat; -background-position:right; -padding-right:25px; -padding-left:10px; -} - -.breadcrumb li a:hover{ -color:#909090; -display:block; -text-decoration:none; -background:url(../images/arrow.png); -background-repeat:no-repeat; -background-position:right; -padding-right:20px; -padding-left:10px; -} - - -/* table of content -no display -*/ - -/* ------------ -headers ------------ -*/ - - -@media screen{ -.title{ -color:#313131; -font-size: 18px; -font-weight: normal; -left: 0; -padding-bottom: 20px; -padding-left: 10px; -padding-top: 20px; -position: absolute; -right: 0; -top: 0; -background-color:#E6E6E6; -border-bottom: 1px #CCC solid; -border-top: 2px #CCC solid; -font-weight:bold; -margin-left:0px; -margin-right:0px; -} -} - -h1 { -margin: 0; -} - -h2, p.h2 { -font: 500 16px/1.2 Arial; -font-weight:100; -background-color:#F2F3F4; -padding:4px; -margin-bottom:30px; -margin-top:30px; -border-top:#E0E0DE 1px solid; -border-bottom: #E0E0DE 1px solid; -max-width: 99%; -} - -h3{ - -font: 500 14px/1.2 Arial; -font-weight:100; -text-decoration:underline; -margin-bottom:30px; -margin-top:30px; -} - -h3.fn,span.fn{ -border-width: 1px; -border-style: solid; -border-color: #E6E6E6; --moz-border-radius: 7px 7px 7px 7px; --webkit-border-radius: 7px 7px 7px 7px; -border-radius: 7px 7px 7px 7px; -background-color: #F6F6F6; -word-spacing: 3px; -padding: 5px 5px; -text-decoration:none; -font-weight:bold; -max-width:75%; -font-size:14px; -margin:0px; -margin-top:30px; - -} - -.name{ -color:#1A1A1A; -} -.type{ -color:#808080; -} - - - -@media print { -.title { -color:#0066CB; -font-family:Arial, Helvetica; -font-size: 32px; -font-weight: normal; -left: 0; -position: absolute; -right: 0; -top: 0; -} -} - - -/* ------------------ -table styles ------------------ -*/ -.table img { -border:none; -margin-left:0px; --moz-box-shadow:0px 0px 0px #fff; --webkit-box-shadow: 0px 0px 0px #fff; -box-shadow: 0px 0px 0px #fff; -} - -/* table with border alternative colours*/ - - table,pre{ --moz-border-radius: 7px 7px 7px 7px; --webkit-border-radius: 7px 7px 7px 7px; - border-radius: 7px 7px 7px 7px; -background-color: #F6F6F6; -border: 1px solid #E6E6E6; -border-collapse: separate; -font-size: 12px; -line-height: 1.2; -margin-bottom: 25px; -margin-left: 15px; -font-size: 12px; -line-height: 1.2; -margin-bottom: 25px; -margin-left: 15px; -} - - -table th{ -text-align:left; -padding-left:20px; -} - -table td { -padding: 3px 15px 3px 20px; -border-bottom:#CCC dotted 1px; -} -table p { margin:0px;} - -table tr.even { -background-color: white; -color: #66666E; -} - -table tr.odd { -background-color: #F6F6F6; -color: #66666E; -} - - -table thead { -text-align:left; -padding-left:20px; -background-color:#e1e0e0; -border-left:none; -border-right:none; -} - -table thead th { -padding-top:5px; -padding-left:10px; -padding-bottom:5px; -border-bottom: 2px solid #D1D1D1; -padding-right:10px; -} - - -/* table bodless & white*/ - -.borderless { -border-radius: 0px 0px 0px 0px; -background-color: #fff; -border: 1px solid #fff; -} - -.borderless tr { -background-color: #FFF; -color: #66666E; -} - -.borderless td { -border:none; -border-bottom:#fff dotted 1px; -} - -/* ------------ -List ------------ -*/ - -ul{ -padding-bottom:2px; -} - -li ul { -padding-top: 10px; -} -li { -margin-bottom: 10px; -padding-left: 8px; -list-style:outside; -list-style-type:square; -text-align:left; -} - - -ol{ -margin:10px; -padding:0; -} - -ol > li{ -margin-left: 30px; -padding-left:8px; -list-style:decimal; -} - -.centerAlign{ -text-align: left; -} - -.cpp{ -display: block; -margin: 10; -overflow: hidden; -overflow-x: hidden; -overflow-y: hidden; -padding: 20px 0 20px 0; -} - -.footer{ -margin-top: 50px; -padding-left:5px; -margin-bottom: 10px; -font-size:10px; -border-top: 1px solid #999; -padding-top:11px; -} - -.footerNavi{ -width:auto; -text-align:right; -margin-top:50px; -z-index:1; -} - -.memItemLeft{ -padding-right: 3px; -} - -.memItemRight{ -padding: 3px 15px 3px 0; -} - -.qml{ -display: block; -margin: 10; -overflow: hidden; -overflow-x: hidden; -overflow-y: hidden; -padding: 20px 0 20px 0; -} - -.qmldefault{ -padding-left: 5px; -float: right; -color: red; -} - -.qmlreadonly{ -padding-left: 5px; -float: right; -color: #254117; -} - -.rightAlign{ -padding: 3px 5px 3px 10px; -text-align: right; -} - -/* ------------ -Content table ------------ -*/ - -@media print{ -.toc { -float: right; -padding-bottom: 10px; -padding-top: 50px; -width: 100%; -background-image:url(../images/bgrContent.png); -background-position:top; -background-repeat:no-repeat; -} -} - -@media screen{ -.toc{ -clear:both; -float:right; -vertical-align:top; --moz-border-radius: 7px 7px 7px 7px; --webkit-border-radius: 7px 7px 7px 7px; -border-radius: 7px 7px 7px 7px; - background:#FFF url(../images/bgrContent.png); -background-position:top; -background-repeat:repeat-x; -border: 1px solid #E6E6E6; -padding-left:5px; -padding-bottom:10px; -height: auto; -width: 200px; -text-align:left; -z-index:2; -margin-left:20px; -margin-right:20px; -margin-top:0px; -padding-top:0px; -} -} - -.toc h3{ -text-decoration:none; -} - -.toc h3{font: 500 14px/1.2 Arial; -font-weight:100; -padding:0px; -margin:0px; -padding-top:5px; -padding-left:5px; -} - - -.toc ul{ -width:160px; -padding-left:10px; -padding-right:5px; -padding-bottom:10px; -padding-top:10px; -} - -.toc ul li{ -margin-left:20px; -list-style-image:url(../images/blu_dot.png); -list-style:outside; - -} - - -.toc ul li a:link{ -color: #2C418D; -text-decoration: none; -} - -.toc ul li a:hover{ -color: #869CD1; -text-decoration:underline; - -} - -.toc ul li a:visited{ -color: #869CD1; -font-weight: bold; -} - -.level1{ -border:none;} - -.clearfix{ -clear:both;} - diff --git a/doc/templates/style/style.css b/doc/templates/style/style.css deleted file mode 100644 index af16d41e7..000000000 --- a/doc/templates/style/style.css +++ /dev/null @@ -1,1592 +0,0 @@ -@media screen -{ - -/* basic elements */ - html - { - color: #000000; - background: #FFFFFF; - } - body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, p, blockquote, th, td - { - margin: 0; - padding: 0; - } - table - { - border-collapse: collapse; - border-spacing: 0; - } - fieldset, img - { - border: 0; - max-width:100%; - } - address, caption, cite, code, dfn, em, strong, th, var, optgroup - { - font-style: inherit; - font-weight: inherit; - } - del, ins - { - text-decoration: none; - } - li - { - list-style: none; - } - ol li - { - list-style: decimal; - } - caption, th - { - text-align: left; - } - h1, h2, h3, h4, h5, h6 - { - font-size: 100%; - } - q:before, q:after - { - content: ''; - } - abbr, acronym - { - border: 0; - font-variant: normal; - } - sup, sub - { - vertical-align: baseline; - } - tt, .qmlreadonly span, .qmldefault span - { - word-spacing:5px; - } - legend - { - color: #000000; - } - input, button, textarea, select, optgroup, option - { - font-family: inherit; - font-size: inherit; - font-style: inherit; - font-weight: inherit; - } - input, button, textarea, select - { - font-size: 100%; - } - strong - { - font-weight: bold; - } - em - { - font-style: italic; - } - - /* adding Qt theme */ - html - { - /* background-color: #e5e5e5;*/ - } - body - { - background: #e6e7e8 url(../images/page_bg.png) repeat-x 0 0; - font: normal 13px/1.2 Verdana; - color: #363534; - } - a - { - color: #00732f; - text-decoration: none; - } - hr - { - background-color: #E6E6E6; - border: 1px solid #E6E6E6; - height: 1px; - width: 100%; - text-align: left; - margin: 15px 0px 15px 0px; - } - - pre - { - border: 1px solid #DDDDDD; - -moz-border-radius: 7px 7px 7px 7px; - -webkit-border-radius: 7px 7px 7px 7px; - border-radius: 7px 7px 7px 7px; - margin: 0 20px 10px 10px; - padding: 20px 15px 20px 20px; - overflow-x: auto; - } - table, pre - { - -moz-border-radius: 7px 7px 7px 7px; - -webkit-border-radius: 7px 7px 7px 7px; - border-radius: 7px 7px 7px 7px; - background-color: #F6F6F6; - border: 1px solid #E6E6E6; - border-collapse: separate; - font-size: 11px; - margin-bottom: 25px; - } - pre.highlightedCode { - display: block; - overflow:hidden; - } - thead - { - margin-top: 5px; - font:600 12px/1.2 Arial; - } - th - { - padding: 5px 15px 5px 15px; - background-color: #E1E1E1; - border-left: 1px solid #E6E6E6; - } - td - { - padding: 3px 15px 3px 15px; - } - tr.odd td:hover, tr.even td:hover {} - - td.rightAlign - { - padding: 3px 5px 3px 10px; - } - table tr.odd - { - border-left: 1px solid #E6E6E6; - background-color: #F6F6F6; - color: #66666E; - } - table tr.even - { - border-left: 1px solid #E6E6E6; - background-color: #ffffff; - color: #66666E; - } - table tr.odd td:hover, table tr.even td:hover - { - /* background-color: #E6E6E6;*/ /* disabled until further notice */ - } - - span.comment - { - color: #8B0000; - font-style: italic; - } - span.string, span.char - { - color: #254117; - } - - -/* end basic elements */ - -/* font style elements */ - .heading - { - font: normal bold 16px/1.2 Arial; - padding-bottom: 15px; - } - .subtitle - { - font-size: 13px; - } - .small-subtitle - { - font-size: 13px; - } -/* end font style elements */ - -/* global settings*/ - .header, .footer, .wrapper - { - min-width: 600px; - max-width: 1500px; - margin: 0 30px; - } - .header, .footer - { - display: block; - clear: both; - overflow: hidden; - } - .header:after, .footer:after, .breadcrumb:after, .wrap .content:after, .group:after - { - content: "."; - display: block; - height: 0; - clear: both; - visibility: hidden; - } - -/* end global settings*/ -/* header elements */ - .header - { - height: 115px; - position: relative; - } - .header .icon - { - position: absolute; - top: 13px; - left: 0; - } - .header .qtref - { - position: absolute; - top: 28px; - left: 88px; - width: 302px; - height: 22px; - } - .header .qtref span - { - display: block; - width: 302px; - height: 22px; - text-indent: -999em; - background: url(../images/sprites-combined.png) no-repeat -78px -235px; - } - .content a:visited - { - color: #4c0033; - text-decoration: none; - } - .content a:visited:hover - { - color: #4c0033; - text-decoration: underline; - } - - #nav-topright - { - height: 70px; - } - - #nav-topright ul - { - list-style-type: none; - float: right; - width: 370px; - margin-top: 11px; - } - - #nav-topright li - { - display: inline-block; - margin-right: 20px; - float: left; - } - - #nav-topright li.nav-topright-last - { - margin-right: 0; - } - - #nav-topright li a - { - background: transparent url(../images/sprites-combined.png) no-repeat; - height: 18px; - display: block; - overflow: hidden; - text-indent: -9999px; - } - - #nav-topright li.nav-topright-home a - { - width: 65px; - background-position: -2px -91px; - } - - #nav-topright li.nav-topright-home a:hover - { - background-position: -2px -117px; - } - - - #nav-topright li.nav-topright-dev a - { - width: 30px; - background-position: -76px -91px; - } - - #nav-topright li.nav-topright-dev a:hover - { - background-position: -76px -117px; - } - - - #nav-topright li.nav-topright-labs a - { - width: 40px; - background-position: -114px -91px; - } - - #nav-topright li.nav-topright-labs a:hover - { - background-position: -114px -117px; - } - - #nav-topright li.nav-topright-doc a - { - width: 32px; - background-position: -162px -91px; - } - - #nav-topright li.nav-topright-doc a:hover, #nav-topright li.nav-topright-doc-active a - { - background-position: -162px -117px; - } - - #nav-topright li.nav-topright-blog a - { - width: 40px; - background-position: -203px -91px; - } - - #nav-topright li.nav-topright-blog a:hover, #nav-topright li.nav-topright-blog-active a - { - background-position: -203px -117px; - } - - #nav-topright li.nav-topright-shop a - { - width: 40px; - background-position: -252px -91px; - } - - #nav-topright li.nav-topright-shop a:hover, #nav-topright li.nav-topright-shop-active a - { - background-position: -252px -117px; - } - - #nav-logo - { - background: transparent url(../images/sprites-combined.png ) no-repeat 0 -225px; - left: -3px; - position: absolute; - width: 75px; - height: 75px; - top: 13px; - } - #nav-logo a - { - width: 75px; - height: 75px; - display: block; - text-indent: -9999px; - overflow: hidden; - } - - - .shortCut-topleft-inactive - { - padding-left: 3px; - padding-right: 3px; - background: transparent url( ../images/sprites-combined.png) no-repeat 0px -58px; - height: 20px; - } - .shortCut-topleft-inactive span - { - font-variant: normal; - } - .shortCut-topleft-inactive span a:hover, .shortCut-topleft-active a:hover - { - text-decoration:none; - } - #shortCut - { - padding-top: 10px; - font-weight: bolder; - color: #b0adab; - } - #shortCut ul - { - list-style-type: none; - float: left; - width: 347px; - margin-left: 100px; - } - #shortCut li - { - display: inline-block; - margin-right: 25px; - float: left; - white-space: nowrap; - } - #shortCut li a - { - color: #b0adab; - } - #shortCut li a:hover - { - color: #44a51c; - } - - - -/* end header elements */ -/* content and sidebar elements */ - .wrapper - { - background: url(../images/bg_r.png) repeat-y 100% 0; - } - .wrapper .hd - { - padding-left: 216px; - height: 15px; - background: url(../images/page.png) no-repeat 0 0; - overflow: hidden; - } - - - - - .wrapper .hd span - { - height: 15px; - display: block; - overflow: hidden; - background: url(../images/page.png) no-repeat 100% -30px; - } - .wrapper .bd - { - background: url(../images/bg_l.png) repeat-y 0 0; - position: relative; - } - - - - - .wrapper .ft - { - padding-left: 216px; - height: 15px; - background: url(../images/page.png) no-repeat 0 -75px; - overflow: hidden; - } - - - - - .wrapper .ft span - { - height: 15px; - display: block; - background: url(../images/page.png) no-repeat 100% -60px; - overflow: hidden; - } - .navTop{ - float:right; - display:block; - padding-right:15px; - - - } - - - -/* end content and sidebar elements */ -/* sidebar elements */ - .sidebar - { - float: left; - margin-left: 5px; - width: 200px; - font-size: 11px; - } - - - - - - - .sidebar .searchlabel - { - padding: 0 0 2px 17px; - font: normal bold 11px/1.2 Verdana; - } - - .sidebar .search - { - padding: 0 15px 0 16px; - } - - .sidebar .search form - { - background: url(../images/sprites-combined.png) no-repeat -6px -348px; - height:21px; - padding:2px 0 0 5px; - width:167px; - } - - .sidebar .search form input#pageType - { - width: 158px; - height: 19px; - padding: 0; - border: 0px; - outline: none; - font: 13px/1.2 Verdana; - } - - .sidebar .box - { - padding: 17px 15px 5px 16px; - } - - .sidebar .box .first - { - background-image: none; - } - - .sidebar .box h2 - { - font: bold 16px/1.2 Arial; - padding: 0; - } - .sidebar .box h2 span - { - overflow: hidden; - display: inline-block; - } - .sidebar .box#lookup h2 - { - background-image: none; - } - .sidebar #lookup.box h2 span - { - } - .sidebar .box#topics h2 - { - background-image: none; - } - .sidebar #topics.box h2 span - { - } - .sidebar .box#examples h2 - { - background-image: none; - } - .sidebar #examples.box h2 span - { - } - - .sidebar .box .list - { - display: block; - max-height:200px; - min-height:120px; - overflow-y:auto; - overflow-x:none; - } - .list li a:hover - { - text-decoration: underline; - } - .sidebar .box ul - { - padding-bottom:5px; - padding-left:10px; - padding-top:5px; - } - .sidebar .box ul li - { - padding-left: 12px; - background: url(../images/bullet_gt.png) no-repeat 0 5px; - margin-bottom: 5px; - } - .sidebar .bottombar - { - background: url(../images/box_bg.png) repeat-x 0 bottom; - } - .sidebar .box ul li.noMatch - { - background: none; - color:#FF2A00; - font-style:italic; - } - .sidebar .box ul li.hit - { - background: none; - color:#AAD2F0; - font-style:italic; - } - .sidebar .search form input.loading - { - background:url("../images/spinner.gif") no-repeat scroll right center transparent; - } - -.floatingResult{ - z-index:1; - position:relative; - padding-top:0px; - background-color:white; - border:solid 1px black; - height:250px; - width:600px; - overflow-x:hidden; - overflow-y:auto; -} - - .floatingResult:hover{ - display:block; - } - .floatingResult:hover{ - } - -/* end sidebar elements */ -/* content elements */ - .wrap - { - margin: 0 5px 0 208px; - overflow: visible; - } - - - - - .wrap .toolbar - { - background-color: #fafafa; - border-bottom: 1px solid #d1d1d1; - height: 20px; - position: relative; - } - .wrap .toolbar .toolblock - { - position: absolute; - } - .wrap .toolbar .breadcrumb - { - font-size: 11px; - line-height: 1.2; - padding: 0 0 10px 21px; - height: 10px; - } - .wrap .toolbar .toolbuttons - { - padding: 0 0 10px 21px; - right: 5px; - vertical-align: middle; - overflow: hidden; - } - .wrap .toolbar .toolbuttons .active - { - color: #00732F; - } - .wrap .toolbar .toolbuttons ul - { - float: right; - } - .wrap .toolbar .toolbuttons li - { - float: left; - text-indent: -10px; - margin-top: -5px; - margin-right: 15px; - font-weight: bold; - color: #B0ADAB; - } - - .toolbuttons #print - { - border-left: 1px solid #c5c4c4; - margin-top: 0; - padding-left: 7px; - text-indent: 0; - } - .toolbuttons #print a - { - width: 16px; - height: 16px; - } - - .toolbuttons #print a span - { - width: 16px; - height: 16px; - text-indent: -999em; - display: block; - overflow: hidden; - background: url(../images/sprites-combined.png) no-repeat -137px -311px; - } - - .toolbuttons #smallA - { - font-size: 10pt; - } - .toolbuttons #medA - { - font-size: 12pt; - } - .toolbuttons #bigA - { - font-size: 14pt; - margin-right: 7px; - } - - #smallA:hover, #medA:hover, #bigA:hover - { - color: #00732F; - } - - - .wrap .content - { - padding: 30px; - word-wrap:break-word; - } - - .wrap .breadcrumb ul - { - } - .wrap .breadcrumb ul li - { - float: left; - background: url(../images/breadcrumb.png) no-repeat 0 3px; - padding-left: 15px; - margin-left: 15px; - font-weight: bold; - } - .wrap .breadcrumb ul li.last - { - font-weight: normal; - } - .wrap .breadcrumb ul li a - { - color: #363534; - } - .wrap .breadcrumb ul li.first - { - background-image: none; - padding-left: 0; - margin-left: 0; - } - - - - - .wrap .content ol li { - background:none; - font:normal 10pt/1.2 Verdana; - - margin-bottom:10px; - margin-left:12px; - /*list-style-type:disc;*/ - } - - .wrap .content ol li - { - background:none; - margin-bottom: 10px; - padding-left:0px; - margin-left:52px; - } - - .wrap .content li - { - background: url(../images/bullet_sq.png) no-repeat 0 5px; - font: normal 400 10pt/1.2 Verdana; - margin-bottom: 10px; - padding-left:12px; - } - - .content li:hover {} - - .wrap .content h1 - { - font: bold 18px/1.2 Arial; - } - .wrap .content h2 - { - border-bottom:1px solid #DDDDDD; - font:600 16px/1.2 Arial; - margin-top:15px; - width:100%; - } - .wrap .content h3 - { - font: bold 14px/1.2 Arial; - font:600 16px/1.2 Arial; - margin-top:15px; - width:100%; - } - .wrap .content p - { - line-height: 20px; - padding: 5px; - } - .wrap .content table p - { - line-height: 20px; - /* padding: 0px;*/ - } - .wrap .content ul - { - padding-left: 25px; - padding-top: 10px; - } - .wrap .content ul img { - vertical-align:middle; - } - a:hover - { - color: #4c0033; - text-decoration: underline; - } - .feedback - { - float: none; - position: absolute; - right: 15px; - bottom: 10px; - font: normal 8px/1 Verdana; - color: #B0ADAB; - } - .feedback:hover - { - float: right; - font: normal 8px/1 Verdana; - color: #00732F; - text-decoration: underline; - } - .alphaChar{ - width:95%; - background-color:#F6F6F6; - border:1px solid #E6E6E6; - -moz-border-radius: 7px 7px 7px 7px; - border-radius: 7px 7px 7px 7px; - -webkit-border-radius: 7px 7px 7px 7px; - font-size:12pt; - padding-left:10px; - margin-top:10px; - margin-bottom:10px; - } - .flowList{ - /*vertical-align:top;*/ - /*margin:20px auto;*/ - - column-count:3; - -webkit-column-count:3; - -moz-column-count:3; -/* - column-width:100%; - -webkit-column-width:200px; - -col-column-width:200px; -*/ - column-gap:41px; - -webkit-column-gap:41px; - -moz-column-gap:41px; - - column-rule: 1px dashed #ccc; - -webkit-column-rule: 1px dashed #ccc; - -moz-column-rule: 1px dashed #ccc; - } - - .flowList dl{ - } - .flowList dd{ - /*display:inline-block;*/ - margin-left:10px; - min-width:250px; - line-height: 1.2; - min-width:100%; - - } - - .flowList dd a{ - } - - .wrap .content .flowList p{ - padding:0px; - } - - .content .alignedsummary - { - margin: 15px; - } - - - .qmltype - { - text-align: center; - font-size: 160%; - } - .qmlreadonly - { - padding-left: 5px; - float: right; - color: #254117; - } - - .qmldefault - { - padding-left: 5px; - float: right; - color: red; - } - - .qmldoc - { - } - - *.qmlitem p - { - } - #feedbackBox - { - display: none; - -moz-border-radius: 7px 7px 7px 7px; - -webkit-border-radius: 7px 7px 7px 7px; - border-radius: 7px 7px 7px 7px; - border: 1px solid #DDDDDD; - position: fixed; - top: 100px; - left: 33%; - height: 230px; - width: 400px; - padding: 5px; - background-color: #e6e7e8; - z-index: 4; - } - #feedcloseX - { - display: inline; - padding: 5px 5px 0 0; - margin-bottom: 3px; - color: #363534; - font-weight: bold; - float: right; - text-decoration: none; - } - - #feedbox - { - display: inline; - width: 370px; - height: 120px; - margin: 0px 25px 10px 15px; - } - #noteHead - { - font-weight:bold; - padding:10px 10px 10px 20px; - } - #feedsubmit - { - display: inline; - float: right; - margin: 4px 32px 0 0; - } - - .note - { - font-size:7pt; - padding-bottom:3px; - padding-left:20px; - } - - #blurpage - { - display: none; - position: fixed; - float: none; - top: 0px; - left: 0px; - right: 0px; - bottom: 0px; - background: transparent url(../images/feedbackground.png) 0 0; - z-index: 3; - } - .toc - { - float: right; - -moz-border-radius: 7px 7px 7px 7px; - -webkit-border-radius: 7px 7px 7px 7px; - border-radius: 7px 7px 7px 7px; - background-color: #F6F6F6; - border: 1px solid #DDDDDD; - margin: 0 20px 10px 10px; - padding: 20px 15px 20px 20px; - height: auto; - width: 200px; - } - - .toc h3, .generic a - { - font: bold 12px/1.2 Arial; - } - - .generic{ - } - .generic td{ - /* padding:5px;*/ - } - .generic .alphaChar{ - margin-top:5px; - } - - .generic .odd .alphaChar{ - background-color: #F6F6F6; - } - - .generic .even .alphaChar{ - background-color: #FFFFFF; - } - - .alignedsummary{} - .propsummary{} - .memItemLeft{} - .memItemRight{ - padding:3px 15px 3px 0; - } - .bottomAlign{} - .highlightedCode - { - margin:10px; - } - .LegaleseLeft{} - .valuelist{} - .annotated td{ - padding: 3px 5px 3px 5px; - } - .obsolete{} - .compat{} - .flags{} - .qmlsummary{} - .qmlitem{} - .qmlproto{} - .qmlname{} - .qmlreadonly{} - .qmldefault{} - .qmldoc{} - .qt-style{} - .redFont{} - code{} - - .wrap .content .toc ul - { - padding-left: 0px; - } - - .wrap .content .toc h3{ - border-bottom:0px; - margin-top:0px; - } - - .wrap .content .toc h3 a:hover{ - color:#00732F; - text-decoration:none; - } - - - .wrap .content .toc .level2 - { - margin-left: 15px; - } - - .wrap .content .toc .level3 - { - margin-left: 30px; - } - - .content .toc li - { - font: normal 10px/1.2 Verdana; - background: url(../images/bullet_dn.png) no-repeat 0 5px; - } - .relpage - { - -moz-border-radius: 7px 7px 7px 7px; - -webkit-border-radius: 7px 7px 7px 7px; - border-radius: 7px 7px 7px 7px; - border: 1px solid #DDDDDD; - padding: 25px 25px; - clear: both; - } - .relpage ul - { - float: none; - padding: 15px; - } - .content .relpage li - { - font: normal 11px/1.2 Verdana; - } - h3.fn, span.fn - { - -moz-border-radius:7px 7px 7px 7px; - -webkit-border-radius:7px 7px 7px 7px; - border-radius:7px 7px 7px 7px; - background-color: #F6F6F6; - border-width: 1px; - border-style: solid; - border-color: #E6E6E6; - font-weight: bold; - word-spacing:3px; - padding:3px 5px; - } - - .functionIndex { - font-size:12pt; - word-spacing:10px; - margin-bottom:10px; - background-color: #F6F6F6; - border-width: 1px; - border-style: solid; - border-color: #E6E6E6; - -moz-border-radius: 7px 7px 7px 7px; - -webkit-border-radius: 7px 7px 7px 7px; - border-radius: 7px 7px 7px 7px; - width:100%; - } - - .centerAlign - { - text-align:center; - } - - .rightAlign - { - text-align:right; - } - - - .leftAlign - { - text-align:left; - } - - .topAlign{ - vertical-align:top - } - - .functionIndex a{ - display:inline-block; - } - -/* end content elements */ -/* footer elements */ - - .footer - { - min-height: 100px; - color: #797775; - font: normal 9px/1 Verdana; - text-align: center; - padding-top: 40px; - background-color: #E6E7E8; - margin: 0; - } -/* end footer elements */ - - - - - /* start index box */ - .indexbox - { - width: 100%; - display:inline-block; - } - - .indexboxcont - { - display: block; - - } - - .indexboxbar - { - background: transparent url(../images/horBar.png ) repeat-x left bottom; - margin-bottom: 25px; - - - } - - .indexboxcont .section - { - display: inline-block; - width: 49%; - *width:42%; - _width:42%; - padding:0 2% 0 1%; - vertical-align:top; - -} - - .indexboxcont .indexIcon - { - width: 11%; - *width:18%; - _width:18%; - overflow:hidden; - -} - -.indexboxcont .section { - float: left; -} - - .indexboxcont .section p - { - padding-top: 20px; - padding-bottom: 20px; - } - .indexboxcont .sectionlist - { - display: inline-block; - vertical-align:top; - width: 32.5%; - padding: 0; - } - .indexboxcont .sectionlist ul - { - margin-bottom: 20px; - } - - .indexboxcont .sectionlist ul li - { - line-height: 12px; - } - - .content .indexboxcont li - { - font: normal bold 13px/1 Verdana; - } - - .indexbox a:hover, .indexbox a:visited:hover - { - color: #4c0033; - text-decoration: underline; - } - - .indexbox a:visited - { - color: #00732f; - text-decoration: none; - } - - .indexbox .indexIcon { - width: 11%; - } - - - .indexbox .indexIcon span - { - display: block; - } - - .indexbox.guide .indexIcon span - { - width: 96px; - height: 137px; - background: url(../images/sprites-combined.png) no-repeat -5px -376px; - padding: 0; - } - - .indexbox.tools .indexIcon span - { - width: 115px; - height: 137px; - background: url(../images/sprites-combined.png) no-repeat -111px -376px; - padding: 0; - } - .indexboxcont:after - { - content: "."; - display: block; - height: 0; - clear: both; - visibility: hidden; - } - - - -/* start of creator spec*/ - .creator - { - margin-left:0px; - margin-right:0px; - padding-left:0px; - padding-right:0px; - } - .creator .wrap .content ol li { - list-style-type:decimal; - - } - .creator .header .icon, - .creator .feedback, - .creator .t_button, - .creator .feedback, - .creator #feedbackBox, - .creator #feedback, - .creator #blurpage, - /*.creator .indexbox .indexIcon span,*/ - .creator .wrapper .hd, -/* .creator .indexbox .indexIcon,*/ - .creator .header #nav-logo, - .creator #offlinemenu, - .creator #offlinesearch, - .creator .header #nav-topright, - .creator .header #shortCut , - .creator .wrapper .hd, - .creator .wrapper .ft, - .creator .sidebar, - .creator .wrap .feedback - { - display:none; - } - - body.creator - { - background: none; - - font: normal 13px/1.2 Verdana; - color: #363534; - background-color: #FAFAFA; - } - - .wrap .content ol li { - - } - - - .creator .header, .footer, .wrapper - { - max-width: 1500px; - margin: 0px; - } - - .creator .wrapper - { - position:relative; - top:5px; - } - .creator .wrapper .bd - { - - background:#FFFFFF; - } - - - .creator .header, .footer - { - display: block; - clear: both; - overflow: hidden; - } - .creator .wrap .content p - - { - line-height: 20px; - padding: 5px; - } - - .creator .header .qtref span - { - background:none; - } - - - - .creator .footer - { - border-top:1px solid #E5E5E5; - height: 50px; - margin:0px; - padding:10px; - } - - .creator .footer p - { - text-align:justify; - max-width:900px; - } - - .creator .wrap - { - - padding:0 5px 0 5px; - margin: 0px; - } - .creator .wrap .toolbar - { - - - border-bottom:1px solid #E5E5E5; - /*width:100%;*/ - margin-left:-5px; - margin-right:-5px; - } - .creator .wrap .breadcrumb ul li a - { - /* color: #363534;*/ - color: #00732F; - } - - .creator .wrap .content - { - padding: 0px; - word-wrap:break-word; - } - - .creator .wrap .content ol li { - background:none; - font: inherit; - padding-left: 0px; - } - - .creator .wrap .content .descr ol li { - margin-left: 45px; - - } - .creator .content .alignedsummary - { - margin: 5px; - width:100%; - } - .creator .generic{ - max-width:75%; - } - .creator .generic td{ - /* padding:0;*/ - } - .creator .indexboxbar - { - border-bottom:1px solid #E5E5E5; - margin-bottom: 25px; - background: none; - } - - - - .creator .header - { - width: 100%; - margin: 0; - height: auto; - background-color: #ffffff; - padding: 10px 0 5px 0; - overflow: visible; - border-bottom: solid #E5E5E5 1px; - z-index:1; - - - - - - - - - /* position:fixed;*/ - } - - - .creator .header .content - { - } - .creator .header .qtref - { - color: #00732F; - position: static; - float: left; - margin-left: 5px; - font: bold 18px/1 Arial; - } - - .creator .header .qtref:visited - { - color: #00732F; - } - .creator .header .qtref:hover - { - color: #00732F; - text-decoration:none; - } - .creator .header .qtref span - { - background-image: none; - text-indent: 0; - text-decoration:none; - } - - - - - - - .creator .wrap .toolbar - { - display:block; - padding-top:0px; - } - - - - .creator .wrap .breadcrumb ul li { - font-weight: normal; - } - - .creator .wrap .breadcrumb ul li a { - /*color: #44a51c;*/ - } - - .creator .wrap .breadcrumb ul li.last a { - /*color: #363534;*/ - } - - .creator #narrowmenu ul - { - border-bottom:solid 1px #E5E5E5; - border-left:solid 1px #E5E5E5; - border-right:solid 1px #E5E5E5; - } - - .creator #narrowmenu li ul { - margin-top:-15px; - } - - - .creator .toc { - margin:10px 20px 10px 10px; - } - - .creator #narrowsearch, .creator #narrowmenu{ - display:none; - } -/* end of creator spec*/ - -} - -/* end of screen media */ - -/* start of print media */ - -@media print -{ - input, textarea, .header, .footer, .toolbar, .feedback, .wrapper .hd, .wrapper .bd .sidebar, .wrapper .ft, #feedbackBox, #blurpage, .toc, .breadcrumb, .toolbar, .floatingResult - { - display: none; - background: none; - } - .content - { - background: none; - display: block; - width: 100%; margin: 0; float: none; - - } -} -/* end of print media */ diff --git a/doc/templates/style/style_ie6.css b/doc/templates/style/style_ie6.css deleted file mode 100644 index 16fb8505d..000000000 --- a/doc/templates/style/style_ie6.css +++ /dev/null @@ -1,54 +0,0 @@ -.indexbox, .indexboxcont, .group { - zoom: 1; - height: 1%; -} - -.sidebar { - margin-left: 3px; - width: 199px; - overflow: hidden; -} - -.sidebar .search form { - position: relative; -} - -.sidebar .search form fieldset { - position: absolute; - margin-top: -1px; -} - -.sidebar .search form input#searchstring { - border: 1px solid #fff; - height: 18px; -} - -.wrap { - zoom: 1; -} - -.content, -.toolbar { - zoom: 1; - margin-left: -3px; - position: relative; -} - -.indexbox { - clear: both; -} - -.indexboxcont .section { - zoom: 1; - float: left; -} - -.indexboxcont .sectionlist { - zoom: 1; - float: left; -} - -.wrap .toolbar .toolbuttons li { - text-indent: 0; - margin-right: 8px; -}
\ No newline at end of file diff --git a/doc/templates/style/style_ie7.css b/doc/templates/style/style_ie7.css deleted file mode 100644 index afbff5f88..000000000 --- a/doc/templates/style/style_ie7.css +++ /dev/null @@ -1,19 +0,0 @@ -.indexbox, .indexboxcont, .group { - min-height: 1px; -} - -.sidebar .search form input#searchstring { - border: 1px solid #fff; - height: 17px; -} - - -.indexboxcont .section { - zoom: 1; - float: left; -} - -.indexboxcont .sectionlist { - zoom: 1; - float: left; -} diff --git a/doc/templates/style/superfish.css b/doc/templates/style/superfish.css deleted file mode 100644 index 2bdaef4d9..000000000 --- a/doc/templates/style/superfish.css +++ /dev/null @@ -1,51 +0,0 @@ -.sf-menu, .sf-menu * { - margin: 0; - padding: 0; - list-style: none; -} -.sf-menu { - line-height: 1.0; -} -.sf-menu ul { - position: absolute; - top: -999em; - width: 10em; /* left offset of submenus need to match (see below) */ -} -.sf-menu ul li { - width: 100%; -} -.sf-menu li:hover { - visibility: inherit; /* fixes IE7 'sticky bug' */ -} -.sf-menu li { - float: left; - position: relative; -} -.sf-menu a { - display: block; - position: relative; -} -.sf-menu li:hover ul, -.sf-menu li.sfHover ul { - left: 0; - top: 2.5em; /* match top ul list item height */ - z-index: 99; -} -ul.sf-menu li:hover li ul, -ul.sf-menu li.sfHover li ul { - top: -999em; -} -ul.sf-menu li li:hover ul, -ul.sf-menu li li.sfHover ul { - left: 10em; /* match ul width */ - top: 0; -} -ul.sf-menu li li:hover li ul, -ul.sf-menu li li.sfHover li ul { - top: -999em; -} -ul.sf-menu li li li:hover ul, -ul.sf-menu li li li.sfHover ul { - left: 10em; /* match ul width */ - top: 0; -} diff --git a/doc/templates/style/superfish_skin.css b/doc/templates/style/superfish_skin.css deleted file mode 100644 index 8d84827c4..000000000 --- a/doc/templates/style/superfish_skin.css +++ /dev/null @@ -1,83 +0,0 @@ - -/*** DEMO SKIN ***/ -.sf-menu { - float: left; - margin-bottom: 1em; -} -.sf-menu a { - border-left: 1px solid #fff; - border-top: 1px solid #CFDEFF; - padding: .75em 1em; - text-decoration:none; -} -.sf-menu a, .sf-menu a:visited { /* visited pseudo selector so IE6 applies text colour*/ - color: #13a; -} -.sf-menu li { - background: #BDD2FF; -} -.sf-menu li li { - background: #AABDE6; -} -.sf-menu li li li { - background: #9AAEDB; -} -.sf-menu li:hover, .sf-menu li.sfHover, -.sf-menu a:focus, .sf-menu a:hover, .sf-menu a:active { - background: #CFDEFF; - outline: 0; -} - -/*** arrows **/ -.sf-menu a.sf-with-ul { - padding-right: 2.25em; - min-width: 1px; /* trigger IE7 hasLayout so spans position accurately */ -} -.sf-sub-indicator { - position: absolute; - display: block; - right: .75em; - top: 1.05em; /* IE6 only */ - width: 10px; - height: 10px; - text-indent: -999em; - overflow: hidden; - background: url('../images/arrows-ffffff.png') no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */ -} -a > .sf-sub-indicator { /* give all except IE6 the correct values */ - top: .8em; - background-position: 0 -100px; /* use translucent arrow for modern browsers*/ -} -/* apply hovers to modern browsers */ -a:focus > .sf-sub-indicator, -a:hover > .sf-sub-indicator, -a:active > .sf-sub-indicator, -li:hover > a > .sf-sub-indicator, -li.sfHover > a > .sf-sub-indicator { - background-position: -10px -100px; /* arrow hovers for modern browsers*/ -} - -/* point right for anchors in subs */ -.sf-menu ul .sf-sub-indicator { background-position: -10px 0; } -.sf-menu ul a > .sf-sub-indicator { background-position: 0 0; } -/* apply hovers to modern browsers */ -.sf-menu ul a:focus > .sf-sub-indicator, -.sf-menu ul a:hover > .sf-sub-indicator, -.sf-menu ul a:active > .sf-sub-indicator, -.sf-menu ul li:hover > a > .sf-sub-indicator, -.sf-menu ul li.sfHover > a > .sf-sub-indicator { - background-position: -10px 0; /* arrow hovers for modern browsers*/ -} - -/*** shadows for all but IE6 ***/ -.sf-shadow ul { - background: url('../images/shadow.png') no-repeat bottom right; - padding: 0 8px 9px 0; - -moz-border-radius-bottomleft: 17px; - -moz-border-radius-topright: 17px; - -webkit-border-top-right-radius: 17px; - -webkit-border-bottom-left-radius: 17px; -} -.sf-shadow ul.sf-shadow-off { - background: transparent; -} diff --git a/examples/collidingmice/collidingmice.qbs b/examples/collidingmice/collidingmice.qbs index 0ec1bdbed..312f6b0ab 100644 --- a/examples/collidingmice/collidingmice.qbs +++ b/examples/collidingmice/collidingmice.qbs @@ -53,6 +53,7 @@ import qbs 1.0 Application { name : "CollidingMice" Depends { name: "Qt.widgets" } + property bool isBundle: qbs.targetOS.contains("darwin") && bundle.isBundle files : [ "images/cheese.jpg", "main.cpp", @@ -61,9 +62,9 @@ Application { "mice.qrc" ] Group { - fileTagsFilter: bundle.isBundle ? ["bundle.content"] : ["application"] + fileTagsFilter: isBundle ? ["bundle.content"] : ["application"] qbs.install: true - qbs.installPrefix: bundle.isBundle ? "Applications" : "bin" + qbs.installPrefix: isBundle ? "Applications" : "bin" qbs.installSourceBase: product.buildDirectory } } diff --git a/examples/examples.qbs b/examples/examples.qbs index 0e4e5052c..4e51bdbaf 100644 --- a/examples/examples.qbs +++ b/examples/examples.qbs @@ -62,5 +62,7 @@ Project { "helloworld-minimal/hello.qbs", "helloworld-qt/hello.qbs", "install-bundle/install-bundle.qbs", + "protobuf/cpp/addressbook.qbs", + "protobuf/objc/addressbook.qbs", ] } diff --git a/examples/protobuf/cpp/README.md b/examples/protobuf/cpp/README.md new file mode 100644 index 000000000..f0e1b1a93 --- /dev/null +++ b/examples/protobuf/cpp/README.md @@ -0,0 +1,13 @@ +### Addressbook c++ example + +This example shows how to build a cpp application that uses Google protobuf. + +In order to build this example, you'll need to have a protobuf headers and library installed in the system in locations where QBS can find them. + +On Linux, you can install a package to the system. + +On macOS, you can use brew or compile and install protobuf manually: +- to /usr/local/ +- to any folder, say /Users/<USER>/protobuf. Then you'll need to set protobuf.libraryPath: "/Users/<USER>/protobuf/lib" and protobuf.includePath: "/Users/<USER>/protobuf/include" + +On Windows, you have to compile and install protobuf manually to any folder and use libraryPath and includePath as shown above diff --git a/examples/protobuf/cpp/addressbook.qbs b/examples/protobuf/cpp/addressbook.qbs new file mode 100644 index 000000000..bd5afd377 --- /dev/null +++ b/examples/protobuf/cpp/addressbook.qbs @@ -0,0 +1,18 @@ +import qbs + +CppApplication { + name: "addressbook_cpp" + consoleApplication: true + condition: protobuf.present + + Depends { name: "cpp" } + cpp.cxxLanguageVersion: "c++11" + + Depends { id: protobuf; name: "protobuf.cpp"; required: false } + + files: [ + "../shared/addressbook.proto", + "main.cpp", + "README.md", + ] +} diff --git a/examples/protobuf/cpp/main.cpp b/examples/protobuf/cpp/main.cpp new file mode 100644 index 000000000..703a9d302 --- /dev/null +++ b/examples/protobuf/cpp/main.cpp @@ -0,0 +1,171 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <ctime> +#include <fstream> +#include <google/protobuf/util/time_util.h> +#include <iostream> +#include <string> + +#include "addressbook.pb.h" + +using google::protobuf::util::TimeUtil; + +int printUsage(char *argv0) +{ + std::cerr << "Usage: " << argv0 << "add|list ADDRESS_BOOK_FILE" << std::endl; + return -1; +} + +std::string readString(const std::string &promt) +{ + std::string result; + std::cout << promt; + std::getline(std::cin, result); + return result; +} + +// This function fills in a Person message based on user input. +void promptForAddress(tutorial::Person* person) +{ + std::cout << "Enter person ID number: "; + int id; + std::cin >> id; + person->set_id(id); + std::cin.ignore(256, '\n'); + + *person->mutable_name() = readString("Enter name: "); + + const auto email = readString("Enter email address (blank for none): "); + if (!email.empty()) + person->set_email(email); + + while (true) { + const auto number = readString("Enter a phone number (or leave blank to finish): "); + if (number.empty()) + break; + + tutorial::Person::PhoneNumber *phone_number = person->add_phones(); + phone_number->set_number(number); + + const auto type = readString("Is this a mobile, home, or work phone? "); + if (type == "mobile") + phone_number->set_type(tutorial::Person::MOBILE); + else if (type == "home") + phone_number->set_type(tutorial::Person::HOME); + else if (type == "work") + phone_number->set_type(tutorial::Person::WORK); + else + std::cout << "Unknown phone type. Using default." << std::endl; + } + *person->mutable_last_updated() = TimeUtil::SecondsToTimestamp(time(NULL)); +} + +// Iterates though all people in the AddressBook and prints info about them. +void listPeople(const tutorial::AddressBook& address_book) +{ + for (int i = 0; i < address_book.people_size(); i++) { + const tutorial::Person& person = address_book.people(i); + + std::cout << "Person ID: " << person.id() << std::endl; + std::cout << " Name: " << person.name() << std::endl; + if (person.email() != "") { + std::cout << " E-mail address: " << person.email() << std::endl; + } + + for (int j = 0; j < person.phones_size(); j++) { + const tutorial::Person::PhoneNumber& phone_number = person.phones(j); + + switch (phone_number.type()) { + case tutorial::Person::MOBILE: + std::cout << " Mobile phone #: "; + break; + case tutorial::Person::HOME: + std::cout << " Home phone #: "; + break; + case tutorial::Person::WORK: + std::cout << " Work phone #: "; + break; + default: + std::cout << " Unknown phone #: "; + break; + } + std::cout << phone_number.number() << std::endl; + } + if (person.has_last_updated()) { + std::cout << " Updated: " << TimeUtil::ToString(person.last_updated()) << std::endl; + } + } +} + +int main(int argc, char* argv[]) { + // Verify that the version of the library that we linked against is + // compatible with the version of the headers we compiled against. + GOOGLE_PROTOBUF_VERIFY_VERSION; + + if (argc != 3) + return printUsage(argv[0]); + + tutorial::AddressBook address_book; + + // Read the existing address book. + std::fstream input(argv[2], std::ios::in | std::ios::binary); + if (!input) { + std::cout << argv[2] << ": File not found." << std::endl; + } else if (!address_book.ParseFromIstream(&input)) { + std::cerr << "Failed to parse address book." << std::endl; + return -1; + } + + const std::string mode(argv[1]); + if (mode == "add") { + // Add an address. + promptForAddress(address_book.add_people()); + + if (!input) + std::cout << "Creating a new file." << std::endl; + + // Write the new address book back to disk. + std::fstream output(argv[2], std::ios::out | std::ios::trunc | std::ios::binary); + if (!address_book.SerializeToOstream(&output)) { + std::cerr << "Failed to write address book." << std::endl; + return -1; + } + } else if (mode == "list") { + listPeople(address_book); + } else { + return printUsage(argv[0]); + } + + // Optional: Delete all global objects allocated by libprotobuf. + google::protobuf::ShutdownProtobufLibrary(); + + return 0; +} diff --git a/examples/protobuf/objc/README.md b/examples/protobuf/objc/README.md new file mode 100644 index 000000000..c0fc7c0e5 --- /dev/null +++ b/examples/protobuf/objc/README.md @@ -0,0 +1,5 @@ +### Addressbook objc example + +This example shows how to build an objective-c application that uses Google protobuf. + +In order to build this example, you'll need to have a ProtocolBuffers library or framework installed in the system. diff --git a/examples/protobuf/objc/addressbook.qbs b/examples/protobuf/objc/addressbook.qbs new file mode 100644 index 000000000..f087113d9 --- /dev/null +++ b/examples/protobuf/objc/addressbook.qbs @@ -0,0 +1,15 @@ +import qbs + +CppApplication { + name: "addressbook_objc" + consoleApplication: true + condition: protobuf.present && qbs.targetOS.contains("darwin") + + Depends { name: "cpp" } + Depends { id: protobuf; name: "protobuf.objc"; required: false } + + files: [ + "../shared/addressbook.proto", + "main.m", + ] +} diff --git a/examples/protobuf/objc/main.m b/examples/protobuf/objc/main.m new file mode 100644 index 000000000..903799fca --- /dev/null +++ b/examples/protobuf/objc/main.m @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Ivan Komissarov +** Contact: abbapoh@gmail.com +** +** This file is part of Qbs. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#import "Addressbook.pbobjc.h" + +#import <Foundation/Foundation.h> + +int printUsage(char *argv0) +{ + NSString *programName = [[NSString alloc] initWithUTF8String:argv0]; + NSLog(@"%@", [[NSString alloc] initWithFormat:@"Usage: %@ add|list ADDRESS_BOOK_FILE", programName]); + [programName release]; + return -1; +} + +NSString *readString(NSString *promt) +{ + NSLog(@"%@", promt); + NSFileHandle *inputFile = [NSFileHandle fileHandleWithStandardInput]; + NSData *inputData = [inputFile availableData]; + NSString *result = [[[NSString alloc]initWithData:inputData encoding:NSUTF8StringEncoding] autorelease]; + result = [[result stringByTrimmingCharactersInSet: + [NSCharacterSet whitespaceAndNewlineCharacterSet]] autorelease]; + return result; +} + +// This function fills in a Person message based on user input. +void promptForAddress(Person* person) +{ + person.id_p = [readString(@"Enter person ID number:") intValue]; + person.name = readString(@"Enter name:"); + + NSString *email = readString(@"Enter email address (blank for none):"); + if ([email length] != 0) + person.email = email; + + while (true) { + NSString *number = readString(@"Enter a phone number (or leave blank to finish):"); + if ([number length] == 0) + break; + + Person_PhoneNumber* phoneNumber = [[Person_PhoneNumber alloc] init]; + phoneNumber.number = number; + + NSString *type = readString(@"Is this a mobile, home, or work phone?:"); + NSLog(@"\"%@\"", type); + if ([type compare:@"mobile"] == NSOrderedSame) + phoneNumber.type = Person_PhoneType_Mobile; + else if ([type compare:@"home"] == NSOrderedSame) + phoneNumber.type = Person_PhoneType_Home; + else if ([type compare:@"work"] == NSOrderedSame) + phoneNumber.type = Person_PhoneType_Work; + else + NSLog(@"%@", @"Unknown phone type. Using default."); + + [person.phonesArray addObject:phoneNumber]; + } +} + +// Iterates though all people in the AddressBook and prints info about them. +void listPeople(AddressBook *addressBook) +{ + NSArray *people = addressBook.peopleArray; + for (unsigned i = 0; i < [people count]; i++) { + Person *person = [people objectAtIndex:i]; + + NSLog(@"%@", [[[NSString alloc] initWithFormat:@"Person ID: %d", person.id_p] autorelease]); + NSLog(@"%@", [[[NSString alloc] initWithFormat:@"Person name: %@", person.name] autorelease]); + + if ([person.email length] != 0) { + NSLog(@"%@", [[[NSString alloc] initWithFormat:@"E-mail address: %@", person.email] autorelease]); + } + + NSArray *phones = person.phonesArray; + for (unsigned j = 0; j < [phones count]; j++) { + Person_PhoneNumber *phoneNumber = [phones objectAtIndex:j]; + NSString *phonePrefix; + + switch (phoneNumber.type) { + case Person_PhoneType_Mobile: + phonePrefix = @"Mobile phone"; + break; + case Person_PhoneType_Home: + phonePrefix = @"Home phone"; + break; + case Person_PhoneType_Work: + phonePrefix = @"Work phone"; + break; + default: + phonePrefix = @"Unknown phone"; + break; + } + + NSLog(@"%@", [[[NSString alloc] initWithFormat:@" %@ #: %@", phonePrefix, phoneNumber.number] autorelease]); + } + printf("\n"); + } +} + +int main(int argc, char *argv[]) +{ + if (argc != 3) + return printUsage(argv[0]); + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + AddressBook *addressBook;// = [AddressBook alloc]; + NSString *filePath = [[[NSString alloc] initWithUTF8String:argv[2]] autorelease]; + + // Read the existing address book. + NSData *data = [NSData dataWithContentsOfFile:filePath]; + if (!data) { + NSLog(@"%@", [[NSString alloc] initWithFormat:@"%@ : File not found.", filePath]); + addressBook = [[[AddressBook alloc] init] autorelease]; + } else { + NSError *error; + addressBook = [AddressBook parseFromData:data error:&error]; + if (!addressBook) { + NSLog(@"%@", @"Failed to parse address book."); + [pool drain]; + return -1; + } + } + + if (strcmp(argv[1], "add") == 0) { + // Add an address. + Person *person = [[Person alloc] init]; + promptForAddress(person); + [addressBook.peopleArray addObject:person]; + + if (!data) { + NSLog(@"%@", @"Creating a new file."); + } + [[addressBook data] writeToFile:filePath atomically:YES]; + } else if (strcmp(argv[1], "list") == 0) { + listPeople(addressBook); + } else { + [pool drain]; + return printUsage(argv[0]); + } + + [pool drain]; + return 0; +} diff --git a/examples/protobuf/shared/addressbook.proto b/examples/protobuf/shared/addressbook.proto new file mode 100644 index 000000000..b4b33b4c6 --- /dev/null +++ b/examples/protobuf/shared/addressbook.proto @@ -0,0 +1,51 @@ +// See README.txt for information and build instructions. +// +// Note: START and END tags are used in comments to define sections used in +// tutorials. They are not part of the syntax for Protocol Buffers. +// +// To get an in-depth walkthrough of this file and the related examples, see: +// https://developers.google.com/protocol-buffers/docs/tutorials + +// [START declaration] +syntax = "proto3"; +package tutorial; + +import "google/protobuf/timestamp.proto"; +// [END declaration] + +// [START java_declaration] +option java_package = "com.example.tutorial"; +option java_outer_classname = "AddressBookProtos"; +// [END java_declaration] + +// [START csharp_declaration] +option csharp_namespace = "Google.Protobuf.Examples.AddressBook"; +// [END csharp_declaration] + +// [START messages] +message Person { + string name = 1; + int32 id = 2; // Unique ID number for this person. + string email = 3; + + enum PhoneType { + MOBILE = 0; + HOME = 1; + WORK = 2; + } + + message PhoneNumber { + string number = 1; + PhoneType type = 2; + } + + repeated PhoneNumber phones = 4; + + google.protobuf.Timestamp last_updated = 5; +} + +// Our address book file is just one of these. +message AddressBook { + repeated Person people = 1; +} +// [END messages] diff --git a/qbs-resources/imports/QbsApp.qbs b/qbs-resources/imports/QbsApp.qbs index 9d4710219..caec90f85 100644 --- a/qbs-resources/imports/QbsApp.qbs +++ b/qbs-resources/imports/QbsApp.qbs @@ -8,7 +8,6 @@ QbsProduct { type: ["application", "qbsapplication"] version: qbsversion.version consoleApplication: true - destinationDirectory: FileInfo.joinPaths(project.buildDirectory, "bin") cpp.includePaths: [ "../shared", // for the logger ] @@ -16,8 +15,8 @@ QbsProduct { fileTagsFilter: product.type .concat(qbs.buildVariant === "debug" ? ["debuginfo_app"] : []) qbs.install: true - qbs.installSourceBase: destinationDirectory qbs.installDir: targetInstallDir + qbs.installSourceBase: buildDirectory } targetInstallDir: qbsbuildconfig.appInstallDir Group { diff --git a/qbs-resources/imports/QbsAutotest.qbs b/qbs-resources/imports/QbsAutotest.qbs index 307bfe836..78db72d11 100644 --- a/qbs-resources/imports/QbsAutotest.qbs +++ b/qbs-resources/imports/QbsAutotest.qbs @@ -18,7 +18,6 @@ QtApplication { "../../../src/app/shared", // for the logger ] cpp.cxxLanguageVersion: "c++14" - destinationDirectory: "bin" Group { name: "logging" prefix: FileInfo.joinPaths(product.sourceDirectory, "../../../src/app/shared/logging") + '/' @@ -31,6 +30,11 @@ QtApplication { } cpp.rpaths: [FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix, qbsbuildconfig.libDirName)] qbs.commonRunEnvironment: ({ - "QBS_INSTALL_ROOT": qbs.installRoot + "QBS_INSTALL_DIR": FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix) }) + Group { + fileTagsFilter: product.type + qbs.install: true + qbs.installDir: qbsbuildconfig.appInstallDir + } } diff --git a/qbs-resources/imports/QbsLibrary.qbs b/qbs-resources/imports/QbsLibrary.qbs index 69e107871..bf39cb8d6 100644 --- a/qbs-resources/imports/QbsLibrary.qbs +++ b/qbs-resources/imports/QbsLibrary.qbs @@ -7,8 +7,6 @@ QbsProduct { version: qbsversion.version type: libType targetName: (qbs.enableDebugCode && qbs.targetOS.contains("windows")) ? (name + 'd') : name - destinationDirectory: FileInfo.joinPaths(project.buildDirectory, - qbs.targetOS.contains("windows") ? "bin" : qbsbuildconfig.libDirName) cpp.defines: base.concat(visibilityType === "static" ? ["QBS_STATIC_LIB"] : ["QBS_LIBRARY"]) cpp.sonamePrefix: qbs.targetOS.contains("darwin") ? "@rpath" : undefined Properties { @@ -31,8 +29,8 @@ QbsProduct { fileTagsFilter: libType.concat("dynamiclibrary_symlink") .concat(qbs.buildVariant === "debug" ? ["debuginfo_dll"] : []) qbs.install: install - qbs.installSourceBase: destinationDirectory qbs.installDir: targetInstallDir + qbs.installSourceBase: buildDirectory } targetInstallDir: qbsbuildconfig.libInstallDir Group { diff --git a/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs b/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs index 0627a5cf9..bcdf4efd2 100644 --- a/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs +++ b/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs @@ -2,6 +2,11 @@ import qbs import qbs.FileInfo Module { + Depends { + condition: project.withCode + name: "cpp" + } + property bool enableAddressSanitizer: false property bool enableUnitTests: false property bool enableProjectFileUpdates: false property bool enableRPath: true @@ -28,26 +33,9 @@ Module { property string relativeLibexecPath: "../" + libexecInstallDir property string relativePluginsPath: "../" + libDirName property string relativeSearchPath: ".." - property string rpathOrigin: { - // qbs < 1.11 compatibility for cpp.rpathOrigin - if (qbs.targetOS.contains("darwin")) - return "@loader_path"; - if (qbs.targetOS.contains("unix")) - return "$ORIGIN"; - } property stringList libRPaths: { - if (enableRPath && rpathOrigin && product.targetInstallDir) { - if (!FileInfo.cleanPath) { - // qbs < 1.10 compatibility - FileInfo.cleanPath = function (a) { - if (a.endsWith("/.")) - return a.slice(0, -2); - if (a.endsWith("/")) - return a.slice(0, -1); - return a; - } - } - return [FileInfo.joinPaths(rpathOrigin, FileInfo.relativePath( + if (enableRPath && project.withCode && cpp.rpathOrigin && product.targetInstallDir) { + return [FileInfo.joinPaths(cpp.rpathOrigin, FileInfo.relativePath( FileInfo.joinPaths('/', product.targetInstallDir), FileInfo.joinPaths('/', libDirName)))]; } @@ -57,4 +45,10 @@ Module { property string pluginsInstallDir: libDirName + "/qbs/plugins" property string qmlTypeDescriptionsInstallDir: FileInfo.joinPaths(resourcesInstallDir, "share/qbs/qml-type-descriptions") + + Properties { + condition: project.withCode && enableAddressSanitizer && qbs.toolchain.contains("gcc") + cpp.cxxFlags: "-fno-omit-frame-pointer" + cpp.driverFlags: "-fsanitize=address" + } } diff --git a/share/qbs/imports/qbs/DarwinTools/darwin-tools.js b/share/qbs/imports/qbs/DarwinTools/darwin-tools.js index 95e8dab25..01aa41ddf 100644 --- a/share/qbs/imports/qbs/DarwinTools/darwin-tools.js +++ b/share/qbs/imports/qbs/DarwinTools/darwin-tools.js @@ -98,8 +98,11 @@ function applePlatformDirectoryName(targetOSList, platformType, version, throwOn }; for (var key in _platformMap) { - if (targetOSList.contains(key)) - return _platformMap[key] + (suffixMap[platformType] || "") + (version || ""); + if (targetOSList.contains(key)) { + // there are no MacOSXOS or MacOSXSimulator platforms + var suffix = (key !== "macos") ? (suffixMap[platformType] || "") : ""; + return _platformMap[key] + suffix + (version || ""); + } } if (throwOnError || throwOnError === undefined) diff --git a/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs b/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs index 1aac95fba..d7c80144e 100644 --- a/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs +++ b/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs @@ -29,7 +29,6 @@ ** ****************************************************************************/ -import qbs import qbs.Environment import qbs.File import qbs.FileInfo @@ -41,7 +40,7 @@ PathProbe { property path sdkPath environmentPaths: Environment.getEnv("ANDROID_NDK_ROOT") - platformPaths: { + platformSearchPaths: { var paths = []; if (sdkPath) paths.push(FileInfo.joinPaths(sdkPath, "ndk-bundle")); @@ -79,7 +78,7 @@ PathProbe { return result; } - var i, j, allPaths = (environmentPaths || []).concat(platformPaths || []); + var i, j, allPaths = (environmentPaths || []).concat(platformSearchPaths || []); candidatePaths = allPaths; for (i in allPaths) { var platforms = []; diff --git a/share/qbs/imports/qbs/Probes/AndroidSdkProbe.qbs b/share/qbs/imports/qbs/Probes/AndroidSdkProbe.qbs index 1dc2a4919..28a9c568a 100644 --- a/share/qbs/imports/qbs/Probes/AndroidSdkProbe.qbs +++ b/share/qbs/imports/qbs/Probes/AndroidSdkProbe.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.Environment import qbs.File import qbs.FileInfo @@ -36,7 +35,7 @@ import "../../../modules/Android/sdk/utils.js" as SdkUtils BinaryProbe { environmentPaths: Environment.getEnv("ANDROID_HOME") - platformPaths: { + platformSearchPaths: { if (qbs.hostOS.contains("windows")) return [FileInfo.joinPaths(Environment.getEnv("LOCALAPPDATA"), "Android", "sdk")]; if (qbs.hostOS.contains("macos")) @@ -54,7 +53,7 @@ BinaryProbe { configure: { var suffixes = nameSuffixes || [""]; - var i, allPaths = (environmentPaths || []).concat(platformPaths || []); + var i, allPaths = (environmentPaths || []).concat(platformSearchPaths || []); candidatePaths = allPaths; for (i in allPaths) { for (var j in suffixes) { diff --git a/share/qbs/imports/qbs/Probes/BinaryProbe.qbs b/share/qbs/imports/qbs/Probes/BinaryProbe.qbs index 7dec8757c..0bb264bd6 100644 --- a/share/qbs/imports/qbs/Probes/BinaryProbe.qbs +++ b/share/qbs/imports/qbs/Probes/BinaryProbe.qbs @@ -28,10 +28,8 @@ ** ****************************************************************************/ -import qbs 1.0 - PathProbe { nameSuffixes: qbs.hostOS.contains("windows") ? [".com", ".exe", ".bat", ".cmd"] : undefined - platformPaths: hostOS.contains("unix") ? ["/usr/bin", "/usr/local/bin"] : [] + platformSearchPaths: hostOS.contains("unix") ? ["/usr/bin", "/usr/local/bin"] : [] platformEnvironmentPaths: [ "PATH" ] } diff --git a/share/qbs/imports/qbs/Probes/FrameworkProbe.qbs b/share/qbs/imports/qbs/Probes/FrameworkProbe.qbs index 196e776fc..e0fe73b40 100644 --- a/share/qbs/imports/qbs/Probes/FrameworkProbe.qbs +++ b/share/qbs/imports/qbs/Probes/FrameworkProbe.qbs @@ -28,15 +28,13 @@ ** ****************************************************************************/ -import qbs 1.0 - PathProbe { - platformPaths: [ - "~/Library/Frameworks", - "/usr/local/lib", - "/Library/Frameworks", - "/System/Library/Frameworks" - ] + platformSearchPaths: (qbs.sysroot ? [qbs.sysroot + "/System/Library/Frameworks"] : []).concat([ + "~/Library/Frameworks", + "/usr/local/lib", + "/Library/Frameworks", + "/System/Library/Frameworks" + ]) nameFilter: { return function(name) { diff --git a/share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs b/share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs index 9908d8239..6ebaff8be 100644 --- a/share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs +++ b/share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Environment import qbs.FileInfo import "path-probe.js" as PathProbeConfigure @@ -11,7 +10,7 @@ BinaryProbe { // Outputs property string tcPrefix - platformPaths: { + platformSearchPaths: { var paths = base; if (qbs.targetOS.contains("windows") && qbs.hostOS.contains("windows")) paths.push(FileInfo.joinPaths( @@ -48,8 +47,8 @@ BinaryProbe { } configure: { - var result = PathProbeConfigure.configure(names, nameSuffixes, nameFilter, pathPrefixes, - pathSuffixes, platformPaths, environmentPaths, + var result = PathProbeConfigure.configure(names, nameSuffixes, nameFilter, searchPaths, + pathSuffixes, platformSearchPaths, environmentPaths, platformEnvironmentPaths, pathListSeparator); found = result.found; candidatePaths = result.candidatePaths; diff --git a/share/qbs/imports/qbs/Probes/GccProbe.qbs b/share/qbs/imports/qbs/Probes/GccProbe.qbs index 8dceb531a..4e1aecbed 100644 --- a/share/qbs/imports/qbs/Probes/GccProbe.qbs +++ b/share/qbs/imports/qbs/Probes/GccProbe.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.File import qbs.ModUtils import "../../../modules/cpp/gcc.js" as Gcc diff --git a/share/qbs/imports/qbs/Probes/GccVersionProbe.qbs b/share/qbs/imports/qbs/Probes/GccVersionProbe.qbs index c0044f307..f45c0a8e8 100644 --- a/share/qbs/imports/qbs/Probes/GccVersionProbe.qbs +++ b/share/qbs/imports/qbs/Probes/GccVersionProbe.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.File import "../../../modules/cpp/gcc.js" as Gcc diff --git a/share/qbs/imports/qbs/Probes/IcoUtilsVersionProbe.qbs b/share/qbs/imports/qbs/Probes/IcoUtilsVersionProbe.qbs index d6f3a0587..90c3a06b1 100644 --- a/share/qbs/imports/qbs/Probes/IcoUtilsVersionProbe.qbs +++ b/share/qbs/imports/qbs/Probes/IcoUtilsVersionProbe.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import "../../../modules/ico/ico.js" as IcoUtils Probe { diff --git a/share/qbs/imports/qbs/Probes/IncludeProbe.qbs b/share/qbs/imports/qbs/Probes/IncludeProbe.qbs index 5b90671e9..fa2e44dd4 100644 --- a/share/qbs/imports/qbs/Probes/IncludeProbe.qbs +++ b/share/qbs/imports/qbs/Probes/IncludeProbe.qbs @@ -28,8 +28,6 @@ ** ****************************************************************************/ -import qbs 1.0 - PathProbe { pathSuffixes: [ "include" ] platformEnvironmentPaths: { diff --git a/share/qbs/imports/qbs/Probes/InnoSetupProbe.qbs b/share/qbs/imports/qbs/Probes/InnoSetupProbe.qbs index d0e756d19..2c06a6a0b 100644 --- a/share/qbs/imports/qbs/Probes/InnoSetupProbe.qbs +++ b/share/qbs/imports/qbs/Probes/InnoSetupProbe.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.Utilities PathProbe { diff --git a/share/qbs/imports/qbs/Probes/JdkProbe.qbs b/share/qbs/imports/qbs/Probes/JdkProbe.qbs index 9eaa3c36c..1f414b0fa 100644 --- a/share/qbs/imports/qbs/Probes/JdkProbe.qbs +++ b/share/qbs/imports/qbs/Probes/JdkProbe.qbs @@ -29,7 +29,6 @@ ** ****************************************************************************/ -import qbs import qbs.Environment import "../../../modules/java/utils.js" as JavaUtils @@ -41,14 +40,14 @@ PathProbe { && !qbs.hostOS.contains("android") environmentPaths: Environment.getEnv("JAVA_HOME") - platformPaths: [ + platformSearchPaths: [ "/usr/lib/jvm/default-java", // Debian/Ubuntu "/etc/alternatives/java_sdk_openjdk", // Fedora "/usr/lib/jvm/default" // Arch ] configure: { - path = JavaUtils.findJdkPath(hostOS, architecture, environmentPaths, platformPaths); + path = JavaUtils.findJdkPath(hostOS, architecture, environmentPaths, platformSearchPaths); found = !!path; } } diff --git a/share/qbs/imports/qbs/Probes/JdkVersionProbe.qbs b/share/qbs/imports/qbs/Probes/JdkVersionProbe.qbs index 299ebbb01..786d62f75 100644 --- a/share/qbs/imports/qbs/Probes/JdkVersionProbe.qbs +++ b/share/qbs/imports/qbs/Probes/JdkVersionProbe.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import "../../../modules/java/utils.js" as JavaUtils Probe { diff --git a/share/qbs/imports/qbs/Probes/LibraryProbe.qbs b/share/qbs/imports/qbs/Probes/LibraryProbe.qbs new file mode 100644 index 000000000..26787d1b4 --- /dev/null +++ b/share/qbs/imports/qbs/Probes/LibraryProbe.qbs @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Ivan Komissarov. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qbs. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +PathProbe { + nameSuffixes: { + if (qbs.targetOS.contains("windows")) + return [".lib"]; + if (qbs.targetOS.contains("macos")) + return [".dylib", ".a"]; + return [".so", ".a"]; + } + platformSearchPaths: qbs.targetOS.contains("unix") ? [ + "/usr/lib", + "/usr/local/lib", + ] : [] + nameFilter: { + if (qbs.targetOS.contains("unix")) { + return function(name) { + return "lib" + name; + } + } else { + return function(name) { + return name; + } + } + } + platformEnvironmentPaths: { + if (qbs.targetOS.contains("windows")) + return [ "PATH" ]; + else + return [ "LIBRARY_PATH" ]; + } +} diff --git a/share/qbs/imports/qbs/Probes/MsvcProbe.qbs b/share/qbs/imports/qbs/Probes/MsvcProbe.qbs index 2bbe57939..2d5faecdd 100644 --- a/share/qbs/imports/qbs/Probes/MsvcProbe.qbs +++ b/share/qbs/imports/qbs/Probes/MsvcProbe.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.File import qbs.FileInfo import qbs.ModUtils diff --git a/share/qbs/imports/qbs/Probes/NodeJsProbe.qbs b/share/qbs/imports/qbs/Probes/NodeJsProbe.qbs index 64ab32019..b0162c715 100644 --- a/share/qbs/imports/qbs/Probes/NodeJsProbe.qbs +++ b/share/qbs/imports/qbs/Probes/NodeJsProbe.qbs @@ -28,13 +28,12 @@ ** ****************************************************************************/ -import qbs import qbs.Environment import qbs.FileInfo BinaryProbe { names: ["node", "nodejs"] - platformPaths: { + platformSearchPaths: { var paths = base; if (qbs.hostOS.contains("windows")) { var env32 = Environment.getEnv("PROGRAMFILES(X86)"); diff --git a/share/qbs/imports/qbs/Probes/NpmProbe.qbs b/share/qbs/imports/qbs/Probes/NpmProbe.qbs index a13fd3615..4e8124d56 100644 --- a/share/qbs/imports/qbs/Probes/NpmProbe.qbs +++ b/share/qbs/imports/qbs/Probes/NpmProbe.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.ModUtils import "path-probe.js" as PathProbeConfigure import "../../../modules/nodejs/nodejs.js" as NodeJs @@ -48,9 +47,10 @@ NodeJsProbe { if (!interpreterPath) throw '"interpreterPath" must be specified'; - var result = PathProbeConfigure.configure(names, nameSuffixes, nameFilter, pathPrefixes, - pathSuffixes, platformPaths, environmentPaths, - platformEnvironmentPaths, pathListSeparator); + var result = PathProbeConfigure.configure(names, nameSuffixes, nameFilter, searchPaths, + pathSuffixes, platformSearchPaths, + environmentPaths, platformEnvironmentPaths, + pathListSeparator); var v = new ModUtils.EnvironmentVariable("PATH", pathListSeparator, hostOS.contains("windows")); diff --git a/share/qbs/imports/qbs/Probes/PathProbe.qbs b/share/qbs/imports/qbs/Probes/PathProbe.qbs index 73ce2e049..1235ce211 100644 --- a/share/qbs/imports/qbs/Probes/PathProbe.qbs +++ b/share/qbs/imports/qbs/Probes/PathProbe.qbs @@ -28,8 +28,8 @@ ** ****************************************************************************/ -import qbs 1.0 import "path-probe.js" as PathProbeConfigure +import qbs.ModUtils Probe { // Inputs @@ -37,10 +37,12 @@ Probe { property stringList nameSuffixes property var nameFilter property pathList pathPrefixes + property pathList searchPaths property stringList pathSuffixes - property pathList platformPaths: hostOS.contains("unix") ? ['/usr', '/usr/local'] : [] - property pathList environmentPaths - property pathList platformEnvironmentPaths + property pathList platformSearchPaths: hostOS.contains("unix") ? ['/usr', '/usr/local'] : [] + property pathList platformPaths + property stringList environmentPaths + property stringList platformEnvironmentPaths property stringList hostOS: qbs.hostOS property string pathListSeparator: qbs.pathListSeparator @@ -51,9 +53,16 @@ Probe { property string fileName configure: { - var result = PathProbeConfigure.configure(names, nameSuffixes, nameFilter, pathPrefixes, - pathSuffixes, platformPaths, environmentPaths, - platformEnvironmentPaths, pathListSeparator); + if (pathPrefixes) + console.warn("PathProbe.pathPrefixes is deprecated, use searchPaths instead"); + if (platformPaths) + console.warn("PathProbe.platformPaths is deprecated, use platformSearchPaths instead"); + var _searchPaths = ModUtils.concatAll(pathPrefixes, searchPaths); + var _platformSearchPaths = ModUtils.concatAll(platformPaths, platformSearchPaths); + var result = PathProbeConfigure.configure(names, nameSuffixes, nameFilter, _searchPaths, + pathSuffixes, _platformSearchPaths, + environmentPaths, platformEnvironmentPaths, + pathListSeparator); found = result.found; candidatePaths = result.candidatePaths; path = result.path; diff --git a/share/qbs/imports/qbs/Probes/PkgConfigProbe.qbs b/share/qbs/imports/qbs/Probes/PkgConfigProbe.qbs index 5f60c17a2..fe665b227 100644 --- a/share/qbs/imports/qbs/Probes/PkgConfigProbe.qbs +++ b/share/qbs/imports/qbs/Probes/PkgConfigProbe.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs 1.0 import qbs.Process import qbs.FileInfo diff --git a/share/qbs/imports/qbs/Probes/TypeScriptProbe.qbs b/share/qbs/imports/qbs/Probes/TypeScriptProbe.qbs index da2116660..de28fa327 100644 --- a/share/qbs/imports/qbs/Probes/TypeScriptProbe.qbs +++ b/share/qbs/imports/qbs/Probes/TypeScriptProbe.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.File import qbs.FileInfo import qbs.ModUtils @@ -38,7 +37,7 @@ import "../../../modules/typescript/typescript.js" as TypeScript BinaryProbe { id: tsc names: ["tsc"] - pathPrefixes: packageManagerBinPath ? [packageManagerBinPath] : [] + searchPaths: packageManagerBinPath ? [packageManagerBinPath] : [] // Inputs property path interpreterPath @@ -58,9 +57,10 @@ BinaryProbe { if (!packageManagerRootPath) throw '"packageManagerRootPath" must be specified'; - var result = PathProbeConfigure.configure(names, nameSuffixes, nameFilter, pathPrefixes, - pathSuffixes, platformPaths, environmentPaths, - platformEnvironmentPaths, pathListSeparator); + var result = PathProbeConfigure.configure(names, nameSuffixes, nameFilter, searchPaths, + pathSuffixes, platformSearchPaths, + environmentPaths, platformEnvironmentPaths, + pathListSeparator); var v = new ModUtils.EnvironmentVariable("PATH", pathListSeparator, hostOS.contains("windows")); diff --git a/share/qbs/imports/qbs/Probes/WiXProbe.qbs b/share/qbs/imports/qbs/Probes/WiXProbe.qbs index c754162b7..561b275cf 100644 --- a/share/qbs/imports/qbs/Probes/WiXProbe.qbs +++ b/share/qbs/imports/qbs/Probes/WiXProbe.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.Utilities PathProbe { diff --git a/share/qbs/imports/qbs/Probes/XcodeProbe.qbs b/share/qbs/imports/qbs/Probes/XcodeProbe.qbs index ed3e1a1ea..e0ed99346 100644 --- a/share/qbs/imports/qbs/Probes/XcodeProbe.qbs +++ b/share/qbs/imports/qbs/Probes/XcodeProbe.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.File import qbs.FileInfo import qbs.Process diff --git a/share/qbs/imports/qbs/Probes/path-probe.js b/share/qbs/imports/qbs/Probes/path-probe.js index bf30e8ec6..a48a7e4fe 100644 --- a/share/qbs/imports/qbs/Probes/path-probe.js +++ b/share/qbs/imports/qbs/Probes/path-probe.js @@ -33,7 +33,7 @@ var File = require("qbs.File"); var FileInfo = require("qbs.FileInfo"); var ModUtils = require("qbs.ModUtils"); -function configure(names, nameSuffixes, nameFilter, pathPrefixes, pathSuffixes, platformPaths, +function configure(names, nameSuffixes, nameFilter, searchPaths, pathSuffixes, platformSearchPaths, environmentPaths, platformEnvironmentPaths, pathListSeparator) { var result = { found: false, candidatePaths: [] }; if (!names) @@ -45,7 +45,7 @@ function configure(names, nameSuffixes, nameFilter, pathPrefixes, pathSuffixes, return (nameSuffixes || [""]).map(function(suffix) { return name + suffix; }); })); // FIXME: Suggest how to obtain paths from system - var _paths = ModUtils.concatAll(pathPrefixes, platformPaths); + var _paths = ModUtils.concatAll(searchPaths, platformSearchPaths); // FIXME: Add getenv support var envs = ModUtils.concatAll(platformEnvironmentPaths, environmentPaths); for (var i = 0; i < envs.length; ++i) { diff --git a/share/qbs/imports/qbs/base/AndroidApk.qbs b/share/qbs/imports/qbs/base/AndroidApk.qbs index d881b791f..5f86d8457 100644 --- a/share/qbs/imports/qbs/base/AndroidApk.qbs +++ b/share/qbs/imports/qbs/base/AndroidApk.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.File import qbs.FileInfo @@ -36,50 +35,4 @@ Product { type: ["android.apk"] qbs.targetPlatform: "android" Depends { name: "Android.sdk" } - - property string packageName: name - property bool automaticSources: true - property bool legacyLayout: false - - property path sourceSetDir: legacyLayout ? undefined - : FileInfo.joinPaths(sourceDirectory, "src/main") - property path resourcesDir: FileInfo.joinPaths(sourceSetDir, "res") - property path assetsDir: FileInfo.joinPaths(sourceSetDir, "assets") - property path sourcesDir: FileInfo.joinPaths(sourceSetDir, legacyLayout ? "src" : "java") - property path manifestFile: defaultManifestFile - - readonly property path defaultManifestFile: FileInfo.joinPaths(sourceSetDir, - "AndroidManifest.xml") - - Group { - name: "java sources" - condition: product.automaticSources - prefix: product.sourcesDir + '/' - files: "**/*.java" - } - - Group { - name: "android resources" - condition: product.automaticSources - fileTags: ["android.resources"] - prefix: product.resourcesDir + '/' - files: "**/*" - } - - Group { - name: "android assets" - condition: product.automaticSources - fileTags: ["android.assets"] - prefix: product.assetsDir + '/' - files: "**/*" - } - - Group { - name: "manifest" - condition: product.automaticSources - fileTags: ["android.manifest"] - files: manifestFile && manifestFile !== defaultManifestFile - ? [manifestFile] - : (File.exists(defaultManifestFile) ? [defaultManifestFile] : []) - } } diff --git a/share/qbs/imports/qbs/base/AppleApplicationDiskImage.qbs b/share/qbs/imports/qbs/base/AppleApplicationDiskImage.qbs index d1d4988c6..134f4dee0 100644 --- a/share/qbs/imports/qbs/base/AppleApplicationDiskImage.qbs +++ b/share/qbs/imports/qbs/base/AppleApplicationDiskImage.qbs @@ -41,7 +41,6 @@ AppleDiskImage { Rule { multiplex: true - inputs: ["qbs"] outputFileTags: ["dmg.input", "dmg.input.symlink"] outputArtifacts: Array.prototype.map.call(product.symlinks, function (symlink) { var symlinkTarget = symlink.split(':')[0]; diff --git a/share/qbs/imports/qbs/base/Application.qbs b/share/qbs/imports/qbs/base/Application.qbs index e16a93761..694cfb83b 100644 --- a/share/qbs/imports/qbs/base/Application.qbs +++ b/share/qbs/imports/qbs/base/Application.qbs @@ -28,12 +28,42 @@ ** ****************************************************************************/ -import qbs - NativeBinary { - type: { - if (isForAndroid && !consoleApplication) - return ["dynamiclibrary", "android.nativelibrary"]; - return ["application"]; + type: isForAndroid && !consoleApplication ? ["android.apk"] : ["application"] + + property bool usesNativeCode + + Depends { + // Note: If we are multiplexing, then this dependency is technically only needed in + // the aggregate. However, the user should not have to write the respective + // condition when assigning to properties of this module, so we load it + // regardless and turn off its rules for the native part of the build. + name: "Android.sdk" + condition: isForAndroid && !consoleApplication + } + Properties { + condition: isForAndroid && !consoleApplication && !usesNativeCode + multiplexByQbsProperties: [] + aggregate: false + } + Properties { + condition: isForAndroid && !consoleApplication && usesNativeCode + && multiplexByQbsProperties && multiplexByQbsProperties.contains("architectures") + && qbs.architectures && qbs.architectures.length > 1 + aggregate: true + multiplexedType: "android.nativelibrary" + } + aggregate: base + multiplexByQbsProperties: base + multiplexedType: base + + installDir: isBundle ? "Applications" : "bin" + + Group { + condition: install + fileTagsFilter: isBundle ? "bundle.content" : "application"; + qbs.install: true + qbs.installDir: installDir + qbs.installSourceBase: isBundle ? destinationDirectory : outer } } diff --git a/share/qbs/imports/qbs/base/ApplicationExtension.qbs b/share/qbs/imports/qbs/base/ApplicationExtension.qbs index e02c7c7e5..140475909 100644 --- a/share/qbs/imports/qbs/base/ApplicationExtension.qbs +++ b/share/qbs/imports/qbs/base/ApplicationExtension.qbs @@ -28,8 +28,6 @@ ** ****************************************************************************/ -import qbs - XPCService { Depends { name: "xcode" } diff --git a/share/qbs/imports/qbs/base/AutotestRunner.qbs b/share/qbs/imports/qbs/base/AutotestRunner.qbs index 4f175d662..ab9ba15f7 100644 --- a/share/qbs/imports/qbs/base/AutotestRunner.qbs +++ b/share/qbs/imports/qbs/base/AutotestRunner.qbs @@ -28,11 +28,9 @@ ** ****************************************************************************/ -import qbs import qbs.File import qbs.FileInfo import qbs.ModUtils -import qbs.Utilities Product { name: "autotest-runner" @@ -57,11 +55,7 @@ Product { Rule { inputsFromDependencies: "application" auxiliaryInputs: product.auxiliaryInputs - Artifact { - filePath: Utilities.getHash(input.filePath) + ".result.dummy" // Will never exist. - fileTags: "autotest-result" - alwaysUpdated: false - } + outputFileTags: "autotest-result" prepare: { // TODO: This is hacky. Possible solution: Add autotest tag to application // in autotest module and have that as inputsFromDependencies instead of application. @@ -76,14 +70,29 @@ Product { commandFilePath = ModUtils.artifactInstalledFilePath(input); if (!commandFilePath || !File.exists(commandFilePath)) commandFilePath = input.filePath; + var workingDir = product.workingDir ? product.workingDir + : FileInfo.path(commandFilePath); + var arguments = product.arguments; + var allowFailure = false; + if (input.autotest) { + // FIXME: We'd like to let the user override with an empty list, but + // qbscore turns undefined lists into empty ones at the moment. + if (input.autotest.arguments && input.autotest.arguments.length > 0) + arguments = input.autotest.arguments; + + if (input.autotest.workingDir) + workingDir = input.autotest.workingDir; + allowFailure = input.autotest.allowFailure; + } var fullCommandLine = product.wrapper .concat([commandFilePath]) - .concat(product.arguments); + .concat(arguments); var cmd = new Command(fullCommandLine[0], fullCommandLine.slice(1)); cmd.description = "Running test " + input.fileName; cmd.environment = product.environment; - cmd.workingDirectory = product.workingDir ? product.workingDir - : FileInfo.path(commandFilePath); + cmd.workingDirectory = workingDir; + if (allowFailure) + cmd.maxExitCode = 32767; return cmd; } } diff --git a/share/qbs/imports/qbs/base/CppApplication.qbs b/share/qbs/imports/qbs/base/CppApplication.qbs index 9b7de2bf8..86d2fc74a 100644 --- a/share/qbs/imports/qbs/base/CppApplication.qbs +++ b/share/qbs/imports/qbs/base/CppApplication.qbs @@ -28,9 +28,8 @@ ** ****************************************************************************/ -import qbs 1.0 - Application { Depends { name: "cpp" } + usesNativeCode: true } diff --git a/share/qbs/imports/qbs/base/DynamicLibrary.qbs b/share/qbs/imports/qbs/base/DynamicLibrary.qbs index 32d8fec41..267519a42 100644 --- a/share/qbs/imports/qbs/base/DynamicLibrary.qbs +++ b/share/qbs/imports/qbs/base/DynamicLibrary.qbs @@ -28,8 +28,26 @@ ** ****************************************************************************/ -import qbs - Library { type: ["dynamiclibrary"].concat(isForAndroid ? ["android.nativelibrary"] : []) + + installDir: isBundle ? "Library/Frameworks" : qbs.targetOS.contains("windows") + ? "bin" : "lib" + property bool installImportLib: false + property string importLibInstallDir: "lib" + + Group { + condition: install + fileTagsFilter: isBundle ? "bundle.content" : ["dynamiclibrary", "dynamiclibrary_symlink"] + qbs.install: true + qbs.installDir: installDir + qbs.installSourceBase: isBundle ? destinationDirectory : outer + } + + Group { + condition: installImportLib + fileTagsFilter: "dynamiclibrary_import" + qbs.install: true + qbs.installDir: importLibInstallDir + } } diff --git a/share/qbs/imports/qbs/base/InnoSetup.qbs b/share/qbs/imports/qbs/base/InnoSetup.qbs index c4873412a..5ea076eb3 100644 --- a/share/qbs/imports/qbs/base/InnoSetup.qbs +++ b/share/qbs/imports/qbs/base/InnoSetup.qbs @@ -28,8 +28,6 @@ ** ****************************************************************************/ -import qbs - Product { Depends { name: "innosetup"; condition: qbs.targetOS.contains("windows") } type: ["innosetup.exe"] diff --git a/share/qbs/imports/qbs/base/InstallPackage.qbs b/share/qbs/imports/qbs/base/InstallPackage.qbs index 9e621aed0..e85fe3821 100644 --- a/share/qbs/imports/qbs/base/InstallPackage.qbs +++ b/share/qbs/imports/qbs/base/InstallPackage.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.FileInfo import qbs.ModUtils import qbs.TextFile diff --git a/share/qbs/imports/qbs/base/Library.qbs b/share/qbs/imports/qbs/base/Library.qbs index 4f0b45789..615c2319f 100644 --- a/share/qbs/imports/qbs/base/Library.qbs +++ b/share/qbs/imports/qbs/base/Library.qbs @@ -28,8 +28,6 @@ ** ****************************************************************************/ -import qbs - NativeBinary { type: { if (qbs.targetOS.contains("ios") && parseInt(cpp.minimumIosVersion, 10) < 8) diff --git a/share/qbs/imports/qbs/base/LoadableModule.qbs b/share/qbs/imports/qbs/base/LoadableModule.qbs index 607a7d8d2..34579e4de 100644 --- a/share/qbs/imports/qbs/base/LoadableModule.qbs +++ b/share/qbs/imports/qbs/base/LoadableModule.qbs @@ -28,8 +28,6 @@ ** ****************************************************************************/ -import qbs - DynamicLibrary { type: isForDarwin ? ["loadablemodule"] : base } diff --git a/share/qbs/imports/qbs/base/NSISSetup.qbs b/share/qbs/imports/qbs/base/NSISSetup.qbs index 6401a17c4..1362f2713 100644 --- a/share/qbs/imports/qbs/base/NSISSetup.qbs +++ b/share/qbs/imports/qbs/base/NSISSetup.qbs @@ -28,8 +28,6 @@ ** ****************************************************************************/ -import qbs - Product { Depends { name: "nsis"; condition: qbs.targetOS.contains("windows") } type: ["nsissetup"] diff --git a/share/qbs/imports/qbs/base/NativeBinary.qbs b/share/qbs/imports/qbs/base/NativeBinary.qbs index 0a772b60c..3597f348f 100644 --- a/share/qbs/imports/qbs/base/NativeBinary.qbs +++ b/share/qbs/imports/qbs/base/NativeBinary.qbs @@ -28,13 +28,15 @@ ** ****************************************************************************/ -import qbs - Product { property bool isForAndroid: qbs.targetOS.contains("android") property bool isForDarwin: qbs.targetOS.contains("darwin") + property bool isBundle: isForDarwin && bundle.isBundle + + property bool install: false + property string installDir - Depends { name: "bundle" } + Depends { name: "bundle"; condition: isForDarwin } aggregate: { if (!isForDarwin) diff --git a/share/qbs/imports/qbs/base/QtApplication.qbs b/share/qbs/imports/qbs/base/QtApplication.qbs index b9e8f2603..32800d294 100644 --- a/share/qbs/imports/qbs/base/QtApplication.qbs +++ b/share/qbs/imports/qbs/base/QtApplication.qbs @@ -28,8 +28,6 @@ ** ****************************************************************************/ -import qbs - CppApplication { Depends { name: "Qt.core" } } diff --git a/share/qbs/imports/qbs/base/QtGuiApplication.qbs b/share/qbs/imports/qbs/base/QtGuiApplication.qbs index 1d92142fa..61bc69752 100644 --- a/share/qbs/imports/qbs/base/QtGuiApplication.qbs +++ b/share/qbs/imports/qbs/base/QtGuiApplication.qbs @@ -28,14 +28,6 @@ ** ****************************************************************************/ -import qbs - CppApplication { Depends { name: "Qt.gui" } - Depends { - name: "Qt" - submodules: Qt.gui.defaultQpaPlugin - condition: linkDefaultQpaPlugin && Qt.gui.defaultQpaPlugin - } - property bool linkDefaultQpaPlugin: Qt.gui.isStaticLibrary } diff --git a/share/qbs/imports/qbs/base/StaticLibrary.qbs b/share/qbs/imports/qbs/base/StaticLibrary.qbs index 1609bdcea..4eea3c991 100644 --- a/share/qbs/imports/qbs/base/StaticLibrary.qbs +++ b/share/qbs/imports/qbs/base/StaticLibrary.qbs @@ -28,8 +28,15 @@ ** ****************************************************************************/ -import qbs - Library { type: ["staticlibrary"] + + installDir: isBundle ? "Library/Frameworks" : "lib" + Group { + condition: install + fileTagsFilter: isBundle ? "bundle.content" : "staticlibrary"; + qbs.install: true + qbs.installDir: installDir + qbs.installSourceBase: isBundle ? destinationDirectory : outer + } } diff --git a/share/qbs/imports/qbs/base/WindowsInstallerPackage.qbs b/share/qbs/imports/qbs/base/WindowsInstallerPackage.qbs index d624be864..791fc9473 100644 --- a/share/qbs/imports/qbs/base/WindowsInstallerPackage.qbs +++ b/share/qbs/imports/qbs/base/WindowsInstallerPackage.qbs @@ -28,8 +28,6 @@ ** ****************************************************************************/ -import qbs - Product { Depends { name: "wix"; condition: qbs.targetOS.contains("windows") } type: ["msi"] diff --git a/share/qbs/imports/qbs/base/XPCService.qbs b/share/qbs/imports/qbs/base/XPCService.qbs index 0e8e1eb7c..16c25900c 100644 --- a/share/qbs/imports/qbs/base/XPCService.qbs +++ b/share/qbs/imports/qbs/base/XPCService.qbs @@ -28,8 +28,6 @@ ** ****************************************************************************/ -import qbs - Application { type: base.concat(["xpcservice"]) diff --git a/share/qbs/modules/Android/ndk/ndk.qbs b/share/qbs/modules/Android/ndk/ndk.qbs index 226423d61..94211ea39 100644 --- a/share/qbs/modules/Android/ndk/ndk.qbs +++ b/share/qbs/modules/Android/ndk/ndk.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.File import qbs.FileInfo import qbs.ModUtils @@ -146,8 +145,6 @@ Module { return toolchainVersion; } - property string gdbserverFileName: "gdbserver" - property string armMode: abi && abi.startsWith("armeabi") ? (qbs.buildVariant === "debug" ? "arm" : "thumb") : undefined; @@ -168,7 +165,8 @@ Module { + "ANDROID_NDK_ROOT environment variable to a valid " + "Android NDK location."); } - + if (product.aggregate && !product.multiplexConfigurationId) + return; var validator = new ModUtils.PropertyValidator("Android.ndk"); validator.setRequiredProperty("abi", abi); validator.setRequiredProperty("appStl", appStl); diff --git a/share/qbs/modules/Android/ndk/utils.js b/share/qbs/modules/Android/ndk/utils.js index 7d1f7d6d0..a2e342897 100644 --- a/share/qbs/modules/Android/ndk/utils.js +++ b/share/qbs/modules/Android/ndk/utils.js @@ -63,25 +63,13 @@ function androidAbi(arch) { function commonCompilerFlags(toolchain, buildVariant, abi, armMode) { var flags = ["-ffunction-sections", "-funwind-tables", - "-Wa,--noexecstack", "-Werror=format-security"]; + "-Wa,--noexecstack", "-Werror=format-security", "-fstack-protector-strong"]; - if (buildVariant === "debug") - flags.push("-fno-omit-frame-pointer", "-fno-strict-aliasing"); - if (buildVariant === "release") - flags.push("-fomit-frame-pointer"); - - if (abi === "arm64-v8a") { - flags.push("-fpic", "-fstack-protector") - if (!toolchain.contains("clang")) - flags.push("-finline-limit=300", "-funswitch-loops"); - if (buildVariant === "release") - flags.push("-fstrict-aliasing"); - } + if (abi === "arm64-v8a") + flags.push("-fpic"); if (abi === "armeabi" || abi === "armeabi-v7a") { - flags.push("-fpic", "-fstack-protector"); - if (!toolchain.contains("clang")) - flags.push("-finline-limit=64"); + flags.push("-fpic"); if (abi === "armeabi") flags.push("-mtune=xscale", "-msoft-float"); @@ -90,29 +78,16 @@ function commonCompilerFlags(toolchain, buildVariant, abi, armMode) { flags.push("-mfpu=vfpv3-d16"); flags.push("-mfloat-abi=softfp"); } - - if (buildVariant === "release") - flags.push("-fno-strict-aliasing"); } if (abi === "mips" || abi === "mips64") { flags.push("-fpic", "-finline-functions", "-fmessage-length=0", "-fno-inline-functions-called-once", "-fgcse-after-reload", "-frerun-cse-after-loop", "-frename-registers"); - if (buildVariant === "release") { - flags.push("-fno-strict-aliasing"); - if (!toolchain.contains("clang")) - flags.push("-funswitch-loops", "-finline-limit=300"); - } } - if (abi === "x86" || abi === "x86_64") { - flags.push("-fstack-protector"); - if (!toolchain.contains("clang")) - flags.push("-funswitch-loops", "-finline-limit=300"); - if (buildVariant === "release") - flags.push("-fstrict-aliasing"); - } + if ((abi === "x86" || abi === "x86_64") && toolchain.contains("clang")) + flags.push("-fPIC"); if (armMode) flags.push("-m" + armMode); diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs index 84cee56e9..79ec9ad81 100644 --- a/share/qbs/modules/Android/sdk/sdk.qbs +++ b/share/qbs/modules/Android/sdk/sdk.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.Environment import qbs.File import qbs.FileInfo @@ -36,6 +35,7 @@ import qbs.ModUtils import qbs.Probes import qbs.TextFile import qbs.Utilities +import qbs.Xml import "utils.js" as SdkUtils Module { @@ -60,6 +60,58 @@ Module { property int buildToolsVersionPatch: buildToolsVersionParts[2] property string platform: sdkProbe.platform + // Product-specific properties and files + property string packageName: product.name + property string apkBaseName: packageName + property bool automaticSources: true + property bool legacyLayout: false + property string sourceSetDir: legacyLayout + ? product.sourceDirectory + : FileInfo.joinPaths(product.sourceDirectory, "src/main") + property string resourcesDir: FileInfo.joinPaths(sourceSetDir, "res") + property string assetsDir: FileInfo.joinPaths(sourceSetDir, "assets") + property string sourcesDir: FileInfo.joinPaths(sourceSetDir, legacyLayout ? "src" : "java") + property string manifestFile: defaultManifestFile + readonly property string defaultManifestFile: FileInfo.joinPaths(sourceSetDir, + "AndroidManifest.xml") + + property bool _enableRules: !product.multiplexConfigurationId && !!packageName + + Group { + name: "java sources" + condition: Android.sdk.automaticSources + prefix: Android.sdk.sourcesDir + '/' + files: "**/*.java" + } + + Group { + name: "android resources" + condition: Android.sdk.automaticSources + fileTags: ["android.resources"] + prefix: Android.sdk.resourcesDir + '/' + files: "**/*" + } + + Group { + name: "android assets" + condition: Android.sdk.automaticSources + fileTags: ["android.assets"] + prefix: Android.sdk.assetsDir + '/' + files: "**/*" + } + + Group { + name: "manifest" + condition: Android.sdk.automaticSources + fileTags: ["android.manifest"] + files: Android.sdk.manifestFile + && Android.sdk.manifestFile !== Android.sdk.defaultManifestFile + ? [Android.sdk.manifestFile] + : (File.exists(Android.sdk.defaultManifestFile) + ? [Android.sdk.defaultManifestFile] : []) + } + + // Internal properties. property int platformVersion: { if (platform) { @@ -84,9 +136,11 @@ Module { property path zipalignFilePath: FileInfo.joinPaths(buildToolsDir, "zipalign") property path androidJarFilePath: FileInfo.joinPaths(sdkDir, "platforms", platform, "android.jar") + property path frameworkAidlFilePath: FileInfo.joinPaths(sdkDir, "platforms", platform, + "framework.aidl") property path generatedJavaFilesBaseDir: FileInfo.joinPaths(product.buildDirectory, "gen") property path generatedJavaFilesDir: FileInfo.joinPaths(generatedJavaFilesBaseDir, - (product.packageName || "").split('.').join('/')) + (packageName || "").split('.').join('/')) property string apkContentsDir: FileInfo.joinPaths(product.buildDirectory, "bin") property string debugKeyStorePath: FileInfo.joinPaths( Environment.getEnv(qbs.hostOS.contains("windows") @@ -94,11 +148,15 @@ Module { ".android", "debug.keystore") property bool useApksigner: buildToolsVersion && Utilities.versionCompare( buildToolsVersion, "24.0.3") >= 0 + property stringList aidlSearchPaths - Depends { name: "java" } - java.languageVersion: platformJavaVersion - java.runtimeVersion: platformJavaVersion - java.bootClassPaths: androidJarFilePath + Depends { name: "java"; condition: _enableRules } + Properties { + condition: _enableRules + java.languageVersion: platformJavaVersion + java.runtimeVersion: platformJavaVersion + java.bootClassPaths: androidJarFilePath + } validate: { if (!sdkDir) { @@ -156,6 +214,7 @@ Module { } Rule { + condition: _enableRules inputs: ["android.aidl"] Artifact { filePath: FileInfo.joinPaths(Utilities.getHash(input.filePath), @@ -164,16 +223,51 @@ Module { } prepare: { - var aidl = ModUtils.moduleProperty(product, "aidlFilePath"); - cmd = new Command(aidl, [input.filePath, output.filePath]); + var aidl = product.Android.sdk.aidlFilePath; + var args = ["-p" + product.Android.sdk.frameworkAidlFilePath]; + var aidlSearchPaths = input.Android.sdk.aidlSearchPaths; + for (var i = 0; i < (aidlSearchPaths ? aidlSearchPaths.length : 0); ++i) + args.push("-I" + aidlSearchPaths[i]); + args.push(input.filePath, output.filePath); + cmd = new Command(aidl, args); cmd.description = "Processing " + input.fileName; return [cmd]; } } + property bool customManifestProcessing: false + Group { + condition: !Android.sdk.customManifestProcessing + fileTagsFilter: "android.manifest_processed" + fileTags: "android.manifest_final" + } Rule { + condition: _enableRules + inputs: "android.manifest" + Artifact { + filePath: FileInfo.joinPaths("processed_manifest", input.fileName) + fileTags: "android.manifest_processed" + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "Ensuring correct package name in Android manifest file"; + cmd.sourceCode = function() { + var manifestData = new Xml.DomDocument(); + manifestData.load(input.filePath); + var rootElem = manifestData.documentElement(); + if (!rootElem || !rootElem.isElement() || rootElem.tagName() != "manifest") + throw "No manifest tag found in '" + input.filePath + "'."; + rootElem.setAttribute("package", product.Android.sdk.packageName); + manifestData.save(output.filePath, 4); + } + return cmd; + } + } + + Rule { + condition: _enableRules multiplex: true - inputs: ["android.resources", "android.assets", "android.manifest"] + inputs: ["android.resources", "android.assets", "android.manifest_final"] outputFileTags: ["java.java"] outputArtifacts: { @@ -181,9 +275,8 @@ Module { var resources = inputs["android.resources"]; if (resources && resources.length) { artifacts.push({ - filePath: FileInfo.joinPaths( - ModUtils.moduleProperty(product, "generatedJavaFilesDir"), - "R.java"), + filePath: FileInfo.joinPaths(product.Android.sdk.generatedJavaFilesDir, + "R.java"), fileTags: ["java.java"] }); } @@ -195,11 +288,11 @@ Module { } Rule { + condition: _enableRules multiplex: true - condition: !!product.packageName Artifact { - filePath: FileInfo.joinPaths(ModUtils.moduleProperty(product, "generatedJavaFilesDir"), + filePath: FileInfo.joinPaths(product.Android.sdk.generatedJavaFilesDir, "BuildConfig.java") fileTags: ["java.java"] } @@ -208,10 +301,9 @@ Module { var cmd = new JavaScriptCommand(); cmd.description = "Generating BuildConfig.java"; cmd.sourceCode = function() { - var debugValue = product.moduleProperty("qbs", "buildVariant") === "debug" - ? "true" : "false"; + var debugValue = product.qbs.buildVariant === "debug" ? "true" : "false"; var ofile = new TextFile(output.filePath, TextFile.WriteOnly); - ofile.writeLine("package " + product.packageName + ";") + ofile.writeLine("package " + product.Android.sdk.packageName + ";") ofile.writeLine("public final class BuildConfig {"); ofile.writeLine(" public final static boolean DEBUG = " + debugValue + ";"); ofile.writeLine("}"); @@ -222,6 +314,7 @@ Module { } Rule { + condition: _enableRules multiplex: true inputs: ["java.class"] inputsFromDependencies: ["java.jar"] @@ -233,71 +326,97 @@ Module { } Rule { + condition: _enableRules + property stringList inputTags: "android.nativelibrary" + inputsFromDependencies: inputTags + inputs: product.aggregate ? [] : inputTags + Artifact { + filePath: FileInfo.joinPaths(product.Android.sdk.apkContentsDir, "lib", + input.Android.ndk.abi, input.fileName) + fileTags: "android.nativelibrary_deployed" + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "copying " + input.fileName + " for packaging"; + cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); }; + return cmd; + } + } + + Rule { + condition: _enableRules multiplex: true - inputsFromDependencies: [ - "android.gdbserver-info", "android.stl-info", "android.nativelibrary" - ] - outputFileTags: ["android.gdbserver", "android.stl", "android.nativelibrary-deployed"] + property stringList inputTags: "android.gdbserver" + inputsFromDependencies: inputTags + inputs: product.aggregate ? [] : inputTags + outputFileTags: "android.gdbserver_deployed" outputArtifacts: { - var libArtifacts = []; - if (inputs["android.nativelibrary"]) { - for (var i = 0; i < inputs["android.nativelibrary"].length; ++i) { - var inp = inputs["android.nativelibrary"][i]; - var destDir = FileInfo.joinPaths(product.Android.sdk.apkContentsDir, "lib", - inp.moduleProperty("Android.ndk", "abi")); - libArtifacts.push({ - filePath: FileInfo.joinPaths(destDir, inp.fileName), - fileTags: ["android.nativelibrary-deployed"] - }); - } + var deploymentData = SdkUtils.gdbserverOrStlDeploymentData(product, inputs, + "gdbserver"); + var outputs = []; + for (i = 0; i < deploymentData.outputFilePaths.length; ++i) { + outputs.push({filePath: deploymentData.outputFilePaths[i], + fileTags: "android.gdbserver_deployed"}); } - var gdbServerArtifacts = SdkUtils.outputArtifactsFromInfoFiles(inputs, - product, "android.gdbserver-info", "android.gdbserver"); - var stlArtifacts = SdkUtils.outputArtifactsFromInfoFiles(inputs, product, - "android.stl-info", "android.deployed-stl"); - return libArtifacts.concat(gdbServerArtifacts).concat(stlArtifacts); + return outputs; } prepare: { - var cmd = new JavaScriptCommand(); - cmd.description = "Pre-packaging native binaries"; + var cmd = new JavaScriptCommand; + cmd.description = "deploying gdbserver binaries"; cmd.sourceCode = function() { - if (inputs["android.nativelibrary"]) { - for (var i = 0; i < inputs["android.nativelibrary"].length; ++i) { - for (var j = 0; j < outputs["android.nativelibrary-deployed"].length; ++j) { - var inp = inputs["android.nativelibrary"][i]; - var outp = outputs["android.nativelibrary-deployed"][j]; - var inpAbi = inp.moduleProperty("Android.ndk", "abi"); - var outpAbi = FileInfo.fileName(outp.baseDir); - if (inp.fileName === outp.fileName && inpAbi === outpAbi) { - File.copy(inp.filePath, outp.filePath); - break; - } - } - } + var deploymentData = SdkUtils.gdbserverOrStlDeploymentData(product, inputs, + "gdbserver"); + for (var i = 0; i < deploymentData.uniqueInputs.length; ++i) { + File.copy(deploymentData.uniqueInputs[i].filePath, + deploymentData.outputFilePaths[i]); } - var pathsSpecs = SdkUtils.sourceAndTargetFilePathsFromInfoFiles(inputs, product, - "android.gdbserver-info"); - for (i = 0; i < pathsSpecs.sourcePaths.length; ++i) - File.copy(pathsSpecs.sourcePaths[i], pathsSpecs.targetPaths[i]); - pathsSpecs = SdkUtils.sourceAndTargetFilePathsFromInfoFiles(inputs, product, - "android.stl-info"); - for (i = 0; i < pathsSpecs.sourcePaths.length; ++i) - File.copy(pathsSpecs.sourcePaths[i], pathsSpecs.targetPaths[i]); }; - return [cmd]; + return cmd; + } + } + + Rule { + condition: _enableRules + multiplex: true + property stringList inputTags: "android.stl" + inputsFromDependencies: inputTags + inputs: product.aggregate ? [] : inputTags + outputFileTags: "android.stl_deployed" + outputArtifacts: { + var deploymentData = SdkUtils.gdbserverOrStlDeploymentData(product, inputs, "stl"); + var outputs = []; + for (i = 0; i < deploymentData.outputFilePaths.length; ++i) { + outputs.push({filePath: deploymentData.outputFilePaths[i], + fileTags: "android.stl_deployed"}); + } + return outputs; + } + prepare: { + var cmds = []; + var deploymentData = SdkUtils.gdbserverOrStlDeploymentData(product, inputs); + for (var i = 0; i < deploymentData.uniqueInputs.length; ++i) { + var input = deploymentData.uniqueInputs[i]; + var stripArgs = ["--strip-unneeded", "-o", deploymentData.outputFilePaths[i], + input.filePath]; + var cmd = new Command(input.cpp.stripPath, stripArgs); + cmd.description = "deploying " + input.fileName; + cmds.push(cmd); + } + return cmds; } } Rule { + condition: _enableRules multiplex: true inputs: [ - "android.resources", "android.assets", "android.manifest", - "android.dex", "android.gdbserver", "android.stl", - "android.nativelibrary-deployed", "android.keystore" + "android.resources", "android.assets", "android.manifest_final", + "android.dex", "android.gdbserver_deployed", "android.stl_deployed", + "android.nativelibrary_deployed", "android.keystore" ] Artifact { - filePath: product.targetName + ".apk" - fileTags: ["android.apk"] + filePath: product.Android.sdk.apkBaseName + ".apk" + fileTags: "android.apk" } prepare: SdkUtils.prepareAaptPackage.apply(SdkUtils, arguments) } diff --git a/share/qbs/modules/Android/sdk/utils.js b/share/qbs/modules/Android/sdk/utils.js index 6d9fff65c..6a89fd5f2 100644 --- a/share/qbs/modules/Android/sdk/utils.js +++ b/share/qbs/modules/Android/sdk/utils.js @@ -34,34 +34,6 @@ var Process = require("qbs.Process"); var TextFile = require("qbs.TextFile"); var Utilities = require("qbs.Utilities"); -function sourceAndTargetFilePathsFromInfoFiles(inputs, product, inputTag) -{ - var sourceFilePaths = []; - var targetFilePaths = []; - var inputsLength = inputs[inputTag] ? inputs[inputTag].length : 0; - for (var i = 0; i < inputsLength; ++i) { - var infoFile = new TextFile(inputs[inputTag][i].filePath, TextFile.ReadOnly); - var sourceFilePath = infoFile.readLine(); - var targetFilePath = FileInfo.joinPaths(product.Android.sdk.apkContentsDir, - infoFile.readLine()); - if (!targetFilePaths.contains(targetFilePath)) { - sourceFilePaths.push(sourceFilePath); - targetFilePaths.push(targetFilePath); - } - infoFile.close(); - } - return { sourcePaths: sourceFilePaths, targetPaths: targetFilePaths }; -} - -function outputArtifactsFromInfoFiles(inputs, product, inputTag, outputTag) -{ - var pathSpecs = sourceAndTargetFilePathsFromInfoFiles(inputs, product, inputTag) - var artifacts = []; - for (i = 0; i < pathSpecs.targetPaths.length; ++i) - artifacts.push({filePath: pathSpecs.targetPaths[i], fileTags: [outputTag]}); - return artifacts; -} - function availableSdkPlatforms(sdkDir) { var re = /^android-([0-9]+)$/; var platforms = File.directoryEntries(FileInfo.joinPaths(sdkDir, "platforms"), @@ -129,19 +101,56 @@ function prepareDex(project, product, inputs, outputs, input, output, explicitly return [cmd]; } +function findParentDir(filePath, parentDirName) +{ + var lastDir; + var currentDir = FileInfo.path(filePath); + while (lastDir !== currentDir) { + if (FileInfo.fileName(currentDir) === parentDirName) + return currentDir; + lastDir = currentDir; + currentDir = FileInfo.path(currentDir); + } +} + function commonAaptPackageArgs(project, product, inputs, outputs, input, output, explicitlyDependsOn) { - var manifestFilePath = inputs["android.manifest"][0].filePath; + var manifestFilePath = inputs["android.manifest_final"][0].filePath; var args = ["package", "-f", "-M", manifestFilePath, "-I", product.Android.sdk.androidJarFilePath]; var resources = inputs["android.resources"]; - if (resources && resources.length) - args.push("-S", product.resourcesDir); + var resourceDirs = []; + if (resources) { + for (var i = 0; i < resources.length; ++i) { + var resDir = findParentDir(resources[i].filePath, "res"); + if (!resDir) { + throw "File '" + resources[i].filePath + "' is tagged as an Android resource, " + + "but is not located under a directory called 'res'."; + } + if (!resourceDirs.contains(resDir)) + resourceDirs.push(resDir); + } + } + for (i = 0; i < resourceDirs.length; ++i) + args.push("-S", resourceDirs[i]); + var assets = inputs["android.assets"]; + var assetDirs = []; + if (assets) { + for (i = 0; i < assets.length; ++i) { + var assetDir = findParentDir(assets[i].filePath, "assets"); + if (!assetDir) { + throw "File '" + assets[i].filePath + "' is tagged as an Android asset, " + + "but is not located under a directory called 'assets'."; + } + if (!assetDirs.contains(assetDir)) + assetDirs.push(assetDir); + } + } + for (i = 0; i < assetDirs.length; ++i) + args.push("-A", assetDirs[i]); if (product.qbs.buildVariant === "debug") args.push("--debug-mode"); - if (File.exists(product.assetsDir)) - args.push("-A", product.assetsDir); return args; } @@ -210,3 +219,24 @@ function createDebugKeyStoreCommandString(keytoolFilePath, keystoreFilePath) { "CN=Android Debug,O=Android,C=US"]; return Process.shellQuote(keytoolFilePath, args); } + +function gdbserverOrStlDeploymentData(product, inputs, type) +{ + var data = { uniqueInputs: [], outputFilePaths: []}; + var uniqueFilePaths = []; + var theInputs = inputs[type === "gdbserver" ? "android.gdbserver" : "android.stl"]; + if (!theInputs) + return data; + for (var i = 0; i < theInputs.length; ++i) { + var currentInput = theInputs[i]; + if (uniqueFilePaths.contains(currentInput.filePath)) + continue; + uniqueFilePaths.push(currentInput.filePath); + data.uniqueInputs.push(currentInput); + var outputFileName = type === "gdbserver" ? "libgdbserver.so" : currentInput.fileName; + data.outputFilePaths.push(FileInfo.joinPaths(product.Android.sdk.apkContentsDir, "lib", + currentInput.Android.ndk.abi, + outputFileName)); + } + return data; +} diff --git a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs index aecad6126..8cc55f885 100644 --- a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs +++ b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo import qbs.TextFile diff --git a/share/qbs/modules/Exporter/qbs/qbsexporter.qbs b/share/qbs/modules/Exporter/qbs/qbsexporter.qbs index 351edfefe..861483ef0 100644 --- a/share/qbs/modules/Exporter/qbs/qbsexporter.qbs +++ b/share/qbs/modules/Exporter/qbs/qbsexporter.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.FileInfo import qbs.TextFile diff --git a/share/qbs/modules/archiver/archiver.qbs b/share/qbs/modules/archiver/archiver.qbs index c70b57bf4..6ae53dd37 100644 --- a/share/qbs/modules/archiver/archiver.qbs +++ b/share/qbs/modules/archiver/archiver.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.Environment import qbs.File import qbs.FileInfo @@ -52,7 +51,7 @@ Module { Probes.BinaryProbe { id: sevenZipProbe names: ["7z"] - platformPaths: { + platformSearchPaths: { var paths = base; if (qbs.hostOS.contains("windows")) { var env32 = Environment.getEnv("PROGRAMFILES(X86)"); diff --git a/share/qbs/modules/autotest/autotest.qbs b/share/qbs/modules/autotest/autotest.qbs new file mode 100644 index 000000000..ba280169e --- /dev/null +++ b/share/qbs/modules/autotest/autotest.qbs @@ -0,0 +1,5 @@ +Module { + property stringList arguments + property bool allowFailure: false + property string workingDir +} diff --git a/share/qbs/modules/bundle/BundleModule.qbs b/share/qbs/modules/bundle/BundleModule.qbs index 7752ee65e..ec0062347 100644 --- a/share/qbs/modules/bundle/BundleModule.qbs +++ b/share/qbs/modules/bundle/BundleModule.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.BundleTools import qbs.DarwinTools import qbs.Environment @@ -264,7 +263,8 @@ Module { Rule { condition: qbs.targetOS.contains("darwin") multiplex: true - inputs: ["qbs", "infoplist", "partial_infoplist"] + requiresInputs: false // TODO: The resources property should probably be a tag instead. + inputs: ["infoplist", "partial_infoplist"] outputFileTags: ["bundle.input", "aggregate_infoplist"] outputArtifacts: { @@ -518,7 +518,7 @@ Module { "bundle.symlink.headers", "bundle.symlink.private-headers", "bundle.symlink.resources", "bundle.symlink.executable", "bundle.symlink.version", "bundle.hpp", "bundle.resource", - "bundle.provisioningprofile"] + "bundle.provisioningprofile", "bundle.content.copied", "bundle.application-executable"] outputArtifacts: { var i, artifacts = []; if (ModUtils.moduleProperty(product, "isBundle")) { diff --git a/share/qbs/modules/cli/CLIModule.qbs b/share/qbs/modules/cli/CLIModule.qbs index 866580029..d0ca120ef 100644 --- a/share/qbs/modules/cli/CLIModule.qbs +++ b/share/qbs/modules/cli/CLIModule.qbs @@ -1,5 +1,4 @@ // base for Common Language Infrastructure modules -import qbs import qbs.FileInfo import qbs.ModUtils import "cli.js" as CLI diff --git a/share/qbs/modules/cli/mono.qbs b/share/qbs/modules/cli/mono.qbs index c679c4bf0..f04956a5e 100644 --- a/share/qbs/modules/cli/mono.qbs +++ b/share/qbs/modules/cli/mono.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.Probes @@ -13,7 +12,7 @@ CLIModule { Probes.PathProbe { id: monoProbe names: ["mono"] - platformPaths: { + platformSearchPaths: { var paths = []; if (qbs.hostOS.contains("macos")) paths.push("/Library/Frameworks/Mono.framework/Commands"); diff --git a/share/qbs/modules/cli/windows-dotnet.qbs b/share/qbs/modules/cli/windows-dotnet.qbs index b1b29d7a9..6fde50b85 100644 --- a/share/qbs/modules/cli/windows-dotnet.qbs +++ b/share/qbs/modules/cli/windows-dotnet.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities CLIModule { diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs index c26be036d..01b0f8af9 100644 --- a/share/qbs/modules/cpp/CppModule.qbs +++ b/share/qbs/modules/cpp/CppModule.qbs @@ -178,6 +178,7 @@ Module { property string debugInfoSuffix: "" property string debugInfoBundleSuffix: "" property string variantSuffix: "" + property string dynamicLibraryImportSuffix: ".lib" property bool createSymlinks: true property stringList dynamicLibraries // list of names, will be linked with -lname property stringList staticLibraries // list of static library files @@ -353,7 +354,7 @@ Module { property stringList targetDriverFlags property stringList targetLinkerFlags - property bool _skipAllChecks: false // Internal, for testing only. + property bool _skipAllChecks: false // Internal property bool validateTargetTriple: true diff --git a/share/qbs/modules/cpp/DarwinGCC.qbs b/share/qbs/modules/cpp/DarwinGCC.qbs index 16176b4eb..0bd294fb4 100644 --- a/share/qbs/modules/cpp/DarwinGCC.qbs +++ b/share/qbs/modules/cpp/DarwinGCC.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.DarwinTools import qbs.File import qbs.FileInfo @@ -50,7 +49,7 @@ UnixGCC { id: lipoProbe condition: !_skipAllChecks names: [lipoName] - platformPaths: { + platformSearchPaths: { var paths = (xcode.present && xcode.devicePlatformPath) ? [xcode.devicePlatformPath + "/Developer/usr/bin"] : []; @@ -211,7 +210,8 @@ UnixGCC { inputsFromDependencies: ["application"] multiplex: true - outputFileTags: ["bundle.input", "application", "primary", "debuginfo_app"] + outputFileTags: ["bundle.input", "application", "primary", "debuginfo_app", + "debuginfo_bundle", "bundle.variant_symlink", "debuginfo_plist"] outputArtifacts: Darwin.lipoOutputArtifacts(product, inputs, "application", "app") prepare: Darwin.prepareLipo.apply(Darwin, arguments) @@ -235,7 +235,8 @@ UnixGCC { multiplex: true outputFileTags: ["bundle.input", "dynamiclibrary", "dynamiclibrary_symbols", "primary", - "debuginfo_dll"] + "debuginfo_dll","debuginfo_bundle","bundle.variant_symlink", + "debuginfo_plist"] outputArtifacts: Darwin.lipoOutputArtifacts(product, inputs, "dynamiclibrary", "dll") prepare: Darwin.prepareLipo.apply(Darwin, arguments) diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs index 4e68dc267..972555ed7 100644 --- a/share/qbs/modules/cpp/GenericGCC.qbs +++ b/share/qbs/modules/cpp/GenericGCC.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs 1.0 import qbs.File import qbs.FileInfo import qbs.ModUtils @@ -389,7 +388,7 @@ CppModule { || product.multiplexConfigurationId Rule { - id: dynamicLibraryLinker + name: "dynamicLibraryLinker" condition: product.cpp.shouldLink multiplex: true inputs: { @@ -400,11 +399,12 @@ CppModule { } return tags; } - inputsFromDependencies: ["dynamiclibrary_symbols", "staticlibrary"] + inputsFromDependencies: ["dynamiclibrary_symbols", "staticlibrary", "dynamiclibrary_import"] outputFileTags: [ "bundle.input", - "dynamiclibrary", "dynamiclibrary_symlink", "dynamiclibrary_symbols", "debuginfo_dll" + "dynamiclibrary", "dynamiclibrary_symlink", "dynamiclibrary_symbols", "debuginfo_dll", + "debuginfo_bundle","dynamiclibrary_import", "debuginfo_plist", ] outputArtifacts: { var artifacts = [{ @@ -416,7 +416,14 @@ CppModule { + PathTools.bundleExecutableFilePath(product) } }]; - if (!product.qbs.toolchain.contains("mingw")) { + if (product.qbs.toolchain.contains("mingw")) { + artifacts.push({ + fileTags: ["dynamiclibrary_import"], + filePath: FileInfo.joinPaths(product.destinationDirectory, + PathTools.importLibraryFilePath(product)), + alwaysUpdated: false + }); + } else { // List of libfoo's public symbols for smart re-linking. artifacts.push({ filePath: product.destinationDirectory + "/.sosymbols/" @@ -451,11 +458,11 @@ CppModule { } Rule { - id: staticLibraryLinker + name: "staticLibraryLinker" condition: product.cpp.shouldLink multiplex: true inputs: ["obj", "linkerscript"] - inputsFromDependencies: ["dynamiclibrary_symbols", "staticlibrary"] + inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"] outputFileTags: ["bundle.input", "staticlibrary", "c_staticlibrary", "cpp_staticlibrary"] outputArtifacts: { @@ -487,13 +494,14 @@ CppModule { var cmd = new Command(product.cpp.archiverPath, args); cmd.description = 'creating ' + output.fileName; cmd.highlight = 'linker' + cmd.jobPool = "linker"; cmd.responseFileUsagePrefix = '@'; return cmd; } } Rule { - id: loadableModuleLinker + name: "loadableModuleLinker" condition: product.cpp.shouldLink multiplex: true inputs: { @@ -504,9 +512,10 @@ CppModule { } return tags; } - inputsFromDependencies: ["dynamiclibrary_symbols", "staticlibrary"] + inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"] - outputFileTags: ["bundle.input", "loadablemodule", "debuginfo_loadablemodule"] + outputFileTags: ["bundle.input", "loadablemodule", "debuginfo_loadablemodule", + "debuginfo_bundle","debuginfo_plist"] outputArtifacts: { var app = { filePath: FileInfo.joinPaths(product.destinationDirectory, @@ -530,7 +539,7 @@ CppModule { } Rule { - id: applicationLinker + name: "applicationLinker" condition: product.cpp.shouldLink multiplex: true inputs: { @@ -541,9 +550,10 @@ CppModule { } return tags; } - inputsFromDependencies: ["dynamiclibrary_symbols", "staticlibrary"] + inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"] - outputFileTags: ["bundle.input", "application", "debuginfo_app"] + outputFileTags: ["bundle.input", "application", "debuginfo_app","debuginfo_bundle", + "debuginfo_plist"] outputArtifacts: { var app = { filePath: FileInfo.joinPaths(product.destinationDirectory, @@ -566,14 +576,18 @@ CppModule { } Rule { - id: compiler + name: "compiler" inputs: ["cpp", "c", "objcpp", "objc", "asm_cpp"] auxiliaryInputs: ["hpp"] explicitlyDependsOn: ["c_pch", "cpp_pch", "objc_pch", "objcpp_pch"] - outputFileTags: ["obj", "c_obj", "cpp_obj"] + outputFileTags: ["obj", "c_obj", "cpp_obj", "intermediate_obj"] outputArtifacts: { - var tags = ["obj"]; + var tags; + if (input.fileTags.contains("cpp_intermediate_object")) + tags = ["intermediate_obj"]; + else + tags = ["obj"]; if (inputs.c || inputs.objc) tags.push("c_obj"); if (inputs.cpp || inputs.objcpp) @@ -591,7 +605,7 @@ CppModule { } Rule { - id: assembler + name: "assembler" inputs: ["asm"] Artifact { diff --git a/share/qbs/modules/cpp/LinuxGCC.qbs b/share/qbs/modules/cpp/LinuxGCC.qbs index 6af648c40..14fb0a7e9 100644 --- a/share/qbs/modules/cpp/LinuxGCC.qbs +++ b/share/qbs/modules/cpp/LinuxGCC.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs 1.0 import qbs.Process UnixGCC { diff --git a/share/qbs/modules/cpp/UnixGCC.qbs b/share/qbs/modules/cpp/UnixGCC.qbs index ec26cffb6..e5b99cd98 100644 --- a/share/qbs/modules/cpp/UnixGCC.qbs +++ b/share/qbs/modules/cpp/UnixGCC.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs 1.0 import qbs.File GenericGCC { diff --git a/share/qbs/modules/cpp/android-gcc.qbs b/share/qbs/modules/cpp/android-gcc.qbs index b5dc367ee..e20f1e198 100644 --- a/share/qbs/modules/cpp/android-gcc.qbs +++ b/share/qbs/modules/cpp/android-gcc.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.File import qbs.FileInfo import qbs.ModUtils @@ -90,9 +89,18 @@ LinuxGCC { Group { name: "Android STL" - condition: product.cpp.sharedStlFilePath + condition: product.cpp.sharedStlFilePath && product.cpp.shouldLink files: product.cpp.sharedStlFilePath ? [product.cpp.sharedStlFilePath] : [] - fileTags: ["android.unstripped-stl"] + fileTags: "android.stl" + } + + Group { + name: "gdbserver" + condition: qbs.buildVariant !== "release" && product.cpp.shouldLink + files: FileInfo.joinPaths(Android.ndk.ndkDir, "prebuilt", + "android-" + NdkUtils.abiNameToDirName(Android.ndk.abi), + "gdbserver", "gdbserver") + fileTags: "android.gdbserver" } toolchainInstallPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains", @@ -222,82 +230,24 @@ LinuxGCC { endianness: "little" Rule { - inputs: ["android.unstripped-stl"] + condition: shouldLink + inputs: "dynamiclibrary" Artifact { - filePath: FileInfo.joinPaths("stripped-libs", input.fileName); - fileTags: ["android.stripped-stl"] + filePath: FileInfo.joinPaths("stripped-libs", input.fileName) + fileTags: "android.nativelibrary" } prepare: { - var args = ["--strip-unneeded", "-o", output.filePath, input.filePath]; - var cmd = new Command(product.cpp.stripPath, args); - cmd.description = "stripping " + input.fileName; - return [cmd]; + var stripArgs = ["--strip-unneeded", "-o", output.filePath, input.filePath]; + var stripCmd = new Command(product.cpp.stripPath, stripArgs); + stripCmd.description = "Stripping unneeded symbols from " + input.fileName; + return stripCmd; } } - Rule { - inputs: ["dynamiclibrary"] - explicitlyDependsOn: ["android.stripped-stl"]; - outputFileTags: ["android.nativelibrary", "android.gdbserver-info", "android.stl-info"] - outputArtifacts: { - var artifacts = [{ - filePath: FileInfo.joinPaths("stripped-libs", - inputs["dynamiclibrary"][0].fileName), - fileTags: ["android.nativelibrary"] - }]; - if (product.moduleProperty("qbs", "buildVariant") === "debug") { - artifacts.push({ - filePath: "android.gdbserver-info.txt", - fileTags: ["android.gdbserver-info"] - }); - } - if (explicitlyDependsOn["android.stripped-stl"]) - artifacts.push({filePath: "android.stl-info.txt", fileTags: ["android.stl-info"]}); - return artifacts; - } - - prepare: { - var copyCmd = new JavaScriptCommand(); - copyCmd.silent = true; - copyCmd.sourceCode = function() { - File.copy(inputs["dynamiclibrary"][0].filePath, - outputs["android.nativelibrary"][0].filePath); - var arch = product.moduleProperty("Android.ndk", "abi"); - var destDir = FileInfo.joinPaths("lib", arch); - if (product.moduleProperty("qbs", "buildVariant") === "debug") { - arch = NdkUtils.abiNameToDirName(arch); - var srcPath = FileInfo.joinPaths( - product.moduleProperty("Android.ndk", "ndkDir"), - "prebuilt/android-" + arch, "gdbserver/gdbserver"); - var targetPath = FileInfo.joinPaths(destDir, - product.moduleProperty("Android.ndk", "gdbserverFileName")); - var infoFile = new TextFile(outputs["android.gdbserver-info"][0].filePath, - TextFile.WriteOnly); - infoFile.writeLine(srcPath); - infoFile.writeLine(targetPath); - infoFile.close(); - } - var strippedStlList = explicitlyDependsOn["android.stripped-stl"]; - if (strippedStlList) { - var srcPath = strippedStlList[0].filePath; - var targetPath = FileInfo.joinPaths(destDir, FileInfo.fileName(srcPath)); - var infoFile = new TextFile(outputs["android.stl-info"][0].filePath, - TextFile.WriteOnly); - infoFile.writeLine(srcPath); - infoFile.writeLine(targetPath); - infoFile.close(); - } - } - var stripArgs = ["--strip-unneeded", outputs["android.nativelibrary"][0].filePath]; - var stripCmd = new Command(product.moduleProperty("cpp", "stripPath"), stripArgs); - stripCmd.description = "Stripping unneeded symbols from " - + outputs["android.nativelibrary"][0].fileName; - return [copyCmd, stripCmd]; - } - } + _skipAllChecks: !shouldLink validate: { - if (!_skipAllChecks) + if (_skipAllChecks) return; var baseValidator = new ModUtils.PropertyValidator("qbs"); baseValidator.addCustomValidator("architecture", targetArch, function (value) { diff --git a/share/qbs/modules/cpp/freebsd-gcc.qbs b/share/qbs/modules/cpp/freebsd-gcc.qbs index 724f242ff..b5a4b89f3 100644 --- a/share/qbs/modules/cpp/freebsd-gcc.qbs +++ b/share/qbs/modules/cpp/freebsd-gcc.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import "freebsd.js" as FreeBSD UnixGCC { diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js index 452d7a4d1..7e25fa402 100644 --- a/share/qbs/modules/cpp/gcc.js +++ b/share/qbs/modules/cpp/gcc.js @@ -78,6 +78,8 @@ function collectLibraryDependencies(product, isDarwin) { var publicDeps = {}; var objects = []; var objectByFilePath = {}; + var tagForLinkingAgainstSharedLib = product.qbs.toolchain.contains("mingw") + ? "dynamiclibrary_import" : "dynamiclibrary"; function addObject(obj, addFunc) { addFunc.call(objects, obj); @@ -151,7 +153,7 @@ function collectLibraryDependencies(product, isDarwin) { var isStaticLibrary = typeof dep.artifacts["staticlibrary"] !== "undefined"; var isDynamicLibrary = !isStaticLibrary - && typeof dep.artifacts["dynamiclibrary"] !== "undefined"; + && typeof dep.artifacts[tagForLinkingAgainstSharedLib] !== "undefined"; if (!isStaticLibrary && !isDynamicLibrary) return; @@ -173,10 +175,10 @@ function collectLibraryDependencies(product, isDarwin) { } } else if (isDynamicLibrary) { if (!isBelowIndirectDynamicLib) { - addArtifactFilePaths(dep, "dynamiclibrary", addPublicFilePath); + addArtifactFilePaths(dep, tagForLinkingAgainstSharedLib, addPublicFilePath); publicDeps[dep.name] = true; } else { - addArtifactFilePaths(dep, "dynamiclibrary", addPrivateFilePath); + addArtifactFilePaths(dep, tagForLinkingAgainstSharedLib, addPrivateFilePath); } } } @@ -245,7 +247,7 @@ function escapeLinkerFlags(product, inputs, linkerFlags) { return linkerFlags; } -function linkerFlags(project, product, inputs, output, linkerPath) { +function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPath) { var libraryPaths = product.cpp.libraryPaths; var distributionLibraryPaths = product.cpp.distributionLibraryPaths; var isDarwin = product.qbs.targetOS.contains("darwin"); @@ -261,7 +263,7 @@ function linkerFlags(project, product, inputs, output, linkerPath) { var escapableLinkerFlags = []; - if (output.fileTags.contains("dynamiclibrary")) { + if (primaryOutput.fileTags.contains("dynamiclibrary")) { if (isDarwin) { args.push((function () { var tags = ["c", "cpp", "objc", "objcpp", "asm_cpp"]; @@ -279,16 +281,18 @@ function linkerFlags(project, product, inputs, output, linkerPath) { var internalVersion = product.cpp.internalVersion; if (internalVersion && isNumericProductVersion(internalVersion)) args.push("-current_version", internalVersion); - escapableLinkerFlags.push("-install_name", UnixUtils.soname(product, output.fileName)); + escapableLinkerFlags.push("-install_name", UnixUtils.soname(product, + primaryOutput.fileName)); } else { - escapableLinkerFlags.push("-soname=" + UnixUtils.soname(product, output.fileName)); + escapableLinkerFlags.push("-soname=" + UnixUtils.soname(product, + primaryOutput.fileName)); } } - if (output.fileTags.contains("loadablemodule")) + if (primaryOutput.fileTags.contains("loadablemodule")) args.push(isDarwin ? "-bundle" : "-shared"); - if (output.fileTags.containsAny(["dynamiclibrary", "loadablemodule"])) { + if (primaryOutput.fileTags.containsAny(["dynamiclibrary", "loadablemodule"])) { if (isDarwin) escapableLinkerFlags.push("-headerpad_max_install_names"); else @@ -414,7 +418,7 @@ function linkerFlags(project, product, inputs, output, linkerPath) { // Note: due to the QCC response files hack in prepareLinker(), at least one object file or // library file must follow the output file path so that QCC has something to process before // sending the rest of the arguments through the response file. - args.push("-o", output.filePath); + args.push("-o", primaryOutput.filePath); if (inputs.obj) args = args.concat(inputs.obj.map(function (obj) { return obj.filePath })); @@ -501,6 +505,10 @@ function linkerFlags(project, product, inputs, output, linkerPath) { })); } + var importLibs = outputs.dynamiclibrary_import; + if (importLibs) + escapableLinkerFlags.push("--out-implib", importLibs[0].filePath); + var escapedLinkerFlags = escapeLinkerFlags(product, inputs, escapableLinkerFlags); Array.prototype.push.apply(escapedLinkerFlags, args); var driverLinkerFlags = useCompilerDriver ? product.cpp.driverLinkerFlags : undefined; @@ -976,6 +984,7 @@ function prepareAssembler(project, product, inputs, outputs, input, output) { var cmd = new Command(assemblerPath, args); cmd.description = "assembling " + input.fileName; cmd.highlight = "compiler"; + cmd.jobPool = "assembler"; return cmd; } @@ -1035,7 +1044,25 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli var args = compilerFlags(project, product, input, output, explicitlyDependsOn); var wrapperArgsLength = 0; var wrapperArgs = product.cpp.compilerWrapper; + var extraEnv; if (wrapperArgs && wrapperArgs.length > 0) { + + // distcc cannot deal with absolute compiler paths (QBS-1336). + for (var i = 0; i < wrapperArgs.length; ++i) { + if (FileInfo.baseName(wrapperArgs[i]) !== "distcc") + continue; + if (i === wrapperArgs.length - 1) { + if (FileInfo.isAbsolutePath(compilerPath)) { + extraEnv = ["PATH=" + FileInfo.path(compilerPath)]; + compilerPath = FileInfo.fileName(compilerPath); + } + } else if (FileInfo.isAbsolutePath(wrapperArgs[i + 1])) { + extraEnv = ["PATH=" + FileInfo.path(FileInfo.path(wrapperArgs[i + 1]))]; + wrapperArgs[i + 1] = FileInfo.fileName(wrapperArgs[i + 1]); + } + break; + } + wrapperArgsLength = wrapperArgs.length; args.unshift(compilerPath); compilerPath = wrapperArgs.shift(); @@ -1047,7 +1074,10 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli if (pchOutput) cmd.description += ' (' + compilerInfo.tag + ')'; cmd.highlight = "compiler"; + cmd.jobPool = "compiler"; cmd.relevantEnvironmentVariables = compilerEnvVars(input, compilerInfo); + if (extraEnv) + cmd.environment = extraEnv; cmd.responseFileArgumentIndex = wrapperArgsLength; cmd.responseFileUsagePrefix = '@'; setResponseFileThreshold(cmd, product); @@ -1240,7 +1270,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) { var linkerPath = effectiveLinkerPath(product, inputs) - var args = linkerFlags(project, product, inputs, primaryOutput, linkerPath); + var args = linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPath); var wrapperArgsLength = 0; var wrapperArgs = product.cpp.linkerWrapper; if (wrapperArgs && wrapperArgs.length > 0) { @@ -1266,6 +1296,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) { cmd = new Command(linkerPath, args); cmd.description = 'linking ' + primaryOutput.fileName; cmd.highlight = 'linker'; + cmd.jobPool = "linker"; cmd.relevantEnvironmentVariables = linkerEnvVars(product, inputs); cmd.responseFileArgumentIndex = responseFileArgumentIndex; cmd.responseFileUsagePrefix = useQnxResponseFileHack ? "-Wl,@" : "@"; diff --git a/share/qbs/modules/cpp/ios-gcc.qbs b/share/qbs/modules/cpp/ios-gcc.qbs index 408bc3aec..735766650 100644 --- a/share/qbs/modules/cpp/ios-gcc.qbs +++ b/share/qbs/modules/cpp/ios-gcc.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs 1.0 import qbs.DarwinTools import qbs.File import qbs.FileInfo diff --git a/share/qbs/modules/cpp/macos-gcc.qbs b/share/qbs/modules/cpp/macos-gcc.qbs index e2c930c80..612b46ae8 100644 --- a/share/qbs/modules/cpp/macos-gcc.qbs +++ b/share/qbs/modules/cpp/macos-gcc.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs 1.0 import qbs.ModUtils import qbs.Utilities diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js index d6df99dc2..1864c40e1 100644 --- a/share/qbs/modules/cpp/msvc.js +++ b/share/qbs/modules/cpp/msvc.js @@ -188,7 +188,8 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli if (product.cpp.debugInformation && product.cpp.separateDebugInformation) args.push("/Fd" + product.targetName + ".cl" + product.cpp.debugInfoSuffix); - var objOutput = outputs.obj ? outputs.obj[0] : undefined + var objectMap = outputs.obj || outputs.intermediate_obj + var objOutput = objectMap ? objectMap[0] : undefined args.push('/Fo' + FileInfo.toWindowsSeparators(objOutput.filePath)) args.push(FileInfo.toWindowsSeparators(input.filePath)) @@ -246,6 +247,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli if (pchOutput) cmd.description += ' (' + tag + ')'; cmd.highlight = "compiler"; + cmd.jobPool = "compiler"; cmd.workingDirectory = product.buildDirectory; cmd.responseFileUsagePrefix = '@'; // cl.exe outputs the cpp file name. We filter that out. @@ -261,8 +263,8 @@ function collectLibraryDependencies(product) { var seen = {}; var result = []; - function addFilePath(filePath, wholeArchive) { - result.push({ filePath: filePath, wholeArchive: wholeArchive }); + function addFilePath(filePath, wholeArchive, productName) { + result.push({ filePath: filePath, wholeArchive: wholeArchive, productName: productName }); } function addArtifactFilePaths(dep, artifacts) { @@ -270,8 +272,12 @@ function collectLibraryDependencies(product) { return; var artifactFilePaths = artifacts.map(function(a) { return a.filePath; }); var wholeArchive = dep.parameters.cpp && dep.parameters.cpp.linkWholeArchive; - for (var i = 0; i < artifactFilePaths.length; ++i) - addFilePath(artifactFilePaths[i], wholeArchive); + var artifactsAreImportLibs = artifacts.length > 0 + && artifacts[0].fileTags.contains("dynamiclibrary_import"); + for (var i = 0; i < artifactFilePaths.length; ++i) { + addFilePath(artifactFilePaths[i], wholeArchive, + artifactsAreImportLibs ? dep.name : undefined); + } } function addExternalLibs(obj) { @@ -466,14 +472,31 @@ function prepareLinker(project, product, inputs, outputs, input, output) { args = wrapperArgs.concat(args); } var commands = []; + var warningCmd = new JavaScriptCommand(); + warningCmd.silent = true; + warningCmd.libDeps = libDeps; + warningCmd.sourceCode = function() { + for (var i = 0; i < libDeps.length; ++i) { + if (!libDeps[i].productName || File.exists(libDeps[i].filePath)) + continue; + console.warn("Import library '" + FileInfo.toNativeSeparators(libDeps[i].filePath) + + "' does not exist. This typically happens when a DLL does not " + + "export any symbols. Please make sure the '" + libDeps[i].productName + + "' library exports symbols, or, if you do not intend to actually " + + "link against it, specify \"cpp.link: false\" in the Depends item."); + } + }; + commands.push(warningCmd); var cmd = new Command(linkerPath, args) cmd.description = 'linking ' + primaryOutput.fileName; cmd.highlight = 'linker'; + cmd.jobPool = "linker"; cmd.relevantEnvironmentVariables = ["LINK", "_LINK_", "LIB", "TMP"]; cmd.workingDirectory = FileInfo.path(primaryOutput.filePath) cmd.responseFileUsagePrefix = '@'; cmd.stdoutFilterFunction = function(output) { - return output.replace(/^(.*performing full link.*\r\n)? +Creating library.*\r\n$/, ""); + res = output.replace(/^.*performing full link.*\s*/, ""); + return res.replace(/^ *Creating library.*\r\n$/, ""); }; commands.push(cmd); diff --git a/share/qbs/modules/cpp/qnx-qcc.qbs b/share/qbs/modules/cpp/qnx-qcc.qbs index 28c9ce266..a39a6a998 100644 --- a/share/qbs/modules/cpp/qnx-qcc.qbs +++ b/share/qbs/modules/cpp/qnx-qcc.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.FileInfo UnixGCC { diff --git a/share/qbs/modules/cpp/tvos-gcc.qbs b/share/qbs/modules/cpp/tvos-gcc.qbs index ae4dd5c5b..19bc9b787 100644 --- a/share/qbs/modules/cpp/tvos-gcc.qbs +++ b/share/qbs/modules/cpp/tvos-gcc.qbs @@ -28,8 +28,6 @@ ** ****************************************************************************/ -import qbs - DarwinGCC { priority: 1 condition: qbs.targetOS.contains('tvos') && diff --git a/share/qbs/modules/cpp/watchos-gcc.qbs b/share/qbs/modules/cpp/watchos-gcc.qbs index c8bd0a55d..46e4bf874 100644 --- a/share/qbs/modules/cpp/watchos-gcc.qbs +++ b/share/qbs/modules/cpp/watchos-gcc.qbs @@ -29,8 +29,6 @@ ** ****************************************************************************/ -import qbs - DarwinGCC { priority: 1 condition: qbs.targetOS.contains('watchos') && diff --git a/share/qbs/modules/cpp/windows-mingw.qbs b/share/qbs/modules/cpp/windows-mingw.qbs index 3e3ba409d..27382742f 100644 --- a/share/qbs/modules/cpp/windows-mingw.qbs +++ b/share/qbs/modules/cpp/windows-mingw.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs 1.0 import qbs.ModUtils import qbs.TextFile import qbs.Utilities diff --git a/share/qbs/modules/cpp/windows-msvc.qbs b/share/qbs/modules/cpp/windows-msvc.qbs index 3164e08b5..8dd6dd2c0 100644 --- a/share/qbs/modules/cpp/windows-msvc.qbs +++ b/share/qbs/modules/cpp/windows-msvc.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs 1.0 import qbs.File import qbs.FileInfo import qbs.ModUtils @@ -114,7 +113,6 @@ CppModule { dynamicLibrarySuffix: ".dll" executableSuffix: ".exe" debugInfoSuffix: ".pdb" - property string dynamicLibraryImportSuffix: ".lib" imageFormat: "pe" Properties { condition: product.multiplexByQbsProperties.contains("buildVariants") @@ -170,14 +168,20 @@ CppModule { } Rule { - id: compiler + name: "compiler" inputs: ["cpp", "c"] auxiliaryInputs: ["hpp"] explicitlyDependsOn: ["c_pch", "cpp_pch"] - Artifact { - fileTags: ['obj'] - filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + ".obj" + outputFileTags: ["obj", "intermediate_obj"] + outputArtifacts: { + var tags = input.fileTags.contains("cpp_intermediate_object") + ? ["intermediate_obj"] + : ["obj"]; + return [{ + fileTags: tags, + filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + ".obj" + }]; } prepare: { @@ -191,7 +195,7 @@ CppModule { } Rule { - id: applicationLinker + name: "applicationLinker" multiplex: true inputs: ['obj', 'native.pe.manifest'] inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_app"] @@ -221,7 +225,7 @@ CppModule { } Rule { - id: dynamicLibraryLinker + name: "dynamicLibraryLinker" multiplex: true inputs: ['obj', 'native.pe.manifest'] inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_dll"] @@ -256,7 +260,7 @@ CppModule { } Rule { - id: libtool + name: "libtool" multiplex: true inputs: ["obj"] inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"] @@ -289,6 +293,7 @@ CppModule { var cmd = new Command("lib.exe", args); cmd.description = 'creating ' + lib.fileName; cmd.highlight = 'linker'; + cmd.jobPool = "linker"; cmd.workingDirectory = FileInfo.path(lib.filePath) cmd.responseFileUsagePrefix = '@'; return cmd; @@ -341,6 +346,7 @@ CppModule { var cmd = new Command('rc', args); cmd.description = 'compiling ' + input.fileName; cmd.highlight = 'compiler'; + cmd.jobPool = "compiler"; if (!hasNoLogo) { // Remove the first two lines of stdout. That's the logo. @@ -377,6 +383,7 @@ CppModule { ModUtils.moduleProperty(input, 'flags', 'asm')); var cmd = new Command(product.cpp.assemblerPath, args); cmd.description = "assembling " + input.fileName; + cmd.jobPool = "assembler"; cmd.inputFileName = input.fileName; cmd.stdoutFilterFunction = function(output) { var lines = output.split("\r\n").filter(function (s) { diff --git a/share/qbs/modules/cpufeatures/cpufeatures.qbs b/share/qbs/modules/cpufeatures/cpufeatures.qbs index a7ef95193..17e6b851e 100644 --- a/share/qbs/modules/cpufeatures/cpufeatures.qbs +++ b/share/qbs/modules/cpufeatures/cpufeatures.qbs @@ -1,5 +1,3 @@ -import qbs - Module { property bool arm_neon property bool arm_vfpv4 diff --git a/share/qbs/modules/dmg/DMGModule.qbs b/share/qbs/modules/dmg/DMGModule.qbs index 09e31f696..c5d097a0b 100644 --- a/share/qbs/modules/dmg/DMGModule.qbs +++ b/share/qbs/modules/dmg/DMGModule.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.DarwinTools import qbs.File import qbs.FileInfo @@ -140,7 +139,7 @@ Module { Rule { multiplex: true - inputs: ["qbs", "dmg.input", "dmg.license", "icns", "tiff"] + inputs: ["dmg.input", "dmg.license", "icns", "tiff"] Artifact { fileTags: ["dmg.dmg"] diff --git a/share/qbs/modules/ib/IBModule.qbs b/share/qbs/modules/ib/IBModule.qbs index 66d76aede..6af5e94e4 100644 --- a/share/qbs/modules/ib/IBModule.qbs +++ b/share/qbs/modules/ib/IBModule.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.BundleTools import qbs.DarwinTools import qbs.File @@ -175,7 +174,7 @@ Module { inputs: ["nib", "storyboard"] outputFileTags: { - var tags = []; + var tags = ["partial_infoplist"]; for (var i = 0; i < inputs.length; ++i) tags = tags.uniqueConcat(ModUtils.allFileTags(Ib.ibtoolFileTaggers(inputs[i]))); return tags; diff --git a/share/qbs/modules/ico/IcoModule.qbs b/share/qbs/modules/ico/IcoModule.qbs index 444fcd597..7157aab09 100644 --- a/share/qbs/modules/ico/IcoModule.qbs +++ b/share/qbs/modules/ico/IcoModule.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.FileInfo import qbs.ModUtils diff --git a/share/qbs/modules/innosetup/InnoSetupModule.qbs b/share/qbs/modules/innosetup/InnoSetupModule.qbs index bc5b74460..1caf39dc8 100644 --- a/share/qbs/modules/innosetup/InnoSetupModule.qbs +++ b/share/qbs/modules/innosetup/InnoSetupModule.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.FileInfo import qbs.ModUtils import qbs.Probes diff --git a/share/qbs/modules/java/JavaModule.qbs b/share/qbs/modules/java/JavaModule.qbs index 928684a4f..5191d6497 100644 --- a/share/qbs/modules/java/JavaModule.qbs +++ b/share/qbs/modules/java/JavaModule.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.FileInfo import qbs.ModUtils import qbs.Probes @@ -65,6 +64,8 @@ Module { property string keytoolFilePath: FileInfo.joinPaths(jdkPath, "bin", keytoolName) property string keytoolName: "keytool" + property bool _tagJniHeaders: true + property string jdkPath: jdk.path version: [compilerVersionMajor, compilerVersionMinor, compilerVersionPatch].join(".") @@ -233,9 +234,17 @@ Module { inputsFromDependencies: ["java.jar"] explicitlyDependsOn: ["java.class-internal"] - outputFileTags: ["java.class", "hpp"] // Annotations can produce additional java source files. Ignored for now. + outputFileTags: ["java.class"].concat(_tagJniHeaders ? ["hpp"] : []) // Annotations can produce additional java source files. Ignored for now. outputArtifacts: { - return JavaUtils.outputArtifacts(product, inputs); + var artifacts = JavaUtils.outputArtifacts(product, inputs); + if (!product.java._tagJniHeaders) { + for (var i = 0; i < artifacts.length; ++i) { + var a = artifacts[i]; + if (Array.isArray(a.fileTags)) + a.fileTags = a.fileTags.filter(function(tag) { return tag != "hpp"; }); + } + } + return artifacts; } prepare: { var cmd = new Command(ModUtils.moduleProperty(product, "compilerFilePath"), diff --git a/share/qbs/modules/lex_yacc/lexyacc.qbs b/share/qbs/modules/lex_yacc/lexyacc.qbs index 20982f7aa..48af1d793 100644 --- a/share/qbs/modules/lex_yacc/lexyacc.qbs +++ b/share/qbs/modules/lex_yacc/lexyacc.qbs @@ -1,4 +1,3 @@ -import qbs import "lexyacc.js" as HelperFunctions Module { diff --git a/share/qbs/modules/nodejs/NodeJS.qbs b/share/qbs/modules/nodejs/NodeJS.qbs index b40ea2d9e..7fd992fdb 100644 --- a/share/qbs/modules/nodejs/NodeJS.qbs +++ b/share/qbs/modules/nodejs/NodeJS.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.Environment import qbs.File import qbs.FileInfo @@ -42,12 +41,12 @@ Module { Probes.NodeJsProbe { id: nodejs - pathPrefixes: toolchainInstallPath ? [toolchainInstallPath] : [] + searchPaths: toolchainInstallPath ? [toolchainInstallPath] : [] } Probes.NpmProbe { id: npm - pathPrefixes: toolchainInstallPath ? [toolchainInstallPath] : [] + searchPaths: toolchainInstallPath ? [toolchainInstallPath] : [] interpreterPath: FileInfo.path(nodejs.filePath) } diff --git a/share/qbs/modules/nsis/NSISModule.qbs b/share/qbs/modules/nsis/NSISModule.qbs index ef1d5b0e1..e426aee56 100644 --- a/share/qbs/modules/nsis/NSISModule.qbs +++ b/share/qbs/modules/nsis/NSISModule.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs 1.0 import qbs.File import qbs.FileInfo import qbs.ModUtils diff --git a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs new file mode 100644 index 000000000..5cb3257d4 --- /dev/null +++ b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs @@ -0,0 +1,48 @@ +import qbs +import qbs.File +import qbs.FileInfo +import qbs.Probes +import "../protobufbase.qbs" as ProtobufBase +import "../protobuf.js" as HelperFunctions + +ProtobufBase { + property string includePath: includeProbe.path + property string libraryPath: libraryProbe.path + + Depends { name: "cpp" } + + cpp.libraryPaths: [libraryPath] + cpp.dynamicLibraries: qbs.targetOS.contains("unix") ? ["protobuf", "pthread"] : ["protobuf"] + cpp.includePaths: [outputDir, includePath] + + Rule { + inputs: ["protobuf.input"] + outputFileTags: ["hpp", "cpp"] + outputArtifacts: { + return [ + HelperFunctions.cppArtifact(input.protobuf.cpp, product, input, "hpp", ".pb.h"), + HelperFunctions.cppArtifact(input.protobuf.cpp, product, input, "cpp", ".pb.cc") + ]; + } + + prepare: HelperFunctions.doPrepare(input.protobuf.cpp, product, input, outputs, "cpp") + } + + validate: { + baseValidate(); + if (!HelperFunctions.checkPath(includePath)) + throw "Can't find cpp protobuf include files. Please set the includePath property."; + if (!HelperFunctions.checkPath(libraryPath)) + throw "Can't find cpp protobuf library. Please set the libraryPath property."; + } + + Probes.IncludeProbe { + id: includeProbe + names: "google/protobuf/message.h" + } + + Probes.LibraryProbe { + id: libraryProbe + names: "protobuf" + } +} diff --git a/share/qbs/modules/protobuf/objc/protobufobjc.qbs b/share/qbs/modules/protobuf/objc/protobufobjc.qbs new file mode 100644 index 000000000..c252d9949 --- /dev/null +++ b/share/qbs/modules/protobuf/objc/protobufobjc.qbs @@ -0,0 +1,70 @@ +import qbs +import qbs.File +import qbs.FileInfo +import qbs.Probes +import "../protobufbase.qbs" as ProtobufBase +import "../protobuf.js" as HelperFunctions + +ProtobufBase { + property string includePath: includeProbe.path + property string libraryPath: libraryProbe.path + property string frameworkPath: frameworkProbe.path + + Depends { name: "cpp" } + + // library build + Properties { + condition: !frameworkPath + cpp.includePaths: [outputDir, includePath] + cpp.libraryPaths: [libraryPath] + cpp.frameworks: ["Foundation"] + cpp.dynamicLibraries: ["ProtocolBuffers"] + } + + // framework build + Properties { + condition: frameworkPath + cpp.includePaths: [outputDir] + cpp.frameworkPaths: [frameworkPath] + cpp.frameworks: ["Foundation", "Protobuf"] + cpp.defines: ["GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS"] + } + + Rule { + inputs: ["protobuf.input"] + outputFileTags: ["hpp", "objc"] + outputArtifacts: { + return [ + HelperFunctions.objcArtifact(input.protobuf.objc, product, input, "hpp", ".pbobjc.h"), + HelperFunctions.objcArtifact(input.protobuf.objc, product, input, "objc", ".pbobjc.m") + ]; + } + + prepare: HelperFunctions.doPrepare(input.protobuf.objc, product, input, outputs, "objc") + } + + validate: { + baseValidate(); + if (!HelperFunctions.checkPath(frameworkPath)) { + if (!HelperFunctions.checkPath(includePath)) + throw "Can't find objective-c protobuf include files. Please set the includePath or frameworkPath property."; + if (!HelperFunctions.checkPath(libraryPath)) + throw "Can't find objective-c protobuf library. Please set the libraryPath or frameworkPath property."; + } + } + + Probes.IncludeProbe { + id: includeProbe + names: "GPBMessage.h" + } + + Probes.LibraryProbe { + id: libraryProbe + names: "ProtocolBuffers" + } + + Probes.FrameworkProbe { + id: frameworkProbe + names: ["Protobuf"] + } +} diff --git a/share/qbs/modules/protobuf/protobuf.js b/share/qbs/modules/protobuf/protobuf.js new file mode 100644 index 000000000..576a5ec07 --- /dev/null +++ b/share/qbs/modules/protobuf/protobuf.js @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Ivan Komissarov +** Contact: abbapoh@gmail.com +** +** This file is part of Qbs. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +var File = require("qbs.File"); +var FileInfo = require("qbs.FileInfo"); + +var checkPath = function(path) { + return path && File.exists(path) +}; + +function toCamelCase(str){ + return str.split('_').map(function(word, index) { + // If it is the first word make sure to lowercase all the chars. + if (index === 0) { + return word.toLowerCase(); + } + // If it is not the first word only upper case the first char and lowercase the rest. + return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); + }).join(''); +} + +function getOutputDir(module, product, input) { + var outputDir = module.outputDir; + var importPaths = module.importPaths; + if (importPaths.length !== 0) { + var canonicalInput = File.canonicalFilePath(FileInfo.path(input.filePath)); + for (var i = 0; i < importPaths.length; ++i) { + path = File.canonicalFilePath(importPaths[i]); + + if (canonicalInput.startsWith(path)) { + return outputDir + "/" + FileInfo.relativePath(path, canonicalInput); + } + } + } + return outputDir; +} + +function cppArtifact(module, product, input, tag, suffix) { + var outputDir = getOutputDir(module, product, input); + return { + fileTags: [tag], + filePath: outputDir + "/" + FileInfo.baseName(input.fileName) + suffix, + cpp: { + includePaths: [].concat(input.cpp.includePaths, outputDir), + warningLevel: "none", + } + }; +} + +function objcArtifact(module, product, input, tag, suffix) { + var outputDir = getOutputDir(module, product, input); + return { + fileTags: [tag], + filePath: outputDir + "/" + toCamelCase(FileInfo.baseName(input.fileName)) + suffix, + cpp: { + includePaths: [].concat(input.cpp.includePaths, outputDir), + warningLevel: "none", + } + } +} + +function doPrepare(module, product, input, outputs, lang) +{ + var outputDir = module.outputDir; + var args = []; + + args.push("--" + lang + "_out", outputDir); + + var importPaths = module.importPaths; + if (importPaths.length === 0) + importPaths = [FileInfo.path(input.filePath)]; + importPaths.forEach(function(path) { + if (!FileInfo.isAbsolutePath(path)) + path = FileInfo.joinPaths(product.sourceDirectory, path); + args.push("--proto_path", path); + }); + + args.push(input.filePath); + + var cmd = new Command(module.protocBinary, args); + cmd.highlight = "codegen"; + cmd.description = "generating " + lang + " files for " + input.fileName; + return [cmd]; +} diff --git a/share/qbs/modules/protobuf/protobufbase.qbs b/share/qbs/modules/protobuf/protobufbase.qbs new file mode 100644 index 000000000..1c2e68800 --- /dev/null +++ b/share/qbs/modules/protobuf/protobufbase.qbs @@ -0,0 +1,30 @@ +import qbs +import qbs.File +import qbs.FileInfo +import qbs.Probes +import "protobuf.js" as HelperFunctions + +Module { + property string protocBinary: protocProbe.filePath + property pathList importPaths: [] + + property string outputDir: product.buildDirectory + "/protobuf" + readonly property string protobufRoot: FileInfo.path(FileInfo.path(protocBinary)) + + readonly property var baseValidate: { + return function() { + if (!File.exists(protocBinary)) + throw "Can't find protoc binary. Please set the protocBinary property or make sure it is found in PATH"; + } + } + + FileTagger { + patterns: ["*.proto"] + fileTags: ["protobuf.input"]; + } + + Probes.BinaryProbe { + id: protocProbe + names: ["protoc"] + } +} diff --git a/share/qbs/modules/qbs/common.qbs b/share/qbs/modules/qbs/common.qbs index 86ce27c59..63bc29f8e 100644 --- a/share/qbs/modules/qbs/common.qbs +++ b/share/qbs/modules/qbs/common.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs 1.0 import qbs.Environment import qbs.FileInfo import qbs.ModUtils @@ -102,7 +101,7 @@ Module { property path installSourceBase property string installRoot: project.buildDirectory + "/install-root" property string installDir - property string installPrefix: "" + property string installPrefix: qbs.targetOS.contains("unix") ? "/usr/local" : "" property path sysroot PropertyOptions { @@ -196,28 +195,9 @@ Module { } // Properties that can be set for multiplexing products. - property stringList profiles - property stringList architectures: { - if (targetOS.contains("android")) - return ["armv7a"]; // default should be armv5te for NDK < r16, but we can't check here - if (targetOS.contains("ios-simulator")) - return ["x86", "x86_64"]; - if (targetOS.contains("ios")) - return ["armv7a", "arm64"]; - if (targetOS.contains("macos")) - return ["x86_64"]; - if (targetOS.contains("tvos-simulator")) - return ["x86_64"]; - if (targetOS.contains("tvos")) - return ["arm64"]; - if (targetOS.contains("watchos-simulator")) - return ["x86"]; - if (targetOS.contains("watchos")) - return ["armv7k"]; - return architecture ? [architecture] : undefined; - } - - property stringList buildVariants: [buildVariant] + property stringList profiles: [] + property stringList architectures: [] + property stringList buildVariants: [] // internal properties readonly property string version: [versionMajor, versionMinor, versionPatch].join(".") diff --git a/share/qbs/modules/qnx/qnx.qbs b/share/qbs/modules/qnx/qnx.qbs index 49ebc36b6..9cab5abb6 100644 --- a/share/qbs/modules/qnx/qnx.qbs +++ b/share/qbs/modules/qnx/qnx.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.Environment import qbs.File import qbs.FileInfo @@ -40,7 +39,7 @@ Module { Probes.PathProbe { id: qnxSdkProbe names: ["qnx700", "qnx660", "qnx650"] - pathPrefixes: qbs.hostOS.contains("windows") + searchPaths: qbs.hostOS.contains("windows") ? [Environment.getEnv("USERPROFILE"), Environment.getEnv("SystemDrive")] : [Environment.getEnv("HOME"), "/opt"] } diff --git a/share/qbs/modules/texttemplate/texttemplate.qbs b/share/qbs/modules/texttemplate/texttemplate.qbs new file mode 100644 index 000000000..c72929660 --- /dev/null +++ b/share/qbs/modules/texttemplate/texttemplate.qbs @@ -0,0 +1,64 @@ +import qbs.TextFile + +Module { + property var dict: ({}) + property string outputTag: "text" + property string outputFileName + FileTagger { + patterns: ["*.in"] + fileTags: ["texttemplate.input"] + } + Rule { + inputs: ["texttemplate.input"] + outputFileTags: [product.texttemplate.outputTag] + outputArtifacts: [ + { + fileTags: [product.texttemplate.outputTag], + filePath: input.texttemplate.outputFileName || input.completeBaseName + } + ] + prepare: { + var cmd = new JavaScriptCommand(); + cmd.silent = true; + cmd.sourceCode = function() { + try { + var src = new TextFile(input.filePath, TextFile.ReadOnly); + var dst = new TextFile(output.filePath, TextFile.WriteOnly); + var rex = /\${(\$|\w+)}/g; + var match; + while (!src.atEof()) { + rex.lastIndex = 0; + var line = src.readLine(); + var matches = []; + while (match = rex.exec(line)) + matches.push(match); + for (var i = matches.length; --i >= 0;) { + match = matches[i]; + var replacement; + if (match[1] === "$") { + replacement = "$"; + } else { + replacement = input.texttemplate.dict[match[1]]; + if (typeof replacement === "undefined") { + throw new Error("Placeholder '" + match[1] + + "' is not defined in textemplate.dict for '" + + input.fileName + "'."); + } + } + line = line.substr(0, match.index) + + replacement + + line.substr(match.index + match[0].length); + } + dst.writeLine(line); + } + } finally { + if (src) + src.close(); + if (dst) + dst.close(); + } + }; + return [cmd]; + } + } +} diff --git a/share/qbs/modules/typescript/TypeScriptModule.qbs b/share/qbs/modules/typescript/TypeScriptModule.qbs index 7cbd02265..d8e61b17f 100644 --- a/share/qbs/modules/typescript/TypeScriptModule.qbs +++ b/share/qbs/modules/typescript/TypeScriptModule.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.File import qbs.FileInfo import qbs.ModUtils diff --git a/share/qbs/modules/vcs/vcs-module.qbs b/share/qbs/modules/vcs/vcs-module.qbs index ee7a34582..f3a47d2a6 100644 --- a/share/qbs/modules/vcs/vcs-module.qbs +++ b/share/qbs/modules/vcs/vcs-module.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.FileInfo import qbs.Process diff --git a/share/qbs/modules/wix/WiXModule.qbs b/share/qbs/modules/wix/WiXModule.qbs index 3159822de..ad8586da1 100644 --- a/share/qbs/modules/wix/WiXModule.qbs +++ b/share/qbs/modules/wix/WiXModule.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.File import qbs.FileInfo import qbs.ModUtils diff --git a/share/qbs/modules/xcode/xcode.qbs b/share/qbs/modules/xcode/xcode.qbs index 0df7f5204..922580505 100644 --- a/share/qbs/modules/xcode/xcode.qbs +++ b/share/qbs/modules/xcode/xcode.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.BundleTools import qbs.Environment import qbs.File diff --git a/share/share.qbs b/share/share.qbs index 2d4b4532f..6c99f64d5 100644 --- a/share/share.qbs +++ b/share/share.qbs @@ -6,7 +6,7 @@ import qbs.Utilities Product { name: "qbs resources" - type: ["copied qbs resources", "qbs qml type descriptions", "qbs qml type bundle"] + type: ["qbs qml type descriptions", "qbs qml type bundle"] Depends { name: "qbsbuildconfig" } Group { @@ -65,31 +65,10 @@ Product { } Rule { - inputs: ["qbs resources"] - Artifact { - filePath: FileInfo.joinPaths( - project.buildDirectory, - input.moduleProperty("qbs", "installDir"), - FileInfo.relativePath(input.moduleProperty("qbs", "installSourceBase"), - input.filePath)) - fileTags: ["copied qbs resources"] - } - prepare: { - var cmd = new JavaScriptCommand(); - cmd.description = "Copying resource " + input.fileName + " to build directory."; - cmd.highlight = "codegen"; - cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); } - return cmd; - } - } - - Rule { condition: Utilities.versionCompare(product.qbs.version, "1.9.1") >= 0 multiplex: true Artifact { - filePath: FileInfo.joinPaths( - project.buildDirectory, - product.qbsbuildconfig.qmlTypeDescriptionsInstallDir, "qbs.qmltypes") + filePath: "qbs.qmltypes" fileTags: ["qbs qml type descriptions"] } prepare: { @@ -114,9 +93,7 @@ Product { condition: Utilities.versionCompare(product.qbs.version, "1.9.1") >= 0 multiplex: true Artifact { - filePath: FileInfo.joinPaths( - project.buildDirectory, - product.qbsbuildconfig.qmlTypeDescriptionsInstallDir, "qbs-bundle.json") + filePath: "qbs-bundle.json" fileTags: ["qbs qml type bundle"] } prepare: { @@ -155,6 +132,6 @@ Product { name: "QML Type Info" fileTagsFilter: ["qbs qml type descriptions", "qbs qml type bundle"] qbs.install: true - qbs.installSourceBase: project.buildDirectory + qbs.installDir: qbsbuildconfig.qmlTypeDescriptionsInstallDir } } diff --git a/src/app/qbs-setup-android/commandlineparser.cpp b/src/app/qbs-setup-android/commandlineparser.cpp index 1bdf2188b..616c829de 100644 --- a/src/app/qbs-setup-android/commandlineparser.cpp +++ b/src/app/qbs-setup-android/commandlineparser.cpp @@ -86,6 +86,8 @@ void CommandLineParser::parse(const QStringList &commandLine) assignOptionArgument(ndkDirOption(), m_ndkDir); else if (arg == qtSdkDirOption()) assignOptionArgument(arg, m_qtSdkDir); + else + throwError(Tr::tr("Unknown option '%1'.").arg(arg)); } if (m_helpRequested) { diff --git a/src/app/qbs/commandlinefrontend.cpp b/src/app/qbs/commandlinefrontend.cpp index d07af0d6f..978fdbb7a 100644 --- a/src/app/qbs/commandlinefrontend.cpp +++ b/src/app/qbs/commandlinefrontend.cpp @@ -588,8 +588,14 @@ void CommandLineFrontend::listProducts() { const QList<ProductData> products = productsToUse().begin().value(); QStringList output; - for (const ProductData &p : products) - output += p.fullDisplayName(); + for (const ProductData &p : products) { + QString productInfo = p.fullDisplayName(); + if (!p.isEnabled()) + productInfo.append(QLatin1Char(' ')).append(Tr::tr("[disabled]")); + else if (!p.properties().value(QLatin1String("builtByDefault")).toBool()) + productInfo.append(QLatin1Char(' ')).append(Tr::tr("[not built by default]")); + output += productInfo; + } output.sort(); qbsInfo() << output.join(QLatin1Char('\n')); } diff --git a/src/app/qbs/consoleprogressobserver.cpp b/src/app/qbs/consoleprogressobserver.cpp index b6110077b..b49723a64 100644 --- a/src/app/qbs/consoleprogressobserver.cpp +++ b/src/app/qbs/consoleprogressobserver.cpp @@ -87,11 +87,16 @@ void ConsoleProgressObserver::setProgressValue(int value) void ConsoleProgressObserver::eraseCurrentPercentageString() { const int charsToErase = m_percentage == 0 ? 2 : m_percentage < 10 ? 3 : 4; + const QByteArray backspaceCommand(charsToErase, '\b'); - // (1) Move cursor before the old percentage string. - // (2) Erase current line content to the right of the cursor. - std::cout << QString::fromLatin1("\x1b[%1D").arg(charsToErase).toLocal8Bit().constData(); - std::cout << "\x1b[K"; + // Move cursor before the old percentage string. + std::cout << backspaceCommand.constData(); + + // Erase old percentage string. + std::cout << QByteArray(charsToErase, ' ').constData(); + + // Move cursor before the erased string. + std::cout << backspaceCommand.constData(); } void ConsoleProgressObserver::updateProgressBarIfNecessary() diff --git a/src/app/qbs/parser/commandlineoption.cpp b/src/app/qbs/parser/commandlineoption.cpp index c2eea340a..e18658751 100644 --- a/src/app/qbs/parser/commandlineoption.cpp +++ b/src/app/qbs/parser/commandlineoption.cpp @@ -574,6 +574,59 @@ void SettingsDirOption::doParse(const QString &representation, QStringList &inpu m_settingsDir = input.takeFirst(); } +QString JobLimitsOption::description(CommandType command) const +{ + Q_UNUSED(command); + return Tr::tr("%1 <pool1>:<limit1>[,<pool2>:<limit2>...]\n" + "\tSet pool-specific job limits.\n").arg(longRepresentation()); +} + +QString JobLimitsOption::longRepresentation() const +{ + return QLatin1String("--job-limits"); +} + +void JobLimitsOption::doParse(const QString &representation, QStringList &input) +{ + if (input.empty()) { + throw ErrorInfo(Tr::tr("Invalid use of option '%1: Argument expected.\n" + "Usage: %2").arg(representation, description(command()))); + } + const QString jobLimitsSpec = input.takeFirst(); + const QStringList jobLimitStrings = jobLimitsSpec.split(QLatin1Char(',')); + for (const QString &jobLimitString : jobLimitStrings) { + const int sepIndex = jobLimitString.indexOf(QLatin1Char(':')); + if (sepIndex <= 0 || sepIndex == jobLimitString.size() - 1) { + throw ErrorInfo(Tr::tr("Invalid use of option '%1: " + "Invalid job limits specification '%2'.\n" + "Usage: %3").arg(representation, jobLimitsSpec, + description(command()))); + } + const QString pool = jobLimitString.left(sepIndex); + const QString limitString = jobLimitString.mid(sepIndex + 1); + bool isValidNumber; + const int limit = limitString.toInt(&isValidNumber); + if (!isValidNumber) { + throw ErrorInfo(Tr::tr("Invalid use of option '%1: '%2' is not a number.\n" + "Usage: %3").arg(representation, limitString, + description(command()))); + } + m_jobLimits.setJobLimit(pool, limit); + } +} + +QString RespectProjectJobLimitsOption::description(CommandType command) const +{ + Q_UNUSED(command); + return Tr::tr("%1\n\tGive maximum priority to job limits defined inside the project.\n") + .arg(longRepresentation()); +} + +QString RespectProjectJobLimitsOption::longRepresentation() const +{ + return QLatin1String("--enforce-project-job-limits"); +} + CommandEchoModeOption::CommandEchoModeOption() { } diff --git a/src/app/qbs/parser/commandlineoption.h b/src/app/qbs/parser/commandlineoption.h index c645c533b..d57ec76b7 100644 --- a/src/app/qbs/parser/commandlineoption.h +++ b/src/app/qbs/parser/commandlineoption.h @@ -42,6 +42,7 @@ #include "commandtype.h" #include <tools/commandechomode.h> +#include <tools/joblimits.h> #include <QtCore/qstringlist.h> @@ -69,6 +70,8 @@ public: LogTimeOptionType, CommandEchoModeOptionType, SettingsDirOptionType, + JobLimitsOptionType, + RespectProjectJobLimitsOptionType, GeneratorOptionType, WaitLockOptionType, RunEnvConfigOptionType, @@ -380,6 +383,29 @@ private: QString m_settingsDir; }; +class JobLimitsOption : public CommandLineOption +{ +public: + JobLimits jobLimits() const { return m_jobLimits; } + + QString description(CommandType command) const override; + QString shortRepresentation() const override { return QString(); } + QString longRepresentation() const override; + +private: + void doParse(const QString &representation, QStringList &input) override; + + JobLimits m_jobLimits; +}; + +class RespectProjectJobLimitsOption : public OnOffOption +{ +public: + QString description(CommandType command) const override; + QString shortRepresentation() const override { return QString(); } + QString longRepresentation() const override; +}; + class WaitLockOption : public OnOffOption { public: diff --git a/src/app/qbs/parser/commandlineoptionpool.cpp b/src/app/qbs/parser/commandlineoptionpool.cpp index 8850fad87..9964f051a 100644 --- a/src/app/qbs/parser/commandlineoptionpool.cpp +++ b/src/app/qbs/parser/commandlineoptionpool.cpp @@ -116,6 +116,12 @@ CommandLineOption *CommandLineOptionPool::getOption(CommandLineOption::Type type case CommandLineOption::SettingsDirOptionType: option = new SettingsDirOption; break; + case CommandLineOption::JobLimitsOptionType: + option = new JobLimitsOption; + break; + case CommandLineOption::RespectProjectJobLimitsOptionType: + option = new RespectProjectJobLimitsOption; + break; case CommandLineOption::GeneratorOptionType: option = new GeneratorOption; break; @@ -246,6 +252,17 @@ SettingsDirOption *CommandLineOptionPool::settingsDirOption() const return static_cast<SettingsDirOption *>(getOption(CommandLineOption::SettingsDirOptionType)); } +JobLimitsOption *CommandLineOptionPool::jobLimitsOption() const +{ + return static_cast<JobLimitsOption *>(getOption(CommandLineOption::JobLimitsOptionType)); +} + +RespectProjectJobLimitsOption *CommandLineOptionPool::respectProjectJobLimitsOption() const +{ + return static_cast<RespectProjectJobLimitsOption *>( + getOption(CommandLineOption::RespectProjectJobLimitsOptionType)); +} + GeneratorOption *CommandLineOptionPool::generatorOption() const { return static_cast<GeneratorOption *>(getOption(CommandLineOption::GeneratorOptionType)); diff --git a/src/app/qbs/parser/commandlineoptionpool.h b/src/app/qbs/parser/commandlineoptionpool.h index a4e6c30c1..6a4669165 100644 --- a/src/app/qbs/parser/commandlineoptionpool.h +++ b/src/app/qbs/parser/commandlineoptionpool.h @@ -73,6 +73,8 @@ public: LogTimeOption *logTimeOption() const; CommandEchoModeOption *commandEchoModeOption() const; SettingsDirOption *settingsDirOption() const; + JobLimitsOption *jobLimitsOption() const; + RespectProjectJobLimitsOption *respectProjectJobLimitsOption() const; GeneratorOption *generatorOption() const; WaitLockOption *waitLockOption() const; RunEnvConfigOption *runEnvConfigOption() const; diff --git a/src/app/qbs/parser/commandlineparser.cpp b/src/app/qbs/parser/commandlineparser.cpp index 92c43c8c6..c2e265336 100644 --- a/src/app/qbs/parser/commandlineparser.cpp +++ b/src/app/qbs/parser/commandlineparser.cpp @@ -462,6 +462,10 @@ void CommandLineParser::CommandLineParserPrivate::setupBuildOptions() buildOptions.setEchoMode(echoMode()); buildOptions.setInstall(!optionPool.noInstallOption()->enabled()); buildOptions.setRemoveExistingInstallation(optionPool.removeFirstoption()->enabled()); + buildOptions.setJobLimits(optionPool.jobLimitsOption()->jobLimits()); + buildOptions.setProjectJobLimitsTakePrecedence( + optionPool.respectProjectJobLimitsOption()->enabled()); + buildOptions.setSettingsDirectory(settingsDir()); } void CommandLineParser::CommandLineParserPrivate::setupBuildConfigurations() diff --git a/src/app/qbs/parser/parsercommand.cpp b/src/app/qbs/parser/parsercommand.cpp index b85e98540..33f93ce53 100644 --- a/src/app/qbs/parser/parsercommand.cpp +++ b/src/app/qbs/parser/parsercommand.cpp @@ -94,8 +94,6 @@ void Command::parsePropertyAssignment(const QString &argument) QList<CommandLineOption::Type> Command::actualSupportedOptions() const { QList<CommandLineOption::Type> options = supportedOptions(); - if (!HostOsInfo::isAnyUnixHost()) - options.removeOne(CommandLineOption::ShowProgressOptionType); if (type() != HelpCommandType) options.push_back(CommandLineOption::SettingsDirOptionType); // Valid for almost all commands. return options; @@ -287,6 +285,8 @@ static QList<CommandLineOption::Type> buildOptions() << CommandLineOption::CommandEchoModeOptionType << CommandLineOption::NoInstallOptionType << CommandLineOption::RemoveFirstOptionType + << CommandLineOption::JobLimitsOptionType + << CommandLineOption::RespectProjectJobLimitsOptionType << CommandLineOption::WaitLockOptionType; } diff --git a/src/app/shared/logging/coloredoutput.cpp b/src/app/shared/logging/coloredoutput.cpp index 33e647d36..0f1bb26da 100644 --- a/src/app/shared/logging/coloredoutput.cpp +++ b/src/app/shared/logging/coloredoutput.cpp @@ -38,7 +38,7 @@ ****************************************************************************/ #include "coloredoutput.h" -#include <QtCore/qglobal.h> +#include <QtCore/qbytearray.h> #ifdef Q_OS_WIN32 # include <QtCore/qt_windows.h> #endif @@ -99,3 +99,13 @@ void fprintfColored(TextColor color, FILE *file, const char *str, ...) fprintfColored(color, file, str, vl); va_end(vl); } + +bool terminalSupportsColor() +{ +#if defined(Q_OS_UNIX) + const QByteArray &term = qgetenv("TERM"); + return !term.isEmpty() && term != "dumb"; +#else + return true; +#endif +} diff --git a/src/app/shared/logging/coloredoutput.h b/src/app/shared/logging/coloredoutput.h index 182d96bbe..a7b145ba5 100644 --- a/src/app/shared/logging/coloredoutput.h +++ b/src/app/shared/logging/coloredoutput.h @@ -68,5 +68,6 @@ void printfColored(TextColor color, const char *str, va_list vl); void printfColored(TextColor color, const char *str, ...); void fprintfColored(TextColor color, FILE *file, const char *str, va_list vl); void fprintfColored(TextColor color, FILE *file, const char *str, ...); +bool terminalSupportsColor(); #endif // QBS_COLOREDOUTPUT_H diff --git a/src/app/shared/logging/consolelogger.cpp b/src/app/shared/logging/consolelogger.cpp index ca270759c..7639fb111 100644 --- a/src/app/shared/logging/consolelogger.cpp +++ b/src/app/shared/logging/consolelogger.cpp @@ -91,7 +91,7 @@ void ConsoleLogSink::fprintfWrapper(TextColor color, FILE *file, const char *str { va_list vl; va_start(vl, str); - if (m_coloredOutputEnabled) + if (m_coloredOutputEnabled && terminalSupportsColor()) fprintfColored(color, file, str, vl); else vfprintf(file, str, vl); diff --git a/src/lib/corelib/api/internaljobs.cpp b/src/lib/corelib/api/internaljobs.cpp index 5122db8ee..048ae5656 100644 --- a/src/lib/corelib/api/internaljobs.cpp +++ b/src/lib/corelib/api/internaljobs.cpp @@ -161,7 +161,10 @@ void InternalJob::storeBuildGraph(const TopLevelProjectPtr &project) TimedActivityLogger storeTimer(m_logger, Tr::tr("Storing build graph"), timed()); project->store(logger()); } catch (const ErrorInfo &error) { - logger().printWarning(error); + ErrorInfo fullError = this->error(); + for (const ErrorItem &item : error.items()) + fullError.append(item); + setError(fullError); } } @@ -246,7 +249,7 @@ TopLevelProjectPtr InternalSetupProjectJob::project() const void InternalSetupProjectJob::start() { - BuildGraphLocker *bgLocker = m_existingProject ? m_existingProject->bgLocker : 0; + BuildGraphLocker *bgLocker = m_existingProject ? m_existingProject->bgLocker : nullptr; bool deleteLocker = false; try { const ErrorInfo err = m_parameters.expandBuildConfiguration(); diff --git a/src/lib/corelib/api/jobs.cpp b/src/lib/corelib/api/jobs.cpp index 28b8a40fa..32b7accc7 100644 --- a/src/lib/corelib/api/jobs.cpp +++ b/src/lib/corelib/api/jobs.cpp @@ -229,10 +229,8 @@ SetupProjectJob::SetupProjectJob(const Logger &logger, QObject *parent) */ Project SetupProjectJob::project() const { - const InternalJobThreadWrapper * const wrapper - = qobject_cast<InternalJobThreadWrapper *>(internalJob()); - const InternalSetupProjectJob * const job - = qobject_cast<InternalSetupProjectJob *>(wrapper->synchronousJob()); + auto const wrapper = qobject_cast<const InternalJobThreadWrapper *>(internalJob()); + auto const job = qobject_cast<const InternalSetupProjectJob *>(wrapper->synchronousJob()); return Project(job->project(), job->logger()); } @@ -244,20 +242,16 @@ void SetupProjectJob::resolve(const Project &existingProject, = existingProject.d ? existingProject.d->internalProject : TopLevelProjectPtr(); if (existingInternalProject && !lockProject(existingInternalProject)) return; - InternalJobThreadWrapper * const wrapper - = qobject_cast<InternalJobThreadWrapper *>(internalJob()); - InternalSetupProjectJob * const job - = qobject_cast<InternalSetupProjectJob *>(wrapper->synchronousJob()); + auto const wrapper = qobject_cast<InternalJobThreadWrapper *>(internalJob()); + auto const job = qobject_cast<InternalSetupProjectJob *>(wrapper->synchronousJob()); job->init(existingInternalProject, parameters); wrapper->start(); } void SetupProjectJob::reportError(const ErrorInfo &error) { - InternalJobThreadWrapper * const wrapper - = qobject_cast<InternalJobThreadWrapper *>(internalJob()); - InternalSetupProjectJob * const job - = qobject_cast<InternalSetupProjectJob *>(wrapper->synchronousJob()); + auto const wrapper = qobject_cast<const InternalJobThreadWrapper *>(internalJob()); + auto const job = qobject_cast<InternalSetupProjectJob *>(wrapper->synchronousJob()); job->reportError(error); } @@ -351,7 +345,7 @@ void CleanJob::clean(const TopLevelProjectPtr &project, const QList<ResolvedProd { if (!lockProject(project)) return; - InternalJobThreadWrapper * wrapper = qobject_cast<InternalJobThreadWrapper *>(internalJob()); + auto wrapper = qobject_cast<InternalJobThreadWrapper *>(internalJob()); qobject_cast<InternalCleanJob *>(wrapper->synchronousJob())->init(project, products, options); wrapper->start(); } @@ -371,8 +365,8 @@ void InstallJob::install(const TopLevelProjectPtr &project, { if (!lockProject(project)) return; - InternalJobThreadWrapper *wrapper = qobject_cast<InternalJobThreadWrapper *>(internalJob()); - InternalInstallJob *installJob = qobject_cast<InternalInstallJob *>(wrapper->synchronousJob()); + auto wrapper = qobject_cast<InternalJobThreadWrapper *>(internalJob()); + auto installJob = qobject_cast<InternalInstallJob *>(wrapper->synchronousJob()); installJob->init(project, std::vector<ResolvedProductPtr>(products.cbegin(), products.cend()), options); diff --git a/src/lib/corelib/api/jobs.h b/src/lib/corelib/api/jobs.h index 04a0093c1..f121cc403 100644 --- a/src/lib/corelib/api/jobs.h +++ b/src/lib/corelib/api/jobs.h @@ -118,7 +118,7 @@ private: void resolve(const Project &existingProject, const SetupProjectParameters ¶meters); void reportError(const ErrorInfo &error); - void finish(); + void finish() override; Project m_existingProject; }; @@ -140,7 +140,7 @@ private: const BuildOptions &options); void handleLauncherError(const ErrorInfo &error); - void finish(); + void finish() override; }; diff --git a/src/lib/corelib/api/project.cpp b/src/lib/corelib/api/project.cpp index 5bbfb31c7..d1cb351be 100644 --- a/src/lib/corelib/api/project.cpp +++ b/src/lib/corelib/api/project.cpp @@ -1031,7 +1031,7 @@ RunEnvironment Project::getRunEnvironment(const ProductData &product, BuildJob *Project::buildAllProducts(const BuildOptions &options, ProductSelection productSelection, QObject *jobOwner) const { - QBS_ASSERT(isValid(), return 0); + QBS_ASSERT(isValid(), return nullptr); const bool includingNonDefault = productSelection == ProductSelectionWithNonDefault; return d->buildProducts(d->allEnabledInternalProducts(includingNonDefault), options, !includingNonDefault, jobOwner); @@ -1046,7 +1046,7 @@ BuildJob *Project::buildAllProducts(const BuildOptions &options, ProductSelectio BuildJob *Project::buildSomeProducts(const QList<ProductData> &products, const BuildOptions &options, QObject *jobOwner) const { - QBS_ASSERT(isValid(), return 0); + QBS_ASSERT(isValid(), return nullptr); return d->buildProducts(d->internalProducts(products), options, true, jobOwner); } @@ -1067,7 +1067,7 @@ BuildJob *Project::buildOneProduct(const ProductData &product, const BuildOption */ CleanJob *Project::cleanAllProducts(const CleanOptions &options, QObject *jobOwner) const { - QBS_ASSERT(isValid(), return 0); + QBS_ASSERT(isValid(), return nullptr); return d->cleanProducts(d->allEnabledInternalProducts(true), options, jobOwner); } @@ -1078,7 +1078,7 @@ CleanJob *Project::cleanAllProducts(const CleanOptions &options, QObject *jobOwn CleanJob *Project::cleanSomeProducts(const QList<ProductData> &products, const CleanOptions &options, QObject *jobOwner) const { - QBS_ASSERT(isValid(), return 0); + QBS_ASSERT(isValid(), return nullptr); return d->cleanProducts(d->internalProducts(products), options, jobOwner); } @@ -1101,7 +1101,7 @@ CleanJob *Project::cleanOneProduct(const ProductData &product, const CleanOption InstallJob *Project::installAllProducts(const InstallOptions &options, ProductSelection productSelection, QObject *jobOwner) const { - QBS_ASSERT(isValid(), return 0); + QBS_ASSERT(isValid(), return nullptr); const bool includingNonDefault = productSelection == ProductSelectionWithNonDefault; return d->installProducts(d->allEnabledInternalProducts(includingNonDefault), options, !includingNonDefault, jobOwner); @@ -1114,7 +1114,7 @@ InstallJob *Project::installAllProducts(const InstallOptions &options, InstallJob *Project::installSomeProducts(const QList<ProductData> &products, const InstallOptions &options, QObject *jobOwner) const { - QBS_ASSERT(isValid(), return 0); + QBS_ASSERT(isValid(), return nullptr); return d->installProducts(d->internalProducts(products), options, true, jobOwner); } diff --git a/src/lib/corelib/api/project.h b/src/lib/corelib/api/project.h index b43eecfc7..05f08deee 100644 --- a/src/lib/corelib/api/project.h +++ b/src/lib/corelib/api/project.h @@ -104,25 +104,26 @@ public: enum ProductSelection { ProductSelectionDefaultOnly, ProductSelectionWithNonDefault }; BuildJob *buildAllProducts(const BuildOptions &options, ProductSelection productSelection = ProductSelectionDefaultOnly, - QObject *jobOwner = 0) const; + QObject *jobOwner = nullptr) const; BuildJob *buildSomeProducts(const QList<ProductData> &products, const BuildOptions &options, - QObject *jobOwner = 0) const; + QObject *jobOwner = nullptr) const; BuildJob *buildOneProduct(const ProductData &product, const BuildOptions &options, - QObject *jobOwner = 0) const; + QObject *jobOwner = nullptr) const; - CleanJob *cleanAllProducts(const CleanOptions &options, QObject *jobOwner = 0) const; + CleanJob *cleanAllProducts(const CleanOptions &options, QObject *jobOwner = nullptr) const; CleanJob *cleanSomeProducts(const QList<ProductData> &products, const CleanOptions &options, - QObject *jobOwner = 0) const; + QObject *jobOwner = nullptr) const; CleanJob *cleanOneProduct(const ProductData &product, const CleanOptions &options, - QObject *jobOwner = 0) const; + QObject *jobOwner = nullptr) const; InstallJob *installAllProducts(const InstallOptions &options, ProductSelection productSelection = ProductSelectionDefaultOnly, - QObject *jobOwner = 0) const; + QObject *jobOwner = nullptr) const; InstallJob *installSomeProducts(const QList<ProductData> &products, - const InstallOptions &options, QObject *jobOwner = 0) const; + const InstallOptions &options, + QObject *jobOwner = nullptr) const; InstallJob *installOneProduct(const ProductData &product, const InstallOptions &options, - QObject *jobOwner = 0) const; + QObject *jobOwner = nullptr) const; void updateTimestamps(const QList<ProductData> &products); @@ -136,7 +137,7 @@ public: std::set<QString> buildSystemFiles() const; RuleCommandList ruleCommands(const ProductData &product, const QString &inputFilePath, - const QString &outputFileTag, ErrorInfo *error = 0) const; + const QString &outputFileTag, ErrorInfo *error = nullptr) const; ProjectTransformerData transformerData(ErrorInfo *error = nullptr) const; ErrorInfo dumpNodesTree(QIODevice &outDevice, const QList<ProductData> &products); diff --git a/src/lib/corelib/api/projectfileupdater.cpp b/src/lib/corelib/api/projectfileupdater.cpp index b11c43673..25c2705d1 100644 --- a/src/lib/corelib/api/projectfileupdater.cpp +++ b/src/lib/corelib/api/projectfileupdater.cpp @@ -71,7 +71,7 @@ public: UiObjectDefinition *item() const { return m_item; } private: - bool visit(UiObjectDefinition *ast) + bool visit(UiObjectDefinition *ast) override { if (toCodeLocation(m_cl.filePath(), ast->firstSourceLocation()) == m_cl) { m_item = ast; @@ -95,14 +95,14 @@ public: UiScriptBinding *binding() const { return m_binding; } private: - bool visit(UiObjectDefinition *ast) + bool visit(UiObjectDefinition *ast) override { // We start with the direct parent of the binding, so do not descend into any // other item. return ast == m_startItem; } - bool visit(UiScriptBinding *ast) + bool visit(UiScriptBinding *ast) override { if (ast->qualifiedId->name.toString() != StringConstants::filesProperty()) return true; diff --git a/src/lib/corelib/api/projectfileupdater.h b/src/lib/corelib/api/projectfileupdater.h index 7615b45f9..bc8de30eb 100644 --- a/src/lib/corelib/api/projectfileupdater.h +++ b/src/lib/corelib/api/projectfileupdater.h @@ -94,7 +94,7 @@ public: ProjectFileGroupInserter(const ProductData &product, const QString &groupName); private: - void doApply(QString &fileContent, QbsQmlJS::AST::UiProgram *ast); + void doApply(QString &fileContent, QbsQmlJS::AST::UiProgram *ast) override; const ProductData m_product; const QString m_groupName; @@ -108,7 +108,7 @@ public: const QStringList &files); private: - void doApply(QString &fileContent, QbsQmlJS::AST::UiProgram *ast); + void doApply(QString &fileContent, QbsQmlJS::AST::UiProgram *ast) override; const ProductData m_product; const GroupData m_group; @@ -122,7 +122,7 @@ public: const QStringList &files); private: - void doApply(QString &fileContent, QbsQmlJS::AST::UiProgram *ast); + void doApply(QString &fileContent, QbsQmlJS::AST::UiProgram *ast) override; const ProductData m_product; const GroupData m_group; @@ -135,7 +135,7 @@ public: ProjectFileGroupRemover(const ProductData &product, const GroupData &group); private: - void doApply(QString &fileContent, QbsQmlJS::AST::UiProgram *ast); + void doApply(QString &fileContent, QbsQmlJS::AST::UiProgram *ast) override; const ProductData m_product; const GroupData m_group; diff --git a/src/lib/corelib/api/qmljsrewriter.cpp b/src/lib/corelib/api/qmljsrewriter.cpp index ebcc00b07..60c384004 100644 --- a/src/lib/corelib/api/qmljsrewriter.cpp +++ b/src/lib/corelib/api/qmljsrewriter.cpp @@ -177,11 +177,11 @@ UiObjectMemberList *Rewriter::searchMemberToInsertAfter(UiObjectMemberList *memb if (cast<UiObjectDefinition*>(member)) lastObjectDef = iter; - else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) + else if (auto arrayBinding = cast<UiArrayBinding*>(member)) idx = propertyOrder.indexOf(toString(arrayBinding->qualifiedId)); - else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) + else if (auto objectBinding = cast<UiObjectBinding*>(member)) idx = propertyOrder.indexOf(toString(objectBinding->qualifiedId)); - else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) + else if (auto scriptBinding = cast<UiScriptBinding*>(member)) idx = propertyOrder.indexOf(toString(scriptBinding->qualifiedId)); else if (cast<UiPublicMember*>(member)) idx = propertyOrder.indexOf(QLatin1String("property")); @@ -210,11 +210,11 @@ UiArrayMemberList *Rewriter::searchMemberToInsertAfter(UiArrayMemberList *member if (cast<UiObjectDefinition*>(member)) lastObjectDef = iter; - else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) + else if (auto arrayBinding = cast<UiArrayBinding*>(member)) idx = propertyOrder.indexOf(toString(arrayBinding->qualifiedId)); - else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) + else if (auto objectBinding = cast<UiObjectBinding*>(member)) idx = propertyOrder.indexOf(toString(objectBinding->qualifiedId)); - else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) + else if (auto scriptBinding = cast<UiScriptBinding*>(member)) idx = propertyOrder.indexOf(toString(scriptBinding->qualifiedId)); else if (cast<UiPublicMember*>(member)) idx = propertyOrder.indexOf(QLatin1String("property")); @@ -241,13 +241,13 @@ UiObjectMemberList *Rewriter::searchMemberToInsertAfter(UiObjectMemberList *memb for (UiObjectMemberList *iter = members; iter; iter = iter->next) { UiObjectMember *member = iter->member; - if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) + if (auto arrayBinding = cast<UiArrayBinding*>(member)) orderedMembers[toString(arrayBinding->qualifiedId)] = iter; - else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) + else if (auto objectBinding = cast<UiObjectBinding*>(member)) orderedMembers[toString(objectBinding->qualifiedId)] = iter; else if (cast<UiObjectDefinition*>(member)) orderedMembers[QString::null] = iter; - else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) + else if (auto scriptBinding = cast<UiScriptBinding*>(member)) orderedMembers[toString(scriptBinding->qualifiedId)] = iter; else if (cast<UiPublicMember*>(member)) orderedMembers[QLatin1String("property")] = iter; @@ -262,7 +262,7 @@ UiObjectMemberList *Rewriter::searchMemberToInsertAfter(UiObjectMemberList *memb for (; idx > 0; --idx) { const QString prop = propertyOrder.at(idx - 1); UiObjectMemberList *candidate = orderedMembers.value(prop, 0); - if (candidate != 0) + if (candidate != nullptr) return candidate; } @@ -306,7 +306,7 @@ void Rewriter::changeBinding(UiObjectInitializer *ast, break; // for grouped properties: } else if (!prefix.isEmpty()) { - if (UiObjectDefinition *def = cast<UiObjectDefinition *>(member)) { + if (auto def = cast<UiObjectDefinition *>(member)) { if (toString(def->qualifiedTypeNameId) == prefix) changeBinding(def->initializer, suffix, newValue, binding); } @@ -321,16 +321,16 @@ void Rewriter::replaceMemberValue(UiObjectMember *propertyMember, QString replacement = newValue; int startOffset = -1; int endOffset = -1; - if (UiObjectBinding *objectBinding = AST::cast<UiObjectBinding *>(propertyMember)) { + if (auto objectBinding = AST::cast<UiObjectBinding *>(propertyMember)) { startOffset = objectBinding->qualifiedTypeNameId->identifierToken.offset; endOffset = objectBinding->initializer->rbraceToken.end(); - } else if (UiScriptBinding *scriptBinding = AST::cast<UiScriptBinding *>(propertyMember)) { + } else if (auto scriptBinding = AST::cast<UiScriptBinding *>(propertyMember)) { startOffset = scriptBinding->statement->firstSourceLocation().offset; endOffset = scriptBinding->statement->lastSourceLocation().end(); - } else if (UiArrayBinding *arrayBinding = AST::cast<UiArrayBinding *>(propertyMember)) { + } else if (auto arrayBinding = AST::cast<UiArrayBinding *>(propertyMember)) { startOffset = arrayBinding->lbracketToken.offset; endOffset = arrayBinding->rbracketToken.end(); - } else if (UiPublicMember *publicMember = AST::cast<UiPublicMember*>(propertyMember)) { + } else if (auto publicMember = AST::cast<UiPublicMember*>(propertyMember)) { if (publicMember->statement) { startOffset = publicMember->statement->firstSourceLocation().offset; if (publicMember->semicolonToken.isValid()) @@ -357,13 +357,13 @@ void Rewriter::replaceMemberValue(UiObjectMember *propertyMember, bool Rewriter::isMatchingPropertyMember(const QString &propertyName, UiObjectMember *member) { - if (UiPublicMember *publicMember = cast<UiPublicMember*>(member)) + if (auto publicMember = cast<UiPublicMember*>(member)) return publicMember->name == propertyName; - else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) + else if (auto objectBinding = cast<UiObjectBinding*>(member)) return toString(objectBinding->qualifiedId) == propertyName; - else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) + else if (auto scriptBinding = cast<UiScriptBinding*>(member)) return toString(scriptBinding->qualifiedId) == propertyName; - else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) + else if (auto arrayBinding = cast<UiArrayBinding*>(member)) return toString(arrayBinding->qualifiedId) == propertyName; else return false; @@ -409,7 +409,7 @@ void Rewriter::removeBindingByName(UiObjectInitializer *ast, const QString &prop removeMember(member); // check for grouped properties: } else if (!prefix.isEmpty()) { - if (UiObjectDefinition *def = cast<UiObjectDefinition *>(member)) { + if (auto def = cast<UiObjectDefinition *>(member)) { if (toString(def->qualifiedTypeNameId) == prefix) removeGroupedProperty(def, propertyName); } @@ -680,10 +680,10 @@ void Rewriter::removeObjectMember(UiObjectMember *member, UiObjectMember *parent int start = member->firstSourceLocation().offset; int end = member->lastSourceLocation().end(); - if (UiArrayBinding *parentArray = cast<UiArrayBinding *>(parent)) { + if (auto parentArray = cast<UiArrayBinding *>(parent)) { extendToLeadingOrTrailingComma(parentArray, member, start, end); } else { - if (UiObjectDefinition *parentObjectDefinition = cast<UiObjectDefinition *>(parent)) + if (auto parentObjectDefinition = cast<UiObjectDefinition *>(parent)) includeEmptyGroupedProperty(parentObjectDefinition, member, start, end); includeSurroundingWhitespace(m_originalText, start, end); } diff --git a/src/lib/corelib/buildgraph/artifact.cpp b/src/lib/corelib/buildgraph/artifact.cpp index 667194356..e82919560 100644 --- a/src/lib/corelib/buildgraph/artifact.cpp +++ b/src/lib/corelib/buildgraph/artifact.cpp @@ -42,6 +42,7 @@ #include "transformer.h" #include "buildgraphvisitor.h" #include "productbuilddata.h" +#include "rulenode.h" #include <language/language.h> #include <language/propertymapinternal.h> #include <tools/persistence.h> @@ -77,15 +78,21 @@ QString Artifact::toString() const void Artifact::addFileTag(const FileTag &t) { m_fileTags += t; - if (!product.expired() && product->buildData) + if (!product.expired() && product->buildData) { product->buildData->addFileTagToArtifact(this, t); + if (product->fileTags.contains(t)) + product->buildData->addRootNode(this); + } } void Artifact::removeFileTag(const FileTag &t) { m_fileTags -= t; - if (!product.expired() && product->buildData) + if (!product.expired() && product->buildData) { product->buildData->removeArtifactFromSetByFileTag(this, t); + if (product->fileTags.contains(t) && !product->fileTags.intersects(m_fileTags)) + product->buildData->removeFromRootNodes(this); + } } void Artifact::setFileTags(const FileTags &newFileTags) @@ -94,10 +101,23 @@ void Artifact::setFileTags(const FileTags &newFileTags) m_fileTags = newFileTags; return; } - for (const FileTag &t : qAsConst(m_fileTags)) - product->buildData->removeArtifactFromSetByFileTag(this, t); - m_fileTags = newFileTags; - product->buildData->addArtifactToSet(this); + if (m_fileTags == newFileTags) + return; + const Set<FileTag> addedTags = newFileTags - m_fileTags; + for (const FileTag &t : addedTags) + addFileTag(t); + const Set<FileTag> removedTags = m_fileTags - newFileTags; + for (const FileTag &t : removedTags) + removeFileTag(t); +} + +RuleNode *Artifact::producer() const +{ + if (artifactType == SourceFile) + return nullptr; + const auto ruleNodes = filterByType<RuleNode>(children); + QBS_CHECK(ruleNodes.begin() != ruleNodes.end()); + return *ruleNodes.begin(); } void Artifact::initialize() @@ -133,7 +153,7 @@ void Artifact::load(PersistentPool &pool) children.load(pool); // restore parents of the loaded children - for (NodeSet::const_iterator it = children.constBegin(); it != children.constEnd(); ++it) + for (auto it = children.constBegin(); it != children.constEnd(); ++it) (*it)->parents.insert(this); pool.load(childrenAddedByScanner); @@ -142,10 +162,11 @@ void Artifact::load(PersistentPool &pool) pool.load(targetOfModule); pool.load(transformer); pool.load(m_fileTags); + pool.load(pureFileTags); + pool.load(pureProperties); artifactType = static_cast<ArtifactType>(pool.load<quint8>()); alwaysUpdated = pool.load<bool>(); oldDataPossiblyPresent = pool.load<bool>(); - pool.load(knownOutOfDate); } void Artifact::store(PersistentPool &pool) @@ -160,10 +181,11 @@ void Artifact::store(PersistentPool &pool) pool.store(targetOfModule); pool.store(transformer); pool.store(m_fileTags); + pool.store(pureFileTags); + pool.store(pureProperties); pool.store(static_cast<quint8>(artifactType)); pool.store(alwaysUpdated); pool.store(oldDataPossiblyPresent); - pool.store(knownOutOfDate); } } // namespace Internal diff --git a/src/lib/corelib/buildgraph/artifact.h b/src/lib/corelib/buildgraph/artifact.h index b1669974c..4d2a20086 100644 --- a/src/lib/corelib/buildgraph/artifact.h +++ b/src/lib/corelib/buildgraph/artifact.h @@ -50,6 +50,9 @@ #include <QtCore/qstring.h> +#include <utility> +#include <vector> + namespace qbs { namespace Internal { class Logger; @@ -81,12 +84,23 @@ public: void setFileTags(const FileTags &newFileTags); const FileTags &fileTags() const { return m_fileTags; } + RuleNode *producer() const; + ArtifactSet childrenAddedByScanner; Set<FileDependency *> fileDependencies; TransformerPtr transformer; PropertyMapPtr properties; QString targetOfModule; + // The tags set directly via an Artifact item or an outputArtifacts script, + // not the result of file taggers or fileTagsFilter groups, nor the ones inherited from + // the product. + FileTags pureFileTags; + + // The properties attached directly to an artifact in an Artifact item or outputArtifacts + // script. + std::vector<std::pair<QStringList, QVariant>> pureProperties; + enum ArtifactType { Unknown = 1, @@ -100,8 +114,6 @@ public: bool alwaysUpdated : 1; bool oldDataPossiblyPresent : 1; - bool knownOutOfDate = false; - void initialize(); const TypeFilter<Artifact> parentArtifacts() const; const TypeFilter<Artifact> childArtifacts() const; @@ -118,7 +130,7 @@ private: template<> inline QString Set<Artifact *>::toString(Artifact * const &artifact) const { - return artifact->filePath(); + return artifact ? artifact->filePath() : QLatin1String("<null>"); } template<> inline const void *uniqueAddress(const Artifact *a) { diff --git a/src/lib/corelib/buildgraph/artifactcleaner.h b/src/lib/corelib/buildgraph/artifactcleaner.h index 34be4e0f4..4d8c86ea8 100644 --- a/src/lib/corelib/buildgraph/artifactcleaner.h +++ b/src/lib/corelib/buildgraph/artifactcleaner.h @@ -59,7 +59,7 @@ public: private: void removeEmptyDirectories(const QString &rootDir, const CleanOptions &options, - bool *isEmpty = 0); + bool *isEmpty = nullptr); Logger m_logger; bool m_hasError; diff --git a/src/lib/corelib/buildgraph/artifactvisitor.h b/src/lib/corelib/buildgraph/artifactvisitor.h index 6304d5f43..89bd4429a 100644 --- a/src/lib/corelib/buildgraph/artifactvisitor.h +++ b/src/lib/corelib/buildgraph/artifactvisitor.h @@ -56,8 +56,8 @@ public: void visitProduct(const ResolvedProductConstPtr &product); void visitProject(const ResolvedProjectConstPtr &project); - bool visit(RuleNode *ruleNode); - bool visit(Artifact *artifact); + bool visit(RuleNode *ruleNode) override; + bool visit(Artifact *artifact) override; private: virtual void doVisit(Artifact *artifact) = 0; diff --git a/src/lib/corelib/buildgraph/buildgraph.cpp b/src/lib/corelib/buildgraph/buildgraph.cpp index ed48b427d..e6d49f3d5 100644 --- a/src/lib/corelib/buildgraph/buildgraph.cpp +++ b/src/lib/corelib/buildgraph/buildgraph.cpp @@ -50,6 +50,7 @@ #include <jsextensions/jsextensions.h> #include <jsextensions/moduleproperties.h> +#include <language/artifactproperties.h> #include <language/language.h> #include <language/preparescriptobserver.h> #include <language/propertymapinternal.h> @@ -71,6 +72,7 @@ #include <QtScript/qscriptclass.h> #include <algorithm> +#include <iterator> #include <vector> namespace qbs { @@ -464,7 +466,7 @@ void connect(BuildGraphNode *p, BuildGraphNode *c) QBS_CHECK(p != c); qCDebug(lcBuildGraph).noquote() << "connect" << p->toString() << "->" << c->toString(); if (c->type() == BuildGraphNode::ArtifactNodeType) { - Artifact * const ac = static_cast<Artifact *>(c); + auto const ac = static_cast<Artifact *>(c); for (const Artifact *child : filterByType<Artifact>(p->children)) { if (child == ac) return; @@ -576,7 +578,7 @@ Artifact *lookupArtifact(const ResolvedProductConstPtr &product, it != lookupResults.constEnd(); ++it) { if ((*it)->fileType() != FileResourceBase::FileTypeArtifact) continue; - Artifact *artifact = static_cast<Artifact *>(*it); + auto artifact = static_cast<Artifact *>(*it); if (compareByName ? artifact->product->uniqueName() == product->uniqueName() : artifact->product == product) { @@ -620,12 +622,31 @@ Artifact *createArtifact(const ResolvedProductPtr &product, { auto artifact = new Artifact; artifact->artifactType = Artifact::SourceFile; + setArtifactData(artifact, sourceArtifact); + insertArtifact(product, artifact); + return artifact; +} + +void setArtifactData(Artifact *artifact, const SourceArtifactConstPtr &sourceArtifact) +{ artifact->targetOfModule = sourceArtifact->targetOfModule; artifact->setFilePath(sourceArtifact->absoluteFilePath); artifact->setFileTags(sourceArtifact->fileTags); artifact->properties = sourceArtifact->properties; - insertArtifact(product, artifact); - return artifact; +} + +void updateArtifactFromSourceArtifact(const ResolvedProductPtr &product, + const SourceArtifactConstPtr &sourceArtifact) +{ + Artifact * const artifact = lookupArtifact(product, sourceArtifact->absoluteFilePath, false); + QBS_CHECK(artifact); + const FileTags oldFileTags = artifact->fileTags(); + const QVariantMap oldModuleProperties = artifact->properties->value(); + setArtifactData(artifact, sourceArtifact); + if (oldFileTags != artifact->fileTags() + || oldModuleProperties != artifact->properties->value()) { + invalidateArtifactAsRuleInputIfNecessary(artifact); + } } void insertArtifact(const ResolvedProductPtr &product, Artifact *artifact) @@ -638,6 +659,76 @@ void insertArtifact(const ResolvedProductPtr &product, Artifact *artifact) product->buildData->addArtifact(artifact); } +void provideFullFileTagsAndProperties(Artifact *artifact) +{ + artifact->properties = artifact->product->moduleProperties; + FileTags allTags = artifact->pureFileTags.empty() + ? artifact->product->fileTagsForFileName(artifact->fileName()) : artifact->pureFileTags; + for (const ArtifactPropertiesConstPtr &props : artifact->product->artifactProperties) { + if (allTags.intersects(props->fileTagsFilter())) { + artifact->properties = props->propertyMap(); + allTags += props->extraFileTags(); + break; + } + } + artifact->setFileTags(allTags); + + // Let a positive value of qbs.install imply the file tag "installable". + if (artifact->properties->qbsPropertyValue(StringConstants::installProperty()).toBool()) + artifact->addFileTag("installable"); +} + +void applyPerArtifactProperties(Artifact *artifact) +{ + if (artifact->pureProperties.empty()) + return; + QVariantMap props = artifact->properties->value(); + for (const auto &property : artifact->pureProperties) + setConfigProperty(props, property.first, property.second); + artifact->properties = artifact->properties->clone(); + artifact->properties->setValue(props); +} + +void updateGeneratedArtifacts(ResolvedProduct *product) +{ + if (!product->buildData) + return; + for (Artifact * const artifact : filterByType<Artifact>(product->buildData->allNodes())) { + if (artifact->artifactType == Artifact::Generated) { + const FileTags oldFileTags = artifact->fileTags(); + const QVariantMap oldModuleProperties = artifact->properties->value(); + provideFullFileTagsAndProperties(artifact); + applyPerArtifactProperties(artifact); + if (oldFileTags != artifact->fileTags() + || oldModuleProperties != artifact->properties->value()) { + invalidateArtifactAsRuleInputIfNecessary(artifact); + } + } + } +} + +// This is needed for artifacts which are inputs to rules whose outputArtifacts script +// returned an empty array for this input. Since there is no transformer, our usual change +// tracking procedure will not notice if the artifact's file tags or module properties have +// changed, so we need to force a re-run of the outputArtifacts script. +void invalidateArtifactAsRuleInputIfNecessary(Artifact *artifact) +{ + for (RuleNode * const parentRuleNode : filterByType<RuleNode>(artifact->parents)) { + if (!parentRuleNode->rule()->isDynamic()) + continue; + bool artifactNeedsExplicitInvalidation = true; + for (Artifact * const output : filterByType<Artifact>(parentRuleNode->parents)) { + if (output->children.contains(artifact) + && !output->childrenAddedByScanner.contains(artifact)) { + artifactNeedsExplicitInvalidation = false; + break; + } + } + if (artifactNeedsExplicitInvalidation) + parentRuleNode->removeOldInputArtifact(artifact); + } +} + static void doSanityChecksForProduct(const ResolvedProductConstPtr &product, const Set<ResolvedProductPtr> &allProducts, const Logger &logger) { @@ -674,7 +765,7 @@ static void doSanityChecksForProduct(const ResolvedProductConstPtr &product, ? static_cast<Artifact *>(node) : nullptr; if (!artifact) { QBS_CHECK(node->type() == BuildGraphNode::RuleNodeType); - RuleNode * const ruleNode = static_cast<RuleNode *>(node); + auto const ruleNode = static_cast<RuleNode *>(node); QBS_CHECK(ruleNode->rule()); QBS_CHECK(ruleNode->rule()->product); QBS_CHECK(ruleNode->rule()->product == ruleNode->product.get()); @@ -695,6 +786,9 @@ static void doSanityChecksForProduct(const ResolvedProductConstPtr &product, if (artifact->artifactType == Artifact::SourceFile) continue; + const auto parentRuleNodes = filterByType<RuleNode>(artifact->children); + QBS_CHECK(std::distance(parentRuleNodes.begin(), parentRuleNodes.end()) == 1); + QBS_CHECK(transformer); QBS_CHECK(transformer->rule); QBS_CHECK(transformer->rule->product); diff --git a/src/lib/corelib/buildgraph/buildgraph.h b/src/lib/corelib/buildgraph/buildgraph.h index 50195903d..2909b06bb 100644 --- a/src/lib/corelib/buildgraph/buildgraph.h +++ b/src/lib/corelib/buildgraph/buildgraph.h @@ -69,9 +69,15 @@ Artifact *lookupArtifact(const ResolvedProductConstPtr &product, const Artifact Artifact *createArtifact(const ResolvedProductPtr &product, const SourceArtifactConstPtr &sourceArtifact); +void setArtifactData(Artifact *artifact, const SourceArtifactConstPtr &sourceArtifact); +void updateArtifactFromSourceArtifact(const ResolvedProductPtr &product, + const SourceArtifactConstPtr &sourceArtifact); void insertArtifact(const ResolvedProductPtr &product, Artifact *artifact); void dumpProductBuildData(const ResolvedProductConstPtr &product); - +void provideFullFileTagsAndProperties(Artifact *artifact); +void applyPerArtifactProperties(Artifact *artifact); +void updateGeneratedArtifacts(ResolvedProduct *product); +void invalidateArtifactAsRuleInputIfNecessary(Artifact *artifact); bool findPath(BuildGraphNode *u, BuildGraphNode *v, QList<BuildGraphNode*> &path); void QBS_AUTOTEST_EXPORT connect(BuildGraphNode *p, BuildGraphNode *c); diff --git a/src/lib/corelib/buildgraph/buildgraphloader.cpp b/src/lib/corelib/buildgraph/buildgraphloader.cpp index f9b9910e6..a1ca7afdb 100644 --- a/src/lib/corelib/buildgraph/buildgraphloader.cpp +++ b/src/lib/corelib/buildgraph/buildgraphloader.cpp @@ -380,7 +380,10 @@ void BuildGraphLoader::trackProjectChanges() // an a per-artifact basis by the Executor on the next build. QHash<QString, AllRescuableArtifactData> rescuableArtifactData; for (const ResolvedProductPtr &product : qAsConst(changedProducts)) { - ResolvedProductPtr freshProduct = m_freshProductsByName.value(product->uniqueName()); + const QString name = product->uniqueName(); + m_changedSourcesByProduct.erase(name); + m_productsWhoseArtifactsNeedUpdate.remove(name); + ResolvedProductPtr freshProduct = m_freshProductsByName.value(name); if (!freshProduct) continue; onProductRemoved(product, product->topLevelProject()->buildData.get(), false); @@ -433,6 +436,20 @@ void BuildGraphLoader::trackProjectChanges() allNewlyResolvedProducts); } + for (auto it = m_changedSourcesByProduct.cbegin(); it != m_changedSourcesByProduct.cend(); + ++it) { + const ResolvedProductPtr product = m_freshProductsByName.value(it->first); + QBS_CHECK(!!product); + for (const SourceArtifactConstPtr &sa : it->second) + updateArtifactFromSourceArtifact(product, sa); + } + + for (const QString &productName : m_productsWhoseArtifactsNeedUpdate) { + const ResolvedProductPtr product = m_freshProductsByName.value(productName); + QBS_CHECK(!!product); + updateGeneratedArtifacts(product.get()); + } + for (const ResolvedProductConstPtr &changedProduct : qAsConst(changedProducts)) { rescueOldBuildData(changedProduct, m_freshProductsByName.value(changedProduct->uniqueName()), @@ -663,8 +680,7 @@ void BuildGraphLoader::checkAllProductsForChanges( continue; } - if (!sourceArtifactSetsAreEqual(restoredProduct->allEnabledFiles(), - newlyResolvedProduct->allEnabledFiles())) { + if (checkProductForChangesInSourceFiles(restoredProduct, newlyResolvedProduct)) { qCDebug(lcBuildGraph) << "File list of product" << restoredProduct->uniqueName() << "was changed."; if (!contains(changedProducts, restoredProduct)) @@ -673,6 +689,38 @@ void BuildGraphLoader::checkAllProductsForChanges( } } +bool BuildGraphLoader::checkProductForChangesInSourceFiles( + const ResolvedProductPtr &restoredProduct, const ResolvedProductPtr &newlyResolvedProduct) +{ + std::vector<SourceArtifactPtr> oldFiles = restoredProduct->allEnabledFiles(); + std::vector<SourceArtifactPtr> newFiles = newlyResolvedProduct->allEnabledFiles(); + // TODO: Also handle added and removed files in a fine-grained manner. + if (oldFiles.size() != newFiles.size()) + return true; + static const auto cmp = [](const SourceArtifactConstPtr &a1, + const SourceArtifactConstPtr &a2) { + return a1->absoluteFilePath < a2->absoluteFilePath; + }; + std::sort(oldFiles.begin(), oldFiles.end(), cmp); + std::sort(newFiles.begin(), newFiles.end(), cmp); + std::vector<SourceArtifactConstPtr> changedFiles; + for (int i = 0; i < int(oldFiles.size()); ++i) { + const SourceArtifactConstPtr &oldFile = oldFiles.at(i); + const SourceArtifactConstPtr &newFile = newFiles.at(i); + if (oldFile->absoluteFilePath != newFile->absoluteFilePath) + return true; + if (*oldFile != *newFile) { + qCDebug(lcBuildGraph) << "source artifact" << oldFile->absoluteFilePath << "changed"; + changedFiles.push_back(newFile); + } + } + if (!changedFiles.empty()) { + m_changedSourcesByProduct.insert(std::make_pair(restoredProduct->uniqueName(), + changedFiles)); + } + return false; +} + static bool dependenciesAreEqual(const ResolvedProductConstPtr &p1, const ResolvedProductConstPtr &p2) { @@ -742,7 +790,14 @@ bool BuildGraphLoader::checkForPropertyChanges(const ResolvedProductPtr &restore return true; if (!artifactPropertyListsAreEqual(restoredProduct->artifactProperties, newlyResolvedProduct->artifactProperties)) { - return true; + qCDebug(lcBuildGraph) << "a fileTagFilter group changed for product" + << restoredProduct->uniqueName(); + m_productsWhoseArtifactsNeedUpdate << restoredProduct->uniqueName(); + } + if (restoredProduct->moduleProperties != newlyResolvedProduct->moduleProperties) { + qCDebug(lcBuildGraph) << "module properties changed for product" + << restoredProduct->uniqueName(); + m_productsWhoseArtifactsNeedUpdate << restoredProduct->uniqueName(); } return false; } @@ -857,7 +912,7 @@ void BuildGraphLoader::rescueOldBuildData(const ResolvedProductConstPtr &restore if (!newArtifact) { RescuableArtifactData rad; rad.timeStamp = oldArtifact->timestamp(); - rad.knownOutOfDate = oldArtifact->knownOutOfDate; + rad.knownOutOfDate = oldArtifact->transformer->markedForRerun; rad.fileTags = oldArtifact->fileTags(); rad.properties = oldArtifact->properties; rad.commands = oldArtifact->transformer->commands; diff --git a/src/lib/corelib/buildgraph/buildgraphloader.h b/src/lib/corelib/buildgraph/buildgraphloader.h index e83a4a088..30d7b9b45 100644 --- a/src/lib/corelib/buildgraph/buildgraphloader.h +++ b/src/lib/corelib/buildgraph/buildgraphloader.h @@ -51,6 +51,8 @@ #include <QtCore/qprocess.h> #include <QtCore/qvariant.h> +#include <unordered_map> + namespace qbs { namespace Internal { @@ -101,6 +103,8 @@ private: std::vector<ResolvedProductPtr> &changedProducts); bool checkProductForChanges(const ResolvedProductPtr &restoredProduct, const ResolvedProductPtr &newlyResolvedProduct); + bool checkProductForChangesInSourceFiles(const ResolvedProductPtr &restoredProduct, + const ResolvedProductPtr &newlyResolvedProduct); bool checkProductForInstallInfoChanges(const ResolvedProductPtr &restoredProduct, const ResolvedProductPtr &newlyResolvedProduct); bool checkForPropertyChanges(const ResolvedProductPtr &restoredProduct, @@ -135,6 +139,8 @@ private: BuildGraphLoadResult m_result; Logger m_logger; QStringList m_artifactsRemovedFromDisk; + std::unordered_map<QString, std::vector<SourceArtifactConstPtr>> m_changedSourcesByProduct; + Set<QString> m_productsWhoseArtifactsNeedUpdate; qint64 m_wildcardExpansionEffort; qint64 m_propertyComparisonEffort; diff --git a/src/lib/corelib/buildgraph/cycledetector.h b/src/lib/corelib/buildgraph/cycledetector.h index d280f6ecd..fffe6ed2f 100644 --- a/src/lib/corelib/buildgraph/cycledetector.h +++ b/src/lib/corelib/buildgraph/cycledetector.h @@ -58,8 +58,8 @@ public: void visitProduct(const ResolvedProductConstPtr &product); private: - bool visit(Artifact *artifact); - bool visit(RuleNode *ruleNode); + bool visit(Artifact *artifact) override; + bool visit(RuleNode *ruleNode) override; bool visitNode(BuildGraphNode *node); diff --git a/src/lib/corelib/buildgraph/depscanner.h b/src/lib/corelib/buildgraph/depscanner.h index fef71058f..5c8ef83d9 100644 --- a/src/lib/corelib/buildgraph/depscanner.h +++ b/src/lib/corelib/buildgraph/depscanner.h @@ -84,13 +84,13 @@ public: PluginDependencyScanner(ScannerPlugin *plugin); private: - QStringList collectSearchPaths(Artifact *artifact); - QStringList collectDependencies(FileResourceBase *file, const char *fileTags); - bool recursive() const; - const void *key() const; - QString createId() const; + QStringList collectSearchPaths(Artifact *artifact) override; + QStringList collectDependencies(FileResourceBase *file, const char *fileTags) override; + bool recursive() const override; + const void *key() const override; + QString createId() const override; bool areModulePropertiesCompatible(const PropertyMapConstPtr &m1, - const PropertyMapConstPtr &m2) const; + const PropertyMapConstPtr &m2) const override; ScannerPlugin* m_plugin; }; @@ -101,13 +101,13 @@ public: UserDependencyScanner(const ResolvedScannerConstPtr &scanner, ScriptEngine *engine); private: - QStringList collectSearchPaths(Artifact *artifact); - QStringList collectDependencies(FileResourceBase *file, const char *fileTags); - bool recursive() const; - const void *key() const; - QString createId() const; + QStringList collectSearchPaths(Artifact *artifact) override; + QStringList collectDependencies(FileResourceBase *file, const char *fileTags) override; + bool recursive() const override; + const void *key() const override; + QString createId() const override; bool areModulePropertiesCompatible(const PropertyMapConstPtr &m1, - const PropertyMapConstPtr &m2) const; + const PropertyMapConstPtr &m2) const override; QStringList evaluate(Artifact *artifact, const PrivateScriptFunction &script); diff --git a/src/lib/corelib/buildgraph/executor.cpp b/src/lib/corelib/buildgraph/executor.cpp index 42e3eee8c..0558980d6 100644 --- a/src/lib/corelib/buildgraph/executor.cpp +++ b/src/lib/corelib/buildgraph/executor.cpp @@ -61,10 +61,12 @@ #include <logging/translator.h> #include <tools/error.h> #include <tools/fileinfo.h> +#include <tools/preferences.h> #include <tools/profiling.h> #include <tools/progressobserver.h> #include <tools/qbsassert.h> #include <tools/qttools.h> +#include <tools/settings.h> #include <tools/stringconstants.h> #include <QtCore/qdir.h> @@ -223,7 +225,6 @@ void Executor::doBuild() } QBS_CHECK(m_state == ExecutorIdle); m_leaves = Leaves(); - m_changedSourceArtifacts.clear(); m_error.clear(); m_explicitlyCanceled = false; m_activeFileTags = FileTags::fromStringList(m_buildOptions.activeFileTags()); @@ -231,6 +232,9 @@ void Executor::doBuild() m_tagsNeededForFilesToConsider.clear(); m_productsOfFilesToConsider.clear(); m_artifactsRemovedFromDisk.clear(); + m_jobCountPerPool.clear(); + + setupJobLimits(); // TODO: The "filesToConsider" thing is badly designed; we should know exactly which artifact // it is. Remove this from the BuildOptions class and introduce Project::buildSomeFiles() @@ -243,7 +247,7 @@ void Executor::doBuild() for (const FileResourceBase * const file : files) { if (file->fileType() != FileResourceBase::FileTypeArtifact) continue; - const Artifact * const artifact = static_cast<const Artifact *>(file); + auto const artifact = static_cast<const Artifact *>(file); if (contains(m_productsToBuild, artifact->product.lock())) { m_tagsOfFilesToConsider.unite(artifact->fileTags()); m_productsOfFilesToConsider << artifact->product.lock(); @@ -323,7 +327,7 @@ void Executor::updateLeaves(BuildGraphNode *node, NodeSet &seenNodes) if (node->buildState == BuildGraphNode::Untouched) { node->buildState = BuildGraphNode::Buildable; if (node->type() == BuildGraphNode::ArtifactNodeType) { - Artifact * const artifact = static_cast<Artifact *>(node); + auto const artifact = static_cast<Artifact *>(node); if (artifact->artifactType == Artifact::SourceFile) retrieveSourceFileTimestamp(artifact); } @@ -347,6 +351,7 @@ void Executor::updateLeaves(BuildGraphNode *node, NodeSet &seenNodes) bool Executor::scheduleJobs() { QBS_CHECK(m_state == ExecutorRunning); + std::vector<BuildGraphNode *> delayedLeaves; while (!m_leaves.empty() && !m_availableJobs.empty()) { BuildGraphNode * const nodeToBuild = m_leaves.top(); m_leaves.pop(); @@ -356,9 +361,17 @@ bool Executor::scheduleJobs() QBS_ASSERT(!"untouched node in leaves list", qDebug("%s", qPrintable(nodeToBuild->toString()))); break; - case BuildGraphNode::Buildable: - // This is the only state in which we want to build a node. - nodeToBuild->accept(this); + case BuildGraphNode::Buildable: // This is the only state in which we want to build a node. + // TODO: It's a bit annoying that we have to check this here already, when we + // don't know whether the transformer needs to run at all. Investigate + // moving the whole job allocation logic to runTransformer(). + if (schedulingBlockedByJobLimit(nodeToBuild)) { + qCDebug(lcExec).noquote() << "node delayed due to occupied job pool:" + << nodeToBuild->toString(); + delayedLeaves.push_back(nodeToBuild); + } else { + nodeToBuild->accept(this); + } break; case BuildGraphNode::Building: qCDebug(lcExec).noquote() << nodeToBuild->toString(); @@ -370,9 +383,50 @@ bool Executor::scheduleJobs() break; } } + for (BuildGraphNode * const delayedLeaf : delayedLeaves) + m_leaves.push(delayedLeaf); return !m_leaves.empty() || !m_processingJobs.empty(); } +bool Executor::schedulingBlockedByJobLimit(const BuildGraphNode *node) +{ + if (node->type() != BuildGraphNode::ArtifactNodeType) + return false; + const Artifact * const artifact = static_cast<const Artifact *>(node); + if (artifact->artifactType == Artifact::SourceFile) + return false; + + const Transformer * const transformer = artifact->transformer.get(); + for (const QString &jobPool : transformer->jobPools()) { + const int currentJobCount = m_jobCountPerPool[jobPool]; + if (currentJobCount == 0) + continue; + const auto jobLimitIsExceeded = [currentJobCount, jobPool, this](const Transformer *t) { + const int maxJobCount = m_jobLimitsPerProduct.at(t->product().get()) + .getLimit(jobPool); + return maxJobCount > 0 && currentJobCount >= maxJobCount; + }; + + // Different products can set different limits. The effective limit is the minimum of what + // is set in this transformer's product and in the products of all currently + // running transformers. + if (jobLimitIsExceeded(transformer)) + return true; + for (const ExecutorJob * const runningJob : m_processingJobs.keys()) { + if (!runningJob->jobPools().contains(jobPool)) + continue; + const Transformer * const runningTransformer = runningJob->transformer(); + if (!runningTransformer) + continue; // This can happen if the ExecutorJob has already finished. + if (runningTransformer->product() == transformer->product()) + continue; // We have already checked this product's job limit. + if (jobLimitIsExceeded(runningTransformer)) + return true; + } + } + return false; +} + bool Executor::isUpToDate(Artifact *artifact) const { QBS_CHECK(artifact->artifactType == Artifact::Generated); @@ -391,11 +445,6 @@ bool Executor::isUpToDate(Artifact *artifact) const return false; } - if (artifact->knownOutOfDate) { - qCDebug(lcUpToDateCheck) << "Explicitly marked as out of date."; - return false; - } - for (Artifact *childArtifact : filterByType<Artifact>(artifact->children)) { QBS_CHECK(!childArtifact->alwaysUpdated || childArtifact->timestamp().isValid()); qCDebug(lcUpToDateCheck) << "child timestamp" @@ -407,13 +456,9 @@ bool Executor::isUpToDate(Artifact *artifact) const for (FileDependency *fileDependency : qAsConst(artifact->fileDependencies)) { if (!fileDependency->timestamp().isValid()) { - FileInfo fi(fileDependency->filePath()); - fileDependency->setTimestamp(fi.lastModified()); - if (!fileDependency->timestamp().isValid()) { - qCDebug(lcUpToDateCheck) << "file dependency doesn't exist" - << fileDependency->filePath(); - return false; - } + qCDebug(lcUpToDateCheck) << "file dependency doesn't exist" + << fileDependency->filePath(); + return false; } qCDebug(lcUpToDateCheck) << "file dependency timestamp" << fileDependency->timestamp().toString() @@ -429,6 +474,10 @@ bool Executor::mustExecuteTransformer(const TransformerPtr &transformer) const { if (transformer->alwaysRun) return true; + if (transformer->markedForRerun) { + qCDebug(lcUpToDateCheck) << "explicitly marked for re-run."; + return true; + } bool hasAlwaysUpdatedArtifacts = false; bool hasUpToDateNotAlwaysUpdatedArtifacts = false; @@ -488,70 +537,24 @@ void Executor::executeRuleNode(RuleNode *ruleNode) return; QBS_CHECK(!m_evalContext->engine()->isActive()); - ArtifactSet changedInputArtifacts; - if (ruleNode->rule()->isDynamic()) { - for (Artifact * const artifact : qAsConst(m_changedSourceArtifacts)) { - if (artifact->product != ruleNode->product) - continue; - if (artifact->isTargetOfModule()) - continue; - if (ruleNode->rule()->acceptsAsInput(artifact)) - changedInputArtifacts += artifact; - } - for (Artifact *artifact : filterByType<Artifact>(ruleNode->product->buildData->allNodes())) { - if (artifact->artifactType == Artifact::SourceFile) - continue; - if (ruleNode->rule()->acceptsAsInput(artifact)) { - for (const Artifact * const parent : artifact->parentArtifacts()) { - if (parent->transformer->rule != ruleNode->rule()) - continue; - if (!parent->alwaysUpdated) - continue; - if (parent->timestamp() < artifact->timestamp()) { - changedInputArtifacts += artifact; - break; - } - } - } - } - } RuleNode::ApplicationResult result; - ruleNode->apply(m_logger, changedInputArtifacts, m_productsByName, m_projectsByName, &result); + ruleNode->apply(m_logger, m_productsByName, m_projectsByName, &result); + updateLeaves(result.createdArtifacts); + updateLeaves(result.invalidatedArtifacts); + m_artifactsRemovedFromDisk << result.removedArtifacts; - if (result.upToDate) { - qCDebug(lcExec).noquote() << ruleNode->toString() << "is up to date. Skipping."; - } else { - qCDebug(lcExec).noquote() << ruleNode->toString(); - const WeakPointer<ResolvedProduct> &product = ruleNode->product; - Set<RuleNode *> parentRules; - if (!result.createdNodes.empty()) { - for (BuildGraphNode *parent : qAsConst(ruleNode->parents)) { - if (parent->type() == BuildGraphNode::RuleNodeType) - parentRules += static_cast<RuleNode *>(parent); - } - } - for (BuildGraphNode *node : qAsConst(result.createdNodes)) { - qCDebug(lcExec).noquote() << "rule created" << node->toString(); - Internal::connect(node, ruleNode); - if (node->type() != BuildGraphNode::ArtifactNodeType) - continue; - Artifact * const outputArtifact = static_cast<Artifact *>(node); - if (outputArtifact->fileTags().intersects(product->fileTags)) - product->buildData->addRootNode(outputArtifact); - - for (Artifact *inputArtifact : qAsConst(outputArtifact->transformer->inputs)) - Internal::connect(ruleNode, inputArtifact); - - for (RuleNode *parentRule : qAsConst(parentRules)) - Internal::connect(parentRule, outputArtifact); + if (m_progressObserver) { + const int transformerCount = ruleNode->transformerCount(); + if (transformerCount == 0) { + m_progressObserver->incrementProgressValue(); + } else { + m_pendingTransformersPerRule.insert(std::make_pair(ruleNode->rule().get(), + transformerCount)); } - updateLeaves(result.createdNodes); - updateLeaves(result.invalidatedNodes); } + finishNode(ruleNode); - if (m_progressObserver) - m_progressObserver->incrementProgressValue(); } void Executor::finishJob(ExecutorJob *job, bool success) @@ -564,14 +567,14 @@ void Executor::finishJob(ExecutorJob *job, bool success) const TransformerPtr transformer = it.value(); m_processingJobs.erase(it); m_availableJobs.push_back(job); + updateJobCounts(transformer.get(), -1); if (success) { m_project->buildData->setDirty(); for (Artifact * const artifact : qAsConst(transformer->outputs)) { if (artifact->alwaysUpdated) { artifact->setTimestamp(FileTime::currentTime()); - artifact->knownOutOfDate = false; for (Artifact * const parent : artifact->parentArtifacts()) - parent->knownOutOfDate = true; + parent->transformer->markedForRerun = true; if (m_buildOptions.forceOutputCheck() && !m_buildOptions.dryRun() && !FileInfo(artifact->filePath()).exists()) { if (transformer->rule) { @@ -692,6 +695,30 @@ bool Executor::transformerHasMatchingInputFiles(const TransformerConstPtr &trans return false; } +void Executor::setupJobLimits() +{ + Settings settings(m_buildOptions.settingsDirectory()); + for (const ResolvedProductConstPtr &p : m_productsToBuild) { + const Preferences prefs(&settings, p->profile()); + const JobLimits &jobLimitsFromSettings = prefs.jobLimits(); + JobLimits effectiveJobLimits; + if (m_buildOptions.projectJobLimitsTakePrecedence()) { + effectiveJobLimits.update(jobLimitsFromSettings).update(m_buildOptions.jobLimits()) + .update(p->jobLimits); + } else { + effectiveJobLimits.update(p->jobLimits).update(jobLimitsFromSettings) + .update(m_buildOptions.jobLimits()); + } + m_jobLimitsPerProduct.insert(std::make_pair(p.get(), effectiveJobLimits)); + } +} + +void Executor::updateJobCounts(const Transformer *transformer, int diff) +{ + for (const QString &jobPool : transformer->jobPools()) + m_jobCountPerPool[jobPool] += diff; +} + void Executor::cancelJobs() { if (m_state == ExecutorCanceling) @@ -754,7 +781,7 @@ void Executor::addExecutorJobs() } } -void Executor::rescueOldBuildData(Artifact *artifact, bool *childrenAdded = 0) +void Executor::rescueOldBuildData(Artifact *artifact, bool *childrenAdded = nullptr) { if (childrenAdded) *childrenAdded = false; @@ -823,9 +850,7 @@ void Executor::rescueOldBuildData(Artifact *artifact, bool *childrenAdded = 0) << "not in the project's list of dependencies anymore."; break; } - FileDependency * const dep = static_cast<FileDependency *>(*depIt); - dep->clearTimestamp(); - artifact->fileDependencies.insert(dep); + artifact->fileDependencies.insert(static_cast<FileDependency *>(*depIt)); } if (canRescue) { @@ -868,7 +893,8 @@ void Executor::rescueOldBuildData(Artifact *artifact, bool *childrenAdded = 0) artifact->transformer->lastPrepareScriptExecutionTime = rad.lastPrepareScriptExecutionTime; artifact->transformer->commandsNeedChangeTracking = true; artifact->setTimestamp(rad.timeStamp); - artifact->knownOutOfDate = artifact->knownOutOfDate || rad.knownOutOfDate; + artifact->transformer->markedForRerun + = artifact->transformer->markedForRerun || rad.knownOutOfDate; if (childrenAdded && !childrenToConnect.empty()) *childrenAdded = true; for (Artifact * const child : childrenToConnect) { @@ -986,15 +1012,25 @@ void Executor::runTransformer(const TransformerPtr &transformer) for (Artifact * const artifact : qAsConst(transformer->outputs)) artifact->buildState = BuildGraphNode::Building; m_processingJobs.insert(job, transformer); + updateJobCounts(transformer.get(), 1); job->run(transformer.get()); } void Executor::finishTransformer(const TransformerPtr &transformer) { + transformer->markedForRerun = false; for (Artifact * const artifact : qAsConst(transformer->outputs)) { possiblyInstallArtifact(artifact); finishArtifact(artifact); } + if (m_progressObserver) { + const auto it = m_pendingTransformersPerRule.find(transformer->rule.get()); + QBS_CHECK(it != m_pendingTransformersPerRule.cend()); + if (--it->second == 0) { + m_progressObserver->incrementProgressValue(); + m_pendingTransformersPerRule.erase(it); + } + } } void Executor::possiblyInstallArtifact(const Artifact *artifact) @@ -1013,7 +1049,7 @@ void Executor::possiblyInstallArtifact(const Artifact *artifact) void Executor::onJobFinished(const qbs::ErrorInfo &err) { try { - ExecutorJob * const job = qobject_cast<ExecutorJob *>(sender()); + auto const job = qobject_cast<ExecutorJob *>(sender()); QBS_CHECK(job); if (m_evalContext->engine()->isActive()) { qCDebug(lcExec) << "Executor job finished while rule execution is pausing. " @@ -1178,7 +1214,9 @@ void Executor::syncFileDependencies() Set<FileDependency *> &globalFileDepList = m_project->buildData->fileDependencies; for (auto it = globalFileDepList.begin(); it != globalFileDepList.end(); ) { FileDependency * const dep = *it; - if (FileInfo(dep->filePath()).exists()) { + FileInfo fi(dep->filePath()); + if (fi.exists()) { + dep->setTimestamp(fi.lastModified()); ++it; continue; } @@ -1203,6 +1241,7 @@ void Executor::syncFileDependencies() it = globalFileDepList.erase(it); delete dep; } else { + dep->clearTimestamp(); ++it; } } @@ -1214,19 +1253,9 @@ void Executor::prepareArtifact(Artifact *artifact) artifact->timestampRetrieved = false; if (artifact->artifactType == Artifact::SourceFile) { - const FileTime oldTimestamp = artifact->timestamp(); retrieveSourceFileTimestamp(artifact); - if (oldTimestamp != artifact->timestamp()) - m_changedSourceArtifacts.push_back(artifact); possiblyInstallArtifact(artifact); } - - // Timestamps of file dependencies must be invalid for every build. - // TODO: These should be a subset of ProjectBuildData::fileDependencies, so clear the - // timestamps in syncFileDepencencies() instead. - // TODO: Verify this assumption in the sanity checks. - for (FileDependency * const fileDependency : qAsConst(artifact->fileDependencies)) - fileDependency->clearTimestamp(); } void Executor::setupForBuildingSelectedFiles(const BuildGraphNode *node) diff --git a/src/lib/corelib/buildgraph/executor.h b/src/lib/corelib/buildgraph/executor.h index a73e5f812..2756a7120 100644 --- a/src/lib/corelib/buildgraph/executor.h +++ b/src/lib/corelib/buildgraph/executor.h @@ -99,8 +99,8 @@ private: void checkForCancellation(); // BuildGraphVisitor implementation - bool visit(Artifact *artifact); - bool visit(RuleNode *ruleNode); + bool visit(Artifact *artifact) override; + bool visit(RuleNode *ruleNode) override; enum ExecutorState { ExecutorIdle, ExecutorRunning, ExecutorCanceling }; @@ -154,6 +154,10 @@ private: bool artifactHasMatchingOutputTags(const Artifact *artifact) const; bool transformerHasMatchingInputFiles(const TransformerConstPtr &transformer) const; + void setupJobLimits(); + void updateJobCounts(const Transformer *transformer, int diff); + bool schedulingBlockedByJobLimit(const BuildGraphNode *node); + typedef QHash<ExecutorJob *, TransformerPtr> JobMap; JobMap m_processingJobs; @@ -169,9 +173,11 @@ private: std::vector<ResolvedProductPtr> m_allProducts; std::unordered_map<QString, const ResolvedProduct *> m_productsByName; std::unordered_map<QString, const ResolvedProject *> m_projectsByName; + std::unordered_map<QString, int> m_jobCountPerPool; + std::unordered_map<const ResolvedProduct *, JobLimits> m_jobLimitsPerProduct; + std::unordered_map<const Rule *, int> m_pendingTransformersPerRule; NodeSet m_roots; Leaves m_leaves; - QList<Artifact *> m_changedSourceArtifacts; InputArtifactScannerContext *m_inputArtifactScanContext; ErrorInfo m_error; bool m_explicitlyCanceled; diff --git a/src/lib/corelib/buildgraph/executorjob.cpp b/src/lib/corelib/buildgraph/executorjob.cpp index e90b498f6..79f17377d 100644 --- a/src/lib/corelib/buildgraph/executorjob.cpp +++ b/src/lib/corelib/buildgraph/executorjob.cpp @@ -113,6 +113,7 @@ void ExecutorJob::run(Transformer *t) m_processCommandExecutor->setProcessEnvironment( (*t->outputs.cbegin())->product->buildEnvironment); m_transformer = t; + m_jobPools = t->jobPools(); runNextCommand(); } @@ -171,6 +172,7 @@ void ExecutorJob::setFinished() void ExecutorJob::reset() { m_transformer = nullptr; + m_jobPools.clear(); m_currentCommandExecutor = nullptr; m_currentCommandIdx = -1; m_error.clear(); diff --git a/src/lib/corelib/buildgraph/executorjob.h b/src/lib/corelib/buildgraph/executorjob.h index b1701a11d..e28d42f7f 100644 --- a/src/lib/corelib/buildgraph/executorjob.h +++ b/src/lib/corelib/buildgraph/executorjob.h @@ -43,8 +43,10 @@ #include <language/forward_decls.h> #include <tools/commandechomode.h> #include <tools/error.h> +#include <tools/set.h> #include <QtCore/qobject.h> +#include <QtCore/qstring.h> namespace qbs { class CodeLocation; @@ -71,6 +73,8 @@ public: void setEchoMode(CommandEchoMode echoMode); void run(Transformer *t); void cancel(); + const Transformer *transformer() const { return m_transformer; } + Set<QString> jobPools() const { return m_jobPools; } signals: void reportCommandDescription(const QString &highlight, const QString &message); @@ -88,6 +92,7 @@ private: ProcessCommandExecutor *m_processCommandExecutor; JsCommandExecutor *m_jsCommandExecutor; Transformer *m_transformer; + Set<QString> m_jobPools; int m_currentCommandIdx; ErrorInfo m_error; }; diff --git a/src/lib/corelib/buildgraph/forward_decls.h b/src/lib/corelib/buildgraph/forward_decls.h index 4f84041af..f39c9eb6f 100644 --- a/src/lib/corelib/buildgraph/forward_decls.h +++ b/src/lib/corelib/buildgraph/forward_decls.h @@ -48,6 +48,7 @@ class Artifact; class BuildGraphNode; class ProjectBuildData; class ProductBuildData; +class RuleNode; class Transformer; typedef std::shared_ptr<Transformer> TransformerPtr; diff --git a/src/lib/corelib/buildgraph/inputartifactscanner.cpp b/src/lib/corelib/buildgraph/inputartifactscanner.cpp index e96f6fdde..143c99fb5 100644 --- a/src/lib/corelib/buildgraph/inputartifactscanner.cpp +++ b/src/lib/corelib/buildgraph/inputartifactscanner.cpp @@ -84,7 +84,7 @@ static void resolveDepencency(const RawScannedDependency &dependency, fileDependencyArtifact = static_cast<FileDependency *>(lookupResult); break; case FileResourceBase::FileTypeArtifact: { - Artifact * const foundArtifact = static_cast<Artifact *>(lookupResult); + auto const foundArtifact = static_cast<Artifact *>(lookupResult); if (foundArtifact->product == product) dependencyInProduct = foundArtifact; else @@ -170,7 +170,7 @@ void InputArtifactScanner::scanForFileDependencies(Artifact *inputArtifact) for (DependencyScanner * const scanner : scanners) { scanForScannerFileDependencies(scanner, inputArtifact, fileToBeScanned, - scanner->recursive() ? &filesToScan : 0, cacheItem[scanner->key()]); + scanner->recursive() ? &filesToScan : nullptr, cacheItem[scanner->key()]); } } } @@ -277,8 +277,7 @@ resolved: if (artifactsToScan && resolvedDependency.file) { if (resolvedDependency.file->fileType() == FileResourceBase::FileTypeArtifact) { // Do not scan an artifact that is not built yet: Its contents might still change. - Artifact * const artifactDependency - = static_cast<Artifact *>(resolvedDependency.file); + auto const artifactDependency = static_cast<Artifact *>(resolvedDependency.file); if (artifactDependency->artifactType == Artifact::SourceFile || artifactDependency->buildState == BuildGraphNode::Built) { artifactsToScan->push_back(artifactDependency); diff --git a/src/lib/corelib/buildgraph/jscommandexecutor.h b/src/lib/corelib/buildgraph/jscommandexecutor.h index ec9d43147..207e18097 100644 --- a/src/lib/corelib/buildgraph/jscommandexecutor.h +++ b/src/lib/corelib/buildgraph/jscommandexecutor.h @@ -64,9 +64,9 @@ signals: private: void onJavaScriptCommandFinished(); - void doReportCommandDescription(const QString &productName); - void doStart(); - void cancel(); + void doReportCommandDescription(const QString &productName) override; + void doStart() override; + void cancel() override; void waitForFinished(); diff --git a/src/lib/corelib/buildgraph/processcommandexecutor.cpp b/src/lib/corelib/buildgraph/processcommandexecutor.cpp index cee45bcd0..0818e1200 100644 --- a/src/lib/corelib/buildgraph/processcommandexecutor.cpp +++ b/src/lib/corelib/buildgraph/processcommandexecutor.cpp @@ -197,7 +197,7 @@ void ProcessCommandExecutor::doStart() void ProcessCommandExecutor::cancel() { // We don't want this command to be reported as failing, since we explicitly terminated it. - disconnect(this, &ProcessCommandExecutor::reportProcessResult, 0, 0); + disconnect(this, &ProcessCommandExecutor::reportProcessResult, nullptr, nullptr); m_process.cancel(); } diff --git a/src/lib/corelib/buildgraph/processcommandexecutor.h b/src/lib/corelib/buildgraph/processcommandexecutor.h index bebe3a5e2..67eb9f746 100644 --- a/src/lib/corelib/buildgraph/processcommandexecutor.h +++ b/src/lib/corelib/buildgraph/processcommandexecutor.h @@ -69,10 +69,10 @@ private: void onProcessError(); void onProcessFinished(); - void doSetup(); - void doReportCommandDescription(const QString &productName); - void doStart(); - void cancel(); + void doSetup() override; + void doReportCommandDescription(const QString &productName) override; + void doStart() override; + void cancel() override; void startProcessCommand(); QString filterProcessOutput(const QByteArray &output, const QString &filterFunctionSource); diff --git a/src/lib/corelib/buildgraph/productbuilddata.cpp b/src/lib/corelib/buildgraph/productbuilddata.cpp index 7445c93cb..db51b2b9f 100644 --- a/src/lib/corelib/buildgraph/productbuilddata.cpp +++ b/src/lib/corelib/buildgraph/productbuilddata.cpp @@ -100,27 +100,6 @@ void ProductBuildData::addFileTagToArtifact(Artifact *artifact, const FileTag &t m_jsArtifactsMapUpToDate = false; } -void ProductBuildData::addArtifactWithChangedInputsForRule(const RuleConstPtr &rule, - Artifact *artifact) -{ - m_artifactsWithChangedInputsPerRule[rule] += artifact; -} - -void ProductBuildData::removeArtifactWithChangedInputsForRule(const RuleConstPtr &rule, Artifact *artifact) -{ - m_artifactsWithChangedInputsPerRule[rule] -= artifact; -} - -void ProductBuildData::removeAllArtifactsWithChangedInputsForRule(const RuleConstPtr &rule) -{ - m_artifactsWithChangedInputsPerRule.remove(rule); -} - -bool ProductBuildData::ruleHasArtifactWithChangedInputs(const RuleConstPtr &rule) const -{ - return !m_artifactsWithChangedInputsPerRule.value(rule).empty(); -} - ArtifactSetByFileTag ProductBuildData::artifactsByFileTag() const { std::lock_guard<std::mutex> l(m_artifactsMapMutex); diff --git a/src/lib/corelib/buildgraph/productbuilddata.h b/src/lib/corelib/buildgraph/productbuilddata.h index 553f79159..bcc500de8 100644 --- a/src/lib/corelib/buildgraph/productbuilddata.h +++ b/src/lib/corelib/buildgraph/productbuilddata.h @@ -68,15 +68,12 @@ public: void addNode(BuildGraphNode *node) { m_nodes.insert(node); } void addRootNode(BuildGraphNode *node) { m_roots.insert(node); } + void removeFromRootNodes(BuildGraphNode *node) { m_roots.remove(node); } void addArtifact(Artifact *artifact); void addArtifactToSet(Artifact *artifact); void removeArtifact(Artifact *artifact); void removeArtifactFromSetByFileTag(Artifact *artifact, const FileTag &fileTag); void addFileTagToArtifact(Artifact *artifact, const FileTag &tag); - void addArtifactWithChangedInputsForRule(const RuleConstPtr &rule, Artifact *artifact); - void removeArtifactWithChangedInputsForRule(const RuleConstPtr &rule, Artifact *artifact); - void removeAllArtifactsWithChangedInputsForRule(const RuleConstPtr &rule); - bool ruleHasArtifactWithChangedInputs(const RuleConstPtr &rule) const; ArtifactSetByFileTag artifactsByFileTag() const; @@ -93,7 +90,7 @@ public: template<PersistentPool::OpType opType> void completeSerializationOp(PersistentPool &pool) { pool.serializationOp<opType>(m_nodes, m_roots, m_rescuableArtifactData, - m_artifactsByFileTag, m_artifactsWithChangedInputsPerRule); + m_artifactsByFileTag); } private: @@ -114,9 +111,6 @@ private: ArtifactSetByFileTag m_artifactsByFileTag; mutable std::mutex m_artifactsMapMutex; - typedef QHash<RuleConstPtr, ArtifactSet> ArtifactSetByRule; - ArtifactSetByRule m_artifactsWithChangedInputsPerRule; - bool m_jsArtifactsMapUpToDate = true; }; diff --git a/src/lib/corelib/buildgraph/projectbuilddata.cpp b/src/lib/corelib/buildgraph/projectbuilddata.cpp index 88de0f392..ccb6c5123 100644 --- a/src/lib/corelib/buildgraph/projectbuilddata.cpp +++ b/src/lib/corelib/buildgraph/projectbuilddata.cpp @@ -167,12 +167,11 @@ static void disconnectArtifactParents(Artifact *artifact) parent->children.remove(artifact); if (parent->type() != BuildGraphNode::ArtifactNodeType) continue; - Artifact * const parentArtifact = static_cast<Artifact *>(parent); + auto const parentArtifact = static_cast<Artifact *>(parent); QBS_CHECK(parentArtifact->transformer); parentArtifact->childrenAddedByScanner.remove(artifact); parentArtifact->transformer->inputs.remove(artifact); parentArtifact->transformer->explicitlyDependsOn.remove(artifact); - parentArtifact->product->registerArtifactWithChangedInputs(parentArtifact); } artifact->parents.clear(); @@ -205,7 +204,6 @@ void ProjectBuildData::removeArtifactAndExclusiveDependents(Artifact *artifact, if (parent->children.empty()) { removeParent = true; } else if (parent->transformer) { - parent->product->registerArtifactWithChangedInputs(parent); parent->transformer->inputs.remove(artifact); removeParent = parent->transformer->inputs.empty(); } @@ -222,18 +220,8 @@ void ProjectBuildData::removeArtifactAndExclusiveDependents(Artifact *artifact, static void removeFromRuleNodes(Artifact *artifact) { - for (const ResolvedProductPtr &product : artifact->product->topLevelProject()->allProducts()) { - if (!product->buildData) - continue; - for (BuildGraphNode *n : qAsConst(product->buildData->allNodes())) { - if (n->type() != BuildGraphNode::RuleNodeType) - continue; - const auto ruleNode = static_cast<RuleNode *>(n); - qCDebug(lcBuildGraph) << "remove old input" << artifact->filePath() - << "from rule" << ruleNode->rule()->toString(); - ruleNode->removeOldInputArtifact(artifact); - } - } + for (RuleNode * const ruleNode : filterByType<RuleNode>(artifact->parents)) + ruleNode->removeOldInputArtifact(artifact); } void ProjectBuildData::removeArtifact(Artifact *artifact, @@ -245,10 +233,8 @@ void ProjectBuildData::removeArtifact(Artifact *artifact, removeFromLookupTable(artifact); removeFromRuleNodes(artifact); disconnectArtifact(artifact); - if (artifact->transformer) { - artifact->product->unregisterArtifactWithChangedInputs(artifact); + if (artifact->transformer) artifact->transformer->outputs.remove(artifact); - } if (removeFromProduct) artifact->product->buildData->removeArtifact(artifact); m_isDirty = false; diff --git a/src/lib/corelib/buildgraph/projectbuilddata.h b/src/lib/corelib/buildgraph/projectbuilddata.h index e63922bae..0df303c0b 100644 --- a/src/lib/corelib/buildgraph/projectbuilddata.h +++ b/src/lib/corelib/buildgraph/projectbuilddata.h @@ -62,7 +62,7 @@ class ScriptEngine; class QBS_AUTOTEST_EXPORT ProjectBuildData { public: - ProjectBuildData(const ProjectBuildData *other = 0); + ProjectBuildData(const ProjectBuildData *other = nullptr); ~ProjectBuildData(); static QString deriveBuildGraphFilePath(const QString &buildDir, const QString &projectId); @@ -75,7 +75,7 @@ public: QList<FileResourceBase *> lookupFiles(const Artifact *artifact) const; void insertFileDependency(FileDependency *dependency); void removeArtifactAndExclusiveDependents(Artifact *artifact, const Logger &logger, - bool removeFromProduct = true, ArtifactSet *removedArtifacts = 0); + bool removeFromProduct = true, ArtifactSet *removedArtifacts = nullptr); void removeArtifact(Artifact *artifact, const Logger &logger, bool removeFromDisk = true, bool removeFromProduct = true); diff --git a/src/lib/corelib/buildgraph/qtmocscanner.cpp b/src/lib/corelib/buildgraph/qtmocscanner.cpp index a2e9786aa..8c165cb80 100644 --- a/src/lib/corelib/buildgraph/qtmocscanner.cpp +++ b/src/lib/corelib/buildgraph/qtmocscanner.cpp @@ -219,8 +219,6 @@ QScriptValue QtMocScanner::apply(QScriptEngine *engine, const Artifact *artifact m_cppScanner = scanners.front(); } - findIncludedMocCppFiles(); - qCDebug(lcMocScan).noquote() << "scanning" << artifact->toString(); bool hasQObjectMacro = false; @@ -237,6 +235,7 @@ QScriptValue QtMocScanner::apply(QScriptEngine *engine, const Artifact *artifact hasQObjectMacro = true; hasPluginMetaDataMacro = true; } + findIncludedMocCppFiles(); if (!m_includedMocCppFiles.contains(FileInfo::completeBaseName(artifact->fileName()))) mustCompile = true; } else { @@ -257,6 +256,7 @@ QScriptValue QtMocScanner::apply(QScriptEngine *engine, const Artifact *artifact obj.setProperty(QStringLiteral("hasQObjectMacro"), hasQObjectMacro); obj.setProperty(QStringLiteral("mustCompile"), mustCompile); obj.setProperty(QStringLiteral("hasPluginMetaDataMacro"), hasPluginMetaDataMacro); + static_cast<ScriptEngine *>(engine)->setUsesIo(); return obj; } diff --git a/src/lib/corelib/buildgraph/rescuableartifactdata.h b/src/lib/corelib/buildgraph/rescuableartifactdata.h index a88d63273..068c543ed 100644 --- a/src/lib/corelib/buildgraph/rescuableartifactdata.h +++ b/src/lib/corelib/buildgraph/rescuableartifactdata.h @@ -104,7 +104,6 @@ public: FileTime timeStamp; std::vector<ChildData> children; std::vector<QString> fileDependencies; - bool knownOutOfDate = false; // Per-Transformer data CommandList commands; @@ -122,6 +121,7 @@ public: FileTime lastCommandExecutionTime; std::unordered_map<QString, ExportedModule> exportedModulesAccessedInPrepareScript; std::unordered_map<QString, ExportedModule> exportedModulesAccessedInCommands; + bool knownOutOfDate = false; // Only needed for API purposes FileTags fileTags; diff --git a/src/lib/corelib/buildgraph/rulecommands.cpp b/src/lib/corelib/buildgraph/rulecommands.cpp index c2aad1ce1..a15047290 100644 --- a/src/lib/corelib/buildgraph/rulecommands.cpp +++ b/src/lib/corelib/buildgraph/rulecommands.cpp @@ -103,6 +103,7 @@ bool AbstractCommand::equals(const AbstractCommand *other) const && m_highlight == other->m_highlight && m_ignoreDryRun == other->m_ignoreDryRun && m_silent == other->m_silent + && m_jobPool == other->m_jobPool && m_properties == other->m_properties; } @@ -113,6 +114,7 @@ void AbstractCommand::fillFromScriptValue(const QScriptValue *scriptValue, const m_highlight = scriptValue->property(highlightProperty()).toString(); m_ignoreDryRun = scriptValue->property(ignoreDryRunProperty()).toBool(); m_silent = scriptValue->property(silentProperty()).toBool(); + m_jobPool = scriptValue->property(StringConstants::jobPoolProperty()).toString(); m_codeLocation = codeLocation; m_predefinedProperties @@ -120,6 +122,7 @@ void AbstractCommand::fillFromScriptValue(const QScriptValue *scriptValue, const << extendedDescriptionProperty() << highlightProperty() << ignoreDryRunProperty() + << StringConstants::jobPoolProperty() << silentProperty(); } @@ -146,7 +149,9 @@ void AbstractCommand::applyCommandProperties(const QScriptValue *scriptValue) if (m_predefinedProperties.contains(it.name())) continue; const QVariant value = it.value().toVariant(); - if (QMetaType::Type(value.type()) == QMetaType::QObjectStar) { + if (QMetaType::Type(value.type()) == QMetaType::QObjectStar + || it.value().scriptClass() + || it.value().data().isValid()) { throw ErrorInfo(Tr::tr("Property '%1' has a type unsuitable for storing in a command " "object.").arg(it.name()), m_codeLocation); } @@ -392,8 +397,7 @@ bool JavaScriptCommand::equals(const AbstractCommand *otherAbstractCommand) cons { if (!AbstractCommand::equals(otherAbstractCommand)) return false; - const JavaScriptCommand * const other - = static_cast<const JavaScriptCommand *>(otherAbstractCommand); + auto const other = static_cast<const JavaScriptCommand *>(otherAbstractCommand); return m_sourceCode == other->m_sourceCode; } diff --git a/src/lib/corelib/buildgraph/rulecommands.h b/src/lib/corelib/buildgraph/rulecommands.h index 7583de2b6..4e56359f4 100644 --- a/src/lib/corelib/buildgraph/rulecommands.h +++ b/src/lib/corelib/buildgraph/rulecommands.h @@ -81,6 +81,7 @@ public: const QString highlight() const { return m_highlight; } bool ignoreDryRun() const { return m_ignoreDryRun; } bool isSilent() const { return m_silent; } + QString jobPool() const { return m_jobPool; } CodeLocation codeLocation() const { return m_codeLocation; } const QVariantMap &properties() const { return m_properties; } @@ -98,7 +99,8 @@ private: template<PersistentPool::OpType opType> void serializationOp(PersistentPool &pool) { pool.serializationOp<opType>(m_description, m_extendedDescription, m_highlight, - m_ignoreDryRun, m_silent, m_codeLocation, m_properties); + m_ignoreDryRun, m_silent, m_codeLocation, m_jobPool, + m_properties); } QString m_description; @@ -107,6 +109,7 @@ private: bool m_ignoreDryRun; bool m_silent; CodeLocation m_codeLocation; + QString m_jobPool; QVariantMap m_properties; }; @@ -116,9 +119,10 @@ public: static ProcessCommandPtr create() { return ProcessCommandPtr(new ProcessCommand); } static void setupForJavaScript(QScriptValue targetObject); - CommandType type() const { return ProcessCommandType; } - bool equals(const AbstractCommand *otherAbstractCommand) const; - void fillFromScriptValue(const QScriptValue *scriptValue, const CodeLocation &codeLocation); + CommandType type() const override { return ProcessCommandType; } + bool equals(const AbstractCommand *otherAbstractCommand) const override; + void fillFromScriptValue(const QScriptValue *scriptValue, + const CodeLocation &codeLocation) override; const QString program() const { return m_program; } const QStringList arguments() const { return m_arguments; } const QString workingDir() const { return m_workingDir; } @@ -136,8 +140,8 @@ public: QString stdoutFilePath() const { return m_stdoutFilePath; } QString stderrFilePath() const { return m_stderrFilePath; } - void load(PersistentPool &pool); - void store(PersistentPool &pool); + void load(PersistentPool &pool) override; + void store(PersistentPool &pool) override; private: ProcessCommand(); @@ -178,16 +182,17 @@ public: static JavaScriptCommandPtr create() { return JavaScriptCommandPtr(new JavaScriptCommand); } static void setupForJavaScript(QScriptValue targetObject); - virtual CommandType type() const { return JavaScriptCommandType; } - bool equals(const AbstractCommand *otherAbstractCommand) const; - void fillFromScriptValue(const QScriptValue *scriptValue, const CodeLocation &codeLocation); + CommandType type() const override { return JavaScriptCommandType; } + bool equals(const AbstractCommand *otherAbstractCommand) const override; + void fillFromScriptValue(const QScriptValue *scriptValue, + const CodeLocation &codeLocation) override; const QString &scopeName() const { return m_scopeName; } const QString &sourceCode() const { return m_sourceCode; } void setSourceCode(const QString &str) { m_sourceCode = str; } - void load(PersistentPool &pool); - void store(PersistentPool &pool); + void load(PersistentPool &pool) override; + void store(PersistentPool &pool) override; private: JavaScriptCommand(); diff --git a/src/lib/corelib/buildgraph/rulenode.cpp b/src/lib/corelib/buildgraph/rulenode.cpp index 27f2d2c55..516b9b830 100644 --- a/src/lib/corelib/buildgraph/rulenode.cpp +++ b/src/lib/corelib/buildgraph/rulenode.cpp @@ -78,15 +78,22 @@ QString RuleNode::toString() const + QLatin1String(" located at ") + m_rule->prepareScript.location().toString(); } -void RuleNode::apply(const Logger &logger, const ArtifactSet &changedInputs, +void RuleNode::apply(const Logger &logger, const std::unordered_map<QString, const ResolvedProduct *> &productsByName, const std::unordered_map<QString, const ResolvedProject *> &projectsByName, ApplicationResult *result) { ArtifactSet allCompatibleInputs = currentInputArtifacts(); + const ArtifactSet explicitlyDependsOn + = RulesApplicator::collectExplicitlyDependsOn(m_rule.get(), product.get()); + const ArtifactSet auxiliaryInputs + = RulesApplicator::collectAuxiliaryInputs(m_rule.get(), product.get()); const ArtifactSet addedInputs = allCompatibleInputs - m_oldInputArtifacts; const ArtifactSet removedInputs = m_oldInputArtifacts - allCompatibleInputs; - result->upToDate = changedInputs.empty() && addedInputs.empty() && removedInputs.empty(); + const ArtifactSet changedInputs = changedInputArtifacts(allCompatibleInputs, + explicitlyDependsOn, + auxiliaryInputs); + bool upToDate = changedInputs.empty() && addedInputs.empty() && removedInputs.empty(); qCDebug(lcBuildGraph).noquote().nospace() << "consider " << (m_rule->isDynamic() ? "dynamic " : "") @@ -98,13 +105,6 @@ void RuleNode::apply(const Logger &logger, const ArtifactSet &changedInputs, << "\n\tremoved: " << removedInputs.toString(); ArtifactSet inputs = changedInputs; - if (product->isMarkedForReapplication(m_rule)) { - QBS_CHECK(m_rule->multiplex); - result->upToDate = false; - product->unmarkForReapplication(m_rule); - qCDebug(lcBuildGraph) << "rule is marked for reapplication " << m_rule->toString(); - } - if (m_rule->multiplex) inputs = allCompatibleInputs; else @@ -117,7 +117,7 @@ void RuleNode::apply(const Logger &logger, const ArtifactSet &changedInputs, if (prepareScriptNeedsRerun(output->transformer.get(), output->transformer->product().get(), productsByName, projectsByName)) { - result->upToDate = false; + upToDate = false; inputs += input; } break; @@ -128,8 +128,7 @@ void RuleNode::apply(const Logger &logger, const ArtifactSet &changedInputs, // Handle rules without inputs: We want to run such a rule if and only if it has not run yet // or its transformer is not up to date regarding the prepare script. - if (result->upToDate && (!m_rule->declaresInputs() || !m_rule->requiresInputs) - && inputs.empty()) { + if (upToDate && (!m_rule->declaresInputs() || !m_rule->requiresInputs) && inputs.empty()) { bool hasOutputs = false; for (const Artifact * const output : filterByType<Artifact>(parents)) { if (output->transformer->rule != m_rule) @@ -138,46 +137,77 @@ void RuleNode::apply(const Logger &logger, const ArtifactSet &changedInputs, if (prepareScriptNeedsRerun(output->transformer.get(), output->transformer->product().get(), productsByName, projectsByName)) { - result->upToDate = false; + upToDate = false; break; } if (m_rule->multiplex) break; } if (!hasOutputs) - result->upToDate = false; + upToDate = false; } - if (result->upToDate) + if (upToDate) { + qCDebug(lcExec) << "rule is up to date. Skipping."; return; - if (!removedInputs.empty()) { - ArtifactSet outputArtifactsToRemove; - for (Artifact * const artifact : removedInputs) { - for (Artifact *parent : filterByType<Artifact>(artifact->parents)) { - if (parent->transformer->rule != m_rule) { - // parent was not created by our rule. - continue; - } - - // parent must always have a transformer, because it's generated. - QBS_CHECK(parent->transformer); - - // artifact is a former input of m_rule and parent was created by m_rule - // the inputs of the transformer must contain artifact - QBS_CHECK(parent->transformer->inputs.contains(artifact)); + } - outputArtifactsToRemove += parent; + const bool mustApplyRule = !inputs.empty() || !m_rule->declaresInputs() + || !m_rule->requiresInputs; + + // For a non-multiplex rule, the removal of an input always implies that the + // corresponding outputs disappear. + // For a multiplex rule, the outputs disappear only if *all* inputs are gone *and* + // the rule requires inputs. This is exactly the opposite condition of whether to + // re-apply the rule. + const bool removedInputForcesOutputRemoval = !m_rule->multiplex || !mustApplyRule; + ArtifactSet outputArtifactsToRemove; + std::vector<std::pair<Artifact *, Artifact *>> connectionsToBreak; + for (Artifact * const artifact : removedInputs) { + if (!artifact) // dummy artifact + continue; + for (Artifact *parent : filterByType<Artifact>(artifact->parents)) { + if (parent->transformer->rule != m_rule) { + // parent was not created by our rule. + continue; } + + // parent must always have a transformer, because it's generated. + QBS_CHECK(parent->transformer); + + // artifact is a former input of m_rule and parent was created by m_rule + // the inputs of the transformer must contain artifact + QBS_CHECK(parent->transformer->inputs.contains(artifact)); + + if (removedInputForcesOutputRemoval) + outputArtifactsToRemove += parent; + else + connectionsToBreak.push_back(std::make_pair(parent, artifact)); } - RulesApplicator::handleRemovedRuleOutputs(inputs, outputArtifactsToRemove, logger); + disconnect(this, artifact); + } + for (const auto &connection : connectionsToBreak) + disconnect(connection.first, connection.second); + if (!outputArtifactsToRemove.empty()) { + RulesApplicator::handleRemovedRuleOutputs(inputs, outputArtifactsToRemove, + result->removedArtifacts, logger); } - if (!inputs.empty() || !m_rule->declaresInputs() || !m_rule->requiresInputs) { + + if (mustApplyRule) { RulesApplicator applicator(product.lock(), productsByName, projectsByName, logger); - applicator.applyRule(m_rule, inputs); - result->createdNodes = applicator.createdArtifacts(); - result->invalidatedNodes = applicator.invalidatedArtifacts(); - m_oldInputArtifacts.unite(inputs); + applicator.applyRule(this, inputs, explicitlyDependsOn); + result->createdArtifacts = applicator.createdArtifacts(); + result->invalidatedArtifacts = applicator.invalidatedArtifacts(); + m_lastApplicationTime = FileTime::currentTime(); + if (applicator.ruleUsesIo()) + m_needsToConsiderChangedInputs = true; + } else { + qCDebug(lcExec).noquote() << "prepare script does not need to run"; } + m_oldInputArtifacts = allCompatibleInputs; + m_oldExplicitlyDependsOn = explicitlyDependsOn; + m_oldAuxiliaryInputs = auxiliaryInputs; + product->topLevelProject()->buildData->setDirty(); } void RuleNode::load(PersistentPool &pool) @@ -192,6 +222,14 @@ void RuleNode::store(PersistentPool &pool) serializationOp<PersistentPool::Store>(pool); } +int RuleNode::transformerCount() const +{ + Set<const Transformer *> transformers; + for (const Artifact * const output : filterByType<Artifact>(parents)) + transformers.insert(output->transformer.get()); + return transformers.size(); +} + ArtifactSet RuleNode::currentInputArtifacts() const { ArtifactSet s; @@ -237,5 +275,51 @@ ArtifactSet RuleNode::currentInputArtifacts() const return s; } +ArtifactSet RuleNode::changedInputArtifacts(const ArtifactSet &allCompatibleInputs, + const ArtifactSet &explicitlyDependsOn, + const ArtifactSet &auxiliaryInputs) const +{ + ArtifactSet changedInputArtifacts; + if (explicitlyDependsOn != m_oldExplicitlyDependsOn) + return allCompatibleInputs; + if (!m_needsToConsiderChangedInputs) + return changedInputArtifacts; + + for (Artifact * const artifact : explicitlyDependsOn) { + if (artifact->timestamp() > m_lastApplicationTime) + return allCompatibleInputs; + } + if (auxiliaryInputs != m_oldAuxiliaryInputs) + return allCompatibleInputs; + for (Artifact * const artifact : auxiliaryInputs) { + if (artifact->timestamp() > m_lastApplicationTime) + return allCompatibleInputs; + } + for (Artifact * const artifact : allCompatibleInputs) { + if (artifact->timestamp() > m_lastApplicationTime) + changedInputArtifacts.insert(artifact); + } + return changedInputArtifacts; +} + +void RuleNode::removeOldInputArtifact(Artifact *artifact) +{ + if (m_oldInputArtifacts.remove(artifact)) { + qCDebug(lcBuildGraph) << "remove old input" << artifact->filePath() + << "from rule" << rule()->toString(); + m_oldInputArtifacts.insert(nullptr); + } + if (m_oldExplicitlyDependsOn.remove(artifact)) { + qCDebug(lcBuildGraph) << "remove old explicitlyDependsOn" << artifact->filePath() + << "from rule" << rule()->toString(); + m_oldExplicitlyDependsOn.insert(nullptr); + } + if (m_oldAuxiliaryInputs.remove(artifact)) { + qCDebug(lcBuildGraph) << "remove old auxiliaryInput" << artifact->filePath() + << "from rule" << rule()->toString(); + m_oldAuxiliaryInputs.insert(nullptr); + } +} + } // namespace Internal } // namespace qbs diff --git a/src/lib/corelib/buildgraph/rulenode.h b/src/lib/corelib/buildgraph/rulenode.h index b502b7ac8..0585678ec 100644 --- a/src/lib/corelib/buildgraph/rulenode.h +++ b/src/lib/corelib/buildgraph/rulenode.h @@ -63,36 +63,52 @@ public: void setRule(const RuleConstPtr &rule) { m_rule = rule; } const RuleConstPtr &rule() const { return m_rule; } - Type type() const { return RuleNodeType; } - void accept(BuildGraphVisitor *visitor); - QString toString() const; + Type type() const override { return RuleNodeType; } + void accept(BuildGraphVisitor *visitor) override; + QString toString() const override; struct ApplicationResult { - bool upToDate; - NodeSet createdNodes; - NodeSet invalidatedNodes; + NodeSet createdArtifacts; + NodeSet invalidatedArtifacts; + QStringList removedArtifacts; }; - void apply(const Logger &logger, const ArtifactSet &changedInputs, + void apply(const Logger &logger, const std::unordered_map<QString, const ResolvedProduct *> &productsByName, const std::unordered_map<QString, const ResolvedProject *> &projectsByName, ApplicationResult *result); - void removeOldInputArtifact(Artifact *artifact) { m_oldInputArtifacts.remove(artifact); } + void removeOldInputArtifact(Artifact *artifact); - void load(PersistentPool &pool); - void store(PersistentPool &pool); + void load(PersistentPool &pool) override; + void store(PersistentPool &pool) override; + + int transformerCount() const; private: template<PersistentPool::OpType opType> void serializationOp(PersistentPool &pool) { - pool.serializationOp<opType>(m_rule, m_oldInputArtifacts); + pool.serializationOp<opType>(m_rule, m_oldInputArtifacts, m_oldExplicitlyDependsOn, + m_oldAuxiliaryInputs, m_lastApplicationTime, + m_needsToConsiderChangedInputs); } ArtifactSet currentInputArtifacts() const; + ArtifactSet changedInputArtifacts(const ArtifactSet &allCompatibleInputs, + const ArtifactSet &explicitlyDependsOn, const ArtifactSet &auxiliaryInputs) const; RuleConstPtr m_rule; + + // These three can contain null pointers, which represent a "dummy artifact" encoding + // the information that an artifact that used to be in here has ceased to exist. + // This is okay, because no code outside this class has access to these sets, so + // we cannot break any assumptions about non-nullness. ArtifactSet m_oldInputArtifacts; + ArtifactSet m_oldExplicitlyDependsOn; + ArtifactSet m_oldAuxiliaryInputs; + + FileTime m_lastApplicationTime; + bool m_needsToConsiderChangedInputs = false; }; template<> inline bool hasDynamicType<RuleNode>(const BuildGraphNode *n) diff --git a/src/lib/corelib/buildgraph/rulesapplicator.cpp b/src/lib/corelib/buildgraph/rulesapplicator.cpp index 1144e5ff5..777ec4b9e 100644 --- a/src/lib/corelib/buildgraph/rulesapplicator.cpp +++ b/src/lib/corelib/buildgraph/rulesapplicator.cpp @@ -39,11 +39,11 @@ #include "rulesapplicator.h" #include "buildgraph.h" -#include "emptydirectoriesremover.h" #include "productbuilddata.h" #include "projectbuilddata.h" #include "qtmocscanner.h" #include "rulecommands.h" +#include "rulenode.h" #include "rulesevaluationcontext.h" #include "transformer.h" #include "transformerchangetracking.h" @@ -65,6 +65,7 @@ #include <tools/qttools.h> #include <tools/stringconstants.h> +#include <QtCore/qcryptographichash.h> #include <QtCore/qdir.h> #include <QtScript/qscriptvalueiterator.h> @@ -92,19 +93,22 @@ RulesApplicator::~RulesApplicator() delete m_mocScanner; } -void RulesApplicator::applyRule(const RuleConstPtr &rule, const ArtifactSet &inputArtifacts) +void RulesApplicator::applyRule(RuleNode *ruleNode, const ArtifactSet &inputArtifacts, + const ArtifactSet &explicitlyDependsOn) { - if (inputArtifacts.empty() && rule->declaresInputs() && rule->requiresInputs) - return; + m_ruleNode = ruleNode; + m_rule = ruleNode->rule(); + QBS_CHECK(!inputArtifacts.empty() || !m_rule->declaresInputs() || !m_rule->requiresInputs); m_product->topLevelProject()->buildData->setDirty(); m_createdArtifacts.clear(); m_invalidatedArtifacts.clear(); + m_removedArtifacts.clear(); + m_explicitlyDependsOn = explicitlyDependsOn; RulesEvaluationContext::Scope s(evalContext().get()); - m_rule = rule; m_completeInputSet = inputArtifacts; - if (rule->name == QLatin1String("QtCoreMocRule")) { + if (m_rule->name.startsWith(QLatin1String("QtCoreMocRule"))) { delete m_mocScanner; m_mocScanner = new QtMocScanner(m_product, scope()); } @@ -115,6 +119,7 @@ void RulesApplicator::applyRule(const RuleConstPtr &rule, const ArtifactSet &inp setupScriptEngineForProduct(engine(), m_product.get(), m_rule->module.get(), prepareScriptContext, true); + engine()->clearUsesIo(); if (m_rule->multiplex) { // apply the rule once for a set of inputs doApply(inputArtifacts, prepareScriptContext); } else { // apply the rule once for each input @@ -124,10 +129,13 @@ void RulesApplicator::applyRule(const RuleConstPtr &rule, const ArtifactSet &inp doApply(lst, prepareScriptContext); } } + if (engine()->usesIo()) + m_ruleUsesIo = true; } void RulesApplicator::handleRemovedRuleOutputs(const ArtifactSet &inputArtifacts, - const ArtifactSet &outputArtifactsToRemove, const Logger &logger) + const ArtifactSet &outputArtifactsToRemove, QStringList &removedArtifacts, + const Logger &logger) { ArtifactSet artifactsToRemove; const TopLevelProject *project = nullptr; @@ -139,14 +147,9 @@ void RulesApplicator::handleRemovedRuleOutputs(const ArtifactSet &inputArtifacts project->buildData->removeArtifactAndExclusiveDependents(removedArtifact, logger, true, &artifactsToRemove); } - // parents of removed artifacts must update their transformers - for (Artifact *removedArtifact : qAsConst(artifactsToRemove)) { - for (Artifact *parent : removedArtifact->parentArtifacts()) - parent->product->registerArtifactWithChangedInputs(parent); - } - EmptyDirectoriesRemover(project, logger).removeEmptyParentDirectories(artifactsToRemove); for (Artifact * const artifact : qAsConst(artifactsToRemove)) { QBS_CHECK(!inputArtifacts.contains(artifact)); + removedArtifacts << artifact->filePath(); delete artifact; } } @@ -183,13 +186,13 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p qCDebug(lcBuildGraph) << "apply rule" << m_rule->toString() << toStringList(inputArtifacts).join(QLatin1String(",\n ")); - QList<std::pair<const RuleArtifact *, Artifact *> > ruleArtifactArtifactMap; + QList<std::pair<const RuleArtifact *, OutputArtifactInfo>> ruleArtifactArtifactMap; QList<Artifact *> outputArtifacts; m_transformer = Transformer::create(); m_transformer->rule = m_rule; m_transformer->inputs = inputArtifacts; - m_transformer->explicitlyDependsOn = collectExplicitlyDependsOn(); + m_transformer->explicitlyDependsOn = m_explicitlyDependsOn; m_transformer->alwaysRun = m_rule->alwaysRun; m_oldTransformer.reset(); @@ -206,19 +209,37 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p if (m_rule->isDynamic()) { outputArtifacts = runOutputArtifactsScript(inputArtifacts, ScriptEngine::argumentList(Rule::argumentNamesForOutputArtifacts(), scope())); - ArtifactSet newOutputs = ArtifactSet::fromList(outputArtifacts); - const ArtifactSet oldOutputs = collectOldOutputArtifacts(inputArtifacts); - handleRemovedRuleOutputs(m_completeInputSet, oldOutputs - newOutputs, m_logger); } else { Set<QString> outputFilePaths; for (const RuleArtifactConstPtr &ruleArtifact : m_rule->artifacts) { - Artifact * const outputArtifact - = createOutputArtifactFromRuleArtifact(ruleArtifact, inputArtifacts, - &outputFilePaths); - if (!outputArtifact) + const OutputArtifactInfo outputInfo = createOutputArtifactFromRuleArtifact( + ruleArtifact, inputArtifacts, &outputFilePaths); + if (!outputInfo.artifact) continue; - outputArtifacts.push_back(outputArtifact); - ruleArtifactArtifactMap.push_back({ ruleArtifact.get(), outputArtifact }); + outputArtifacts.push_back(outputInfo.artifact); + ruleArtifactArtifactMap.push_back({ ruleArtifact.get(), outputInfo }); + } + if (m_rule->artifacts.empty()) { + outputArtifacts.push_back(createOutputArtifactFromRuleArtifact( + nullptr, inputArtifacts, &outputFilePaths).artifact); + } + } + + ArtifactSet newOutputs = ArtifactSet::fromList(outputArtifacts); + const ArtifactSet oldOutputs = collectOldOutputArtifacts(inputArtifacts); + handleRemovedRuleOutputs(m_completeInputSet, oldOutputs - newOutputs, m_removedArtifacts, + m_logger); + + // The inputs become children of the rule node. Generated artifacts in the same product + // already are children, because output artifacts become children of the producing + // rule node's parent rule node. + for (Artifact * const input : inputArtifacts) { + if (input->artifactType == Artifact::SourceFile || input->product != m_ruleNode->product + || input->producer()->rule()->collectedOutputFileTags().intersects( + m_ruleNode->rule()->excludedInputs)) { + connect(m_ruleNode, input); + } else { + QBS_CHECK(m_ruleNode->children.contains(input)); } } @@ -228,7 +249,6 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p for (Artifact * const outputArtifact : qAsConst(outputArtifacts)) { for (Artifact * const dependency : qAsConst(m_transformer->explicitlyDependsOn)) connect(outputArtifact, dependency); - outputArtifact->product->unregisterArtifactWithChangedInputs(outputArtifact); } if (inputArtifacts != m_transformer->inputs) @@ -245,7 +265,8 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p continue; // expose attributes of this artifact - Artifact *outputArtifact = it->second; + const OutputArtifactInfo outputInfo = it->second; + Artifact *outputArtifact = outputInfo.artifact; outputArtifact->properties = outputArtifact->properties->clone(); scope().setProperty(StringConstants::fileNameProperty(), @@ -262,9 +283,15 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p engine()->lastErrorString(scriptValue)), engine()->lastErrorLocation(scriptValue, binding.location)); } - setConfigProperty(artifactModulesCfg, binding.name, scriptValue.toVariant()); + const QVariant value = scriptValue.toVariant(); + setConfigProperty(artifactModulesCfg, binding.name, value); + outputArtifact->pureProperties.push_back(std::make_pair(binding.name, value)); } outputArtifact->properties->setValue(artifactModulesCfg); + if (!outputInfo.newlyCreated && (outputArtifact->fileTags() != outputInfo.oldFileTags + || outputArtifact->properties->value() != outputInfo.oldProperties)) { + invalidateArtifactAsRuleInputIfNecessary(outputArtifact); + } } if (!ruleArtifactArtifactMap.empty()) engine()->setGlobalObject(prepareScriptContext.prototype()); @@ -276,6 +303,8 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p throw ErrorInfo(Tr::tr("There is a rule without commands: %1.") .arg(m_rule->toString()), m_rule->prepareScript.location()); if (!m_oldTransformer || m_oldTransformer->outputs != m_transformer->outputs + || m_oldTransformer->inputs != m_transformer->inputs + || m_oldTransformer->explicitlyDependsOn != m_transformer->explicitlyDependsOn || m_oldTransformer->commands != m_transformer->commands || commandsNeedRerun(m_transformer.get(), m_product.get(), m_productsByName, m_projectsByName)) { @@ -336,43 +365,72 @@ ArtifactSet RulesApplicator::collectAdditionalInputs(const FileTags &tags, const return artifacts; } -ArtifactSet RulesApplicator::collectExplicitlyDependsOn() +ArtifactSet RulesApplicator::collectExplicitlyDependsOn(const Rule *rule, + const ResolvedProduct *product) { ArtifactSet first = collectAdditionalInputs( - m_rule->explicitlyDependsOn, m_rule.get(), m_product.get(), CurrentProduct); + rule->explicitlyDependsOn, rule, product, CurrentProduct); ArtifactSet second = collectAdditionalInputs( - m_rule->explicitlyDependsOnFromDependencies, m_rule.get(), m_product.get(), - Dependencies); + rule->explicitlyDependsOnFromDependencies, rule, product, Dependencies); return first.unite(second); } -Artifact *RulesApplicator::createOutputArtifactFromRuleArtifact( +RulesApplicator::OutputArtifactInfo RulesApplicator::createOutputArtifactFromRuleArtifact( const RuleArtifactConstPtr &ruleArtifact, const ArtifactSet &inputArtifacts, Set<QString> *outputFilePaths) { - QScriptValue scriptValue = engine()->evaluate(ruleArtifact->filePath, - ruleArtifact->filePathLocation.filePath(), - ruleArtifact->filePathLocation.line()); - if (Q_UNLIKELY(engine()->hasErrorOrException(scriptValue))) - throw engine()->lastError(scriptValue, ruleArtifact->filePathLocation); - QString outputPath = FileInfo::resolvePath(m_product->buildDirectory(), scriptValue.toString()); + QString outputPath; + FileTags fileTags; + bool alwaysUpdated; + if (ruleArtifact) { + QScriptValue scriptValue = engine()->evaluate(ruleArtifact->filePath, + ruleArtifact->filePathLocation.filePath(), + ruleArtifact->filePathLocation.line()); + if (Q_UNLIKELY(engine()->hasErrorOrException(scriptValue))) + throw engine()->lastError(scriptValue, ruleArtifact->filePathLocation); + outputPath = scriptValue.toString(); + fileTags = ruleArtifact->fileTags; + alwaysUpdated = ruleArtifact->alwaysUpdated; + } else { + outputPath = QStringLiteral("__dummyoutput__"); + QByteArray hashInput = m_rule->toString().toLatin1(); + for (const Artifact * const input : inputArtifacts) + hashInput += input->filePath().toLatin1(); + outputPath += QLatin1String(QCryptographicHash::hash(hashInput, QCryptographicHash::Sha1) + .toHex().left(16)); + fileTags = m_rule->outputFileTags; + alwaysUpdated = false; + } + outputPath = FileInfo::resolvePath(m_product->buildDirectory(), outputPath); if (Q_UNLIKELY(!outputFilePaths->insert(outputPath).second)) { throw ErrorInfo(Tr::tr("Rule %1 already created '%2'.") .arg(m_rule->toString(), outputPath)); } - return createOutputArtifact(outputPath, ruleArtifact->fileTags, ruleArtifact->alwaysUpdated, - inputArtifacts); + return createOutputArtifact(outputPath, fileTags, alwaysUpdated, inputArtifacts); } -Artifact *RulesApplicator::createOutputArtifact(const QString &filePath, const FileTags &fileTags, - bool alwaysUpdated, const ArtifactSet &inputArtifacts) +RulesApplicator::OutputArtifactInfo RulesApplicator::createOutputArtifact(const QString &filePath, + const FileTags &fileTags, bool alwaysUpdated, const ArtifactSet &inputArtifacts) { QString outputPath = filePath; // don't let the output artifact "escape" its build dir outputPath.replace(StringConstants::dotDot(), QStringLiteral("dotdot")); outputPath = resolveOutPath(outputPath); - Artifact *outputArtifact = lookupArtifact(m_product, outputPath); + if (m_rule->isDynamic()) { + const Set<FileTag> undeclaredTags = fileTags - m_rule->collectedOutputFileTags(); + if (!undeclaredTags.empty()) { + throw ErrorInfo(Tr::tr("Artifact '%1' has undeclared file tags [\"%2\"].") + .arg(outputPath, undeclaredTags.toStringList() + .join(QLatin1String("\",\""))), + m_rule->prepareScript.location()); + } + } + + OutputArtifactInfo outputInfo; + Artifact *& outputArtifact = outputInfo.artifact; + outputArtifact = lookupArtifact(m_product, outputPath); + outputInfo.newlyCreated = !outputArtifact; if (outputArtifact) { const Transformer * const transformer = outputArtifact->transformer.get(); if (transformer && transformer->rule != m_rule) { @@ -413,6 +471,8 @@ Artifact *RulesApplicator::createOutputArtifact(const QString &filePath, const F } m_transformer->rescueChangeTrackingData(outputArtifact->transformer); m_oldTransformer = outputArtifact->transformer; + outputInfo.oldFileTags = outputArtifact->fileTags(); + outputInfo.oldProperties = outputArtifact->properties->value(); } else { std::unique_ptr<Artifact> newArtifact(new Artifact); newArtifact->artifactType = Artifact::Generated; @@ -420,25 +480,17 @@ Artifact *RulesApplicator::createOutputArtifact(const QString &filePath, const F insertArtifact(m_product, newArtifact.get()); m_createdArtifacts += newArtifact.get(); outputArtifact = newArtifact.release(); + qCDebug(lcExec).noquote() << "rule created" << outputArtifact->toString(); + connect(outputArtifact, m_ruleNode); } outputArtifact->alwaysUpdated = alwaysUpdated; - outputArtifact->properties = m_product->moduleProperties; - - FileTags outputArtifactFileTags = fileTags.empty() - ? m_product->fileTagsForFileName(outputArtifact->fileName()) : fileTags; - for (const ArtifactPropertiesConstPtr &props : m_product->artifactProperties) { - if (outputArtifactFileTags.intersects(props->fileTagsFilter())) { - outputArtifact->properties = props->propertyMap(); - outputArtifactFileTags += props->extraFileTags(); - break; - } + outputArtifact->pureFileTags = fileTags; + provideFullFileTagsAndProperties(outputArtifact); + if (outputInfo.newlyCreated || outputInfo.oldFileTags != outputArtifact->fileTags()) { + for (RuleNode * const parentRule : filterByType<RuleNode>(m_ruleNode->parents)) + connect(parentRule, outputArtifact); } - outputArtifact->setFileTags(outputArtifactFileTags); - - // Let a positive value of qbs.install imply the file tag "installable". - if (outputArtifact->properties->qbsPropertyValue(StringConstants::installProperty()).toBool()) - outputArtifact->addFileTag("installable"); for (Artifact * const inputArtifact : inputArtifacts) { QBS_CHECK(outputArtifact != inputArtifact); @@ -449,7 +501,7 @@ Artifact *RulesApplicator::createOutputArtifact(const QString &filePath, const F m_transformer->outputs.insert(outputArtifact); QBS_CHECK(m_rule->multiplex || m_transformer->inputs.size() == 1); - return outputArtifact; + return outputInfo; } class RuleOutputArtifactsException : public ErrorInfo @@ -550,8 +602,11 @@ public: outputArtifact->properties = outputArtifact->properties->clone(); QVariantMap artifactCfg = outputArtifact->properties->value(); - for (const auto &e : m_propertyValues) - setConfigProperty(artifactCfg, {e.module, e.name}, e.value); + for (const auto &e : m_propertyValues) { + const QStringList key{e.module, e.name}; + setConfigProperty(artifactCfg, key, e.value); + outputArtifact->pureProperties.push_back(std::make_pair(key, e.value)); + } outputArtifact->properties->setValue(artifactCfg); } }; @@ -575,8 +630,9 @@ Artifact *RulesApplicator::createOutputArtifactFromScriptValue(const QScriptValu const QVariant alwaysUpdatedVar = obj.property(StringConstants::alwaysUpdatedProperty()).toVariant(); const bool alwaysUpdated = alwaysUpdatedVar.isValid() ? alwaysUpdatedVar.toBool() : true; - Artifact *output = createOutputArtifact(filePath, fileTags, alwaysUpdated, inputArtifacts); - if (output->fileTags().empty()) { + OutputArtifactInfo outputInfo = createOutputArtifact(filePath, fileTags, alwaysUpdated, + inputArtifacts); + if (outputInfo.artifact->fileTags().empty()) { // Check the file tags after file taggers were run. throw RuleOutputArtifactsException( Tr::tr("Property fileTags for artifact '%1' must be a non-empty string list. " @@ -588,10 +644,14 @@ Artifact *RulesApplicator::createOutputArtifactFromScriptValue(const QScriptValu .toVariant().toStringList()); for (const FileTag &tag : explicitlyDependsOn) { for (Artifact * const dependency : m_product->lookupArtifactsByFileTag(tag)) - connect(output, dependency); + connect(outputInfo.artifact, dependency); + } + ArtifactBindingsExtractor().apply(outputInfo.artifact, obj); + if (!outputInfo.newlyCreated && (outputInfo.artifact->fileTags() != outputInfo.oldFileTags + || outputInfo.artifact->properties->value() != outputInfo.oldProperties)) { + invalidateArtifactAsRuleInputIfNecessary(outputInfo.artifact); } - ArtifactBindingsExtractor().apply(output, obj); - return output; + return outputInfo.artifact; } QString RulesApplicator::resolveOutPath(const QString &path) const diff --git a/src/lib/corelib/buildgraph/rulesapplicator.h b/src/lib/corelib/buildgraph/rulesapplicator.h index adc58f3d0..f6fadb1ec 100644 --- a/src/lib/corelib/buildgraph/rulesapplicator.h +++ b/src/lib/corelib/buildgraph/rulesapplicator.h @@ -70,11 +70,16 @@ public: const NodeSet &createdArtifacts() const { return m_createdArtifacts; } const NodeSet &invalidatedArtifacts() const { return m_invalidatedArtifacts; } + QStringList removedArtifacts() const { return m_removedArtifacts; } + bool ruleUsesIo() const { return m_ruleUsesIo; } - void applyRule(const RuleConstPtr &rule, const ArtifactSet &inputArtifacts); + void applyRule(RuleNode *ruleNode, const ArtifactSet &inputArtifacts, + const ArtifactSet &explicitlyDependsOn); static void handleRemovedRuleOutputs(const ArtifactSet &inputArtifacts, - const ArtifactSet &artifactsToRemove, const Logger &logger); + const ArtifactSet &artifactsToRemove, QStringList &removedArtifacts, + const Logger &logger); static ArtifactSet collectAuxiliaryInputs(const Rule *rule, const ResolvedProduct *product); + static ArtifactSet collectExplicitlyDependsOn(const Rule *rule, const ResolvedProduct *product); enum InputsSourceFlag { CurrentProduct = 1, Dependencies = 2 }; Q_DECLARE_FLAGS(InputsSources, InputsSourceFlag) @@ -82,11 +87,17 @@ public: private: void doApply(const ArtifactSet &inputArtifacts, QScriptValue &prepareScriptContext); ArtifactSet collectOldOutputArtifacts(const ArtifactSet &inputArtifacts) const; - ArtifactSet collectExplicitlyDependsOn(); - ArtifactSet collectExplicitlyDependsOnFromDependencies(); - Artifact *createOutputArtifactFromRuleArtifact(const RuleArtifactConstPtr &ruleArtifact, - const ArtifactSet &inputArtifacts, Set<QString> *outputFilePaths); - Artifact *createOutputArtifact(const QString &filePath, const FileTags &fileTags, + + struct OutputArtifactInfo { + Artifact *artifact = nullptr; + bool newlyCreated = false; + FileTags oldFileTags; + QVariantMap oldProperties; + }; + OutputArtifactInfo createOutputArtifactFromRuleArtifact( + const RuleArtifactConstPtr &ruleArtifact, const ArtifactSet &inputArtifacts, + Set<QString> *outputFilePaths); + OutputArtifactInfo createOutputArtifact(const QString &filePath, const FileTags &fileTags, bool alwaysUpdated, const ArtifactSet &inputArtifacts); QList<Artifact *> runOutputArtifactsScript(const ArtifactSet &inputArtifacts, const QScriptValueList &args); @@ -104,14 +115,18 @@ private: const ResolvedProductPtr m_product; const std::unordered_map<QString, const ResolvedProduct *> &m_productsByName; const std::unordered_map<QString, const ResolvedProject *> &m_projectsByName; + ArtifactSet m_explicitlyDependsOn; NodeSet m_createdArtifacts; NodeSet m_invalidatedArtifacts; + QStringList m_removedArtifacts; + RuleNode *m_ruleNode = nullptr; RuleConstPtr m_rule; ArtifactSet m_completeInputSet; TransformerPtr m_transformer; TransformerConstPtr m_oldTransformer; QtMocScanner *m_mocScanner; Logger m_logger; + bool m_ruleUsesIo = false; }; Q_DECLARE_OPERATORS_FOR_FLAGS(RulesApplicator::InputsSources) diff --git a/src/lib/corelib/buildgraph/transformer.cpp b/src/lib/corelib/buildgraph/transformer.cpp index 009e8cde4..ccde486ab 100644 --- a/src/lib/corelib/buildgraph/transformer.cpp +++ b/src/lib/corelib/buildgraph/transformer.cpp @@ -41,6 +41,7 @@ #include "artifact.h" #include <jsextensions/moduleproperties.h> #include <language/language.h> +#include <language/preparescriptobserver.h> #include <language/scriptengine.h> #include <logging/translator.h> #include <tools/error.h> @@ -97,6 +98,18 @@ static QScriptValue js_baseDir(QScriptContext *ctx, QScriptEngine *engine, return basedir; } +static QScriptValue js_children(QScriptContext *ctx, QScriptEngine *engine, const Artifact *artifact) +{ + Q_UNUSED(ctx); + QScriptValue sv = engine->newArray(); + uint idx = 0; + for (const Artifact *parent : artifact->childArtifacts()) { + sv.setProperty(idx++, Transformer::translateFileConfig(static_cast<ScriptEngine *>(engine), + parent, QString())); + } + return sv; +} + static void setArtifactProperty(QScriptValue &obj, const QString &name, QScriptValue (*func)(QScriptContext *, QScriptEngine *, const Artifact *), const Artifact *artifact) @@ -117,8 +130,11 @@ QScriptValue Transformer::translateFileConfig(ScriptEngine *scriptEngine, const setArtifactProperty(obj, StringConstants::completeBaseNameProperty(), js_completeBaseName, artifact); setArtifactProperty(obj, QStringLiteral("baseDir"), js_baseDir, artifact); + setArtifactProperty(obj, QStringLiteral("children"), js_children, artifact); const QStringList fileTags = sorted(artifact->fileTags().toStringList()); - obj.setProperty(StringConstants::fileTagsProperty(), scriptEngine->toScriptValue(fileTags)); + scriptEngine->setObservedProperty(obj, StringConstants::fileTagsProperty(), + scriptEngine->toScriptValue(fileTags)); + scriptEngine->observer()->addArtifactId(obj.objectId()); if (!defaultModuleName.isEmpty()) obj.setProperty(StringConstants::moduleNameProperty(), defaultModuleName); return obj; @@ -224,7 +240,7 @@ AbstractCommandPtr Transformer::createCommandFromScriptValue(const QScriptValue if (cmdBase) cmdBase->fillFromScriptValue(&scriptValue, codeLocation); if (className == StringConstants::commandType()) { - ProcessCommand *procCmd = static_cast<ProcessCommand *>(cmdBase.get()); + auto procCmd = static_cast<ProcessCommand *>(cmdBase.get()); procCmd->clearRelevantEnvValues(); for (const QString &key : procCmd->relevantEnvVars()) procCmd->addRelevantEnvValue(key, product()->buildEnvironment.value(key)); @@ -297,9 +313,20 @@ void Transformer::rescueChangeTrackingData(const TransformerConstPtr &other) lastPrepareScriptExecutionTime = other->lastPrepareScriptExecutionTime; prepareScriptNeedsChangeTracking = other->prepareScriptNeedsChangeTracking; commandsNeedChangeTracking = other->commandsNeedChangeTracking; + markedForRerun = other->markedForRerun; exportedModulesAccessedInPrepareScript = other->exportedModulesAccessedInPrepareScript; exportedModulesAccessedInCommands = other->exportedModulesAccessedInCommands; } +Set<QString> Transformer::jobPools() const +{ + Set<QString> pools; + for (const AbstractCommandPtr &c : commands.commands()) { + if (!c->jobPool().isEmpty()) + pools.insert(c->jobPool()); + } + return pools; +} + } // namespace Internal } // namespace qbs diff --git a/src/lib/corelib/buildgraph/transformer.h b/src/lib/corelib/buildgraph/transformer.h index 1b6d36253..2f6a8e56d 100644 --- a/src/lib/corelib/buildgraph/transformer.h +++ b/src/lib/corelib/buildgraph/transformer.h @@ -89,6 +89,7 @@ public: bool alwaysRun; bool prepareScriptNeedsChangeTracking = false; bool commandsNeedChangeTracking = false; + bool markedForRerun = false; static QScriptValue translateFileConfig(ScriptEngine *scriptEngine, const Artifact *artifact, @@ -101,6 +102,8 @@ public: const QScriptValueList &args); void rescueChangeTrackingData(const TransformerConstPtr &other); + Set<QString> jobPools() const; + template<PersistentPool::OpType opType> void completeSerializationOp(PersistentPool &pool) { pool.serializationOp<opType>(rule, inputs, outputs, explicitlyDependsOn, @@ -116,7 +119,7 @@ public: exportedModulesAccessedInPrepareScript, exportedModulesAccessedInCommands, alwaysRun, prepareScriptNeedsChangeTracking, - commandsNeedChangeTracking); + commandsNeedChangeTracking, markedForRerun); } private: diff --git a/src/lib/corelib/buildgraph/transformerchangetracking.cpp b/src/lib/corelib/buildgraph/transformerchangetracking.cpp index d784ed5b7..551d2b1b1 100644 --- a/src/lib/corelib/buildgraph/transformerchangetracking.cpp +++ b/src/lib/corelib/buildgraph/transformerchangetracking.cpp @@ -124,6 +124,7 @@ QVariantMap TrafoChangeTracker::propertyMapByKind(const Property &property) cons return v; return getParameterValue(p->moduleParameters, depName); } + case Property::PropertyInArtifact: default: QBS_CHECK(false); } @@ -151,7 +152,10 @@ bool TrafoChangeTracker::checkForPropertyChange(const Property &restoredProperty while (!moduleName.empty()) map = map.value(moduleName.takeFirst()).toMap(); v = map.value(restoredProperty.propertyName); + break; } + case Property::PropertyInArtifact: + QBS_CHECK(false); } if (restoredProperty.value != v) { qCDebug(lcBuildGraph).noquote().nospace() @@ -227,7 +231,7 @@ const Artifact *TrafoChangeTracker::getArtifact(const QString &filePath, const Artifact *artifact = nullptr; for (const FileResourceBase * const candidate : candidates) { if (candidate->fileType() == FileResourceBase::FileTypeArtifact) { - const Artifact * const a = static_cast<const Artifact *>(candidate); + auto const a = static_cast<const Artifact *>(candidate); if (a->product.get() == product) { m_lastArtifact = artifact = a; break; @@ -271,6 +275,11 @@ bool TrafoChangeTracker::prepareScriptNeedsRerun() const const Artifact * const artifact = getArtifact(it.key(), property.productName); if (!artifact) return true; + if (property.kind == Property::PropertyInArtifact) { + if (sorted(artifact->fileTags().toStringList()) != property.value.toStringList()) + return true; + continue; + } if (checkForPropertyChange(property, artifact->properties->value())) return true; } @@ -302,6 +311,11 @@ bool TrafoChangeTracker::commandsNeedRerun() const const Artifact * const artifact = getArtifact(it.key(), property.productName); if (!artifact) return true; + if (property.kind == Property::PropertyInArtifact) { + if (sorted(artifact->fileTags().toStringList()) != property.value.toStringList()) + return true; + continue; + } if (checkForPropertyChange(property, artifact->properties->value())) return true; } diff --git a/src/lib/corelib/corelib.qbs b/src/lib/corelib/corelib.qbs index 93509763b..c947cb484 100644 --- a/src/lib/corelib/corelib.qbs +++ b/src/lib/corelib/corelib.qbs @@ -397,6 +397,7 @@ QbsLibrary { "id.cpp", "id.h", "iosutils.h", + "joblimits.cpp", "jsliterals.cpp", "jsliterals.h", "installoptions.cpp", @@ -467,6 +468,7 @@ QbsLibrary { "error.h", "generateoptions.h", "installoptions.h", + "joblimits.h", "preferences.h", "processresult.h", "profile.h", diff --git a/src/lib/corelib/generators/generator.h b/src/lib/corelib/generators/generator.h index f5e70f36f..8d4e4f21b 100644 --- a/src/lib/corelib/generators/generator.h +++ b/src/lib/corelib/generators/generator.h @@ -59,7 +59,7 @@ class QBS_EXPORT ProjectGenerator : public QObject Q_OBJECT Q_DISABLE_COPY(ProjectGenerator) public: - virtual ~ProjectGenerator(); + ~ProjectGenerator(); /*! * Returns the name of the generator used to create the external build system files. diff --git a/src/lib/corelib/jsextensions/binaryfile.cpp b/src/lib/corelib/jsextensions/binaryfile.cpp index eb8497e6f..a2c095dcb 100644 --- a/src/lib/corelib/jsextensions/binaryfile.cpp +++ b/src/lib/corelib/jsextensions/binaryfile.cpp @@ -115,6 +115,7 @@ QScriptValue BinaryFile::ctor(QScriptContext *context, QScriptEngine *engine) DubiousContext(EvalContext::PropertyEvaluation, DubiousContext::SuggestMoving) }; se->checkContext(QLatin1String("qbs.BinaryFile"), dubiousContexts); + se->setUsesIo(); return engine->newQObject(t, QScriptEngine::QtOwnership); } diff --git a/src/lib/corelib/jsextensions/domxml.cpp b/src/lib/corelib/jsextensions/domxml.cpp index 09acccbab..dc84fbdaf 100644 --- a/src/lib/corelib/jsextensions/domxml.cpp +++ b/src/lib/corelib/jsextensions/domxml.cpp @@ -38,6 +38,8 @@ ** ****************************************************************************/ +#include <language/scriptengine.h> + #include <QtCore/qfile.h> #include <QtCore/qobject.h> #include <QtCore/qvariant.h> @@ -132,6 +134,7 @@ QScriptValue XmlDomDocument::ctor(QScriptContext *context, QScriptEngine *engine return context->throwError(QLatin1String("DomXml(QString file = QLatin1String(\"\"))")); } QScriptValue obj = engine->newQObject(xml, QScriptEngine::ScriptOwnership); + static_cast<ScriptEngine *>(engine)->setUsesIo(); return obj; } @@ -364,7 +367,7 @@ QScriptValue XmlDomNode::nextSibling(const QString &tagName) const QScriptValue XmlDomNode::appendChild(QScriptValue newChild) { - XmlDomNode *newNode = qobject_cast<XmlDomNode*>(newChild.toQObject()); + auto newNode = qobject_cast<XmlDomNode*>(newChild.toQObject()); if (!newNode) { context()->throwError(QString::fromLatin1("First argument is not a XmlDomNode object")); return QScriptValue(); @@ -374,13 +377,13 @@ QScriptValue XmlDomNode::appendChild(QScriptValue newChild) QScriptValue XmlDomNode::insertBefore(const QScriptValue &newChild, const QScriptValue &refChild) { - XmlDomNode *newNode = qobject_cast<XmlDomNode*>(newChild.toQObject()); + auto newNode = qobject_cast<XmlDomNode*>(newChild.toQObject()); if (!newNode) { context()->throwError(QString::fromLatin1("First argument is not a XmlDomNode object")); return QScriptValue(); } - XmlDomNode *refNode = qobject_cast<XmlDomNode*>(refChild.toQObject()); + auto refNode = qobject_cast<XmlDomNode*>(refChild.toQObject()); if (!refNode) { context()->throwError(QString::fromLatin1("Second argument is not a XmlDomNode object")); return QScriptValue(); @@ -391,13 +394,13 @@ QScriptValue XmlDomNode::insertBefore(const QScriptValue &newChild, const QScrip QScriptValue XmlDomNode::insertAfter(const QScriptValue &newChild, const QScriptValue &refChild) { - XmlDomNode *newNode = qobject_cast<XmlDomNode*>(newChild.toQObject()); + auto newNode = qobject_cast<XmlDomNode*>(newChild.toQObject()); if (!newNode) { context()->throwError(QString::fromLatin1("First argument is not a XmlDomNode object")); return QScriptValue(); } - XmlDomNode *refNode = qobject_cast<XmlDomNode*>(refChild.toQObject()); + auto refNode = qobject_cast<XmlDomNode*>(refChild.toQObject()); if (!refNode) { context()->throwError(QString::fromLatin1("Second argument is not a XmlDomNode object")); return QScriptValue(); @@ -408,13 +411,13 @@ QScriptValue XmlDomNode::insertAfter(const QScriptValue &newChild, const QScript QScriptValue XmlDomNode::replaceChild(const QScriptValue &newChild, const QScriptValue &oldChild) { - XmlDomNode *newNode = qobject_cast<XmlDomNode*>(newChild.toQObject()); + auto newNode = qobject_cast<XmlDomNode*>(newChild.toQObject()); if (!newNode) { context()->throwError(QString::fromLatin1("First argument is not a XmlDomNode object")); return QScriptValue(); } - XmlDomNode *oldNode = qobject_cast<XmlDomNode*>(oldChild.toQObject()); + auto oldNode = qobject_cast<XmlDomNode*>(oldChild.toQObject()); if (!oldNode) { context()->throwError(QString::fromLatin1("Second argument is not a XmlDomNode object")); return QScriptValue(); @@ -425,7 +428,7 @@ QScriptValue XmlDomNode::replaceChild(const QScriptValue &newChild, const QScrip QScriptValue XmlDomNode::removeChild(const QScriptValue &oldChild) { - XmlDomNode *oldNode = qobject_cast<XmlDomNode*>(oldChild.toQObject()); + auto oldNode = qobject_cast<XmlDomNode*>(oldChild.toQObject()); if (!oldNode) { context()->throwError(QString::fromLatin1("First argument is not a XmlDomNode object")); return QScriptValue(); diff --git a/src/lib/corelib/jsextensions/environmentextension.cpp b/src/lib/corelib/jsextensions/environmentextension.cpp index e40831f5d..22c4f069b 100644 --- a/src/lib/corelib/jsextensions/environmentextension.cpp +++ b/src/lib/corelib/jsextensions/environmentextension.cpp @@ -72,7 +72,7 @@ static QProcessEnvironment *getProcessEnvironment(QScriptContext *context, QScri const QString &func, bool doThrow = true) { QVariant v = engine->property(StringConstants::qbsProcEnvVarInternal()); - QProcessEnvironment *procenv = reinterpret_cast<QProcessEnvironment *>(v.value<void *>()); + auto procenv = reinterpret_cast<QProcessEnvironment *>(v.value<void *>()); if (!procenv && doThrow) throw context->throwError(QScriptContext::UnknownError, QStringLiteral("%1 can only be called from ").arg(func) + diff --git a/src/lib/corelib/jsextensions/moduleproperties.cpp b/src/lib/corelib/jsextensions/moduleproperties.cpp index 7607b3dc2..4deed3fd1 100644 --- a/src/lib/corelib/jsextensions/moduleproperties.cpp +++ b/src/lib/corelib/jsextensions/moduleproperties.cpp @@ -261,7 +261,7 @@ void ModuleProperties::init(QScriptValue artifactObject, const Artifact *artifac void ModuleProperties::setModuleScriptValue(QScriptValue targetObject, const QScriptValue &moduleObject, const QString &moduleName) { - ScriptEngine * const e = static_cast<ScriptEngine *>(targetObject.engine()); + auto const e = static_cast<ScriptEngine *>(targetObject.engine()); const QualifiedId name = QualifiedId::fromString(moduleName); QScriptValue obj = targetObject; for (int i = 0; i < name.size() - 1; ++i) { diff --git a/src/lib/corelib/jsextensions/process.cpp b/src/lib/corelib/jsextensions/process.cpp index ced69a3e6..1c714fe64 100644 --- a/src/lib/corelib/jsextensions/process.cpp +++ b/src/lib/corelib/jsextensions/process.cpp @@ -135,6 +135,7 @@ QScriptValue Process::ctor(QScriptContext *context, QScriptEngine *engine) t->m_environment = QProcessEnvironment(*reinterpret_cast<QProcessEnvironment*>(v.value<void*>())); } + se->setUsesIo(); return obj; } diff --git a/src/lib/corelib/jsextensions/propertylist.mm b/src/lib/corelib/jsextensions/propertylist.mm index a7c7eb98d..75154d252 100644 --- a/src/lib/corelib/jsextensions/propertylist.mm +++ b/src/lib/corelib/jsextensions/propertylist.mm @@ -101,13 +101,13 @@ public: QScriptValue PropertyList::ctor(QScriptContext *context, QScriptEngine *engine) { - ScriptEngine * const se = static_cast<ScriptEngine *>(engine); + auto const se = static_cast<ScriptEngine *>(engine); const DubiousContextList dubiousContexts({ DubiousContext(EvalContext::PropertyEvaluation, DubiousContext::SuggestMoving) }); se->checkContext(QLatin1String("qbs.PropertyList"), dubiousContexts); - PropertyList *p = new PropertyList(context); + auto p = new PropertyList(context); QScriptValue obj = engine->newQObject(p, QScriptEngine::ScriptOwnership); return obj; } @@ -132,14 +132,14 @@ PropertyList::PropertyList(QScriptContext *context) bool PropertyList::isEmpty() const { Q_ASSERT(thisObject().engine() == engine()); - PropertyList *p = qscriptvalue_cast<PropertyList*>(thisObject()); + auto p = qscriptvalue_cast<PropertyList*>(thisObject()); return p->d->propertyListObject.isNull(); } void PropertyList::clear() { Q_ASSERT(thisObject().engine() == engine()); - PropertyList *p = qscriptvalue_cast<PropertyList*>(thisObject()); + auto p = qscriptvalue_cast<PropertyList*>(thisObject()); p->d->propertyListObject = QVariant(); p->d->propertyListFormat = 0; } @@ -147,7 +147,7 @@ void PropertyList::clear() void PropertyList::readFromObject(const QScriptValue &value) { Q_ASSERT(thisObject().engine() == engine()); - PropertyList *p = qscriptvalue_cast<PropertyList*>(thisObject()); + auto p = qscriptvalue_cast<PropertyList*>(thisObject()); p->d->propertyListObject = value.toVariant(); p->d->propertyListFormat = 0; // wasn't deserialized from any external format } @@ -160,7 +160,7 @@ void PropertyList::readFromString(const QString &input) void PropertyList::readFromFile(const QString &filePath) { Q_ASSERT(thisObject().engine() == engine()); - PropertyList *p = qscriptvalue_cast<PropertyList*>(thisObject()); + auto p = qscriptvalue_cast<PropertyList*>(thisObject()); QFile file(filePath); if (file.open(QIODevice::ReadOnly)) { @@ -177,14 +177,14 @@ void PropertyList::readFromFile(const QString &filePath) void PropertyList::readFromData(const QByteArray &data) { Q_ASSERT(thisObject().engine() == engine()); - PropertyList *p = qscriptvalue_cast<PropertyList*>(thisObject()); + auto p = qscriptvalue_cast<PropertyList*>(thisObject()); p->d->readFromData(p->context(), data); } void PropertyList::writeToFile(const QString &filePath, const QString &plistFormat) { Q_ASSERT(thisObject().engine() == engine()); - PropertyList *p = qscriptvalue_cast<PropertyList*>(thisObject()); + auto p = qscriptvalue_cast<PropertyList*>(thisObject()); QFile file(filePath); QByteArray data = p->d->writeToData(p->context(), plistFormat); @@ -200,7 +200,7 @@ void PropertyList::writeToFile(const QString &filePath, const QString &plistForm QScriptValue PropertyList::format() const { Q_ASSERT(thisObject().engine() == engine()); - PropertyList *p = qscriptvalue_cast<PropertyList*>(thisObject()); + auto p = qscriptvalue_cast<PropertyList*>(thisObject()); switch (p->d->propertyListFormat) { case QPropertyListOpenStepFormat: @@ -219,14 +219,14 @@ QScriptValue PropertyList::format() const QScriptValue PropertyList::toObject() const { Q_ASSERT(thisObject().engine() == engine()); - PropertyList *p = qscriptvalue_cast<PropertyList*>(thisObject()); + auto p = qscriptvalue_cast<PropertyList*>(thisObject()); return p->engine()->toScriptValue(p->d->propertyListObject); } QString PropertyList::toString(const QString &plistFormat) const { Q_ASSERT(thisObject().engine() == engine()); - PropertyList *p = qscriptvalue_cast<PropertyList*>(thisObject()); + auto p = qscriptvalue_cast<PropertyList*>(thisObject()); if (plistFormat == QLatin1String("binary1")) { p->context()->throwError(QLatin1String("Property list object cannot be converted to a " diff --git a/src/lib/corelib/jsextensions/textfile.cpp b/src/lib/corelib/jsextensions/textfile.cpp index e52fb9daf..0ba3c80ef 100644 --- a/src/lib/corelib/jsextensions/textfile.cpp +++ b/src/lib/corelib/jsextensions/textfile.cpp @@ -125,6 +125,7 @@ QScriptValue TextFile::ctor(QScriptContext *context, QScriptEngine *engine) DubiousContext(EvalContext::PropertyEvaluation, DubiousContext::SuggestMoving) }); se->checkContext(QLatin1String("qbs.TextFile"), dubiousContexts); + se->setUsesIo(); return engine->newQObject(t, QScriptEngine::QtOwnership); } diff --git a/src/lib/corelib/language/artifactproperties.cpp b/src/lib/corelib/language/artifactproperties.cpp index 4897c6cff..dd61bf1a2 100644 --- a/src/lib/corelib/language/artifactproperties.cpp +++ b/src/lib/corelib/language/artifactproperties.cpp @@ -57,9 +57,9 @@ FileTags ArtifactProperties::extraFileTags() const return m_extraFileTags; } -void ArtifactProperties::setExtraFileTags(const FileTags &extraFileTags) +void ArtifactProperties::addExtraFileTags(const FileTags &extraFileTags) { - m_extraFileTags = extraFileTags; + m_extraFileTags.unite(extraFileTags); } bool operator==(const ArtifactProperties &ap1, const ArtifactProperties &ap2) diff --git a/src/lib/corelib/language/artifactproperties.h b/src/lib/corelib/language/artifactproperties.h index a255950d0..856aa80c7 100644 --- a/src/lib/corelib/language/artifactproperties.h +++ b/src/lib/corelib/language/artifactproperties.h @@ -59,7 +59,7 @@ public: void setPropertyMapInternal(const PropertyMapPtr &pmap) { m_propertyMap = pmap; } FileTags extraFileTags() const; - void setExtraFileTags(const FileTags &extraFileTags); + void addExtraFileTags(const FileTags &extraFileTags); template<PersistentPool::OpType opType> void completeSerializationOp(PersistentPool &pool) { diff --git a/src/lib/corelib/language/astimportshandler.cpp b/src/lib/corelib/language/astimportshandler.cpp index f1d103718..960af4cda 100644 --- a/src/lib/corelib/language/astimportshandler.cpp +++ b/src/lib/corelib/language/astimportshandler.cpp @@ -75,14 +75,22 @@ void ASTImportsHandler::handleImports(const QbsQmlJS::AST::UiImportList *uiImpor // files in the same directory are available as prototypes collectPrototypes(m_directory, QString()); + bool baseImported = false; for (const auto *it = uiImportList; it; it = it->next) - handleImport(it->import); + handleImport(it->import, &baseImported); + if (!baseImported) { + QStringRef qbsref(&StringConstants::qbsModule()); + QbsQmlJS::AST::UiQualifiedId qbsURI(qbsref); + qbsURI.finish(); + QbsQmlJS::AST::UiImport imp(&qbsURI); + handleImport(&imp, &baseImported); + } for (auto it = m_jsImports.constBegin(); it != m_jsImports.constEnd(); ++it) m_file->addJsImport(it.value()); } -void ASTImportsHandler::handleImport(const QbsQmlJS::AST::UiImport *import) +void ASTImportsHandler::handleImport(const QbsQmlJS::AST::UiImport *import, bool *baseImported) { QStringList importUri; bool isBase = false; @@ -92,6 +100,7 @@ void ASTImportsHandler::handleImport(const QbsQmlJS::AST::UiImport *import) || (importUri.size() == 2 && importUri.front() == StringConstants::qbsModule() && importUri.last() == StringConstants::baseVar()); if (isBase) { + *baseImported = true; checkImportVersion(import->versionToken); } else if (import->versionToken.length) { m_logger.printWarning(ErrorInfo(Tr::tr("Superfluous version specification."), diff --git a/src/lib/corelib/language/astimportshandler.h b/src/lib/corelib/language/astimportshandler.h index b69a8fab7..e9c2b6c27 100644 --- a/src/lib/corelib/language/astimportshandler.h +++ b/src/lib/corelib/language/astimportshandler.h @@ -75,7 +75,7 @@ private: void collectPrototypes(const QString &path, const QString &as); void collectPrototypesAndJsCollections(const QString &path, const QString &as, const CodeLocation &location); - void handleImport(const QbsQmlJS::AST::UiImport *import); + void handleImport(const QbsQmlJS::AST::UiImport *import, bool *baseImported); ItemReaderVisitorState &m_visitorState; Logger &m_logger; diff --git a/src/lib/corelib/language/builtindeclarations.cpp b/src/lib/corelib/language/builtindeclarations.cpp index 4be405112..4886675d0 100644 --- a/src/lib/corelib/language/builtindeclarations.cpp +++ b/src/lib/corelib/language/builtindeclarations.cpp @@ -67,6 +67,7 @@ BuiltinDeclarations::BuiltinDeclarations() { QLatin1String("Export"), ItemType::Export }, { QLatin1String("FileTagger"), ItemType::FileTagger }, { QLatin1String("Group"), ItemType::Group }, + { QLatin1String("JobLimit"), ItemType::JobLimit }, { QLatin1String("Module"), ItemType::Module }, { QLatin1String("Parameter"), ItemType::Parameter }, { QLatin1String("Parameters"), ItemType::Parameters }, @@ -87,6 +88,7 @@ BuiltinDeclarations::BuiltinDeclarations() addExportItem(); addFileTaggerItem(); addGroupItem(); + addJobLimitItem(); addModuleItem(); addProbeItem(); addProductItem(); @@ -298,6 +300,15 @@ void BuiltinDeclarations::addGroupItem() insert(item); } +void BuiltinDeclarations::addJobLimitItem() +{ + ItemDeclaration item(ItemType::JobLimit); + item << conditionProperty(); + item << PropertyDeclaration(StringConstants::jobPoolProperty(), PropertyDeclaration::String); + item << PropertyDeclaration(StringConstants::jobCountProperty(), PropertyDeclaration::Integer); + insert(item); +} + void BuiltinDeclarations::addModuleItem() { ItemDeclaration item = moduleLikeItem(ItemType::Module); @@ -312,6 +323,7 @@ ItemDeclaration BuiltinDeclarations::moduleLikeItem(ItemType type) << ItemType::Group << ItemType::Depends << ItemType::FileTagger + << ItemType::JobLimit << ItemType::Rule << ItemType::Parameter << ItemType::Probe @@ -360,6 +372,7 @@ void BuiltinDeclarations::addProductItem() << ItemType::Depends << ItemType::Group << ItemType::FileTagger + << ItemType::JobLimit << ItemType::Export << ItemType::Probe << ItemType::Profile @@ -429,6 +442,7 @@ void BuiltinDeclarations::addProjectItem() << ItemType::Profile << ItemType::Probe << ItemType::FileTagger + << ItemType::JobLimit << ItemType::Rule); item << nameProperty(); item << conditionProperty(); diff --git a/src/lib/corelib/language/builtindeclarations.h b/src/lib/corelib/language/builtindeclarations.h index c75475df7..ff16b395a 100644 --- a/src/lib/corelib/language/builtindeclarations.h +++ b/src/lib/corelib/language/builtindeclarations.h @@ -76,6 +76,7 @@ private: void addExportItem(); void addFileTaggerItem(); void addGroupItem(); + void addJobLimitItem(); void addModuleItem(); static ItemDeclaration moduleLikeItem(ItemType type); void addProbeItem(); diff --git a/src/lib/corelib/language/evaluator.cpp b/src/lib/corelib/language/evaluator.cpp index e02720e3a..c4b747a0c 100644 --- a/src/lib/corelib/language/evaluator.cpp +++ b/src/lib/corelib/language/evaluator.cpp @@ -175,7 +175,7 @@ QScriptValue Evaluator::scriptValue(const Item *item) void Evaluator::onItemPropertyChanged(Item *item) { - EvaluationData *data = attachedPointer<EvaluationData>(m_scriptValueMap.value(item)); + auto data = attachedPointer<EvaluationData>(m_scriptValueMap.value(item)); if (data) data->valueCache.clear(); } diff --git a/src/lib/corelib/language/evaluator.h b/src/lib/corelib/language/evaluator.h index 0fd4003d8..d8931a37e 100644 --- a/src/lib/corelib/language/evaluator.h +++ b/src/lib/corelib/language/evaluator.h @@ -69,14 +69,15 @@ public: ScriptEngine *engine() const { return m_scriptEngine; } QScriptValue property(const Item *item, const QString &name); - QScriptValue value(const Item *item, const QString &name, bool *propertySet = 0); + QScriptValue value(const Item *item, const QString &name, bool *propertySet = nullptr); bool boolValue(const Item *item, const QString &name, bool *propertyWasSet = nullptr); int intValue(const Item *item, const QString &name, int defaultValue = 0, - bool *propertyWasSet = 0); - FileTags fileTagsValue(const Item *item, const QString &name, bool *propertySet = 0); + bool *propertyWasSet = nullptr); + FileTags fileTagsValue(const Item *item, const QString &name, bool *propertySet = nullptr); QString stringValue(const Item *item, const QString &name, - const QString &defaultValue = QString(), bool *propertyWasSet = 0); - QStringList stringListValue(const Item *item, const QString &name, bool *propertyWasSet = 0); + const QString &defaultValue = QString(), bool *propertyWasSet = nullptr); + QStringList stringListValue(const Item *item, const QString &name, + bool *propertyWasSet = nullptr); void convertToPropertyType(const PropertyDeclaration& decl, const CodeLocation &loc, QScriptValue &v); @@ -104,7 +105,7 @@ public: bool isNonDefaultValue(const Item *item, const QString &name) const; private: - void onItemPropertyChanged(Item *item); + void onItemPropertyChanged(Item *item) override; bool evaluateProperty(QScriptValue *result, const Item *item, const QString &name, bool *propertyWasSet); diff --git a/src/lib/corelib/language/evaluatorscriptclass.cpp b/src/lib/corelib/language/evaluatorscriptclass.cpp index 6db308a7f..a5e23a131 100644 --- a/src/lib/corelib/language/evaluatorscriptclass.cpp +++ b/src/lib/corelib/language/evaluatorscriptclass.cpp @@ -381,7 +381,7 @@ QScriptClass::QueryFlags EvaluatorScriptClass::queryProperty(const QScriptValue if (debugProperties) qDebug() << "[SC] queryProperty " << object.objectId() << " " << name; - EvaluationData *const data = attachedPointer<EvaluationData>(object); + auto const data = attachedPointer<EvaluationData>(object); const QString nameString = name.toString(); if (nameString == QStringLiteral("parent")) { *id = QPTParentProperty; @@ -751,7 +751,7 @@ private: QScriptClassPropertyIterator *EvaluatorScriptClass::newIterator(const QScriptValue &object) { - EvaluationData *const data = attachedPointer<EvaluationData>(object); + auto const data = attachedPointer<EvaluationData>(object); return data ? new EvaluatorScriptClassPropertyIterator(object, data) : nullptr; } diff --git a/src/lib/corelib/language/identifiersearch.h b/src/lib/corelib/language/identifiersearch.h index e466c576a..d9769266c 100644 --- a/src/lib/corelib/language/identifiersearch.h +++ b/src/lib/corelib/language/identifiersearch.h @@ -57,8 +57,8 @@ public: void add(const QString &name, bool *found); private: - bool preVisit(QbsQmlJS::AST::Node *); - bool visit(QbsQmlJS::AST::IdentifierExpression *e); + bool preVisit(QbsQmlJS::AST::Node *) override; + bool visit(QbsQmlJS::AST::IdentifierExpression *e) override; QMap<QString, bool *> m_requests; int m_numberOfFoundIds; diff --git a/src/lib/corelib/language/item.h b/src/lib/corelib/language/item.h index 6756e576d..2dafaa774 100644 --- a/src/lib/corelib/language/item.h +++ b/src/lib/corelib/language/item.h @@ -97,7 +97,7 @@ public: Item *outerItem() const { return m_outerItem; } Item *parent() const { return m_parent; } const FileContextPtr &file() const { return m_file; } - QList<Item *> children() const { return m_children; } + const QList<Item *> &children() const { return m_children; } Item *child(ItemType type, bool checkForMultiple = true) const; const PropertyMap &properties() const { return m_properties; } const PropertyDeclarationMap &propertyDeclarations() const { return m_propertyDeclarations; } @@ -134,6 +134,7 @@ public: void setOuterItem(Item *item) { m_outerItem = item; } void setChildren(const QList<Item *> &children) { m_children = children; } void setParent(Item *item) { m_parent = item; } + void childrenReserve(int size) { m_children.reserve(size); } static void addChild(Item *parent, Item *child); static void removeChild(Item *parent, Item *child); void dump() const; diff --git a/src/lib/corelib/language/itemreaderastvisitor.cpp b/src/lib/corelib/language/itemreaderastvisitor.cpp index 5b042ffb4..2ea306138 100644 --- a/src/lib/corelib/language/itemreaderastvisitor.cpp +++ b/src/lib/corelib/language/itemreaderastvisitor.cpp @@ -75,12 +75,12 @@ ItemReaderASTVisitor::ItemReaderASTVisitor(ItemReaderVisitorState &visitorState, { } -bool ItemReaderASTVisitor::visit(AST::UiImportList *uiImportList) +bool ItemReaderASTVisitor::visit(AST::UiProgram *uiProgram) { ASTImportsHandler importsHandler(m_visitorState, m_logger, m_file); - importsHandler.handleImports(uiImportList); + importsHandler.handleImports(uiProgram->imports); m_typeNameToFile = importsHandler.typeNameFileMap(); - return false; + return true; } static ItemValuePtr findItemProperty(const Item *container, const Item *item) diff --git a/src/lib/corelib/language/itemreaderastvisitor.h b/src/lib/corelib/language/itemreaderastvisitor.h index 6bd39ceb2..4a0bedc91 100644 --- a/src/lib/corelib/language/itemreaderastvisitor.h +++ b/src/lib/corelib/language/itemreaderastvisitor.h @@ -67,7 +67,7 @@ public: Item *rootItem() const { return m_item; } private: - bool visit(QbsQmlJS::AST::UiImportList *uiImportList) override; + bool visit(QbsQmlJS::AST::UiProgram *uiProgram) override; bool visit(QbsQmlJS::AST::UiObjectDefinition *ast) override; bool visit(QbsQmlJS::AST::UiPublicMember *ast) override; bool visit(QbsQmlJS::AST::UiScriptBinding *ast) override; diff --git a/src/lib/corelib/language/itemtype.h b/src/lib/corelib/language/itemtype.h index c0e76c94b..324a1fb87 100644 --- a/src/lib/corelib/language/itemtype.h +++ b/src/lib/corelib/language/itemtype.h @@ -53,6 +53,7 @@ enum class ItemType { Export, FileTagger, Group, + JobLimit, Module, Parameter, Parameters, diff --git a/src/lib/corelib/language/language.cpp b/src/lib/corelib/language/language.cpp index 5351ba80c..d8a5d9162 100644 --- a/src/lib/corelib/language/language.cpp +++ b/src/lib/corelib/language/language.cpp @@ -279,12 +279,6 @@ QString Rule::toString() const + inputTagsSorted.join(QLatin1Char(',')) + QLatin1Char(']'); } -bool Rule::acceptsAsInput(Artifact *artifact) const -{ - return artifact->fileTags().intersects(inputs) - && !artifact->fileTags().intersects(excludedInputs); -} - FileTags Rule::staticOutputFileTags() const { FileTags result; @@ -394,36 +388,6 @@ void ResolvedProduct::store(PersistentPool &pool) serializationOp<PersistentPool::Store>(pool); } -void ResolvedProduct::registerArtifactWithChangedInputs(Artifact *artifact) -{ - QBS_CHECK(buildData); - QBS_CHECK(artifact->product == this); - QBS_CHECK(artifact->transformer); - if (artifact->transformer->rule->multiplex) { - // Reapplication of rules only makes sense for multiplex rules (e.g. linker). - buildData->addArtifactWithChangedInputsForRule(artifact->transformer->rule, artifact); - } -} - -void ResolvedProduct::unregisterArtifactWithChangedInputs(Artifact *artifact) -{ - QBS_CHECK(buildData); - QBS_CHECK(artifact->product == this); - QBS_CHECK(artifact->transformer); - buildData->removeArtifactWithChangedInputsForRule(artifact->transformer->rule, artifact); -} - -void ResolvedProduct::unmarkForReapplication(const RuleConstPtr &rule) -{ - QBS_CHECK(buildData); - buildData->removeAllArtifactsWithChangedInputsForRule(rule); -} - -bool ResolvedProduct::isMarkedForReapplication(const RuleConstPtr &rule) const -{ - return buildData->ruleHasArtifactWithChangedInputs(rule); -} - ArtifactSet ResolvedProduct::lookupArtifactsByFileTag(const FileTag &tag) const { QBS_CHECK(buildData); @@ -444,8 +408,8 @@ ArtifactSet ResolvedProduct::targetArtifacts() const QBS_CHECK(buildData); ArtifactSet taSet; for (Artifact * const a : buildData->rootArtifacts()) { - if (a->fileTags().intersects(fileTags)) - taSet << a; + QBS_CHECK(a->fileTags().intersects(fileTags)); + taSet << a; } return taSet; } @@ -879,12 +843,6 @@ bool operator==(const SourceArtifactInternal &sa1, const SourceArtifactInternal && *sa1.properties == *sa2.properties; } -bool sourceArtifactSetsAreEqual(const std::vector<SourceArtifactPtr> &l1, - const std::vector<SourceArtifactPtr> &l2) -{ - return listsAreEqual(l1, l2); -} - bool operator==(const Rule &r1, const Rule &r2) { if (r1.artifacts.size() != r2.artifacts.size()) diff --git a/src/lib/corelib/language/language.h b/src/lib/corelib/language/language.h index 571681241..f9d69efff 100644 --- a/src/lib/corelib/language/language.h +++ b/src/lib/corelib/language/language.h @@ -49,6 +49,7 @@ #include <buildgraph/forward_decls.h> #include <tools/codelocation.h> #include <tools/filetime.h> +#include <tools/joblimits.h> #include <tools/persistence.h> #include <tools/set.h> #include <tools/weakpointer.h> @@ -245,9 +246,6 @@ inline bool operator!=(const SourceArtifactInternal &sa1, const SourceArtifactIn return !(sa1 == sa2); } -bool sourceArtifactSetsAreEqual(const std::vector<SourceArtifactPtr> &l1, - const std::vector<SourceArtifactPtr> &l2); - class SourceWildCards { public: @@ -427,7 +425,6 @@ public: static QStringList argumentNamesForPrepare(); QString toString() const; - bool acceptsAsInput(Artifact *artifact) const; FileTags staticOutputFileTags() const; FileTags collectedOutputFileTags() const; bool isDynamic() const; @@ -575,6 +572,7 @@ public: std::vector<ResolvedProductPtr> dependencies; QHash<ResolvedProductConstPtr, QVariantMap> dependencyParameters; std::vector<FileTaggerConstPtr> fileTaggers; + JobLimits jobLimits; std::vector<ResolvedModulePtr> modules; QHash<ResolvedModuleConstPtr, QVariantMap> moduleParameters; std::vector<ResolvedScannerConstPtr> scanners; @@ -594,10 +592,6 @@ public: std::vector<SourceArtifactPtr> allEnabledFiles() const; FileTags fileTagsForFileName(const QString &fileName) const; - void registerArtifactWithChangedInputs(Artifact *artifact); - void unregisterArtifactWithChangedInputs(Artifact *artifact); - void unmarkForReapplication(const RuleConstPtr &rule); - bool isMarkedForReapplication(const RuleConstPtr &rule) const; ArtifactSet lookupArtifactsByFileTag(const FileTag &tag) const; ArtifactSet lookupArtifactsByFileTags(const FileTags &tags) const; ArtifactSet targetArtifacts() const; @@ -636,7 +630,8 @@ private: missingSourceFiles, location, productProperties, moduleProperties, rules, dependencies, dependencyParameters, fileTaggers, modules, moduleParameters, scanners, groups, - artifactProperties, probes, exportedModule, buildData); + artifactProperties, probes, exportedModule, buildData, + jobLimits); } QHash<QString, QString> m_executablePathCache; diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp index 583354c4d..ff5fd2f84 100644 --- a/src/lib/corelib/language/moduleloader.cpp +++ b/src/lib/corelib/language/moduleloader.cpp @@ -166,7 +166,7 @@ public: for (ProductContext * const rootProduct : rootProducts) traverse(rootProduct); if (m_sortedProducts.size() < allProducts.size()) { - for (auto * const product : qAsConst(allProducts)) { + for (auto const product : qAsConst(allProducts)) { QList<ModuleLoader::ProductContext *> path; findCycle(product, path); } @@ -175,7 +175,7 @@ public: } // No product at position i has dependencies to a product at position j > i. - QList<ProductContext *> sortedProducts() + const QList<ProductContext *> &sortedProducts() const { return m_sortedProducts; } @@ -201,7 +201,7 @@ private: throw error; } path << product; - for (auto * const dep : m_dependencyMap.value(product)) + for (auto const dep : m_dependencyMap.value(product)) findCycle(dep, path); path.removeLast(); } @@ -3370,6 +3370,8 @@ void ModuleLoader::instantiateModule(ProductContext *productContext, Item *expor void ModuleLoader::createChildInstances(Item *instance, Item *prototype, QHash<Item *, Item *> *prototypeInstanceMap) const { + instance->childrenReserve(instance->children().size() + prototype->children().size()); + for (Item * const childPrototype : prototype->children()) { Item *childInstance = Item::create(m_pool, childPrototype->type()); prototypeInstanceMap->insert(childPrototype, childInstance); @@ -3867,8 +3869,7 @@ void ModuleLoader::copyGroupsFromModuleToProduct(const ProductContext &productCo const Item::Module &module, const Item *modulePrototype) { - const auto children = modulePrototype->children(); - for (Item * const child : children) { + for (Item * const child : modulePrototype->children()) { if (child->type() == ItemType::Group) { Item * const clonedGroup = child->clone(); clonedGroup->setScope(productContext.scope); diff --git a/src/lib/corelib/language/moduleloader.h b/src/lib/corelib/language/moduleloader.h index 7be9a0fcc..7b9e0bede 100644 --- a/src/lib/corelib/language/moduleloader.h +++ b/src/lib/corelib/language/moduleloader.h @@ -324,7 +324,7 @@ private: void resolveProbe(ProductContext *productContext, Item *parent, Item *probe); void checkCancelation() const; bool checkItemCondition(Item *item, Item *itemToDisable = nullptr); - QStringList readExtraSearchPaths(Item *item, bool *wasSet = 0); + QStringList readExtraSearchPaths(Item *item, bool *wasSet = nullptr); void copyProperties(const Item *sourceProject, Item *targetProject); Item *wrapInProjectIfNecessary(Item *item); static QString findExistingModulePath(const QString &searchPath, diff --git a/src/lib/corelib/language/preparescriptobserver.cpp b/src/lib/corelib/language/preparescriptobserver.cpp index eca0ccf29..632cbfb51 100644 --- a/src/lib/corelib/language/preparescriptobserver.cpp +++ b/src/lib/corelib/language/preparescriptobserver.cpp @@ -42,7 +42,11 @@ #include "property.h" #include "scriptengine.h" +#include <buildgraph/artifact.h> +#include <language/language.h> +#include <tools/scripttools.h> #include <tools/stlutils.h> +#include <tools/stringconstants.h> #include <QtScript/qscriptvalue.h> @@ -80,6 +84,13 @@ void PrepareScriptObserver::onPropertyRead(const QScriptValue &object, const QSt Property(it->second.first, it->second.second, name, value.toVariant(), Property::PropertyInParameters)); } + if (name == StringConstants::fileTagsProperty() && m_artifactIds.contains(objectId)) { + const Artifact * const artifact = attachedPointer<Artifact>(object); + QBS_CHECK(artifact); + const Property p(artifact->product->uniqueName(), QString(), name, value.toVariant(), + Property::PropertyInArtifact); + engine()->addPropertyRequestedFromArtifact(artifact, p); + } } } // namespace Internal diff --git a/src/lib/corelib/language/preparescriptobserver.h b/src/lib/corelib/language/preparescriptobserver.h index e70652eb4..36e395efc 100644 --- a/src/lib/corelib/language/preparescriptobserver.h +++ b/src/lib/corelib/language/preparescriptobserver.h @@ -68,6 +68,7 @@ public: m_exportsObjectIds.insert(std::make_pair(exportsId, product)); } + void addArtifactId(qint64 artifactId) { m_artifactIds.insert(artifactId); } bool addImportId(qint64 importId) { return m_importIds.insert(importId).second; } void clearImportIds() { m_importIds.clear(); } void addParameterObjectId(qint64 id, const QString &productName, const QString &depName, @@ -79,12 +80,14 @@ public: } private: - void onPropertyRead(const QScriptValue &object, const QString &name, const QScriptValue &value); + void onPropertyRead(const QScriptValue &object, const QString &name, + const QScriptValue &value) override; std::unordered_map<qint64, QString> m_projectObjectIds; std::unordered_map<qint64, std::pair<QString, QString>> m_parameterObjects; std::unordered_map<qint64, const ResolvedProduct *> m_exportsObjectIds; Set<qint64> m_importIds; + Set<qint64> m_artifactIds; }; } // namespace Internal diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp index cf0e6b706..7deb964b3 100644 --- a/src/lib/corelib/language/projectresolver.cpp +++ b/src/lib/corelib/language/projectresolver.cpp @@ -56,6 +56,7 @@ #include <logging/translator.h> #include <tools/error.h> #include <tools/fileinfo.h> +#include <tools/joblimits.h> #include <tools/jsliterals.h> #include <tools/profiling.h> #include <tools/progressobserver.h> @@ -89,6 +90,7 @@ struct ProjectResolver::ProjectContext ResolvedProjectPtr project; std::vector<FileTaggerConstPtr> fileTaggers; std::vector<RulePtr> rules; + JobLimits jobLimits; ResolvedModulePtr dummyModule; }; @@ -97,7 +99,7 @@ struct ProjectResolver::ProductContext ResolvedProductPtr product; QString buildDirectory; Item *item; - typedef std::pair<ArtifactPropertiesPtr, CodeLocation> ArtifactPropertiesInfo; + typedef std::pair<ArtifactPropertiesPtr, std::vector<CodeLocation>> ArtifactPropertiesInfo; QHash<QStringList, ArtifactPropertiesInfo> artifactPropertiesPerFilter; ProjectResolver::FileLocations sourceArtifactLocations; GroupConstPtr currentGroup; @@ -106,6 +108,7 @@ struct ProjectResolver::ProductContext struct ProjectResolver::ModuleContext { ResolvedModulePtr module; + JobLimits jobLimits; }; class CancelException { }; @@ -333,6 +336,7 @@ void ProjectResolver::resolveProjectFully(Item *item, ProjectResolver::ProjectCo { ItemType::Product, &ProjectResolver::resolveProduct }, { ItemType::Probe, &ProjectResolver::ignoreItem }, { ItemType::FileTagger, &ProjectResolver::resolveFileTagger }, + { ItemType::JobLimit, &ProjectResolver::resolveJobLimit }, { ItemType::Rule, &ProjectResolver::resolveRule }, { ItemType::PropertyOptions, &ProjectResolver::ignoreItem } }; @@ -494,6 +498,7 @@ void ProjectResolver::resolveProductFully(Item *item, ProjectContext *projectCon { ItemType::Depends, &ProjectResolver::ignoreItem }, { ItemType::Rule, &ProjectResolver::resolveRule }, { ItemType::FileTagger, &ProjectResolver::resolveFileTagger }, + { ItemType::JobLimit, &ProjectResolver::resolveJobLimit }, { ItemType::Group, &ProjectResolver::resolveGroup }, { ItemType::Product, &ProjectResolver::resolveShadowProduct }, { ItemType::Export, &ProjectResolver::resolveExport }, @@ -504,6 +509,11 @@ void ProjectResolver::resolveProductFully(Item *item, ProjectContext *projectCon for (Item * const child : qAsConst(subItems)) callItemFunction(mapping, child, projectContext); + for (const ProjectContext *p = projectContext; p; p = p->parentContext) { + JobLimits tempLimits = p->jobLimits; + product->jobLimits = tempLimits.update(product->jobLimits); + } + resolveModules(item, projectContext); for (const FileTag &t : qAsConst(product->fileTags)) @@ -512,12 +522,19 @@ void ProjectResolver::resolveProductFully(Item *item, ProjectContext *projectCon void ProjectResolver::resolveModules(const Item *item, ProjectContext *projectContext) { + JobLimits jobLimits; for (const Item::Module &m : item->modules()) - resolveModule(m.name, m.item, m.isProduct, m.parameters, projectContext); + resolveModule(m.name, m.item, m.isProduct, m.parameters, jobLimits, projectContext); + for (int i = 0; i < jobLimits.count(); ++i) { + const JobLimit &moduleJobLimit = jobLimits.jobLimitAt(i); + if (m_productContext->product->jobLimits.getLimit(moduleJobLimit.pool()) == -1) + m_productContext->product->jobLimits.setJobLimit(moduleJobLimit); + } } void ProjectResolver::resolveModule(const QualifiedId &moduleName, Item *item, bool isProduct, - const QVariantMap ¶meters, ProjectContext *projectContext) + const QVariantMap ¶meters, JobLimits &jobLimits, + ProjectContext *projectContext) { checkCancelation(); if (!item->isPresentModule()) @@ -550,6 +567,7 @@ void ProjectResolver::resolveModule(const QualifiedId &moduleName, Item *item, b { ItemType::Group, &ProjectResolver::ignoreItem }, { ItemType::Rule, &ProjectResolver::resolveRule }, { ItemType::FileTagger, &ProjectResolver::resolveFileTagger }, + { ItemType::JobLimit, &ProjectResolver::resolveJobLimit }, { ItemType::Scanner, &ProjectResolver::resolveScanner }, { ItemType::PropertyOptions, &ProjectResolver::ignoreItem }, { ItemType::Depends, &ProjectResolver::ignoreItem }, @@ -559,6 +577,12 @@ void ProjectResolver::resolveModule(const QualifiedId &moduleName, Item *item, b }; for (Item *child : item->children()) callItemFunction(mapping, child, projectContext); + for (int i = 0; i < moduleContext.jobLimits.count(); ++i) { + const JobLimit &newJobLimit = moduleContext.jobLimits.jobLimitAt(i); + const int oldLimit = jobLimits.getLimit(newJobLimit.pool()); + if (oldLimit == -1 || oldLimit > newJobLimit.limit()) + jobLimits.setJobLimit(newJobLimit); + } m_moduleContext = oldModuleContext; } @@ -692,19 +716,30 @@ void ProjectResolver::resolveGroup(Item *item, ProjectContext *projectContext) void ProjectResolver::resolveGroupFully(Item *item, ProjectResolver::ProjectContext *projectContext, bool isEnabled) { - PropertyMapPtr moduleProperties = m_productContext->currentGroup - ? m_productContext->currentGroup->properties - : m_productContext->product->moduleProperties; - const QVariantMap newModuleProperties - = resolveAdditionalModuleProperties(item, moduleProperties->value()); - if (!newModuleProperties.empty()) { - moduleProperties = PropertyMapInternal::create(); - moduleProperties->setValue(newModuleProperties); - } - AccumulatingTimer groupTimer(m_setupParams.logElapsedTime() ? &m_elapsedTimeGroups : nullptr); + const auto getGroupPropertyMap = [this, item](const ArtifactProperties *existingProps) { + PropertyMapPtr moduleProperties; + bool newPropertyMapRequired = false; + if (existingProps) + moduleProperties = existingProps->propertyMap(); + if (!moduleProperties) { + newPropertyMapRequired = true; + moduleProperties = m_productContext->currentGroup + ? m_productContext->currentGroup->properties + : m_productContext->product->moduleProperties; + } + const QVariantMap newModuleProperties + = resolveAdditionalModuleProperties(item, moduleProperties->value()); + if (!newModuleProperties.empty()) { + if (newPropertyMapRequired) + moduleProperties = PropertyMapInternal::create(); + moduleProperties->setValue(newModuleProperties); + } + return moduleProperties; + }; + QStringList files = m_evaluator->stringListValue(item, StringConstants::filesProperty()); bool fileTagsSet; const FileTags fileTags = m_evaluator->fileTagsValue(item, StringConstants::fileTagsProperty(), @@ -716,28 +751,30 @@ void ProjectResolver::resolveGroupFully(Item *item, ProjectResolver::ProjectCont throw ErrorInfo(Tr::tr("Group.files and Group.fileTagsFilters are exclusive."), item->location()); - ProductContext::ArtifactPropertiesInfo apinfo - = m_productContext->artifactPropertiesPerFilter.value(fileTagsFilter); + if (!isEnabled) + return; + + ProductContext::ArtifactPropertiesInfo &apinfo + = m_productContext->artifactPropertiesPerFilter[fileTagsFilter]; if (apinfo.first) { - if (apinfo.second.filePath() == item->location().filePath()) { + const auto it = std::find_if(apinfo.second.cbegin(), apinfo.second.cend(), + [item](const CodeLocation &loc) { + return item->location().filePath() == loc.filePath(); + }); + if (it != apinfo.second.cend()) { ErrorInfo error(Tr::tr("Conflicting fileTagsFilter in Group items.")); - error.append(Tr::tr("First item"), apinfo.second); + error.append(Tr::tr("First item"), *it); error.append(Tr::tr("Second item"), item->location()); throw error; } - - // Discard any Group with the same fileTagsFilter that was defined in a base file. - removeAll(m_productContext->product->artifactProperties, apinfo.first); + } else { + apinfo.first = ArtifactProperties::create(); + apinfo.first->setFileTagsFilter(FileTags::fromStringList(fileTagsFilter)); + m_productContext->product->artifactProperties.push_back(apinfo.first); } - if (!isEnabled) - return; - ArtifactPropertiesPtr aprops = ArtifactProperties::create(); - aprops->setFileTagsFilter(FileTags::fromStringList(fileTagsFilter)); - aprops->setExtraFileTags(fileTags); - aprops->setPropertyMapInternal(moduleProperties); - m_productContext->product->artifactProperties.push_back(aprops); - m_productContext->artifactPropertiesPerFilter.insert(fileTagsFilter, - ProductContext::ArtifactPropertiesInfo(aprops, item->location())); + apinfo.second.push_back(item->location()); + apinfo.first->setPropertyMapInternal(getGroupPropertyMap(apinfo.first.get())); + apinfo.first->addExtraFileTags(fileTags); return; } QStringList patterns; @@ -757,7 +794,7 @@ void ProjectResolver::resolveGroupFully(Item *item, ProjectResolver::ProjectCont } group->location = item->location(); group->enabled = isEnabled; - group->properties = moduleProperties; + group->properties = getGroupPropertyMap(nullptr); group->fileTags = fileTags; group->overrideTags = m_evaluator->boolValue(item, StringConstants::overrideTagsProperty()); if (group->overrideTags && fileTagsSet) { @@ -822,19 +859,26 @@ void ProjectResolver::resolveGroupFully(Item *item, ProjectResolver::ProjectCont resolveGroup(childItem, projectContext); } -void ProjectResolver::adaptExportedPropertyValues() +void ProjectResolver::adaptExportedPropertyValues(const Item *shadowProductItem) { ExportedModule &m = m_productContext->product->exportedModule; const QVariantList prefixList = m.propertyValues.take( StringConstants::prefixMappingProperty()).toList(); - if (prefixList.empty()) - return; + const QString shadowProductName = m_evaluator->stringValue( + shadowProductItem, StringConstants::nameProperty()); + const QString shadowProductBuildDir = m_evaluator->stringValue( + shadowProductItem, StringConstants::buildDirectoryProperty()); QVariantMap prefixMap; for (const QVariant &v : prefixList) { const QVariantMap o = v.toMap(); prefixMap.insert(o.value(QLatin1String("prefix")).toString(), o.value(QLatin1String("replacement")).toString()); } + const auto valueRefersToImportingProduct + = [shadowProductName, shadowProductBuildDir](const QString &value) { + return value.toLower().contains(shadowProductName.toLower()) + || value.contains(shadowProductBuildDir); + }; static const auto stringMapper = [](const QVariantMap &mappings, const QString &value) -> QString { for (auto it = mappings.cbegin(); it != mappings.cend(); ++it) { @@ -843,17 +887,19 @@ void ProjectResolver::adaptExportedPropertyValues() } return value; }; - static const auto stringListMapper = [](const QVariantMap &mappings, const QStringList &value) - -> QStringList { + const auto stringListMapper = [&valueRefersToImportingProduct]( + const QVariantMap &mappings, const QStringList &value) -> QStringList { QStringList result; result.reserve(value.size()); for (const QString &s : value) { - result.push_back(stringMapper(mappings, s)); + if (!valueRefersToImportingProduct(s)) + result.push_back(stringMapper(mappings, s)); } return result; }; - static const std::function<QVariant(const QVariantMap &, const QVariant &)> mapper - = [](const QVariantMap &mappings, const QVariant &value) -> QVariant { + const std::function<QVariant(const QVariantMap &, const QVariant &)> mapper + = [&stringListMapper, &mapper]( + const QVariantMap &mappings, const QVariant &value) -> QVariant { switch (static_cast<QMetaType::Type>(value.type())) { case QMetaType::QString: return stringMapper(mappings, value.toString()); @@ -938,7 +984,9 @@ void ProjectResolver::resolveShadowProduct(Item *item, ProjectResolver::ProjectC collectPropertiesForModuleInExportItem(dep); break; } - adaptExportedPropertyValues(); + try { + adaptExportedPropertyValues(item); + } catch (const ErrorInfo &) {} m_productExportInfo.push_back(std::make_pair(m_productContext->product, item)); } @@ -1162,19 +1210,18 @@ void ProjectResolver::resolveRule(Item *item, ProjectContext *projectContext) rule->prepareScript.initialize(scriptFunctionValue(item, StringConstants::prepareProperty())); rule->outputArtifactsScript.initialize(scriptFunctionValue( item, StringConstants::outputArtifactsProperty())); + rule->outputFileTags = m_evaluator->fileTagsValue( + item, StringConstants::outputFileTagsProperty()); if (rule->outputArtifactsScript.isValid()) { if (hasArtifactChildren) throw ErrorInfo(Tr::tr("The Rule.outputArtifacts script is not allowed in rules " "that contain Artifact items."), item->location()); - rule->outputFileTags = m_evaluator->fileTagsValue( - item, StringConstants::outputFileTagsProperty()); - if (rule->outputFileTags.empty()) - throw ErrorInfo(Tr::tr("Rule.outputFileTags must be specified if " - "Rule.outputArtifacts is specified."), - item->location()); } - + if (!hasArtifactChildren && rule->outputFileTags.empty()) { + throw ErrorInfo(Tr::tr("A rule needs to have Artifact items or a non-empty " + "outputFileTags property."), item->location()); + } rule->multiplex = m_evaluator->boolValue(item, StringConstants::multiplexProperty()); rule->alwaysRun = m_evaluator->boolValue(item, StringConstants::alwaysRunProperty()); rule->inputs = m_evaluator->fileTagsValue(item, StringConstants::inputsProperty()); @@ -1301,6 +1348,35 @@ void ProjectResolver::resolveFileTagger(Item *item, ProjectContext *projectConte fileTaggers.push_back(FileTagger::create(patterns, fileTags, priority)); } +void ProjectResolver::resolveJobLimit(Item *item, ProjectResolver::ProjectContext *projectContext) +{ + if (!m_evaluator->boolValue(item, StringConstants::conditionProperty())) + return; + const QString jobPool = m_evaluator->stringValue(item, StringConstants::jobPoolProperty()); + if (jobPool.isEmpty()) + throw ErrorInfo(Tr::tr("A JobLimit item needs to have a non-empty '%1' property.") + .arg(StringConstants::jobPoolProperty()), item->location()); + bool jobCountWasSet; + const int jobCount = m_evaluator->intValue(item, StringConstants::jobCountProperty(), -1, + &jobCountWasSet); + if (!jobCountWasSet) { + throw ErrorInfo(Tr::tr("A JobLimit item needs to have a '%1' property.") + .arg(StringConstants::jobCountProperty()), item->location()); + } + if (jobCount < 0) { + throw ErrorInfo(Tr::tr("A JobLimit item must have a non-negative '%1' property.") + .arg(StringConstants::jobCountProperty()), item->location()); + } + JobLimits &jobLimits = m_moduleContext + ? m_moduleContext->jobLimits + : m_productContext ? m_productContext->product->jobLimits + : projectContext->jobLimits; + JobLimit jobLimit(jobPool, jobCount); + const int oldLimit = jobLimits.getLimit(jobPool); + if (oldLimit == -1 || oldLimit > jobCount) + jobLimits.setJobLimit(jobLimit); +} + void ProjectResolver::resolveScanner(Item *item, ProjectResolver::ProjectContext *projectContext) { checkCancelation(); diff --git a/src/lib/corelib/language/projectresolver.h b/src/lib/corelib/language/projectresolver.h index e81034b5a..777451fa6 100644 --- a/src/lib/corelib/language/projectresolver.h +++ b/src/lib/corelib/language/projectresolver.h @@ -56,6 +56,7 @@ #include <vector> namespace qbs { +class JobLimits; namespace Internal { class Evaluator; @@ -89,8 +90,8 @@ private: class ProductContextSwitcher; void checkCancelation() const; - QString verbatimValue(const ValueConstPtr &value, bool *propertyWasSet = 0) const; - QString verbatimValue(Item *item, const QString &name, bool *propertyWasSet = 0) const; + QString verbatimValue(const ValueConstPtr &value, bool *propertyWasSet = nullptr) const; + QString verbatimValue(Item *item, const QString &name, bool *propertyWasSet = nullptr) const; ScriptFunctionPtr scriptFunctionValue(Item *item, const QString &name) const; ResolvedFileContextPtr resolvedFileContext(const FileContextConstPtr &ctx) const; void ignoreItem(Item *item, ProjectContext *projectContext); @@ -102,7 +103,8 @@ private: void resolveProductFully(Item *item, ProjectContext *projectContext); void resolveModules(const Item *item, ProjectContext *projectContext); void resolveModule(const QualifiedId &moduleName, Item *item, bool isProduct, - const QVariantMap ¶meters, ProjectContext *projectContext); + const QVariantMap ¶meters, JobLimits &jobLimits, + ProjectContext *projectContext); void gatherProductTypes(ResolvedProduct *product, Item *item); QVariantMap resolveAdditionalModuleProperties(const Item *group, const QVariantMap ¤tValues); @@ -118,6 +120,7 @@ private: const QStringList &namePrefix, QualifiedIdSet *seenBindings); void resolveFileTagger(Item *item, ProjectContext *projectContext); + void resolveJobLimit(Item *item, ProjectContext *projectContext); void resolveScanner(Item *item, ProjectContext *projectContext); void resolveProductDependencies(const ProjectContext &projectContext); void postProcess(const ResolvedProductPtr &product, ProjectContext *projectContext) const; @@ -131,7 +134,7 @@ private: QVariantMap &result, bool checkErrors); void createProductConfig(ResolvedProduct *product); ProjectContext createProjectContext(ProjectContext *parentProjectContext) const; - void adaptExportedPropertyValues(); + void adaptExportedPropertyValues(const Item *shadowProductItem); void collectExportedProductDependencies(); struct ProductDependencyInfo diff --git a/src/lib/corelib/language/property.h b/src/lib/corelib/language/property.h index bae9de74e..8ad992bdb 100644 --- a/src/lib/corelib/language/property.h +++ b/src/lib/corelib/language/property.h @@ -56,7 +56,8 @@ public: PropertyInModule, PropertyInProduct, PropertyInProject, - PropertyInParameters + PropertyInParameters, + PropertyInArtifact, }; Property() diff --git a/src/lib/corelib/language/scriptengine.cpp b/src/lib/corelib/language/scriptengine.cpp index e983ae945..fb4706b3b 100644 --- a/src/lib/corelib/language/scriptengine.cpp +++ b/src/lib/corelib/language/scriptengine.cpp @@ -371,6 +371,11 @@ void ScriptEngine::setEnvironment(const QProcessEnvironment &env) void ScriptEngine::importFile(const QString &filePath, QScriptValue &targetObject) { AccumulatingTimer importTimer(m_elapsedTimeImporting != -1 ? &m_elapsedTimeImporting : nullptr); + QScriptValue &evaluationResult = m_jsFileCache[filePath]; + if (evaluationResult.isValid()) { + ScriptImporter::copyProperties(evaluationResult, targetObject); + return; + } QFile file(filePath); if (Q_UNLIKELY(!file.open(QFile::ReadOnly))) throw ErrorInfo(tr("Cannot open '%1'.").arg(filePath)); @@ -379,7 +384,7 @@ void ScriptEngine::importFile(const QString &filePath, QScriptValue &targetObjec const QString sourceCode = stream.readAll(); file.close(); m_currentDirPathStack.push(FileInfo::path(filePath)); - m_scriptImporter->importSourceCode(sourceCode, filePath, targetObject); + evaluationResult = m_scriptImporter->importSourceCode(sourceCode, filePath, targetObject); m_currentDirPathStack.pop(); } @@ -763,7 +768,7 @@ void ScriptEngine::extendJavaScriptBuiltins() } void ScriptEngine::installFunction(const QString &name, int length, QScriptValue *functionValue, - FunctionSignature f, QScriptValue *targetObject = 0) + FunctionSignature f, QScriptValue *targetObject = nullptr) { if (!functionValue->isValid()) *functionValue = newFunction(f, length); diff --git a/src/lib/corelib/language/scriptengine.h b/src/lib/corelib/language/scriptengine.h index eff4cb48f..226cf16a9 100644 --- a/src/lib/corelib/language/scriptengine.h +++ b/src/lib/corelib/language/scriptengine.h @@ -164,6 +164,10 @@ public: void addImportRequestedInScript(qint64 importValueId); std::vector<QString> importedFilesUsedInScript() const; + void setUsesIo() { m_usesIo = true; } + void clearUsesIo() { m_usesIo = false; } + bool usesIo() const { return m_usesIo; } + void enableProfiling(bool enable); void setPropertyCacheEnabled(bool enable) { m_propertyCacheEnabled = enable; } @@ -314,6 +318,7 @@ private: QScriptClass *m_productPropertyScriptClass = nullptr; QScriptClass *m_artifactsScriptClass = nullptr; QHash<JsImport, QScriptValue> m_jsImportCache; + std::unordered_map<QString, QScriptValue> m_jsFileCache; bool m_propertyCacheEnabled; bool m_active; QHash<PropertyCacheKey, QVariant> m_propertyCache; @@ -336,6 +341,7 @@ private: QScriptValue m_consoleObject; QScriptValue m_cancelationError; qint64 m_elapsedTimeImporting = -1; + bool m_usesIo = false; EvalContext m_evalContext; std::vector<ResourceAcquiringScriptObject *> m_resourceAcquiringScriptObjects; const std::unique_ptr<PrepareScriptObserver> m_observer; diff --git a/src/lib/corelib/language/scriptimporter.cpp b/src/lib/corelib/language/scriptimporter.cpp index 6249e360e..c5dc887b7 100644 --- a/src/lib/corelib/language/scriptimporter.cpp +++ b/src/lib/corelib/language/scriptimporter.cpp @@ -120,7 +120,7 @@ ScriptImporter::ScriptImporter(ScriptEngine *scriptEngine) { } -void ScriptImporter::importSourceCode(const QString &sourceCode, const QString &filePath, +QScriptValue ScriptImporter::importSourceCode(const QString &sourceCode, const QString &filePath, QScriptValue &targetObject) { Q_ASSERT(targetObject.isObject()); @@ -146,6 +146,7 @@ void ScriptImporter::importSourceCode(const QString &sourceCode, const QString & QScriptValue result = m_engine->evaluate(code, filePath, 0); throwOnEvaluationError(m_engine, result, [&filePath] () { return CodeLocation(filePath, 0); }); copyProperties(result, targetObject); + return result; } void ScriptImporter::copyProperties(const QScriptValue &src, QScriptValue &dst) diff --git a/src/lib/corelib/language/scriptimporter.h b/src/lib/corelib/language/scriptimporter.h index 0f37038ff..8cff09382 100644 --- a/src/lib/corelib/language/scriptimporter.h +++ b/src/lib/corelib/language/scriptimporter.h @@ -53,11 +53,11 @@ class ScriptImporter { public: ScriptImporter(ScriptEngine *scriptEngine); - void importSourceCode(const QString &sourceCode, const QString &filePath, QScriptValue &targetObject); + QScriptValue importSourceCode(const QString &sourceCode, const QString &filePath, QScriptValue &targetObject); -private: static void copyProperties(const QScriptValue &src, QScriptValue &dst); +private: ScriptEngine *m_engine; QHash<QString, QString> m_sourceCodeCache; }; diff --git a/src/lib/corelib/language/value.h b/src/lib/corelib/language/value.h index 6e7eca2f8..fde8e79e4 100644 --- a/src/lib/corelib/language/value.h +++ b/src/lib/corelib/language/value.h @@ -117,8 +117,8 @@ public: static JSSourceValuePtr QBS_AUTOTEST_EXPORT create(bool createdByPropertiesBlock = false); ~JSSourceValue(); - void apply(ValueHandler *handler) { handler->handle(this); } - ValuePtr clone() const; + void apply(ValueHandler *handler) override { handler->handle(this); } + ValuePtr clone() const override; void setSourceCode(const QStringRef &sourceCode) { m_sourceCode = sourceCode; } const QStringRef &sourceCode() const { return m_sourceCode; } @@ -127,7 +127,7 @@ public: void setLocation(int line, int column); int line() const { return m_line; } int column() const { return m_column; } - CodeLocation location() const; + CodeLocation location() const override; void setFile(const FileContextPtr &file) { m_file = file; } const FileContextPtr &file() const { return m_file; } @@ -175,7 +175,7 @@ public: void addAlternative(const Alternative &alternative) { m_alternatives.push_back(alternative); } void clearAlternatives(); - void setDefiningItem(Item *item); + void setDefiningItem(Item *item) override; private: QStringRef m_sourceCode; @@ -211,8 +211,8 @@ class VariantValue : public Value public: static VariantValuePtr create(const QVariant &v = QVariant()); - void apply(ValueHandler *handler) { handler->handle(this); } - ValuePtr clone() const; + void apply(ValueHandler *handler) override { handler->handle(this); } + ValuePtr clone() const override; const QVariant &value() const { return m_value; } diff --git a/src/lib/corelib/tools/buildoptions.cpp b/src/lib/corelib/tools/buildoptions.cpp index ac8e39867..5507e0842 100644 --- a/src/lib/corelib/tools/buildoptions.cpp +++ b/src/lib/corelib/tools/buildoptions.cpp @@ -58,6 +58,8 @@ public: QStringList changedFiles; QStringList filesToConsider; QStringList activeFileTags; + JobLimits jobLimits; + QString settingsDir; int maxJobCount; bool dryRun; bool keepGoing; @@ -68,6 +70,7 @@ public: bool install; bool removeExistingInstallation; bool onlyExecuteRules; + bool jobLimitsFromProjectTakePrecedence = false; }; } // namespace Internal @@ -189,6 +192,44 @@ void BuildOptions::setMaxJobCount(int jobCount) } /*! + * \brief The base directory for qbs settings. + * This value is used to locate profiles and preferences. + */ +QString BuildOptions::settingsDirectory() const +{ + return d->settingsDir; +} + +/*! + * \brief Sets the base directory for qbs settings. + * \param settingsBaseDir Will be used to locate profiles and preferences. + */ +void BuildOptions::setSettingsDirectory(const QString &settingsBaseDir) +{ + d->settingsDir = settingsBaseDir; +} + +JobLimits BuildOptions::jobLimits() const +{ + return d->jobLimits; +} + +void BuildOptions::setJobLimits(const JobLimits &jobLimits) +{ + d->jobLimits = jobLimits; +} + +bool BuildOptions::projectJobLimitsTakePrecedence() const +{ + return d->jobLimitsFromProjectTakePrecedence; +} + +void BuildOptions::setProjectJobLimitsTakePrecedence(bool toggle) +{ + d->jobLimitsFromProjectTakePrecedence = toggle; +} + +/*! * \brief Returns true iff qbs will not actually execute any commands, but just show what * would happen. * The default is false. diff --git a/src/lib/corelib/tools/buildoptions.h b/src/lib/corelib/tools/buildoptions.h index 630a6aa22..cea89d0ea 100644 --- a/src/lib/corelib/tools/buildoptions.h +++ b/src/lib/corelib/tools/buildoptions.h @@ -42,6 +42,7 @@ #include "qbs_export.h" #include "commandechomode.h" +#include "joblimits.h" #include <QtCore/qshareddata.h> @@ -73,6 +74,15 @@ public: int maxJobCount() const; void setMaxJobCount(int jobCount); + QString settingsDirectory() const; + void setSettingsDirectory(const QString &settingsBaseDir); + + JobLimits jobLimits() const; + void setJobLimits(const JobLimits &jobLimits); + + bool projectJobLimitsTakePrecedence() const; + void setProjectJobLimitsTakePrecedence(bool toggle); + bool dryRun() const; void setDryRun(bool dryRun); diff --git a/src/lib/corelib/tools/fileinfo.cpp b/src/lib/corelib/tools/fileinfo.cpp index 3adacc883..15a8e8783 100644 --- a/src/lib/corelib/tools/fileinfo.cpp +++ b/src/lib/corelib/tools/fileinfo.cpp @@ -295,15 +295,10 @@ bool FileInfo::fileExists(const QFileInfo &fi) #define z(x) reinterpret_cast<WIN32_FILE_ATTRIBUTE_DATA*>(const_cast<FileInfo::InternalStatType*>(&x)) -template<bool> struct CompileTimeAssert; -template<> struct CompileTimeAssert<true> {}; - FileInfo::FileInfo(const QString &fileName) { - static CompileTimeAssert< - sizeof(FileInfo::InternalStatType) == sizeof(WIN32_FILE_ATTRIBUTE_DATA) - > internal_type_has_wrong_size; - Q_UNUSED(internal_type_has_wrong_size); + static_assert(sizeof(FileInfo::InternalStatType) == sizeof(WIN32_FILE_ATTRIBUTE_DATA), + "FileInfo::InternalStatType has wrong size."); QString filePath = fileName; @@ -368,7 +363,7 @@ FileInfo::FileInfo(const QString &fileName) bool FileInfo::exists() const { - return m_stat.st_mtime != 0; + return m_stat.st_mode != 0; } FileTime FileInfo::lastModified() const diff --git a/src/lib/corelib/tools/filetime.cpp b/src/lib/corelib/tools/filetime.cpp index 14680ef6e..263950d9c 100644 --- a/src/lib/corelib/tools/filetime.cpp +++ b/src/lib/corelib/tools/filetime.cpp @@ -50,11 +50,6 @@ namespace qbs { namespace Internal { -#ifdef Q_OS_WIN -template<bool> struct CompileTimeAssert; -template<> struct CompileTimeAssert<true> {}; -#endif - #ifdef APPLE_CUSTOM_CLOCK_GETTIME #include <sys/time.h> @@ -77,8 +72,8 @@ int clock_gettime(int /*clk_id*/, struct timespec *t) FileTime::FileTime() { #ifdef Q_OS_WIN - static CompileTimeAssert<sizeof(FileTime::InternalType) == sizeof(FILETIME)> internal_type_has_wrong_size; - Q_UNUSED(internal_type_has_wrong_size); + static_assert(sizeof(FileTime::InternalType) == sizeof(FILETIME), + "FileTime::InternalType has wrong size."); m_fileTime = 0; #elif HAS_CLOCK_GETTIME m_fileTime = {0, 0}; @@ -98,8 +93,8 @@ FileTime::FileTime(const FileTime::InternalType &ft) : m_fileTime(ft) int FileTime::compare(const FileTime &other) const { #ifdef Q_OS_WIN - const FILETIME *const t1 = reinterpret_cast<const FILETIME *>(&m_fileTime); - const FILETIME *const t2 = reinterpret_cast<const FILETIME *>(&other.m_fileTime); + auto const t1 = reinterpret_cast<const FILETIME *>(&m_fileTime); + auto const t2 = reinterpret_cast<const FILETIME *>(&other.m_fileTime); return CompareFileTime(t1, t2); #elif HAS_CLOCK_GETTIME if (m_fileTime.tv_sec < other.m_fileTime.tv_sec) @@ -140,7 +135,7 @@ FileTime FileTime::currentTime() FileTime result; SYSTEMTIME st; GetSystemTime(&st); - FILETIME *const ft = reinterpret_cast<FILETIME *>(&result.m_fileTime); + auto const ft = reinterpret_cast<FILETIME *>(&result.m_fileTime); SystemTimeToFileTime(&st, ft); return result; #elif defined APPLE_CUSTOM_CLOCK_GETTIME @@ -173,7 +168,7 @@ FileTime FileTime::oldestTime() 0 }; FileTime result; - FILETIME *const ft = reinterpret_cast<FILETIME *>(&result.m_fileTime); + auto const ft = reinterpret_cast<FILETIME *>(&result.m_fileTime); SystemTimeToFileTime(&st, ft); return result; #elif HAS_CLOCK_GETTIME @@ -195,7 +190,7 @@ double FileTime::asDouble() const QString FileTime::toString() const { #ifdef Q_OS_WIN - const FILETIME *const ft = reinterpret_cast<const FILETIME *>(&m_fileTime); + auto const ft = reinterpret_cast<const FILETIME *>(&m_fileTime); SYSTEMTIME stUTC, stLocal; FileTimeToSystemTime(ft, &stUTC); SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal); diff --git a/src/lib/corelib/tools/joblimits.cpp b/src/lib/corelib/tools/joblimits.cpp new file mode 100644 index 000000000..3b1fde83d --- /dev/null +++ b/src/lib/corelib/tools/joblimits.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "joblimits.h" + +#include <tools/persistence.h> + +#include <utility> +#include <vector> + +namespace qbs { +namespace Internal { + +static int transformLimit(int limitFromUser) +{ + return limitFromUser == 0 + ? std::numeric_limits<int>::max() + : limitFromUser < -1 ? -1 + : limitFromUser; +} + +class JobLimitPrivate : public QSharedData +{ +public: + JobLimitPrivate(const QString &pool, int limit) + : jobLimit(std::make_pair(pool, transformLimit(limit))) + { + } + template<PersistentPool::OpType opType> void serializationOp(PersistentPool &pool) + { + pool.serializationOp<opType>(jobLimit); + } + std::pair<QString, int> jobLimit; +}; + +class JobLimitsPrivate : public QSharedData +{ +public: + template<PersistentPool::OpType opType> void serializationOp(PersistentPool &pool) + { + pool.serializationOp<opType>(jobLimits); + } + std::vector<JobLimit> jobLimits; +}; + +} // namespace Internal + +JobLimit::JobLimit() : JobLimit(QString(), -1) +{ +} +JobLimit::JobLimit(const QString &pool, int limit) : d(new Internal::JobLimitPrivate(pool, limit)) +{ +} +JobLimit::JobLimit(const JobLimit &other) : d(other.d) { } +JobLimit &JobLimit::operator=(const JobLimit &other) +{ + d = other.d; + return *this; +} +JobLimit::~JobLimit() {} +QString JobLimit::pool() const { return d->jobLimit.first; } +int JobLimit::limit() const { return d->jobLimit.second; } + +void JobLimit::load(Internal::PersistentPool &pool) +{ + d->serializationOp<Internal::PersistentPool::Load>(pool); +} + +void JobLimit::store(Internal::PersistentPool &pool) +{ + d->serializationOp<Internal::PersistentPool::Store>(pool); +} + +JobLimits::JobLimits() : d(new Internal::JobLimitsPrivate) { } +JobLimits::JobLimits(const JobLimits &other) : d(other.d) { } +JobLimits &JobLimits::operator=(const JobLimits &other) +{ + d = other.d; + return *this; +} +JobLimits::~JobLimits() {} + +void JobLimits::setJobLimit(const JobLimit &limit) +{ + for (std::size_t i = 0; i < d->jobLimits.size(); ++i) { + JobLimit ¤tLimit = d->jobLimits.at(i); + if (currentLimit.pool() == limit.pool()) { + if (currentLimit.limit() != limit.limit()) + currentLimit = limit; + return; + } + } + d->jobLimits.push_back(limit); +} + +void JobLimits::setJobLimit(const QString &pool, int limit) +{ + setJobLimit(JobLimit(pool, limit)); +} + +int JobLimits::getLimit(const QString &pool) const +{ + for (const JobLimit &l : d->jobLimits) { + if (l.pool() == pool) + return l.limit(); + } + return -1; +} + +bool JobLimits::isEmpty() const +{ + return d->jobLimits.empty(); +} + +int JobLimits::count() const +{ + return d->jobLimits.size(); +} + +JobLimit JobLimits::jobLimitAt(int i) const +{ + return d->jobLimits.at(i); +} + +JobLimits &JobLimits::update(const JobLimits &other) +{ + if (isEmpty()) { + *this = other; + } else { + for (int i = 0; i < other.count(); ++i) { + const JobLimit &l = other.jobLimitAt(i); + if (l.limit() != -1) + setJobLimit(l); + } + } + return *this; +} + +void JobLimits::load(Internal::PersistentPool &pool) +{ + d->serializationOp<Internal::PersistentPool::Load>(pool); +} + +void JobLimits::store(Internal::PersistentPool &pool) +{ + d->serializationOp<Internal::PersistentPool::Store>(pool); +} + +} // namespace qbs diff --git a/src/lib/corelib/tools/joblimits.h b/src/lib/corelib/tools/joblimits.h new file mode 100644 index 000000000..de95f5513 --- /dev/null +++ b/src/lib/corelib/tools/joblimits.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QBS_JOB_LIMITS_H +#define QBS_JOB_LIMITS_H + +#include "qbs_export.h" + +#include <QtCore/qshareddata.h> + +QT_BEGIN_NAMESPACE +class QString; +QT_END_NAMESPACE + +namespace qbs { +namespace Internal { +class JobLimitPrivate; +class JobLimitsPrivate; +class PersistentPool; +} + +class QBS_EXPORT JobLimit +{ +public: + JobLimit(); + JobLimit(const QString &pool, int limit); + JobLimit(const JobLimit &other); + JobLimit &operator=(const JobLimit &other); + ~JobLimit(); + + QString pool() const; + int limit() const; + + void load(Internal::PersistentPool &pool); + void store(Internal::PersistentPool &pool); +private: + QSharedDataPointer<Internal::JobLimitPrivate> d; +}; + +class QBS_EXPORT JobLimits +{ +public: + JobLimits(); + JobLimits(const JobLimits &other); + JobLimits &operator=(const JobLimits &other); + ~JobLimits(); + + void setJobLimit(const JobLimit &limit); + void setJobLimit(const QString &pool, int limit); + int getLimit(const QString &pool) const; + bool hasLimit(const QString &pool) const { return getLimit(pool) != -1; } + bool isEmpty() const; + + int count() const; + JobLimit jobLimitAt(int i) const; + + JobLimits &update(const JobLimits &other); + + void load(Internal::PersistentPool &pool); + void store(Internal::PersistentPool &pool); +private: + QSharedDataPointer<Internal::JobLimitsPrivate> d; +}; + +} // namespace qbs + +#endif // include guard diff --git a/src/lib/corelib/tools/persistence.cpp b/src/lib/corelib/tools/persistence.cpp index 996c8415d..ec412cf3b 100644 --- a/src/lib/corelib/tools/persistence.cpp +++ b/src/lib/corelib/tools/persistence.cpp @@ -42,14 +42,13 @@ #include "fileinfo.h" #include <logging/translator.h> #include <tools/error.h> -#include <tools/qbsassert.h> #include <QtCore/qdir.h> namespace qbs { namespace Internal { -static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-120"; +static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-124"; NoBuildGraphError::NoBuildGraphError(const QString &filePath) : ErrorInfo(Tr::tr("Build graph not found for configuration '%1'. Expected location was '%2'.") @@ -82,7 +81,7 @@ void PersistentPool::load(const QString &filePath) QByteArray magic; m_stream >> magic; if (magic != QBS_PERSISTENCE_MAGIC) { - m_stream.setDevice(0); + m_stream.setDevice(nullptr); throw ErrorInfo(Tr::tr("Cannot use stored build graph at '%1': Incompatible file format. " "Expected magic token '%2', got '%3'.") .arg(filePath, QString::fromLatin1(QBS_PERSISTENCE_MAGIC), @@ -121,6 +120,8 @@ void PersistentPool::setupWriteStream(const QString &filePath) m_stream << QByteArray(qstrlen(QBS_PERSISTENCE_MAGIC), 0) << m_headData.projectConfig; m_lastStoredObjectId = 0; m_lastStoredStringId = 0; + m_lastStoredEnvId = 0; + m_lastStoredStringListId = 0; } void PersistentPool::finalizeWriteStream() @@ -153,7 +154,7 @@ void PersistentPool::storeVariant(const QVariant &variant) m_stream << type; switch (type) { case QMetaType::QString: - storeString(variant.toString()); + store(variant.toString()); break; case QMetaType::QStringList: store(variant.toStringList()); @@ -175,7 +176,7 @@ QVariant PersistentPool::loadVariant() QVariant value; switch (type) { case QMetaType::QString: - value = idLoadString(); + value = load<QString>(); break; case QMetaType::QStringList: value = load<QStringList>(); @@ -200,50 +201,48 @@ void PersistentPool::clear() m_inverseStringStorage.clear(); } -const int StringNotFoundId = -1; -const int NullStringId = -2; - -void PersistentPool::storeString(const QString &t) +void PersistentPool::doLoadValue(QString &s) { - if (t.isNull()) { - m_stream << NullStringId; - return; - } - - int id = m_inverseStringStorage.value(t, StringNotFoundId); - if (id < 0) { - id = m_lastStoredStringId++; - m_inverseStringStorage.insert(t, id); - m_stream << id << t; - } else { - m_stream << id; - } + m_stream >> s; } -QString PersistentPool::loadString(int id) +void PersistentPool::doLoadValue(QStringList &l) { - if (id == NullStringId) - return QString(); + int size; + m_stream >> size; + for (int i = 0; i < size; ++i) + l << load<QString>(); +} - QBS_CHECK(id >= 0); +void PersistentPool::doLoadValue(QProcessEnvironment &env) +{ + const QStringList keys = load<QStringList>(); + for (const QString &key : keys) + env.insert(key, load<QString>()); +} - if (id >= static_cast<int>(m_stringStorage.size())) { - QString s; - m_stream >> s; - m_stringStorage.resize(id + 1); - m_stringStorage[id] = s; - return s; - } +void PersistentPool::doStoreValue(const QString &s) +{ + m_stream << s; +} - return m_stringStorage.at(id); +void PersistentPool::doStoreValue(const QStringList &l) +{ + m_stream << l.size(); + for (const QString &s : l) + store(s); } -QString PersistentPool::idLoadString() +void PersistentPool::doStoreValue(const QProcessEnvironment &env) { - int id; - m_stream >> id; - return loadString(id); + const QStringList &keys = env.keys(); + store(keys); + for (const QString &key : keys) + store(env.value(key)); } +const PersistentPool::PersistentObjectId PersistentPool::ValueNotFoundId; +const PersistentPool::PersistentObjectId PersistentPool::EmptyValueId; + } // namespace Internal } // namespace qbs diff --git a/src/lib/corelib/tools/persistence.h b/src/lib/corelib/tools/persistence.h index 2687d6120..e8d938ad3 100644 --- a/src/lib/corelib/tools/persistence.h +++ b/src/lib/corelib/tools/persistence.h @@ -42,6 +42,8 @@ #include "error.h" #include <logging/logger.h> +#include <tools/qbsassert.h> +#include <tools/qttools.h> #include <QtCore/qdatastream.h> #include <QtCore/qflags.h> @@ -137,20 +139,34 @@ private: template <typename T> T *idLoad(); template <class T> std::shared_ptr<T> idLoadS(); + template <typename T> T idLoadValue(); + + void doLoadValue(QString &s); + void doLoadValue(QStringList &l); + void doLoadValue(QProcessEnvironment &env); template<typename T> void storeSharedObject(const T *object); void storeVariant(const QVariant &variant); QVariant loadVariant(); - void storeString(const QString &t); - QString loadString(int id); - QString idLoadString(); + template <typename T> void idStoreValue(const T &value); + + void doStoreValue(const QString &s); + void doStoreValue(const QStringList &l); + void doStoreValue(const QProcessEnvironment &env); + + template<typename T> std::vector<T> &idStorage(); + template<typename T> QHash<T, PersistentObjectId> &idMap(); + template<typename T> PersistentObjectId &lastStoredId(); // Recursion termination void store() {} void load() {} + static const PersistentObjectId ValueNotFoundId = -1; + static const PersistentObjectId EmptyValueId = -2; + QDataStream m_stream; HeadData m_headData; std::vector<void *> m_loadedRaw; @@ -161,6 +177,12 @@ private: std::vector<QString> m_stringStorage; QHash<QString, int> m_inverseStringStorage; PersistentObjectId m_lastStoredStringId; + std::vector<QProcessEnvironment> m_envStorage; + QHash<QProcessEnvironment, int> m_inverseEnvStorage; + PersistentObjectId m_lastStoredEnvId; + std::vector<QStringList> m_stringListStorage; + QHash<QStringList, int> m_inverseStringListStorage; + PersistentObjectId m_lastStoredStringListId; Logger &m_logger; template<typename T, typename Enable> @@ -209,6 +231,42 @@ template <typename T> inline T *PersistentPool::idLoad() return t; } +template<> inline std::vector<QString> &PersistentPool::idStorage() { return m_stringStorage; } +template<> inline QHash<QString, PersistentPool::PersistentObjectId> &PersistentPool::idMap() +{ + return m_inverseStringStorage; +} +template<> inline PersistentPool::PersistentObjectId &PersistentPool::lastStoredId<QString>() +{ + return m_lastStoredStringId; +} +template<> inline std::vector<QStringList> &PersistentPool::idStorage() +{ + return m_stringListStorage; +} +template<> inline QHash<QStringList, PersistentPool::PersistentObjectId> &PersistentPool::idMap() +{ + return m_inverseStringListStorage; +} +template<> inline PersistentPool::PersistentObjectId &PersistentPool::lastStoredId<QStringList>() +{ + return m_lastStoredStringListId; +} +template<> inline std::vector<QProcessEnvironment> &PersistentPool::idStorage() +{ + return m_envStorage; +} +template<> inline QHash<QProcessEnvironment, PersistentPool::PersistentObjectId> +&PersistentPool::idMap() +{ + return m_inverseEnvStorage; +} +template<> inline PersistentPool::PersistentObjectId +&PersistentPool::lastStoredId<QProcessEnvironment>() +{ + return m_lastStoredEnvId; +} + template <class T> inline std::shared_ptr<T> PersistentPool::idLoadS() { PersistentObjectId id; @@ -227,6 +285,41 @@ template <class T> inline std::shared_ptr<T> PersistentPool::idLoadS() return t; } +template<typename T> inline T PersistentPool::idLoadValue() +{ + int id; + m_stream >> id; + if (id == EmptyValueId) + return T(); + QBS_CHECK(id >= 0); + if (id >= static_cast<int>(idStorage<T>().size())) { + T value; + doLoadValue(value); + idStorage<T>().resize(id + 1); + idStorage<T>()[id] = value; + return value; + } + return idStorage<T>().at(id); +} + +template<typename T> +void PersistentPool::idStoreValue(const T &value) +{ + if (value.isEmpty()) { + m_stream << EmptyValueId; + return; + } + int id = idMap<T>().value(value, ValueNotFoundId); + if (id < 0) { + id = lastStoredId<T>()++; + idMap<T>().insert(value, id); + m_stream << id; + doStoreValue(value); + } else { + m_stream << id; + } +} + // We need a helper class template, because we require partial specialization for some of // the aggregate types, which is not possible with function templates. // The generic implementation assumes that T is of class type and has load() and store() @@ -320,10 +413,11 @@ template<typename T> struct PPHelper<T *> static void load(T* &value, PersistentPool *pool) { value = pool->idLoad<T>(); } }; -template<> struct PPHelper<QString> +template<typename T> struct PPHelper<T, std::enable_if_t<std::is_same<T, QString>::value + || std::is_same<T, QStringList>::value || std::is_same<T, QProcessEnvironment>::value>> { - static void store(const QString &s, PersistentPool *pool) { pool->storeString(s); } - static void load(QString &s, PersistentPool *pool) { s = pool->idLoadString(); } + static void store(const T &v, PersistentPool *pool) { pool->idStoreValue(v); } + static void load(T &v, PersistentPool *pool) { v = pool->idLoadValue<T>(); } }; template<> struct PPHelper<QVariant> @@ -335,30 +429,9 @@ template<> struct PPHelper<QVariant> template<> struct PPHelper<QRegExp> { static void store(const QRegExp &re, PersistentPool *pool) { pool->store(re.pattern()); } - static void load(QRegExp &re, PersistentPool *pool) { re.setPattern(pool->idLoadString()); } + static void load(QRegExp &re, PersistentPool *pool) { re.setPattern(pool->load<QString>()); } }; -template<> struct PPHelper<QProcessEnvironment> -{ - static void store(const QProcessEnvironment &env, PersistentPool *pool) - { - const QStringList &keys = env.keys(); - pool->store(keys.size()); - for (const QString &key : keys) { - pool->store(key); - pool->store(env.value(key)); - } - } - static void load(QProcessEnvironment &env, PersistentPool *pool) - { - const int count = pool->load<int>(); - for (int i = 0; i < count; ++i) { - const auto &key = pool->load<QString>(); - const auto &value = pool->load<QString>(); - env.insert(key, value); - } - } -}; template<typename T, typename U> struct PPHelper<std::pair<T, U>> { static void store(const std::pair<T, U> &pair, PersistentPool *pool) @@ -387,7 +460,6 @@ template<typename T> struct PPHelper<QFlags<T>> }; template<typename T> struct IsSimpleContainer : std::false_type { }; -template<> struct IsSimpleContainer<QStringList> : std::true_type { }; template<typename T> struct IsSimpleContainer<QList<T>> : std::true_type { }; template<typename T> struct IsSimpleContainer<std::vector<T>> : std::true_type { }; diff --git a/src/lib/corelib/tools/preferences.cpp b/src/lib/corelib/tools/preferences.cpp index 66803a0f5..12af4e9c7 100644 --- a/src/lib/corelib/tools/preferences.cpp +++ b/src/lib/corelib/tools/preferences.cpp @@ -124,6 +124,32 @@ QStringList Preferences::pluginPaths(const QString &baseDir) const return pathList(QLatin1String("pluginsPath"), baseDir + QLatin1String("/qbs/plugins")); } +/*! + * \brief Returns the per-pool job limits. + */ +JobLimits Preferences::jobLimits() const +{ + const QString prefix = QLatin1String("preferences.jobLimit"); + JobLimits limits; + for (const QString &key : m_settings->allKeysWithPrefix(prefix, Settings::allScopes())) { + limits.setJobLimit(key, m_settings->value(prefix + QLatin1Char('.') + key, + Settings::allScopes()).toInt()); + } + const QString fullPrefix = prefix + QLatin1Char('.'); + if (!m_profile.isEmpty()) { + Profile p(m_profile, m_settings, m_profileContents); + for (const QString &key : p.allKeys(Profile::KeySelectionRecursive)) { + if (!key.startsWith(fullPrefix)) + continue; + const QString jobPool = key.mid(fullPrefix.size()); + const int limit = p.value(key).toInt(); + if (limit >= 0) + limits.setJobLimit(jobPool, limit); + } + } + return limits; +} + QVariant Preferences::getPreference(const QString &key, const QVariant &defaultValue) const { static const QString keyPrefix = QLatin1String("preferences"); diff --git a/src/lib/corelib/tools/preferences.h b/src/lib/corelib/tools/preferences.h index 07f0edcd7..661b39d7f 100644 --- a/src/lib/corelib/tools/preferences.h +++ b/src/lib/corelib/tools/preferences.h @@ -42,6 +42,7 @@ #include "qbs_export.h" #include "commandechomode.h" +#include "joblimits.h" #include "settings.h" #include <QtCore/qstringlist.h> @@ -63,6 +64,7 @@ public: CommandEchoMode defaultEchoMode() const; QStringList searchPaths(const QString &baseDir = QString()) const; QStringList pluginPaths(const QString &baseDir = QString()) const; + JobLimits jobLimits() const; private: QVariant getPreference(const QString &key, const QVariant &defaultValue = QVariant()) const; diff --git a/src/lib/corelib/tools/profile.h b/src/lib/corelib/tools/profile.h index a4c6a91f1..2ccc99def 100644 --- a/src/lib/corelib/tools/profile.h +++ b/src/lib/corelib/tools/profile.h @@ -59,7 +59,7 @@ public: bool exists() const; QVariant value(const QString &key, const QVariant &defaultValue = QVariant(), - ErrorInfo *error = 0) const; + ErrorInfo *error = nullptr) const; void setValue(const QString &key, const QVariant &value); void remove(const QString &key); @@ -72,7 +72,7 @@ public: void removeProfile(); enum KeySelection { KeySelectionRecursive, KeySelectionNonRecursive }; - QStringList allKeys(KeySelection selection, ErrorInfo *error = 0) const; + QStringList allKeys(KeySelection selection, ErrorInfo *error = nullptr) const; static QString cleanName(const QString &name); diff --git a/src/lib/corelib/tools/qbspluginmanager.cpp b/src/lib/corelib/tools/qbspluginmanager.cpp index a8d22f458..d0be73891 100644 --- a/src/lib/corelib/tools/qbspluginmanager.cpp +++ b/src/lib/corelib/tools/qbspluginmanager.cpp @@ -80,8 +80,7 @@ QbsPluginManager::~QbsPluginManager() unloadStaticPlugins(); for (QLibrary * const lib : qAsConst(d->libs)) { - QbsPluginUnloadFunction unload = reinterpret_cast<QbsPluginUnloadFunction>( - lib->resolve("QbsPluginUnload")); + auto unload = reinterpret_cast<QbsPluginUnloadFunction>(lib->resolve("QbsPluginUnload")); if (unload) unload(); lib->unload(); @@ -146,8 +145,7 @@ void QbsPluginManager::loadPlugins(const std::vector<std::string> &pluginPaths, continue; } - QbsPluginLoadFunction load = reinterpret_cast<QbsPluginLoadFunction>( - lib->resolve("QbsPluginLoad")); + auto load = reinterpret_cast<QbsPluginLoadFunction>(lib->resolve("QbsPluginLoad")); if (load) { load(); qCDebug(lcPluginManager) << "plugin" << QDir::toNativeSeparators(fileName) diff --git a/src/lib/corelib/tools/qttools.cpp b/src/lib/corelib/tools/qttools.cpp index 4e20a7f45..ffd336d56 100644 --- a/src/lib/corelib/tools/qttools.cpp +++ b/src/lib/corelib/tools/qttools.cpp @@ -39,7 +39,10 @@ #include "qttools.h" +#include <QtCore/qprocess.h> + QT_BEGIN_NAMESPACE + uint qHash(const QStringList &list) { uint s = 0; @@ -47,4 +50,10 @@ uint qHash(const QStringList &list) s ^= qHash(n) + 0x9e3779b9 + (s << 6) + (s >> 2); return s; } + +uint qHash(const QProcessEnvironment &env) +{ + return qHash(env.toStringList()); +} + QT_END_NAMESPACE diff --git a/src/lib/corelib/tools/qttools.h b/src/lib/corelib/tools/qttools.h index 50b2829d1..2252c12d3 100644 --- a/src/lib/corelib/tools/qttools.h +++ b/src/lib/corelib/tools/qttools.h @@ -45,6 +45,10 @@ #include <functional> +QT_BEGIN_NAMESPACE +class QProcessEnvironment; +QT_END_NAMESPACE + namespace std { template<> struct hash<QString> { std::size_t operator()(const QString &s) const { return qHash(s); } @@ -53,6 +57,7 @@ template<> struct hash<QString> { QT_BEGIN_NAMESPACE uint qHash(const QStringList &list); +uint qHash(const QProcessEnvironment &env); QT_END_NAMESPACE #endif // QBSQTTOOLS_H diff --git a/src/lib/corelib/tools/settingsmodel.h b/src/lib/corelib/tools/settingsmodel.h index 6f9631585..27936ba52 100644 --- a/src/lib/corelib/tools/settingsmodel.h +++ b/src/lib/corelib/tools/settingsmodel.h @@ -68,14 +68,16 @@ public: void addNewKey(const QModelIndex &parent); void removeKey(const QModelIndex &index); - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &child) const; + Qt::ItemFlags flags(const QModelIndex &index) const override; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &child) const override; private: class SettingsModelPrivate; diff --git a/src/lib/corelib/tools/setupprojectparameters.h b/src/lib/corelib/tools/setupprojectparameters.h index fd73d0748..fe7e3d487 100644 --- a/src/lib/corelib/tools/setupprojectparameters.h +++ b/src/lib/corelib/tools/setupprojectparameters.h @@ -97,7 +97,9 @@ public: void setOverriddenValues(const QVariantMap &values); QVariantMap overriddenValuesTree() const; - static QVariantMap expandedBuildConfiguration(const Profile &profile, const QString &configurationName, ErrorInfo *errorInfo = 0); + static QVariantMap expandedBuildConfiguration(const Profile &profile, + const QString &configurationName, + ErrorInfo *errorInfo = nullptr); ErrorInfo expandBuildConfiguration(); QVariantMap buildConfiguration() const; QVariantMap buildConfigurationTree() const; diff --git a/src/lib/corelib/tools/stringconstants.h b/src/lib/corelib/tools/stringconstants.h index f2666e070..6fcf3002b 100644 --- a/src/lib/corelib/tools/stringconstants.h +++ b/src/lib/corelib/tools/stringconstants.h @@ -104,6 +104,8 @@ public: QBS_STRING_CONSTANT(installPrefixProperty, "installPrefix") QBS_STRING_CONSTANT(installDirProperty, "installDir") QBS_STRING_CONSTANT(installSourceBaseProperty, "installSourceBase") + QBS_STRING_CONSTANT(jobCountProperty, "jobCount") + QBS_STRING_CONSTANT(jobPoolProperty, "jobPool") QBS_STRING_CONSTANT(lengthProperty, "length") QBS_STRING_CONSTANT(limitToSubProjectProperty, "limitToSubProject") QBS_STRING_CONSTANT(minimumQbsVersionProperty, "minimumQbsVersion") diff --git a/src/lib/corelib/tools/tools.pri b/src/lib/corelib/tools/tools.pri index bb3a55f12..f9c6be9a5 100644 --- a/src/lib/corelib/tools/tools.pri +++ b/src/lib/corelib/tools/tools.pri @@ -21,6 +21,7 @@ HEADERS += \ $$PWD/generateoptions.h \ $$PWD/id.h \ $$PWD/iosutils.h \ + $$PWD/joblimits.h \ $$PWD/jsliterals.h \ $$PWD/launcherinterface.h \ $$PWD/launcherpackets.h \ @@ -75,6 +76,7 @@ SOURCES += \ $$PWD/filetime.cpp \ $$PWD/generateoptions.cpp \ $$PWD/id.cpp \ + $$PWD/joblimits.cpp \ $$PWD/jsliterals.cpp \ $$PWD/launcherinterface.cpp \ $$PWD/launcherpackets.cpp \ @@ -124,6 +126,7 @@ osx { $$PWD/error.h \ $$PWD/generateoptions.h \ $$PWD/installoptions.h \ + $$PWD/joblimits.h \ $$PWD/preferences.h \ $$PWD/processresult.h \ $$PWD/profile.h \ diff --git a/src/lib/qtprofilesetup/qtmoduleinfo.cpp b/src/lib/qtprofilesetup/qtmoduleinfo.cpp index 56827a458..c225bde67 100644 --- a/src/lib/qtprofilesetup/qtmoduleinfo.cpp +++ b/src/lib/qtprofilesetup/qtmoduleinfo.cpp @@ -768,7 +768,9 @@ QList<QtModuleInfo> allQt5Modules(const Profile &profile, const QtEnvironment &q } else if (key.endsWith(".TYPE")) { moduleInfo.pluginData.type = QString::fromLatin1(value); } else if (key.endsWith(".EXTENDS")) { - moduleInfo.pluginData.extends = QString::fromLatin1(value); + moduleInfo.pluginData.extends = makeList(value); + if (moduleInfo.pluginData.extends.removeOne(QLatin1String("-"))) + moduleInfo.pluginData.autoLoad = false; } else if (key.endsWith(".CLASS_NAME")) { moduleInfo.pluginData.className = QString::fromLatin1(value); } diff --git a/src/lib/qtprofilesetup/qtmoduleinfo.h b/src/lib/qtprofilesetup/qtmoduleinfo.h index 318b5608f..078e08a19 100644 --- a/src/lib/qtprofilesetup/qtmoduleinfo.h +++ b/src/lib/qtprofilesetup/qtmoduleinfo.h @@ -95,8 +95,9 @@ public: struct PluginData { QString type; - QString extends; + QStringList extends; QString className; + bool autoLoad = true; } pluginData; private: diff --git a/src/lib/qtprofilesetup/qtprofilesetup.cpp b/src/lib/qtprofilesetup/qtprofilesetup.cpp index 1ee4aa3c6..f97b12f2c 100644 --- a/src/lib/qtprofilesetup/qtprofilesetup.cpp +++ b/src/lib/qtprofilesetup/qtprofilesetup.cpp @@ -418,10 +418,12 @@ static std::pair<int, int> findVariable(const QByteArray &content, int start) static QByteArray libraryFileTag(const QtEnvironment &env, const QtModuleInfo &module) { QByteArray result; - if (module.isStaticLibrary) + if (module.isStaticLibrary) { result = "staticlibrary"; - else - result = isMsvcQt(env) ? "dynamiclibrary_import" : "dynamiclibrary"; + } else { + result = isMsvcQt(env) || env.mkspecName.startsWith(QLatin1String("win32-g++")) + ? "dynamiclibrary_import" : "dynamiclibrary"; + } return result; } @@ -464,6 +466,7 @@ static void replaceSpecialValues(QByteArray *content, const Profile &profile, dict.insert("libFilePathRelease", utf8JSLiteral(module.libFilePathRelease)); dict.insert("libNameForLinkerDebug", utf8JSLiteral(module.libNameForLinker(qtEnvironment, true))); + dict.insert("pluginTypes", utf8JSLiteral(module.supportedPluginTypes)); dict.insert("libNameForLinkerRelease", utf8JSLiteral(module.libNameForLinker(qtEnvironment, false))); dict.insert("entryPointLibsDebug", utf8JSLiteral(qtEnvironment.entryPointLibsDebug)); @@ -515,15 +518,21 @@ static void replaceSpecialValues(QByteArray *content, const Profile &profile, additionalContent += "\n "; additionalContent += "isStaticLibrary: true"; } - if (module.isPlugin) + if (module.isPlugin) { dict.insert("className", utf8JSLiteral(module.pluginData.className)); + dict.insert("extends", utf8JSLiteral(module.pluginData.extends)); + } if (module.hasLibrary && !module.isFramework(qtEnvironment)) { if (!additionalContent.isEmpty()) additionalContent += "\n"; const QByteArray indent(4, ' '); - additionalContent += "Group {\n" - + indent + indent + "files: [Qt[\"" + module.qbsName.toUtf8() + "\"]" - + ".libFilePath]\n" + additionalContent += "Group {\n"; + if (module.isPlugin) { + additionalContent += indent + indent + + "condition: Qt[\"" + module.qbsName.toUtf8() + "\"].enableLinking\n"; + } + additionalContent += indent + indent + "files: [Qt[\"" + module.qbsName.toUtf8() + "\"]" + + ".libFilePath]\n" + indent + indent + "filesAreTargets: true\n" + indent + indent + "fileTags: [\"" + libraryFileTag(qtEnvironment, module) + "\"]\n" @@ -542,7 +551,8 @@ static void replaceSpecialValues(QByteArray *content, const Profile &profile, static void copyTemplateFile(const QString &fileName, const QString &targetDirectory, const Profile &profile, const QtEnvironment &qtEnv, QStringList *allFiles, - const QtModuleInfo *module = 0) + const QtModuleInfo *module = nullptr, const QVariantMap &pluginMap = QVariantMap(), + const QStringList &nonEssentialPlugins = QStringList()) { if (!QDir::root().mkpath(targetDirectory)) { throw ErrorInfo(Internal::Tr::tr("Setting up Qt profile '%1' failed: " @@ -555,8 +565,12 @@ static void copyTemplateFile(const QString &fileName, const QString &targetDirec "Cannot open '%1' (%2).").arg(sourceFile.fileName(), sourceFile.errorString())); } QByteArray newContent = sourceFile.readAll(); - if (module) + if (module) { replaceSpecialValues(&newContent, profile, *module, qtEnv); + } else { + newContent.replace("@allPluginsByType@", '(' + utf8JSLiteral(pluginMap) + ')'); + newContent.replace("@nonEssentialPlugins@", utf8JSLiteral(nonEssentialPlugins)); + } sourceFile.close(); const QString targetPath = targetDirectory + QLatin1Char('/') + fileName; allFiles->push_back(QFileInfo(targetPath).absoluteFilePath()); @@ -580,6 +594,16 @@ static void createModules(Profile &profile, Settings *settings, const QList<QtModuleInfo> modules = qtEnvironment.qtMajorVersion < 5 ? allQt4Modules(qtEnvironment) : allQt5Modules(profile, qtEnvironment); + QVariantMap pluginsByType; + QStringList nonEssentialPlugins; + for (const QtModuleInfo &m : modules) { + if (m.isPlugin) { + QVariant &v = pluginsByType[m.pluginData.type]; + v = v.toStringList() << m.name; + if (!m.pluginData.autoLoad) + nonEssentialPlugins << m.name; + } + } const QString profileBaseDir = QString::fromLatin1("%1/profiles/%2") .arg(QFileInfo(settings->fileName()).dir().absolutePath(), profile.name()); @@ -589,6 +613,9 @@ static void createModules(Profile &profile, Settings *settings, &allFiles); copyTemplateFile(QLatin1String("QtPlugin.qbs"), qbsQtModuleBaseDir, profile, qtEnvironment, &allFiles); + copyTemplateFile(QLatin1String("plugin_support.qbs"), + qbsQtModuleBaseDir + QLatin1String("/plugin_support"), profile, qtEnvironment, + &allFiles, nullptr, pluginsByType, nonEssentialPlugins); for (const QtModuleInfo &module : modules) { const QString qbsQtModuleDir = qbsQtModuleBaseDir + QLatin1Char('/') + module.qbsName; QString moduleTemplateFileName; @@ -629,6 +656,13 @@ static void createModules(Profile &profile, Settings *settings, copyTemplateFile(moduleTemplateFileName, qbsQtModuleDir, profile, qtEnvironment, &allFiles, &module); } + + // Note that it's not strictly necessary to copy this one, as it has no variable content. + // But we do it anyway for consistency (and it has no impact on the project files this way). + copyTemplateFile(QLatin1String("android_support.qbs"), + qbsQtModuleBaseDir + QLatin1String("/android_support"), profile, qtEnvironment, + &allFiles); + QDirIterator dit(qbsQtModuleBaseDir, QDirIterator::Subdirectories); while (dit.hasNext()) { dit.next(); diff --git a/src/lib/qtprofilesetup/templates.qrc b/src/lib/qtprofilesetup/templates.qrc index 3c6922862..35bddf8d7 100644 --- a/src/lib/qtprofilesetup/templates.qrc +++ b/src/lib/qtprofilesetup/templates.qrc @@ -16,5 +16,7 @@ <file>templates/qmlcache.qbs</file> <file>templates/quick.js</file> <file>templates/quick.qbs</file> + <file>templates/plugin_support.qbs</file> + <file>templates/android_support.qbs</file> </qresource> </RCC> diff --git a/src/lib/qtprofilesetup/templates/QtModule.qbs b/src/lib/qtprofilesetup/templates/QtModule.qbs index fcc8797cb..04820ee29 100644 --- a/src/lib/qtprofilesetup/templates/QtModule.qbs +++ b/src/lib/qtprofilesetup/templates/QtModule.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.FileInfo Module { @@ -14,6 +13,25 @@ Module { Depends { name: "cpp" } Depends { name: "Qt.core" } + Depends { name: "Qt.plugin_support" } + property stringList pluginTypes + Qt.plugin_support.pluginTypes: pluginTypes + Depends { + condition: Qt.core.staticBuild && !isPlugin + name: "Qt"; + submodules: { + // We have to pull in all plugins here, because dependency resolving happens + // before module merging, and we don't know yet if someone set + // Qt.pluginSupport.pluginsByType in the product. + // The real filtering is done later by the plugin module files themselves. + var list = []; + var allPlugins = Qt.plugin_support.allPluginsByType; + for (var i = 0; i < (pluginTypes || []).length; ++i) + Array.prototype.push.apply(list, allPlugins[pluginTypes[i]]) + return list; + } + } + property string qtModuleName property path binPath: Qt.core.binPath property path incPath: Qt.core.incPath @@ -54,9 +72,10 @@ Module { ? frameworkPathsDebug: frameworkPathsRelease cpp.linkerFlags: Qt.core.qtBuildVariant === "debug" ? linkerFlagsDebug : linkerFlagsRelease + property bool enableLinking: qtModuleName != undefined && hasLibrary Properties { - condition: qtModuleName != undefined && hasLibrary + condition: enableLinking cpp.staticLibraries: staticLibs cpp.dynamicLibraries: dynamicLibs cpp.frameworks: mFrameworks.concat(!isStaticLibrary && Qt.core.frameworkBuild diff --git a/src/lib/qtprofilesetup/templates/QtPlugin.qbs b/src/lib/qtprofilesetup/templates/QtPlugin.qbs index dceb8ef6e..23a6795f3 100644 --- a/src/lib/qtprofilesetup/templates/QtPlugin.qbs +++ b/src/lib/qtprofilesetup/templates/QtPlugin.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.FileInfo import qbs.TextFile @@ -6,9 +5,27 @@ QtModule { isPlugin: true property string className + property stringList extendsModules + + enableLinking: { + if (!base) + return false; + if (!isStaticLibrary) + return false; + if (!(Qt.plugin_support.enabledPlugins || []).contains(qtModuleName)) + return false; + if (!extendsModules || extendsModules.length === 0) + return true; + for (var i = 0; i < extendsModules.length; ++i) { + var moduleName = extendsModules[i]; + if (product.Qt[moduleName] && product.Qt[moduleName].present) + return true; + } + return false; + } Rule { - condition: isStaticLibrary + condition: enableLinking multiplex: true Artifact { filePath: product.targetName + "_qt_plugin_import_" diff --git a/src/lib/qtprofilesetup/templates/android_support.qbs b/src/lib/qtprofilesetup/templates/android_support.qbs new file mode 100644 index 000000000..79276a494 --- /dev/null +++ b/src/lib/qtprofilesetup/templates/android_support.qbs @@ -0,0 +1,291 @@ +import qbs.File +import qbs.FileInfo +import qbs.ModUtils +import qbs.TextFile +import qbs.Utilities + +Module { + property bool useMinistro: false + property string qmlRootDir: product.sourceDirectory + property stringList extraPrefixDirs + property stringList deploymentDependencies // qmake: ANDROID_DEPLOYMENT_DEPENDENCIES + property stringList extraPlugins // qmake: ANDROID_EXTRA_PLUGINS + property bool verboseAndroidDeployQt: false + + property string _androidDeployQtFilePath: FileInfo.joinPaths(_qtInstallDir, "bin", + "androiddeployqt") + property string _qtInstallDir + property bool _enableSdkSupport: product.type && product.type.contains("android.apk") + && !consoleApplication + property bool _enableNdkSupport: !product.aggregate || product.multiplexConfigurationId + property string _templatesBaseDir: FileInfo.joinPaths(_qtInstallDir, "src", "android") + property string _deployQtOutDir: FileInfo.joinPaths(product.buildDirectory, "deployqt_out") + + Depends { name: "Android.sdk"; condition: _enableSdkSupport } + Depends { name: "Android.ndk"; condition: _enableNdkSupport } + Depends { name: "java"; condition: _enableSdkSupport } + + Properties { + condition: _enableNdkSupport && qbs.toolchain.contains("clang") + Android.ndk.appStl: "c++_shared" + } + Properties { + condition: _enableNdkSupport && !qbs.toolchain.contains("clang") + Android.ndk.appStl: "gnustl_shared" + } + Properties { + condition: _enableSdkSupport + Android.sdk.customManifestProcessing: true + java._tagJniHeaders: false // prevent rule cycle + } + + Rule { + condition: _enableSdkSupport + multiplex: true + property stringList inputTags: "android.nativelibrary" + inputsFromDependencies: inputTags + inputs: product.aggregate ? [] : inputTags + Artifact { + filePath: "androiddeployqt.json" + fileTags: "qt_androiddeployqt_input" + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "creating " + output.fileName; + cmd.sourceCode = function() { + var theBinary; + var nativeLibs = inputs["android.nativelibrary"]; + if (nativeLibs.length === 1) { + theBinary = nativeLibs[0]; + } else { + for (i = 0; i < nativeLibs.length; ++i) { + var candidate = nativeLibs[i]; + if (!candidate.fileName.contains(candidate.product.targetName)) + continue; + if (!theBinary) { + theBinary = candidate; + continue; + } + if (theBinary.product.name === product.name + && candidate.product.name !== product.name) { + continue; // We already have a better match. + } + if (candidate.product.name === product.name + && theBinary.product.name !== product.name) { + theBinary = candidate; // The new candidate is a better match. + continue; + } + throw "Qt applications for Android support only one native binary " + + "per package.\n" + + "In particular, you cannot build a Qt app for more than " + + "one architecture at the same time."; + } + } + var f = new TextFile(output.filePath, TextFile.WriteOnly); + f.writeLine("{"); + f.writeLine('"description": "This file was generated by qbs to be read by ' + + 'androiddeployqt and should not be modified by hand.",'); + f.writeLine('"qt": "' + product.Qt.android_support._qtInstallDir + '",'); + f.writeLine('"sdk": "' + product.Android.sdk.sdkDir + '",'); + f.writeLine('"sdkBuildToolsRevision": "' + product.Android.sdk.buildToolsVersion + + '",'); + f.writeLine('"ndk": "' + product.Android.sdk.ndkDir + '",'); + var toolPrefix = theBinary.cpp.toolchainTriple; + var toolchainPrefix = toolPrefix.startsWith("i686-") ? "x86" : toolPrefix; + f.writeLine('"toolchain-prefix": "' + toolchainPrefix + '",'); + f.writeLine('"tool-prefix": "' + toolPrefix + '",'); + f.writeLine('"toolchain-version": "' + theBinary.Android.ndk.toolchainVersion + + '",'); + f.writeLine('"ndk-host": "' + theBinary.Android.ndk.hostArch + '",'); + f.writeLine('"target-architecture": "' + theBinary.Android.ndk.abi + '",'); + f.writeLine('"qml-root-path": "' + product.Qt.android_support.qmlRootDir + '",'); + var deploymentDeps = product.Qt.android_support.deploymentDependencies; + if (deploymentDeps && deploymentDeps.length > 0) + f.writeLine('"deployment-dependencies": "' + deploymentDeps.join() + '",'); + var extraPlugins = product.Qt.android_support.extraPlugins; + if (extraPlugins && extraPlugins.length > 0) + f.writeLine('"android-extra-plugins": "' + extraPlugins.join() + '",'); + var prefixDirs = product.Qt.android_support.extraPrefixDirs; + if (prefixDirs && prefixDirs.length > 0) + f.writeLine('"extraPrefixDirs": ' + JSON.stringify(prefixDirs) + ','); + if (Array.isArray(product.qmlImportPaths) && product.qmlImportPaths.length > 0) + f.writeLine('"qml-import-paths": "' + product.qmlImportPaths.join(',') + '",'); + f.writeLine('"application-binary": "' + theBinary.filePath + '"'); + f.writeLine("}"); + f.close(); + }; + return cmd; + } + } + + // We use the manifest template from the Qt installation if and only if the project + // does not provide a manifest file. + Rule { + condition: _enableSdkSupport + multiplex: true + requiresInputs: false + inputs: "android.manifest" + excludedInputs: "qt.android_manifest" + outputFileTags: ["android.manifest", "qt.android_manifest"] + outputArtifacts: { + if (inputs["android.manifest"]) + return []; + return [{ + filePath: "qt_manifest/AndroidManifest.xml", + fileTags: ["android.manifest", "qt.android_manifest"] + }]; + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "copying Qt Android manifest template"; + cmd.sourceCode = function() { + File.copy(FileInfo.joinPaths(product.Qt.android_support._templatesBaseDir, + "templates", "AndroidManifest.xml"), output.filePath); + }; + return cmd; + } + } + + Rule { + condition: _enableSdkSupport + multiplex: true + inputs: ["qt_androiddeployqt_input", "android.manifest_processed"] + outputFileTags: [ + "android.manifest_final", "android.resources", "android.assets", "bundled_jar", + "android.deployqt_list", + ] + outputArtifacts: { + var artifacts = [ + { + filePath: "AndroidManifest.xml", + fileTags: "android.manifest_final" + }, + { + filePath: product.Qt.android_support._deployQtOutDir + "/res/values/libs.xml", + fileTags: "android.resources" + }, + { + filePath: product.Qt.android_support._deployQtOutDir + + "/res/values/strings.xml", + fileTags: "android.resources" + }, + { + filePath: product.Qt.android_support._deployQtOutDir + "/assets/.dummy", + fileTags: "android.assets" + }, + { + filePath: "deployqt.list", + fileTags: "android.deployqt_list" + }, + + ]; + if (!product.Qt.android_support.useMinistro) { + artifacts.push({ + filePath: FileInfo.joinPaths(product.java.classFilesDir, "QtAndroid.jar"), + fileTags: ["bundled_jar"] + }); + } + return artifacts; + } + prepare: { + var copyCmd = new JavaScriptCommand(); + copyCmd.description = "copying Qt resource templates"; + copyCmd.sourceCode = function() { + File.copy(inputs["android.manifest_processed"][0].filePath, + product.Qt.android_support._deployQtOutDir + "/AndroidManifest.xml"); + File.copy(product.Qt.android_support._templatesBaseDir + "/java/res", + product.Qt.android_support._deployQtOutDir + "/res"); + File.copy(product.Qt.android_support._templatesBaseDir + + "/templates/res/values/libs.xml", + product.Qt.android_support._deployQtOutDir + "/res/values/libs.xml"); + try { + File.remove(FileInfo.path(outputs["android.assets"][0].filePath)); + } catch (e) { + } + }; + var androidDeployQtArgs = [ + "--output", product.Qt.android_support._deployQtOutDir, + "--input", inputs["qt_androiddeployqt_input"][0].filePath, "--aux-mode", + "--deployment", product.Qt.android_support.useMinistro ? "ministro" : "bundled", + "--android-platform", product.Android.sdk.platform, + ]; + if (product.Qt.android_support.verboseAndroidDeployQt) + args.push("--verbose"); + var androidDeployQtCmd = new Command( + product.Qt.android_support._androidDeployQtFilePath, androidDeployQtArgs); + androidDeployQtCmd.description = "running androiddeployqt"; + + // We do not want androiddeployqt to write directly into our APK base dir, so + // we ran it on an isolated directory and now we move stuff over. + // We remember the files for which we do that, so if the next invocation + // of androiddeployqt creates fewer files, the other ones are removed from + // the APK base dir. + var moveCmd = new JavaScriptCommand(); + moveCmd.description = "processing androiddeployqt outout"; + moveCmd.sourceCode = function() { + File.move(product.Qt.android_support._deployQtOutDir + "/AndroidManifest.xml", + outputs["android.manifest_final"][0].filePath); + var libsDir = product.Qt.android_support._deployQtOutDir + "/libs"; + var libDir = product.Android.sdk.apkContentsDir + "/lib"; + var listFilePath = outputs["android.deployqt_list"][0].filePath; + var oldLibs = []; + try { + var listFile = new TextFile(listFilePath, TextFile.ReadOnly); + var listFileLine = listFile.readLine(); + while (listFileLine) { + oldLibs.push(listFileLine); + listFileLine = listFile.readLine(); + } + listFile.close(); + } catch (e) { + } + listFile = new TextFile(listFilePath, TextFile.WriteOnly); + var newLibs = []; + var moveLibFiles = function(prefix) { + var fullSrcPrefix = FileInfo.joinPaths(libsDir, prefix); + var files = File.directoryEntries(fullSrcPrefix, File.Files); + for (var i = 0; i < files.length; ++i) { + var file = files[i]; + var srcFilePath = FileInfo.joinPaths(fullSrcPrefix, file); + var targetFilePath; + if (file.endsWith(".jar")) + targetFilePath = FileInfo.joinPaths(product.java.classFilesDir, file); + else + targetFilePath = FileInfo.joinPaths(libDir, prefix, file); + File.move(srcFilePath, targetFilePath); + listFile.writeLine(targetFilePath); + newLibs.push(targetFilePath); + } + var dirs = File.directoryEntries(fullSrcPrefix, + File.Dirs | File.NoDotAndDotDot); + for (i = 0; i < dirs.length; ++i) + moveLibFiles(FileInfo.joinPaths(prefix, dirs[i])); + }; + moveLibFiles(""); + listFile.close(); + for (i = 0; i < oldLibs.length; ++i) { + if (!newLibs.contains(oldLibs[i])) + File.remove(oldLibs[i]); + } + }; + return [copyCmd, androidDeployQtCmd, moveCmd]; + } + } + + Group { + condition: Qt.android_support._enableSdkSupport + name: "helper sources from qt" + prefix: Qt.android_support._templatesBaseDir + "/java/" + Android.sdk.aidlSearchPaths: prefix + "src" + files: [ + "**/*.java", + "**/*.aidl", + ] + } + + validate: { + if (Utilities.versionCompare(version, "5.12") < 0) + throw ModUtils.ModuleError("Cannot use Qt " + version + " with Android. " + + "Version 5.12 or later is required."); + } +} diff --git a/src/lib/qtprofilesetup/templates/core.qbs b/src/lib/qtprofilesetup/templates/core.qbs index 928c69cda..7abd7aa02 100644 --- a/src/lib/qtprofilesetup/templates/core.qbs +++ b/src/lib/qtprofilesetup/templates/core.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.FileInfo import qbs.ModUtils import qbs.TextFile @@ -19,6 +18,13 @@ Module { Depends { name: "cpp" } + Depends { name: "Qt.android_support"; condition: qbs.targetOS.contains("android") } + Properties { + condition: qbs.targetOS.contains("android") + Qt.android_support._qtInstallDir: FileInfo.path(binPath) + Qt.android_support.version: version + } + version: @version@ property stringList architectures: @archs@ property string targetPlatform: @targetPlatform@ @@ -172,7 +178,6 @@ Module { cpp.cxxFlags: { var flags = []; if (qbs.toolchain.contains('msvc')) { - flags.push('/Zm200'); if (versionMajor < 5) flags.push('/Zc:wchar_t-'); } @@ -266,49 +271,27 @@ Module { } property bool combineMocOutput: cpp.combineCxxSources + property bool enableBigResources: false Rule { - name: "QtCoreMocRule" + name: "QtCoreMocRuleCpp" property string cppInput: cpp.combineCxxSources ? "cpp.combine" : "cpp" property string objcppInput: cpp.combineObjcxxSources ? "objcpp.combine" : "objcpp" - inputs: [objcppInput, cppInput, "hpp"] - auxiliaryInputs: { - var auxInputs = ["qt_plugin_metadata"]; - if (cpp.combineCxxSources) - auxInputs.push("cpp"); - if (cpp.combineObjcxxSources) - auxInputs.push("objcpp"); - return auxInputs; - } - excludedInputs: ["unmocable"] + inputs: [objcppInput, cppInput] + auxiliaryInputs: "qt_plugin_metadata" + excludedInputs: "unmocable" + outputFileTags: ["hpp", "unmocable"] + outputArtifacts: Moc.outputArtifacts.apply(Moc, arguments) + prepare: Moc.commands.apply(Moc, arguments) + } + Rule { + name: "QtCoreMocRuleHpp" + inputs: "hpp" + auxiliaryInputs: ["qt_plugin_metadata", "cpp", "objcpp"]; + excludedInputs: "unmocable" outputFileTags: ["hpp", "cpp", "moc_cpp", "unmocable"] - outputArtifacts: { - if (input.fileTags.contains("unmocable")) - return []; - var mocinfo = QtMocScanner.apply(input); - if (!mocinfo.hasQObjectMacro) - return []; - var artifact = { fileTags: ["unmocable"] }; - if (input.fileTags.contains("hpp")) { - artifact.filePath = input.Qt.core.generatedHeadersDir - + "/moc_" + input.completeBaseName + ".cpp"; - } else { - artifact.filePath = input.Qt.core.generatedHeadersDir - + '/' + input.completeBaseName + ".moc"; - } - var amalgamate = input.Qt.core.combineMocOutput; - artifact.fileTags.push(mocinfo.mustCompile ? (amalgamate ? "moc_cpp" : "cpp") : "hpp"); - if (mocinfo.hasPluginMetaDataMacro) - artifact.explicitlyDependsOn = ["qt_plugin_metadata"]; - return [artifact]; - } - prepare: { - var cmd = new Command(Moc.fullPath(product), - Moc.args(product, input, output.filePath)); - cmd.description = 'moc ' + input.fileName; - cmd.highlight = 'codegen'; - return cmd; - } + outputArtifacts: Moc.outputArtifacts.apply(Moc, arguments) + prepare: Moc.commands.apply(Moc, arguments) } Rule { @@ -387,17 +370,60 @@ Module { Rule { inputs: ["qrc"] + outputFileTags: ["cpp", "cpp_intermediate_object"] + outputArtifacts: { + var artifact = { + filePath: "qrc_" + input.completeBaseName + ".cpp", + fileTags: ["cpp"] + }; + if (input.Qt.core.enableBigResources) + artifact.fileTags.push("cpp_intermediate_object"); + return [artifact]; + } + prepare: { + var args = [input.filePath, + "-name", FileInfo.completeBaseName(input.filePath), + "-o", output.filePath]; + if (input.Qt.core.enableBigResources) + args.push("-pass", "1"); + var cmd = new Command(product.Qt.core.binPath + '/rcc', args); + cmd.description = "rcc " + + (input.Qt.core.enableBigResources ? "(pass 1) " : "") + + input.fileName; + cmd.highlight = 'codegen'; + return cmd; + } + } + Rule { + inputs: ["intermediate_obj"] Artifact { - filePath: "qrc_" + input.completeBaseName + ".cpp" - fileTags: ["cpp"] + filePath: input.completeBaseName + ".2.o" + fileTags: ["obj"] } prepare: { + function findChild(artifact, predicate) { + var children = artifact.children; + var len = children.length; + for (var i = 0; i < len; ++i) { + var child = children[i]; + if (predicate(child)) + return child; + child = findChild(child, predicate); + if (child) + return child; + } + return undefined; + } + var qrcArtifact = findChild(input, function(c) { return c.fileTags.contains("qrc"); }); + var cppArtifact = findChild(input, function(c) { return c.fileTags.contains("cpp"); }); var cmd = new Command(product.Qt.core.binPath + '/rcc', - [input.filePath, '-name', - FileInfo.completeBaseName(input.filePath), - '-o', output.filePath]); - cmd.description = 'rcc ' + input.fileName; + [qrcArtifact.filePath, + "-temp", input.filePath, + "-name", FileInfo.completeBaseName(input.filePath), + "-o", output.filePath, + "-pass", "2"]); + cmd.description = "rcc (pass 2) " + qrcArtifact.fileName; cmd.highlight = 'codegen'; return cmd; } diff --git a/src/lib/qtprofilesetup/templates/dbus.qbs b/src/lib/qtprofilesetup/templates/dbus.qbs index 2bbcf1985..9245a63e3 100644 --- a/src/lib/qtprofilesetup/templates/dbus.qbs +++ b/src/lib/qtprofilesetup/templates/dbus.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.FileInfo import qbs.ModUtils import "../QtModule.qbs" as QtModule @@ -63,6 +62,7 @@ QtModule { libNameForLinkerRelease: @libNameForLinkerRelease@ libFilePathDebug: @libFilePathDebug@ libFilePathRelease: @libFilePathRelease@ + pluginTypes: @pluginTypes@ cpp.defines: @defines@ cpp.includePaths: @includes@ diff --git a/src/lib/qtprofilesetup/templates/gui.qbs b/src/lib/qtprofilesetup/templates/gui.qbs index 81b3bc2fb..eb69e0cad 100644 --- a/src/lib/qtprofilesetup/templates/gui.qbs +++ b/src/lib/qtprofilesetup/templates/gui.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.FileInfo import qbs.ModUtils import '../QtModule.qbs' as QtModule @@ -49,6 +48,7 @@ QtModule { libNameForLinkerRelease: @libNameForLinkerRelease@ libFilePathDebug: @libFilePathDebug@ libFilePathRelease: @libFilePathRelease@ + pluginTypes: @pluginTypes@ cpp.defines: @defines@ cpp.includePaths: @includes@ diff --git a/src/lib/qtprofilesetup/templates/moc.js b/src/lib/qtprofilesetup/templates/moc.js index a9fddbc8a..aa67766b9 100644 --- a/src/lib/qtprofilesetup/templates/moc.js +++ b/src/lib/qtprofilesetup/templates/moc.js @@ -71,3 +71,32 @@ function fullPath(product) { return product.Qt.core.binPath + '/' + product.Qt.core.mocName; } + +function outputArtifacts(project, product, inputs, input) +{ + var mocInfo = QtMocScanner.apply(input); + if (!mocInfo.hasQObjectMacro) + return []; + var artifact = { fileTags: ["unmocable"] }; + if (mocInfo.hasPluginMetaDataMacro) + artifact.explicitlyDependsOn = ["qt_plugin_metadata"]; + if (input.fileTags.contains("hpp")) { + artifact.filePath = input.Qt.core.generatedHeadersDir + + "/moc_" + input.completeBaseName + ".cpp"; + var amalgamate = input.Qt.core.combineMocOutput; + artifact.fileTags.push(mocInfo.mustCompile ? (amalgamate ? "moc_cpp" : "cpp") : "hpp"); + } else { + artifact.filePath = input.Qt.core.generatedHeadersDir + '/' + + input.completeBaseName + ".moc"; + artifact.fileTags.push("hpp"); + } + return [artifact]; +} + +function commands(project, product, inputs, outputs, input, output) +{ + var cmd = new Command(fullPath(product), args(product, input, output.filePath)); + cmd.description = 'moc ' + input.fileName; + cmd.highlight = 'codegen'; + return cmd; +} diff --git a/src/lib/qtprofilesetup/templates/module.qbs b/src/lib/qtprofilesetup/templates/module.qbs index d16307e32..60ad106e5 100644 --- a/src/lib/qtprofilesetup/templates/module.qbs +++ b/src/lib/qtprofilesetup/templates/module.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import '../QtModule.qbs' as QtModule QtModule { @@ -22,6 +21,7 @@ QtModule { libNameForLinkerRelease: @libNameForLinkerRelease@ libFilePathDebug: @libFilePathDebug@ libFilePathRelease: @libFilePathRelease@ + pluginTypes: @pluginTypes@ cpp.defines: @defines@ cpp.includePaths: @includes@ cpp.libraryPaths: @libraryPaths@ diff --git a/src/lib/qtprofilesetup/templates/plugin.qbs b/src/lib/qtprofilesetup/templates/plugin.qbs index 378d8b8fe..e73e2a4d9 100644 --- a/src/lib/qtprofilesetup/templates/plugin.qbs +++ b/src/lib/qtprofilesetup/templates/plugin.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import '../QtPlugin.qbs' as QtPlugin QtPlugin { @@ -23,5 +22,6 @@ QtPlugin { libFilePathDebug: @libFilePathDebug@ libFilePathRelease: @libFilePathRelease@ cpp.libraryPaths: @libraryPaths@ + extendsModules: @extends@ @additionalContent@ } diff --git a/src/lib/qtprofilesetup/templates/plugin_support.qbs b/src/lib/qtprofilesetup/templates/plugin_support.qbs new file mode 100644 index 000000000..13d95c383 --- /dev/null +++ b/src/lib/qtprofilesetup/templates/plugin_support.qbs @@ -0,0 +1,75 @@ +Module { + // Set by user. + property varList pluginsByType + + // Set by Qt modules. + property stringList pluginTypes + + // Set by setup-qt. + readonly property var allPluginsByType: @allPluginsByType@ + readonly property stringList nonEssentialPlugins: @nonEssentialPlugins@ + + // Derived. + readonly property var defaultPluginsByType: { + var map = {}; + for (var i = 0; i < (pluginTypes || []).length; ++i) { + var pType = pluginTypes[i]; + map[pType] = (allPluginsByType[pType] || []).filter(function(p) { + return !nonEssentialPlugins.contains(p); }); + } + return map; + } + readonly property var effectivePluginsByType: { + var ppt = pluginsByType || []; + var eppt = {}; + for (var i = 0; i < ppt.length; ++i) { + var listEntry = ppt[i]; + for (var pluginType in listEntry) { + var newValue = listEntry[pluginType]; + if (!newValue) + newValue = []; + else if (typeof newValue == "string") + newValue = [newValue]; + if (!Array.isArray(newValue)) + throw "Invalid value '" + newValue + "' in Qt.plugin_support.pluginsByType"; + eppt[pluginType] = (eppt[pluginType] || []).uniqueConcat(newValue); + } + } + var dppt = defaultPluginsByType; + for (var pluginType in dppt) { + if (!eppt[pluginType]) + eppt[pluginType] = dppt[pluginType]; + } + return eppt; + } + readonly property stringList enabledPlugins: { + var list = []; + var eppt = effectivePluginsByType; + for (var t in eppt) + Array.prototype.push.apply(list, eppt[t]); + return list; + } + + validate: { + var ppt = pluginsByType; + if (!ppt) + return; + var appt = allPluginsByType; + for (var i = 0; i < ppt.length; ++i) { + for (var pluginType in ppt[i]) { + var requestedPlugins = ppt[i][pluginType]; + if (!requestedPlugins) + continue; + var availablePlugins = appt[pluginType] || []; + if (typeof requestedPlugins === "string") + requestedPlugins = [requestedPlugins]; + for (var j = 0; j < requestedPlugins.length; ++j) { + if (!availablePlugins.contains(requestedPlugins[j])) { + throw "Plugin '" + requestedPlugins[j] + "' of type '" + pluginType + + "' was requested, but is not available."; + } + } + } + } + } +} diff --git a/src/lib/qtprofilesetup/templates/qml.qbs b/src/lib/qtprofilesetup/templates/qml.qbs index 3047873af..51bb5faa2 100644 --- a/src/lib/qtprofilesetup/templates/qml.qbs +++ b/src/lib/qtprofilesetup/templates/qml.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile import '../QtModule.qbs' as QtModule import "qml.js" as Qml @@ -43,6 +42,7 @@ QtModule { libNameForLinkerRelease: @libNameForLinkerRelease@ libFilePathDebug: @libFilePathDebug@ libFilePathRelease: @libFilePathRelease@ + pluginTypes: @pluginTypes@ cpp.defines: @defines@ cpp.includePaths: @includes@ cpp.libraryPaths: @libraryPaths@ diff --git a/src/lib/qtprofilesetup/templates/quick.qbs b/src/lib/qtprofilesetup/templates/quick.qbs index 745f29cc2..67394cabb 100644 --- a/src/lib/qtprofilesetup/templates/quick.qbs +++ b/src/lib/qtprofilesetup/templates/quick.qbs @@ -28,7 +28,6 @@ ** ****************************************************************************/ -import qbs import qbs.File import qbs.FileInfo import qbs.Process @@ -58,6 +57,7 @@ QtModule { libNameForLinkerRelease: @libNameForLinkerRelease@ libFilePathDebug: @libFilePathDebug@ libFilePathRelease: @libFilePathRelease@ + pluginTypes: @pluginTypes@ cpp.defines: @defines@ cpp.includePaths: @includes@ cpp.libraryPaths: @libraryPaths@ diff --git a/src/lib/qtprofilesetup/templates/scxml.qbs b/src/lib/qtprofilesetup/templates/scxml.qbs index 0581ff8d3..b02a49246 100644 --- a/src/lib/qtprofilesetup/templates/scxml.qbs +++ b/src/lib/qtprofilesetup/templates/scxml.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.FileInfo import qbs.Utilities import "../QtModule.qbs" as QtModule @@ -22,7 +21,7 @@ QtModule { } Artifact { filePath: input.baseName + ".cpp" - fileTags: ["cpp"] + fileTags: ["cpp", "unmocable"] } prepare: { @@ -70,6 +69,7 @@ QtModule { libNameForLinkerRelease: @libNameForLinkerRelease@ libFilePathDebug: @libFilePathDebug@ libFilePathRelease: @libFilePathRelease@ + pluginTypes: @pluginTypes@ cpp.defines: @defines@ cpp.includePaths: @includes@ diff --git a/src/libexec/qbs_processlauncher/qbs_processlauncher.qbs b/src/libexec/qbs_processlauncher/qbs_processlauncher.qbs index cfd2ec814..7aa7d3fc0 100644 --- a/src/libexec/qbs_processlauncher/qbs_processlauncher.qbs +++ b/src/libexec/qbs_processlauncher/qbs_processlauncher.qbs @@ -5,8 +5,6 @@ QbsProduct { type: "application" name: "qbs_processlauncher" consoleApplication: true - destinationDirectory: FileInfo.joinPaths(project.buildDirectory, - qbsbuildconfig.libexecInstallDir) Depends { name: "Qt.network" } @@ -34,8 +32,8 @@ QbsProduct { fileTagsFilter: product.type .concat(qbs.buildVariant === "debug" ? ["debuginfo_app"] : []) qbs.install: true - qbs.installSourceBase: destinationDirectory qbs.installDir: targetInstallDir + qbs.installSourceBase: buildDirectory } targetInstallDir: qbsbuildconfig.libexecInstallDir } diff --git a/src/packages/chocolatey/chocolatey.qbs b/src/packages/chocolatey/chocolatey.qbs index bb4856dab..cb8dd6bc6 100644 --- a/src/packages/chocolatey/chocolatey.qbs +++ b/src/packages/chocolatey/chocolatey.qbs @@ -14,7 +14,7 @@ Product { id: choco condition: qbs.targetOS.contains("windows") names: ["choco"] - platformPaths: { + platformSearchPaths: { var chocolateyInstall = Environment.getEnv("ChocolateyInstall"); if (chocolateyInstall) return [FileInfo.joinPaths(chocolateyInstall, "bin")]; diff --git a/src/plugins/qbsplugin.qbs b/src/plugins/qbsplugin.qbs index 269614e11..0f31a8a78 100644 --- a/src/plugins/qbsplugin.qbs +++ b/src/plugins/qbsplugin.qbs @@ -17,15 +17,13 @@ QbsProduct { } cpp.includePaths: base.concat(["../../../lib/corelib"]) cpp.visibility: "minimal" - destinationDirectory: FileInfo.joinPaths(project.buildDirectory, - qbsbuildconfig.libDirName + "/qbs/plugins") Group { fileTagsFilter: [isForDarwin ? "loadablemodule" : "dynamiclibrary"] .concat(qbs.buildVariant === "debug" ? [isForDarwin ? "debuginfo_loadablemodule" : "debuginfo_dll"] : []) qbs.install: true - qbs.installSourceBase: destinationDirectory qbs.installDir: targetInstallDir + qbs.installSourceBase: buildDirectory } targetInstallDir: qbsbuildconfig.pluginsInstallDir Properties { diff --git a/src/shared/bundledqt/bundledqt.qbs b/src/shared/bundledqt/bundledqt.qbs index 8c90dbbea..6e9b744ab 100644 --- a/src/shared/bundledqt/bundledqt.qbs +++ b/src/shared/bundledqt/bundledqt.qbs @@ -9,7 +9,8 @@ Product { property bool deployQt: qbsbuildconfig.enableBundledQt && qbs.targetOS.contains("macos") && Qt.core.qtConfig.contains("rpath") - property bool deployDebugLibraries: qbs.buildVariants.contains("debug") + property bool deployDebugLibraries: qbs.buildVariant === "debug" + || (qbs.buildVariants && qbs.buildVariants.contains("debug")) readonly property string qtDebugLibrarySuffix: { if (qbs.targetOS.contains("windows")) @@ -32,6 +33,8 @@ Product { name: "Qt libraries" files: !Qt.core.staticBuild ? Array.prototype.concat.apply( [], Object.getOwnPropertyNames(Qt).map(function(mod) { + if (mod === "script" && !Qt[mod].present) + return []; if (!Qt[mod].hasLibrary) return []; var fp = Qt[mod].libFilePathRelease; diff --git a/static-res.pro b/static-res.pro index b35836ece..86816bbf0 100644 --- a/static-res.pro +++ b/static-res.pro @@ -3,6 +3,18 @@ TEMPLATE = aux !isEmpty(QBS_APPS_DESTDIR): qbsbindir = $${QBS_APPS_DESTDIR} else: qbsbindir = bin +envSpec = +unix:qbs_disable_rpath { + !isEmpty(QBS_DESTDIR): qbslibdir = $$QBS_DESTDIR + else: qbslibdir = $$OUT_PWD/lib + macos: envVar = DYLD_LIBRARY_PATH + else: envVar = LD_LIBRARY_PATH + oldVal = $$getenv($$envVar) + newVal = $$qbslibdir + !isEmpty(oldVal): newVal = $$newVal:$$oldVal + envSpec = $$envVar=$$newVal +} + builddirname = qbsres typedescdir = share/qbs/qml-type-descriptions typedescdir_src = $$builddirname/default/install-root/$$typedescdir @@ -15,12 +27,13 @@ else: \ qbsres.target = $$builddirname/default/default.bg qbsres.commands = \ - $$shell_quote($$shell_path($$qbsbindir/qbs)) \ + $$envSpec $$shell_quote($$shell_path($$qbsbindir/qbs)) \ build \ --settings-dir $$shell_quote($$builddirname/settings) \ -f $$shell_quote($$PWD/qbs.qbs) \ -d $$shell_quote($$builddirname) \ -p $$shell_quote("qbs resources") \ + qbs.installPrefix:undefined \ project.withCode:false \ project.withDocumentation:false \ profile:none diff --git a/static.pro b/static.pro index b0ab1b950..e172648b0 100644 --- a/static.pro +++ b/static.pro @@ -77,6 +77,7 @@ python_bin.files = $$files(src/3rdparty/python/bin/*) python_bin.path = $${QBS_LIBEXEC_INSTALL_DIR} else: \ python_bin.path = $${QBS_INSTALL_PREFIX}/libexec/qbs -python.files = $$files(src/3rdparty/python/lib/python2.7/site-packages/*) +python.files = $$files(src/3rdparty/python/lib/python2.7/site-packages/*.py, true) +python.base = $$PWD/src/3rdparty/python/lib/python2.7/site-packages python.path = $${share.path}/qbs/python INSTALLS += share examples python_bin python diff --git a/tests/auto/api/testdata/QBS-728/QBS-728.qbs b/tests/auto/api/testdata/QBS-728/QBS-728.qbs index a3090f7ae..5969e13cc 100644 --- a/tests/auto/api/testdata/QBS-728/QBS-728.qbs +++ b/tests/auto/api/testdata/QBS-728/QBS-728.qbs @@ -1,5 +1,3 @@ -import qbs - Product { property bool isBlubbOS: qbs.targetOS.contains("blubb-OS") qbs.profiles: isBlubbOS ? ["blubb-profile"] : [project.profile] diff --git a/tests/auto/api/testdata/add-qobject-macro-to-cpp-file/add-qobject-macro-to-cpp-file.qbs b/tests/auto/api/testdata/add-qobject-macro-to-cpp-file/add-qobject-macro-to-cpp-file.qbs index 40c5395ef..3794408b4 100644 --- a/tests/auto/api/testdata/add-qobject-macro-to-cpp-file/add-qobject-macro-to-cpp-file.qbs +++ b/tests/auto/api/testdata/add-qobject-macro-to-cpp-file/add-qobject-macro-to-cpp-file.qbs @@ -1,5 +1,3 @@ -import qbs - QtApplication { files: ["main.cpp", "object.h", "object.cpp"] } diff --git a/tests/auto/api/testdata/added-file-persistent/added-file-persistent.qbs b/tests/auto/api/testdata/added-file-persistent/added-file-persistent.qbs index 672886646..1f3b28f9b 100644 --- a/tests/auto/api/testdata/added-file-persistent/added-file-persistent.qbs +++ b/tests/auto/api/testdata/added-file-persistent/added-file-persistent.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: [ 'main.cpp', diff --git a/tests/auto/api/testdata/app-without-sources/app-without-sources.qbs b/tests/auto/api/testdata/app-without-sources/app-without-sources.qbs index f12a28fe6..a366e0ce0 100644 --- a/tests/auto/api/testdata/app-without-sources/app-without-sources.qbs +++ b/tests/auto/api/testdata/app-without-sources/app-without-sources.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { StaticLibrary { name: "a" diff --git a/tests/auto/api/testdata/base-properties/imports/Bar.qbs b/tests/auto/api/testdata/base-properties/imports/Bar.qbs index 07ab724e4..cef4cb463 100644 --- a/tests/auto/api/testdata/base-properties/imports/Bar.qbs +++ b/tests/auto/api/testdata/base-properties/imports/Bar.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { Depends { name: "cpp" } cpp.defines: ["FROM_BAR"] diff --git a/tests/auto/api/testdata/base-properties/imports/Foo.qbs b/tests/auto/api/testdata/base-properties/imports/Foo.qbs index f177a17c3..1d90a1c10 100644 --- a/tests/auto/api/testdata/base-properties/imports/Foo.qbs +++ b/tests/auto/api/testdata/base-properties/imports/Foo.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Bar { type: "application" consoleApplication: true diff --git a/tests/auto/api/testdata/base-properties/prj.qbs b/tests/auto/api/testdata/base-properties/prj.qbs index a43b930dc..f7035ba0f 100644 --- a/tests/auto/api/testdata/base-properties/prj.qbs +++ b/tests/auto/api/testdata/base-properties/prj.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import "imports/Foo.qbs" as Foo Project { diff --git a/tests/auto/api/testdata/build-error-code-location/build-error-code-location.qbs b/tests/auto/api/testdata/build-error-code-location/build-error-code-location.qbs index f51e91e1f..afa7e1f2a 100644 --- a/tests/auto/api/testdata/build-error-code-location/build-error-code-location.qbs +++ b/tests/auto/api/testdata/build-error-code-location/build-error-code-location.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "p" type: ["p.out"] diff --git a/tests/auto/api/testdata/build-properties-source/build-properties-source.qbs b/tests/auto/api/testdata/build-properties-source/build-properties-source.qbs index 485bca79d..571feced8 100644 --- a/tests/auto/api/testdata/build-properties-source/build-properties-source.qbs +++ b/tests/auto/api/testdata/build-properties-source/build-properties-source.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { type: "application" diff --git a/tests/auto/api/testdata/build-single-file/build-single-file.qbs b/tests/auto/api/testdata/build-single-file/build-single-file.qbs index eeb38a5ff..903a52f9d 100644 --- a/tests/auto/api/testdata/build-single-file/build-single-file.qbs +++ b/tests/auto/api/testdata/build-single-file/build-single-file.qbs @@ -1,7 +1,7 @@ -import qbs import qbs.TextFile CppApplication { + consoleApplication: true files: ["ignored1.cpp", "ignored2.cpp", "compiled.cpp"] cpp.includePaths: [buildDirectory] @@ -10,10 +10,8 @@ CppApplication { fileTags: ["cpp_pch_src"] } - Group { - fileTagsFilter: ["application"] - qbs.install: true - } + install: true + installDir: "" Rule { multiplex: true diff --git a/tests/auto/api/testdata/buildgraph-info/buildgraph-info.qbs b/tests/auto/api/testdata/buildgraph-info/buildgraph-info.qbs index 8828f3a19..d1762513e 100644 --- a/tests/auto/api/testdata/buildgraph-info/buildgraph-info.qbs +++ b/tests/auto/api/testdata/buildgraph-info/buildgraph-info.qbs @@ -1,5 +1,3 @@ -import qbs - Product { qbs.shellPath: "/bin/bash" } diff --git a/tests/auto/api/testdata/buildgraph-locking/buildgraph-locking.qbs b/tests/auto/api/testdata/buildgraph-locking/buildgraph-locking.qbs index e08b008bc..5e7259ea6 100644 --- a/tests/auto/api/testdata/buildgraph-locking/buildgraph-locking.qbs +++ b/tests/auto/api/testdata/buildgraph-locking/buildgraph-locking.qbs @@ -1,4 +1,2 @@ -import qbs - Project { } diff --git a/tests/auto/api/testdata/change-dependent-lib/change-dependent-lib.qbs b/tests/auto/api/testdata/change-dependent-lib/change-dependent-lib.qbs index f52c90055..222dc4476 100644 --- a/tests/auto/api/testdata/change-dependent-lib/change-dependent-lib.qbs +++ b/tests/auto/api/testdata/change-dependent-lib/change-dependent-lib.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Application { name : "HelloWorld" diff --git a/tests/auto/api/testdata/check-outputs/check-outputs.qbs b/tests/auto/api/testdata/check-outputs/check-outputs.qbs index 27eada48f..519a95ea8 100644 --- a/tests/auto/api/testdata/check-outputs/check-outputs.qbs +++ b/tests/auto/api/testdata/check-outputs/check-outputs.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Project { diff --git a/tests/auto/api/testdata/codegen/codegen.qbs b/tests/auto/api/testdata/codegen/codegen.qbs index fac13f860..d8a217572 100644 --- a/tests/auto/api/testdata/codegen/codegen.qbs +++ b/tests/auto/api/testdata/codegen/codegen.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.FileInfo Project { diff --git a/tests/auto/api/testdata/command-extraction/command-extraction.qbs b/tests/auto/api/testdata/command-extraction/command-extraction.qbs index 73b66aaa0..253992dd0 100644 --- a/tests/auto/api/testdata/command-extraction/command-extraction.qbs +++ b/tests/auto/api/testdata/command-extraction/command-extraction.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: "main.cpp" } diff --git a/tests/auto/api/testdata/disabled-product/disabled-product.qbs b/tests/auto/api/testdata/disabled-product/disabled-product.qbs index c57615c10..dad8f5d4c 100644 --- a/tests/auto/api/testdata/disabled-product/disabled-product.qbs +++ b/tests/auto/api/testdata/disabled-product/disabled-product.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { condition: false files: "main.cpp" diff --git a/tests/auto/api/testdata/disabled-project/disabled-project.qbs b/tests/auto/api/testdata/disabled-project/disabled-project.qbs index 1461b70ad..49f35be94 100644 --- a/tests/auto/api/testdata/disabled-project/disabled-project.qbs +++ b/tests/auto/api/testdata/disabled-project/disabled-project.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Project { diff --git a/tests/auto/api/testdata/disabled_install_group/disabled_install_group.qbs b/tests/auto/api/testdata/disabled_install_group/disabled_install_group.qbs index b80af6e8a..c300f6390 100644 --- a/tests/auto/api/testdata/disabled_install_group/disabled_install_group.qbs +++ b/tests/auto/api/testdata/disabled_install_group/disabled_install_group.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { consoleApplication: true files: "main.cpp" diff --git a/tests/auto/api/testdata/duplicate-product-names/explicit.qbs b/tests/auto/api/testdata/duplicate-product-names/explicit.qbs index 0183b411c..b9a97bf53 100644 --- a/tests/auto/api/testdata/duplicate-product-names/explicit.qbs +++ b/tests/auto/api/testdata/duplicate-product-names/explicit.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "blubb" } Product { name: "blubb" } diff --git a/tests/auto/api/testdata/duplicate-product-names/implicit-indirect.qbs b/tests/auto/api/testdata/duplicate-product-names/implicit-indirect.qbs index 7164aa1c5..bc651c076 100644 --- a/tests/auto/api/testdata/duplicate-product-names/implicit-indirect.qbs +++ b/tests/auto/api/testdata/duplicate-product-names/implicit-indirect.qbs @@ -1,5 +1,3 @@ -import qbs - Project { references: ["subdir1/subproject.qbs", "subdir2/subproject.qbs"] } diff --git a/tests/auto/api/testdata/duplicate-product-names/implicit.qbs b/tests/auto/api/testdata/duplicate-product-names/implicit.qbs index f39f80626..409af1ab8 100644 --- a/tests/auto/api/testdata/duplicate-product-names/implicit.qbs +++ b/tests/auto/api/testdata/duplicate-product-names/implicit.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { } Product { } diff --git a/tests/auto/api/testdata/duplicate-product-names/subdir1/subproject.qbs b/tests/auto/api/testdata/duplicate-product-names/subdir1/subproject.qbs index 6d16a3c53..86718b571 100644 --- a/tests/auto/api/testdata/duplicate-product-names/subdir1/subproject.qbs +++ b/tests/auto/api/testdata/duplicate-product-names/subdir1/subproject.qbs @@ -1,3 +1 @@ -import qbs - Product { } diff --git a/tests/auto/api/testdata/duplicate-product-names/subdir2/subproject.qbs b/tests/auto/api/testdata/duplicate-product-names/subdir2/subproject.qbs index 6d16a3c53..86718b571 100644 --- a/tests/auto/api/testdata/duplicate-product-names/subdir2/subproject.qbs +++ b/tests/auto/api/testdata/duplicate-product-names/subdir2/subproject.qbs @@ -1,3 +1 @@ -import qbs - Product { } diff --git a/tests/auto/api/testdata/empty-filetag-list/empty-filetag-list.qbs b/tests/auto/api/testdata/empty-filetag-list/empty-filetag-list.qbs index 294616124..a13065db0 100644 --- a/tests/auto/api/testdata/empty-filetag-list/empty-filetag-list.qbs +++ b/tests/auto/api/testdata/empty-filetag-list/empty-filetag-list.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Group { files: "dontcompilethis.cpp" diff --git a/tests/auto/api/testdata/empty-submodules-list/empty-submodules-list.qbs b/tests/auto/api/testdata/empty-submodules-list/empty-submodules-list.qbs index 88b5e3177..b39b1ebcc 100644 --- a/tests/auto/api/testdata/empty-submodules-list/empty-submodules-list.qbs +++ b/tests/auto/api/testdata/empty-submodules-list/empty-submodules-list.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Depends { name: "dummy" diff --git a/tests/auto/api/testdata/enable-and-disable-product/enable-and-disable-product.qbs b/tests/auto/api/testdata/enable-and-disable-product/enable-and-disable-product.qbs index 4afa1e25e..fc90377af 100644 --- a/tests/auto/api/testdata/enable-and-disable-product/enable-and-disable-product.qbs +++ b/tests/auto/api/testdata/enable-and-disable-product/enable-and-disable-product.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { property string prop: undefined // Influences source artifact properties and the product condition condition: prop diff --git a/tests/auto/api/testdata/error-in-setup-run-environment/error-in-setup-run-environment.qbs b/tests/auto/api/testdata/error-in-setup-run-environment/error-in-setup-run-environment.qbs index f3247f6f8..63a79551b 100644 --- a/tests/auto/api/testdata/error-in-setup-run-environment/error-in-setup-run-environment.qbs +++ b/tests/auto/api/testdata/error-in-setup-run-environment/error-in-setup-run-environment.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Depends { name: "mymodule" } } diff --git a/tests/auto/api/testdata/error-in-setup-run-environment/modules/mymodule/mymodule.qbs b/tests/auto/api/testdata/error-in-setup-run-environment/modules/mymodule/mymodule.qbs index e698b45b5..1b136fdb9 100644 --- a/tests/auto/api/testdata/error-in-setup-run-environment/modules/mymodule/mymodule.qbs +++ b/tests/auto/api/testdata/error-in-setup-run-environment/modules/mymodule/mymodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { setupRunEnvironment: { trallala diff --git a/tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs b/tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs index faa51d3b9..7633b3ebe 100644 --- a/tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs +++ b/tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.TextFile diff --git a/tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs b/tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs index 17aa74697..05886a99e 100644 --- a/tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs +++ b/tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo import qbs.TextFile diff --git a/tests/auto/api/testdata/export-item-with-group/export-item-with-group.qbs b/tests/auto/api/testdata/export-item-with-group/export-item-with-group.qbs index 30f1868cb..b2079e95f 100644 --- a/tests/auto/api/testdata/export-item-with-group/export-item-with-group.qbs +++ b/tests/auto/api/testdata/export-item-with-group/export-item-with-group.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "dep" diff --git a/tests/auto/api/testdata/export-simple/export-simple.qbs b/tests/auto/api/testdata/export-simple/export-simple.qbs index d07bb0d1a..01177049d 100644 --- a/tests/auto/api/testdata/export-simple/export-simple.qbs +++ b/tests/auto/api/testdata/export-simple/export-simple.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Application { name : "HelloWorld" diff --git a/tests/auto/api/testdata/export-with-recursive-depends/export-with-recursive-depends.qbs b/tests/auto/api/testdata/export-with-recursive-depends/export-with-recursive-depends.qbs index d5f5f79e5..937a73e21 100644 --- a/tests/auto/api/testdata/export-with-recursive-depends/export-with-recursive-depends.qbs +++ b/tests/auto/api/testdata/export-with-recursive-depends/export-with-recursive-depends.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "app1" diff --git a/tests/auto/api/testdata/export-with-recursive-depends/modules/module1/module1.qbs b/tests/auto/api/testdata/export-with-recursive-depends/modules/module1/module1.qbs index c1c4ad358..c7aadde69 100644 --- a/tests/auto/api/testdata/export-with-recursive-depends/modules/module1/module1.qbs +++ b/tests/auto/api/testdata/export-with-recursive-depends/modules/module1/module1.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "module2" } } diff --git a/tests/auto/api/testdata/export-with-recursive-depends/modules/module2/module2.qbs b/tests/auto/api/testdata/export-with-recursive-depends/modules/module2/module2.qbs index 75a274631..2b5f6014e 100644 --- a/tests/auto/api/testdata/export-with-recursive-depends/modules/module2/module2.qbs +++ b/tests/auto/api/testdata/export-with-recursive-depends/modules/module2/module2.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } cpp.defines: ["HAS_FOO"] diff --git a/tests/auto/api/testdata/fallback-gcc/fallback-gcc.qbs b/tests/auto/api/testdata/fallback-gcc/fallback-gcc.qbs index 8b3b63e65..e2fb255ad 100644 --- a/tests/auto/api/testdata/fallback-gcc/fallback-gcc.qbs +++ b/tests/auto/api/testdata/fallback-gcc/fallback-gcc.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "app" cpp._skipAllChecks: true diff --git a/tests/auto/api/testdata/file-tagger/moc_cpp.qbs b/tests/auto/api/testdata/file-tagger/moc_cpp.qbs index fd07730dc..43fa5f330 100644 --- a/tests/auto/api/testdata/file-tagger/moc_cpp.qbs +++ b/tests/auto/api/testdata/file-tagger/moc_cpp.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.TextFile import qbs.FileInfo diff --git a/tests/auto/api/testdata/filetagsfilter_override/InstalledApp.qbs b/tests/auto/api/testdata/filetagsfilter_override/InstalledApp.qbs index 633410c3c..21db6b37a 100644 --- a/tests/auto/api/testdata/filetagsfilter_override/InstalledApp.qbs +++ b/tests/auto/api/testdata/filetagsfilter_override/InstalledApp.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { type: "application" consoleApplication: true diff --git a/tests/auto/api/testdata/filetagsfilter_override/filetagsfilter_override.qbs b/tests/auto/api/testdata/filetagsfilter_override/filetagsfilter_override.qbs index a6cec7d07..6483e8851 100644 --- a/tests/auto/api/testdata/filetagsfilter_override/filetagsfilter_override.qbs +++ b/tests/auto/api/testdata/filetagsfilter_override/filetagsfilter_override.qbs @@ -1,4 +1,3 @@ -import qbs import "InstalledApp.qbs" as InstalledApp InstalledApp { diff --git a/tests/auto/api/testdata/generated-files-list/generated-files-list.qbs b/tests/auto/api/testdata/generated-files-list/generated-files-list.qbs index 30f7bc695..666d72645 100644 --- a/tests/auto/api/testdata/generated-files-list/generated-files-list.qbs +++ b/tests/auto/api/testdata/generated-files-list/generated-files-list.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Depends { name: "Qt.widgets" } consoleApplication: true diff --git a/tests/auto/api/testdata/infinite-loop-js/infinite-loop.qbs b/tests/auto/api/testdata/infinite-loop-js/infinite-loop.qbs index 592c602ec..bb616a9e2 100644 --- a/tests/auto/api/testdata/infinite-loop-js/infinite-loop.qbs +++ b/tests/auto/api/testdata/infinite-loop-js/infinite-loop.qbs @@ -1,5 +1,3 @@ -import qbs - Product { type: "mytype" Rule { diff --git a/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs b/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs index 6155baf28..f0de12df1 100644 --- a/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs +++ b/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { type: "application" @@ -14,10 +12,7 @@ Project { Depends { name: "infinite-loop" } Rule { inputsFromDependencies: "application" - Artifact { - filePath: "dummy" - fileTags: "mytype" - } + outputFileTags: "mytype" prepare: { var cmd = new Command(inputs["application"][0].filePath); cmd.description = "Calling application that runs forever"; diff --git a/tests/auto/api/testdata/infinite-loop-resolving/infinite-loop-resolving.qbs b/tests/auto/api/testdata/infinite-loop-resolving/infinite-loop-resolving.qbs index b690f5041..e9d0db418 100644 --- a/tests/auto/api/testdata/infinite-loop-resolving/infinite-loop-resolving.qbs +++ b/tests/auto/api/testdata/infinite-loop-resolving/infinite-loop-resolving.qbs @@ -1,5 +1,3 @@ -import qbs - Product { type: { while (true); return "Haha!"; } } diff --git a/tests/auto/api/testdata/inherit-qbs-search-paths/imports/Foo.qbs b/tests/auto/api/testdata/inherit-qbs-search-paths/imports/Foo.qbs index 9493b04b5..8920c0fc6 100644 --- a/tests/auto/api/testdata/inherit-qbs-search-paths/imports/Foo.qbs +++ b/tests/auto/api/testdata/inherit-qbs-search-paths/imports/Foo.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { type: "application" consoleApplication: true diff --git a/tests/auto/api/testdata/inherit-qbs-search-paths/prj.qbs b/tests/auto/api/testdata/inherit-qbs-search-paths/prj.qbs index 0e8162809..d79a1ed70 100644 --- a/tests/auto/api/testdata/inherit-qbs-search-paths/prj.qbs +++ b/tests/auto/api/testdata/inherit-qbs-search-paths/prj.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import "imports/Foo.qbs" as Foo Project { diff --git a/tests/auto/api/testdata/inherit-qbs-search-paths/subdir/modules/bli/m.qbs b/tests/auto/api/testdata/inherit-qbs-search-paths/subdir/modules/bli/m.qbs index b4b93678a..34ac9e8e9 100644 --- a/tests/auto/api/testdata/inherit-qbs-search-paths/subdir/modules/bli/m.qbs +++ b/tests/auto/api/testdata/inherit-qbs-search-paths/subdir/modules/bli/m.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Module { Depends {name : "cpp" } cpp.defines: ["HAVE_BLI"] diff --git a/tests/auto/api/testdata/inherit-qbs-search-paths/subdir2/modules/bla/m.qbs b/tests/auto/api/testdata/inherit-qbs-search-paths/subdir2/modules/bla/m.qbs index 0676d0c4d..de93f18e8 100644 --- a/tests/auto/api/testdata/inherit-qbs-search-paths/subdir2/modules/bla/m.qbs +++ b/tests/auto/api/testdata/inherit-qbs-search-paths/subdir2/modules/bla/m.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Module { Depends {name : "cpp" } cpp.defines: ["HAVE_BLA"] diff --git a/tests/auto/api/testdata/installed-artifact/installed-artifact.qbs b/tests/auto/api/testdata/installed-artifact/installed-artifact.qbs index e2d18b2ea..d3f91662a 100644 --- a/tests/auto/api/testdata/installed-artifact/installed-artifact.qbs +++ b/tests/auto/api/testdata/installed-artifact/installed-artifact.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { CppApplication { @@ -18,11 +16,8 @@ Project { qbs.installDir: "src" } qbs.installPrefix: "/usr" - Group { - fileTagsFilter: "application" - qbs.install: true - qbs.installDir: "bin" - } + install: true + installDir: "bin" Group { fileTagsFilter: "obj" qbs.install: true diff --git a/tests/auto/api/testdata/is-runnable/is-runnable.qbs b/tests/auto/api/testdata/is-runnable/is-runnable.qbs index 2883328ed..870279294 100644 --- a/tests/auto/api/testdata/is-runnable/is-runnable.qbs +++ b/tests/auto/api/testdata/is-runnable/is-runnable.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "app" diff --git a/tests/auto/api/testdata/lib-same-source/lib-same-source.qbs b/tests/auto/api/testdata/lib-same-source/lib-same-source.qbs index dc5785e98..97a614eb8 100644 --- a/tests/auto/api/testdata/lib-same-source/lib-same-source.qbs +++ b/tests/auto/api/testdata/lib-same-source/lib-same-source.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { type: "application" diff --git a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/link-dynamiclibs-staticlibs.qbs b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/link-dynamiclibs-staticlibs.qbs index 8fec45700..b2a54080c 100644 --- a/tests/auto/api/testdata/link-dynamiclibs-staticlibs/link-dynamiclibs-staticlibs.qbs +++ b/tests/auto/api/testdata/link-dynamiclibs-staticlibs/link-dynamiclibs-staticlibs.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Application { name : "HelloWorld" diff --git a/tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs b/tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs index d6047060c..cc86a4402 100644 --- a/tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs +++ b/tests/auto/api/testdata/link-dynamiclibs/link-dynamiclibs.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Application { name : "HelloWorld" diff --git a/tests/auto/api/testdata/link-static-lib/link-static-lib.qbs b/tests/auto/api/testdata/link-static-lib/link-static-lib.qbs index 6840a4cc6..6960c7d17 100644 --- a/tests/auto/api/testdata/link-static-lib/link-static-lib.qbs +++ b/tests/auto/api/testdata/link-static-lib/link-static-lib.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { type: "application" diff --git a/tests/auto/api/testdata/link-staticlib-dynamiclib/link-staticlib-dynamiclib.qbs b/tests/auto/api/testdata/link-staticlib-dynamiclib/link-staticlib-dynamiclib.qbs index a14cde651..8573b2f60 100644 --- a/tests/auto/api/testdata/link-staticlib-dynamiclib/link-staticlib-dynamiclib.qbs +++ b/tests/auto/api/testdata/link-staticlib-dynamiclib/link-staticlib-dynamiclib.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { CppApplication { Depends { name: "mystaticlib" } diff --git a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs index eafa764ba..eade97126 100644 --- a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs +++ b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Application { name : "HelloWorld" diff --git a/tests/auto/api/testdata/local-profiles/local-profiles.qbs b/tests/auto/api/testdata/local-profiles/local-profiles.qbs index 7832cab58..c6091f9f5 100644 --- a/tests/auto/api/testdata/local-profiles/local-profiles.qbs +++ b/tests/auto/api/testdata/local-profiles/local-profiles.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property string windowsProfile: "windowsProfile" property bool enableProfiles diff --git a/tests/auto/api/testdata/lots-of-dots/lots-of-dots.qbs b/tests/auto/api/testdata/lots-of-dots/lots-of-dots.qbs index 904cbcf66..096fcaf0c 100644 --- a/tests/auto/api/testdata/lots-of-dots/lots-of-dots.qbs +++ b/tests/auto/api/testdata/lots-of-dots/lots-of-dots.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { QtGuiApplication { type: "application" diff --git a/tests/auto/api/testdata/missing-source-file/missing-source-file.qbs b/tests/auto/api/testdata/missing-source-file/missing-source-file.qbs index db666f9fd..bc17bc7dd 100644 --- a/tests/auto/api/testdata/missing-source-file/missing-source-file.qbs +++ b/tests/auto/api/testdata/missing-source-file/missing-source-file.qbs @@ -1,5 +1,3 @@ -import qbs - Product { files: [ "file1.txt", diff --git a/tests/auto/api/testdata/moc-cpp/moc-cpp.qbs b/tests/auto/api/testdata/moc-cpp/moc-cpp.qbs index f8ee0736b..a6445a399 100644 --- a/tests/auto/api/testdata/moc-cpp/moc-cpp.qbs +++ b/tests/auto/api/testdata/moc-cpp/moc-cpp.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { type: "application" diff --git a/tests/auto/api/testdata/moc-hpp-included/moc-hpp-included.qbs b/tests/auto/api/testdata/moc-hpp-included/moc-hpp-included.qbs index b954d09f0..a484b9c22 100644 --- a/tests/auto/api/testdata/moc-hpp-included/moc-hpp-included.qbs +++ b/tests/auto/api/testdata/moc-hpp-included/moc-hpp-included.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { type: "application" diff --git a/tests/auto/api/testdata/moc-hpp/moc-hpp.qbs b/tests/auto/api/testdata/moc-hpp/moc-hpp.qbs index f90ee4240..27120aade 100644 --- a/tests/auto/api/testdata/moc-hpp/moc-hpp.qbs +++ b/tests/auto/api/testdata/moc-hpp/moc-hpp.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { type: "application" diff --git a/tests/auto/api/testdata/multi-arch/multi-arch.qbs b/tests/auto/api/testdata/multi-arch/multi-arch.qbs index d54809a41..71a66dfc7 100644 --- a/tests/auto/api/testdata/multi-arch/multi-arch.qbs +++ b/tests/auto/api/testdata/multi-arch/multi-arch.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo import qbs.TextFile @@ -14,6 +13,7 @@ Project { files: "host+target.input" fileTags: "input" } + qbs.installPrefix: "" Group { fileTagsFilter: "output" qbs.install: true @@ -28,6 +28,7 @@ Project { files: "host-tool.input" fileTags: "input" } + qbs.installPrefix: "" Group { fileTagsFilter: "output" qbs.install: true diff --git a/tests/auto/api/testdata/multiplexing/multiplexing.qbs b/tests/auto/api/testdata/multiplexing/multiplexing.qbs index 3d099eb7a..8011e4250 100644 --- a/tests/auto/api/testdata/multiplexing/multiplexing.qbs +++ b/tests/auto/api/testdata/multiplexing/multiplexing.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Project { diff --git a/tests/auto/api/testdata/new-output-artifact-in-dependency/new-output-artifact-in-dependency.qbs b/tests/auto/api/testdata/new-output-artifact-in-dependency/new-output-artifact-in-dependency.qbs index 8b50cce2a..5c3e475b0 100644 --- a/tests/auto/api/testdata/new-output-artifact-in-dependency/new-output-artifact-in-dependency.qbs +++ b/tests/auto/api/testdata/new-output-artifact-in-dependency/new-output-artifact-in-dependency.qbs @@ -1,5 +1,3 @@ -import qbs - Project { DynamicLibrary { //Depends { name: "cpp" } diff --git a/tests/auto/api/testdata/new-pattern-match/new-pattern-match.qbs b/tests/auto/api/testdata/new-pattern-match/new-pattern-match.qbs index 18975da75..f4e0856f9 100644 --- a/tests/auto/api/testdata/new-pattern-match/new-pattern-match.qbs +++ b/tests/auto/api/testdata/new-pattern-match/new-pattern-match.qbs @@ -1,5 +1,3 @@ -import qbs - Product { files: "*.txt" } diff --git a/tests/auto/api/testdata/nonexistingprojectproperties/invalidaccessfromproduct.qbs b/tests/auto/api/testdata/nonexistingprojectproperties/invalidaccessfromproduct.qbs index c024b3c2c..5f479c1c5 100644 --- a/tests/auto/api/testdata/nonexistingprojectproperties/invalidaccessfromproduct.qbs +++ b/tests/auto/api/testdata/nonexistingprojectproperties/invalidaccessfromproduct.qbs @@ -1,3 +1 @@ -import qbs - Project { Product { type: project.blubb } } diff --git a/tests/auto/api/testdata/nonexistingprojectproperties/nonexistingprojectproperties.qbs b/tests/auto/api/testdata/nonexistingprojectproperties/nonexistingprojectproperties.qbs index 7d453a671..ba86b0ab7 100644 --- a/tests/auto/api/testdata/nonexistingprojectproperties/nonexistingprojectproperties.qbs +++ b/tests/auto/api/testdata/nonexistingprojectproperties/nonexistingprojectproperties.qbs @@ -1,3 +1 @@ -import qbs - Project { } diff --git a/tests/auto/api/testdata/objc/objc.qbs b/tests/auto/api/testdata/objc/objc.qbs index c88d4693c..845eb8d32 100644 --- a/tests/auto/api/testdata/objc/objc.qbs +++ b/tests/auto/api/testdata/objc/objc.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { CppApplication { condition: qbs.targetOS.contains("macos") diff --git a/tests/auto/api/testdata/precompiled-header-dynamic/precompiled-header-dynamic.qbs b/tests/auto/api/testdata/precompiled-header-dynamic/precompiled-header-dynamic.qbs index 46de774b9..2fd58d24e 100644 --- a/tests/auto/api/testdata/precompiled-header-dynamic/precompiled-header-dynamic.qbs +++ b/tests/auto/api/testdata/precompiled-header-dynamic/precompiled-header-dynamic.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File CppApplication { diff --git a/tests/auto/api/testdata/precompiled-header-new/precompiled-header-new.qbs b/tests/auto/api/testdata/precompiled-header-new/precompiled-header-new.qbs index bb82ed248..059400a21 100644 --- a/tests/auto/api/testdata/precompiled-header-new/precompiled-header-new.qbs +++ b/tests/auto/api/testdata/precompiled-header-new/precompiled-header-new.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - CppApplication { name: "MyApp" consoleApplication: true diff --git a/tests/auto/api/testdata/process-result/process-result.qbs b/tests/auto/api/testdata/process-result/process-result.qbs index 2aaf0626e..84706ace8 100644 --- a/tests/auto/api/testdata/process-result/process-result.qbs +++ b/tests/auto/api/testdata/process-result/process-result.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "app" @@ -15,11 +13,7 @@ Project { property int argument Rule { inputsFromDependencies: ["application"] - Artifact { - filePath: "dummy" - fileTags: product.type - alwaysUpdated: false - } + outputFileTags: "mytype" prepare: { var cmd = new Command(inputs["application"][0].filePath, [product.argument]); if (product.redirectStdout) diff --git a/tests/auto/api/testdata/productNameWithDots/productNameWithDots.qbs b/tests/auto/api/testdata/productNameWithDots/productNameWithDots.qbs index 5e3427793..972598c42 100644 --- a/tests/auto/api/testdata/productNameWithDots/productNameWithDots.qbs +++ b/tests/auto/api/testdata/productNameWithDots/productNameWithDots.qbs @@ -1,4 +1,3 @@ -import qbs Project { CppApplication { name: "myapp" diff --git a/tests/auto/api/testdata/project-data-after-product-invalidation/project-data-after-product-invalidation.qbs b/tests/auto/api/testdata/project-data-after-product-invalidation/project-data-after-product-invalidation.qbs index be68cac47..1794205b4 100644 --- a/tests/auto/api/testdata/project-data-after-product-invalidation/project-data-after-product-invalidation.qbs +++ b/tests/auto/api/testdata/project-data-after-product-invalidation/project-data-after-product-invalidation.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "theProduct" files: [ diff --git a/tests/auto/api/testdata/project-editing/project-editing.qbs b/tests/auto/api/testdata/project-editing/project-editing.qbs index 57cb30355..f8c0aef46 100644 --- a/tests/auto/api/testdata/project-editing/project-editing.qbs +++ b/tests/auto/api/testdata/project-editing/project-editing.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Group { name: "Existing Group 1" diff --git a/tests/auto/api/testdata/project-editing/project-with-no-files.qbs b/tests/auto/api/testdata/project-editing/project-with-no-files.qbs index 824ae6dcd..b12ac6813 100644 --- a/tests/auto/api/testdata/project-editing/project-with-no-files.qbs +++ b/tests/auto/api/testdata/project-editing/project-with-no-files.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Group { files: "file.cpp" diff --git a/tests/auto/api/testdata/project-invalidation/project.early-error.qbs b/tests/auto/api/testdata/project-invalidation/project.early-error.qbs index ecc76c816..701da0eab 100644 --- a/tests/auto/api/testdata/project-invalidation/project.early-error.qbs +++ b/tests/auto/api/testdata/project-invalidation/project.early-error.qbs @@ -1,5 +1,3 @@ -import qbs - Product { type: "mytype" files: "nosuchfile.txt" diff --git a/tests/auto/api/testdata/project-invalidation/project.late-error.qbs b/tests/auto/api/testdata/project-invalidation/project.late-error.qbs index 6bce6f2d3..ce033adbd 100644 --- a/tests/auto/api/testdata/project-invalidation/project.late-error.qbs +++ b/tests/auto/api/testdata/project-invalidation/project.late-error.qbs @@ -1,5 +1,3 @@ -import qbs - Product { type: "mytype" diff --git a/tests/auto/api/testdata/project-invalidation/project.no-error.qbs b/tests/auto/api/testdata/project-invalidation/project.no-error.qbs index 099553ffc..f37cbd64b 100644 --- a/tests/auto/api/testdata/project-invalidation/project.no-error.qbs +++ b/tests/auto/api/testdata/project-invalidation/project.no-error.qbs @@ -1,5 +1,3 @@ -import qbs - Product { type: "mytype" } diff --git a/tests/auto/api/testdata/project-locking/project-locking.qbs b/tests/auto/api/testdata/project-locking/project-locking.qbs index e08b008bc..5e7259ea6 100644 --- a/tests/auto/api/testdata/project-locking/project-locking.qbs +++ b/tests/auto/api/testdata/project-locking/project-locking.qbs @@ -1,4 +1,2 @@ -import qbs - Project { } diff --git a/tests/auto/api/testdata/project-properties-by-name/project-properties-by-name.qbs b/tests/auto/api/testdata/project-properties-by-name/project-properties-by-name.qbs index b90068f87..0bc9d3eab 100644 --- a/tests/auto/api/testdata/project-properties-by-name/project-properties-by-name.qbs +++ b/tests/auto/api/testdata/project-properties-by-name/project-properties-by-name.qbs @@ -1,5 +1,3 @@ -import qbs - Project { name: "toplevel" property stringList theDefines: [] diff --git a/tests/auto/api/testdata/project-with-properties-item/project-with-properties-item.qbs b/tests/auto/api/testdata/project-with-properties-item/project-with-properties-item.qbs index 91d5de42f..866ec4ecb 100644 --- a/tests/auto/api/testdata/project-with-properties-item/project-with-properties-item.qbs +++ b/tests/auto/api/testdata/project-with-properties-item/project-with-properties-item.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { property string binPath: "/usr/bin" property string libPath: "/usr/lib" diff --git a/tests/auto/api/testdata/properties-blocks/properties-blocks.qbs b/tests/auto/api/testdata/properties-blocks/properties-blocks.qbs index 1b4c3680a..dda4652d2 100644 --- a/tests/auto/api/testdata/properties-blocks/properties-blocks.qbs +++ b/tests/auto/api/testdata/properties-blocks/properties-blocks.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { Depends { name: 'cpp' } diff --git a/tests/auto/api/testdata/rc/rc.qbs b/tests/auto/api/testdata/rc/rc.qbs index 3a5ce9cab..5b49c5de9 100644 --- a/tests/auto/api/testdata/rc/rc.qbs +++ b/tests/auto/api/testdata/rc/rc.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Application { type: "application" consoleApplication: true diff --git a/tests/auto/api/testdata/recursive-wildcards/recursive-wildcards.qbs b/tests/auto/api/testdata/recursive-wildcards/recursive-wildcards.qbs index a1970e1c4..df54577f6 100644 --- a/tests/auto/api/testdata/recursive-wildcards/recursive-wildcards.qbs +++ b/tests/auto/api/testdata/recursive-wildcards/recursive-wildcards.qbs @@ -1,4 +1,5 @@ Product { + qbs.installPrefix: "" Group { files: "dir/**" qbs.install: true diff --git a/tests/auto/api/testdata/referenced-file-errors/cycle.qbs b/tests/auto/api/testdata/referenced-file-errors/cycle.qbs index 72ad2b8b8..ec1a90921 100644 --- a/tests/auto/api/testdata/referenced-file-errors/cycle.qbs +++ b/tests/auto/api/testdata/referenced-file-errors/cycle.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property string productName: "p1" Product { name: project.productName } diff --git a/tests/auto/api/testdata/referenced-file-errors/modules/brokenmodule/brokenmodule.qbs b/tests/auto/api/testdata/referenced-file-errors/modules/brokenmodule/brokenmodule.qbs index 861a73931..b52f12ccd 100644 --- a/tests/auto/api/testdata/referenced-file-errors/modules/brokenmodule/brokenmodule.qbs +++ b/tests/auto/api/testdata/referenced-file-errors/modules/brokenmodule/brokenmodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { syntax error } diff --git a/tests/auto/api/testdata/referenced-file-errors/okay.qbs b/tests/auto/api/testdata/referenced-file-errors/okay.qbs index 6ec8b1edd..4f88b3990 100644 --- a/tests/auto/api/testdata/referenced-file-errors/okay.qbs +++ b/tests/auto/api/testdata/referenced-file-errors/okay.qbs @@ -1,3 +1 @@ -import qbs - Product { name: "p2" } diff --git a/tests/auto/api/testdata/referenced-file-errors/okay2.qbs b/tests/auto/api/testdata/referenced-file-errors/okay2.qbs index f3b92dd93..0c5b26750 100644 --- a/tests/auto/api/testdata/referenced-file-errors/okay2.qbs +++ b/tests/auto/api/testdata/referenced-file-errors/okay2.qbs @@ -1,3 +1 @@ -import qbs - Product { name: "p4" } diff --git a/tests/auto/api/testdata/referenced-file-errors/referenced-file-errors.qbs b/tests/auto/api/testdata/referenced-file-errors/referenced-file-errors.qbs index b6b255ab3..eb33f1452 100644 --- a/tests/auto/api/testdata/referenced-file-errors/referenced-file-errors.qbs +++ b/tests/auto/api/testdata/referenced-file-errors/referenced-file-errors.qbs @@ -1,5 +1,3 @@ -import qbs - Project { references: [ "ambiguousdir", diff --git a/tests/auto/api/testdata/referenced-file-errors/wrongtype.qbs b/tests/auto/api/testdata/referenced-file-errors/wrongtype.qbs index 9322b53b1..cd8c6471d 100644 --- a/tests/auto/api/testdata/referenced-file-errors/wrongtype.qbs +++ b/tests/auto/api/testdata/referenced-file-errors/wrongtype.qbs @@ -1,3 +1 @@ -import qbs - Module { } diff --git a/tests/auto/api/testdata/references/invalid1.qbs b/tests/auto/api/testdata/references/invalid1.qbs index 4bbb26d3a..ec4095d83 100644 --- a/tests/auto/api/testdata/references/invalid1.qbs +++ b/tests/auto/api/testdata/references/invalid1.qbs @@ -1,5 +1,3 @@ -import qbs - Project { references: "subdir-with-no-project" }
\ No newline at end of file diff --git a/tests/auto/api/testdata/references/invalid2.qbs b/tests/auto/api/testdata/references/invalid2.qbs index 1946e2221..249c80b4f 100644 --- a/tests/auto/api/testdata/references/invalid2.qbs +++ b/tests/auto/api/testdata/references/invalid2.qbs @@ -1,5 +1,3 @@ -import qbs - Project { references: "subdir-with-multiple-projects" }
\ No newline at end of file diff --git a/tests/auto/api/testdata/references/subdir-with-one-project/p.qbs b/tests/auto/api/testdata/references/subdir-with-one-project/p.qbs index 7d453a671..ba86b0ab7 100644 --- a/tests/auto/api/testdata/references/subdir-with-one-project/p.qbs +++ b/tests/auto/api/testdata/references/subdir-with-one-project/p.qbs @@ -1,3 +1 @@ -import qbs - Project { } diff --git a/tests/auto/api/testdata/references/valid.qbs b/tests/auto/api/testdata/references/valid.qbs index 43d728a4d..97ed7f564 100644 --- a/tests/auto/api/testdata/references/valid.qbs +++ b/tests/auto/api/testdata/references/valid.qbs @@ -1,5 +1,3 @@ -import qbs - Project { references: "subdir-with-one-project" } diff --git a/tests/auto/api/testdata/relaxed-mode-recovery/relaxed-mode-recovery.qbs b/tests/auto/api/testdata/relaxed-mode-recovery/relaxed-mode-recovery.qbs index b9e786a4b..7a066b694 100644 --- a/tests/auto/api/testdata/relaxed-mode-recovery/relaxed-mode-recovery.qbs +++ b/tests/auto/api/testdata/relaxed-mode-recovery/relaxed-mode-recovery.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "dep" diff --git a/tests/auto/api/testdata/remove-file-dependency/removeFileDependency.qbs b/tests/auto/api/testdata/remove-file-dependency/removeFileDependency.qbs index 8ed927761..27bdf96c2 100644 --- a/tests/auto/api/testdata/remove-file-dependency/removeFileDependency.qbs +++ b/tests/auto/api/testdata/remove-file-dependency/removeFileDependency.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: ["main.cpp"] // Do not reference header files here to force them to be FileDependency objects. diff --git a/tests/auto/api/testdata/rename-product/rename.qbs b/tests/auto/api/testdata/rename-product/rename.qbs index 3e5d2da28..9d23bf804 100644 --- a/tests/auto/api/testdata/rename-product/rename.qbs +++ b/tests/auto/api/testdata/rename-product/rename.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { Depends { name: "TheLib" } diff --git a/tests/auto/api/testdata/rename-target-artifact/rename.qbs b/tests/auto/api/testdata/rename-target-artifact/rename.qbs index c5f267ed6..810b0eb08 100644 --- a/tests/auto/api/testdata/rename-target-artifact/rename.qbs +++ b/tests/auto/api/testdata/rename-target-artifact/rename.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { Depends { name: "TheLib" } diff --git a/tests/auto/api/testdata/restored-warnings/restored-warnings.qbs b/tests/auto/api/testdata/restored-warnings/restored-warnings.qbs index 2de943eda..bbdfbeadb 100644 --- a/tests/auto/api/testdata/restored-warnings/restored-warnings.qbs +++ b/tests/auto/api/testdata/restored-warnings/restored-warnings.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Process 1.5 CppApplication { diff --git a/tests/auto/api/testdata/rule-conflict/rule-conflict.qbs b/tests/auto/api/testdata/rule-conflict/rule-conflict.qbs index 5b839076e..7bd462f18 100644 --- a/tests/auto/api/testdata/rule-conflict/rule-conflict.qbs +++ b/tests/auto/api/testdata/rule-conflict/rule-conflict.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: "main.cpp" Group { diff --git a/tests/auto/api/testdata/run-disabled-product/run-disabled-product.qbs b/tests/auto/api/testdata/run-disabled-product/run-disabled-product.qbs index 7cdcf7db1..b187084dd 100644 --- a/tests/auto/api/testdata/run-disabled-product/run-disabled-product.qbs +++ b/tests/auto/api/testdata/run-disabled-product/run-disabled-product.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "app" condition: false diff --git a/tests/auto/api/testdata/same-base-name/same-base-name.qbs b/tests/auto/api/testdata/same-base-name/same-base-name.qbs index c6a7a6fa3..8448d04fd 100644 --- a/tests/auto/api/testdata/same-base-name/same-base-name.qbs +++ b/tests/auto/api/testdata/same-base-name/same-base-name.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { CppApplication { type: "application" diff --git a/tests/auto/api/testdata/simple-probe/simple-probe.qbs b/tests/auto/api/testdata/simple-probe/simple-probe.qbs index 34700a99b..8e76acfe3 100644 --- a/tests/auto/api/testdata/simple-probe/simple-probe.qbs +++ b/tests/auto/api/testdata/simple-probe/simple-probe.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.Probes CppApplication { diff --git a/tests/auto/api/testdata/soft-dependency/soft-dependency.qbs b/tests/auto/api/testdata/soft-dependency/soft-dependency.qbs index bbf37fda8..62713a481 100644 --- a/tests/auto/api/testdata/soft-dependency/soft-dependency.qbs +++ b/tests/auto/api/testdata/soft-dependency/soft-dependency.qbs @@ -1,5 +1,3 @@ -import qbs - Application { Depends { name: "nosuchmodule" diff --git a/tests/auto/api/testdata/source-file-in-build-dir/source-file-in-build-dir.qbs b/tests/auto/api/testdata/source-file-in-build-dir/source-file-in-build-dir.qbs index 9fe39cdba..85115fc78 100644 --- a/tests/auto/api/testdata/source-file-in-build-dir/source-file-in-build-dir.qbs +++ b/tests/auto/api/testdata/source-file-in-build-dir/source-file-in-build-dir.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile CppApplication { diff --git a/tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs b/tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs index c925d4d57..b584b4d41 100644 --- a/tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs +++ b/tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { StaticLibrary { name: "a" diff --git a/tests/auto/api/testdata/subprojects/resources/modules/QtCoreDepender/qtcoredepender.qbs b/tests/auto/api/testdata/subprojects/resources/modules/QtCoreDepender/qtcoredepender.qbs index 328abaa99..906193adf 100644 --- a/tests/auto/api/testdata/subprojects/resources/modules/QtCoreDepender/qtcoredepender.qbs +++ b/tests/auto/api/testdata/subprojects/resources/modules/QtCoreDepender/qtcoredepender.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cute.core" } } diff --git a/tests/auto/api/testdata/subprojects/resources/modules/cute/core/core.qbs b/tests/auto/api/testdata/subprojects/resources/modules/cute/core/core.qbs index 6ad30f229..ae9b47211 100644 --- a/tests/auto/api/testdata/subprojects/resources/modules/cute/core/core.qbs +++ b/tests/auto/api/testdata/subprojects/resources/modules/cute/core/core.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } cpp.includePaths: [path] diff --git a/tests/auto/api/testdata/subprojects/subproject2/subproject2.qbs b/tests/auto/api/testdata/subprojects/subproject2/subproject2.qbs index 3046fe4b2..b0abb38bd 100644 --- a/tests/auto/api/testdata/subprojects/subproject2/subproject2.qbs +++ b/tests/auto/api/testdata/subprojects/subproject2/subproject2.qbs @@ -1,5 +1,3 @@ -import qbs - Project { name: "subproject2" property string libNamePrefix: "test" diff --git a/tests/auto/api/testdata/subprojects/subproject2/subproject3/subproject3.qbs b/tests/auto/api/testdata/subprojects/subproject2/subproject3/subproject3.qbs index 58a09e863..f2c637947 100644 --- a/tests/auto/api/testdata/subprojects/subproject2/subproject3/subproject3.qbs +++ b/tests/auto/api/testdata/subprojects/subproject2/subproject3/subproject3.qbs @@ -1,4 +1,3 @@ -import qbs import LibraryType Project { diff --git a/tests/auto/api/testdata/subprojects/toplevelproject.qbs b/tests/auto/api/testdata/subprojects/toplevelproject.qbs index f167ccabc..402e40501 100644 --- a/tests/auto/api/testdata/subprojects/toplevelproject.qbs +++ b/tests/auto/api/testdata/subprojects/toplevelproject.qbs @@ -1,5 +1,3 @@ -import qbs - Project { name: "top level project" references: ["subproject2"] diff --git a/tests/auto/api/testdata/target-artifact-status/target-artifact-status.qbs b/tests/auto/api/testdata/target-artifact-status/target-artifact-status.qbs new file mode 100644 index 000000000..2f5776613 --- /dev/null +++ b/tests/auto/api/testdata/target-artifact-status/target-artifact-status.qbs @@ -0,0 +1,28 @@ +import qbs.TextFile + +Product { + name: "p" + type: "p_type" + property bool enableTagging + Rule { + multiplex: true + Artifact { filePath: "a1"; fileTags: "p_type" } + Artifact { filePath: "a2"; fileTags: "x" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating outputs"; + cmd.sourceCode = function() { + var f = new TextFile(outputs.p_type[0].filePath, TextFile.WriteOnly); + f.close(); + f = new TextFile(outputs.x[0].filePath, TextFile.WriteOnly); + f.close(); + }; + return cmd; + } + } + Group { + condition: enableTagging + fileTagsFilter: "x" + fileTags: "p_type" + } +} diff --git a/tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs b/tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs index 9521f3ae4..d72ebda17 100644 --- a/tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs +++ b/tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Module { diff --git a/tests/auto/api/testdata/tool-in-module/use-outside-project/use-outside-project.qbs b/tests/auto/api/testdata/tool-in-module/use-outside-project/use-outside-project.qbs index 439e68f51..81db730db 100644 --- a/tests/auto/api/testdata/tool-in-module/use-outside-project/use-outside-project.qbs +++ b/tests/auto/api/testdata/tool-in-module/use-outside-project/use-outside-project.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "user-outside-project" type: ["thetool.output"] diff --git a/tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs b/tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs index bd480fb08..575f4020e 100644 --- a/tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs +++ b/tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs @@ -1,14 +1,15 @@ -import qbs - Project { CppApplication { name: "thetool" + consoleApplication: true files: "main.cpp" + install: true + installDir: "" + qbs.installPrefix: "" Group { fileTagsFilter: ["application"] fileTags: ["thetool.thetool"] - qbs.install: true } Export { diff --git a/tests/auto/api/testdata/transformer-data/transformer-data.qbs b/tests/auto/api/testdata/transformer-data/transformer-data.qbs index b24deebe5..f9433ed73 100644 --- a/tests/auto/api/testdata/transformer-data/transformer-data.qbs +++ b/tests/auto/api/testdata/transformer-data/transformer-data.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.TextFile diff --git a/tests/auto/api/testdata/transformers/transformers.qbs b/tests/auto/api/testdata/transformers/transformers.qbs index 999395445..bbc5c3c65 100644 --- a/tests/auto/api/testdata/transformers/transformers.qbs +++ b/tests/auto/api/testdata/transformers/transformers.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.File import qbs.TextFile import qbs.Xml diff --git a/tests/auto/api/testdata/two-default-property-values/modules/mymodule/mymodule.qbs b/tests/auto/api/testdata/two-default-property-values/modules/mymodule/mymodule.qbs index 52e99e24d..8ac7b75a3 100644 --- a/tests/auto/api/testdata/two-default-property-values/modules/mymodule/mymodule.qbs +++ b/tests/auto/api/testdata/two-default-property-values/modules/mymodule/mymodule.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Module { diff --git a/tests/auto/api/testdata/two-default-property-values/modules/myothermodule/myothermodule.qbs b/tests/auto/api/testdata/two-default-property-values/modules/myothermodule/myothermodule.qbs index e0ec699df..12df4434b 100644 --- a/tests/auto/api/testdata/two-default-property-values/modules/myothermodule/myothermodule.qbs +++ b/tests/auto/api/testdata/two-default-property-values/modules/myothermodule/myothermodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "mymodule" } } diff --git a/tests/auto/api/testdata/two-default-property-values/two-default-property-values.qbs b/tests/auto/api/testdata/two-default-property-values/two-default-property-values.qbs index c0bc720f7..5e3e0f5a7 100644 --- a/tests/auto/api/testdata/two-default-property-values/two-default-property-values.qbs +++ b/tests/auto/api/testdata/two-default-property-values/two-default-property-values.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "two-default-property-values" type: "mymodule" diff --git a/tests/auto/api/testdata/type-change/type-change.qbs b/tests/auto/api/testdata/type-change/type-change.qbs index 7661aa305..e8154b836 100644 --- a/tests/auto/api/testdata/type-change/type-change.qbs +++ b/tests/auto/api/testdata/type-change/type-change.qbs @@ -1,5 +1,3 @@ -import qbs - Product { files: "main.cpp" Depends { name: "cpp" } diff --git a/tests/auto/api/testdata/uic/uic.qbs b/tests/auto/api/testdata/uic/uic.qbs index 301cdad44..50260d73b 100644 --- a/tests/auto/api/testdata/uic/uic.qbs +++ b/tests/auto/api/testdata/uic/uic.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { QtGuiApplication { type: "application" diff --git a/tests/auto/api/tst_api.cpp b/tests/auto/api/tst_api.cpp index 9e43f0218..bec33d1dd 100644 --- a/tests/auto/api/tst_api.cpp +++ b/tests/auto/api/tst_api.cpp @@ -285,7 +285,7 @@ void TestApi::buildErrorCodeLocation() QString("Rule.outputArtifacts must return an array of objects.")); const qbs::CodeLocation errorLoc = errorItem.codeLocation(); QCOMPARE(QFileInfo(errorLoc.filePath()).fileName(), QString("build-error-code-location.qbs")); - QCOMPARE(errorLoc.line(), 9); + QCOMPARE(errorLoc.line(), 7); QCOMPARE(errorLoc.column(), 26); } @@ -1350,7 +1350,8 @@ void TestApi::generatedFilesList() << "moc_mainwindow.cpp" << "moc_mainwindow.cpp.o" << "moc_mainwindow.cpp.obj" << "ui_mainwindow.h" << HostOsInfo::appendExecutableSuffix("generated-files-list"); - QVERIFY2(possibleFileNames.contains(fi.fileName()) || fi.fileName().endsWith(".plist"), + QVERIFY2(possibleFileNames.contains(fi.fileName()) || fi.fileName().endsWith(".plist") + || fi.fileName().contains("qt_plugin_import"), qPrintable(fi.fileName())); } const auto groups = product.groups(); @@ -2776,6 +2777,36 @@ void TestApi::subProjects() qPrintable(errorInfo.toString())); } +void TestApi::targetArtifactStatus_data() +{ + QTest::addColumn<bool>("enableTagging"); + QTest::newRow("tagging off") << false; + QTest::newRow("tagging on") << true; + QTest::newRow("tagging off again") << false; +} + +void TestApi::targetArtifactStatus() +{ + QFETCH(bool, enableTagging); + qbs::SetupProjectParameters params + = defaultSetupParameters("target-artifact-status/target-artifact-status.qbs"); + params.setOverriddenValues({std::make_pair("products.p.enableTagging", enableTagging)}); + const std::unique_ptr<qbs::SetupProjectJob> setupJob(qbs::Project().setupProject(params, + m_logSink, 0)); + waitForFinished(setupJob.get()); + VERIFY_NO_ERROR(setupJob->error()); + const qbs::Project project = setupJob->project(); + QVERIFY(project.isValid()); + const std::unique_ptr<qbs::BuildJob> buildJob(project.buildAllProducts(qbs::BuildOptions())); + QVERIFY(waitForFinished(buildJob.get())); + VERIFY_NO_ERROR(buildJob->error()); + const qbs::ProjectData projectData = project.projectData(); + const QList<qbs::ProductData> products = projectData.products(); + QCOMPARE(products.size(), 1); + const qbs::ProductData product = products.front(); + QCOMPARE(product.targetArtifacts().size(), enableTagging ? 2 : 1); +} + void TestApi::toolInModule() { QVariantMap overrides({std::make_pair("qbs.installRoot", m_workingDataDir diff --git a/tests/auto/api/tst_api.h b/tests/auto/api/tst_api.h index a77b20344..ff32c8634 100644 --- a/tests/auto/api/tst_api.h +++ b/tests/auto/api/tst_api.h @@ -140,6 +140,8 @@ private slots: void softDependency(); void sourceFileInBuildDir(); void subProjects(); + void targetArtifactStatus_data(); + void targetArtifactStatus(); void toolInModule(); void trackAddQObjectHeader(); void trackRemoveQObjectHeader(); diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index f6cc4b26f..1afe48176 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -14,5 +14,6 @@ SUBDIRS += \ blackbox/blackbox-apple.pro \ blackbox/blackbox-clangdb.pro \ blackbox/blackbox-java.pro \ + blackbox/blackbox-joblimits.pro \ blackbox/blackbox-qt.pro \ api diff --git a/tests/auto/auto.qbs b/tests/auto/auto.qbs index 92ab5279f..bf75d0f23 100644 --- a/tests/auto/auto.qbs +++ b/tests/auto/auto.qbs @@ -9,6 +9,7 @@ Project { "blackbox/blackbox-apple.qbs", "blackbox/blackbox-clangdb.qbs", "blackbox/blackbox-java.qbs", + "blackbox/blackbox-joblimits.qbs", "blackbox/blackbox-qt.qbs", "buildgraph/buildgraph.qbs", "cmdlineparser/cmdlineparser.qbs", diff --git a/tests/auto/blackbox/blackbox-android.pro b/tests/auto/blackbox/blackbox-android.pro index d27550301..7aca99e8d 100644 --- a/tests/auto/blackbox/blackbox-android.pro +++ b/tests/auto/blackbox/blackbox-android.pro @@ -16,3 +16,6 @@ for(data_dir, DATA_DIRS) { } OTHER_FILES += $$FILES + +DISTFILES += \ + testdata/texttemplate/expected-output-one.txt diff --git a/tests/auto/blackbox/blackbox-android.qbs b/tests/auto/blackbox/blackbox-android.qbs index 068322cf9..ca7d429ef 100644 --- a/tests/auto/blackbox/blackbox-android.qbs +++ b/tests/auto/blackbox/blackbox-android.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities QbsAutotest { diff --git a/tests/auto/blackbox/blackbox-apple.qbs b/tests/auto/blackbox/blackbox-apple.qbs index 8137aec82..6cc946d12 100644 --- a/tests/auto/blackbox/blackbox-apple.qbs +++ b/tests/auto/blackbox/blackbox-apple.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities QbsAutotest { diff --git a/tests/auto/blackbox/blackbox-clangdb.qbs b/tests/auto/blackbox/blackbox-clangdb.qbs index 359fad1db..38118309f 100644 --- a/tests/auto/blackbox/blackbox-clangdb.qbs +++ b/tests/auto/blackbox/blackbox-clangdb.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities QbsAutotest { diff --git a/tests/auto/blackbox/blackbox-java.qbs b/tests/auto/blackbox/blackbox-java.qbs index b75a5f168..6c56b3d18 100644 --- a/tests/auto/blackbox/blackbox-java.qbs +++ b/tests/auto/blackbox/blackbox-java.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities QbsAutotest { diff --git a/tests/auto/blackbox/blackbox-joblimits.pro b/tests/auto/blackbox/blackbox-joblimits.pro new file mode 100644 index 000000000..85413473e --- /dev/null +++ b/tests/auto/blackbox/blackbox-joblimits.pro @@ -0,0 +1,18 @@ +TARGET = tst_blackbox-joblimits + +HEADERS = tst_blackboxbase.h +SOURCES = tst_blackboxjoblimits.cpp tst_blackboxbase.cpp +OBJECTS_DIR = joblimits +MOC_DIR = $${OBJECTS_DIR}-moc + +include(../auto.pri) + +DATA_DIRS = testdata-joblimits ../find + +for(data_dir, DATA_DIRS) { + files = $$files($$PWD/$$data_dir/*, true) + win32:files ~= s|\\\\|/|g + for(file, files):!exists($$file/*):FILES += $$file +} + +OTHER_FILES += $$FILES diff --git a/tests/auto/blackbox/blackbox-joblimits.qbs b/tests/auto/blackbox/blackbox-joblimits.qbs new file mode 100644 index 000000000..857e1de7f --- /dev/null +++ b/tests/auto/blackbox/blackbox-joblimits.qbs @@ -0,0 +1,20 @@ +import qbs.Utilities + +QbsAutotest { + testName: "blackbox-joblimits" + Depends { name: "qbs_app" } + Depends { name: "qbs-setup-toolchains" } + Group { + name: "testdata" + prefix: "testdata-joblimits/" + files: ["**/*"] + fileTags: [] + } + files: [ + "../shared.h", + "tst_blackboxbase.cpp", + "tst_blackboxbase.h", + "tst_blackboxjoblimits.cpp", + ] + cpp.defines: base.concat(["SRCDIR=" + Utilities.cStringQuote(path)]) +} diff --git a/tests/auto/blackbox/blackbox-qt.qbs b/tests/auto/blackbox/blackbox-qt.qbs index ad473f731..a25221dc9 100644 --- a/tests/auto/blackbox/blackbox-qt.qbs +++ b/tests/auto/blackbox/blackbox-qt.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities QbsAutotest { diff --git a/tests/auto/blackbox/blackbox.qbs b/tests/auto/blackbox/blackbox.qbs index 917e8345b..3f0ff959a 100644 --- a/tests/auto/blackbox/blackbox.qbs +++ b/tests/auto/blackbox/blackbox.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities QbsAutotest { diff --git a/tests/auto/blackbox/find/find-android.qbs b/tests/auto/blackbox/find/find-android.qbs index 5a28b0560..26dedc60f 100644 --- a/tests/auto/blackbox/find/find-android.qbs +++ b/tests/auto/blackbox/find/find-android.qbs @@ -1,8 +1,8 @@ -import qbs import qbs.TextFile Product { property string packageName: "" + qbs.targetPlatform: "android" Depends { name: "Android.sdk"; required: false } Depends { name: "Android.ndk"; required: false } diff --git a/tests/auto/blackbox/find/find-jdk.qbs b/tests/auto/blackbox/find/find-jdk.qbs index 411569f23..81d84fa20 100644 --- a/tests/auto/blackbox/find/find-jdk.qbs +++ b/tests/auto/blackbox/find/find-jdk.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Product { diff --git a/tests/auto/blackbox/find/find-nodejs.qbs b/tests/auto/blackbox/find/find-nodejs.qbs index d8b555ecd..c63d40c81 100644 --- a/tests/auto/blackbox/find/find-nodejs.qbs +++ b/tests/auto/blackbox/find/find-nodejs.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Product { diff --git a/tests/auto/blackbox/find/find-typescript.qbs b/tests/auto/blackbox/find/find-typescript.qbs index df2f86a84..18ca0c5cc 100644 --- a/tests/auto/blackbox/find/find-typescript.qbs +++ b/tests/auto/blackbox/find/find-typescript.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Product { diff --git a/tests/auto/blackbox/find/find-xcode.qbs b/tests/auto/blackbox/find/find-xcode.qbs index b42b2deb7..bb6ee9718 100644 --- a/tests/auto/blackbox/find/find-xcode.qbs +++ b/tests/auto/blackbox/find/find-xcode.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Product { diff --git a/tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml b/tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml new file mode 100644 index 000000000..e8a950847 --- /dev/null +++ b/tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="io.qbs.aidltest"> + <application android:label="AidlTest"> + <activity android:name="MainActivity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/auto/blackbox/testdata-android/aidl/aidl.qbs b/tests/auto/blackbox/testdata-android/aidl/aidl.qbs new file mode 100644 index 000000000..6e827099f --- /dev/null +++ b/tests/auto/blackbox/testdata-android/aidl/aidl.qbs @@ -0,0 +1,8 @@ +Application { + name: "io.qbs.aidltest" + Android.sdk.aidlSearchPaths: path + files: [ + "AndroidManifest.xml", + "io/qbs/aidltest/*", + ] +} diff --git a/tests/auto/blackbox/testdata-android/aidl/io/qbs/aidltest/Interface1.aidl b/tests/auto/blackbox/testdata-android/aidl/io/qbs/aidltest/Interface1.aidl new file mode 100644 index 000000000..34fb0386c --- /dev/null +++ b/tests/auto/blackbox/testdata-android/aidl/io/qbs/aidltest/Interface1.aidl @@ -0,0 +1,7 @@ +package io.qbs.aidltest; + +import io.qbs.aidltest.Interface2; + +interface Interface1 { + void doSomething(in Interface2 param1, in Bundle param2); +} diff --git a/tests/auto/blackbox/testdata-android/aidl/io/qbs/aidltest/Interface2.aidl b/tests/auto/blackbox/testdata-android/aidl/io/qbs/aidltest/Interface2.aidl new file mode 100644 index 000000000..815d44f23 --- /dev/null +++ b/tests/auto/blackbox/testdata-android/aidl/io/qbs/aidltest/Interface2.aidl @@ -0,0 +1,5 @@ +package io.qbs.aidltest; + +interface Interface2 { + void someFunc(in Bundle params); +} diff --git a/tests/auto/blackbox/testdata-android/aidl/io/qbs/aidltest/MainActivity.java b/tests/auto/blackbox/testdata-android/aidl/io/qbs/aidltest/MainActivity.java new file mode 100644 index 000000000..e38cfa55b --- /dev/null +++ b/tests/auto/blackbox/testdata-android/aidl/io/qbs/aidltest/MainActivity.java @@ -0,0 +1,18 @@ +package io.qbs.aidltest; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.TextView; + +public class MainActivity extends Activity +{ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + TextView label = new TextView(this); + label.setText("Hello world!"); + + setContentView(label); + } +} diff --git a/doc/templates/style/style_ie8.css b/tests/auto/blackbox/testdata-android/minimal-native/libdependency.so index e69de29bb..e69de29bb 100644 --- a/doc/templates/style/style_ie8.css +++ b/tests/auto/blackbox/testdata-android/minimal-native/libdependency.so diff --git a/tests/auto/blackbox/testdata-android/minimal-native/minimal-native.qbs b/tests/auto/blackbox/testdata-android/minimal-native/minimal-native.qbs new file mode 100644 index 000000000..8cdda7a3c --- /dev/null +++ b/tests/auto/blackbox/testdata-android/minimal-native/minimal-native.qbs @@ -0,0 +1,11 @@ +CppApplication { + name: "minimalnative" + qbs.buildVariant: "release" + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } + Android.ndk.appStl: "stlport_shared" + files: "src/main/native/native.c" + Group { + files: "libdependency.so" + fileTags: "android.nativelibrary" + } +} diff --git a/tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml b/tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml new file mode 100644 index 000000000..575e95e8d --- /dev/null +++ b/tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="somedefault"> + <application android:label="MinimalNative"> + <activity android:name="MainActivity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/auto/blackbox/testdata-android/minimal-native/src/main/java/minimal/MinimalNative.java b/tests/auto/blackbox/testdata-android/minimal-native/src/main/java/minimal/MinimalNative.java new file mode 100644 index 000000000..1464d2593 --- /dev/null +++ b/tests/auto/blackbox/testdata-android/minimal-native/src/main/java/minimal/MinimalNative.java @@ -0,0 +1,22 @@ +package minimalnative; + +import android.app.Activity; +import android.widget.TextView; +import android.os.Bundle; + +public class MinimalNative extends Activity +{ + @Override + public void onCreate(Bundle savedInstanceState) + { + TextView tv = new TextView(this); + tv.setText(stringFromNative()); + setContentView(tv); + } + + public native String stringFromNative(); + + static { + System.loadLibrary("minimal"); + } +} diff --git a/tests/auto/blackbox/testdata-android/minimal-native/src/main/native/native.c b/tests/auto/blackbox/testdata-android/minimal-native/src/main/native/native.c new file mode 100644 index 000000000..6b625858b --- /dev/null +++ b/tests/auto/blackbox/testdata-android/minimal-native/src/main/native/native.c @@ -0,0 +1,8 @@ +#include <string.h> +#include <jni.h> + +jstring +Java_minimalnative_MinimalNative_stringFromNative(JNIEnv* env, jobject thiz) +{ + return (*env)->NewStringUTF(env, "This message comes from native code."); +} diff --git a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/multiple-apks-per-project.qbs b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/multiple-apks-per-project.qbs index 3d03c309a..5dc5ad269 100644 --- a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/multiple-apks-per-project.qbs +++ b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/multiple-apks-per-project.qbs @@ -1,5 +1,3 @@ -import qbs - Project { references: [ "product1", diff --git a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs index eb63d4c20..c4a78a30b 100644 --- a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs +++ b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs @@ -1,5 +1,3 @@ -import qbs - Project { DynamicLibrary { Depends { name: "Android.ndk" } @@ -24,9 +22,10 @@ Project { cpp.useRPaths: false } - AndroidApk { + Application { name: "twolibs1" - packageName: "io.qt.dummy1" + Android.sdk.apkBaseName: name + Android.sdk.packageName: "io.qt.dummy1" Depends { productTypes: ["android.nativelibrary"] limitToSubProject: true diff --git a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs index 9b7f3eb54..9be70dcda 100644 --- a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs +++ b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs @@ -1,5 +1,3 @@ -import qbs - Project { DynamicLibrary { Depends { name: "cpp" } @@ -19,9 +17,10 @@ Project { Android.ndk.appStl: "stlport_shared" } - AndroidApk { + Application { name: "twolibs2" - packageName: "io.qt.dummy2" + Android.sdk.apkBaseName: name + Android.sdk.packageName: "io.qt.dummy2" Depends { productTypes: ["android.nativelibrary"] limitToSubProject: true diff --git a/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs b/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs index 6dd4e6bdb..8b9ded211 100644 --- a/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs +++ b/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs @@ -1,5 +1,3 @@ -import qbs - Project { DynamicLibrary { Depends { name: "Android.ndk" } @@ -25,6 +23,8 @@ Project { JavaJarFile { Depends { name: "Android.sdk" } + Android.sdk.packageName: undefined + Android.sdk.automaticSources: false Depends { name: "lib6" } Depends { name: "lib8" } name: "lib3" @@ -33,38 +33,49 @@ Project { JavaJarFile { Depends { name: "Android.sdk" } + Android.sdk.packageName: undefined + Android.sdk.automaticSources: false name: "lib4" files: ["lib4.java"] } JavaJarFile { Depends { name: "Android.sdk" } + Android.sdk.packageName: undefined + Android.sdk.automaticSources: false name: "lib5" files: ["lib5.java"] } JavaJarFile { Depends { name: "Android.sdk" } + Android.sdk.packageName: undefined + Android.sdk.automaticSources: false name: "lib6" files: ["lib6.java"] } JavaJarFile { Depends { name: "Android.sdk" } + Android.sdk.packageName: undefined + Android.sdk.automaticSources: false name: "lib7" files: ["lib7.java"] } JavaJarFile { Depends { name: "Android.sdk" } + Android.sdk.packageName: undefined + Android.sdk.automaticSources: false Depends { name: "lib7"; Android.sdk.embedJar: false } name: "lib8" files: ["lib8.java"] } - AndroidApk { + Application { name: "twolibs" - packageName: "io.qt.dummy" + Android.sdk.apkBaseName: name + Android.sdk.packageName: "io.qt.dummy" Depends { productTypes: ["android.nativelibrary"] } Depends { name: "lib3"; Android.sdk.embedJar: true } Depends { name: "lib4"; Android.sdk.embedJar: false } diff --git a/tests/auto/blackbox/testdata-android/no-native/no-native.qbs b/tests/auto/blackbox/testdata-android/no-native/no-native.qbs index 2909adc0c..74514f604 100644 --- a/tests/auto/blackbox/testdata-android/no-native/no-native.qbs +++ b/tests/auto/blackbox/testdata-android/no-native/no-native.qbs @@ -1,8 +1,7 @@ -import qbs - -AndroidApk { +Application { + qbs.targetPlatform: "android" name: "com.example.android.basicmediadecoder" - sourceSetDir: Android.sdk.sdkDir + Android.sdk.sourceSetDir: Android.sdk.sdkDir + "/samples/android-BasicMediaDecoder/Application/src/main" } diff --git a/tests/auto/blackbox/testdata-android/qml-app/main.cpp b/tests/auto/blackbox/testdata-android/qml-app/main.cpp new file mode 100644 index 000000000..e7cf5e16e --- /dev/null +++ b/tests/auto/blackbox/testdata-android/qml-app/main.cpp @@ -0,0 +1,21 @@ +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + if (qEnvironmentVariableIsEmpty("QTGLESSTREAM_DISPLAY")) { + qputenv("QT_QPA_EGLFS_PHYSICAL_WIDTH", QByteArray("213")); + qputenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT", QByteArray("120")); + + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + } + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/tests/auto/blackbox/testdata-android/qml-app/main.qml b/tests/auto/blackbox/testdata-android/qml-app/main.qml new file mode 100644 index 000000000..45ee20a2f --- /dev/null +++ b/tests/auto/blackbox/testdata-android/qml-app/main.qml @@ -0,0 +1,9 @@ +import QtQuick 2.6 +import QtQuick.Window 2.2 + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Hello World") +} diff --git a/tests/auto/blackbox/testdata-android/qml-app/qml-app.qbs b/tests/auto/blackbox/testdata-android/qml-app/qml-app.qbs new file mode 100644 index 000000000..56b9d6eaf --- /dev/null +++ b/tests/auto/blackbox/testdata-android/qml-app/qml-app.qbs @@ -0,0 +1,14 @@ +QtApplication { + name: "qmlapp" + Depends { name: "Qt.quick" } + Depends { name: "Qt.android_support" } + Properties { + condition: qbs.targetOS.contains("android") + Qt.android_support.extraPrefixDirs: path + } + property stringList qmlImportPaths: path + files: [ + "main.cpp", + "qml.qrc", + ] +} diff --git a/tests/auto/blackbox/testdata-android/qml-app/qml.qrc b/tests/auto/blackbox/testdata-android/qml-app/qml.qrc new file mode 100644 index 000000000..5f6483ac3 --- /dev/null +++ b/tests/auto/blackbox/testdata-android/qml-app/qml.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + </qresource> +</RCC> diff --git a/tests/auto/blackbox/testdata-android/qml-app/src/main/AndroidManifest.xml b/tests/auto/blackbox/testdata-android/qml-app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..066ec0a63 --- /dev/null +++ b/tests/auto/blackbox/testdata-android/qml-app/src/main/AndroidManifest.xml @@ -0,0 +1,81 @@ +<?xml version='1.0' encoding='utf-8'?> +<manifest package="org.qtproject.example" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto"> + <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --"> + <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" + android:name="org.qtproject.qt5.android.bindings.QtActivity" + android:label="-- %%INSERT_APP_NAME%% --" + android:screenOrientation="unspecified" + android:launchMode="singleTop"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + + <!-- Application arguments --> + <!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ --> + <!-- Application arguments --> + + <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/> + <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/> + <meta-data android:name="android.app.repository" android:value="default"/> + <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/> + <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/> + <!-- Deploy Qt libs as part of package --> + <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/> + <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/> + <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/> + <!-- Run with local libs --> + <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/> + <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/> + <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/> + <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/> + <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/> + <!-- Messages maps --> + <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/> + <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/> + <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/> + <!-- Messages maps --> + + <!-- Splash screen --> + <!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ --> + <!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ --> + <!-- Splash screen --> + + <!-- Background running --> + <!-- Warning: changing this value to true may cause unexpected crashes if the + application still try to draw after + "applicationStateChanged(Qt::ApplicationSuspended)" + signal is sent! --> + <meta-data android:name="android.app.background_running" android:value="false"/> + <!-- Background running --> + + <!-- auto screen scale factor --> + <meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/> + <!-- auto screen scale factor --> + + <!-- extract android style --> + <!-- available android:values : + * full - useful QWidget & Quick Controls 1 apps + * minimal - useful for Quick Controls 2 apps, it is much faster than "full" + * none - useful for apps that don't use any of the above Qt modules + --> + <meta-data android:name="android.app.extract_android_style" android:value="full"/> + <!-- extract android style --> + </activity> + + <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices --> + + </application> + + <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="16"/> + <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> + + <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application. + Remove the comment if you do not require these default permissions. --> + <!-- %%INSERT_PERMISSIONS --> + + <!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application. + Remove the comment if you do not require these default features. --> + <!-- %%INSERT_FEATURES --> + +</manifest> diff --git a/tests/auto/blackbox/testdata-android/qml-app/src/main/assets/dummyasset.txt b/tests/auto/blackbox/testdata-android/qml-app/src/main/assets/dummyasset.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/auto/blackbox/testdata-android/qml-app/src/main/assets/dummyasset.txt diff --git a/tests/auto/blackbox/testdata-android/teapot/teapot.qbs b/tests/auto/blackbox/testdata-android/teapot/teapot.qbs index 3e0210554..2b5cb8aba 100644 --- a/tests/auto/blackbox/testdata-android/teapot/teapot.qbs +++ b/tests/auto/blackbox/testdata-android/teapot/teapot.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Project { @@ -6,6 +5,7 @@ Project { StaticLibrary { name: "native-glue" qbs.targetPlatform: "android" + cpp.warningLevel: "none" Depends { name: "cpp" } Group { id: glue_sources @@ -23,6 +23,7 @@ Project { StaticLibrary { name: "ndk-helper" qbs.targetPlatform: "android" + cpp.warningLevel: "none" Depends { name: "Android.ndk" } Depends { name: "cpp" } Depends { name: "native-glue" } @@ -78,9 +79,10 @@ Project { } } - DynamicLibrary { + CppApplication { name: "TeapotNativeActivity" qbs.targetPlatform: "android" + Depends { name: "Android.ndk" } Depends { name: "cpp" } Depends { name: "android_cpufeatures" } @@ -88,6 +90,21 @@ Project { Depends { name: "ndk-helper" } Probe { + id: teapotProbe + property string samplesDir: Android.sdk.ndkSamplesDir + property string dir + configure: { + var paths = ["/teapots/classic-teapot/src/main", "/Teapot/app/src/main", "/Teapot"]; + for (var i = 0; i < paths.length; ++i) { + if (File.exists(samplesDir + paths[i])) { + dir = samplesDir + paths[i]; + break; + } + } + } + } + + Probe { id: teapotProbeJni property string samplesDir: Android.ndk.ndkSamplesDir property string jniDir @@ -116,6 +133,9 @@ Project { FileTagger { patterns: ["*.inl"]; fileTags: ["hpp"] } + Android.sdk.apkBaseName: name + Android.sdk.packageName: "com.sample.teapot" + Android.sdk.sourceSetDir: teapotProbe.dir Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "gnustl_shared" cpp.cxxLanguageVersion: "c++11" @@ -126,25 +146,4 @@ Project { // Refer to: https://github.com/android-ndk/ndk/issues/381 cpp.linkerFlags: ["-u", "ANativeActivity_onCreate"] } - - AndroidApk { - Probe { - id: teapotProbe - property string samplesDir: Android.sdk.ndkSamplesDir - property string dir - configure: { - var paths = ["/teapots/classic-teapot/src/main", "/Teapot/app/src/main", "/Teapot"]; - for (var i = 0; i < paths.length; ++i) { - if (File.exists(samplesDir + paths[i])) { - dir = samplesDir + paths[i]; - break; - } - } - } - } - - name: "com.sample.teapot" - sourceSetDir: teapotProbe.dir - Depends { productTypes: ["android.nativelibrary"] } - } } diff --git a/tests/auto/blackbox/testdata-apple/apple-dmg/apple-dmg.qbs b/tests/auto/blackbox/testdata-apple/apple-dmg/apple-dmg.qbs index 3bccebfd0..b3d39fe27 100644 --- a/tests/auto/blackbox/testdata-apple/apple-dmg/apple-dmg.qbs +++ b/tests/auto/blackbox/testdata-apple/apple-dmg/apple-dmg.qbs @@ -1,5 +1,3 @@ -import qbs - Project { AppleApplicationDiskImage { Depends { name: "myapp" } @@ -18,12 +16,7 @@ Project { targetName: "My Great App" files: ["main.c"] - Group { - fileTagsFilter: ["bundle.content"] - qbs.install: true - qbs.installDir: "/Applications" - qbs.installSourceBase: product.buildDirectory - } + install: true } AppleDiskImage { diff --git a/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs b/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs index fcd440e66..438624f70 100644 --- a/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs +++ b/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities Project { @@ -18,11 +17,8 @@ Project { aggregate: false multiplexByQbsProperties: [] - Group { - fileTagsFilter: ["bundle.content"] - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } CppApplication { @@ -39,11 +35,8 @@ Project { qbs.architectures: ["x86_64"] qbs.buildVariants: ["release"] - Group { - fileTagsFilter: ["bundle.content"] - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } DynamicLibrary { @@ -59,11 +52,8 @@ Project { aggregate: false multiplexByQbsProperties: [] - Group { - fileTagsFilter: ["bundle.content"] - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } CppApplication { @@ -75,11 +65,8 @@ Project { cpp.rpaths: [cpp.rpathOrigin + "/../../../"] cpp.minimumMacosVersion: "10.6" - Group { - fileTagsFilter: ["bundle.content"] - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } CppApplication { @@ -94,12 +81,10 @@ Project { qbs.architecture: "x86_64" multiplexByQbsProperties: project.enableX86 ? ["architectures", "buildVariants"] : ["buildVariants"] + qbs.buildVariants: "debug" - Group { - fileTagsFilter: ["bundle.content"] - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } CppApplication { @@ -113,11 +98,8 @@ Project { qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"] qbs.buildVariants: ["debug", "profile"] - Group { - fileTagsFilter: ["bundle.content"] - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } DynamicLibrary { @@ -131,11 +113,8 @@ Project { qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"] qbs.buildVariants: ["release", "debug", "profile"] - Group { - fileTagsFilter: ["bundle.content"] - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } DynamicLibrary { @@ -149,11 +128,8 @@ Project { qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"] qbs.buildVariants: ["debug", "profile"] - Group { - fileTagsFilter: ["bundle.content"] - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } DynamicLibrary { @@ -166,11 +142,8 @@ Project { cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)] qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"] qbs.buildVariants: ["debug", "profile"] - Group { - fileTagsFilter: ["bundle.content"] - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } DynamicLibrary { Depends { name: "cpp" } @@ -181,10 +154,7 @@ Project { cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)] qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"] qbs.buildVariants: ["debug", "profile"] - Group { - fileTagsFilter: ["bundle.content"] - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } } diff --git a/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs b/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs index a7c3e20bf..8cf031e33 100644 --- a/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs +++ b/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property stringList bundleFileTags: ["bundle.content"] @@ -17,11 +15,8 @@ Project { bundle.privateHeaders: ["dummy_p.h"] bundle.resources: ["resource.txt"] files: ["dummy.c"] - Group { - fileTagsFilter: product.type.concat(project.bundleFileTags) - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } Application { @@ -37,11 +32,8 @@ Project { bundle.privateHeaders: ["dummy_p.h"] bundle.resources: ["resource.txt"] files: ["dummy.c"] - Group { - fileTagsFilter: product.type.concat(project.bundleFileTags) - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } Application { @@ -57,11 +49,8 @@ Project { bundle.privateHeaders: ["dummy_p.h"] bundle.resources: ["resource.txt"] files: ["dummy.c"] - Group { - fileTagsFilter: product.type.concat(project.bundleFileTags) - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } DynamicLibrary { @@ -73,11 +62,8 @@ Project { bundle.privateHeaders: ["dummy_p.h"] bundle.resources: ["resource.txt"] files: ["dummy.c"] - Group { - fileTagsFilter: product.type.concat(project.bundleFileTags) - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } StaticLibrary { @@ -89,11 +75,8 @@ Project { bundle.privateHeaders: ["dummy_p.h"] bundle.resources: ["resource.txt"] files: ["dummy.c"] - Group { - fileTagsFilter: product.type.concat(project.bundleFileTags) - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } LoadableModule { @@ -105,11 +88,8 @@ Project { bundle.privateHeaders: ["dummy_p.h"] bundle.resources: ["resource.txt"] files: ["dummy.c"] - Group { - fileTagsFilter: product.type.concat(project.bundleFileTags) - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } ApplicationExtension { @@ -121,11 +101,8 @@ Project { bundle.privateHeaders: ["dummy_p.h"] bundle.resources: ["resource.txt"] files: ["dummy.c"] - Group { - fileTagsFilter: product.type.concat(project.bundleFileTags) - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } XPCService { @@ -137,11 +114,8 @@ Project { bundle.privateHeaders: ["dummy_p.h"] bundle.resources: ["resource.txt"] files: ["dummy.c"] - Group { - fileTagsFilter: product.type.concat(project.bundleFileTags) - qbs.install: true - qbs.installSourceBase: product.buildDirectory - } + install: true + installDir: "" } Product { diff --git a/tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs b/tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs index 940fe74f4..9eff57b60 100644 --- a/tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs +++ b/tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: ["main.c"] diff --git a/tests/auto/blackbox/testdata-apple/embedInfoPlist/embedInfoPlist.qbs b/tests/auto/blackbox/testdata-apple/embedInfoPlist/embedInfoPlist.qbs index 16b00208e..ba23dc32c 100644 --- a/tests/auto/blackbox/testdata-apple/embedInfoPlist/embedInfoPlist.qbs +++ b/tests/auto/blackbox/testdata-apple/embedInfoPlist/embedInfoPlist.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { Depends { name: "lib" } @@ -13,10 +11,8 @@ Project { bundle.infoPlist: ({ "QBS": "org.qt-project.qbs.testdata.embedInfoPlist" }) - Group { - fileTagsFilter: product.type - qbs.install: true - } + install: true + installDir: "" } DynamicLibrary { @@ -30,10 +26,8 @@ Project { bundle.infoPlist: ({ "QBS": "org.qt-project.qbs.testdata.embedInfoPlist.dylib" }) - Group { - fileTagsFilter: product.type - qbs.install: true - } + install: true + installDir: "" } LoadableModule { diff --git a/tests/auto/blackbox/testdata-apple/frameworkStructure/frameworkStructure.qbs b/tests/auto/blackbox/testdata-apple/frameworkStructure/frameworkStructure.qbs index 39b3a1b58..a812ae513 100644 --- a/tests/auto/blackbox/testdata-apple/frameworkStructure/frameworkStructure.qbs +++ b/tests/auto/blackbox/testdata-apple/frameworkStructure/frameworkStructure.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property bool includeHeaders: true Library { diff --git a/tests/auto/blackbox/testdata-apple/ib/assetcatalog/assetcatalogempty.qbs b/tests/auto/blackbox/testdata-apple/ib/assetcatalog/assetcatalogempty.qbs index ef67796f9..622fa46cb 100644 --- a/tests/auto/blackbox/testdata-apple/ib/assetcatalog/assetcatalogempty.qbs +++ b/tests/auto/blackbox/testdata-apple/ib/assetcatalog/assetcatalogempty.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities Project { diff --git a/tests/auto/blackbox/testdata-apple/ib/empty-asset-catalogs/multiple-asset-catalogs.qbs b/tests/auto/blackbox/testdata-apple/ib/empty-asset-catalogs/multiple-asset-catalogs.qbs index 454d3c482..49b389d3d 100644 --- a/tests/auto/blackbox/testdata-apple/ib/empty-asset-catalogs/multiple-asset-catalogs.qbs +++ b/tests/auto/blackbox/testdata-apple/ib/empty-asset-catalogs/multiple-asset-catalogs.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Depends { name: "ib" } files: [ diff --git a/tests/auto/blackbox/testdata-apple/ib/iconset/iconset.qbs b/tests/auto/blackbox/testdata-apple/ib/iconset/iconset.qbs index 1d563f180..b3481587f 100644 --- a/tests/auto/blackbox/testdata-apple/ib/iconset/iconset.qbs +++ b/tests/auto/blackbox/testdata-apple/ib/iconset/iconset.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "ib" } type: ["icns"] diff --git a/tests/auto/blackbox/testdata-apple/ib/iconsetapp/iconsetapp.qbs b/tests/auto/blackbox/testdata-apple/ib/iconsetapp/iconsetapp.qbs index 7e5323a0c..04e6ce0ce 100644 --- a/tests/auto/blackbox/testdata-apple/ib/iconsetapp/iconsetapp.qbs +++ b/tests/auto/blackbox/testdata-apple/ib/iconsetapp/iconsetapp.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Depends { name: "ib" } files: ["main.c", "white.iconset"] diff --git a/tests/auto/blackbox/testdata-apple/ib/multiple-asset-catalogs/multiple-asset-catalogs.qbs b/tests/auto/blackbox/testdata-apple/ib/multiple-asset-catalogs/multiple-asset-catalogs.qbs index 454d3c482..49b389d3d 100644 --- a/tests/auto/blackbox/testdata-apple/ib/multiple-asset-catalogs/multiple-asset-catalogs.qbs +++ b/tests/auto/blackbox/testdata-apple/ib/multiple-asset-catalogs/multiple-asset-catalogs.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Depends { name: "ib" } files: [ diff --git a/tests/auto/blackbox/testdata-apple/infoplist/infoplist.qbs b/tests/auto/blackbox/testdata-apple/infoplist/infoplist.qbs index 58cb361dd..a6ac3d8d1 100644 --- a/tests/auto/blackbox/testdata-apple/infoplist/infoplist.qbs +++ b/tests/auto/blackbox/testdata-apple/infoplist/infoplist.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { cpp.minimumMacosVersion: "10.7" files: ["main.c"] diff --git a/tests/auto/blackbox/testdata-apple/objc-arc/objc-arc.qbs b/tests/auto/blackbox/testdata-apple/objc-arc/objc-arc.qbs index 672de3cb5..545d5701c 100644 --- a/tests/auto/blackbox/testdata-apple/objc-arc/objc-arc.qbs +++ b/tests/auto/blackbox/testdata-apple/objc-arc/objc-arc.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "cpp" } consoleApplication: true diff --git a/tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs b/tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs index 0c2b0b93d..d7baf8c8e 100644 --- a/tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs +++ b/tests/auto/blackbox/testdata-apple/xcode/xcode-project.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property stringList sdks: [] diff --git a/tests/auto/blackbox/testdata-clangdb/project1/project.qbs b/tests/auto/blackbox/testdata-clangdb/project1/project.qbs index 4552deb40..ecfc562b0 100644 --- a/tests/auto/blackbox/testdata-clangdb/project1/project.qbs +++ b/tests/auto/blackbox/testdata-clangdb/project1/project.qbs @@ -1,5 +1,3 @@ -import qbs - // $ g++ 'i like spaces.cpp' '-DSPACES="!have \\fun\x5c!\n"' '-DSPICES=%T% # && $$ 1>&2 '\''\n'\''\n' '-DSLICES=(42>24)' && ./a.out // SPACES=!have \fun\! // SPICES=%T% # && $$ 1>&2 '\n' diff --git a/tests/auto/blackbox/testdata-java/java/inner-class/inner-class.qbs b/tests/auto/blackbox/testdata-java/java/inner-class/inner-class.qbs index 5bc861f5d..c48401478 100644 --- a/tests/auto/blackbox/testdata-java/java/inner-class/inner-class.qbs +++ b/tests/auto/blackbox/testdata-java/java/inner-class/inner-class.qbs @@ -1,5 +1,3 @@ -import qbs - JavaJarFile { files: ["**/*.java"] } diff --git a/tests/auto/blackbox/testdata-java/java/vehicles.qbs b/tests/auto/blackbox/testdata-java/java/vehicles.qbs index 86d1f7d32..8153efe00 100644 --- a/tests/auto/blackbox/testdata-java/java/vehicles.qbs +++ b/tests/auto/blackbox/testdata-java/java/vehicles.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo import qbs.Utilities @@ -14,15 +13,14 @@ Project { name: "native" files: ["engine.c"] - Group { - fileTagsFilter: ["dynamiclibrary"] - qbs.install: true - } + qbs.installPrefix: "" + install: true + installDir: "" } JavaClassCollection { Depends { name: "random_stuff" } - name: "class_collection" + name: "cc" java.additionalCompilerFlags: ["-Xlint:all"] files: [ "Car.java", "HelloWorld.java", "Jet.java", "NoPackage.java", "Ship.java", @@ -44,6 +42,7 @@ Project { name: "random_stuff" files: ["RandomStuff.java"] + qbs.installPrefix: "" Group { fileTagsFilter: ["java.jar"] qbs.install: true @@ -78,6 +77,7 @@ Project { java.manifestClassPath: [product.targetName + ".jar"] } + qbs.installPrefix: "" Group { fileTagsFilter: ["java.jar"] qbs.install: true @@ -98,6 +98,7 @@ Project { return mf; } + qbs.installPrefix: "" Group { fileTagsFilter: ["java.jar"] qbs.install: true diff --git a/tests/auto/blackbox/testdata-joblimits/job-limits/job-limits.qbs b/tests/auto/blackbox/testdata-joblimits/job-limits/job-limits.qbs new file mode 100644 index 000000000..1ab369c88 --- /dev/null +++ b/tests/auto/blackbox/testdata-joblimits/job-limits/job-limits.qbs @@ -0,0 +1,97 @@ +import qbs.TextFile + +Project { + property int projectJobCount + property int productJobCount + property int moduleJobCount + JobLimit { + condition: projectJobCount !== -1 + jobPool: "singleton" + jobCount: projectJobCount + } + JobLimit { + condition: projectJobCount !== -1 + jobPool: "singleton" + jobCount: 100 + } + CppApplication { + name: "tool" + consoleApplication: true + cpp.cxxLanguageVersion: "c++14" + Properties { + condition: qbs.targetOS.contains("macos") + cpp.minimumMacosVersion: "10.9" + } + files: "main.cpp" + Group { + fileTagsFilter: "application" + fileTags: "tool_tag" + } + Export { + Rule { + alwaysRun: true + inputs: "tool_in" + explicitlyDependsOnFromDependencies: "tool_tag" + Artifact { filePath: input.completeBaseName + ".out"; fileTags: "tool_out" } + prepare: { + var cmd = new Command(explicitlyDependsOn.tool_tag[0].filePath, + [output.filePath]); + cmd.workingDirectory = product.buildDirectory; + cmd.description = "Running tool"; + cmd.jobPool = "singleton"; + return cmd; + } + } + JobLimit { + condition: project.moduleJobCount !== -1 + jobPool: "singleton" + jobCount: project.moduleJobCount + } + JobLimit { + condition: project.moduleJobCount !== -1 + jobPool: "singleton" + jobCount: 200 + } + } + } + Product { + name: "p" + type: "tool_out" + Depends { name: "tool" } + Rule { + multiplex: true + outputFileTags: "tool_in" + outputArtifacts: { + var artifacts = []; + for (var i = 0; i < 7; ++i) + artifacts.push({filePath: "file" + i + ".in", fileTags: "tool_in"}); + return artifacts; + } + prepare: { + var commands = []; + for (var i = 0; i < outputs.tool_in.length; ++i) { + var cmd = new JavaScriptCommand(); + var output = outputs.tool_in[i]; + cmd.output = output.filePath; + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { + var f = new TextFile(output, TextFile.WriteOnly); + f.close(); + } + commands.push(cmd); + }; + return commands; + } + } + JobLimit { + condition: project.productJobCount !== -1 + jobPool: "singleton" + jobCount: project.productJobCount + } + JobLimit { + condition: project.productJobCount !== -1 + jobPool: "singleton" + jobCount: 300 + } + } +} diff --git a/tests/auto/blackbox/testdata-joblimits/job-limits/main.cpp b/tests/auto/blackbox/testdata-joblimits/job-limits/main.cpp new file mode 100644 index 000000000..0a94c6393 --- /dev/null +++ b/tests/auto/blackbox/testdata-joblimits/job-limits/main.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <cerrno> +#include <chrono> +#include <cstdio> +#include <cstring> +#include <iostream> +#include <string> +#include <thread> + +#if defined(_WIN32) || defined(WIN32) +#include <io.h> +#include <sys/locking.h> +#else +#include <unistd.h> +#endif + +static bool tryLock(FILE *f) +{ + const int exitCode = +#if defined(_WIN32) || defined(WIN32) + _locking(_fileno(f), _LK_NBLCK, 10); + +#else + lockf(fileno(f), F_TLOCK, 10); +#endif + return exitCode == 0; +} + +int main(int argc, char *argv[]) +{ + if (argc != 2) { + std::cerr << "tool needs exactly one argument" << std::endl; + return 1; + } + + const std::string lockFilePath = std::string(argv[0]) + ".lock"; + std::FILE * const lockFile = std::fopen(lockFilePath.c_str(), "w"); + if (!lockFile) { + std::cerr << "cannot open lock file: " << strerror(errno) << std::endl; + return 2; + } + if (!tryLock(lockFile)) { + if (errno == EACCES || errno == EAGAIN) { + std::cerr << "tool is exclusive" << std::endl; + return 3; + } else { + std::cerr << "unexpected lock failure: " << strerror(errno) << std::endl; + fclose(lockFile); + return 4; + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + fclose(lockFile); + std::FILE * const output = std::fopen(argv[1], "w"); + if (!output) { + std::cerr << "cannot create output file: " << strerror(errno) << std::endl; + return 5; + } + fclose(output); +} diff --git a/tests/auto/blackbox/testdata-qt/add-qobject-macro-to-generated-cpp-file/add-qobject-macro-to-generated-cpp-file.qbs b/tests/auto/blackbox/testdata-qt/add-qobject-macro-to-generated-cpp-file/add-qobject-macro-to-generated-cpp-file.qbs new file mode 100644 index 000000000..db0e20097 --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/add-qobject-macro-to-generated-cpp-file/add-qobject-macro-to-generated-cpp-file.qbs @@ -0,0 +1,25 @@ +import qbs.File + +QtApplication { + name: "p" + files: ["main.cpp", "object.h"] + Group { + files: "object.cpp.in" + fileTags: "cpp.in" + } + Rule { + inputs: "cpp.in" + Artifact { + filePath: input.completeBaseName + fileTags: "cpp" + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generatating " + output.fileName; + cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); } + return cmd; + } + } + cpp.includePaths: path +} + diff --git a/tests/auto/blackbox/testdata-qt/add-qobject-macro-to-generated-cpp-file/main.cpp b/tests/auto/blackbox/testdata-qt/add-qobject-macro-to-generated-cpp-file/main.cpp new file mode 100644 index 000000000..3f57ddafb --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/add-qobject-macro-to-generated-cpp-file/main.cpp @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "object.h" + +int main() +{ + Object o; + o.f(); +} diff --git a/tests/auto/blackbox/testdata-qt/add-qobject-macro-to-generated-cpp-file/object.cpp.in b/tests/auto/blackbox/testdata-qt/add-qobject-macro-to-generated-cpp-file/object.cpp.in new file mode 100644 index 000000000..b1b9922af --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/add-qobject-macro-to-generated-cpp-file/object.cpp.in @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <object.h> + +#include <QObject> + +// class InternalClass : public QObject +// { +// Q_OBJECT +// }; + +void Object::f() { } + + +// #include <object.moc> diff --git a/tests/auto/blackbox/testdata-qt/add-qobject-macro-to-generated-cpp-file/object.h b/tests/auto/blackbox/testdata-qt/add-qobject-macro-to-generated-cpp-file/object.h new file mode 100644 index 000000000..5537a8d32 --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/add-qobject-macro-to-generated-cpp-file/object.h @@ -0,0 +1,32 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +class Object { +public: + void f(); +}; diff --git a/tests/auto/blackbox/testdata-qt/auto-qrc/auto-qrc.qbs b/tests/auto/blackbox/testdata-qt/auto-qrc/auto-qrc.qbs index 63906fd77..e08f89032 100644 --- a/tests/auto/blackbox/testdata-qt/auto-qrc/auto-qrc.qbs +++ b/tests/auto/blackbox/testdata-qt/auto-qrc/auto-qrc.qbs @@ -1,5 +1,3 @@ -import qbs - Project { QtApplication { name: "app" diff --git a/tests/auto/blackbox/testdata-qt/cached-qml/cached-qml.qbs b/tests/auto/blackbox/testdata-qt/cached-qml/cached-qml.qbs index 5117557e1..c95f1190d 100644 --- a/tests/auto/blackbox/testdata-qt/cached-qml/cached-qml.qbs +++ b/tests/auto/blackbox/testdata-qt/cached-qml/cached-qml.qbs @@ -1,11 +1,14 @@ -import qbs import qbs.Utilities CppApplication { name: "app" + consoleApplication: true Depends { name: "Qt.core" } Depends { name: "Qt.quick" } Depends { name: "Qt.qml" } + install: true + installDir: "" + qbs.installPrefix: "" Qt.qml.generateCacheFiles: true Qt.qml.cacheFilesInstallDir: "data" @@ -16,11 +19,6 @@ CppApplication { "stuff.js" ] - Group { - fileTagsFilter: ["application"] - qbs.install: true - } - // Install the C++ sources to tell the blackbox test that Qt.qmlcache is not available. Group { condition: !Qt.qml.cachingEnabled diff --git a/tests/auto/blackbox/testdata-qt/combined-moc/combined-moc.qbs b/tests/auto/blackbox/testdata-qt/combined-moc/combined-moc.qbs index 34529fce6..acbed1639 100644 --- a/tests/auto/blackbox/testdata-qt/combined-moc/combined-moc.qbs +++ b/tests/auto/blackbox/testdata-qt/combined-moc/combined-moc.qbs @@ -1,5 +1,3 @@ -import qbs - QtApplication { name: "theapp" files: [ diff --git a/tests/auto/blackbox/testdata-qt/dbus-adaptors/car.qbs b/tests/auto/blackbox/testdata-qt/dbus-adaptors/car.qbs index f89a8473b..34aab4701 100644 --- a/tests/auto/blackbox/testdata-qt/dbus-adaptors/car.qbs +++ b/tests/auto/blackbox/testdata-qt/dbus-adaptors/car.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "car" condition: Qt.dbus.present diff --git a/tests/auto/blackbox/testdata-qt/dbus-interfaces/controller.qbs b/tests/auto/blackbox/testdata-qt/dbus-interfaces/controller.qbs index f170d4a20..a1bde7f10 100644 --- a/tests/auto/blackbox/testdata-qt/dbus-interfaces/controller.qbs +++ b/tests/auto/blackbox/testdata-qt/dbus-interfaces/controller.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "controller" condition: Qt.dbus.present diff --git a/tests/auto/blackbox/testdata-qt/included-moc-cpp/included-moc-cpp.qbs b/tests/auto/blackbox/testdata-qt/included-moc-cpp/included-moc-cpp.qbs new file mode 100644 index 000000000..1ed85ccdd --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/included-moc-cpp/included-moc-cpp.qbs @@ -0,0 +1,9 @@ +import qbs + +QtApplication { + files: [ + "main.cpp", + "myobject.cpp", + "myobject.h", + ] +} diff --git a/tests/auto/blackbox/testdata-qt/included-moc-cpp/main.cpp b/tests/auto/blackbox/testdata-qt/included-moc-cpp/main.cpp new file mode 100644 index 000000000..5323e4c98 --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/included-moc-cpp/main.cpp @@ -0,0 +1,7 @@ +#include "myobject.h" + +int main() +{ + MyObject o; + QObject::connect(&o, &QObject::destroyed, [] { }); +} diff --git a/tests/auto/blackbox/testdata-qt/included-moc-cpp/myobject.cpp b/tests/auto/blackbox/testdata-qt/included-moc-cpp/myobject.cpp new file mode 100644 index 000000000..de0988c24 --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/included-moc-cpp/myobject.cpp @@ -0,0 +1,3 @@ +#include "myobject.h" + +#include <moc_myobject.cpp> diff --git a/tests/auto/blackbox/testdata-qt/included-moc-cpp/myobject.h b/tests/auto/blackbox/testdata-qt/included-moc-cpp/myobject.h new file mode 100644 index 000000000..61c2920aa --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/included-moc-cpp/myobject.h @@ -0,0 +1,11 @@ +#ifndef MYOBJECT_H +#define MYOBJECT_H + +#include <QObject> + +class MyObject : public QObject +{ + Q_OBJECT +}; + +#endif diff --git a/tests/auto/blackbox/testdata-qt/lrelease/lrelease.qbs b/tests/auto/blackbox/testdata-qt/lrelease/lrelease.qbs index b4119402f..978aba333 100644 --- a/tests/auto/blackbox/testdata-qt/lrelease/lrelease.qbs +++ b/tests/auto/blackbox/testdata-qt/lrelease/lrelease.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "lrelease-test" type: ["ts"] diff --git a/tests/auto/blackbox/testdata-qt/mixed-build-variants/mixed-build-variants.qbs b/tests/auto/blackbox/testdata-qt/mixed-build-variants/mixed-build-variants.qbs index 8f2c1c7fd..7d8ab1b90 100644 --- a/tests/auto/blackbox/testdata-qt/mixed-build-variants/mixed-build-variants.qbs +++ b/tests/auto/blackbox/testdata-qt/mixed-build-variants/mixed-build-variants.qbs @@ -1,5 +1,3 @@ -import qbs - QtApplication { Properties { condition: qbs.toolchain.contains("msvc") diff --git a/tests/auto/blackbox/testdata-qt/moc-and-cxx-combining/moc-and-cxx-combining.qbs b/tests/auto/blackbox/testdata-qt/moc-and-cxx-combining/moc-and-cxx-combining.qbs index 1b0b9f54a..f5463853b 100644 --- a/tests/auto/blackbox/testdata-qt/moc-and-cxx-combining/moc-and-cxx-combining.qbs +++ b/tests/auto/blackbox/testdata-qt/moc-and-cxx-combining/moc-and-cxx-combining.qbs @@ -1,5 +1,3 @@ -import qbs - QtApplication { cpp.combineCxxSources: true files: ["main.cpp", "myobject.h", "myobject.cpp"] diff --git a/tests/auto/blackbox/testdata-qt/moc-flags/moc-flags.qbs b/tests/auto/blackbox/testdata-qt/moc-flags/moc-flags.qbs index d42c7ad87..7cc4e5c4d 100644 --- a/tests/auto/blackbox/testdata-qt/moc-flags/moc-flags.qbs +++ b/tests/auto/blackbox/testdata-qt/moc-flags/moc-flags.qbs @@ -1,5 +1,3 @@ -import qbs - QtApplication { files: ["main.cpp", "blubb.h"] } diff --git a/tests/auto/blackbox/testdata-qt/moc-same-file-name/moc-same-file-name.qbs b/tests/auto/blackbox/testdata-qt/moc-same-file-name/moc-same-file-name.qbs index 42fcff82e..461fec50e 100644 --- a/tests/auto/blackbox/testdata-qt/moc-same-file-name/moc-same-file-name.qbs +++ b/tests/auto/blackbox/testdata-qt/moc-same-file-name/moc-same-file-name.qbs @@ -1,5 +1,3 @@ -import qbs - QtApplication { name: "app" cpp.cxxLanguageVersion: "c++11" diff --git a/tests/auto/blackbox/testdata-qt/pkgconfig/pkgconfig.qbs b/tests/auto/blackbox/testdata-qt/pkgconfig/pkgconfig.qbs index 132ce337a..04b0097ef 100644 --- a/tests/auto/blackbox/testdata-qt/pkgconfig/pkgconfig.qbs +++ b/tests/auto/blackbox/testdata-qt/pkgconfig/pkgconfig.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.Probes Project { diff --git a/tests/auto/blackbox/testdata-qt/plugin-meta-data/plugin-meta-data.qbs b/tests/auto/blackbox/testdata-qt/plugin-meta-data/plugin-meta-data.qbs index d44b82d4a..f018b34e0 100644 --- a/tests/auto/blackbox/testdata-qt/plugin-meta-data/plugin-meta-data.qbs +++ b/tests/auto/blackbox/testdata-qt/plugin-meta-data/plugin-meta-data.qbs @@ -1,5 +1,3 @@ -import qbs - Project { QtApplication { name: "app" diff --git a/tests/auto/blackbox/testdata-qt/plugin-support/modules/m1/m1.qbs b/tests/auto/blackbox/testdata-qt/plugin-support/modules/m1/m1.qbs new file mode 100644 index 000000000..a4cad304f --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/plugin-support/modules/m1/m1.qbs @@ -0,0 +1,12 @@ +Module { + property bool useDummy + Depends { name: "Qt.plugin_support" } + Properties { + condition: useDummy + Qt.plugin_support.pluginsByType: ({imageformats: "dummy"}) + } + Properties { + condition: Qt.plugin_support.allPluginsByType && Qt.plugin_support.allPluginsByType.imageformats + Qt.plugin_support.pluginsByType: ({imageformats: Qt.plugin_support.allPluginsByType.imageformats[0]}) + } +} diff --git a/tests/auto/blackbox/testdata-qt/plugin-support/modules/m2/m2.qbs b/tests/auto/blackbox/testdata-qt/plugin-support/modules/m2/m2.qbs new file mode 100644 index 000000000..c4730ab6b --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/plugin-support/modules/m2/m2.qbs @@ -0,0 +1,7 @@ +Module { + Depends { name: "Qt.plugin_support" } + Properties { + condition: Qt.plugin_support.allPluginsByType && Qt.plugin_support.allPluginsByType.imageformats + Qt.plugin_support.pluginsByType: ({imageformats: Qt.plugin_support.allPluginsByType.imageformats[1]}) + } +} diff --git a/tests/auto/blackbox/testdata-qt/plugin-support/plugin-support-main.cpp b/tests/auto/blackbox/testdata-qt/plugin-support/plugin-support-main.cpp new file mode 100644 index 000000000..237c8ce18 --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/plugin-support/plugin-support-main.cpp @@ -0,0 +1 @@ +int main() {} diff --git a/tests/auto/blackbox/testdata-qt/plugin-support/plugin-support.qbs b/tests/auto/blackbox/testdata-qt/plugin-support/plugin-support.qbs new file mode 100644 index 000000000..c554a7dc2 --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/plugin-support/plugin-support.qbs @@ -0,0 +1,18 @@ +QtGuiApplication { + Probe { + id: staticProbe + property bool isStaticQt: Qt.gui.isStaticLibrary + property var plugins: Qt.plugin_support.effectivePluginsByType + property var allPlugins: Qt.plugin_support.allPluginsByType + configure: { + console.info("static Qt: " + isStaticQt); + console.info("requested image plugins: %" + plugins.imageformats + "%"); + console.info("all image plugins: #" + allPlugins.imageformats + "#"); + console.info("platform plugin count: " + (plugins.platforms || []).length); + } + } + + Depends { name: "m1" } + Depends { name: "m2" } + files: "plugin-support-main.cpp" +} diff --git a/tests/auto/blackbox/testdata-qt/qml-debugging/qml-debugging.qbs b/tests/auto/blackbox/testdata-qt/qml-debugging/qml-debugging.qbs index 3606b4aa3..8176a7c3e 100644 --- a/tests/auto/blackbox/testdata-qt/qml-debugging/qml-debugging.qbs +++ b/tests/auto/blackbox/testdata-qt/qml-debugging/qml-debugging.qbs @@ -1,5 +1,3 @@ -import qbs - QtApplication { name: "debuggable-app" consoleApplication: true diff --git a/tests/auto/blackbox/testdata-qt/qobject-in-mm/qobject-in-mm.qbs b/tests/auto/blackbox/testdata-qt/qobject-in-mm/qobject-in-mm.qbs index 2f819d012..3ceb8515b 100644 --- a/tests/auto/blackbox/testdata-qt/qobject-in-mm/qobject-in-mm.qbs +++ b/tests/auto/blackbox/testdata-qt/qobject-in-mm/qobject-in-mm.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Depends { name: "Qt.core" } files: ["main.mm"] diff --git a/tests/auto/blackbox/testdata-qt/qrc/i.qbs b/tests/auto/blackbox/testdata-qt/qrc/i.qbs index b6aeb9c15..c005490c4 100644 --- a/tests/auto/blackbox/testdata-qt/qrc/i.qbs +++ b/tests/auto/blackbox/testdata-qt/qrc/i.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { consoleApplication: true diff --git a/tests/auto/blackbox/testdata-qt/qt-keywords/qt-keywords.qbs b/tests/auto/blackbox/testdata-qt/qt-keywords/qt-keywords.qbs index 59e964258..ddd93827d 100644 --- a/tests/auto/blackbox/testdata-qt/qt-keywords/qt-keywords.qbs +++ b/tests/auto/blackbox/testdata-qt/qt-keywords/qt-keywords.qbs @@ -1,5 +1,3 @@ -import qbs - QtApplication { files: ["main.cpp"] } diff --git a/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs b/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs index e010e76e6..43151bc56 100644 --- a/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs +++ b/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Environment import qbs.FileInfo @@ -29,10 +28,7 @@ Project { Depends { name: "app" } Rule { inputsFromDependencies: ["application"] - Artifact { - filePath: "dummy" - fileTags: ["runner"] - } + outputFileTags: ["runner"] prepare: { var cmd = new Command(input.filePath); cmd.description = "running " + input.filePath; diff --git a/tests/auto/blackbox/testdata-qt/quick-compiler/quick-compiler.qbs b/tests/auto/blackbox/testdata-qt/quick-compiler/quick-compiler.qbs index 5f79df581..b141c8672 100644 --- a/tests/auto/blackbox/testdata-qt/quick-compiler/quick-compiler.qbs +++ b/tests/auto/blackbox/testdata-qt/quick-compiler/quick-compiler.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Depends { name: "Qt.quick" } Qt.quick.useCompiler: Qt.quick.compilerAvailable diff --git a/tests/auto/blackbox/testdata-qt/remove-moc-header-from-file-list/remove-moc-header-from-file-list.qbs b/tests/auto/blackbox/testdata-qt/remove-moc-header-from-file-list/remove-moc-header-from-file-list.qbs index 120f10b0d..b8ac33b96 100644 --- a/tests/auto/blackbox/testdata-qt/remove-moc-header-from-file-list/remove-moc-header-from-file-list.qbs +++ b/tests/auto/blackbox/testdata-qt/remove-moc-header-from-file-list/remove-moc-header-from-file-list.qbs @@ -1,5 +1,3 @@ -import qbs - QtApplication { name: "p" files: [ diff --git a/tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/static-qt-plugin-linking.qbs b/tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/static-qt-plugin-linking.qbs index a72ce0098..ed479c8f1 100644 --- a/tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/static-qt-plugin-linking.qbs +++ b/tests/auto/blackbox/testdata-qt/static-qt-plugin-linking/static-qt-plugin-linking.qbs @@ -1,5 +1,3 @@ -import qbs - StaticLibrary { name: "somelib" Probe { @@ -13,5 +11,6 @@ StaticLibrary { } Depends { name: "Qt.core" } + Depends { name: "Qt.gui" } Depends { name: "Qt.qminimal"; condition: Qt.core.staticBuild; } } diff --git a/tests/auto/blackbox/testdata-qt/trackAddMocInclude/before/test.qbs b/tests/auto/blackbox/testdata-qt/trackAddMocInclude/before/test.qbs index 0e341c21f..0aa1b1d23 100644 --- a/tests/auto/blackbox/testdata-qt/trackAddMocInclude/before/test.qbs +++ b/tests/auto/blackbox/testdata-qt/trackAddMocInclude/before/test.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Application { Depends { name: "Qt.core" } cpp.cxxLanguageVersion: "c++11" diff --git a/tests/auto/blackbox/testdata-qt/trackQObjChange/i.qbs b/tests/auto/blackbox/testdata-qt/trackQObjChange/i.qbs index c18fab086..348017547 100644 --- a/tests/auto/blackbox/testdata-qt/trackQObjChange/i.qbs +++ b/tests/auto/blackbox/testdata-qt/trackQObjChange/i.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { type: "application" diff --git a/tests/auto/blackbox/testdata-qt/unmocable/unmocable.qbs b/tests/auto/blackbox/testdata-qt/unmocable/unmocable.qbs index bb86fb223..780d27e30 100644 --- a/tests/auto/blackbox/testdata-qt/unmocable/unmocable.qbs +++ b/tests/auto/blackbox/testdata-qt/unmocable/unmocable.qbs @@ -1,5 +1,3 @@ -import qbs - Application { Depends { name: "Qt.core" } files: ["main.cpp"] diff --git a/tests/auto/blackbox/testdata/QTBUG-51237/modules/mymodule/mymodule.qbs b/tests/auto/blackbox/testdata/QTBUG-51237/modules/mymodule/mymodule.qbs index 223da0b3c..55495a950 100644 --- a/tests/auto/blackbox/testdata/QTBUG-51237/modules/mymodule/mymodule.qbs +++ b/tests/auto/blackbox/testdata/QTBUG-51237/modules/mymodule/mymodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { property stringList theProperty: [] //property stringList otherProperty: theProperty.concat([]) diff --git a/tests/auto/blackbox/testdata/QTBUG-51237/qtbug-51237.qbs b/tests/auto/blackbox/testdata/QTBUG-51237/qtbug-51237.qbs index 6edea9dc6..849a943f8 100644 --- a/tests/auto/blackbox/testdata/QTBUG-51237/qtbug-51237.qbs +++ b/tests/auto/blackbox/testdata/QTBUG-51237/qtbug-51237.qbs @@ -1,14 +1,9 @@ -import qbs - Product { type: "custom" Depends { name: "mymodule" } Rule { multiplex: true - Artifact { - filePath: "dummy.custom" - fileTags: ["custom"] - } + outputFileTags: ["custom"] prepare: { var theProperty = product.mymodule.theProperty; if (!theProperty) diff --git a/tests/auto/blackbox/testdata/add-filetag-to-generated-artifact/add-filetag-to-generated-artifact.qbs b/tests/auto/blackbox/testdata/add-filetag-to-generated-artifact/add-filetag-to-generated-artifact.qbs index 1bc9b15ef..7fba9c988 100644 --- a/tests/auto/blackbox/testdata/add-filetag-to-generated-artifact/add-filetag-to-generated-artifact.qbs +++ b/tests/auto/blackbox/testdata/add-filetag-to-generated-artifact/add-filetag-to-generated-artifact.qbs @@ -1,11 +1,12 @@ -import qbs import qbs.File Project { + property bool enableTagging CppApplication { name: "my_app" files: "main.cpp" Group { + condition: project.enableTagging fileTagsFilter: ["application"] fileTags: ["app-to-compress"] } diff --git a/tests/auto/blackbox/testdata/always-run/rule.qbs b/tests/auto/blackbox/testdata/always-run/rule.qbs index 6dbb5c845..7d61e5daf 100644 --- a/tests/auto/blackbox/testdata/always-run/rule.qbs +++ b/tests/auto/blackbox/testdata/always-run/rule.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Product { diff --git a/tests/auto/blackbox/testdata/always-run/transformer.qbs b/tests/auto/blackbox/testdata/always-run/transformer.qbs index b5c83eaab..8ae44fb77 100644 --- a/tests/auto/blackbox/testdata/always-run/transformer.qbs +++ b/tests/auto/blackbox/testdata/always-run/transformer.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Product { diff --git a/tests/auto/blackbox/testdata/archiver/archivable.qbs b/tests/auto/blackbox/testdata/archiver/archivable.qbs index d6a8e048d..8e521ddf0 100644 --- a/tests/auto/blackbox/testdata/archiver/archivable.qbs +++ b/tests/auto/blackbox/testdata/archiver/archivable.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "archivable" type: "archiver.archive" diff --git a/tests/auto/blackbox/testdata/artifact-scanning/artifact-scanning.qbs b/tests/auto/blackbox/testdata/artifact-scanning/artifact-scanning.qbs index 6fa1b5e93..bcd236163 100644 --- a/tests/auto/blackbox/testdata/artifact-scanning/artifact-scanning.qbs +++ b/tests/auto/blackbox/testdata/artifact-scanning/artifact-scanning.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "p1" diff --git a/tests/auto/blackbox/testdata/artifacts-map-change-tracking/artifacts-map-change-tracking.qbs b/tests/auto/blackbox/testdata/artifacts-map-change-tracking/artifacts-map-change-tracking.qbs index 0d3c361f6..879138536 100644 --- a/tests/auto/blackbox/testdata/artifacts-map-change-tracking/artifacts-map-change-tracking.qbs +++ b/tests/auto/blackbox/testdata/artifacts-map-change-tracking/artifacts-map-change-tracking.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Project { diff --git a/tests/auto/blackbox/testdata/artifacts-map-invalidation/artifacts-map-invalidation.qbs b/tests/auto/blackbox/testdata/artifacts-map-invalidation/artifacts-map-invalidation.qbs index 9d0c81d26..cd4e9b790 100644 --- a/tests/auto/blackbox/testdata/artifacts-map-invalidation/artifacts-map-invalidation.qbs +++ b/tests/auto/blackbox/testdata/artifacts-map-invalidation/artifacts-map-invalidation.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Project { diff --git a/tests/auto/blackbox/testdata/artifacts-map-race-condition/artifacts-map-race-condition.qbs b/tests/auto/blackbox/testdata/artifacts-map-race-condition/artifacts-map-race-condition.qbs index 0ab4cea88..86255c6c3 100644 --- a/tests/auto/blackbox/testdata/artifacts-map-race-condition/artifacts-map-race-condition.qbs +++ b/tests/auto/blackbox/testdata/artifacts-map-race-condition/artifacts-map-race-condition.qbs @@ -1,11 +1,9 @@ -import qbs - Product { name: "p" type: ["custom1", "custom2", "custom3", "custom4", "custom5"] Rule { multiplex: true - Artifact { filePath: "dummy"; fileTags: "custom1" } + outputFileTags: "custom1" prepare: { var cmd = new JavaScriptCommand(); cmd.description = "reader1"; @@ -24,7 +22,7 @@ Product { } Rule { multiplex: true - Artifact { filePath: "helperdummy"; fileTags: "helper" } + outputFileTags: "helper" prepare: { var cmd = new JavaScriptCommand(); cmd.description = "helper"; @@ -55,7 +53,7 @@ Product { } Rule { multiplex: true - Artifact { filePath: "dummy2"; fileTags: "custom5" } + outputFileTags: "custom5" prepare: { var cmd = new JavaScriptCommand(); cmd.description = "reader2"; diff --git a/tests/auto/blackbox/testdata/assembly/assembly.qbs b/tests/auto/blackbox/testdata/assembly/assembly.qbs index 7dd82731a..f7bd4ecad 100644 --- a/tests/auto/blackbox/testdata/assembly/assembly.qbs +++ b/tests/auto/blackbox/testdata/assembly/assembly.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.TextFile Project { diff --git a/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs b/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs index 6850ee138..92d5ec6dd 100644 --- a/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs +++ b/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Project { @@ -6,18 +5,18 @@ Project { name: "helper-app" type: ["application", "test-helper"] consoleApplication: true + install: true files: "helper-main.cpp" cpp.executableSuffix: ".exe" Group { fileTagsFilter: "application" fileTags: "test-helper" - qbs.install: true - qbs.installDir: "bin" } } CppApplication { name: "test-app" type: ["application", "autotest"] + Depends { name: "autotest" } files: "test-main.cpp" } diff --git a/tests/auto/blackbox/testdata/autotests/autotests.qbs b/tests/auto/blackbox/testdata/autotests/autotests.qbs new file mode 100644 index 000000000..a2c2646dc --- /dev/null +++ b/tests/auto/blackbox/testdata/autotests/autotests.qbs @@ -0,0 +1,4 @@ +Project { + references: ["test1", "test2", "test3"] + AutotestRunner {} +} diff --git a/tests/auto/blackbox/testdata/autotests/test1/test1.cpp b/tests/auto/blackbox/testdata/autotests/test1/test1.cpp new file mode 100644 index 000000000..08d9d4782 --- /dev/null +++ b/tests/auto/blackbox/testdata/autotests/test1/test1.cpp @@ -0,0 +1,12 @@ +#include <cstdlib> +#include <iostream> + +int main(int argc, char *[]) +{ + if (argc != 2) { + std::cerr << "This test needs exactly one argument" << std::endl; + std::cerr << "FAIL" << std::endl; + return EXIT_FAILURE; + } + std::cout << "PASS" << std::endl; +} diff --git a/tests/auto/blackbox/testdata/autotests/test1/test1.qbs b/tests/auto/blackbox/testdata/autotests/test1/test1.qbs new file mode 100644 index 000000000..8b078a759 --- /dev/null +++ b/tests/auto/blackbox/testdata/autotests/test1/test1.qbs @@ -0,0 +1,9 @@ +CppApplication { + name: "test1" + type: base.concat("autotest") + + Depends { name: "autotest" } + autotest.arguments: "--dummy" + + files: "test1.cpp" +} diff --git a/tests/auto/blackbox/testdata/autotests/test2/test2-resource.txt b/tests/auto/blackbox/testdata/autotests/test2/test2-resource.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/auto/blackbox/testdata/autotests/test2/test2-resource.txt diff --git a/tests/auto/blackbox/testdata/autotests/test2/test2.cpp b/tests/auto/blackbox/testdata/autotests/test2/test2.cpp new file mode 100644 index 000000000..dcc3d270a --- /dev/null +++ b/tests/auto/blackbox/testdata/autotests/test2/test2.cpp @@ -0,0 +1,13 @@ +#include <cstdlib> +#include <fstream> +#include <iostream> + +int main() +{ + std::ifstream input("test2-resource.txt"); + if (!input.is_open()) { + std::cerr << "Test resource not found"; + return EXIT_FAILURE; + } + std::cout << "PASS" << std::endl; +} diff --git a/tests/auto/blackbox/testdata/autotests/test2/test2.qbs b/tests/auto/blackbox/testdata/autotests/test2/test2.qbs new file mode 100644 index 000000000..2ce6ea5fa --- /dev/null +++ b/tests/auto/blackbox/testdata/autotests/test2/test2.qbs @@ -0,0 +1,9 @@ +CppApplication { + name: "test2" + type: base.concat("autotest") + + Depends { name: "autotest" } + autotest.workingDir: sourceDirectory + + files: "test2.cpp" +} diff --git a/tests/auto/blackbox/testdata/autotests/test3/test3.cpp b/tests/auto/blackbox/testdata/autotests/test3/test3.cpp new file mode 100644 index 000000000..2ce7e2bf6 --- /dev/null +++ b/tests/auto/blackbox/testdata/autotests/test3/test3.cpp @@ -0,0 +1,9 @@ +#include <cstdlib> +#include <iostream> + +int main() +{ + std::cerr << "I am an awful test"; + std::cerr << "FAIL" << std::endl; + return EXIT_FAILURE; +} diff --git a/tests/auto/blackbox/testdata/autotests/test3/test3.qbs b/tests/auto/blackbox/testdata/autotests/test3/test3.qbs new file mode 100644 index 000000000..34550dee7 --- /dev/null +++ b/tests/auto/blackbox/testdata/autotests/test3/test3.qbs @@ -0,0 +1,9 @@ +CppApplication { + name: "test3" + type: base.concat("autotest") + + Depends { name: "autotest" } + autotest.allowFailure: true + + files: "test3.cpp" +} diff --git a/tests/auto/blackbox/testdata/aux-inputs-from-deps/aux-inputs-from-deps.qbs b/tests/auto/blackbox/testdata/aux-inputs-from-deps/aux-inputs-from-deps.qbs index 620ae2ea0..6a9e9823d 100644 --- a/tests/auto/blackbox/testdata/aux-inputs-from-deps/aux-inputs-from-deps.qbs +++ b/tests/auto/blackbox/testdata/aux-inputs-from-deps/aux-inputs-from-deps.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.TextFile diff --git a/tests/auto/blackbox/testdata/badInterpreter/badInterpreter.qbs b/tests/auto/blackbox/testdata/badInterpreter/badInterpreter.qbs index a45391478..bef82a003 100644 --- a/tests/auto/blackbox/testdata/badInterpreter/badInterpreter.qbs +++ b/tests/auto/blackbox/testdata/badInterpreter/badInterpreter.qbs @@ -1,5 +1,3 @@ -import qbs - Project { qbsSearchPaths: base.concat(["qbs"]) diff --git a/tests/auto/blackbox/testdata/badInterpreter/qbs/modules/script-test/script-test.qbs b/tests/auto/blackbox/testdata/badInterpreter/qbs/modules/script-test/script-test.qbs index 79c008cf6..4d043ee59 100644 --- a/tests/auto/blackbox/testdata/badInterpreter/qbs/modules/script-test/script-test.qbs +++ b/tests/auto/blackbox/testdata/badInterpreter/qbs/modules/script-test/script-test.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo import qbs.TextFile diff --git a/tests/auto/blackbox/testdata/bom-sources/bom-sources.qbs b/tests/auto/blackbox/testdata/bom-sources/bom-sources.qbs index 8b5dbb238..4446355bc 100644 --- a/tests/auto/blackbox/testdata/bom-sources/bom-sources.qbs +++ b/tests/auto/blackbox/testdata/bom-sources/bom-sources.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "app" files: ["main.cpp", "theheader.h"] diff --git a/tests/auto/blackbox/testdata/build-data-of-disabled-product/build-data-of-disabled-product.qbs b/tests/auto/blackbox/testdata/build-data-of-disabled-product/build-data-of-disabled-product.qbs index 7e9d4779b..d71facf15 100644 --- a/tests/auto/blackbox/testdata/build-data-of-disabled-product/build-data-of-disabled-product.qbs +++ b/tests/auto/blackbox/testdata/build-data-of-disabled-product/build-data-of-disabled-product.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "app" files: ["main.cpp", "test.cpp"] diff --git a/tests/auto/blackbox/testdata/build-directories/build-directories.qbs b/tests/auto/blackbox/testdata/build-directories/build-directories.qbs index dd8fc6c05..be7672ecf 100644 --- a/tests/auto/blackbox/testdata/build-directories/build-directories.qbs +++ b/tests/auto/blackbox/testdata/build-directories/build-directories.qbs @@ -1,15 +1,10 @@ -import qbs - Project { Product { name: "p1" type: "blubb1" Rule { multiplex: true - Artifact { - filePath: "dummy1.txt" - fileTags: product.type - } + outputFileTags: "blubb1" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; @@ -26,10 +21,7 @@ Project { Depends { name: "p1" } Rule { inputsFromDependencies: "blubb1" - Artifact { - filePath: "dummy2.txt" - fileTags: product.type - } + outputFileTags: "blubb2" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; diff --git a/tests/auto/blackbox/testdata/build-graph-versions/build-graph-versions.qbs b/tests/auto/blackbox/testdata/build-graph-versions/build-graph-versions.qbs index f6ae698a0..da7536315 100644 --- a/tests/auto/blackbox/testdata/build-graph-versions/build-graph-versions.qbs +++ b/tests/auto/blackbox/testdata/build-graph-versions/build-graph-versions.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: ["main.cpp"] } diff --git a/tests/auto/blackbox/testdata/buildenv-change/buildenv-change.qbs b/tests/auto/blackbox/testdata/buildenv-change/buildenv-change.qbs index c2445eafd..6c0bcc73e 100644 --- a/tests/auto/blackbox/testdata/buildenv-change/buildenv-change.qbs +++ b/tests/auto/blackbox/testdata/buildenv-change/buildenv-change.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Probe { id: dummy diff --git a/tests/auto/blackbox/testdata/change-in-disabled-product/change-in-disabled-product.qbs b/tests/auto/blackbox/testdata/change-in-disabled-product/change-in-disabled-product.qbs index 8a99d2c8c..2f0dfc08c 100644 --- a/tests/auto/blackbox/testdata/change-in-disabled-product/change-in-disabled-product.qbs +++ b/tests/auto/blackbox/testdata/change-in-disabled-product/change-in-disabled-product.qbs @@ -1,5 +1,3 @@ -import qbs - Product { condition: false files: [ diff --git a/tests/auto/blackbox/testdata/change-in-imported-file/change-in-imported-file.qbs b/tests/auto/blackbox/testdata/change-in-imported-file/change-in-imported-file.qbs index cb8bf0668..cf5354268 100644 --- a/tests/auto/blackbox/testdata/change-in-imported-file/change-in-imported-file.qbs +++ b/tests/auto/blackbox/testdata/change-in-imported-file/change-in-imported-file.qbs @@ -1,4 +1,3 @@ -import qbs import "prepare.js" as PrepareHelper Product { diff --git a/tests/auto/blackbox/testdata/change-tracking-and-multiplexing/change-tracking-and-multiplexing.qbs b/tests/auto/blackbox/testdata/change-tracking-and-multiplexing/change-tracking-and-multiplexing.qbs index 78bd8abda..d1215355c 100644 --- a/tests/auto/blackbox/testdata/change-tracking-and-multiplexing/change-tracking-and-multiplexing.qbs +++ b/tests/auto/blackbox/testdata/change-tracking-and-multiplexing/change-tracking-and-multiplexing.qbs @@ -1,5 +1,3 @@ -import qbs - StaticLibrary { name: "l" diff --git a/tests/auto/blackbox/testdata/changed-files/changed-files.qbs b/tests/auto/blackbox/testdata/changed-files/changed-files.qbs index dd222479f..e5790d2e9 100644 --- a/tests/auto/blackbox/testdata/changed-files/changed-files.qbs +++ b/tests/auto/blackbox/testdata/changed-files/changed-files.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile CppApplication { diff --git a/tests/auto/blackbox/testdata/changed-inputs-from-dependencies/changed-inputs-from-dependencies.qbs b/tests/auto/blackbox/testdata/changed-inputs-from-dependencies/changed-inputs-from-dependencies.qbs new file mode 100644 index 000000000..fb92d1838 --- /dev/null +++ b/tests/auto/blackbox/testdata/changed-inputs-from-dependencies/changed-inputs-from-dependencies.qbs @@ -0,0 +1,58 @@ +import qbs.File +import qbs.TextFile + +Project { + Product { + name: "dep" + type: "dep_tag" + + files: "input.txt" + + FileTagger { patterns: "*.txt"; fileTags: "inp_tag" } + + Rule { + inputs: "inp_tag" + Artifact { filePath: input.baseName + ".intermediate"; fileTags: "int_tag" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); } + return cmd; + } + } + Rule { + inputs: "int_tag" + Artifact { filePath: input.baseName + ".dep"; fileTags: "dep_tag" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); } + return cmd; + } + } + } + Product { + name: "p" + type: "p_tag" + + Depends { name: "dep" } + + Rule { + inputsFromDependencies: "dep_tag" + outputFileTags: "p_tag" + outputArtifacts: { + var dummy = new TextFile(input.filePath, TextFile.ReadOnly); + dummy.close(); + return [{ filePath: input.baseName + ".p", fileTags: "p_tag" }] + } + + prepare: { + console.info("running final prepare script"); + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); } + return cmd; + } + } + } +} diff --git a/tests/auto/blackbox/testdata/changed-inputs-from-dependencies/input.txt b/tests/auto/blackbox/testdata/changed-inputs-from-dependencies/input.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/auto/blackbox/testdata/changed-inputs-from-dependencies/input.txt diff --git a/tests/auto/blackbox/testdata/changed-rule-inputs/changed-rule-inputs.qbs b/tests/auto/blackbox/testdata/changed-rule-inputs/changed-rule-inputs.qbs index 8aef7b9b6..d11613c44 100644 --- a/tests/auto/blackbox/testdata/changed-rule-inputs/changed-rule-inputs.qbs +++ b/tests/auto/blackbox/testdata/changed-rule-inputs/changed-rule-inputs.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "p1" diff --git a/tests/auto/blackbox/testdata/check-timestamps/check-timestamps.qbs b/tests/auto/blackbox/testdata/check-timestamps/check-timestamps.qbs index 32456444c..65c29ca7a 100644 --- a/tests/auto/blackbox/testdata/check-timestamps/check-timestamps.qbs +++ b/tests/auto/blackbox/testdata/check-timestamps/check-timestamps.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "app" files: [ diff --git a/tests/auto/blackbox/testdata/choose-module-instance/choose-module-instance.qbs b/tests/auto/blackbox/testdata/choose-module-instance/choose-module-instance.qbs index 233e21746..5f4148624 100644 --- a/tests/auto/blackbox/testdata/choose-module-instance/choose-module-instance.qbs +++ b/tests/auto/blackbox/testdata/choose-module-instance/choose-module-instance.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Project { diff --git a/tests/auto/blackbox/testdata/choose-module-instance/gerbil.txt.in b/tests/auto/blackbox/testdata/choose-module-instance/gerbil.txt.in index 53b91dbcd..4722829a3 100644 --- a/tests/auto/blackbox/testdata/choose-module-instance/gerbil.txt.in +++ b/tests/auto/blackbox/testdata/choose-module-instance/gerbil.txt.in @@ -1,5 +1,5 @@ I once had a gerbil named Bobby, Who had an unusual hobby. -He $DID on a $THING, -and now -- oh my $IDOL, +He ${DID} on a ${THING}, +and now -- oh my ${IDOL}, now all that's left is a blobby. diff --git a/tests/auto/blackbox/testdata/choose-module-instance/modules/texttemplate/texttemplate.qbs b/tests/auto/blackbox/testdata/choose-module-instance/modules/texttemplate/texttemplate.qbs deleted file mode 100644 index aca755373..000000000 --- a/tests/auto/blackbox/testdata/choose-module-instance/modules/texttemplate/texttemplate.qbs +++ /dev/null @@ -1,49 +0,0 @@ -import qbs.TextFile - -Module { - property var dict: ({}) - FileTagger { - patterns: ["*.in"] - fileTags: ["texttemplate.input"] - } - Rule { - inputs: ["texttemplate.input"] - Artifact { - fileTags: ["text"] - filePath: input.completeBaseName - } - prepare: { - var cmd = new JavaScriptCommand(); - cmd.silent = true; - cmd.sourceCode = function() { - try { - var src = new TextFile(input.filePath, TextFile.ReadOnly); - var dst = new TextFile(output.filePath, TextFile.WriteOnly); - var rex = /\$([A-Z]+)/g; - while (!src.atEof()) { - rex.lastIndex = 0; - var line = src.readLine(); - while (true) { - var result = rex.exec(line); - if (!result) - break; - var replacement = input.texttemplate.dict[result[1]]; - if (replacement) { - line = line.substr(0, result.index) - + replacement - + line.substr(result.index + result[0].length); - } - } - dst.writeLine(line); - } - } finally { - if (src) - src.close(); - if (dst) - dst.close(); - } - }; - return [cmd]; - } - } -} diff --git a/tests/auto/blackbox/testdata/clean/clean.qbs b/tests/auto/blackbox/testdata/clean/clean.qbs index 28ebe91f0..ce3a8eb12 100644 --- a/tests/auto/blackbox/testdata/clean/clean.qbs +++ b/tests/auto/blackbox/testdata/clean/clean.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { DynamicLibrary { Depends { name: "cpp" } diff --git a/tests/auto/blackbox/testdata/cli/dotnettest.qbs b/tests/auto/blackbox/testdata/cli/dotnettest.qbs index c65a54c8c..9a10b8068 100644 --- a/tests/auto/blackbox/testdata/cli/dotnettest.qbs +++ b/tests/auto/blackbox/testdata/cli/dotnettest.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Application { Depends { name: "cli" } diff --git a/tests/auto/blackbox/testdata/cli/fshello.qbs b/tests/auto/blackbox/testdata/cli/fshello.qbs index 44dbb5c4f..0d503d90f 100644 --- a/tests/auto/blackbox/testdata/cli/fshello.qbs +++ b/tests/auto/blackbox/testdata/cli/fshello.qbs @@ -1,5 +1,3 @@ -import qbs - Application { Depends { name: "cli" } type: "application" diff --git a/tests/auto/blackbox/testdata/combined-sources/combined-sources.qbs b/tests/auto/blackbox/testdata/combined-sources/combined-sources.qbs index c22b41c4f..277fc7c3a 100644 --- a/tests/auto/blackbox/testdata/combined-sources/combined-sources.qbs +++ b/tests/auto/blackbox/testdata/combined-sources/combined-sources.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "theapp" files: [ diff --git a/tests/auto/blackbox/testdata/command-file/command-file.qbs b/tests/auto/blackbox/testdata/command-file/command-file.qbs index fb46a0712..8e25221c5 100644 --- a/tests/auto/blackbox/testdata/command-file/command-file.qbs +++ b/tests/auto/blackbox/testdata/command-file/command-file.qbs @@ -1,5 +1,3 @@ -import qbs - Project { StaticLibrary { name: "theLib" diff --git a/tests/auto/blackbox/testdata/compilerDefinesByLanguage/CppDefinesApp.qbs b/tests/auto/blackbox/testdata/compilerDefinesByLanguage/CppDefinesApp.qbs index da58f750a..b205ef2a7 100644 --- a/tests/auto/blackbox/testdata/compilerDefinesByLanguage/CppDefinesApp.qbs +++ b/tests/auto/blackbox/testdata/compilerDefinesByLanguage/CppDefinesApp.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: ["app.c"] diff --git a/tests/auto/blackbox/testdata/compilerDefinesByLanguage/compilerDefinesByLanguage.qbs b/tests/auto/blackbox/testdata/compilerDefinesByLanguage/compilerDefinesByLanguage.qbs index b4b126a50..001a87745 100644 --- a/tests/auto/blackbox/testdata/compilerDefinesByLanguage/compilerDefinesByLanguage.qbs +++ b/tests/auto/blackbox/testdata/compilerDefinesByLanguage/compilerDefinesByLanguage.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppDefinesApp { name: "A" diff --git a/tests/auto/blackbox/testdata/concurrent-executor/concurrent-executor.qbs b/tests/auto/blackbox/testdata/concurrent-executor/concurrent-executor.qbs index 9031890bd..802aa1450 100644 --- a/tests/auto/blackbox/testdata/concurrent-executor/concurrent-executor.qbs +++ b/tests/auto/blackbox/testdata/concurrent-executor/concurrent-executor.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.TextFile import "util.js" as Utils @@ -52,10 +51,7 @@ Product { } Rule { inputs: ["intermediate"] - Artifact { - filePath: "dummy2.final" - fileTags: ["final2"] - } + outputFileTags: "final2" prepare: { do Utils.sleep(6000); diff --git a/tests/auto/blackbox/testdata/conditional-export/conditional-export.qbs b/tests/auto/blackbox/testdata/conditional-export/conditional-export.qbs index c7b6ae09d..0f2fb2f49 100644 --- a/tests/auto/blackbox/testdata/conditional-export/conditional-export.qbs +++ b/tests/auto/blackbox/testdata/conditional-export/conditional-export.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property bool enableExport: false Product { diff --git a/tests/auto/blackbox/testdata/conditional-filetagger/conditional-filetagger.qbs b/tests/auto/blackbox/testdata/conditional-filetagger/conditional-filetagger.qbs index 286eb620a..5f0c93e46 100644 --- a/tests/auto/blackbox/testdata/conditional-filetagger/conditional-filetagger.qbs +++ b/tests/auto/blackbox/testdata/conditional-filetagger/conditional-filetagger.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "theApp" property bool enableTagger diff --git a/tests/auto/blackbox/testdata/configure/configure.qbs b/tests/auto/blackbox/testdata/configure/configure.qbs index 1a3c02bb5..af5638dde 100644 --- a/tests/auto/blackbox/testdata/configure/configure.qbs +++ b/tests/auto/blackbox/testdata/configure/configure.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.FileInfo Project { diff --git a/tests/auto/blackbox/testdata/configure/modules/definition/module.qbs b/tests/auto/blackbox/testdata/configure/modules/definition/module.qbs index 56a5492e4..1d647faa2 100644 --- a/tests/auto/blackbox/testdata/configure/modules/definition/module.qbs +++ b/tests/auto/blackbox/testdata/configure/modules/definition/module.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.Process Module { diff --git a/tests/auto/blackbox/testdata/conflicting-artifacts/conflicting-artifacts.qbs b/tests/auto/blackbox/testdata/conflicting-artifacts/conflicting-artifacts.qbs index f2c5cb2bc..ade073e15 100644 --- a/tests/auto/blackbox/testdata/conflicting-artifacts/conflicting-artifacts.qbs +++ b/tests/auto/blackbox/testdata/conflicting-artifacts/conflicting-artifacts.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "a" diff --git a/tests/auto/blackbox/testdata/cpu-features/cpu-features.qbs b/tests/auto/blackbox/testdata/cpu-features/cpu-features.qbs index 62f163a95..0bfdaceba 100644 --- a/tests/auto/blackbox/testdata/cpu-features/cpu-features.qbs +++ b/tests/auto/blackbox/testdata/cpu-features/cpu-features.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Depends { name: "cpufeatures" } cpufeatures.x86_sse2: true diff --git a/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs b/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs index e0301eee1..6beaabfa3 100644 --- a/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs +++ b/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "app" diff --git a/tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs b/tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs index ea32bbb52..735bfffbc 100644 --- a/tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs +++ b/tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.TextFile import qbs.FileInfo diff --git a/tests/auto/blackbox/testdata/dependency-profile-mismatch/dependency-profile-mismatch.qbs b/tests/auto/blackbox/testdata/dependency-profile-mismatch/dependency-profile-mismatch.qbs index ef2dee093..8a6f733c0 100644 --- a/tests/auto/blackbox/testdata/dependency-profile-mismatch/dependency-profile-mismatch.qbs +++ b/tests/auto/blackbox/testdata/dependency-profile-mismatch/dependency-profile-mismatch.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property string mainProfile property string depProfile diff --git a/tests/auto/blackbox/testdata/disappeared-profile/disappeared-profile.qbs b/tests/auto/blackbox/testdata/disappeared-profile/disappeared-profile.qbs index 659864b14..f1460aea5 100644 --- a/tests/auto/blackbox/testdata/disappeared-profile/disappeared-profile.qbs +++ b/tests/auto/blackbox/testdata/disappeared-profile/disappeared-profile.qbs @@ -1,5 +1,3 @@ -import qbs - Product { type: ["out1", "out2"] Depends { name: "m" } diff --git a/tests/auto/blackbox/testdata/disappeared-profile/modules-dir/modules/m/m.qbs b/tests/auto/blackbox/testdata/disappeared-profile/modules-dir/modules/m/m.qbs index a9c898889..3e1747ade 100644 --- a/tests/auto/blackbox/testdata/disappeared-profile/modules-dir/modules/m/m.qbs +++ b/tests/auto/blackbox/testdata/disappeared-profile/modules-dir/modules/m/m.qbs @@ -1,5 +1,3 @@ -import qbs - Module { property string p1 property string p2 diff --git a/tests/auto/blackbox/testdata/discard-unused-data/discard-unused-data.qbs b/tests/auto/blackbox/testdata/discard-unused-data/discard-unused-data.qbs index 6f433cf63..fdd3aa1f7 100644 --- a/tests/auto/blackbox/testdata/discard-unused-data/discard-unused-data.qbs +++ b/tests/auto/blackbox/testdata/discard-unused-data/discard-unused-data.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "app" type: base.concat("custom") @@ -14,10 +12,7 @@ CppApplication { Rule { multiplex: true - Artifact { - filePath: "dummy.txt" - fileTags: ["custom"] - } + outputFileTags: "custom" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; diff --git a/tests/auto/blackbox/testdata/driver-linker-flags/driver-linker-flags.qbs b/tests/auto/blackbox/testdata/driver-linker-flags/driver-linker-flags.qbs index 0802bc562..5de0fe053 100644 --- a/tests/auto/blackbox/testdata/driver-linker-flags/driver-linker-flags.qbs +++ b/tests/auto/blackbox/testdata/driver-linker-flags/driver-linker-flags.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: "main.cpp" diff --git a/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs index 48a90759a..1acf606dc 100644 --- a/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs +++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs @@ -1,5 +1,3 @@ -import qbs - DynamicLibrary { Depends { name: "cpp" } Depends { name: "bundle"; condition: qbs.targetOS.contains("darwin") } @@ -9,8 +7,9 @@ DynamicLibrary { cpp.minimumMacosVersion: "10.7" // For -rpath } - Group { - fileTagsFilter: ["dynamiclibrary", "dynamiclibrary_import"] - qbs.install: true - } + install: true + installImportLib: true + qbs.installPrefix: "" + installDir: "" + importLibInstallDir: "" } diff --git a/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thelib/thelib.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thelib/thelib.qbs index 41a6436d0..30f87337d 100644 --- a/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thelib/thelib.qbs +++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thelib/thelib.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Module { @@ -14,7 +13,7 @@ Module { } Group { name: "thelib dll import" - condition: qbs.targetOS.contains("windows") && !qbs.toolchain.contains("mingw") + condition: qbs.targetOS.contains("windows") files: FileInfo.joinPaths(product.thelib.baseDir, "thelib.lib") fileTags: ["dynamiclibrary_import"] filesAreTargets: true diff --git a/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/theotherlib/theotherlib.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/theotherlib/theotherlib.qbs index 2a9a7314f..1eb1e01a5 100644 --- a/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/theotherlib/theotherlib.qbs +++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/theotherlib/theotherlib.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Module { @@ -14,7 +13,7 @@ Module { } Group { name: "theotherlib dll import" - condition: qbs.targetOS.contains("windows") && !qbs.toolchain.contains("mingw") + condition: qbs.targetOS.contains("windows") files: FileInfo.joinPaths(product.theotherlib.baseDir, "theotherlib.lib") fileTags: ["dynamiclibrary_import"] filesAreTargets: true diff --git a/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thethirdlib/thethirdlib.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thethirdlib/thethirdlib.qbs index d422d3f2c..b4592f514 100644 --- a/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thethirdlib/thethirdlib.qbs +++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/modules/thethirdlib/thethirdlib.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Module { diff --git a/tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs index 725968dae..b9149d091 100644 --- a/tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs +++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "theapp" diff --git a/tests/auto/blackbox/testdata/dynamic-library-in-module/thelibs.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/thelibs.qbs index 361642cca..b06a3f171 100644 --- a/tests/auto/blackbox/testdata/dynamic-library-in-module/thelibs.qbs +++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/thelibs.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Dll { name: "thelib" diff --git a/tests/auto/blackbox/testdata/dynamic-project/dynamic-project.qbs b/tests/auto/blackbox/testdata/dynamic-project/dynamic-project.qbs index eb7c56738..166648c80 100644 --- a/tests/auto/blackbox/testdata/dynamic-project/dynamic-project.qbs +++ b/tests/auto/blackbox/testdata/dynamic-project/dynamic-project.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.FileInfo import qbs.TextFile diff --git a/tests/auto/blackbox/testdata/dynamicMultiplexRule/dynamicMultiplexRule.qbs b/tests/auto/blackbox/testdata/dynamicMultiplexRule/dynamicMultiplexRule.qbs index d5315ac45..b8adcaf4b 100644 --- a/tests/auto/blackbox/testdata/dynamicMultiplexRule/dynamicMultiplexRule.qbs +++ b/tests/auto/blackbox/testdata/dynamicMultiplexRule/dynamicMultiplexRule.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Project { diff --git a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs index 04820e18f..00c93a2ac 100644 --- a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs +++ b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs @@ -35,7 +35,6 @@ ** ****************************************************************************/ -import qbs 1.0 import qbs.FileInfo import qbs.Probes import qbs.TextFile @@ -54,7 +53,7 @@ Project { Probes.PathProbe { id: flexProbe names: ["flex"] - platformPaths: ["/usr/local/bin", "/usr/bin", "/bin"] + platformSearchPaths: ["/usr/local/bin", "/usr/bin", "/bin"] } property bool isFlexAvailable: flexProbe.found Rule { diff --git a/tests/auto/blackbox/testdata/enableExceptions/exceptions-objc.qbs b/tests/auto/blackbox/testdata/enableExceptions/exceptions-objc.qbs index 74738ad12..eef00da78 100644 --- a/tests/auto/blackbox/testdata/enableExceptions/exceptions-objc.qbs +++ b/tests/auto/blackbox/testdata/enableExceptions/exceptions-objc.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: ["main.m"] cpp.frameworks: ["Foundation"] diff --git a/tests/auto/blackbox/testdata/enableExceptions/exceptions-objcpp-cpp.qbs b/tests/auto/blackbox/testdata/enableExceptions/exceptions-objcpp-cpp.qbs index b6db6879b..7f703b9ad 100644 --- a/tests/auto/blackbox/testdata/enableExceptions/exceptions-objcpp-cpp.qbs +++ b/tests/auto/blackbox/testdata/enableExceptions/exceptions-objcpp-cpp.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Group { files: ["main.cpp"] diff --git a/tests/auto/blackbox/testdata/enableExceptions/exceptions-objcpp.qbs b/tests/auto/blackbox/testdata/enableExceptions/exceptions-objcpp.qbs index 8efb5d585..8946f9a38 100644 --- a/tests/auto/blackbox/testdata/enableExceptions/exceptions-objcpp.qbs +++ b/tests/auto/blackbox/testdata/enableExceptions/exceptions-objcpp.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Group { files: ["main.m"] diff --git a/tests/auto/blackbox/testdata/enableExceptions/exceptions.qbs b/tests/auto/blackbox/testdata/enableExceptions/exceptions.qbs index da6fdbc2d..9a75043a8 100644 --- a/tests/auto/blackbox/testdata/enableExceptions/exceptions.qbs +++ b/tests/auto/blackbox/testdata/enableExceptions/exceptions.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: ["main.cpp"] cpp.treatWarningsAsErrors: true diff --git a/tests/auto/blackbox/testdata/enableExceptions/none.qbs b/tests/auto/blackbox/testdata/enableExceptions/none.qbs index 332af7614..8fb052476 100644 --- a/tests/auto/blackbox/testdata/enableExceptions/none.qbs +++ b/tests/auto/blackbox/testdata/enableExceptions/none.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: ["emptymain.cpp"] diff --git a/tests/auto/blackbox/testdata/enableRtti/rtti.qbs b/tests/auto/blackbox/testdata/enableRtti/rtti.qbs index f032bb16b..85bfa9c1d 100644 --- a/tests/auto/blackbox/testdata/enableRtti/rtti.qbs +++ b/tests/auto/blackbox/testdata/enableRtti/rtti.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property bool treatAsObjcpp: false CppApplication { diff --git a/tests/auto/blackbox/testdata/env-merging/env-merging.qbs b/tests/auto/blackbox/testdata/env-merging/env-merging.qbs index 7f3f73550..6edeca444 100644 --- a/tests/auto/blackbox/testdata/env-merging/env-merging.qbs +++ b/tests/auto/blackbox/testdata/env-merging/env-merging.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "tool" @@ -12,10 +10,7 @@ Project { Depends { name: "tool" } Rule { inputsFromDependencies: "application" - Artifact { - filePath: "dummy" - fileTags: "custom" - } + outputFileTags: "custom" prepare: { var cmd = new Command(input.filePath, []); cmd.description = "running tool"; diff --git a/tests/auto/blackbox/testdata/env-normalization/env-normalization.qbs b/tests/auto/blackbox/testdata/env-normalization/env-normalization.qbs index a197208fb..3b242aeb0 100644 --- a/tests/auto/blackbox/testdata/env-normalization/env-normalization.qbs +++ b/tests/auto/blackbox/testdata/env-normalization/env-normalization.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Environment Product { diff --git a/tests/auto/blackbox/testdata/erroneous/nonexistentWorkingDir/nonexistentWorkingDir.qbs b/tests/auto/blackbox/testdata/erroneous/nonexistentWorkingDir/nonexistentWorkingDir.qbs index 8cf1bfaad..6a763e1ad 100644 --- a/tests/auto/blackbox/testdata/erroneous/nonexistentWorkingDir/nonexistentWorkingDir.qbs +++ b/tests/auto/blackbox/testdata/erroneous/nonexistentWorkingDir/nonexistentWorkingDir.qbs @@ -1,5 +1,3 @@ -import qbs - Application { name: "kaputt" type: ["nutritious"] diff --git a/tests/auto/blackbox/testdata/erroneous/outputArtifacts-missing-filePath/outputArtifacts-missing-filePath.qbs b/tests/auto/blackbox/testdata/erroneous/outputArtifacts-missing-filePath/outputArtifacts-missing-filePath.qbs index 7a6c3a25d..047ddb862 100644 --- a/tests/auto/blackbox/testdata/erroneous/outputArtifacts-missing-filePath/outputArtifacts-missing-filePath.qbs +++ b/tests/auto/blackbox/testdata/erroneous/outputArtifacts-missing-filePath/outputArtifacts-missing-filePath.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - CppApplication { type: base.concat("txt") files : ["main.cpp"] diff --git a/tests/auto/blackbox/testdata/erroneous/outputArtifacts-missing-fileTags/outputArtifacts-missing-fileTags.qbs b/tests/auto/blackbox/testdata/erroneous/outputArtifacts-missing-fileTags/outputArtifacts-missing-fileTags.qbs index 9b71cf73a..8b7b9482e 100644 --- a/tests/auto/blackbox/testdata/erroneous/outputArtifacts-missing-fileTags/outputArtifacts-missing-fileTags.qbs +++ b/tests/auto/blackbox/testdata/erroneous/outputArtifacts-missing-fileTags/outputArtifacts-missing-fileTags.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - CppApplication { type: base.concat("txt") files : ["main.cpp"] diff --git a/tests/auto/blackbox/testdata/erroneous/tag-mismatch/tag-mismatch.qbs b/tests/auto/blackbox/testdata/erroneous/tag-mismatch/tag-mismatch.qbs new file mode 100644 index 000000000..51ea28e99 --- /dev/null +++ b/tests/auto/blackbox/testdata/erroneous/tag-mismatch/tag-mismatch.qbs @@ -0,0 +1,35 @@ +Product { + name: "p" + type: "p_type" + Rule { + multiplex: true + outputFileTags: ["x"] + outputArtifacts: [{filePath: "dummy1", fileTags: ["x","y","z"]}] + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { }; + return cmd; + } + } + Rule { + inputs: ["y"] + Artifact { filePath: "dummy2"; fileTags: "p_type" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { }; + return cmd; + } + } + Rule { + inputs: ["x"] + Artifact { filePath: "dummy3"; fileTags: "p_type" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { }; + return cmd; + } + } +} diff --git a/tests/auto/blackbox/testdata/erroneous/texttemplate-unknown-placeholder/boom.txt.in b/tests/auto/blackbox/testdata/erroneous/texttemplate-unknown-placeholder/boom.txt.in new file mode 100644 index 000000000..359e856ec --- /dev/null +++ b/tests/auto/blackbox/testdata/erroneous/texttemplate-unknown-placeholder/boom.txt.in @@ -0,0 +1 @@ +Boom! shake-shake-shake the ${what}! diff --git a/tests/auto/blackbox/testdata/erroneous/texttemplate-unknown-placeholder/texttemplate-unknown-placeholder.qbs b/tests/auto/blackbox/testdata/erroneous/texttemplate-unknown-placeholder/texttemplate-unknown-placeholder.qbs new file mode 100644 index 000000000..01963292a --- /dev/null +++ b/tests/auto/blackbox/testdata/erroneous/texttemplate-unknown-placeholder/texttemplate-unknown-placeholder.qbs @@ -0,0 +1,6 @@ +Product { + type: ["text"] + Depends { name: "texttemplate" } + texttemplate.dict: ({ wat: "room" }) // typo in key name + files: [ "boom.txt.in" ] +} diff --git a/tests/auto/blackbox/testdata/error-info/error-info.qbs b/tests/auto/blackbox/testdata/error-info/error-info.qbs index afd44c246..b8f42b4b2 100644 --- a/tests/auto/blackbox/testdata/error-info/error-info.qbs +++ b/tests/auto/blackbox/testdata/error-info/error-info.qbs @@ -1,4 +1,3 @@ -import qbs import "helper.js" as Helper Project { diff --git a/tests/auto/blackbox/testdata/escaped-linker-flags/escaped-linker-flags.qbs b/tests/auto/blackbox/testdata/escaped-linker-flags/escaped-linker-flags.qbs index e136acb30..f48bf8d1f 100644 --- a/tests/auto/blackbox/testdata/escaped-linker-flags/escaped-linker-flags.qbs +++ b/tests/auto/blackbox/testdata/escaped-linker-flags/escaped-linker-flags.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "app" property bool escapeLinkerFlags diff --git a/tests/auto/blackbox/testdata/explicitly-depends-on/explicitly-depends-on.qbs b/tests/auto/blackbox/testdata/explicitly-depends-on/explicitly-depends-on.qbs index 10cfa089b..4f190c23d 100644 --- a/tests/auto/blackbox/testdata/explicitly-depends-on/explicitly-depends-on.qbs +++ b/tests/auto/blackbox/testdata/explicitly-depends-on/explicitly-depends-on.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.TextFile diff --git a/tests/auto/blackbox/testdata/explicitly-depends-on/modules/module1/module1.qbs b/tests/auto/blackbox/testdata/explicitly-depends-on/modules/module1/module1.qbs index f1752b4ed..b710c4e21 100644 --- a/tests/auto/blackbox/testdata/explicitly-depends-on/modules/module1/module1.qbs +++ b/tests/auto/blackbox/testdata/explicitly-depends-on/modules/module1/module1.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Group { filesAreTargets: true diff --git a/tests/auto/blackbox/testdata/export-rule/export-rule.qbs b/tests/auto/blackbox/testdata/export-rule/export-rule.qbs index 0b1f9f99b..29899e728 100644 --- a/tests/auto/blackbox/testdata/export-rule/export-rule.qbs +++ b/tests/auto/blackbox/testdata/export-rule/export-rule.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Project { diff --git a/tests/auto/blackbox/testdata/export-to-outside-searchpath/export-to-outside-searchpath.qbs b/tests/auto/blackbox/testdata/export-to-outside-searchpath/export-to-outside-searchpath.qbs index 72c48b75a..42e17486f 100644 --- a/tests/auto/blackbox/testdata/export-to-outside-searchpath/export-to-outside-searchpath.qbs +++ b/tests/auto/blackbox/testdata/export-to-outside-searchpath/export-to-outside-searchpath.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Project { qbsSearchPaths: ["qbs-resources"] diff --git a/tests/auto/blackbox/testdata/export-to-outside-searchpath/qbs-resources/modules/aModule/aModule.qbs b/tests/auto/blackbox/testdata/export-to-outside-searchpath/qbs-resources/modules/aModule/aModule.qbs index 3e67ba10d..84957060c 100644 --- a/tests/auto/blackbox/testdata/export-to-outside-searchpath/qbs-resources/modules/aModule/aModule.qbs +++ b/tests/auto/blackbox/testdata/export-to-outside-searchpath/qbs-resources/modules/aModule/aModule.qbs @@ -1,4 +1,2 @@ -import qbs - Module { } diff --git a/tests/auto/blackbox/testdata/exported-dependency-in-disabled-product/exported-dependency-in-disabled-product.qbs b/tests/auto/blackbox/testdata/exported-dependency-in-disabled-product/exported-dependency-in-disabled-product.qbs index 9904502a6..ac6022b9d 100644 --- a/tests/auto/blackbox/testdata/exported-dependency-in-disabled-product/exported-dependency-in-disabled-product.qbs +++ b/tests/auto/blackbox/testdata/exported-dependency-in-disabled-product/exported-dependency-in-disabled-product.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Application { name: "app" diff --git a/tests/auto/blackbox/testdata/exported-dependency-in-disabled-product/modules/broken/broken.qbs b/tests/auto/blackbox/testdata/exported-dependency-in-disabled-product/modules/broken/broken.qbs index 92f01d5d3..328e5f558 100644 --- a/tests/auto/blackbox/testdata/exported-dependency-in-disabled-product/modules/broken/broken.qbs +++ b/tests/auto/blackbox/testdata/exported-dependency-in-disabled-product/modules/broken/broken.qbs @@ -1,5 +1,3 @@ -import qbs - Module { validate: { throw "broken!"; } } diff --git a/tests/auto/blackbox/testdata/exported-property-in-disabled-product/exported-property-in-disabled-product.qbs b/tests/auto/blackbox/testdata/exported-property-in-disabled-product/exported-property-in-disabled-product.qbs index 2717466b0..ff8beb347 100644 --- a/tests/auto/blackbox/testdata/exported-property-in-disabled-product/exported-property-in-disabled-product.qbs +++ b/tests/auto/blackbox/testdata/exported-property-in-disabled-product/exported-property-in-disabled-product.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "app" diff --git a/tests/auto/blackbox/testdata/exported-property-in-disabled-product/modules/broken/broken.qbs b/tests/auto/blackbox/testdata/exported-property-in-disabled-product/modules/broken/broken.qbs index 92f01d5d3..328e5f558 100644 --- a/tests/auto/blackbox/testdata/exported-property-in-disabled-product/modules/broken/broken.qbs +++ b/tests/auto/blackbox/testdata/exported-property-in-disabled-product/modules/broken/broken.qbs @@ -1,5 +1,3 @@ -import qbs - Module { validate: { throw "broken!"; } } diff --git a/tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs b/tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs index 7934dc3c9..96d1cabb9 100644 --- a/tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs +++ b/tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Project { @@ -85,14 +84,21 @@ Project { Depends { name: "cpp" } cpp.defines: ["SECONDLIB"] + qbs.installPrefix: "" + Depends { name: "TheFirstLib" } Export { Depends { name: "TheFirstLib" } Depends { name: "dummy" } Depends { name: "cpp" } - cpp.includePaths: ["/opt/thesecondlib/include", product.sourceDirectory] + cpp.includePaths: [ + "/opt/thesecondlib/include", + product.sourceDirectory, + importingProduct.buildDirectory + ] property string hurz: importingProduct.name + cpp.defines: hurz.toUpperCase() Rule { property int n: 5 diff --git a/tests/auto/blackbox/testdata/exports-pkgconfig/modules/helper1/helper1.qbs b/tests/auto/blackbox/testdata/exports-pkgconfig/modules/helper1/helper1.qbs index b753ec295..c898e91d1 100644 --- a/tests/auto/blackbox/testdata/exports-pkgconfig/modules/helper1/helper1.qbs +++ b/tests/auto/blackbox/testdata/exports-pkgconfig/modules/helper1/helper1.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } Depends { name: "helper2" } diff --git a/tests/auto/blackbox/testdata/exports-pkgconfig/modules/helper2/helper2.qbs b/tests/auto/blackbox/testdata/exports-pkgconfig/modules/helper2/helper2.qbs index 9d24a812d..2dbdfdb01 100644 --- a/tests/auto/blackbox/testdata/exports-pkgconfig/modules/helper2/helper2.qbs +++ b/tests/auto/blackbox/testdata/exports-pkgconfig/modules/helper2/helper2.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } cpp.includePaths: "/somedir/include2" diff --git a/tests/auto/blackbox/testdata/exports-pkgconfig/modules/helper3/helper3.qbs b/tests/auto/blackbox/testdata/exports-pkgconfig/modules/helper3/helper3.qbs index 452191994..57e65f2f9 100644 --- a/tests/auto/blackbox/testdata/exports-pkgconfig/modules/helper3/helper3.qbs +++ b/tests/auto/blackbox/testdata/exports-pkgconfig/modules/helper3/helper3.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } cpp.includePaths: "/somedir/include3" diff --git a/tests/auto/blackbox/testdata/exports-qbs/consumer.qbs b/tests/auto/blackbox/testdata/exports-qbs/consumer.qbs index 252cb8291..02affdfe8 100644 --- a/tests/auto/blackbox/testdata/exports-qbs/consumer.qbs +++ b/tests/auto/blackbox/testdata/exports-qbs/consumer.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "consumer" qbsSearchPaths: "default/install-root/usr/qbs" diff --git a/tests/auto/blackbox/testdata/exports-qbs/exports-qbs.qbs b/tests/auto/blackbox/testdata/exports-qbs/exports-qbs.qbs index 2bad55aaa..27e417ef9 100644 --- a/tests/auto/blackbox/testdata/exports-qbs/exports-qbs.qbs +++ b/tests/auto/blackbox/testdata/exports-qbs/exports-qbs.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Project { diff --git a/tests/auto/blackbox/testdata/exports-qbs/lib.qbs b/tests/auto/blackbox/testdata/exports-qbs/lib.qbs index 6ae0885d5..53a472dbb 100644 --- a/tests/auto/blackbox/testdata/exports-qbs/lib.qbs +++ b/tests/auto/blackbox/testdata/exports-qbs/lib.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo DynamicLibrary { @@ -28,11 +27,9 @@ DynamicLibrary { qbs.install: true qbs.installDir: headersInstallDir } - Group { - fileTagsFilter: ["dynamiclibrary", "dynamiclibrary_import"] - qbs.install: true - qbs.installDir: "lib" - } + install: true + installImportLib: true + installDir: "lib" Group { fileTagsFilter: ["Exporter.qbs.module"] qbs.install: true diff --git a/tests/auto/blackbox/testdata/exports-qbs/tool.qbs b/tests/auto/blackbox/testdata/exports-qbs/tool.qbs index b0078a75c..655597cf7 100644 --- a/tests/auto/blackbox/testdata/exports-qbs/tool.qbs +++ b/tests/auto/blackbox/testdata/exports-qbs/tool.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo import "helper.js" as Helper @@ -11,6 +10,7 @@ CppApplication { Depends { name: "Exporter.qbs" } Exporter.qbs.artifactTypes: ["installable", "blubb"] files: ["tool.cpp"] + install: true qbs.installPrefix: project.installPrefix Group { files: ["helper.js"] @@ -25,8 +25,6 @@ CppApplication { Group { fileTagsFilter: ["application"] - qbs.install: true - qbs.installDir: "bin" fileTags: toolTags } Group { diff --git a/tests/auto/blackbox/testdata/external-libs/external-libs.qbs b/tests/auto/blackbox/testdata/external-libs/external-libs.qbs index d2e983c3e..619f40867 100644 --- a/tests/auto/blackbox/testdata/external-libs/external-libs.qbs +++ b/tests/auto/blackbox/testdata/external-libs/external-libs.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Project { diff --git a/tests/auto/blackbox/testdata/fileDependencies/fileDependencies.qbs b/tests/auto/blackbox/testdata/fileDependencies/fileDependencies.qbs index e99e0932c..49f413807 100644 --- a/tests/auto/blackbox/testdata/fileDependencies/fileDependencies.qbs +++ b/tests/auto/blackbox/testdata/fileDependencies/fileDependencies.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { type: "application" diff --git a/tests/auto/blackbox/testdata/filetagsfilter-merging/MyApplication.qbs b/tests/auto/blackbox/testdata/filetagsfilter-merging/MyApplication.qbs new file mode 100644 index 000000000..890fc51ce --- /dev/null +++ b/tests/auto/blackbox/testdata/filetagsfilter-merging/MyApplication.qbs @@ -0,0 +1,9 @@ +CppApplication { + consoleApplication: true + Group { + fileTagsFilter: "application" + qbs.install:true + qbs.installPrefix: product.name + qbs.installDir: "wrong" + } +} diff --git a/tests/auto/blackbox/testdata/filetagsfilter-merging/filetagsfilter-merging.qbs b/tests/auto/blackbox/testdata/filetagsfilter-merging/filetagsfilter-merging.qbs new file mode 100644 index 000000000..eee20782e --- /dev/null +++ b/tests/auto/blackbox/testdata/filetagsfilter-merging/filetagsfilter-merging.qbs @@ -0,0 +1,28 @@ +import qbs.TextFile + +MyApplication { + name: "myapp" + type: base.concat("extra-output") + files: "main.cpp" + Group { + fileTagsFilter: "application" + qbs.installDir: "binDir" + fileTags: "extra-input" + } + Rule { + inputs: "extra-input" + Artifact { + filePath: input.baseName + ".txt" + fileTags: "extra-output" + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "creating " + output.fileName; + cmd.sourceCode = function() { + var f = new TextFile(output.filePath, TextFile.WriteOnly); + f.close(); + } + return cmd; + } + } +} diff --git a/tests/auto/blackbox/testdata/filetagsfilter-merging/main.cpp b/tests/auto/blackbox/testdata/filetagsfilter-merging/main.cpp new file mode 100644 index 000000000..237c8ce18 --- /dev/null +++ b/tests/auto/blackbox/testdata/filetagsfilter-merging/main.cpp @@ -0,0 +1 @@ +int main() {} diff --git a/tests/auto/blackbox/testdata/find/find-cli.qbs b/tests/auto/blackbox/testdata/find/find-cli.qbs index 63609b3b2..20d94803e 100644 --- a/tests/auto/blackbox/testdata/find/find-cli.qbs +++ b/tests/auto/blackbox/testdata/find/find-cli.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Product { diff --git a/tests/auto/blackbox/testdata/generated-artifact-as-input-to-dynamic-rule/p.qbs b/tests/auto/blackbox/testdata/generated-artifact-as-input-to-dynamic-rule/p.qbs index f26d92262..7ed5f5d96 100644 --- a/tests/auto/blackbox/testdata/generated-artifact-as-input-to-dynamic-rule/p.qbs +++ b/tests/auto/blackbox/testdata/generated-artifact-as-input-to-dynamic-rule/p.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.TextFile @@ -46,8 +45,8 @@ Product { var cmd = new JavaScriptCommand(); var output = outputs["mytype.final"][0]; cmd.description = "generating " + output.fileName; - cmd.output = output; - cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); }; + cmd.outputFilePath = output.filePath; + cmd.sourceCode = function() { File.copy(input.filePath, outputFilePath); }; return [cmd]; } } diff --git a/tests/auto/blackbox/testdata/generator/generator.qbs b/tests/auto/blackbox/testdata/generator/generator.qbs index 18f2caaea..d0857beb5 100644 --- a/tests/auto/blackbox/testdata/generator/generator.qbs +++ b/tests/auto/blackbox/testdata/generator/generator.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile CppApplication { diff --git a/tests/auto/blackbox/testdata/group-condition-change/group-condition-change.qbs b/tests/auto/blackbox/testdata/group-condition-change/group-condition-change.qbs index d8dccde39..ae1811375 100644 --- a/tests/auto/blackbox/testdata/group-condition-change/group-condition-change.qbs +++ b/tests/auto/blackbox/testdata/group-condition-change/group-condition-change.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property bool kaputt: true Product { diff --git a/tests/auto/blackbox/testdata/groups-in-modules/groups-in-modules.qbs b/tests/auto/blackbox/testdata/groups-in-modules/groups-in-modules.qbs index 5fa09c4d0..7347b1211 100644 --- a/tests/auto/blackbox/testdata/groups-in-modules/groups-in-modules.qbs +++ b/tests/auto/blackbox/testdata/groups-in-modules/groups-in-modules.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { Depends { name: "dep" } diff --git a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper/helper.qbs b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper/helper.qbs index 3154986a6..cbd30a35d 100644 --- a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper/helper.qbs +++ b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper/helper.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Module { diff --git a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper2/helper2.qbs b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper2/helper2.qbs index fbf15f6da..18d11c8f5 100644 --- a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper2/helper2.qbs +++ b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper2/helper2.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } diff --git a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper3/helper3.qbs b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper3/helper3.qbs index 00c619a38..de3e6171c 100644 --- a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper3/helper3.qbs +++ b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper3/helper3.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } diff --git a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper4/helper4.qbs b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper4/helper4.qbs index e2d668209..18dce4dc5 100644 --- a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper4/helper4.qbs +++ b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper4/helper4.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } Depends { name: "helper5" } diff --git a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper5/helper5.qbs b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper5/helper5.qbs index 3e4e8923e..58c8144d6 100644 --- a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper5/helper5.qbs +++ b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper5/helper5.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } Depends { diff --git a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper6/helper6.qbs b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper6/helper6.qbs index 736572570..8f73567e6 100644 --- a/tests/auto/blackbox/testdata/groups-in-modules/modules/helper6/helper6.qbs +++ b/tests/auto/blackbox/testdata/groups-in-modules/modules/helper6/helper6.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } diff --git a/tests/auto/blackbox/testdata/ico/ico.qbs b/tests/auto/blackbox/testdata/ico/ico.qbs index 920189b85..e9d635820 100644 --- a/tests/auto/blackbox/testdata/ico/ico.qbs +++ b/tests/auto/blackbox/testdata/ico/ico.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { Depends { name: "ico" } diff --git a/tests/auto/blackbox/testdata/import-assignment/import-assignment.qbs b/tests/auto/blackbox/testdata/import-assignment/import-assignment.qbs index 2bff00f35..f5efbd14b 100644 --- a/tests/auto/blackbox/testdata/import-assignment/import-assignment.qbs +++ b/tests/auto/blackbox/testdata/import-assignment/import-assignment.qbs @@ -1,4 +1,3 @@ -import qbs import MyImport Product { diff --git a/tests/auto/blackbox/testdata/import-change-tracking/import-change-tracking-product.qbs b/tests/auto/blackbox/testdata/import-change-tracking/import-change-tracking-product.qbs index c229de889..c86a1bbb7 100644 --- a/tests/auto/blackbox/testdata/import-change-tracking/import-change-tracking-product.qbs +++ b/tests/auto/blackbox/testdata/import-change-tracking/import-change-tracking-product.qbs @@ -1,4 +1,3 @@ -import qbs import "irrelevant.js" as Irrelevant import "custom1prepare1.js" as Custom1Prepare import "custom2prepare" as Custom2Prepare diff --git a/tests/auto/blackbox/testdata/import-change-tracking/import-change-tracking.qbs b/tests/auto/blackbox/testdata/import-change-tracking/import-change-tracking.qbs index 009c0897f..c97e0c7f8 100644 --- a/tests/auto/blackbox/testdata/import-change-tracking/import-change-tracking.qbs +++ b/tests/auto/blackbox/testdata/import-change-tracking/import-change-tracking.qbs @@ -1,5 +1,3 @@ -import qbs - Project { qbsSearchPaths: ["."] references: "import-change-tracking-product.qbs" diff --git a/tests/auto/blackbox/testdata/import-in-properties-condition/import-in-properties-condition.qbs b/tests/auto/blackbox/testdata/import-in-properties-condition/import-in-properties-condition.qbs index 32b8d2a03..d4ed153af 100644 --- a/tests/auto/blackbox/testdata/import-in-properties-condition/import-in-properties-condition.qbs +++ b/tests/auto/blackbox/testdata/import-in-properties-condition/import-in-properties-condition.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "amodule" } } diff --git a/tests/auto/blackbox/testdata/import-in-properties-condition/modules/amodule/m.qbs b/tests/auto/blackbox/testdata/import-in-properties-condition/modules/amodule/m.qbs index 92ea2cd45..3402b16de 100644 --- a/tests/auto/blackbox/testdata/import-in-properties-condition/modules/amodule/m.qbs +++ b/tests/auto/blackbox/testdata/import-in-properties-condition/modules/amodule/m.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Module { diff --git a/tests/auto/blackbox/testdata/import-in-properties-condition/modules/depmodule/m.qbs b/tests/auto/blackbox/testdata/import-in-properties-condition/modules/depmodule/m.qbs index 4c2f9281d..3a4266b78 100644 --- a/tests/auto/blackbox/testdata/import-in-properties-condition/modules/depmodule/m.qbs +++ b/tests/auto/blackbox/testdata/import-in-properties-condition/modules/depmodule/m.qbs @@ -1,5 +1,3 @@ -import qbs - Module { property string prop } diff --git a/tests/auto/blackbox/testdata/import-searchpath/import-searchpath.qbs b/tests/auto/blackbox/testdata/import-searchpath/import-searchpath.qbs index b4d0194a2..3dbb1f641 100644 --- a/tests/auto/blackbox/testdata/import-searchpath/import-searchpath.qbs +++ b/tests/auto/blackbox/testdata/import-searchpath/import-searchpath.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Project { qbsSearchPaths: ["qbs"] diff --git a/tests/auto/blackbox/testdata/import-searchpath/qbs/imports/CppApplication.qbs b/tests/auto/blackbox/testdata/import-searchpath/qbs/imports/CppApplication.qbs index 18dc695f3..bdef20fd8 100644 --- a/tests/auto/blackbox/testdata/import-searchpath/qbs/imports/CppApplication.qbs +++ b/tests/auto/blackbox/testdata/import-searchpath/qbs/imports/CppApplication.qbs @@ -1,4 +1,2 @@ -import qbs - Product { } diff --git a/tests/auto/blackbox/testdata/import-searchpath/src/import-searchpath-app1.qbs b/tests/auto/blackbox/testdata/import-searchpath/src/import-searchpath-app1.qbs index c12158d24..a973a2722 100644 --- a/tests/auto/blackbox/testdata/import-searchpath/src/import-searchpath-app1.qbs +++ b/tests/auto/blackbox/testdata/import-searchpath/src/import-searchpath-app1.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: ["somefile.cpp"] } diff --git a/tests/auto/blackbox/testdata/import-searchpath/src/import-searchpath-app2.qbs b/tests/auto/blackbox/testdata/import-searchpath/src/import-searchpath-app2.qbs index f6ae698a0..da7536315 100644 --- a/tests/auto/blackbox/testdata/import-searchpath/src/import-searchpath-app2.qbs +++ b/tests/auto/blackbox/testdata/import-searchpath/src/import-searchpath-app2.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: ["main.cpp"] } diff --git a/tests/auto/blackbox/testdata/importing-product/importing-product.qbs b/tests/auto/blackbox/testdata/importing-product/importing-product.qbs index e81f76077..dfc4cd65e 100644 --- a/tests/auto/blackbox/testdata/importing-product/importing-product.qbs +++ b/tests/auto/blackbox/testdata/importing-product/importing-product.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Project { diff --git a/tests/auto/blackbox/testdata/imports-conflict/imports-conflict.qbs b/tests/auto/blackbox/testdata/imports-conflict/imports-conflict.qbs index 1c6be24bd..4966b2f09 100644 --- a/tests/auto/blackbox/testdata/imports-conflict/imports-conflict.qbs +++ b/tests/auto/blackbox/testdata/imports-conflict/imports-conflict.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "Utils" diff --git a/tests/auto/blackbox/testdata/includeLookup/includeLookup.qbs b/tests/auto/blackbox/testdata/includeLookup/includeLookup.qbs index 452e4b5bd..182d1e232 100644 --- a/tests/auto/blackbox/testdata/includeLookup/includeLookup.qbs +++ b/tests/auto/blackbox/testdata/includeLookup/includeLookup.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.FileInfo Project { diff --git a/tests/auto/blackbox/testdata/includeLookup/modules/definition/module.qbs b/tests/auto/blackbox/testdata/includeLookup/modules/definition/module.qbs index e894cfd49..8762a780a 100644 --- a/tests/auto/blackbox/testdata/includeLookup/modules/definition/module.qbs +++ b/tests/auto/blackbox/testdata/includeLookup/modules/definition/module.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.Probes Module { @@ -8,7 +7,7 @@ Module { Probes.IncludeProbe { id: includeNode names: "fakeopenssl/sha.h" - platformPaths: [modulePath] + platformSearchPaths: [modulePath] } cpp.defines: includeNode.found ? 'TEXT="' + includeNode.path + '"' : undefined } diff --git a/tests/auto/blackbox/testdata/innosetup/innosetup.qbs b/tests/auto/blackbox/testdata/innosetup/innosetup.qbs index 679f1de8f..c9f6a22e8 100644 --- a/tests/auto/blackbox/testdata/innosetup/innosetup.qbs +++ b/tests/auto/blackbox/testdata/innosetup/innosetup.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Project { diff --git a/tests/auto/blackbox/testdata/innosetupDependencies/innosetupDependencies.qbs b/tests/auto/blackbox/testdata/innosetupDependencies/innosetupDependencies.qbs index 17536ff8b..db65e127f 100644 --- a/tests/auto/blackbox/testdata/innosetupDependencies/innosetupDependencies.qbs +++ b/tests/auto/blackbox/testdata/innosetupDependencies/innosetupDependencies.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Project { @@ -42,7 +41,7 @@ Project { // This rule tries to provoke the installer into building too early (and the test // verifies that it does not) by causing the build of the installables to take // a lot longer. - inputs: ["qbs"] + multiplex: true outputFileTags: ["c"] outputArtifacts: { var artifacts = []; diff --git a/tests/auto/blackbox/testdata/input-tags-change-tracking/input-tags-change-tracking.qbs b/tests/auto/blackbox/testdata/input-tags-change-tracking/input-tags-change-tracking.qbs new file mode 100644 index 000000000..ef2c5c55b --- /dev/null +++ b/tests/auto/blackbox/testdata/input-tags-change-tracking/input-tags-change-tracking.qbs @@ -0,0 +1,63 @@ +import qbs.TextFile + +Product { + name: "p" + type: "p_tag" + property string generateInput + Group { + condition: generateInput == "no" + files: "input.txt" + fileTags: ["txt", "empty"] + } + Rule { + condition: generateInput == "static" + multiplex: true + Artifact { filePath: "input.txt"; fileTags: ["txt", "empty"] } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { + var out = new TextFile(output.filePath, TextFile.WriteOnly); + out.close(); + }; + return cmd; + } + } + Rule { + condition: generateInput == "dynamic" + multiplex: true + outputFileTags: ["txt", "empty"] + outputArtifacts: [{filePath: "input.txt", fileTags: ["txt", "empty"]}] + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { + var out = new TextFile(output.filePath, TextFile.WriteOnly); + out.close(); + }; + return cmd; + } + } + + Rule { + inputs: "txt" + outputFileTags: "p_tag" + outputArtifacts: { + if (input.fileTags.contains("empty")) + return []; + return [{ + filePath: input.fileTags.contains("y") ? "y.out" : "x.out", + fileTags: "p_tag" + }] + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { + var out = new TextFile(output.filePath, TextFile.WriteOnly); + out.close(); + }; + return cmd; + } + } +} diff --git a/tests/auto/blackbox/testdata/input-tags-change-tracking/input.txt b/tests/auto/blackbox/testdata/input-tags-change-tracking/input.txt new file mode 100644 index 000000000..c6cac6926 --- /dev/null +++ b/tests/auto/blackbox/testdata/input-tags-change-tracking/input.txt @@ -0,0 +1 @@ +empty diff --git a/tests/auto/blackbox/testdata/inputs-from-dependencies/inputs-from-dependencies.qbs b/tests/auto/blackbox/testdata/inputs-from-dependencies/inputs-from-dependencies.qbs index 1b40abaeb..919060c73 100644 --- a/tests/auto/blackbox/testdata/inputs-from-dependencies/inputs-from-dependencies.qbs +++ b/tests/auto/blackbox/testdata/inputs-from-dependencies/inputs-from-dependencies.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "TextFileContainer1" diff --git a/tests/auto/blackbox/testdata/install-duplicates-no-error/install-duplicates-no-error.qbs b/tests/auto/blackbox/testdata/install-duplicates-no-error/install-duplicates-no-error.qbs index 3f2c4e974..a3282f941 100644 --- a/tests/auto/blackbox/testdata/install-duplicates-no-error/install-duplicates-no-error.qbs +++ b/tests/auto/blackbox/testdata/install-duplicates-no-error/install-duplicates-no-error.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "p1" diff --git a/tests/auto/blackbox/testdata/install-duplicates/install-duplicates.qbs b/tests/auto/blackbox/testdata/install-duplicates/install-duplicates.qbs index 2f91ba560..5edc83d81 100644 --- a/tests/auto/blackbox/testdata/install-duplicates/install-duplicates.qbs +++ b/tests/auto/blackbox/testdata/install-duplicates/install-duplicates.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Group { files: ["*.txt"] diff --git a/tests/auto/blackbox/testdata/install-locations/install-locations.qbs b/tests/auto/blackbox/testdata/install-locations/install-locations.qbs new file mode 100644 index 000000000..8a97f74a1 --- /dev/null +++ b/tests/auto/blackbox/testdata/install-locations/install-locations.qbs @@ -0,0 +1,26 @@ +Project { + property bool dummy: { + if (qbs.targetOS.contains("windows")) + console.info("is windows"); + else if (qbs.targetOS.contains("macos")) + console.info("is mac"); + else + console.info("is unix"); + } + CppApplication { + name: "theapp" + install: true + files: "main.cpp" + Group { + fileTagsFilter: "application" + fileTags: "some-tag" + } + } + DynamicLibrary { + name: "thelib" + install: true + installImportLib: true + Depends { name: "cpp" } + files: "thelib.cpp" + } +} diff --git a/tests/auto/blackbox/testdata/install-locations/main.cpp b/tests/auto/blackbox/testdata/install-locations/main.cpp new file mode 100644 index 000000000..237c8ce18 --- /dev/null +++ b/tests/auto/blackbox/testdata/install-locations/main.cpp @@ -0,0 +1 @@ +int main() {} diff --git a/tests/auto/blackbox/testdata/install-locations/thelib.cpp b/tests/auto/blackbox/testdata/install-locations/thelib.cpp new file mode 100644 index 000000000..d3877db26 --- /dev/null +++ b/tests/auto/blackbox/testdata/install-locations/thelib.cpp @@ -0,0 +1,3 @@ +#include "../dllexport.h" + +DLL_EXPORT void libFunc() {} diff --git a/tests/auto/blackbox/testdata/install-root-from-project-file/install-root-from-project-file.qbs b/tests/auto/blackbox/testdata/install-root-from-project-file/install-root-from-project-file.qbs index ea7284a05..80a63c956 100644 --- a/tests/auto/blackbox/testdata/install-root-from-project-file/install-root-from-project-file.qbs +++ b/tests/auto/blackbox/testdata/install-root-from-project-file/install-root-from-project-file.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "p" property string installRoot diff --git a/tests/auto/blackbox/testdata/install-tree/install-tree.qbs b/tests/auto/blackbox/testdata/install-tree/install-tree.qbs index cbd7300d6..dde39d231 100644 --- a/tests/auto/blackbox/testdata/install-tree/install-tree.qbs +++ b/tests/auto/blackbox/testdata/install-tree/install-tree.qbs @@ -1,7 +1,6 @@ -import qbs - CppApplication { files: ["main.cpp"] + qbs.installPrefix: "" Group { files: ["data/**/*.txt"] qbs.install: true diff --git a/tests/auto/blackbox/testdata/installable-as-auxiliary-input/installable-as-auxiliary-input.qbs b/tests/auto/blackbox/testdata/installable-as-auxiliary-input/installable-as-auxiliary-input.qbs index 822473157..2d37e85d6 100644 --- a/tests/auto/blackbox/testdata/installable-as-auxiliary-input/installable-as-auxiliary-input.qbs +++ b/tests/auto/blackbox/testdata/installable-as-auxiliary-input/installable-as-auxiliary-input.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.FileInfo import qbs.TextFile @@ -34,6 +33,7 @@ Project { property string installDir: "include" + qbs.installPrefix: "" Group { fileTagsFilter: "header" qbs.install: true diff --git a/tests/auto/blackbox/testdata/installable/installable.qbs b/tests/auto/blackbox/testdata/installable/installable.qbs index 7ce41867b..56feb6ec5 100644 --- a/tests/auto/blackbox/testdata/installable/installable.qbs +++ b/tests/auto/blackbox/testdata/installable/installable.qbs @@ -1,19 +1,17 @@ -import qbs import qbs.TextFile Project { CppApplication { type: ["application"] name: "app" + consoleApplication: true Group { files: ["main.cpp"] qbs.install: true } - Group { - fileTagsFilter: ["application"] - qbs.install: true - } + install: true + installDir: "" } Product { diff --git a/tests/auto/blackbox/testdata/installed-source-files/installed-source-files.qbs b/tests/auto/blackbox/testdata/installed-source-files/installed-source-files.qbs index 1aa564553..7b4d30091 100644 --- a/tests/auto/blackbox/testdata/installed-source-files/installed-source-files.qbs +++ b/tests/auto/blackbox/testdata/installed-source-files/installed-source-files.qbs @@ -1,8 +1,7 @@ -import qbs - CppApplication { consoleApplication: true files: ["main.cpp"] + qbs.installPrefix: "" Group { fileTagsFilter: ["cpp"] qbs.install: true diff --git a/tests/auto/blackbox/testdata/installed-transformer-output/qbs668.qbs b/tests/auto/blackbox/testdata/installed-transformer-output/qbs668.qbs index 99acc5585..aa40b7691 100644 --- a/tests/auto/blackbox/testdata/installed-transformer-output/qbs668.qbs +++ b/tests/auto/blackbox/testdata/installed-transformer-output/qbs668.qbs @@ -1,9 +1,9 @@ -import qbs 1.0 import qbs.TextFile Product { name: "install-test" type: ["text"] + qbs.installPrefix: "" Group { qbs.install: true qbs.installDir: "textfiles" diff --git a/tests/auto/blackbox/testdata/installed_artifact/installed_artifact.qbs b/tests/auto/blackbox/testdata/installed_artifact/installed_artifact.qbs index d1f9f54ea..f7ae7f5e0 100644 --- a/tests/auto/blackbox/testdata/installed_artifact/installed_artifact.qbs +++ b/tests/auto/blackbox/testdata/installed_artifact/installed_artifact.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Application { name: "installedApp" type: "application" diff --git a/tests/auto/blackbox/testdata/installpackage/installpackage.qbs b/tests/auto/blackbox/testdata/installpackage/installpackage.qbs index d04ecdd57..a0649a578 100644 --- a/tests/auto/blackbox/testdata/installpackage/installpackage.qbs +++ b/tests/auto/blackbox/testdata/installpackage/installpackage.qbs @@ -1,9 +1,10 @@ -import qbs - Project { CppApplication { name: "public_tool" - bundle.isBundle: false + Properties { + condition: qbs.targetOS.contains("darwin") + bundle.isBundle: false + } Depends { name: "mylib" } files: ["main.cpp"] Group { @@ -18,7 +19,10 @@ Project { files: ["main.cpp"] } DynamicLibrary { - bundle.isBundle: false + Properties { + condition: qbs.targetOS.contains("darwin") + bundle.isBundle: false + } Depends { name: "cpp" } name: "mylib" files: ["lib.cpp"] diff --git a/tests/auto/blackbox/testdata/invalid-command-property/invalid-command-property.qbs b/tests/auto/blackbox/testdata/invalid-command-property/invalid-command-property.qbs index 65437311e..b08fcd4a3 100644 --- a/tests/auto/blackbox/testdata/invalid-command-property/invalid-command-property.qbs +++ b/tests/auto/blackbox/testdata/invalid-command-property/invalid-command-property.qbs @@ -1,7 +1,8 @@ -import qbs import qbs.TextFile Product { + name: "p" + property string errorType type: ["output"] Group { files: ["input.txt"] @@ -16,11 +17,15 @@ Product { prepare: { var cmd = new JavaScriptCommand(); cmd.description = "Creating output"; - cmd.textFile = new TextFile(input.filePath, TextFile.ReadOnly); - cmd.sourceCode = function() { - var content = textFile.readAll(); - textFile.close(); - } + if (product.errorType === "qobject") + cmd.dummy = new TextFile(input.filePath, TextFile.ReadOnly); + else if (product.errorType === "input") + cmd.dummy = input; + else if (product.errorType === "artifact") + cmd.dummy = product.artifacts.qbs[0]; + else + throw "invalid error type " + product.errorType; + cmd.sourceCode = function() { } return [cmd]; } } diff --git a/tests/auto/blackbox/testdata/invalid-extension-instantiation/invalid-extension-instantiation.qbs b/tests/auto/blackbox/testdata/invalid-extension-instantiation/invalid-extension-instantiation.qbs index ad2f55da4..d5e4dd5c7 100644 --- a/tests/auto/blackbox/testdata/invalid-extension-instantiation/invalid-extension-instantiation.qbs +++ b/tests/auto/blackbox/testdata/invalid-extension-instantiation/invalid-extension-instantiation.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Environment import qbs.File import qbs.FileInfo diff --git a/tests/auto/blackbox/testdata/invalid-install-dir/invalid-install-dir.qbs b/tests/auto/blackbox/testdata/invalid-install-dir/invalid-install-dir.qbs index f4a608904..57505712c 100644 --- a/tests/auto/blackbox/testdata/invalid-install-dir/invalid-install-dir.qbs +++ b/tests/auto/blackbox/testdata/invalid-install-dir/invalid-install-dir.qbs @@ -1,11 +1,7 @@ -import qbs - CppApplication { consoleApplication: true files: ["main.cpp"] - Group { - fileTagsFilter: ["application"] - qbs.install: true - qbs.installDir: "../whatever" - } + qbs.installPrefix: "" + install: true + installDir: "../whatever" } diff --git a/tests/auto/blackbox/testdata/invalid-library-names/invalid-library-names.qbs b/tests/auto/blackbox/testdata/invalid-library-names/invalid-library-names.qbs index 1ddfecd38..659b39962 100644 --- a/tests/auto/blackbox/testdata/invalid-library-names/invalid-library-names.qbs +++ b/tests/auto/blackbox/testdata/invalid-library-names/invalid-library-names.qbs @@ -1,5 +1,3 @@ -import qbs - Project { minimumQbsVersion: "1.6" property var values: [null, undefined, 5, [], ""] diff --git a/tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs b/tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs index 7d3ada851..1e7426744 100644 --- a/tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs +++ b/tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs @@ -1,14 +1,10 @@ -import qbs import qbs.BinaryFile Product { type: ["dummy"] Rule { multiplex: true - Artifact { - filePath: "dummy.dat" - fileTags: ["dummy"] - } + outputFileTags: "dummy" prepare: { var commands = []; var cmd = new JavaScriptCommand(); diff --git a/tests/auto/blackbox/testdata/jsextensions-file/file.qbs b/tests/auto/blackbox/testdata/jsextensions-file/file.qbs index 2b0ec8de1..6adf714e2 100644 --- a/tests/auto/blackbox/testdata/jsextensions-file/file.qbs +++ b/tests/auto/blackbox/testdata/jsextensions-file/file.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.FileInfo import qbs.TextFile @@ -7,10 +6,7 @@ Product { type: ["dummy"] Rule { multiplex: true - Artifact { - filePath: "dummy.txt" - fileTags: ["dummy"] - } + outputFileTags: "dummy" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; diff --git a/tests/auto/blackbox/testdata/jsextensions-fileinfo/fileinfo.qbs b/tests/auto/blackbox/testdata/jsextensions-fileinfo/fileinfo.qbs index cf28b4014..244f2122e 100644 --- a/tests/auto/blackbox/testdata/jsextensions-fileinfo/fileinfo.qbs +++ b/tests/auto/blackbox/testdata/jsextensions-fileinfo/fileinfo.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo import qbs.TextFile @@ -6,10 +5,7 @@ Product { type: ["dummy"] Rule { multiplex: true - Artifact { - filePath: "dummy.txt" - fileTags: ["dummy"] - } + outputFileTags: "dummy" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; diff --git a/tests/auto/blackbox/testdata/jsextensions-process/process.qbs b/tests/auto/blackbox/testdata/jsextensions-process/process.qbs index c9c832ba4..be9e718df 100644 --- a/tests/auto/blackbox/testdata/jsextensions-process/process.qbs +++ b/tests/auto/blackbox/testdata/jsextensions-process/process.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Environment import qbs.FileInfo import qbs.Process @@ -13,10 +12,7 @@ Project { Rule { multiplex: true inputs: ["application"] - Artifact { - filePath: "dummy.txt" - fileTags: ["dummy"] - } + outputFileTags: "dummy" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; diff --git a/tests/auto/blackbox/testdata/jsextensions-propertylist/propertylist.qbs b/tests/auto/blackbox/testdata/jsextensions-propertylist/propertylist.qbs index a70b81625..aa1351543 100644 --- a/tests/auto/blackbox/testdata/jsextensions-propertylist/propertylist.qbs +++ b/tests/auto/blackbox/testdata/jsextensions-propertylist/propertylist.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Process import qbs.PropertyList import qbs.TextFile diff --git a/tests/auto/blackbox/testdata/jsextensions-temporarydir/jsextensions-temporarydir.qbs b/tests/auto/blackbox/testdata/jsextensions-temporarydir/jsextensions-temporarydir.qbs index fb54a45ec..c540e9196 100644 --- a/tests/auto/blackbox/testdata/jsextensions-temporarydir/jsextensions-temporarydir.qbs +++ b/tests/auto/blackbox/testdata/jsextensions-temporarydir/jsextensions-temporarydir.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File import qbs.TemporaryDir diff --git a/tests/auto/blackbox/testdata/jsextensions-textfile/textfile.qbs b/tests/auto/blackbox/testdata/jsextensions-textfile/textfile.qbs index ef433a1e4..62b54b131 100644 --- a/tests/auto/blackbox/testdata/jsextensions-textfile/textfile.qbs +++ b/tests/auto/blackbox/testdata/jsextensions-textfile/textfile.qbs @@ -1,14 +1,10 @@ -import qbs import qbs.TextFile Product { type: ["dummy"] Rule { multiplex: true - Artifact { - filePath: "dummy.txt" - fileTags: ["dummy"] - } + outputFileTags: "dummy" prepare: { var commands = []; var cmd = new JavaScriptCommand(); diff --git a/tests/auto/blackbox/testdata/ld/ld.qbs b/tests/auto/blackbox/testdata/ld/ld.qbs index f95157012..25fede1b0 100644 --- a/tests/auto/blackbox/testdata/ld/ld.qbs +++ b/tests/auto/blackbox/testdata/ld/ld.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Library { Depends { name: "cpp" } diff --git a/tests/auto/blackbox/testdata/lexyacc/lex_outfile/lex_outfile.qbs b/tests/auto/blackbox/testdata/lexyacc/lex_outfile/lex_outfile.qbs index 3708140ad..61f76f4be 100644 --- a/tests/auto/blackbox/testdata/lexyacc/lex_outfile/lex_outfile.qbs +++ b/tests/auto/blackbox/testdata/lexyacc/lex_outfile/lex_outfile.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { qbsSearchPaths: ".." Depends { name: "bisonhelper" } diff --git a/tests/auto/blackbox/testdata/lexyacc/lex_prefix/lex_prefix.qbs b/tests/auto/blackbox/testdata/lexyacc/lex_prefix/lex_prefix.qbs index 3708140ad..61f76f4be 100644 --- a/tests/auto/blackbox/testdata/lexyacc/lex_prefix/lex_prefix.qbs +++ b/tests/auto/blackbox/testdata/lexyacc/lex_prefix/lex_prefix.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { qbsSearchPaths: ".." Depends { name: "bisonhelper" } diff --git a/tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs b/tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs index 3708140ad..61f76f4be 100644 --- a/tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs +++ b/tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { qbsSearchPaths: ".." Depends { name: "bisonhelper" } diff --git a/tests/auto/blackbox/testdata/lexyacc/two-grammars/two-grammars.qbs b/tests/auto/blackbox/testdata/lexyacc/two-grammars/two-grammars.qbs index fb1375598..7b0c1e515 100644 --- a/tests/auto/blackbox/testdata/lexyacc/two-grammars/two-grammars.qbs +++ b/tests/auto/blackbox/testdata/lexyacc/two-grammars/two-grammars.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Depends { name: "lex_yacc" } consoleApplication: true diff --git a/tests/auto/blackbox/testdata/lexyacc/yacc_output/yacc_output.qbs b/tests/auto/blackbox/testdata/lexyacc/yacc_output/yacc_output.qbs index 298190996..7e89b317e 100644 --- a/tests/auto/blackbox/testdata/lexyacc/yacc_output/yacc_output.qbs +++ b/tests/auto/blackbox/testdata/lexyacc/yacc_output/yacc_output.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Depends { name: "lex_yacc" } lex_yacc.outputTag: "cpp" diff --git a/tests/auto/blackbox/testdata/linkerMode/linkerMode.qbs b/tests/auto/blackbox/testdata/linkerMode/linkerMode.qbs index 05e3eabed..1be50c0aa 100644 --- a/tests/auto/blackbox/testdata/linkerMode/linkerMode.qbs +++ b/tests/auto/blackbox/testdata/linkerMode/linkerMode.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { consoleApplication: true diff --git a/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs b/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs index 42b3884ea..b30a498bb 100644 --- a/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs +++ b/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs @@ -1,5 +1,3 @@ -import qbs - DynamicLibrary { type: base.concat("custom") Depends { name: "cpp" } @@ -12,10 +10,7 @@ DynamicLibrary { Rule { multiplex: true - Artifact { - filePath: "dummy.txt" - fileTags: ["custom"] - } + outputFileTags: "custom" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; @@ -26,8 +21,7 @@ DynamicLibrary { } } - Group { - fileTagsFilter: ["dynamiclibrary"] - qbs.install: true - } + qbs.installPrefix: "" + install: true + installDir: "" } diff --git a/tests/auto/blackbox/testdata/list-products/list-products.qbs b/tests/auto/blackbox/testdata/list-products/list-products.qbs index 559a7d274..5431b9371 100644 --- a/tests/auto/blackbox/testdata/list-products/list-products.qbs +++ b/tests/auto/blackbox/testdata/list-products/list-products.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "a" diff --git a/tests/auto/blackbox/testdata/list-properties-with-outer/list-properties-with-outer.qbs b/tests/auto/blackbox/testdata/list-properties-with-outer/list-properties-with-outer.qbs index 3b0b3be49..ba157a7ac 100644 --- a/tests/auto/blackbox/testdata/list-properties-with-outer/list-properties-with-outer.qbs +++ b/tests/auto/blackbox/testdata/list-properties-with-outer/list-properties-with-outer.qbs @@ -1,5 +1,3 @@ -import qbs - Product { type: ["outtype"] Depends { name: "higher" } diff --git a/tests/auto/blackbox/testdata/list-properties-with-outer/modules/higher/higher.qbs b/tests/auto/blackbox/testdata/list-properties-with-outer/modules/higher/higher.qbs index a8d1b186f..ddb7b6f40 100644 --- a/tests/auto/blackbox/testdata/list-properties-with-outer/modules/higher/higher.qbs +++ b/tests/auto/blackbox/testdata/list-properties-with-outer/modules/higher/higher.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "lower" } lower.listProp: ["higher"] diff --git a/tests/auto/blackbox/testdata/list-properties-with-outer/modules/lower/lower.qbs b/tests/auto/blackbox/testdata/list-properties-with-outer/modules/lower/lower.qbs index 3d5824bc2..63c97aa76 100644 --- a/tests/auto/blackbox/testdata/list-properties-with-outer/modules/lower/lower.qbs +++ b/tests/auto/blackbox/testdata/list-properties-with-outer/modules/lower/lower.qbs @@ -1,14 +1,9 @@ -import qbs - Module { property stringList listProp Rule { inputs: ["intype"] - Artifact { - filePath: "dummy.out" - fileTags: ["outtype"] - } + outputFileTags: "outtype" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; diff --git a/tests/auto/blackbox/testdata/list-property-order/modules/higher1/higher1.qbs b/tests/auto/blackbox/testdata/list-property-order/modules/higher1/higher1.qbs index c56dd33bc..67c7c790a 100644 --- a/tests/auto/blackbox/testdata/list-property-order/modules/higher1/higher1.qbs +++ b/tests/auto/blackbox/testdata/list-property-order/modules/higher1/higher1.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "lower" } lower.listProp: ["higher1"] diff --git a/tests/auto/blackbox/testdata/list-property-order/modules/higher2/higher2.qbs b/tests/auto/blackbox/testdata/list-property-order/modules/higher2/higher2.qbs index 75600ffa4..3ca22f51c 100644 --- a/tests/auto/blackbox/testdata/list-property-order/modules/higher2/higher2.qbs +++ b/tests/auto/blackbox/testdata/list-property-order/modules/higher2/higher2.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "lower" } lower.listProp: ["higher2"] diff --git a/tests/auto/blackbox/testdata/list-property-order/modules/higher3/higher3.qbs b/tests/auto/blackbox/testdata/list-property-order/modules/higher3/higher3.qbs index 5372b92db..f534cf8bf 100644 --- a/tests/auto/blackbox/testdata/list-property-order/modules/higher3/higher3.qbs +++ b/tests/auto/blackbox/testdata/list-property-order/modules/higher3/higher3.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "lower" } lower.listProp: ["higher3"] diff --git a/tests/auto/blackbox/testdata/list-property-order/modules/lower/lower.qbs b/tests/auto/blackbox/testdata/list-property-order/modules/lower/lower.qbs index eeed377bc..c7462676d 100644 --- a/tests/auto/blackbox/testdata/list-property-order/modules/lower/lower.qbs +++ b/tests/auto/blackbox/testdata/list-property-order/modules/lower/lower.qbs @@ -1,5 +1,3 @@ -import qbs - Module { property stringList listProp diff --git a/tests/auto/blackbox/testdata/list-property-order/product.qbs b/tests/auto/blackbox/testdata/list-property-order/product.qbs index ef5e5c827..e92494693 100644 --- a/tests/auto/blackbox/testdata/list-property-order/product.qbs +++ b/tests/auto/blackbox/testdata/list-property-order/product.qbs @@ -1,5 +1,3 @@ -import qbs - Product { type: "outtype" name: "toplevel" diff --git a/tests/auto/blackbox/testdata/loadablemodule/loadablemodule.qbs b/tests/auto/blackbox/testdata/loadablemodule/loadablemodule.qbs index 15b5906af..ec5b0b358 100644 --- a/tests/auto/blackbox/testdata/loadablemodule/loadablemodule.qbs +++ b/tests/auto/blackbox/testdata/loadablemodule/loadablemodule.qbs @@ -1,5 +1,3 @@ -import qbs - Project { LoadableModule { Depends { name: "cpp" } diff --git a/tests/auto/blackbox/testdata/localDeployment/localDeployment.qbs b/tests/auto/blackbox/testdata/localDeployment/localDeployment.qbs index 2b4d1f241..650f07104 100644 --- a/tests/auto/blackbox/testdata/localDeployment/localDeployment.qbs +++ b/tests/auto/blackbox/testdata/localDeployment/localDeployment.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { type: ["application"] diff --git a/tests/auto/blackbox/testdata/makefile-generator/app.qbs b/tests/auto/blackbox/testdata/makefile-generator/app.qbs index 103f71ecf..dfd67276e 100644 --- a/tests/auto/blackbox/testdata/makefile-generator/app.qbs +++ b/tests/auto/blackbox/testdata/makefile-generator/app.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "the app" consoleApplication: true @@ -14,9 +12,5 @@ CppApplication { files: "main.cpp" qbs.installPrefix: "/usr/local" - Group { - fileTagsFilter: "application" - qbs.install: true - qbs.installDir: "bin" - } + install: true } diff --git a/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs b/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs index 2ac47b66a..320494d00 100644 --- a/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs +++ b/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "app" property bool enableNewestModule: true diff --git a/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newermodule/newermodule.qbs b/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newermodule/newermodule.qbs index 4dd343b3b..d5b015e42 100644 --- a/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newermodule/newermodule.qbs +++ b/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newermodule/newermodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } cpp.cLanguageVersion: "c99" diff --git a/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newestmodule/newestmodule.qbs b/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newestmodule/newestmodule.qbs index f8316a35e..5437957fe 100644 --- a/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newestmodule/newestmodule.qbs +++ b/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newestmodule/newestmodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } cpp.cLanguageVersion: "c11" diff --git a/tests/auto/blackbox/testdata/maximum-c-language-version/modules/oldmodule/oldmodule.qbs b/tests/auto/blackbox/testdata/maximum-c-language-version/modules/oldmodule/oldmodule.qbs index a753b3e3e..10e530098 100644 --- a/tests/auto/blackbox/testdata/maximum-c-language-version/modules/oldmodule/oldmodule.qbs +++ b/tests/auto/blackbox/testdata/maximum-c-language-version/modules/oldmodule/oldmodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } cpp.cLanguageVersion: "c90" diff --git a/tests/auto/blackbox/testdata/maximum-cxx-language-version/maximum-cxx-language-version.qbs b/tests/auto/blackbox/testdata/maximum-cxx-language-version/maximum-cxx-language-version.qbs index 5dd298aa8..71933cf60 100644 --- a/tests/auto/blackbox/testdata/maximum-cxx-language-version/maximum-cxx-language-version.qbs +++ b/tests/auto/blackbox/testdata/maximum-cxx-language-version/maximum-cxx-language-version.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "app" property bool enableNewestModule: true diff --git a/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newermodule/newermodule.qbs b/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newermodule/newermodule.qbs index dfc28b946..88b1da212 100644 --- a/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newermodule/newermodule.qbs +++ b/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newermodule/newermodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } cpp.cxxLanguageVersion: "c++14" diff --git a/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newestmodule/newestmodule.qbs b/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newestmodule/newestmodule.qbs index f306a5389..f99932b10 100644 --- a/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newestmodule/newestmodule.qbs +++ b/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/newestmodule/newestmodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } cpp.cxxLanguageVersion: "c++17" diff --git a/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/oldmodule/oldmodule.qbs b/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/oldmodule/oldmodule.qbs index b05c855a3..73d3bf16a 100644 --- a/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/oldmodule/oldmodule.qbs +++ b/tests/auto/blackbox/testdata/maximum-cxx-language-version/modules/oldmodule/oldmodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "cpp" } cpp.cxxLanguageVersion: "c++11" diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/fakewindows.qbs b/tests/auto/blackbox/testdata/minimumSystemVersion/fakewindows.qbs index f536da6ac..1a56e0b7e 100644 --- a/tests/auto/blackbox/testdata/minimumSystemVersion/fakewindows.qbs +++ b/tests/auto/blackbox/testdata/minimumSystemVersion/fakewindows.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities // non-existent versions of Windows should print a QBS warning diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs b/tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs index 82cce3e07..8440da779 100644 --- a/tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs +++ b/tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs @@ -1,5 +1,3 @@ -import qbs - // just to make sure three-digit minimum versions work on macOS // this only affects the value of __MAC_OS_X_VERSION_MIN_REQUIRED, // not the actual LC_VERSION_MIN_MACOSX command which is limited to two diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs b/tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs index 2af95134a..f6ecab418 100644 --- a/tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs +++ b/tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities // a specific version of the operating systems is specified diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified-forced.qbs b/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified-forced.qbs index 2285e20ba..a5ea620fd 100644 --- a/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified-forced.qbs +++ b/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified-forced.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities // no minimum versions are specified, and explicitly set to undefined in diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified.qbs b/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified.qbs index ac0a7abdc..0eeb2d547 100644 --- a/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified.qbs +++ b/tests/auto/blackbox/testdata/minimumSystemVersion/unspecified.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities // no minimum versions are specified so the profile defaults will be used diff --git a/tests/auto/blackbox/testdata/missing-dependency/missing-dependency.qbs b/tests/auto/blackbox/testdata/missing-dependency/missing-dependency.qbs index a30ac2a70..6bb8b96f2 100644 --- a/tests/auto/blackbox/testdata/missing-dependency/missing-dependency.qbs +++ b/tests/auto/blackbox/testdata/missing-dependency/missing-dependency.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Project { diff --git a/tests/auto/blackbox/testdata/missing-override-prefix/missing-override-prefix.qbs b/tests/auto/blackbox/testdata/missing-override-prefix/missing-override-prefix.qbs index 6d16a3c53..86718b571 100644 --- a/tests/auto/blackbox/testdata/missing-override-prefix/missing-override-prefix.qbs +++ b/tests/auto/blackbox/testdata/missing-override-prefix/missing-override-prefix.qbs @@ -1,3 +1 @@ -import qbs - Product { } diff --git a/tests/auto/blackbox/testdata/missing-project-file/project-dir/missing-project-file.qbs b/tests/auto/blackbox/testdata/missing-project-file/project-dir/missing-project-file.qbs index a294cbd24..421bad1f0 100644 --- a/tests/auto/blackbox/testdata/missing-project-file/project-dir/missing-project-file.qbs +++ b/tests/auto/blackbox/testdata/missing-project-file/project-dir/missing-project-file.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: [ "file.cpp", diff --git a/tests/auto/blackbox/testdata/moved-file-dependency/moved-file-dependency.qbs b/tests/auto/blackbox/testdata/moved-file-dependency/moved-file-dependency.qbs index 6252f98ed..797198686 100644 --- a/tests/auto/blackbox/testdata/moved-file-dependency/moved-file-dependency.qbs +++ b/tests/auto/blackbox/testdata/moved-file-dependency/moved-file-dependency.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { cpp.includePaths: ["subdir1", "subdir2"] files: ["main.cpp"] diff --git a/tests/auto/blackbox/testdata/multiple-changes/multiple-changes.qbs b/tests/auto/blackbox/testdata/multiple-changes/multiple-changes.qbs index 254e2b4da..51e6b1a5c 100644 --- a/tests/auto/blackbox/testdata/multiple-changes/multiple-changes.qbs +++ b/tests/auto/blackbox/testdata/multiple-changes/multiple-changes.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property bool prop: false Product { diff --git a/tests/auto/blackbox/testdata/multiple-configurations/multiple-configurations.qbs b/tests/auto/blackbox/testdata/multiple-configurations/multiple-configurations.qbs index f8371e983..f6fd16ba2 100644 --- a/tests/auto/blackbox/testdata/multiple-configurations/multiple-configurations.qbs +++ b/tests/auto/blackbox/testdata/multiple-configurations/multiple-configurations.qbs @@ -1,5 +1,3 @@ -import qbs - Project { StaticLibrary { name: "lib" diff --git a/tests/auto/blackbox/testdata/multiplexed-tool/multiplexed-tool.qbs b/tests/auto/blackbox/testdata/multiplexed-tool/multiplexed-tool.qbs index b36ea5be9..3994bd95f 100644 --- a/tests/auto/blackbox/testdata/multiplexed-tool/multiplexed-tool.qbs +++ b/tests/auto/blackbox/testdata/multiplexed-tool/multiplexed-tool.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "tool" diff --git a/tests/auto/blackbox/testdata/nested-groups/modules/themodule/themodule.qbs b/tests/auto/blackbox/testdata/nested-groups/modules/themodule/themodule.qbs index ffca11cdf..73426ddf5 100644 --- a/tests/auto/blackbox/testdata/nested-groups/modules/themodule/themodule.qbs +++ b/tests/auto/blackbox/testdata/nested-groups/modules/themodule/themodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Group { cpp.defines: ["REQUIRED_FOR_FILE3"] diff --git a/tests/auto/blackbox/testdata/nested-groups/nested-groups.qbs b/tests/auto/blackbox/testdata/nested-groups/nested-groups.qbs index 827eda64e..88f5ae30e 100644 --- a/tests/auto/blackbox/testdata/nested-groups/nested-groups.qbs +++ b/tests/auto/blackbox/testdata/nested-groups/nested-groups.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { consoleApplication: true Depends { name: "themodule" } diff --git a/tests/auto/blackbox/testdata/nested-properties/modules/higherlevel/higher-level.qbs b/tests/auto/blackbox/testdata/nested-properties/modules/higherlevel/higher-level.qbs index a3c117efd..071737c36 100644 --- a/tests/auto/blackbox/testdata/nested-properties/modules/higherlevel/higher-level.qbs +++ b/tests/auto/blackbox/testdata/nested-properties/modules/higherlevel/higher-level.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "lowerlevel" } lowerlevel.propDependency: "value in higherlevel" diff --git a/tests/auto/blackbox/testdata/nested-properties/modules/lowerlevel/lower-level.qbs b/tests/auto/blackbox/testdata/nested-properties/modules/lowerlevel/lower-level.qbs index 6b2d00587..f8b6a7dc0 100644 --- a/tests/auto/blackbox/testdata/nested-properties/modules/lowerlevel/lower-level.qbs +++ b/tests/auto/blackbox/testdata/nested-properties/modules/lowerlevel/lower-level.qbs @@ -1,5 +1,3 @@ -import qbs - Module { property string propDependency: "value in lowerlevel module" property string prop: propDependency @@ -7,10 +5,7 @@ Module { Rule { inputs: ["dummy-input"] - Artifact { - filePath: "dummy.out" - fileTags: "mytype" - } + outputFileTags: "mytype" prepare: { var cmd = new JavaScriptCommand(); cmd.sourceCode = function() { }; diff --git a/tests/auto/blackbox/testdata/nested-properties/product.qbs b/tests/auto/blackbox/testdata/nested-properties/product.qbs index 916cee151..e38813b72 100644 --- a/tests/auto/blackbox/testdata/nested-properties/product.qbs +++ b/tests/auto/blackbox/testdata/nested-properties/product.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "dep" diff --git a/tests/auto/blackbox/testdata/new-output-artifact/new-output-artifact.qbs b/tests/auto/blackbox/testdata/new-output-artifact/new-output-artifact.qbs index 10e0e4305..b297a3f61 100644 --- a/tests/auto/blackbox/testdata/new-output-artifact/new-output-artifact.qbs +++ b/tests/auto/blackbox/testdata/new-output-artifact/new-output-artifact.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Product { @@ -9,6 +8,7 @@ Product { files: ["input.txt"] fileTags: ["input"] } + qbs.installPrefix: "" Group { fileTagsFilter: product.type qbs.install: true diff --git a/tests/auto/blackbox/testdata/no-exported-symbols/lib.cpp b/tests/auto/blackbox/testdata/no-exported-symbols/lib.cpp new file mode 100644 index 000000000..20cfe21da --- /dev/null +++ b/tests/auto/blackbox/testdata/no-exported-symbols/lib.cpp @@ -0,0 +1 @@ +static void someFunc() {} diff --git a/tests/auto/blackbox/testdata/no-exported-symbols/lib.h b/tests/auto/blackbox/testdata/no-exported-symbols/lib.h new file mode 100644 index 000000000..48fa2de97 --- /dev/null +++ b/tests/auto/blackbox/testdata/no-exported-symbols/lib.h @@ -0,0 +1,6 @@ +#ifndef TEST_LIB +#define TEST_LIB + +inline int success() { return 0; } + +#endif diff --git a/tests/auto/blackbox/testdata/no-exported-symbols/main.cpp b/tests/auto/blackbox/testdata/no-exported-symbols/main.cpp new file mode 100644 index 000000000..a76122e19 --- /dev/null +++ b/tests/auto/blackbox/testdata/no-exported-symbols/main.cpp @@ -0,0 +1,6 @@ +#include <lib.h> + +int main() +{ + return success(); +} diff --git a/tests/auto/blackbox/testdata/no-exported-symbols/no-exported-symbols.qbs b/tests/auto/blackbox/testdata/no-exported-symbols/no-exported-symbols.qbs new file mode 100644 index 000000000..4bda00caf --- /dev/null +++ b/tests/auto/blackbox/testdata/no-exported-symbols/no-exported-symbols.qbs @@ -0,0 +1,28 @@ +Project { + DynamicLibrary { + name: "the_lib" + Depends { name: "cpp" } + files: ["lib.cpp", "lib.h"] + Export { + Depends { name: "cpp" } + cpp.includePaths: path + } + + Probe { + id: toolchainProbe + property stringList toolchain: qbs.toolchain + configure: { + if (toolchain.contains("msvc")) + console.info("compiler is MSVC") + else + console.info("compiler is not MSVC") + } + } + } + CppApplication { + name: "the_app" + property bool link + Depends { name: "the_lib"; cpp.link: product.link } + files: "main.cpp" + } +} diff --git a/tests/auto/blackbox/testdata/no-profile/no-profile.qbs b/tests/auto/blackbox/testdata/no-profile/no-profile.qbs index cc251c6ab..6fd7dd07a 100644 --- a/tests/auto/blackbox/testdata/no-profile/no-profile.qbs +++ b/tests/auto/blackbox/testdata/no-profile/no-profile.qbs @@ -1,5 +1,3 @@ -import qbs - Product { property bool dummy: { console.info("profile: " + project.profile); } } diff --git a/tests/auto/blackbox/testdata/nodejs/hello.qbs b/tests/auto/blackbox/testdata/nodejs/hello.qbs index d5e92209a..c19e455db 100644 --- a/tests/auto/blackbox/testdata/nodejs/hello.qbs +++ b/tests/auto/blackbox/testdata/nodejs/hello.qbs @@ -1,5 +1,3 @@ -import qbs - NodeJSApplication { nodejs.applicationFile: "hello.js" name: "hello" diff --git a/tests/auto/blackbox/testdata/non-broken-files-in-broken-product/non-broken-files-in-broken-product.qbs b/tests/auto/blackbox/testdata/non-broken-files-in-broken-product/non-broken-files-in-broken-product.qbs index 1ec764dfa..abd41fb6b 100644 --- a/tests/auto/blackbox/testdata/non-broken-files-in-broken-product/non-broken-files-in-broken-product.qbs +++ b/tests/auto/blackbox/testdata/non-broken-files-in-broken-product/non-broken-files-in-broken-product.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { consoleApplication: true files: ["fine.cpp", "broken.cpp"] diff --git a/tests/auto/blackbox/testdata/non-default-product/non-default-product.qbs b/tests/auto/blackbox/testdata/non-default-product/non-default-product.qbs index 498344975..6e006e831 100644 --- a/tests/auto/blackbox/testdata/non-default-product/non-default-product.qbs +++ b/tests/auto/blackbox/testdata/non-default-product/non-default-product.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "default app" diff --git a/tests/auto/blackbox/testdata/nsis/hello.qbs b/tests/auto/blackbox/testdata/nsis/hello.qbs index b7f3da505..a161a6998 100644 --- a/tests/auto/blackbox/testdata/nsis/hello.qbs +++ b/tests/auto/blackbox/testdata/nsis/hello.qbs @@ -1,5 +1,3 @@ -import qbs - NSISSetup { condition: qbs.targetOS.contains("windows") name: "Qbs Hello" diff --git a/tests/auto/blackbox/testdata/nsisDependencies/nsisDependencies.qbs b/tests/auto/blackbox/testdata/nsisDependencies/nsisDependencies.qbs index 7f19bf8d7..d8185aabf 100644 --- a/tests/auto/blackbox/testdata/nsisDependencies/nsisDependencies.qbs +++ b/tests/auto/blackbox/testdata/nsisDependencies/nsisDependencies.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo import qbs.TextFile @@ -37,7 +36,7 @@ Project { // This rule tries to provoke the installer into building too early (and the test // verifies that it does not) by causing the build of the installables to take // a lot longer. - inputs: ["qbs"] + multiplex: true outputFileTags: ["c"] outputArtifacts: { var artifacts = []; diff --git a/tests/auto/blackbox/testdata/out-of-date-marking/out-of-date-marking.qbs b/tests/auto/blackbox/testdata/out-of-date-marking/out-of-date-marking.qbs index 1ef57bae7..d52246578 100644 --- a/tests/auto/blackbox/testdata/out-of-date-marking/out-of-date-marking.qbs +++ b/tests/auto/blackbox/testdata/out-of-date-marking/out-of-date-marking.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile CppApplication { diff --git a/tests/auto/blackbox/testdata/output-artifact-auto-tagging/output-artifact-auto-tagging.qbs b/tests/auto/blackbox/testdata/output-artifact-auto-tagging/output-artifact-auto-tagging.qbs index a9090f3db..7ec8fd916 100644 --- a/tests/auto/blackbox/testdata/output-artifact-auto-tagging/output-artifact-auto-tagging.qbs +++ b/tests/auto/blackbox/testdata/output-artifact-auto-tagging/output-artifact-auto-tagging.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File CppApplication { diff --git a/tests/auto/blackbox/testdata/overrideProjectProperties/helper_lib.qbs b/tests/auto/blackbox/testdata/overrideProjectProperties/helper_lib.qbs index b26b0f31f..b69dd0da8 100644 --- a/tests/auto/blackbox/testdata/overrideProjectProperties/helper_lib.qbs +++ b/tests/auto/blackbox/testdata/overrideProjectProperties/helper_lib.qbs @@ -1,5 +1,3 @@ -import qbs - DynamicLibrary { name: "helperLib" files: "helperlib.cpp" diff --git a/tests/auto/blackbox/testdata/overrideProjectProperties/overrideProjectProperties.qbs b/tests/auto/blackbox/testdata/overrideProjectProperties/overrideProjectProperties.qbs index 6e8ef62a1..650606fbd 100644 --- a/tests/auto/blackbox/testdata/overrideProjectProperties/overrideProjectProperties.qbs +++ b/tests/auto/blackbox/testdata/overrideProjectProperties/overrideProjectProperties.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { property string nameSuffix: "" property bool someBool diff --git a/tests/auto/blackbox/testdata/overrideProjectProperties/project_using_helper_lib.qbs b/tests/auto/blackbox/testdata/overrideProjectProperties/project_using_helper_lib.qbs index c61716e6e..1eb21cdd1 100644 --- a/tests/auto/blackbox/testdata/overrideProjectProperties/project_using_helper_lib.qbs +++ b/tests/auto/blackbox/testdata/overrideProjectProperties/project_using_helper_lib.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { property bool linkSuccessfully: false references: linkSuccessfully ? ["helper_lib.qbs"] : [] diff --git a/tests/auto/blackbox/testdata/pch-change-tracking/pch-change-tracking.qbs b/tests/auto/blackbox/testdata/pch-change-tracking/pch-change-tracking.qbs index 2cfb17337..3da526fdb 100644 --- a/tests/auto/blackbox/testdata/pch-change-tracking/pch-change-tracking.qbs +++ b/tests/auto/blackbox/testdata/pch-change-tracking/pch-change-tracking.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: [ "header1.h", diff --git a/tests/auto/blackbox/testdata/per-group-define-in-export-item/per-group-define-in-export-item.qbs b/tests/auto/blackbox/testdata/per-group-define-in-export-item/per-group-define-in-export-item.qbs index 514de7ecb..a81b8f6c9 100644 --- a/tests/auto/blackbox/testdata/per-group-define-in-export-item/per-group-define-in-export-item.qbs +++ b/tests/auto/blackbox/testdata/per-group-define-in-export-item/per-group-define-in-export-item.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "dep" diff --git a/tests/auto/blackbox/testdata/pkg-config-probe-sysroot/modules/themodule/themodule.qbs b/tests/auto/blackbox/testdata/pkg-config-probe-sysroot/modules/themodule/themodule.qbs index 2b33922a2..991876f6b 100644 --- a/tests/auto/blackbox/testdata/pkg-config-probe-sysroot/modules/themodule/themodule.qbs +++ b/tests/auto/blackbox/testdata/pkg-config-probe-sysroot/modules/themodule/themodule.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Probes Module { @@ -11,10 +10,7 @@ Module { Rule { multiplex: true - Artifact { - filePath: "dummy.out" - fileTags: ["theType"] - } + outputFileTags: "theType" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; diff --git a/tests/auto/blackbox/testdata/pkg-config-probe-sysroot/pkg-config.qbs b/tests/auto/blackbox/testdata/pkg-config-probe-sysroot/pkg-config.qbs index 0eac3cca0..11498ebdb 100644 --- a/tests/auto/blackbox/testdata/pkg-config-probe-sysroot/pkg-config.qbs +++ b/tests/auto/blackbox/testdata/pkg-config-probe-sysroot/pkg-config.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property string packageBaseName diff --git a/tests/auto/blackbox/testdata/pkg-config-probe/modules/themodule/themodule.qbs b/tests/auto/blackbox/testdata/pkg-config-probe/modules/themodule/themodule.qbs index 81dfa955f..d5488da1f 100644 --- a/tests/auto/blackbox/testdata/pkg-config-probe/modules/themodule/themodule.qbs +++ b/tests/auto/blackbox/testdata/pkg-config-probe/modules/themodule/themodule.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Probes Module { @@ -18,10 +17,7 @@ Module { Rule { multiplex: true - Artifact { - filePath: "dummy.out" - fileTags: ["theType"] - } + outputFileTags: "theType" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; diff --git a/tests/auto/blackbox/testdata/pkg-config-probe/pkg-config.qbs b/tests/auto/blackbox/testdata/pkg-config-probe/pkg-config.qbs index db831fbc2..d4dc3b92b 100644 --- a/tests/auto/blackbox/testdata/pkg-config-probe/pkg-config.qbs +++ b/tests/auto/blackbox/testdata/pkg-config-probe/pkg-config.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property string packageBaseName diff --git a/tests/auto/blackbox/testdata/plugin-dependency/plugin-dependency.qbs b/tests/auto/blackbox/testdata/plugin-dependency/plugin-dependency.qbs index f003a71cb..c619b33ef 100644 --- a/tests/auto/blackbox/testdata/plugin-dependency/plugin-dependency.qbs +++ b/tests/auto/blackbox/testdata/plugin-dependency/plugin-dependency.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "myapp" diff --git a/tests/auto/blackbox/testdata/precompiled-and-prefix-headers/precompiled-and-prefix-headers.qbs b/tests/auto/blackbox/testdata/precompiled-and-prefix-headers/precompiled-and-prefix-headers.qbs index b30f76874..bbd524e23 100644 --- a/tests/auto/blackbox/testdata/precompiled-and-prefix-headers/precompiled-and-prefix-headers.qbs +++ b/tests/auto/blackbox/testdata/precompiled-and-prefix-headers/precompiled-and-prefix-headers.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "MyApp" consoleApplication: true diff --git a/tests/auto/blackbox/testdata/prevent-floating-point-values/prevent-floating-point-values.qbs b/tests/auto/blackbox/testdata/prevent-floating-point-values/prevent-floating-point-values.qbs index 619e44f20..bd1d3162a 100644 --- a/tests/auto/blackbox/testdata/prevent-floating-point-values/prevent-floating-point-values.qbs +++ b/tests/auto/blackbox/testdata/prevent-floating-point-values/prevent-floating-point-values.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "p" property bool dummy: { console.info("version: " + version); } diff --git a/tests/auto/blackbox/testdata/probe-change-tracking/probe-change-tracking.qbs b/tests/auto/blackbox/testdata/probe-change-tracking/probe-change-tracking.qbs index ff37985a4..6007a33ac 100644 --- a/tests/auto/blackbox/testdata/probe-change-tracking/probe-change-tracking.qbs +++ b/tests/auto/blackbox/testdata/probe-change-tracking/probe-change-tracking.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Probe { id: tlpProbe diff --git a/tests/auto/blackbox/testdata/probe-in-exported-module/dependee.qbs b/tests/auto/blackbox/testdata/probe-in-exported-module/dependee.qbs index 121ec6c39..fe81cf55c 100644 --- a/tests/auto/blackbox/testdata/probe-in-exported-module/dependee.qbs +++ b/tests/auto/blackbox/testdata/probe-in-exported-module/dependee.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "dependee" Depends { name: "myothermodule" } diff --git a/tests/auto/blackbox/testdata/probe-in-exported-module/dependency.qbs b/tests/auto/blackbox/testdata/probe-in-exported-module/dependency.qbs index 1413777dc..eea5180ef 100644 --- a/tests/auto/blackbox/testdata/probe-in-exported-module/dependency.qbs +++ b/tests/auto/blackbox/testdata/probe-in-exported-module/dependency.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "dependency" Export { diff --git a/tests/auto/blackbox/testdata/probe-in-exported-module/modules/depmodule/depmodule.qbs b/tests/auto/blackbox/testdata/probe-in-exported-module/modules/depmodule/depmodule.qbs index b880d6dac..41c6cfe50 100644 --- a/tests/auto/blackbox/testdata/probe-in-exported-module/modules/depmodule/depmodule.qbs +++ b/tests/auto/blackbox/testdata/probe-in-exported-module/modules/depmodule/depmodule.qbs @@ -1,15 +1,10 @@ -import qbs - Module { property string prop property stringList listProp: [] Rule { inputs: ["dep-in"] - Artifact { - filePath: "dummy.txt" - fileTags: ["dep-out"] - } + outputFileTags: "dep-out" prepare: { var cmd = new JavaScriptCommand(); cmd.description = "Creating dep-out artifact"; diff --git a/tests/auto/blackbox/testdata/probe-in-exported-module/modules/mymodule/mymodule.qbs b/tests/auto/blackbox/testdata/probe-in-exported-module/modules/mymodule/mymodule.qbs index 9f3657f34..89d544f7e 100644 --- a/tests/auto/blackbox/testdata/probe-in-exported-module/modules/mymodule/mymodule.qbs +++ b/tests/auto/blackbox/testdata/probe-in-exported-module/modules/mymodule/mymodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "depmodule" } Probe { @@ -12,10 +10,7 @@ Module { Rule { inputs: ["in"] - Artifact { - filePath: "dummy2.txt" - fileTags: ["out"] - } + outputFileTags: "out" prepare: { var cmd = new JavaScriptCommand(); cmd.description = "Creating out artifact"; diff --git a/tests/auto/blackbox/testdata/probe-in-exported-module/modules/myothermodule/myothermodule.qbs b/tests/auto/blackbox/testdata/probe-in-exported-module/modules/myothermodule/myothermodule.qbs index d3009f532..4ea5dd077 100644 --- a/tests/auto/blackbox/testdata/probe-in-exported-module/modules/myothermodule/myothermodule.qbs +++ b/tests/auto/blackbox/testdata/probe-in-exported-module/modules/myothermodule/myothermodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "depmodule" } depmodule.listProp: ["myother"] diff --git a/tests/auto/blackbox/testdata/probe-in-exported-module/probe-in-exported-module.qbs b/tests/auto/blackbox/testdata/probe-in-exported-module/probe-in-exported-module.qbs index 4e0f13f60..398090195 100644 --- a/tests/auto/blackbox/testdata/probe-in-exported-module/probe-in-exported-module.qbs +++ b/tests/auto/blackbox/testdata/probe-in-exported-module/probe-in-exported-module.qbs @@ -1,5 +1,3 @@ -import qbs - Project { references: [ "dependee.qbs", "dependency.qbs" ] } diff --git a/tests/auto/blackbox/testdata/probeProperties/probeProperties.qbs b/tests/auto/blackbox/testdata/probeProperties/probeProperties.qbs index 36842e40b..9846eacef 100644 --- a/tests/auto/blackbox/testdata/probeProperties/probeProperties.qbs +++ b/tests/auto/blackbox/testdata/probeProperties/probeProperties.qbs @@ -1,17 +1,16 @@ -import qbs import qbs.Probes CppApplication { Probes.PathProbe { id: probe1 names: ["bin/tool"] - platformPaths: [product.sourceDirectory] + platformSearchPaths: [product.sourceDirectory] } Probes.PathProbe { id: probe2 names: ["tool"] - platformPaths: [product.sourceDirectory + "/bin"] + platformSearchPaths: [product.sourceDirectory + "/bin"] } targetName: { diff --git a/tests/auto/blackbox/testdata/probes-and-array-properties/modules/mymodule/mymodule.qbs b/tests/auto/blackbox/testdata/probes-and-array-properties/modules/mymodule/mymodule.qbs index 6479bdfac..e5c368a88 100644 --- a/tests/auto/blackbox/testdata/probes-and-array-properties/modules/mymodule/mymodule.qbs +++ b/tests/auto/blackbox/testdata/probes-and-array-properties/modules/mymodule/mymodule.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Probe { id: propProbe @@ -15,11 +13,7 @@ Module { Rule { multiplex: true - alwaysRun: true - Artifact { - filePath: "dummy" - fileTags: ["the-output"] - } + outputFileTags: "the-output" prepare: { var cmd = new JavaScriptCommand(); cmd.description = "generating dummy"; diff --git a/tests/auto/blackbox/testdata/probes-and-array-properties/probes-and-array-properties.qbs b/tests/auto/blackbox/testdata/probes-and-array-properties/probes-and-array-properties.qbs index c7d88ec14..70ca8e1de 100644 --- a/tests/auto/blackbox/testdata/probes-and-array-properties/probes-and-array-properties.qbs +++ b/tests/auto/blackbox/testdata/probes-and-array-properties/probes-and-array-properties.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "theProduct" type: ["the-output"] diff --git a/tests/auto/blackbox/testdata/probes-and-shadow-products/probes-and-shadow-products.qbs b/tests/auto/blackbox/testdata/probes-and-shadow-products/probes-and-shadow-products.qbs index 660c088a0..19fc67f71 100644 --- a/tests/auto/blackbox/testdata/probes-and-shadow-products/probes-and-shadow-products.qbs +++ b/tests/auto/blackbox/testdata/probes-and-shadow-products/probes-and-shadow-products.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "p" multiplexByQbsProperties: "buildVariants" diff --git a/tests/auto/blackbox/testdata/probes-in-nested-modules/modules/inner/inner.qbs b/tests/auto/blackbox/testdata/probes-in-nested-modules/modules/inner/inner.qbs index b6d39b021..5a254b49b 100644 --- a/tests/auto/blackbox/testdata/probes-in-nested-modules/modules/inner/inner.qbs +++ b/tests/auto/blackbox/testdata/probes-in-nested-modules/modules/inner/inner.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Probes Module { diff --git a/tests/auto/blackbox/testdata/probes-in-nested-modules/modules/outer/outer.qbs b/tests/auto/blackbox/testdata/probes-in-nested-modules/modules/outer/outer.qbs index 71b745f44..4472d573b 100644 --- a/tests/auto/blackbox/testdata/probes-in-nested-modules/modules/outer/outer.qbs +++ b/tests/auto/blackbox/testdata/probes-in-nested-modules/modules/outer/outer.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "inner" } diff --git a/tests/auto/blackbox/testdata/probes-in-nested-modules/probes-in-nested-modules.qbs b/tests/auto/blackbox/testdata/probes-in-nested-modules/probes-in-nested-modules.qbs index ffc273e18..877300c1a 100644 --- a/tests/auto/blackbox/testdata/probes-in-nested-modules/probes-in-nested-modules.qbs +++ b/tests/auto/blackbox/testdata/probes-in-nested-modules/probes-in-nested-modules.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "a" diff --git a/tests/auto/blackbox/testdata/product-dependencies-by-type/modules/myconfig/myconfig.qbs b/tests/auto/blackbox/testdata/product-dependencies-by-type/modules/myconfig/myconfig.qbs index f3d789842..5bc1fd613 100644 --- a/tests/auto/blackbox/testdata/product-dependencies-by-type/modules/myconfig/myconfig.qbs +++ b/tests/auto/blackbox/testdata/product-dependencies-by-type/modules/myconfig/myconfig.qbs @@ -1,5 +1,3 @@ -import qbs - Module { property bool typeDecider: true } diff --git a/tests/auto/blackbox/testdata/product-dependencies-by-type/product-dependencies-by-type.qbs b/tests/auto/blackbox/testdata/product-dependencies-by-type/product-dependencies-by-type.qbs index 1297a3942..8fa761a2d 100644 --- a/tests/auto/blackbox/testdata/product-dependencies-by-type/product-dependencies-by-type.qbs +++ b/tests/auto/blackbox/testdata/product-dependencies-by-type/product-dependencies-by-type.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Project { diff --git a/tests/auto/blackbox/testdata/productproperties/app.qbs b/tests/auto/blackbox/testdata/productproperties/app.qbs index 405d08adb..b867aec3d 100644 --- a/tests/auto/blackbox/testdata/productproperties/app.qbs +++ b/tests/auto/blackbox/testdata/productproperties/app.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { consoleApplication: true type: "application" diff --git a/tests/auto/blackbox/testdata/productproperties/header.qbs b/tests/auto/blackbox/testdata/productproperties/header.qbs index 5c3e2db63..42f9c88d9 100644 --- a/tests/auto/blackbox/testdata/productproperties/header.qbs +++ b/tests/auto/blackbox/testdata/productproperties/header.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.TextFile Product { diff --git a/tests/auto/blackbox/testdata/productproperties/productproperties.qbs b/tests/auto/blackbox/testdata/productproperties/productproperties.qbs index 75c6224bc..79fdc34a2 100644 --- a/tests/auto/blackbox/testdata/productproperties/productproperties.qbs +++ b/tests/auto/blackbox/testdata/productproperties/productproperties.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { property string blubbProp: "5" references: ["header.qbs", "app.qbs"] diff --git a/tests/auto/blackbox/testdata/project_filepath_check/project1.qbs b/tests/auto/blackbox/testdata/project_filepath_check/project1.qbs index 5fc79d432..253992dd0 100644 --- a/tests/auto/blackbox/testdata/project_filepath_check/project1.qbs +++ b/tests/auto/blackbox/testdata/project_filepath_check/project1.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - CppApplication { files: "main.cpp" } diff --git a/tests/auto/blackbox/testdata/project_filepath_check/project2.qbs b/tests/auto/blackbox/testdata/project_filepath_check/project2.qbs index 9abdac987..8bae2dd60 100644 --- a/tests/auto/blackbox/testdata/project_filepath_check/project2.qbs +++ b/tests/auto/blackbox/testdata/project_filepath_check/project2.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - CppApplication { files: "main2.cpp" } diff --git a/tests/auto/blackbox/testdata/properties-in-export-items/properties-in-export-items.qbs b/tests/auto/blackbox/testdata/properties-in-export-items/properties-in-export-items.qbs index db9f3b2b4..a13578f95 100644 --- a/tests/auto/blackbox/testdata/properties-in-export-items/properties-in-export-items.qbs +++ b/tests/auto/blackbox/testdata/properties-in-export-items/properties-in-export-items.qbs @@ -1,5 +1,3 @@ -import qbs - Project { minimumQbsVersion: "1.6" diff --git a/tests/auto/blackbox/testdata/property-assignment-in-failed-module/modules/m/m.qbs b/tests/auto/blackbox/testdata/property-assignment-in-failed-module/modules/m/m.qbs index 38b15d807..8170c1991 100644 --- a/tests/auto/blackbox/testdata/property-assignment-in-failed-module/modules/m/m.qbs +++ b/tests/auto/blackbox/testdata/property-assignment-in-failed-module/modules/m/m.qbs @@ -1,5 +1,3 @@ -import qbs - Module { property bool doFail Depends { name: "cpp" } diff --git a/tests/auto/blackbox/testdata/property-assignment-in-failed-module/property-assignment-in-failed-module.qbs b/tests/auto/blackbox/testdata/property-assignment-in-failed-module/property-assignment-in-failed-module.qbs index 8a3a6f359..baf315bfc 100644 --- a/tests/auto/blackbox/testdata/property-assignment-in-failed-module/property-assignment-in-failed-module.qbs +++ b/tests/auto/blackbox/testdata/property-assignment-in-failed-module/property-assignment-in-failed-module.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "app" Depends { name: "m"; required: false } diff --git a/tests/auto/blackbox/testdata/property-assignment-on-non-present-module/property-assignment-on-non-present-module.qbs b/tests/auto/blackbox/testdata/property-assignment-on-non-present-module/property-assignment-on-non-present-module.qbs index 4484a2542..a01d6c561 100644 --- a/tests/auto/blackbox/testdata/property-assignment-on-non-present-module/property-assignment-on-non-present-module.qbs +++ b/tests/auto/blackbox/testdata/property-assignment-on-non-present-module/property-assignment-on-non-present-module.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "nein"; required: false } nein.doch: "ohhh!" diff --git a/tests/auto/blackbox/testdata/property-precedence/dep.qbs b/tests/auto/blackbox/testdata/property-precedence/dep.qbs index c464b7d24..9f9668ceb 100644 --- a/tests/auto/blackbox/testdata/property-precedence/dep.qbs +++ b/tests/auto/blackbox/testdata/property-precedence/dep.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "dep" Export { diff --git a/tests/auto/blackbox/testdata/property-precedence/modules/leaf/leaf.qbs b/tests/auto/blackbox/testdata/property-precedence/modules/leaf/leaf.qbs index 1ccc95939..1bfb1a1b8 100644 --- a/tests/auto/blackbox/testdata/property-precedence/modules/leaf/leaf.qbs +++ b/tests/auto/blackbox/testdata/property-precedence/modules/leaf/leaf.qbs @@ -1,16 +1,10 @@ -import qbs - Module { property string scalarProp: "leaf" property stringList listProp: ["leaf"] Rule { inputs: ["rule-input"] - Artifact { - filePath: "dummy" - fileTags: ["rule-output"] - alwaysUpdated: false - } + outputFileTags: "rule-output" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; diff --git a/tests/auto/blackbox/testdata/property-precedence/modules/nonleaf/nonleaf.qbs b/tests/auto/blackbox/testdata/property-precedence/modules/nonleaf/nonleaf.qbs index d67b261c1..a829da09d 100644 --- a/tests/auto/blackbox/testdata/property-precedence/modules/nonleaf/nonleaf.qbs +++ b/tests/auto/blackbox/testdata/property-precedence/modules/nonleaf/nonleaf.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "leaf" } diff --git a/tests/auto/blackbox/testdata/property-precedence/property-precedence.qbs b/tests/auto/blackbox/testdata/property-precedence/property-precedence.qbs index 5246c8a7b..1691376e8 100644 --- a/tests/auto/blackbox/testdata/property-precedence/property-precedence.qbs +++ b/tests/auto/blackbox/testdata/property-precedence/property-precedence.qbs @@ -1,5 +1,3 @@ -import qbs - Project { references: ["dep.qbs"] Product { diff --git a/tests/auto/blackbox/testdata/propertyChanges/modules/TestModule/module.qbs b/tests/auto/blackbox/testdata/propertyChanges/modules/TestModule/module.qbs index 14cdc570e..b1e4a1fdc 100644 --- a/tests/auto/blackbox/testdata/propertyChanges/modules/TestModule/module.qbs +++ b/tests/auto/blackbox/testdata/propertyChanges/modules/TestModule/module.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Module { diff --git a/tests/auto/blackbox/testdata/propertyChanges/propertyChanges.qbs b/tests/auto/blackbox/testdata/propertyChanges/propertyChanges.qbs index da9a862c5..f13b1986e 100644 --- a/tests/auto/blackbox/testdata/propertyChanges/propertyChanges.qbs +++ b/tests/auto/blackbox/testdata/propertyChanges/propertyChanges.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.Environment import qbs.File import qbs.TextFile diff --git a/tests/auto/blackbox/testdata/propertyChanges/ruletest.qbs b/tests/auto/blackbox/testdata/propertyChanges/ruletest.qbs index 21d6f75ef..1d8ea961c 100644 --- a/tests/auto/blackbox/testdata/propertyChanges/ruletest.qbs +++ b/tests/auto/blackbox/testdata/propertyChanges/ruletest.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "ruletest" type: "test-output" diff --git a/tests/auto/blackbox/testdata/protobuf/addressbook.proto b/tests/auto/blackbox/testdata/protobuf/addressbook.proto new file mode 100644 index 000000000..b4b33b4c6 --- /dev/null +++ b/tests/auto/blackbox/testdata/protobuf/addressbook.proto @@ -0,0 +1,51 @@ +// See README.txt for information and build instructions. +// +// Note: START and END tags are used in comments to define sections used in +// tutorials. They are not part of the syntax for Protocol Buffers. +// +// To get an in-depth walkthrough of this file and the related examples, see: +// https://developers.google.com/protocol-buffers/docs/tutorials + +// [START declaration] +syntax = "proto3"; +package tutorial; + +import "google/protobuf/timestamp.proto"; +// [END declaration] + +// [START java_declaration] +option java_package = "com.example.tutorial"; +option java_outer_classname = "AddressBookProtos"; +// [END java_declaration] + +// [START csharp_declaration] +option csharp_namespace = "Google.Protobuf.Examples.AddressBook"; +// [END csharp_declaration] + +// [START messages] +message Person { + string name = 1; + int32 id = 2; // Unique ID number for this person. + string email = 3; + + enum PhoneType { + MOBILE = 0; + HOME = 1; + WORK = 2; + } + + message PhoneNumber { + string number = 1; + PhoneType type = 2; + } + + repeated PhoneNumber phones = 4; + + google.protobuf.Timestamp last_updated = 5; +} + +// Our address book file is just one of these. +message AddressBook { + repeated Person people = 1; +} +// [END messages] diff --git a/tests/auto/blackbox/testdata/protobuf/addressbook_cpp.qbs b/tests/auto/blackbox/testdata/protobuf/addressbook_cpp.qbs new file mode 100644 index 000000000..a5a4caf75 --- /dev/null +++ b/tests/auto/blackbox/testdata/protobuf/addressbook_cpp.qbs @@ -0,0 +1,21 @@ +import qbs + +CppApplication { + name: "addressbook_cpp" + consoleApplication: true + condition: hasProtobuf + + Depends { name: "cpp" } + cpp.cxxLanguageVersion: "c++11" + + Depends { name: "protobuf.cpp"; required: false } + property bool hasProtobuf: { + console.info("has protobuf: " + protobuf.cpp.present); + return protobuf.cpp.present; + } + + files: [ + "addressbook.proto", + "main.cpp", + ] +} diff --git a/tests/auto/blackbox/testdata/protobuf/addressbook_objc.qbs b/tests/auto/blackbox/testdata/protobuf/addressbook_objc.qbs new file mode 100644 index 000000000..be68abfee --- /dev/null +++ b/tests/auto/blackbox/testdata/protobuf/addressbook_objc.qbs @@ -0,0 +1,19 @@ +import qbs + +CppApplication { + name: "addressbook_objc" + consoleApplication: true + condition: hasProtobuf + + Depends { name: "cpp" } + Depends { name: "protobuf.objc"; required: false } + property bool hasProtobuf: { + console.info("has protobuf: " + protobuf.objc.present); + return protobuf.objc.present; + } + + files: [ + "addressbook.proto", + "main.m", + ] +} diff --git a/tests/auto/blackbox/testdata/protobuf/import-main.cpp b/tests/auto/blackbox/testdata/protobuf/import-main.cpp new file mode 100644 index 000000000..6d90cdf16 --- /dev/null +++ b/tests/auto/blackbox/testdata/protobuf/import-main.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Ivan Komissarov +** Contact: abbapoh@gmail.com +** +** This file is part of Qbs. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include <import.pb.h> + +int main() +{ + MyMessage message; + message.set_msg("msg"); + return 0; +} diff --git a/tests/auto/blackbox/testdata/protobuf/import.proto b/tests/auto/blackbox/testdata/protobuf/import.proto new file mode 100644 index 000000000..d11e83b7a --- /dev/null +++ b/tests/auto/blackbox/testdata/protobuf/import.proto @@ -0,0 +1,6 @@ +syntax = "proto2"; +import "subdir/myenum.proto"; + +message MyMessage { + required string msg = 1; +} diff --git a/tests/auto/blackbox/testdata/protobuf/import.qbs b/tests/auto/blackbox/testdata/protobuf/import.qbs new file mode 100644 index 000000000..4c4de063f --- /dev/null +++ b/tests/auto/blackbox/testdata/protobuf/import.qbs @@ -0,0 +1,23 @@ +import qbs + +CppApplication { + name: "app" + consoleApplication: true + condition: hasProtobuf + + protobuf.cpp.importPaths: [sourceDirectory] + + cpp.cxxLanguageVersion: "c++11" + + Depends { name: "protobuf.cpp"; required: false } + property bool hasProtobuf: { + console.info("has protobuf: " + protobuf.cpp.present); + return protobuf.cpp.present; + } + + files: [ + "import.proto", + "import-main.cpp", + "subdir/myenum.proto", + ] +} diff --git a/tests/auto/blackbox/testdata/protobuf/main.cpp b/tests/auto/blackbox/testdata/protobuf/main.cpp new file mode 100644 index 000000000..c93c46717 --- /dev/null +++ b/tests/auto/blackbox/testdata/protobuf/main.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Ivan Komissarov +** Contact: abbapoh@gmail.com +** +** This file is part of Qbs. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include <google/protobuf/util/time_util.h> +#include <string> + +#include "addressbook.pb.h" + +using google::protobuf::util::TimeUtil; + +int main(int /*argc*/, char* /*argv*/[]) { + GOOGLE_PROTOBUF_VERIFY_VERSION; + + tutorial::AddressBook addressBook; + + auto person = addressBook.add_people(); + person->set_name("name"); + person->set_id(1); + person->set_email("email"); + + auto phone_number = person->add_phones(); + phone_number->set_number("number"); + phone_number->set_type(tutorial::Person::MOBILE); + + *person->mutable_last_updated() = TimeUtil::SecondsToTimestamp(time(nullptr)); + + google::protobuf::ShutdownProtobufLibrary(); + + return 0; +} + diff --git a/tests/auto/blackbox/testdata/protobuf/main.m b/tests/auto/blackbox/testdata/protobuf/main.m new file mode 100644 index 000000000..e9d7ce66a --- /dev/null +++ b/tests/auto/blackbox/testdata/protobuf/main.m @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Ivan Komissarov +** Contact: abbapoh@gmail.com +** +** This file is part of Qbs. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#import "Addressbook.pbobjc.h" + +int main(int argc, char* argv[]) +{ + AddressBook *addressBook = [[AddressBook alloc] init]; + + Person *person = [[Person alloc] init]; + person.name = @"name"; + person.id_p = 1; + person.email = @"email"; + + Person_PhoneNumber *number = [[Person_PhoneNumber alloc] init]; + number.number = @"number"; + number.type = Person_PhoneType_Mobile; + + [addressBook.peopleArray addObject:person]; + [addressBook release]; + + return 0; +} diff --git a/tests/auto/blackbox/testdata/protobuf/needs-import-dir-main.cpp b/tests/auto/blackbox/testdata/protobuf/needs-import-dir-main.cpp new file mode 100644 index 000000000..d6faf9e84 --- /dev/null +++ b/tests/auto/blackbox/testdata/protobuf/needs-import-dir-main.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Ivan Komissarov +** Contact: abbapoh@gmail.com +** +** This file is part of Qbs. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include <needs-import-dir.pb.h> + +int main() +{ + MyMessage message; + message.set_msg("msg"); + return 0; +} diff --git a/tests/auto/blackbox/testdata/protobuf/needs-import-dir.proto b/tests/auto/blackbox/testdata/protobuf/needs-import-dir.proto new file mode 100644 index 000000000..0d0cb6578 --- /dev/null +++ b/tests/auto/blackbox/testdata/protobuf/needs-import-dir.proto @@ -0,0 +1,6 @@ +syntax = "proto2"; +import "myenum.proto"; + +message MyMessage { + required string msg = 1; +} diff --git a/tests/auto/blackbox/testdata/protobuf/needs-import-dir.qbs b/tests/auto/blackbox/testdata/protobuf/needs-import-dir.qbs new file mode 100644 index 000000000..788bbc93c --- /dev/null +++ b/tests/auto/blackbox/testdata/protobuf/needs-import-dir.qbs @@ -0,0 +1,24 @@ +import qbs + +CppApplication { + name: "app" + consoleApplication: true + condition: hasProtobuf + + property path theImportDir + protobuf.cpp.importPaths: (theImportDir ? [theImportDir] : []).concat([sourceDirectory]) + + cpp.cxxLanguageVersion: "c++11" + + Depends { name: "protobuf.cpp"; required: false } + property bool hasProtobuf: { + console.info("has protobuf: " + protobuf.cpp.present); + return protobuf.cpp.present; + } + + files: [ + "needs-import-dir.proto", + "needs-import-dir-main.cpp", + "subdir/myenum.proto", + ] +} diff --git a/tests/auto/blackbox/testdata/protobuf/subdir/myenum.proto b/tests/auto/blackbox/testdata/protobuf/subdir/myenum.proto new file mode 100644 index 000000000..0b82869fc --- /dev/null +++ b/tests/auto/blackbox/testdata/protobuf/subdir/myenum.proto @@ -0,0 +1,6 @@ +syntax = "proto2"; + +enum MyEnum { + VAL1 = 0; + VAL2 = 1; +} diff --git a/tests/auto/blackbox/testdata/pseudo-multiplexing/pseudo-multiplexing.qbs b/tests/auto/blackbox/testdata/pseudo-multiplexing/pseudo-multiplexing.qbs index 0639adc8a..88c565ba2 100644 --- a/tests/auto/blackbox/testdata/pseudo-multiplexing/pseudo-multiplexing.qbs +++ b/tests/auto/blackbox/testdata/pseudo-multiplexing/pseudo-multiplexing.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "a" diff --git a/tests/auto/blackbox/testdata/qbsVersion/qbs-version.qbs b/tests/auto/blackbox/testdata/qbsVersion/qbs-version.qbs index d7ef0d68b..ced0f3a33 100644 --- a/tests/auto/blackbox/testdata/qbsVersion/qbs-version.qbs +++ b/tests/auto/blackbox/testdata/qbsVersion/qbs-version.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property string qbsVersion property int qbsVersionMajor diff --git a/tests/auto/blackbox/testdata/rad-after-incomplete-build/project_with_rule.qbs b/tests/auto/blackbox/testdata/rad-after-incomplete-build/project_with_rule.qbs index 42ec452db..ca71ab930 100644 --- a/tests/auto/blackbox/testdata/rad-after-incomplete-build/project_with_rule.qbs +++ b/tests/auto/blackbox/testdata/rad-after-incomplete-build/project_with_rule.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Product { diff --git a/tests/auto/blackbox/testdata/recursive_renaming/recursive_renaming.qbs b/tests/auto/blackbox/testdata/recursive_renaming/recursive_renaming.qbs index 5c2c4ec48..b49e9c53f 100644 --- a/tests/auto/blackbox/testdata/recursive_renaming/recursive_renaming.qbs +++ b/tests/auto/blackbox/testdata/recursive_renaming/recursive_renaming.qbs @@ -1,6 +1,5 @@ -import qbs 1.0 - Product { + qbs.installPrefix: "" Group { qbs.install: true qbs.installSourceBase: "." diff --git a/tests/auto/blackbox/testdata/recursive_wildcards/recursive_wildcards.qbs b/tests/auto/blackbox/testdata/recursive_wildcards/recursive_wildcards.qbs index 703a65e0e..4e9da01d3 100644 --- a/tests/auto/blackbox/testdata/recursive_wildcards/recursive_wildcards.qbs +++ b/tests/auto/blackbox/testdata/recursive_wildcards/recursive_wildcards.qbs @@ -1,8 +1,8 @@ -import qbs import qbs.TextFile Product { type: ["txt.out"] + qbs.installPrefix: "" Group { files: "dir/**" qbs.install: true diff --git a/tests/auto/blackbox/testdata/referenceErrorInExport/referenceErrorInExport.qbs b/tests/auto/blackbox/testdata/referenceErrorInExport/referenceErrorInExport.qbs index 91069f629..d64244f0f 100644 --- a/tests/auto/blackbox/testdata/referenceErrorInExport/referenceErrorInExport.qbs +++ b/tests/auto/blackbox/testdata/referenceErrorInExport/referenceErrorInExport.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { Depends { name: "other" } diff --git a/tests/auto/blackbox/testdata/renameDependency/before/renameDependency.qbs b/tests/auto/blackbox/testdata/renameDependency/before/renameDependency.qbs index e6f3cf66b..d42a760dd 100644 --- a/tests/auto/blackbox/testdata/renameDependency/before/renameDependency.qbs +++ b/tests/auto/blackbox/testdata/renameDependency/before/renameDependency.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: ["*.cpp", "*.h"] } diff --git a/tests/auto/blackbox/testdata/reproducible-build/reproducible-build.qbs b/tests/auto/blackbox/testdata/reproducible-build/reproducible-build.qbs index ebf2ba639..f7ed8e61a 100644 --- a/tests/auto/blackbox/testdata/reproducible-build/reproducible-build.qbs +++ b/tests/auto/blackbox/testdata/reproducible-build/reproducible-build.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { name: "the product" files: ["file1.cpp", "file2.cpp", "main.cpp"] diff --git a/tests/auto/blackbox/testdata/require-deprecated/require.qbs b/tests/auto/blackbox/testdata/require-deprecated/require.qbs index d30a15805..87d8b054b 100644 --- a/tests/auto/blackbox/testdata/require-deprecated/require.qbs +++ b/tests/auto/blackbox/testdata/require-deprecated/require.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import 'blubb.js' as blubb Product { diff --git a/tests/auto/blackbox/testdata/require/require.qbs b/tests/auto/blackbox/testdata/require/require.qbs index d30a15805..87d8b054b 100644 --- a/tests/auto/blackbox/testdata/require/require.qbs +++ b/tests/auto/blackbox/testdata/require/require.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import 'blubb.js' as blubb Product { diff --git a/tests/auto/blackbox/testdata/rescue-transformer-data/modules/m/m.qbs b/tests/auto/blackbox/testdata/rescue-transformer-data/modules/m/m.qbs index 03fdf7a6b..640d2c3b3 100644 --- a/tests/auto/blackbox/testdata/rescue-transformer-data/modules/m/m.qbs +++ b/tests/auto/blackbox/testdata/rescue-transformer-data/modules/m/m.qbs @@ -1,5 +1,3 @@ -import qbs - Module { property bool p diff --git a/tests/auto/blackbox/testdata/rescue-transformer-data/transformer-data-rescue.qbs b/tests/auto/blackbox/testdata/rescue-transformer-data/transformer-data-rescue.qbs index 2eafcc01d..4d266bbd4 100644 --- a/tests/auto/blackbox/testdata/rescue-transformer-data/transformer-data-rescue.qbs +++ b/tests/auto/blackbox/testdata/rescue-transformer-data/transformer-data-rescue.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { type: base.concat(["out"]) Depends { name: "m" } diff --git a/tests/auto/blackbox/testdata/response-files/response-files.qbs b/tests/auto/blackbox/testdata/response-files/response-files.qbs index 73eb720fe..fbb6f0518 100644 --- a/tests/auto/blackbox/testdata/response-files/response-files.qbs +++ b/tests/auto/blackbox/testdata/response-files/response-files.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo import qbs.TextFile @@ -13,6 +12,7 @@ Project { type: ["text"] Depends { name: "cpp" } Depends { name: "cat-response-file" } + qbs.installPrefix: "" Group { fileTagsFilter: ["text"] qbs.install: true diff --git a/tests/auto/blackbox/testdata/retagged-output-artifact/retagged-output-artifact.qbs b/tests/auto/blackbox/testdata/retagged-output-artifact/retagged-output-artifact.qbs new file mode 100644 index 000000000..8af84bcd7 --- /dev/null +++ b/tests/auto/blackbox/testdata/retagged-output-artifact/retagged-output-artifact.qbs @@ -0,0 +1,42 @@ +import qbs.File +import qbs.TextFile + +Product { + name: "p" + type: "p_type" + property bool useTag1 + Rule { + multiplex: true + outputFileTags: ["tag1", "tag2"] + outputArtifacts: [{filePath: "a1.txt", fileTags: product.useTag1 ? "tag1" : "tag2"}] + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "creating " + output.filePath; + cmd.sourceCode = function() { + var f = new TextFile(output.filePath, TextFile.WriteOnly); + f.close(); + }; + return cmd; + } + } + Rule { + inputs: "tag1" + Artifact { filePath: "a2.txt"; fileTags: "p_type" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "creating " + output.filePath; + cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); }; + return cmd; + } + } + Rule { + inputs: "tag2" + Artifact { filePath: "a3.txt"; fileTags: "p_type" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "creating " + output.filePath; + cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); }; + return cmd; + } + } +} diff --git a/tests/auto/blackbox/testdata/rule-connection-with-excluded-inputs/rule-connection-with-excluded-inputs.qbs b/tests/auto/blackbox/testdata/rule-connection-with-excluded-inputs/rule-connection-with-excluded-inputs.qbs new file mode 100644 index 000000000..9d6482f90 --- /dev/null +++ b/tests/auto/blackbox/testdata/rule-connection-with-excluded-inputs/rule-connection-with-excluded-inputs.qbs @@ -0,0 +1,40 @@ +Product { + name: "p" + type: "p_type" + Rule { + multiplex: true + Artifact { filePath: "x.txt"; fileTags: "x" } + Artifact { filePath: "y.txt"; fileTags: "y" } + Artifact { filePath: "p.txt"; fileTags: "p_type" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.silent = true; + cmd.sourceCode = function() {}; + return cmd; + } + } + Rule { + multiplex: true + Artifact { filePath: "x2.txt"; fileTags: "x" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.silent = true; + cmd.sourceCode = function() {}; + return cmd; + } + } + Rule { + multiplex: true + inputs: "x" + excludedInputs: "y" + Artifact { filePath: "dummy"; fileTags: "p_type" } + prepare: { + console.info("inputs.x: " + (inputs.x ? inputs.x.length : 0)); + console.info("inputs.y: " + (inputs.y ? inputs.y.length : 0)); + var cmd = new JavaScriptCommand(); + cmd.silent = true; + cmd.sourceCode = function() {}; + return cmd; + } + } +} diff --git a/tests/auto/blackbox/testdata/rule-with-no-inputs/rule-with-no-inputs.qbs b/tests/auto/blackbox/testdata/rule-with-no-inputs/rule-with-no-inputs.qbs index 6e2bf4430..9c0f01217 100644 --- a/tests/auto/blackbox/testdata/rule-with-no-inputs/rule-with-no-inputs.qbs +++ b/tests/auto/blackbox/testdata/rule-with-no-inputs/rule-with-no-inputs.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Product { diff --git a/tests/auto/blackbox/testdata/rule-with-non-required-inputs/rule-with-non-required-inputs.qbs b/tests/auto/blackbox/testdata/rule-with-non-required-inputs/rule-with-non-required-inputs.qbs index 6719bc69d..1bd9beebf 100644 --- a/tests/auto/blackbox/testdata/rule-with-non-required-inputs/rule-with-non-required-inputs.qbs +++ b/tests/auto/blackbox/testdata/rule-with-non-required-inputs/rule-with-non-required-inputs.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Product { diff --git a/tests/auto/blackbox/testdata/ruleConditions/modules/narfzort/narfzort.qbs b/tests/auto/blackbox/testdata/ruleConditions/modules/narfzort/narfzort.qbs index 187367388..0044537cb 100644 --- a/tests/auto/blackbox/testdata/ruleConditions/modules/narfzort/narfzort.qbs +++ b/tests/auto/blackbox/testdata/ruleConditions/modules/narfzort/narfzort.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.FileInfo import qbs.TextFile diff --git a/tests/auto/blackbox/testdata/ruleConditions/ruleConditions.qbs b/tests/auto/blackbox/testdata/ruleConditions/ruleConditions.qbs index 766bf3c5d..a8f7ffad2 100644 --- a/tests/auto/blackbox/testdata/ruleConditions/ruleConditions.qbs +++ b/tests/auto/blackbox/testdata/ruleConditions/ruleConditions.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import "templates/zorduct.qbs" as Zorduct Project { diff --git a/tests/auto/blackbox/testdata/ruleConditions/templates/zorduct.qbs b/tests/auto/blackbox/testdata/ruleConditions/templates/zorduct.qbs index 8f19a5a6d..cddad8c30 100644 --- a/tests/auto/blackbox/testdata/ruleConditions/templates/zorduct.qbs +++ b/tests/auto/blackbox/testdata/ruleConditions/templates/zorduct.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { type: ["application", "zort"] consoleApplication: true diff --git a/tests/auto/blackbox/testdata/ruleCycle/ruleCycle.qbs b/tests/auto/blackbox/testdata/ruleCycle/ruleCycle.qbs index 6898afeac..1c5d61d95 100644 --- a/tests/auto/blackbox/testdata/ruleCycle/ruleCycle.qbs +++ b/tests/auto/blackbox/testdata/ruleCycle/ruleCycle.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { name: "the cycle of life" diff --git a/tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs b/tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs index b28d7b822..48bdff904 100644 --- a/tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs +++ b/tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "app1" diff --git a/tests/auto/blackbox/testdata/setup-build-environment/modules/buildenv/buildenv.qbs b/tests/auto/blackbox/testdata/setup-build-environment/modules/buildenv/buildenv.qbs index 9beb22393..9213c6469 100644 --- a/tests/auto/blackbox/testdata/setup-build-environment/modules/buildenv/buildenv.qbs +++ b/tests/auto/blackbox/testdata/setup-build-environment/modules/buildenv/buildenv.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Environment Module { diff --git a/tests/auto/blackbox/testdata/setup-build-environment/modules/m/m.qbs b/tests/auto/blackbox/testdata/setup-build-environment/modules/m/m.qbs index 81cf47bcd..74e718c50 100644 --- a/tests/auto/blackbox/testdata/setup-build-environment/modules/m/m.qbs +++ b/tests/auto/blackbox/testdata/setup-build-environment/modules/m/m.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Environment import qbs.TextFile diff --git a/tests/auto/blackbox/testdata/setup-build-environment/setup-build-environment.qbs b/tests/auto/blackbox/testdata/setup-build-environment/setup-build-environment.qbs index 3248815f0..c5a7e87e0 100644 --- a/tests/auto/blackbox/testdata/setup-build-environment/setup-build-environment.qbs +++ b/tests/auto/blackbox/testdata/setup-build-environment/setup-build-environment.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "first_product" diff --git a/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs b/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs index 9f841effd..b5ac8b289 100644 --- a/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs +++ b/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Project { @@ -8,12 +7,11 @@ Project { files: ["lib1.cpp"] - Group { - condition: !qbs.targetOS.contains("darwin") - fileTagsFilter: ["dynamiclibrary", "dynamiclibrary_import"] - qbs.install: true - qbs.installDir: "/lib1" - } + install: !qbs.targetOS.contains("darwin") + installImportLib: true + installDir: "lib1" + importLibInstallDir: installDir + Group { condition: qbs.targetOS.contains("darwin") fileTagsFilter: ["bundle.content"] @@ -41,16 +39,15 @@ Project { files: ["lib3.cpp"] - Properties { + Properties { condition: qbs.targetOS.contains("darwin") bundle.isBundle: false } - Group { - fileTagsFilter: ["dynamiclibrary", "dynamiclibrary_import"] - qbs.install: true - qbs.installDir: "/lib3" - } + install: true + installImportLib: true + installDir: "lib3" + importLibInstallDir: installDir } DynamicLibrary { // Non-dependency, referred to by name @@ -59,16 +56,15 @@ Project { files: ["lib4.cpp"] - Properties { + Properties { condition: qbs.targetOS.contains("darwin") bundle.isBundle: false } - Group { - fileTagsFilter: ["dynamiclibrary", "dynamiclibrary_import"] - qbs.install: true - qbs.installDir: "/lib4" - } + install: true + installImportLib: true + installDir: "lib4" + importLibInstallDir: installDir } DynamicLibrary { // Recursive product dependency diff --git a/tests/auto/blackbox/testdata/smart-relinking/smart-relinking.qbs b/tests/auto/blackbox/testdata/smart-relinking/smart-relinking.qbs index 44d8013b9..aac0692a8 100644 --- a/tests/auto/blackbox/testdata/smart-relinking/smart-relinking.qbs +++ b/tests/auto/blackbox/testdata/smart-relinking/smart-relinking.qbs @@ -1,5 +1,3 @@ -import qbs - Project { minimumQbsVersion: "1.6" Probe { diff --git a/tests/auto/blackbox/testdata/source-artifact-changes/modules/module_with_files/main.cpp b/tests/auto/blackbox/testdata/source-artifact-changes/modules/module_with_files/main.cpp new file mode 100644 index 000000000..237c8ce18 --- /dev/null +++ b/tests/auto/blackbox/testdata/source-artifact-changes/modules/module_with_files/main.cpp @@ -0,0 +1 @@ +int main() {} diff --git a/tests/auto/blackbox/testdata/source-artifact-changes/modules/module_with_files/module_with_files.qbs b/tests/auto/blackbox/testdata/source-artifact-changes/modules/module_with_files/module_with_files.qbs new file mode 100644 index 000000000..514248d27 --- /dev/null +++ b/tests/auto/blackbox/testdata/source-artifact-changes/modules/module_with_files/module_with_files.qbs @@ -0,0 +1,15 @@ +Module { + property stringList fileTags + property bool overrideTags + property bool filesAreTargets + + Depends { name: "cpp" } + + Group { + prefix: path + '/' + files: "main.cpp" + fileTags: product.module_with_files.fileTags + overrideTags: product.module_with_files.overrideTags + filesAreTargets: product.module_with_files.filesAreTargets + } +} diff --git a/tests/auto/blackbox/testdata/source-artifact-changes/source-artifact-changes.qbs b/tests/auto/blackbox/testdata/source-artifact-changes/source-artifact-changes.qbs new file mode 100644 index 000000000..de56376df --- /dev/null +++ b/tests/auto/blackbox/testdata/source-artifact-changes/source-artifact-changes.qbs @@ -0,0 +1,56 @@ +CppApplication { + name: "app" + type: base.concat("dummy") + consoleApplication: true + + Properties { + condition: qbs.targetOS.contains("darwin") + bundle.embedInfoPlist: false + } + + Probe { + id: toolchainProbe + property stringList toolchain: qbs.toolchain + configure: { + console.info("is gcc: " + toolchain.contains("gcc")); + found = true; + } + } + + Rule { + multiplex: true + inputs: "cpp" + Artifact { + filePath: "dummy" + fileTags: "dummy" + cpp.cxxLanguageVersion: "hoppla" + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.silent = true; + cmd.sourceCode = function() { + if (output.cpp.cxxLanguageVersion !== "hoppla") + throw "This cannot be!"; + }; + return cmd; + } + } + + Rule { + multiplex: true + inputs: "cpp" + requiresInputs: false + Artifact { filePath: "dummy2"; fileTags: "dummy" } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.silent = true; + cmd.sourceCode = function() { + console.info("cpp artifacts: " + + (product.artifacts.cpp ? product.artifacts.cpp.length : 0)) + }; + return cmd; + } + } + + Depends { name: "module_with_files" } +} diff --git a/tests/auto/blackbox/testdata/source-artifact-in-inputs-from-dependencies/source-artifact-in-inputs-from-dependencies.qbs b/tests/auto/blackbox/testdata/source-artifact-in-inputs-from-dependencies/source-artifact-in-inputs-from-dependencies.qbs index ef038a687..3486667f9 100644 --- a/tests/auto/blackbox/testdata/source-artifact-in-inputs-from-dependencies/source-artifact-in-inputs-from-dependencies.qbs +++ b/tests/auto/blackbox/testdata/source-artifact-in-inputs-from-dependencies/source-artifact-in-inputs-from-dependencies.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo import qbs.TextFile diff --git a/tests/auto/blackbox/testdata/soversion/soversion.qbs b/tests/auto/blackbox/testdata/soversion/soversion.qbs index d024c25b9..6ce2144c0 100644 --- a/tests/auto/blackbox/testdata/soversion/soversion.qbs +++ b/tests/auto/blackbox/testdata/soversion/soversion.qbs @@ -1,5 +1,3 @@ -import qbs - DynamicLibrary { name: "mylib" property bool useVersion diff --git a/tests/auto/blackbox/testdata/static-lib-without-sources/static-lib-without-sources.qbs b/tests/auto/blackbox/testdata/static-lib-without-sources/static-lib-without-sources.qbs index 6109b428c..32a58c94b 100644 --- a/tests/auto/blackbox/testdata/static-lib-without-sources/static-lib-without-sources.qbs +++ b/tests/auto/blackbox/testdata/static-lib-without-sources/static-lib-without-sources.qbs @@ -1,5 +1,3 @@ -import qbs - Project { StaticLibrary { name: "a" diff --git a/tests/auto/blackbox/testdata/subprofile-change-tracking/subprofile-change-tracking.qbs b/tests/auto/blackbox/testdata/subprofile-change-tracking/subprofile-change-tracking.qbs index b3fba23fe..8abd12869 100644 --- a/tests/auto/blackbox/testdata/subprofile-change-tracking/subprofile-change-tracking.qbs +++ b/tests/auto/blackbox/testdata/subprofile-change-tracking/subprofile-change-tracking.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "app1"; files: ["main1.cpp"] } CppApplication { diff --git a/tests/auto/blackbox/testdata/successive-changes/successive-changes.qbs b/tests/auto/blackbox/testdata/successive-changes/successive-changes.qbs index f42ca4096..77df81e39 100644 --- a/tests/auto/blackbox/testdata/successive-changes/successive-changes.qbs +++ b/tests/auto/blackbox/testdata/successive-changes/successive-changes.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Project { diff --git a/tests/auto/blackbox/testdata/suspicious-calls/copy-command.qbs b/tests/auto/blackbox/testdata/suspicious-calls/copy-command.qbs index e01435fc0..3d43ef1f5 100644 --- a/tests/auto/blackbox/testdata/suspicious-calls/copy-command.qbs +++ b/tests/auto/blackbox/testdata/suspicious-calls/copy-command.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Product { @@ -9,10 +8,7 @@ Product { } Rule { inputs: ["in"] - Artifact { - filePath: "dummy.txt" - fileTags: ["out"] - } + outputFileTags: "out" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; diff --git a/tests/auto/blackbox/testdata/suspicious-calls/copy-eval.qbs b/tests/auto/blackbox/testdata/suspicious-calls/copy-eval.qbs index 93bfca81d..b074c00cf 100644 --- a/tests/auto/blackbox/testdata/suspicious-calls/copy-eval.qbs +++ b/tests/auto/blackbox/testdata/suspicious-calls/copy-eval.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Product { diff --git a/tests/auto/blackbox/testdata/suspicious-calls/copy-prepare.qbs b/tests/auto/blackbox/testdata/suspicious-calls/copy-prepare.qbs index b6098e8de..0408c9d5a 100644 --- a/tests/auto/blackbox/testdata/suspicious-calls/copy-prepare.qbs +++ b/tests/auto/blackbox/testdata/suspicious-calls/copy-prepare.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Product { @@ -9,10 +8,7 @@ Product { } Rule { inputs: ["in"] - Artifact { - filePath: "dummy.txt" - fileTags: ["out"] - } + outputFileTags: "out" prepare: { File.copy(input.filePath, output.filePath); var cmd = new JavaScriptCommand(); diff --git a/tests/auto/blackbox/testdata/suspicious-calls/copy-probe.qbs b/tests/auto/blackbox/testdata/suspicious-calls/copy-probe.qbs index dd97839c2..f47b204d5 100644 --- a/tests/auto/blackbox/testdata/suspicious-calls/copy-probe.qbs +++ b/tests/auto/blackbox/testdata/suspicious-calls/copy-probe.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Product { diff --git a/tests/auto/blackbox/testdata/suspicious-calls/direntries-command.qbs b/tests/auto/blackbox/testdata/suspicious-calls/direntries-command.qbs index d15351c25..c20d6f2ef 100644 --- a/tests/auto/blackbox/testdata/suspicious-calls/direntries-command.qbs +++ b/tests/auto/blackbox/testdata/suspicious-calls/direntries-command.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Product { @@ -9,10 +8,7 @@ Product { } Rule { inputs: ["in"] - Artifact { - filePath: "dummy.txt" - fileTags: ["out"] - } + outputFileTags: "out" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; diff --git a/tests/auto/blackbox/testdata/suspicious-calls/direntries-eval.qbs b/tests/auto/blackbox/testdata/suspicious-calls/direntries-eval.qbs index 4cd0d634e..2a759d93a 100644 --- a/tests/auto/blackbox/testdata/suspicious-calls/direntries-eval.qbs +++ b/tests/auto/blackbox/testdata/suspicious-calls/direntries-eval.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Product { diff --git a/tests/auto/blackbox/testdata/suspicious-calls/direntries-prepare.qbs b/tests/auto/blackbox/testdata/suspicious-calls/direntries-prepare.qbs index 6f7320110..7b39a8969 100644 --- a/tests/auto/blackbox/testdata/suspicious-calls/direntries-prepare.qbs +++ b/tests/auto/blackbox/testdata/suspicious-calls/direntries-prepare.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Product { @@ -9,10 +8,7 @@ Product { } Rule { inputs: ["in"] - Artifact { - filePath: "dummy.txt" - fileTags: ["out"] - } + outputFileTags: "out" prepare: { var dummy = File.directoryEntries(product.sourceDirectory, File.Files); var cmd = new JavaScriptCommand(); diff --git a/tests/auto/blackbox/testdata/suspicious-calls/direntries-probe.qbs b/tests/auto/blackbox/testdata/suspicious-calls/direntries-probe.qbs index d2c8b8ded..fff82df81 100644 --- a/tests/auto/blackbox/testdata/suspicious-calls/direntries-probe.qbs +++ b/tests/auto/blackbox/testdata/suspicious-calls/direntries-probe.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.File Product { diff --git a/tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs b/tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs index 624b1abb0..2d3d64b00 100644 --- a/tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs +++ b/tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Project { diff --git a/tests/auto/blackbox/testdata/symlink-removal/symlink-removal.qbs b/tests/auto/blackbox/testdata/symlink-removal/symlink-removal.qbs index fc47c450f..4aa36142d 100644 --- a/tests/auto/blackbox/testdata/symlink-removal/symlink-removal.qbs +++ b/tests/auto/blackbox/testdata/symlink-removal/symlink-removal.qbs @@ -1,14 +1,10 @@ -import qbs import qbs.File Product { type: "removal" Rule { multiplex: true - Artifact { - filePath: "dummy" - fileTags: product.type - } + outputFileTags: "removal" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; diff --git a/tests/auto/blackbox/testdata/system-include-paths/system-include-paths.qbs b/tests/auto/blackbox/testdata/system-include-paths/system-include-paths.qbs index 081d40202..9c644fc2a 100644 --- a/tests/auto/blackbox/testdata/system-include-paths/system-include-paths.qbs +++ b/tests/auto/blackbox/testdata/system-include-paths/system-include-paths.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { files: ["main.cpp"] cpp.systemIncludePaths: ["subdir"] diff --git a/tests/auto/blackbox/testdata/system-run-paths/system-run-paths.qbs b/tests/auto/blackbox/testdata/system-run-paths/system-run-paths.qbs index 81778d6f7..6e2137173 100644 --- a/tests/auto/blackbox/testdata/system-run-paths/system-run-paths.qbs +++ b/tests/auto/blackbox/testdata/system-run-paths/system-run-paths.qbs @@ -1,11 +1,10 @@ -import qbs - Project { property bool setRunPaths Product { name: "theLib" type: ["dynamiclibrary"] Depends { name: "cpp" } + qbs.installPrefix: "" Group { fileTagsFilter: product.type qbs.install: true diff --git a/tests/auto/blackbox/testdata/texttemplate/cdefgabc.txt.in b/tests/auto/blackbox/testdata/texttemplate/cdefgabc.txt.in new file mode 100644 index 000000000..9e3a753bc --- /dev/null +++ b/tests/auto/blackbox/testdata/texttemplate/cdefgabc.txt.in @@ -0,0 +1 @@ +${c} ${d} ${e} ${f} ${g} ${a} ${b} ${c} diff --git a/tests/auto/blackbox/testdata/texttemplate/expected/lalala.txt b/tests/auto/blackbox/testdata/texttemplate/expected/lalala.txt new file mode 100644 index 000000000..c47434717 --- /dev/null +++ b/tests/auto/blackbox/testdata/texttemplate/expected/lalala.txt @@ -0,0 +1 @@ +do re mi fa so la ti do diff --git a/tests/auto/blackbox/testdata/texttemplate/expected/output.txt b/tests/auto/blackbox/testdata/texttemplate/expected/output.txt new file mode 100644 index 000000000..5c4b1a82a --- /dev/null +++ b/tests/auto/blackbox/testdata/texttemplate/expected/output.txt @@ -0,0 +1,12 @@ +foo bar baz +fu bar baz +foo BAR baz +foo bar buzz +fu BAR baz +fu bar buzz +fu BAR buzz +fooBARbaz +foo\BARbaz +foo\\BARbaz +foo\\\BARbaz +foo${bar}baz diff --git a/tests/auto/blackbox/testdata/texttemplate/output.txt.in b/tests/auto/blackbox/testdata/texttemplate/output.txt.in new file mode 100644 index 000000000..f5f645b73 --- /dev/null +++ b/tests/auto/blackbox/testdata/texttemplate/output.txt.in @@ -0,0 +1,12 @@ +foo bar baz +${foo} bar baz +foo ${bar} baz +foo bar ${baz} +${foo} ${bar} baz +${foo} bar ${baz} +${foo} ${bar} ${baz} +foo${bar}baz +foo\${bar}baz +foo\\${bar}baz +foo\\\${bar}baz +foo${$}{bar}baz diff --git a/tests/auto/blackbox/testdata/texttemplate/texttemplatetest.qbs b/tests/auto/blackbox/testdata/texttemplate/texttemplatetest.qbs new file mode 100644 index 000000000..6abda64f9 --- /dev/null +++ b/tests/auto/blackbox/testdata/texttemplate/texttemplatetest.qbs @@ -0,0 +1,24 @@ +Product { + name: "one" + type: ["text"] + files: ["output.txt.in"] + Depends { name: "texttemplate" } + texttemplate.dict: ({ + foo: "fu", + bar: "BAR", + baz: "buzz", + }) + Group { + files: ["cdefgabc.txt.in"] + texttemplate.outputFileName: "lalala.txt" + texttemplate.dict: ({ + c: "do", + d: "re", + e: "mi", + f: "fa", + g: "so", + a: "la", + b: "ti", + }) + } +} diff --git a/tests/auto/blackbox/testdata/toplevel-searchpath/qbs-resources/imports/MyProduct.qbs b/tests/auto/blackbox/testdata/toplevel-searchpath/qbs-resources/imports/MyProduct.qbs index 6d16a3c53..86718b571 100644 --- a/tests/auto/blackbox/testdata/toplevel-searchpath/qbs-resources/imports/MyProduct.qbs +++ b/tests/auto/blackbox/testdata/toplevel-searchpath/qbs-resources/imports/MyProduct.qbs @@ -1,3 +1 @@ -import qbs - Product { } diff --git a/tests/auto/blackbox/testdata/toplevel-searchpath/toplevel-searchpath.qbs b/tests/auto/blackbox/testdata/toplevel-searchpath/toplevel-searchpath.qbs index 2dd54a81f..8ca6cfca9 100644 --- a/tests/auto/blackbox/testdata/toplevel-searchpath/toplevel-searchpath.qbs +++ b/tests/auto/blackbox/testdata/toplevel-searchpath/toplevel-searchpath.qbs @@ -1,3 +1 @@ -import qbs - MyProduct { } diff --git a/tests/auto/blackbox/testdata/trackAddFile/after/trackAddFile.qbs b/tests/auto/blackbox/testdata/trackAddFile/after/trackAddFile.qbs index 469aff097..f4b9ba21f 100644 --- a/tests/auto/blackbox/testdata/trackAddFile/after/trackAddFile.qbs +++ b/tests/auto/blackbox/testdata/trackAddFile/after/trackAddFile.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { name: 'someapp' diff --git a/tests/auto/blackbox/testdata/trackAddFile/before/trackAddFile.qbs b/tests/auto/blackbox/testdata/trackAddFile/before/trackAddFile.qbs index fc647cdbe..bb0ab7d44 100644 --- a/tests/auto/blackbox/testdata/trackAddFile/before/trackAddFile.qbs +++ b/tests/auto/blackbox/testdata/trackAddFile/before/trackAddFile.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { name: 'someapp' diff --git a/tests/auto/blackbox/testdata/trackExternalProductChanges/trackExternalProductChanges.qbs b/tests/auto/blackbox/testdata/trackExternalProductChanges/trackExternalProductChanges.qbs index 232c8ea41..534f49ff2 100644 --- a/tests/auto/blackbox/testdata/trackExternalProductChanges/trackExternalProductChanges.qbs +++ b/tests/auto/blackbox/testdata/trackExternalProductChanges/trackExternalProductChanges.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Environment import "fileList.js" as FileList diff --git a/tests/auto/blackbox/testdata/trackFileTags/after/trackFileTags.qbs b/tests/auto/blackbox/testdata/trackFileTags/after/trackFileTags.qbs index c0e5c4715..869ce238b 100644 --- a/tests/auto/blackbox/testdata/trackFileTags/after/trackFileTags.qbs +++ b/tests/auto/blackbox/testdata/trackFileTags/after/trackFileTags.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.TextFile Project { diff --git a/tests/auto/blackbox/testdata/trackFileTags/before/trackFileTags.qbs b/tests/auto/blackbox/testdata/trackFileTags/before/trackFileTags.qbs index 7ac895c5f..ebe31bf26 100644 --- a/tests/auto/blackbox/testdata/trackFileTags/before/trackFileTags.qbs +++ b/tests/auto/blackbox/testdata/trackFileTags/before/trackFileTags.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.TextFile Project { diff --git a/tests/auto/blackbox/testdata/trackProducts/after/product3.qbs b/tests/auto/blackbox/testdata/trackProducts/after/product3.qbs index 4dac755c0..bd9cdc009 100644 --- a/tests/auto/blackbox/testdata/trackProducts/after/product3.qbs +++ b/tests/auto/blackbox/testdata/trackProducts/after/product3.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { Depends { name: "cpp" } type: "application" diff --git a/tests/auto/blackbox/testdata/trackProducts/after/trackProducts.qbs b/tests/auto/blackbox/testdata/trackProducts/after/trackProducts.qbs index 343405c08..2935ed1df 100644 --- a/tests/auto/blackbox/testdata/trackProducts/after/trackProducts.qbs +++ b/tests/auto/blackbox/testdata/trackProducts/after/trackProducts.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { name: "trackProducts" diff --git a/tests/auto/blackbox/testdata/trackProducts/before/product1.qbs b/tests/auto/blackbox/testdata/trackProducts/before/product1.qbs index 60e8b0924..48176c809 100644 --- a/tests/auto/blackbox/testdata/trackProducts/before/product1.qbs +++ b/tests/auto/blackbox/testdata/trackProducts/before/product1.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { Depends { name: "cpp" } type: "application" diff --git a/tests/auto/blackbox/testdata/trackProducts/before/product2.qbs b/tests/auto/blackbox/testdata/trackProducts/before/product2.qbs index 5490b8844..be250486d 100644 --- a/tests/auto/blackbox/testdata/trackProducts/before/product2.qbs +++ b/tests/auto/blackbox/testdata/trackProducts/before/product2.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { Depends { name: "cpp" } type: "application" diff --git a/tests/auto/blackbox/testdata/trackProducts/before/trackProducts.qbs b/tests/auto/blackbox/testdata/trackProducts/before/trackProducts.qbs index 6d5555c68..8b5edb6bf 100644 --- a/tests/auto/blackbox/testdata/trackProducts/before/trackProducts.qbs +++ b/tests/auto/blackbox/testdata/trackProducts/before/trackProducts.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { name: "trackProducts" diff --git a/tests/auto/blackbox/testdata/transitive-optional-dependencies/modules/a/a.qbs b/tests/auto/blackbox/testdata/transitive-optional-dependencies/modules/a/a.qbs index adec14e41..ffe7ef70a 100644 --- a/tests/auto/blackbox/testdata/transitive-optional-dependencies/modules/a/a.qbs +++ b/tests/auto/blackbox/testdata/transitive-optional-dependencies/modules/a/a.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "b"; required: false } } diff --git a/tests/auto/blackbox/testdata/transitive-optional-dependencies/modules/b/b.qbs b/tests/auto/blackbox/testdata/transitive-optional-dependencies/modules/b/b.qbs index fb38b600a..ba08b862b 100644 --- a/tests/auto/blackbox/testdata/transitive-optional-dependencies/modules/b/b.qbs +++ b/tests/auto/blackbox/testdata/transitive-optional-dependencies/modules/b/b.qbs @@ -1,5 +1,3 @@ -import qbs - Module { condition: false } diff --git a/tests/auto/blackbox/testdata/transitive-optional-dependencies/transitive-optional-dependencies.qbs b/tests/auto/blackbox/testdata/transitive-optional-dependencies/transitive-optional-dependencies.qbs index 08860b057..6171fa94f 100644 --- a/tests/auto/blackbox/testdata/transitive-optional-dependencies/transitive-optional-dependencies.qbs +++ b/tests/auto/blackbox/testdata/transitive-optional-dependencies/transitive-optional-dependencies.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "a" } } diff --git a/tests/auto/blackbox/testdata/typescript/typescript.qbs b/tests/auto/blackbox/testdata/typescript/typescript.qbs index b6604830f..28c62eb45 100644 --- a/tests/auto/blackbox/testdata/typescript/typescript.qbs +++ b/tests/auto/blackbox/testdata/typescript/typescript.qbs @@ -1,5 +1,3 @@ -import qbs - Project { NodeJSApplication { Depends { name: "typescript" } diff --git a/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/usings-as-sole-inputs-non-multiplexed.qbs b/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/usings-as-sole-inputs-non-multiplexed.qbs index 7d4087620..cd2d23895 100644 --- a/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/usings-as-sole-inputs-non-multiplexed.qbs +++ b/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/usings-as-sole-inputs-non-multiplexed.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo import qbs.TextFile diff --git a/tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs b/tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs index b919f84eb..b6e025e4c 100644 --- a/tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs +++ b/tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs @@ -1,5 +1,3 @@ -import qbs - StaticLibrary { name: "l" @@ -22,11 +20,8 @@ StaticLibrary { cpp.staticLibraryPrefix: "lib" cpp.staticLibrarySuffix: ".ext" - Group { - fileTagsFilter: ["staticlibrary"] - qbs.install: true - qbs.installDir: "lib" - } + qbs.installPrefix: "" + install: true Depends { name: "cpp" } diff --git a/tests/auto/blackbox/testdata/vcs/vcstest.qbs b/tests/auto/blackbox/testdata/vcs/vcstest.qbs index 11d001743..5d359e2c7 100644 --- a/tests/auto/blackbox/testdata/vcs/vcstest.qbs +++ b/tests/auto/blackbox/testdata/vcs/vcstest.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { Depends { name: "vcs" } vcs.headerFileName: "my-repo-state.h" diff --git a/tests/auto/blackbox/testdata/versioncheck/modules/higher/higher.qbs b/tests/auto/blackbox/testdata/versioncheck/modules/higher/higher.qbs index 4a9c85ceb..c5ab20f58 100644 --- a/tests/auto/blackbox/testdata/versioncheck/modules/higher/higher.qbs +++ b/tests/auto/blackbox/testdata/versioncheck/modules/higher/higher.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "lower" diff --git a/tests/auto/blackbox/testdata/versioncheck/modules/lower/lower.qbs b/tests/auto/blackbox/testdata/versioncheck/modules/lower/lower.qbs index 9322b53b1..cd8c6471d 100644 --- a/tests/auto/blackbox/testdata/versioncheck/modules/lower/lower.qbs +++ b/tests/auto/blackbox/testdata/versioncheck/modules/lower/lower.qbs @@ -1,3 +1 @@ -import qbs - Module { } diff --git a/tests/auto/blackbox/testdata/versioncheck/versioncheck.qbs b/tests/auto/blackbox/testdata/versioncheck/versioncheck.qbs index 8214428f1..63bef1d75 100644 --- a/tests/auto/blackbox/testdata/versioncheck/versioncheck.qbs +++ b/tests/auto/blackbox/testdata/versioncheck/versioncheck.qbs @@ -1,5 +1,3 @@ -import qbs - Product { property string requestedMinVersion property string requestedMaxVersion diff --git a/tests/auto/blackbox/testdata/versionscript/versionscript.qbs b/tests/auto/blackbox/testdata/versionscript/versionscript.qbs index 0309d3e06..cc5c7b1cc 100644 --- a/tests/auto/blackbox/testdata/versionscript/versionscript.qbs +++ b/tests/auto/blackbox/testdata/versionscript/versionscript.qbs @@ -1,5 +1,3 @@ -import qbs - DynamicLibrary { type: base.concat("custom") Depends { name: "cpp" } @@ -12,10 +10,7 @@ DynamicLibrary { Rule { multiplex: true - Artifact { - filePath: "dummy.txt" - fileTags: ["custom"] - } + outputFileTags: "custom" prepare: { var cmd = new JavaScriptCommand(); cmd.silent = true; @@ -26,8 +21,7 @@ DynamicLibrary { } } - Group { - fileTagsFilter: ["dynamiclibrary"] - qbs.install: true - } + qbs.installPrefix: "" + install: true + installDir: "" } diff --git a/tests/auto/blackbox/testdata/whole-archive/whole-archive.qbs b/tests/auto/blackbox/testdata/whole-archive/whole-archive.qbs index 4ab93af28..f3bcff2cd 100644 --- a/tests/auto/blackbox/testdata/whole-archive/whole-archive.qbs +++ b/tests/auto/blackbox/testdata/whole-archive/whole-archive.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities Project { diff --git a/tests/auto/blackbox/testdata/wildcard_renaming/wildcard_renaming.qbs b/tests/auto/blackbox/testdata/wildcard_renaming/wildcard_renaming.qbs index 4cb2c071c..124161880 100644 --- a/tests/auto/blackbox/testdata/wildcard_renaming/wildcard_renaming.qbs +++ b/tests/auto/blackbox/testdata/wildcard_renaming/wildcard_renaming.qbs @@ -1,6 +1,5 @@ -import qbs 1.0 - Product { + qbs.installPrefix: "" Group { qbs.install: true files: "*" diff --git a/tests/auto/blackbox/testdata/wildcards-and-rules/wildcards-and-rules.qbs b/tests/auto/blackbox/testdata/wildcards-and-rules/wildcards-and-rules.qbs index 88fadd3a5..f6662529d 100644 --- a/tests/auto/blackbox/testdata/wildcards-and-rules/wildcards-and-rules.qbs +++ b/tests/auto/blackbox/testdata/wildcards-and-rules/wildcards-and-rules.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Product { diff --git a/tests/auto/blackbox/testdata/wix/WiXInstallers.qbs b/tests/auto/blackbox/testdata/wix/WiXInstallers.qbs index eabb6da1e..07f61ba2c 100644 --- a/tests/auto/blackbox/testdata/wix/WiXInstallers.qbs +++ b/tests/auto/blackbox/testdata/wix/WiXInstallers.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.FileInfo Project { diff --git a/tests/auto/blackbox/testdata/wixDependencies/wixDependencies.qbs b/tests/auto/blackbox/testdata/wixDependencies/wixDependencies.qbs index 2d9763ef1..d42a18054 100644 --- a/tests/auto/blackbox/testdata/wixDependencies/wixDependencies.qbs +++ b/tests/auto/blackbox/testdata/wixDependencies/wixDependencies.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.TextFile Project { @@ -35,7 +34,7 @@ Project { // This rule tries to provoke the installer into building too early (and the test // verifies that it does not) by causing the build of the installables to take // a lot longer. - inputs: ["qbs"] + multiplex: true outputFileTags: ["c"] outputArtifacts: { var artifacts = []; diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index 598836c81..de0e2c26d 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -259,6 +259,19 @@ void TestBlackbox::tar() QCOMPARE(listContents.readAllStandardOutput(), listFile.readAll()); } +void TestBlackbox::textTemplate() +{ + QVERIFY(QDir::setCurrent(testDataDir + "/texttemplate")); + rmDirR(relativeBuildDir()); + QCOMPARE(runQbs(), 0); + QString outputFilePath = relativeProductBuildDir("one") + "/output.txt"; + QString expectedOutputFilePath = QFINDTESTDATA("expected/output.txt"); + TEXT_FILE_COMPARE(outputFilePath, expectedOutputFilePath); + outputFilePath = relativeProductBuildDir("one") + "/lalala.txt"; + expectedOutputFilePath = QFINDTESTDATA("expected/lalala.txt"); + TEXT_FILE_COMPARE(outputFilePath, expectedOutputFilePath); +} + static QStringList sortedFileList(const QByteArray &ba) { auto list = QString::fromUtf8(ba).split(QRegExp("[\r\n]"), QString::SkipEmptyParts); @@ -329,12 +342,15 @@ TestBlackbox::TestBlackbox() : TestBlackboxBase (SRCDIR "/testdata", "blackbox") void TestBlackbox::addFileTagToGeneratedArtifact() { QDir::setCurrent(testDataDir + "/add-filetag-to-generated-artifact"); - QCOMPARE(runQbs(), 0); + QCOMPARE(runQbs(QStringList("project.enableTagging:true")), 0); QVERIFY2(m_qbsStdout.contains("compressing my_app"), m_qbsStdout.constData()); const QString compressedAppFilePath = relativeProductBuildDir("my_compressed_app") + '/' + qbs::Internal::HostOsInfo::appendExecutableSuffix("compressed-my_app"); QVERIFY(regularFileExists(compressedAppFilePath)); + QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("project.enableTagging:false"))), 0); + QCOMPARE(runQbs(), 0); + QVERIFY(!regularFileExists(compressedAppFilePath)); } void TestBlackbox::alwaysRun() @@ -392,7 +408,7 @@ void TestBlackbox::artifactsMapChangeTracking() const QString projectFile("artifacts-map-change-tracking.qbs"); REPLACE_IN_FILE(projectFile, "TheBinary", "TheNewBinary"); QCOMPARE(runQbs(QStringList{"-p", "TheApp"}), 0); - QEXPECT_FAIL("", "change tracking could become even more fine-grained", Continue); + QVERIFY2(!m_qbsStdout.contains("running rule for test.cpp"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("creating test.cpp"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("linking"), m_qbsStdout.constData()); @@ -473,11 +489,7 @@ void TestBlackbox::artifactsMapInvalidation() const QString projectDir = testDataDir + "/artifacts-map-invalidation"; QDir::setCurrent(projectDir); QCOMPARE(runQbs(), 0); - QFile sourceFile("file.in"); - QVERIFY2(sourceFile.open(QIODevice::ReadOnly), qPrintable(sourceFile.errorString())); - QFile generatedFile(relativeProductBuildDir("p") + "/myfile.out"); - QVERIFY2(generatedFile.open(QIODevice::ReadOnly), qPrintable(generatedFile.errorString())); - QCOMPARE(sourceFile.readAll(), generatedFile.readAll()); + TEXT_FILE_COMPARE(relativeProductBuildDir("p") + "/myfile.out", "file.in"); } void TestBlackbox::artifactsMapRaceCondition() @@ -720,6 +732,19 @@ void TestBlackbox::changedFiles() QVERIFY2(m_qbsStdout.contains("file1.cpp"), m_qbsStdout.constData()); } +void TestBlackbox::changedInputsFromDependencies() +{ + QDir::setCurrent(testDataDir + "/changed-inputs-from-dependencies"); + QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.contains("final prepare script"), m_qbsStdout.constData()); + QCOMPARE(runQbs(), 0); + QVERIFY2(!m_qbsStdout.contains("final prepare script"), m_qbsStdout.constData()); + WAIT_FOR_NEW_TIMESTAMP(); + touch("input.txt"); + QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.contains("final prepare script"), m_qbsStdout.constData()); +} + void TestBlackbox::changedRuleInputs() { QDir::setCurrent(testDataDir + "/changed-rule-inputs"); @@ -2217,7 +2242,7 @@ void TestBlackbox::referenceErrorInExport() params.expectFailure = true; QVERIFY(runQbs(params) != 0); QVERIFY(m_qbsStderr.contains( - "referenceErrorInExport.qbs:17:12 ReferenceError: Can't find variable: includePaths")); + "referenceErrorInExport.qbs:15:12 ReferenceError: Can't find variable: includePaths")); } void TestBlackbox::reproducibleBuild() @@ -2278,6 +2303,29 @@ void TestBlackbox::responseFiles() QCOMPARE(lines, expected); } +void TestBlackbox::retaggedOutputArtifact() +{ + QDir::setCurrent(testDataDir + "/retagged-output-artifact"); + QbsRunParameters resolveParams("resolve"); + resolveParams.arguments = QStringList("products.p.useTag1:true"); + QCOMPARE(runQbs(resolveParams), 0); + QCOMPARE(runQbs(), 0); + const QString a2 = relativeProductBuildDir("p") + "/a2.txt"; + const QString a3 = relativeProductBuildDir("p") + "/a3.txt"; + QVERIFY2(QFile::exists(a2), qPrintable(a2)); + QVERIFY2(!QFile::exists(a3), qPrintable(a3)); + resolveParams.arguments = QStringList("products.p.useTag1:false"); + QCOMPARE(runQbs(resolveParams), 0); + QCOMPARE(runQbs(), 0); + QVERIFY2(!QFile::exists(a2), qPrintable(a2)); + QVERIFY2(QFile::exists(a3), qPrintable(a3)); + resolveParams.arguments = QStringList("products.p.useTag1:true"); + QCOMPARE(runQbs(resolveParams), 0); + QCOMPARE(runQbs(), 0); + QVERIFY2(QFile::exists(a2), qPrintable(a2)); + QVERIFY2(!QFile::exists(a3), qPrintable(a3)); +} + void TestBlackbox::ruleConditions() { QDir::setCurrent(testDataDir + "/ruleConditions"); @@ -2288,6 +2336,14 @@ void TestBlackbox::ruleConditions() QVERIFY(!QFileInfo(relativeProductBuildDir("unzorted") + "/unzorted.foo.narf.zort").exists()); } +void TestBlackbox::ruleConnectionWithExcludedInputs() +{ + QDir::setCurrent(testDataDir + "/rule-connection-with-excluded-inputs"); + QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.contains("inputs.x: 2") && m_qbsStdout.contains("inputs.y: 0"), + m_qbsStdout.constData()); +} + void TestBlackbox::ruleCycle() { QDir::setCurrent(testDataDir + "/ruleCycle"); @@ -2525,6 +2581,82 @@ void TestBlackbox::soVersion_data() QTest::newRow("no version, empty soVersion") << QString("") << false << QString("libmylib.so"); } +void TestBlackbox::sourceArtifactChanges() +{ + QDir::setCurrent(testDataDir + "/source-artifact-changes"); + bool useCustomFileTags = false; + bool overrideFileTags = true; + bool filesAreTargets = false; + bool useCxx11 = false; + const QString appFilePath = QDir::currentPath() + '/' + relativeExecutableFilePath("app"); + static const auto b2s = [](bool b) { return QString(b ? "true" : "false"); }; + const auto resolveParams = [&useCustomFileTags, &overrideFileTags, &filesAreTargets, &useCxx11] { + return QbsRunParameters("resolve", QStringList{ + "modules.module_with_files.overrideTags:" + b2s(overrideFileTags), + "modules.module_with_files.filesAreTargets:" + b2s(filesAreTargets), + "modules.module_with_files.fileTags:" + QString(useCustomFileTags ? "custom" : "cpp"), + "modules.cpp.cxxLanguageVersion:" + QString(useCxx11 ? "c++11" : "c++98") + }); + }; +#define VERIFY_COMPILATION(expected) \ + do { \ + QVERIFY2(m_qbsStdout.contains("compiling main.cpp") == expected, m_qbsStdout.constData()); \ + QVERIFY2(QFile::exists(appFilePath) == expected, qPrintable(appFilePath)); \ + if (expected) \ + QVERIFY2(m_qbsStdout.contains("cpp artifacts: 1"), m_qbsStdout.constData()); \ + else \ + QVERIFY2(m_qbsStdout.contains("cpp artifacts: 0"), m_qbsStdout.constData()); \ + } while (false) + + // Initial build. + QCOMPARE(runQbs(resolveParams()), 0); + QVERIFY2(m_qbsStdout.contains("is gcc: "), m_qbsStdout.constData()); + const bool isGcc = m_qbsStdout.contains("is gcc: true"); + QCOMPARE(runQbs(), 0); + VERIFY_COMPILATION(true); + + // Overwrite the file tags. Now the source file is no longer tagged "cpp" and nothing + // should get built. + WAIT_FOR_NEW_TIMESTAMP(); + touch("modules/module_with_files/main.cpp"); + useCustomFileTags = true; + QCOMPARE(runQbs(resolveParams()), 0); + QCOMPARE(runQbs(), 0); + VERIFY_COMPILATION(false); + + // Now the custom file tag exists in addition to "cpp", and the app should get built again. + overrideFileTags = false; + QCOMPARE(runQbs(resolveParams()), 0); + QCOMPARE(runQbs(), 0); + VERIFY_COMPILATION(true); + + // Mark the cpp file as a module target. Now it will no longer be considered an input + // by the compiler rule, and nothing should get built. + WAIT_FOR_NEW_TIMESTAMP(); + touch("modules/module_with_files/main.cpp"); + filesAreTargets = true; + QCOMPARE(runQbs(resolveParams()), 0); + QCOMPARE(runQbs(), 0); + VERIFY_COMPILATION(false); + + // Now just revert the last change. + filesAreTargets = false; + QCOMPARE(runQbs(resolveParams()), 0); + QCOMPARE(runQbs(), 0); + VERIFY_COMPILATION(true); + + // Change a relevant cpp property. A rebuild is expected. + useCxx11 = true; + QCOMPARE(runQbs(resolveParams()), 0); + QCOMPARE(runQbs(QStringList({"--command-echo-mode", "command-line"})), 0); + if (isGcc) { + QVERIFY2(m_qbsStdout.contains("-std=c++11") || m_qbsStdout.contains("-std=c++0x"), + m_qbsStdout.constData()); + } + +#undef VERIFY_COMPILATION +} + void TestBlackbox::overrideProjectProperties() { QDir::setCurrent(testDataDir + "/overrideProjectProperties"); @@ -2672,10 +2804,8 @@ void TestBlackbox::pluginDependency() QVERIFY2(!m_qbsStdout.contains("linking"), m_qbsStdout.constData()); QCOMPARE(runQbs(QStringList{"--command-echo-mode", "command-line"}), 0); output = m_qbsStdout + '\n' + m_qbsStderr; - if (!HostOsInfo::isMacosHost()) { // TODO: Remove in master - QVERIFY2(!output.contains("plugin1"), output.constData()); - QVERIFY2(!output.contains("helper2"), output.constData()); - } + QVERIFY2(!output.contains("plugin1"), output.constData()); + QVERIFY2(!output.contains("helper2"), output.constData()); QVERIFY2(output.contains("plugin2"), output.constData()); // Test change tracking for parameter in Depends item. @@ -3189,6 +3319,11 @@ void TestBlackbox::erroneousFiles_data() << "Error in Rule\\.outputArtifacts\\[0\\]\n\r?" "Property fileTags for artifact 'outputArtifacts-missing-fileTags\\.txt' " "must be a non-empty string list\\."; + QTest::newRow("texttemplate-unknown-placeholder") + << "Placeholder 'what' is not defined in textemplate.dict for 'boom.txt.in'"; + QTest::newRow("tag-mismatch") + << "tag-mismatch.qbs:8:18.*Artifact '.*dummy1' has undeclared file tags " + "\\[\"y\",\"z\"\\]."; } void TestBlackbox::erroneousFiles() @@ -3200,8 +3335,8 @@ void TestBlackbox::erroneousFiles() QVERIFY(runQbs(params) != 0); QString err = QString::fromLocal8Bit(m_qbsStderr); if (!err.contains(QRegExp(errorMessage))) { - qDebug() << "Output: " << err; - qDebug() << "Expected: " << errorMessage; + qDebug().noquote() << "Output: " << err; + qDebug().noquote() << "Expected: " << errorMessage; QFAIL("Unexpected error message."); } } @@ -3220,25 +3355,25 @@ void TestBlackbox::errorInfo() QCOMPARE(runQbs(resolveParams), 0); buildParams.arguments = resolveParams.arguments; QVERIFY(runQbs(buildParams) != 0); - QVERIFY2(m_qbsStderr.contains("error-info.qbs:25"), m_qbsStderr); + QVERIFY2(m_qbsStderr.contains("error-info.qbs:24"), m_qbsStderr); resolveParams.arguments = QStringList() << "project.fail2:true"; QCOMPARE(runQbs(resolveParams), 0); buildParams.arguments = resolveParams.arguments; QVERIFY(runQbs(buildParams) != 0); - QVERIFY2(m_qbsStderr.contains("error-info.qbs:37"), m_qbsStderr); + QVERIFY2(m_qbsStderr.contains("error-info.qbs:36"), m_qbsStderr); resolveParams.arguments = QStringList() << "project.fail3:true"; QCOMPARE(runQbs(resolveParams), 0); buildParams.arguments = resolveParams.arguments; QVERIFY(runQbs(buildParams) != 0); - QVERIFY2(m_qbsStderr.contains("error-info.qbs:52"), m_qbsStderr); + QVERIFY2(m_qbsStderr.contains("error-info.qbs:51"), m_qbsStderr); resolveParams.arguments = QStringList() << "project.fail4:true"; QCOMPARE(runQbs(resolveParams), 0); buildParams.arguments = resolveParams.arguments; QVERIFY(runQbs(buildParams) != 0); - QVERIFY2(m_qbsStderr.contains("error-info.qbs:67"), m_qbsStderr); + QVERIFY2(m_qbsStderr.contains("error-info.qbs:66"), m_qbsStderr); resolveParams.arguments = QStringList() << "project.fail5:true"; QCOMPARE(runQbs(resolveParams), 0); @@ -3257,7 +3392,7 @@ void TestBlackbox::errorInfo() buildParams.arguments = resolveParams.arguments; QVERIFY(runQbs(buildParams) != 0); QVERIFY2(m_qbsStderr.contains("JavaScriptCommand.sourceCode"), m_qbsStderr); - QVERIFY2(m_qbsStderr.contains("error-info.qbs:58"), m_qbsStderr); + QVERIFY2(m_qbsStderr.contains("error-info.qbs:57"), m_qbsStderr); } void TestBlackbox::escapedLinkerFlags() @@ -3409,12 +3544,8 @@ void TestBlackbox::exportsPkgconfig() QCOMPARE(generatedPcFile.readAll().replace("\r", ""), sourcePcFile.readAll().replace("\r", "")); sourcePcFile.close(); generatedPcFile.close(); - sourcePcFile.setFileName("TheSecondLib.pc"); - generatedPcFilePath = relativeProductBuildDir("TheSecondLib") + "/TheSecondLib.pc"; - generatedPcFile.setFileName(generatedPcFilePath); - QVERIFY2(sourcePcFile.open(QIODevice::ReadOnly), qPrintable(sourcePcFile.errorString())); - QVERIFY2(generatedPcFile.open(QIODevice::ReadOnly), qPrintable(generatedPcFile.errorString())); - QCOMPARE(generatedPcFile.readAll(), sourcePcFile.readAll()); + TEXT_FILE_COMPARE(relativeProductBuildDir("TheSecondLib") + "/TheSecondLib.pc", + "TheSecondLib.pc"); WAIT_FOR_NEW_TIMESTAMP(); touch("firstlib.cpp"); QCOMPARE(runQbs(), 0); @@ -3546,6 +3677,17 @@ void TestBlackbox::fileDependencies() QVERIFY(!m_qbsStdout.contains("compiling zort.cpp")); } +void TestBlackbox::fileTagsFilterMerging() +{ + QDir::setCurrent(testDataDir + "/filetagsfilter-merging"); + QCOMPARE(runQbs(QStringList{"-f", "filetagsfilter-merging.qbs"}), 0); + const QString installedApp = defaultInstallRoot + "/myapp/binDir/" + + QFileInfo(relativeExecutableFilePath("myapp")).fileName(); + QVERIFY2(QFile::exists(installedApp), qPrintable(installedApp)); + const QString otherOutput = relativeProductBuildDir("myapp") + "/myapp.txt"; + QVERIFY2(QFile::exists(otherOutput), qPrintable(otherOutput)); +} + void TestBlackbox::installedTransformerOutput() { QDir::setCurrent(testDataDir + "/installed-transformer-output"); @@ -3554,6 +3696,59 @@ void TestBlackbox::installedTransformerOutput() QVERIFY2(QFile::exists(installedFilePath), qPrintable(installedFilePath)); } +void TestBlackbox::installLocations_data() +{ + QTest::addColumn<QString>("binDir"); + QTest::addColumn<QString>("dllDir"); + QTest::addColumn<QString>("libDir"); + QTest::newRow("explicit values") << QString("bindir") << QString("dlldir") << QString("libdir"); + QTest::newRow("default values") << QString() << QString() << QString(); +} + +void TestBlackbox::installLocations() +{ + QDir::setCurrent(testDataDir + "/install-locations"); + QFETCH(QString, binDir); + QFETCH(QString, dllDir); + QFETCH(QString, libDir); + QbsRunParameters params("resolve"); + if (!binDir.isEmpty()) + params.arguments.push_back("products.theapp.installDir:" + binDir); + if (!dllDir.isEmpty()) + params.arguments.push_back("products.thelib.installDir:" + dllDir); + if (!libDir.isEmpty()) + params.arguments.push_back("products.thelib.importLibInstallDir:" + libDir); + QCOMPARE(runQbs(params), 0); + const bool isWindows = m_qbsStdout.contains("is windows"); + const bool isMac = m_qbsStdout.contains("is mac"); + const bool isUnix = m_qbsStdout.contains("is unix"); + QVERIFY(isWindows || isMac || isUnix); + QCOMPARE(runQbs(QbsRunParameters(QStringList("--clean-install-root"))), 0); + const QString dllFileName = isWindows ? "thelib.dll" : isMac ? "thelib" : "libthelib.so"; + const QString appFileName = isWindows ? "theapp.exe" : "theapp"; + if (binDir.isEmpty()) + binDir = isMac ? "/Applications" : "/bin"; + if (dllDir.isEmpty()) + dllDir = isMac ? "/Library/Frameworks" : isWindows ? "/bin" : "/lib"; + if (libDir.isEmpty()) + libDir = "/lib"; + if (isMac) { + binDir += "/theapp.app/Contents/MacOS"; + dllDir += "/thelib.framework"; + } + const QString installRoot = QDir::currentPath() + "/default/install-root"; + const QString installPrefix = isWindows ? QString() : "/usr/local"; + const QString fullInstallPrefix = installRoot + '/' + installPrefix + '/'; + const QString appFilePath = fullInstallPrefix + binDir + '/' + appFileName; + QVERIFY2(QFile::exists(appFilePath), qPrintable(appFilePath)); + const QString dllFilePath = fullInstallPrefix + dllDir + '/' + dllFileName; + QVERIFY2(QFile::exists(dllFilePath), qPrintable(dllFilePath)); + if (isWindows) { + const QString libFilePath = fullInstallPrefix + libDir + "/thelib.lib"; + QVERIFY2(QFile::exists(libFilePath), qPrintable(libFilePath)); + } +} + void TestBlackbox::inputsFromDependencies() { QDir::setCurrent(testDataDir + "/inputs-from-dependencies"); @@ -3637,9 +3832,21 @@ void TestBlackbox::installTree() QVERIFY(QFile::exists(installRoot + "content/subdir2/baz.txt")); } +void TestBlackbox::invalidCommandProperty_data() +{ + QTest::addColumn<QString>("errorType"); + + QTest::newRow("assigning QObject") << QString("qobject"); + QTest::newRow("assigning input artifact") << QString("input"); + QTest::newRow("assigning other artifact") << QString("artifact"); +} + void TestBlackbox::invalidCommandProperty() { QDir::setCurrent(testDataDir + "/invalid-command-property"); + QFETCH(QString, errorType); + QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("products.p.errorType:" + errorType))), + 0); QbsRunParameters params; params.expectFailure = true; QVERIFY(runQbs(params) != 0); @@ -3684,7 +3891,7 @@ void TestBlackbox::invalidExtensionInstantiation() params.expectFailure = true; params.arguments << (QString("products.theProduct.extension:") + QTest::currentDataTag()); QVERIFY(runQbs(params) != 0); - QVERIFY2(m_qbsStderr.contains("invalid-extension-instantiation.qbs:18") + QVERIFY2(m_qbsStderr.contains("invalid-extension-instantiation.qbs:17") && m_qbsStderr.contains('\'' + QByteArray(QTest::currentDataTag()) + "' cannot be instantiated"), m_qbsStderr.constData()); @@ -3958,7 +4165,7 @@ void TestBlackbox::symbolLinkMode() QbsRunParameters params; params.command = "run"; const QStringList commonArgs{"-p", "driver", "--setup-run-env-config", - "ignore-lib-dependencies"}; + "ignore-lib-dependencies", "qbs.installPrefix:''"}; rmDirR(relativeBuildDir()); params.arguments = QStringList() << commonArgs << "project.shouldInstallLibrary:true"; @@ -3990,7 +4197,7 @@ void TestBlackbox::linkerMode() QSKIP("only applies on Unix"); QDir::setCurrent(testDataDir + "/linkerMode"); - QCOMPARE(runQbs(), 0); + QCOMPARE(runQbs(QbsRunParameters(QStringList("qbs.installPrefix:''"))), 0); auto testCondition = [&](const QString &lang, const std::function<bool(const QByteArray &)> &condition) { @@ -4294,6 +4501,37 @@ void TestBlackbox::newOutputArtifact() QVERIFY(regularFileExists(the100thArtifact)); } +void TestBlackbox::noExportedSymbols_data() +{ + QTest::addColumn<bool>("link"); + QTest::addColumn<bool>("dryRun"); + QTest::newRow("link") << true << false; + QTest::newRow("link (dry run)") << true << true; + QTest::newRow("do not link") << false << false; +} + +void TestBlackbox::noExportedSymbols() +{ + QDir::setCurrent(testDataDir + "/no-exported-symbols"); + QFETCH(bool, link); + QFETCH(bool, dryRun); + QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList{"--force-probe-execution", + QString("products.the_app.link:") + (link ? "true" : "false")})), 0); + const bool isMsvc = m_qbsStdout.contains("compiler is MSVC"); + const bool isNotMsvc = m_qbsStdout.contains("compiler is not MSVC"); + QVERIFY2(isMsvc || isNotMsvc, m_qbsStdout.constData()); + if (isNotMsvc) + QSKIP("Test applies with MSVC only"); + QbsRunParameters buildParams; + if (dryRun) + buildParams.arguments << "--dry-run"; + buildParams.expectFailure = link && !dryRun; + QCOMPARE(runQbs(buildParams) == 0, !buildParams.expectFailure); + QVERIFY2(m_qbsStderr.contains("This typically happens when a DLL does not export " + "any symbols.") == buildParams.expectFailure, + m_qbsStderr.constData()); +} + void TestBlackbox::noProfile() { QDir::setCurrent(testDataDir + "/no-profile"); @@ -4733,6 +4971,40 @@ void TestBlackbox::propertiesInExportItems() QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData()); } +void TestBlackbox::protobuf_data() +{ + QTest::addColumn<QString>("projectFile"); + QTest::addColumn<QStringList>("properties"); + QTest::addColumn<bool>("successExpected"); + QTest::newRow("cpp") << QString("addressbook_cpp.qbs") << QStringList() << true; + QTest::newRow("objc") << QString("addressbook_objc.qbs") << QStringList() << true; + QTest::newRow("import") << QString("import.qbs") << QStringList() << true; + QTest::newRow("missing import dir") << QString("needs-import-dir.qbs") + << QStringList() << false; + QTest::newRow("provided import dir") + << QString("needs-import-dir.qbs") + << QStringList("products.app.theImportDir:subdir") << true; +} + +void TestBlackbox::protobuf() +{ + QDir::setCurrent(testDataDir + "/protobuf"); + QFETCH(QString, projectFile); + QFETCH(QStringList, properties); + QFETCH(bool, successExpected); + rmDirR(relativeBuildDir()); + QbsRunParameters resolveParams("resolve", QStringList{"-f", projectFile} << properties); + QCOMPARE(runQbs(resolveParams), 0); + const bool withProtobuf = m_qbsStdout.contains("has protobuf: true"); + const bool withoutProtobuf = m_qbsStdout.contains("has protobuf: false"); + QVERIFY2(withProtobuf || withoutProtobuf, m_qbsStdout.constData()); + if (withoutProtobuf) + QSKIP("protobuf module not present"); + QbsRunParameters runParams("run"); + runParams.expectFailure = !successExpected; + QCOMPARE(runQbs(runParams) == 0, successExpected); +} + void TestBlackbox::pseudoMultiplexing() { // This is "pseudo-multiplexing" on all platforms that initialize qbs.architectures @@ -5175,6 +5447,44 @@ void TestBlackbox::autotestWithDependencies() && m_qbsStdout.contains("i am the helper"), m_qbsStdout.constData()); } +void TestBlackbox::autotests_data() +{ + QTest::addColumn<QString>("evilPropertySpec"); + QTest::addColumn<QByteArray>("expectedErrorMessage"); + QTest::newRow("missing arguments") << QString("products.test1.autotest.arguments:[]") + << QByteArray("This test needs exactly one argument"); + QTest::newRow("missing working dir") << QString("products.test2.autotest.workingDir:''") + << QByteArray("Test resource not found"); + QTest::newRow("missing flaky specifier") + << QString("products.test3.autotest.allowFailure:false") + << QByteArray("I am an awful test"); + QTest::newRow("everything's fine") << QString() << QByteArray(); +} + +void TestBlackbox::autotests() +{ + QDir::setCurrent(testDataDir + "/autotests"); + QFETCH(QString, evilPropertySpec); + QFETCH(QByteArray, expectedErrorMessage); + QbsRunParameters resolveParams("resolve"); + if (!evilPropertySpec.isEmpty()) + resolveParams.arguments << evilPropertySpec; + QCOMPARE(runQbs(resolveParams), 0); + QbsRunParameters testParams(QStringList{"-p", "autotest-runner"}); + if (!evilPropertySpec.isEmpty()) + testParams.expectFailure = true; + QCOMPARE(runQbs(testParams) == 0, !testParams.expectFailure); + if (testParams.expectFailure) { + QVERIFY2(m_qbsStderr.contains(expectedErrorMessage), m_qbsStderr.constData()); + return; + } + QVERIFY2(m_qbsStdout.contains("Running test test1") + && m_qbsStdout.contains("Running test test2") + && m_qbsStdout.contains("Running test test3"), m_qbsStdout.constData()); + QCOMPARE(m_qbsStdout.count("PASS"), 2); + QCOMPARE(m_qbsStderr.count("FAIL"), 1); +} + void TestBlackbox::auxiliaryInputsFromDependencies() { QDir::setCurrent(testDataDir + "/aux-inputs-from-deps"); @@ -5727,6 +6037,47 @@ void TestBlackbox::innoSetupDependencies() QVERIFY(regularFileExists(relativeBuildDir() + "/qbs.setup.test.exe")); } +void TestBlackbox::inputTagsChangeTracking_data() +{ + QTest::addColumn<QString>("generateInput"); + QTest::newRow("source artifact") << QString("no"); + QTest::newRow("generated artifact (static)") << QString("static"); + QTest::newRow("generated artifact (dynamic)") << QString("dynamic"); +} + +void TestBlackbox::inputTagsChangeTracking() +{ + QDir::setCurrent(testDataDir + "/input-tags-change-tracking"); + const QString xOut = QDir::currentPath() + '/' + relativeProductBuildDir("p") + "/x.out"; + const QString yOut = QDir::currentPath() + '/' + relativeProductBuildDir("p") + "/y.out"; + QFETCH(QString, generateInput); + const QbsRunParameters resolveParams("resolve", + QStringList("products.p.generateInput:" + generateInput)); + QCOMPARE(runQbs(resolveParams), 0); + QCOMPARE(runQbs(), 0); + QVERIFY(m_qbsStdout.contains("generating input.txt") == (generateInput == "static")); + QVERIFY2(!QFile::exists(xOut), qPrintable(xOut)); + QVERIFY2(!QFile::exists(yOut), qPrintable(yOut)); + WAIT_FOR_NEW_TIMESTAMP(); + REPLACE_IN_FILE("input-tags-change-tracking.qbs", "Tags: [\"txt\", \"empty\"]", + "Tags: \"txt\""); + QCOMPARE(runQbs(), 0); + QVERIFY2(QFile::exists(xOut), qPrintable(xOut)); + QVERIFY2(!QFile::exists(yOut), qPrintable(yOut)); + WAIT_FOR_NEW_TIMESTAMP(); + REPLACE_IN_FILE("input-tags-change-tracking.qbs", "Tags: \"txt\"", + "Tags: [\"txt\", \"y\"]"); + QCOMPARE(runQbs(), 0); + QVERIFY2(!QFile::exists(xOut), qPrintable(xOut)); + QVERIFY2(QFile::exists(yOut), qPrintable(yOut)); + WAIT_FOR_NEW_TIMESTAMP(); + REPLACE_IN_FILE("input-tags-change-tracking.qbs", "Tags: [\"txt\", \"y\"]", + "Tags: [\"txt\", \"empty\"]"); + QCOMPARE(runQbs(), 0); + QVERIFY2(!QFile::exists(xOut), qPrintable(xOut)); + QVERIFY2(!QFile::exists(yOut), qPrintable(yOut)); +} + void TestBlackbox::outputArtifactAutoTagging() { QDir::setCurrent(testDataDir + QLatin1String("/output-artifact-auto-tagging")); diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index 58cc8f6fb..874690ad2 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -48,6 +48,8 @@ private slots: void artifactScanning(); void assembly(); void autotestWithDependencies(); + void autotests_data(); + void autotests(); void auxiliaryInputsFromDependencies(); void badInterpreter(); void bomSources(); @@ -57,6 +59,7 @@ private slots: void buildGraphVersions(); void changedFiles_data(); void changedFiles(); + void changedInputsFromDependencies(); void changedRuleInputs(); void changeInDisabledProduct(); void changeInImportedFile(); @@ -111,6 +114,7 @@ private slots: void exportsQbs(); void externalLibs(); void fileDependencies(); + void fileTagsFilterMerging(); void generatedArtifactAsInputToDynamicRule(); void generator(); void generator_data(); @@ -125,6 +129,8 @@ private slots: void includeLookup(); void innoSetup(); void innoSetupDependencies(); + void inputTagsChangeTracking_data(); + void inputTagsChangeTracking(); void inputsFromDependencies(); void installable(); void installableAsAuxiliaryInput(); @@ -133,9 +139,12 @@ private slots: void installDuplicatesNoError(); void installedSourceFiles(); void installedTransformerOutput(); + void installLocations_data(); + void installLocations(); void installPackage(); void installRootFromProjectFile(); void installTree(); + void invalidCommandProperty_data(); void invalidCommandProperty(); void invalidExtensionInstantiation(); void invalidExtensionInstantiation_data(); @@ -178,6 +187,8 @@ private slots: void nestedGroups(); void nestedProperties(); void newOutputArtifact(); + void noExportedSymbols_data(); + void noExportedSymbols(); void noProfile(); void noSuchProfile(); void nodejs(); @@ -211,6 +222,8 @@ private slots: void propertyPrecedence(); void properQuoting(); void propertiesInExportItems(); + void protobuf_data(); + void protobuf(); void pseudoMultiplexing(); void qbsConfig(); void qbsVersion(); @@ -226,7 +239,9 @@ private slots: void requireDeprecated(); void rescueTransformerData(); void responseFiles(); + void retaggedOutputArtifact(); void ruleConditions(); + void ruleConnectionWithExcludedInputs(); void ruleCycle(); void ruleWithNoInputs(); void ruleWithNonRequiredInputs(); @@ -236,6 +251,7 @@ private slots: void smartRelinking_data(); void soVersion(); void soVersion_data(); + void sourceArtifactChanges(); void subProfileChangeTracking(); void successiveChanges(); void symbolLinkMode(); @@ -251,6 +267,7 @@ private slots: void systemRunPaths(); void systemRunPaths_data(); void tar(); + void textTemplate(); void toolLookup(); void topLevelSearchPath(); void trackAddFile(); diff --git a/tests/auto/blackbox/tst_blackboxandroid.cpp b/tests/auto/blackbox/tst_blackboxandroid.cpp index a551a77c4..bf47c241c 100644 --- a/tests/auto/blackbox/tst_blackboxandroid.cpp +++ b/tests/auto/blackbox/tst_blackboxandroid.cpp @@ -69,14 +69,22 @@ TestBlackboxAndroid::TestBlackboxAndroid() { } +static QString theProfileName(bool forQt) +{ + return forQt ? "qbs_autotests-android-qt" : profileName(); +} + void TestBlackboxAndroid::android() { QFETCH(QString, projectDir); QFETCH(QStringList, productNames); QFETCH(QList<QByteArrayList>, expectedFilesLists); + QFETCH(QStringList, customProperties); const SettingsPtr s = settings(); - Profile p(profileName(), s.get()); + Profile p(theProfileName(projectDir == "qml-app"), s.get()); + if (!p.exists()) + p = Profile("none", s.get()); int status; const auto androidPaths = findAndroid(&status, p.name()); QCOMPARE(status, 0); @@ -100,12 +108,21 @@ void TestBlackboxAndroid::android() static const QStringList configNames { "debug", "release" }; for (const QString &configName : configNames) { auto currentExpectedFilesLists = expectedFilesLists; - QbsRunParameters params(QStringList { "--command-echo-mode", "command-line", - "modules.Android.ndk.platform:android-21", - "config:" + configName }); - params.profile = p.name(); - QCOMPARE(runQbs(params), 0); + const QString configArgument = "config:" + configName; + QbsRunParameters resolveParams("resolve"); + resolveParams.arguments << "modules.Android.ndk.platform:android-21" << configArgument + << customProperties; + resolveParams.profile = p.name(); + QCOMPARE(runQbs(resolveParams), 0); + QbsRunParameters buildParams(QStringList{"--command-echo-mode", "command-line", + configArgument}); + buildParams.profile = p.name(); + QCOMPARE(runQbs(buildParams), 0); for (const QString &productName : qAsConst(productNames)) { + const QByteArray tag(QTest::currentDataTag()); + const bool isIncrementalBuild = tag.startsWith("qml app") && tag != "qml app"; + QCOMPARE(m_qbsStdout.count("Generating BuildConfig.java"), + isIncrementalBuild ? 0 : productNames.size()); QVERIFY(m_qbsStdout.contains(productName.toLocal8Bit() + ".apk")); const QString apkFilePath = relativeProductBuildDir(productName, configName) + '/' + productName + ".apk"; @@ -123,7 +140,7 @@ void TestBlackboxAndroid::android() QByteArrayList missingExpectedFiles; QByteArrayList expectedFiles = currentExpectedFilesLists.takeFirst(); for (const QByteArray &expectedFile : expectedFiles) { - if (expectedFile.endsWith("/gdbserver") && configName == "release") + if (expectedFile.endsWith("/libgdbserver.so") && configName == "release") continue; auto it = std::find(actualFiles.begin(), actualFiles.end(), expectedFile); if (it != actualFiles.end()) { @@ -139,10 +156,15 @@ void TestBlackboxAndroid::android() auto isFileSharedObject = [](const QByteArray &f) { return f.endsWith(".so"); }; - if (none_of(actualFiles, isFileSharedObject)) + const auto isQmlToolingLib = [](const QByteArray &f) { + return f.contains("qmltooling"); + }; + if (none_of(actualFiles, isFileSharedObject) + || std::all_of(actualFiles.cbegin(), actualFiles.cend(), isQmlToolingLib)) { QWARN(msg); - else + } else { QFAIL(msg); + } } } @@ -169,6 +191,7 @@ void TestBlackboxAndroid::android_data() { const SettingsPtr s = settings(); const Profile p(profileName(), s.get()); + const Profile pQt(theProfileName(true), s.get()); QStringList archsStringList = p.value(QLatin1String("qbs.architectures")).toStringList(); if (archsStringList.empty()) archsStringList << QStringLiteral("armv7a"); // must match default in common.qbs @@ -179,10 +202,19 @@ void TestBlackboxAndroid::android_data() .replace("armv5te", "armeabi") .replace("arm64", "arm64-v8a"); }); - const bool usesClang = p.value(QLatin1String("qbs.toolchainType")).toString() == "clang"; - const auto cxxLibPath = [usesClang](const QByteArray &oldcxxLib) { + const auto cxxLibPath = [&p, &pQt](const QByteArray &oldcxxLib, bool forQt) { + const bool usesClang = (forQt ? pQt : p).value(QLatin1String("qbs.toolchainType")) + .toString() == "clang"; return QByteArray("lib/${ARCH}/") + (usesClang ? "libc++_shared.so" : oldcxxLib); }; + const QByteArrayList archsForQt = { pQt.value("qbs.architecture").toString().toUtf8() }; + QByteArrayList ndkArchsForQt = archsForQt; + if (ndkArchsForQt.first() == "armv7a") + ndkArchsForQt.first() = "armeabi-v7a"; + else if (ndkArchsForQt.first() == "armv5te") + ndkArchsForQt.first() = "armeabi"; + else if (ndkArchsForQt.first() == "arm64") + ndkArchsForQt.first() = "arm64-v8a"; auto expandArchs = [] (const QByteArrayList &archs, const QByteArrayList &lst) { const QByteArray &archPlaceHolder = "${ARCH}"; @@ -200,25 +232,136 @@ void TestBlackboxAndroid::android_data() const QByteArrayList commonFiles = expandArchs(archs, { "AndroidManifest.xml", "META-INF/ANDROIDD.RSA", "META-INF/ANDROIDD.SF", - "META-INF/MANIFEST.MF", "classes.dex", "resources.arsc" + "META-INF/MANIFEST.MF", "classes.dex" }); QTest::addColumn<QString>("projectDir"); QTest::addColumn<QStringList>("productNames"); QTest::addColumn<QList<QByteArrayList>>("expectedFilesLists"); + QTest::addColumn<QStringList>("customProperties"); QTest::newRow("teapot") - << "teapot" << QStringList("com.sample.teapot") + << "teapot" << QStringList("TeapotNativeActivity") << (QList<QByteArrayList>() << commonFiles + expandArchs(archs, { + "resources.arsc", "assets/Shaders/ShaderPlain.fsh", "assets/Shaders/VS_ShaderPlain.vsh", - "lib/${ARCH}/gdbserver", - cxxLibPath("libgnustl_shared.so"), + "lib/${ARCH}/libgdbserver.so", + cxxLibPath("libgnustl_shared.so", false), "lib/${ARCH}/libTeapotNativeActivity.so", - "res/layout/widgets.xml"})); + "res/layout/widgets.xml"})) + << QStringList(); + QTest::newRow("minimal-native") + << "minimal-native" << QStringList("minimalnative") + << (QList<QByteArrayList>() << commonFiles + expandArchs({archs.first()}, { + "lib/${ARCH}/libminimalnative.so", + cxxLibPath("libstlport_shared.so", false), + "lib/${ARCH}/libdependency.so"})) + << QStringList{"products.minimalnative.multiplexByQbsProperties:[]", + "modules.qbs.architecture:" + archsStringList.first()}; + QTest::newRow("qml app") + << "qml-app" << QStringList("qmlapp") + << (QList<QByteArrayList>() << commonFiles + expandArchs(ndkArchsForQt, { + "resources.arsc", + "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/plugins.qmltypes", + "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/qmldir", + "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/plugins.qmltypes", + "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/qmldir", + "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list", + "lib/${ARCH}/libgdbserver.so", + cxxLibPath("libgnustl_shared.so", true), + "lib/${ARCH}/libplugins_bearer_libqandroidbearer.so", + "lib/${ARCH}/libplugins_imageformats_libqgif.so", + "lib/${ARCH}/libplugins_imageformats_libqicns.so", + "lib/${ARCH}/libplugins_imageformats_libqico.so", + "lib/${ARCH}/libplugins_imageformats_libqjpeg.so", + "lib/${ARCH}/libplugins_imageformats_libqtga.so", + "lib/${ARCH}/libplugins_imageformats_libqtiff.so", + "lib/${ARCH}/libplugins_imageformats_libqwbmp.so", + "lib/${ARCH}/libplugins_imageformats_libqwebp.so", + "lib/${ARCH}/libplugins_platforms_android_libqtforandroid.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_debugger.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_inspector.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_local.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_messages.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_native.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_nativedebugger.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_profiler.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_preview.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_quickprofiler.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_server.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_tcp.so", + "lib/${ARCH}/libqml_QtQuick.2_libqtquick2plugin.so", + "lib/${ARCH}/libqml_QtQuick_Window.2_libwindowplugin.so", + "lib/${ARCH}/libQt5Core.so", + "lib/${ARCH}/libQt5Gui.so", + "lib/${ARCH}/libQt5Network.so", + "lib/${ARCH}/libQt5Qml.so", + "lib/${ARCH}/libQt5QuickParticles.so", + "lib/${ARCH}/libQt5Quick.so", + "lib/${ARCH}/libqmlapp.so", + "res/layout/splash.xml"})) + << QStringList{"modules.Android.sdk.automaticSources:false", + "modules.qbs.architecture:" + archsForQt.first()}; + QTest::newRow("qml app using Ministro") + << "qml-app" << QStringList("qmlapp") + << (QList<QByteArrayList>() << commonFiles + expandArchs(ndkArchsForQt, { + "resources.arsc", + "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list", + "lib/${ARCH}/libgdbserver.so", + cxxLibPath("libgnustl_shared.so", true), + "lib/${ARCH}/libqmlapp.so", + "res/layout/splash.xml"})) + << QStringList{"modules.Qt.android_support.useMinistro:true", + "modules.Android.sdk.automaticSources:false"}; + QTest::newRow("qml app with custom metadata") + << "qml-app" << QStringList("qmlapp") + << (QList<QByteArrayList>() << commonFiles + expandArchs(ndkArchsForQt, { + "resources.arsc", + "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/plugins.qmltypes", + "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/qmldir", + "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/plugins.qmltypes", + "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/qmldir", + "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list", + "assets/dummyasset.txt", + "lib/${ARCH}/libgdbserver.so", + cxxLibPath("libgnustl_shared.so", true), + "lib/${ARCH}/libplugins_bearer_libqandroidbearer.so", + "lib/${ARCH}/libplugins_imageformats_libqgif.so", + "lib/${ARCH}/libplugins_imageformats_libqicns.so", + "lib/${ARCH}/libplugins_imageformats_libqico.so", + "lib/${ARCH}/libplugins_imageformats_libqjpeg.so", + "lib/${ARCH}/libplugins_imageformats_libqtga.so", + "lib/${ARCH}/libplugins_imageformats_libqtiff.so", + "lib/${ARCH}/libplugins_imageformats_libqwbmp.so", + "lib/${ARCH}/libplugins_imageformats_libqwebp.so", + "lib/${ARCH}/libplugins_platforms_android_libqtforandroid.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_debugger.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_inspector.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_local.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_messages.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_native.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_nativedebugger.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_profiler.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_preview.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_quickprofiler.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_server.so", + "lib/${ARCH}/libplugins_qmltooling_libqmldbg_tcp.so", + "lib/${ARCH}/libqml_QtQuick.2_libqtquick2plugin.so", + "lib/${ARCH}/libqml_QtQuick_Window.2_libwindowplugin.so", + "lib/${ARCH}/libQt5Core.so", + "lib/${ARCH}/libQt5Gui.so", + "lib/${ARCH}/libQt5Network.so", + "lib/${ARCH}/libQt5Qml.so", + "lib/${ARCH}/libQt5QuickParticles.so", + "lib/${ARCH}/libQt5Quick.so", + "lib/${ARCH}/libqmlapp.so", + "res/layout/splash.xml"})) + << QStringList("modules.Android.sdk.automaticSources:true"); QTest::newRow("no native") << "no-native" << QStringList("com.example.android.basicmediadecoder") << (QList<QByteArrayList>() << commonFiles + expandArchs(archs, { + "resources.arsc", "res/drawable-hdpi-v4/ic_action_play_disabled.png", "res/drawable-hdpi-v4/ic_action_play.png", "res/drawable-hdpi-v4/ic_launcher.png", @@ -234,34 +377,41 @@ void TestBlackboxAndroid::android_data() "res/layout/sample_main.xml", "res/menu/action_menu.xml", "res/menu-v11/action_menu.xml", - "res/raw/vid_bigbuckbunny.mp4"})); + "res/raw/vid_bigbuckbunny.mp4"})) + << QStringList(); + QTest::newRow("aidl") << "aidl" << QStringList("io.qbs.aidltest") + << QList<QByteArrayList>{commonFiles} << QStringList(); QTest::newRow("multiple libs") << "multiple-libs-per-apk" << QStringList("twolibs") << (QList<QByteArrayList>() << commonFiles + expandArchs(archs, { - "lib/${ARCH}/gdbserver", + "resources.arsc", + "lib/${ARCH}/libgdbserver.so", "lib/${ARCH}/liblib1.so", "lib/${ARCH}/liblib2.so", - cxxLibPath("libstlport_shared.so")})); + cxxLibPath("libstlport_shared.so", false)})) + << QStringList(); QByteArrayList expectedFiles1 = (commonFiles + expandArchs(QByteArrayList{"armeabi-v7a", "x86"}, { - "lib/${ARCH}/gdbserver", + "resources.arsc", + "lib/${ARCH}/libgdbserver.so", "lib/${ARCH}/libp1lib1.so", - cxxLibPath("libstlport_shared.so")}) + cxxLibPath("libstlport_shared.so", false)}) + expandArchs(QByteArrayList{archs}, { - "lib/${ARCH}/gdbserver", + "resources.arsc", + "lib/${ARCH}/libgdbserver.so", "lib/${ARCH}/libp1lib2.so", - cxxLibPath("libstlport_shared.so")})).toSet().toList(); + cxxLibPath("libstlport_shared.so", false)})).toSet().toList(); QByteArrayList expectedFiles2 = commonFiles + expandArchs(archs, { - "lib/${ARCH}/gdbserver", + "lib/${ARCH}/libgdbserver.so", "lib/${ARCH}/libp2lib1.so", "lib/${ARCH}/libp2lib2.so", - cxxLibPath("libstlport_shared.so")}); - expectedFiles2.removeOne("resources.arsc"); + cxxLibPath("libstlport_shared.so", false)}); QTest::newRow("multiple apks") << "multiple-apks-per-project" << (QStringList() << "twolibs1" << "twolibs2") - << QList<QByteArrayList>{expectedFiles1, expectedFiles2}; + << QList<QByteArrayList>{expectedFiles1, expectedFiles2} + << QStringList(); } QTEST_MAIN(TestBlackboxAndroid) diff --git a/tests/auto/blackbox/tst_blackboxapple.cpp b/tests/auto/blackbox/tst_blackboxapple.cpp index b3ba13f04..0cb4d5abb 100644 --- a/tests/auto/blackbox/tst_blackboxapple.cpp +++ b/tests/auto/blackbox/tst_blackboxapple.cpp @@ -80,9 +80,9 @@ void TestBlackboxApple::appleMultiConfig() const bool supportsX86 = xcodeVersion < qbs::Version(10); QDir::setCurrent(testDataDir + "/apple-multiconfig"); - - QCOMPARE(runQbs(QbsRunParameters(QStringList(QString("project.enableX86:") - + (supportsX86 ? "true" : "false")))), 0); + QCOMPARE(runQbs(QbsRunParameters(QStringList{ + "qbs.installPrefix:''", + QString("project.enableX86:") + (supportsX86 ? "true" : "false")})), 0); QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Contents/MacOS/singleapp").isExecutable()); QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Contents/Info.plist").isRegularFile()); @@ -303,7 +303,7 @@ void TestBlackboxApple::bundleStructure() QFETCH(bool, isShallow); QDir::setCurrent(testDataDir + "/bundle-structure"); - QbsRunParameters params; + QbsRunParameters params(QStringList{"qbs.installPrefix:''"}); params.arguments << "project.buildableProducts:" + productName; if (isShallow) { // Coerce shallow bundles - don't set bundle.isShallow directly because we want to test the @@ -644,7 +644,7 @@ void TestBlackboxApple::embedInfoPlist() { QDir::setCurrent(testDataDir + QLatin1String("/embedInfoPlist")); - QbsRunParameters params; + QbsRunParameters params(QStringList{"qbs.installPrefix:''"}); QCOMPARE(runQbs(params), 0); QVERIFY(!getEmbeddedBinaryPlist(defaultInstallRoot + "/app").isEmpty()); diff --git a/tests/auto/blackbox/tst_blackboxbase.cpp b/tests/auto/blackbox/tst_blackboxbase.cpp index b07f14553..e1844b69c 100644 --- a/tests/auto/blackbox/tst_blackboxbase.cpp +++ b/tests/auto/blackbox/tst_blackboxbase.cpp @@ -46,9 +46,9 @@ using qbs::Profile; static QString initQbsExecutableFilePath() { - const QString qbsInstallRoot = QString::fromLocal8Bit(qgetenv("QBS_INSTALL_ROOT")); - return HostOsInfo::appendExecutableSuffix(QDir::cleanPath(!qbsInstallRoot.isEmpty() - ? qbsInstallRoot + QLatin1String("/bin/qbs") + const QString qbsInstallDir = QString::fromLocal8Bit(qgetenv("QBS_INSTALL_DIR")); + return HostOsInfo::appendExecutableSuffix(QDir::cleanPath(!qbsInstallDir.isEmpty() + ? qbsInstallDir + QLatin1String("/bin/qbs") : QCoreApplication::applicationDirPath() + QLatin1String("/qbs"))); } diff --git a/tests/auto/blackbox/tst_blackboxjava.cpp b/tests/auto/blackbox/tst_blackboxjava.cpp index 59553f8dc..0ea3c41ce 100644 --- a/tests/auto/blackbox/tst_blackboxjava.cpp +++ b/tests/auto/blackbox/tst_blackboxjava.cpp @@ -79,8 +79,7 @@ void TestBlackboxJava::java() QStringList() << "Jet" << "Ship" << "Vehicles"; QStringList classFiles1 = QStringList(classFiles) << "io/qt/qbs/HelloWorld" << "NoPackage"; for (QString &classFile : classFiles1) { - classFile = relativeProductBuildDir("class_collection") + "/classes/" - + classFile + ".class"; + classFile = relativeProductBuildDir("cc") + "/classes/" + classFile + ".class"; QVERIFY2(regularFileExists(classFile), qPrintable(classFile)); } diff --git a/tests/auto/blackbox/tst_blackboxjoblimits.cpp b/tests/auto/blackbox/tst_blackboxjoblimits.cpp new file mode 100644 index 000000000..0c366759d --- /dev/null +++ b/tests/auto/blackbox/tst_blackboxjoblimits.cpp @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "tst_blackboxbase.h" + +#include "../shared.h" +#include <tools/profile.h> + +class TestBlackboxJobLimits : public TestBlackboxBase +{ + Q_OBJECT + +public: + TestBlackboxJobLimits(); + +private slots: + void jobLimits_data(); + void jobLimits(); +}; + +TestBlackboxJobLimits::TestBlackboxJobLimits() + : TestBlackboxBase (SRCDIR "/testdata-joblimits", "blackbox-joblimits") +{ +} + +void TestBlackboxJobLimits::jobLimits_data() +{ + QTest::addColumn<int>("projectJobCount"); + QTest::addColumn<int>("productJobCount"); + QTest::addColumn<int>("moduleJobCount"); + QTest::addColumn<int>("prefsJobCount"); + QTest::addColumn<int>("cliJobCount"); + QTest::addColumn<bool>("projectPrecedence"); + QTest::addColumn<bool>("expectSuccess"); + for (int projectJobCount = -1; projectJobCount <= 1; ++projectJobCount) { + for (int productJobCount = -1; productJobCount <= 1; ++productJobCount) { + for (int moduleJobCount = -1; moduleJobCount <= 1; ++moduleJobCount) { + for (int prefsJobCount = -1; prefsJobCount <= 1; ++prefsJobCount) { + for (int cliJobCount = -1; cliJobCount <= 1; ++cliJobCount) { + QString description = QString("project:%1/" + "product:%2/module:%3/prefs:%4/cli:%5/project precedence") + .arg(projectJobCount).arg(productJobCount).arg(moduleJobCount) + .arg(prefsJobCount).arg(cliJobCount).toLocal8Bit(); + bool expectSuccess; + switch (productJobCount) { + case 1: expectSuccess = true; break; + case 0: expectSuccess = false; break; + case -1: + switch (projectJobCount) { + case 1: expectSuccess = true; break; + case 0: expectSuccess = false; break; + case -1: + switch (moduleJobCount) { + case 1: expectSuccess = true; break; + case 0: expectSuccess = false; break; + case -1: + switch (cliJobCount) { + case 1: expectSuccess = true; break; + case 0: expectSuccess = false; break; + case -1: expectSuccess = prefsJobCount == 1; break; + } + break; + } + break; + } + break; + } + QTest::newRow(qPrintable(description)) + << projectJobCount << productJobCount << moduleJobCount + << prefsJobCount << cliJobCount << true << expectSuccess; + description = QString("project:%1/" + "product:%2/module:%3/prefs:%4/cli:%5/default precedence") + .arg(projectJobCount).arg(productJobCount).arg(moduleJobCount) + .arg(prefsJobCount).arg(cliJobCount).toLocal8Bit(); + switch (cliJobCount) { + case 1: expectSuccess = true; break; + case 0: expectSuccess = false; break; + case -1: + switch (prefsJobCount) { + case 1: expectSuccess = true; break; + case 0: expectSuccess = false; break; + case -1: + switch (productJobCount) { + case 1: expectSuccess = true; break; + case 0: expectSuccess = false; break; + case -1: + switch (projectJobCount) { + case 1: expectSuccess = true; break; + case 0: expectSuccess = false; break; + case -1: expectSuccess = moduleJobCount == 1; break; + } + break; + } + break; + } + break; + } + QTest::newRow(qPrintable(description)) + << projectJobCount << productJobCount << moduleJobCount + << prefsJobCount << cliJobCount << false << expectSuccess; + } + } + } + } + } +} + +void TestBlackboxJobLimits::jobLimits() +{ + QDir::setCurrent(testDataDir + "/job-limits"); + QFETCH(int, projectJobCount); + QFETCH(int, productJobCount); + QFETCH(int, moduleJobCount); + QFETCH(int, prefsJobCount); + QFETCH(int, cliJobCount); + QFETCH(bool, projectPrecedence); + QFETCH(bool, expectSuccess); + SettingsPtr theSettings = settings(); + qbs::Internal::TemporaryProfile profile("jobLimitsProfile", theSettings.get()); + profile.p.setValue("preferences.jobLimit.singleton", prefsJobCount); + theSettings->sync(); + QbsRunParameters resolveParams("resolve"); + resolveParams.profile = profile.p.name(); + resolveParams.arguments << ("project.projectJobCount:" + QString::number(projectJobCount)) + << ("project.productJobCount:" + QString::number(productJobCount)) + << ("project.moduleJobCount:" + QString::number(moduleJobCount)); + QCOMPARE(runQbs(resolveParams), 0); + QbsRunParameters buildParams; + buildParams.expectFailure = !expectSuccess; + if (cliJobCount != -1) + buildParams.arguments << "--job-limits" << ("singleton:" + QString::number(cliJobCount)); + if (projectPrecedence) + buildParams.arguments << "--enforce-project-job-limits"; + buildParams.profile = profile.p.name(); + const int exitCode = runQbs(buildParams); + if (expectSuccess) + QCOMPARE(exitCode, 0); + else if (exitCode == 0) + QSKIP("no failure with no limit in place, result inconclusive"); + else + QVERIFY2(m_qbsStderr.contains("exclusive"), m_qbsStderr.constData()); + if (exitCode == 0) + QCOMPARE(m_qbsStdout.count("Running tool"), 7); +} + +QTEST_MAIN(TestBlackboxJobLimits) + +#include <tst_blackboxjoblimits.moc> diff --git a/tests/auto/blackbox/tst_blackboxqt.cpp b/tests/auto/blackbox/tst_blackboxqt.cpp index 3ab2c601c..3441255e2 100644 --- a/tests/auto/blackbox/tst_blackboxqt.cpp +++ b/tests/auto/blackbox/tst_blackboxqt.cpp @@ -64,6 +64,17 @@ void TestBlackboxQt::validateTestProfile() "in the global search paths.")); } +void TestBlackboxQt::addQObjectMacroToGeneratedCppFile() +{ + QDir::setCurrent(testDataDir + "/add-qobject-macro-to-generated-cpp-file"); + QCOMPARE(runQbs(), 0); + QVERIFY2(!m_qbsStdout.contains("moc"), m_qbsStdout.constData()); + WAIT_FOR_NEW_TIMESTAMP(); + REPLACE_IN_FILE("object.cpp.in", "// ", ""); + QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.contains("moc"), m_qbsStdout.constData()); +} + void TestBlackboxQt::autoQrc() { QDir::setCurrent(testDataDir + "/auto-qrc"); @@ -134,6 +145,21 @@ void TestBlackboxQt::dbusInterfaces() QCOMPARE(runQbs(), 0); } +void TestBlackboxQt::includedMocCpp() +{ + QDir::setCurrent(testDataDir + "/included-moc-cpp"); + QCOMPARE(runQbs(), 0); + QVERIFY2(!m_qbsStdout.contains("compiling moc_myobject.cpp"), m_qbsStdout.constData()); + WAIT_FOR_NEW_TIMESTAMP(); + REPLACE_IN_FILE("myobject.cpp", "#include <moc_myobject.cpp", "// #include <moc_myobject.cpp"); + QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.contains("compiling moc_myobject.cpp"), m_qbsStdout.constData()); + WAIT_FOR_NEW_TIMESTAMP(); + REPLACE_IN_FILE("myobject.cpp", "// #include <moc_myobject.cpp", "#include <moc_myobject.cpp"); + QCOMPARE(runQbs(), 0); + QVERIFY2(!m_qbsStdout.contains("compiling moc_myobject.cpp"), m_qbsStdout.constData()); +} + void TestBlackboxQt::lrelease() { QDir::setCurrent(testDataDir + QLatin1String("/lrelease")); @@ -230,6 +256,56 @@ void TestBlackboxQt::pluginMetaData() QVERIFY2(m_qbsStdout.contains("moc"), m_qbsStdout.constData()); } +void TestBlackboxQt::pluginSupport_data() +{ + QTest::addColumn<bool>("invalidPlugin"); + QTest::newRow("request valid plugins") << false; + QTest::newRow("request invalid plugin") << true; +} + +void TestBlackboxQt::pluginSupport() +{ + QDir::setCurrent(testDataDir + "/plugin-support"); + QFETCH(bool, invalidPlugin); + QbsRunParameters resolveParams("resolve"); + if (invalidPlugin) { + resolveParams.arguments << "modules.m1.useDummy:true"; + resolveParams.expectFailure = true; + } + QCOMPARE(runQbs(resolveParams) == 0, !invalidPlugin); + if (invalidPlugin) { + QVERIFY2(m_qbsStderr.contains("Plugin 'dummy' of type 'imageformats' was requested, " + "but is not available"), m_qbsStderr.constData()); + return; + } + const bool isStaticQt = m_qbsStdout.contains("static Qt: true"); + const bool isDynamicQt = m_qbsStdout.contains("static Qt: false"); + QVERIFY(isStaticQt != isDynamicQt); + if (isStaticQt) + QVERIFY2(m_qbsStdout.contains("platform plugin count: 1"), m_qbsStdout.constData()); + else + QVERIFY2(m_qbsStdout.contains("platform plugin count: 0"), m_qbsStdout.constData()); + const auto extractList = [this](const char sep) { + const int listStartIndex = m_qbsStdout.indexOf(sep); + const int listEndIndex = m_qbsStdout.indexOf(sep, listStartIndex + 1); + const QByteArray listString = m_qbsStdout.mid(listStartIndex + 1, + listEndIndex - listStartIndex - 1); + return listString.isEmpty() ? QByteArrayList() : listString.split(','); + }; + const QByteArrayList enabledPlugins = extractList('%'); + if (isStaticQt) + QCOMPARE(enabledPlugins.size(), 2); + else + QVERIFY(enabledPlugins.empty()); + const QByteArrayList allPlugins = extractList('#'); + QVERIFY(allPlugins.size() >= enabledPlugins.size()); + QCOMPARE(runQbs(), 0); + for (const QByteArray &plugin : allPlugins) { + QCOMPARE(m_qbsStdout.contains("qt_plugin_import_" + plugin + ".cpp"), + enabledPlugins.contains(plugin)); + } +} + void TestBlackboxQt::qmlDebugging() { QDir::setCurrent(testDataDir + "/qml-debugging"); @@ -371,6 +447,7 @@ void TestBlackboxQt::track_qrc() QVERIFY2(!m_qbsStdout.contains("compiling test.cpp"), m_qbsStdout.constData()); const QString fileName = relativeExecutableFilePath("i"); QVERIFY2(regularFileExists(fileName), qPrintable(fileName)); + QDateTime dt = QFileInfo(fileName).lastModified(); WAIT_FOR_NEW_TIMESTAMP(); { @@ -383,16 +460,42 @@ void TestBlackboxQt::track_qrc() REPLACE_IN_FILE("i.qbs", "//\"test.cpp\"", "\"test.cpp\""); waitForFileUnlock(); QCOMPARE(runQbs(QbsRunParameters("run")), 0); - QVERIFY2(m_qbsStdout.contains("rcc"), m_qbsStdout.constData()); + QVERIFY2(m_qbsStdout.contains("rcc bla.qrc"), m_qbsStdout.constData()); QVERIFY2(m_qbsStdout.contains("compiling test.cpp"), m_qbsStdout.constData()); QVERIFY(regularFileExists(fileName)); QVERIFY(dt < QFileInfo(fileName).lastModified()); + WAIT_FOR_NEW_TIMESTAMP(); touch("i.qbs"); QCOMPARE(runQbs(), 0); QVERIFY2(m_qbsStdout.contains("Resolving"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("rcc"), m_qbsStdout.constData()); QVERIFY2(!m_qbsStdout.contains("compiling test.cpp"), m_qbsStdout.constData()); + + // Turn on big resources. + WAIT_FOR_NEW_TIMESTAMP(); + QCOMPARE(runQbs(QbsRunParameters("resolve", {"modules.Qt.core.enableBigResources:true"})), 0); + QCOMPARE(runQbs(QbsRunParameters("run")), 0); + QVERIFY2(m_qbsStdout.contains("rcc (pass 1) bla.qrc"), m_qbsStdout.constData()); + QVERIFY2(m_qbsStdout.contains("rcc (pass 2) bla.qrc"), m_qbsStdout.constData()); + + // Check null build. + WAIT_FOR_NEW_TIMESTAMP(); + QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.contains("Building"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("rcc"), m_qbsStdout.constData()); + + // Turn off big resources. + WAIT_FOR_NEW_TIMESTAMP(); + QCOMPARE(runQbs(QbsRunParameters("resolve", {"modules.Qt.core.enableBigResources:false"})), 0); + QCOMPARE(runQbs(QbsRunParameters("run")), 0); + QVERIFY2(m_qbsStdout.contains("rcc bla.qrc"), m_qbsStdout.constData()); + + // Check null build. + WAIT_FOR_NEW_TIMESTAMP(); + QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.contains("Building"), m_qbsStdout.constData()); + QVERIFY2(!m_qbsStdout.contains("rcc"), m_qbsStdout.constData()); } void TestBlackboxQt::unmocable() diff --git a/tests/auto/blackbox/tst_blackboxqt.h b/tests/auto/blackbox/tst_blackboxqt.h index 0f7535224..f42c225d8 100644 --- a/tests/auto/blackbox/tst_blackboxqt.h +++ b/tests/auto/blackbox/tst_blackboxqt.h @@ -42,12 +42,14 @@ protected: void validateTestProfile() override; private slots: + void addQObjectMacroToGeneratedCppFile(); void autoQrc(); void cachedQml(); void combinedMoc(); void createProject(); void dbusAdaptors(); void dbusInterfaces(); + void includedMocCpp(); void lrelease(); void mixedBuildVariants(); void mocAndCppCombining(); @@ -55,6 +57,8 @@ private slots: void mocSameFileName(); void pkgconfig(); void pluginMetaData(); + void pluginSupport_data(); + void pluginSupport(); void qmlDebugging(); void qobjectInObjectiveCpp(); void qtKeywords(); diff --git a/tests/auto/cmdlineparser/tst_cmdlineparser.cpp b/tests/auto/cmdlineparser/tst_cmdlineparser.cpp index 88a458d53..15b9ec382 100644 --- a/tests/auto/cmdlineparser/tst_cmdlineparser.cpp +++ b/tests/auto/cmdlineparser/tst_cmdlineparser.cpp @@ -84,14 +84,11 @@ private slots: QVERIFY(parser.parseCommandLine(QStringList() << "-t" << m_fileArgs)); QVERIFY(parser.logTime()); - if (!Internal::HostOsInfo::isWindowsHost()) { // Windows has no progress bar atm. - // Note: We cannot just check for !parser.logTime() here, because if the test is not - // run in a terminal, "--show-progress" is ignored, in which case "--log-time" - // takes effect. - QVERIFY(parser.parseCommandLine(QStringList() << "-t" << "--show-progress" - << m_fileArgs)); - QVERIFY(parser.showProgress() != parser.logTime()); - } + // Note: We cannot just check for !parser.logTime() here, because if the test is not + // run in a terminal, "--show-progress" is ignored, in which case "--log-time" + // takes effect. + QVERIFY(parser.parseCommandLine(QStringList() << "-t" << "--show-progress" << m_fileArgs)); + QVERIFY(parser.showProgress() != parser.logTime()); QVERIFY(parser.parseCommandLine(QStringList() << "-vvqqq" << m_fileArgs)); QCOMPARE(ConsoleLogger::instance().logSink()->logLevel(), LoggerWarning); diff --git a/tests/auto/language/testdata/MyProperties.qbs b/tests/auto/language/testdata/MyProperties.qbs index b29bfc18f..cca5a9c9a 100644 --- a/tests/auto/language/testdata/MyProperties.qbs +++ b/tests/auto/language/testdata/MyProperties.qbs @@ -1,4 +1,2 @@ -import qbs - Properties { } diff --git a/tests/auto/language/testdata/additional-product-types.qbs b/tests/auto/language/testdata/additional-product-types.qbs index af510bed7..686650f42 100644 --- a/tests/auto/language/testdata/additional-product-types.qbs +++ b/tests/auto/language/testdata/additional-product-types.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "p" type: ["tag1"] diff --git a/tests/auto/language/testdata/base-validate/base-validate.qbs b/tests/auto/language/testdata/base-validate/base-validate.qbs index b1b025f94..657917739 100644 --- a/tests/auto/language/testdata/base-validate/base-validate.qbs +++ b/tests/auto/language/testdata/base-validate/base-validate.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "m" } } diff --git a/tests/auto/language/testdata/base-validate/modules/m/MParent.qbs b/tests/auto/language/testdata/base-validate/modules/m/MParent.qbs index 9874fbd5d..8b147cfa5 100644 --- a/tests/auto/language/testdata/base-validate/modules/m/MParent.qbs +++ b/tests/auto/language/testdata/base-validate/modules/m/MParent.qbs @@ -1,5 +1,3 @@ -import qbs - Module { condition: false validate: true diff --git a/tests/auto/language/testdata/base-validate/modules/m/m.qbs b/tests/auto/language/testdata/base-validate/modules/m/m.qbs index 6fcdc9ebc..6fca37adc 100644 --- a/tests/auto/language/testdata/base-validate/modules/m/m.qbs +++ b/tests/auto/language/testdata/base-validate/modules/m/m.qbs @@ -1,5 +1,3 @@ -import qbs - MParent { condition: true validate: { diff --git a/tests/auto/language/testdata/broken-dependency-cycle1.qbs b/tests/auto/language/testdata/broken-dependency-cycle1.qbs index d23e5b459..aef4eb588 100644 --- a/tests/auto/language/testdata/broken-dependency-cycle1.qbs +++ b/tests/auto/language/testdata/broken-dependency-cycle1.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "p1" diff --git a/tests/auto/language/testdata/broken-dependency-cycle2.qbs b/tests/auto/language/testdata/broken-dependency-cycle2.qbs index f0c6e4f57..69a6e4f85 100644 --- a/tests/auto/language/testdata/broken-dependency-cycle2.qbs +++ b/tests/auto/language/testdata/broken-dependency-cycle2.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "p1" diff --git a/tests/auto/language/testdata/builtinFunctionInSearchPathsProperty.qbs b/tests/auto/language/testdata/builtinFunctionInSearchPathsProperty.qbs index 0df9f4d5c..50ff29142 100644 --- a/tests/auto/language/testdata/builtinFunctionInSearchPathsProperty.qbs +++ b/tests/auto/language/testdata/builtinFunctionInSearchPathsProperty.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Environment Project { diff --git a/tests/auto/language/testdata/canonicalArchitecture.qbs b/tests/auto/language/testdata/canonicalArchitecture.qbs index 16c040ba0..4f548251b 100644 --- a/tests/auto/language/testdata/canonicalArchitecture.qbs +++ b/tests/auto/language/testdata/canonicalArchitecture.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities Product { diff --git a/tests/auto/language/testdata/chained-probes/chained-probes.qbs b/tests/auto/language/testdata/chained-probes/chained-probes.qbs index b1b025f94..657917739 100644 --- a/tests/auto/language/testdata/chained-probes/chained-probes.qbs +++ b/tests/auto/language/testdata/chained-probes/chained-probes.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "m" } } diff --git a/tests/auto/language/testdata/chained-probes/modules/m/m.qbs b/tests/auto/language/testdata/chained-probes/modules/m/m.qbs index cf7ab16c7..3c6bcd1c9 100644 --- a/tests/auto/language/testdata/chained-probes/modules/m/m.qbs +++ b/tests/auto/language/testdata/chained-probes/modules/m/m.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Probe { id: probe1 diff --git a/tests/auto/language/testdata/conditionaldepends.qbs b/tests/auto/language/testdata/conditionaldepends.qbs index e61888c9d..9a499da92 100644 --- a/tests/auto/language/testdata/conditionaldepends.qbs +++ b/tests/auto/language/testdata/conditionaldepends.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import "conditionaldepends_base.qbs" as CondBase Project { diff --git a/tests/auto/language/testdata/conditionaldepends_base.qbs b/tests/auto/language/testdata/conditionaldepends_base.qbs index 81782ba44..5ab5b973a 100644 --- a/tests/auto/language/testdata/conditionaldepends_base.qbs +++ b/tests/auto/language/testdata/conditionaldepends_base.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Application { name: 'conditionaldepends_base' property bool someProp: false diff --git a/tests/auto/language/testdata/defaultvalue/egon.qbs b/tests/auto/language/testdata/defaultvalue/egon.qbs index 7b254b0c8..6313e080a 100644 --- a/tests/auto/language/testdata/defaultvalue/egon.qbs +++ b/tests/auto/language/testdata/defaultvalue/egon.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "dep" diff --git a/tests/auto/language/testdata/defaultvalue/modules/higher/higher.qbs b/tests/auto/language/testdata/defaultvalue/modules/higher/higher.qbs index 9894f80cf..6639b811a 100644 --- a/tests/auto/language/testdata/defaultvalue/modules/higher/higher.qbs +++ b/tests/auto/language/testdata/defaultvalue/modules/higher/higher.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "lower" } lower.prop2: lower.prop1 === "egon" ? "withEgon" : original diff --git a/tests/auto/language/testdata/defaultvalue/modules/lower/lower.qbs b/tests/auto/language/testdata/defaultvalue/modules/lower/lower.qbs index 0540185e9..72cb23011 100644 --- a/tests/auto/language/testdata/defaultvalue/modules/lower/lower.qbs +++ b/tests/auto/language/testdata/defaultvalue/modules/lower/lower.qbs @@ -1,5 +1,3 @@ -import qbs - Module { property string prop1 property string prop2: prop1 === "blubb" ? "withBlubb" : "withoutBlubb" diff --git a/tests/auto/language/testdata/delayed-error/modules/m/m.qbs b/tests/auto/language/testdata/delayed-error/modules/m/m.qbs index 8529f47a4..4b562806b 100644 --- a/tests/auto/language/testdata/delayed-error/modules/m/m.qbs +++ b/tests/auto/language/testdata/delayed-error/modules/m/m.qbs @@ -1,5 +1,3 @@ -import qbs - Module { validate: { throw "Validation error!"; } } diff --git a/tests/auto/language/testdata/delayed-error/nonexisting.qbs b/tests/auto/language/testdata/delayed-error/nonexisting.qbs index 3825146c6..4034b7b94 100644 --- a/tests/auto/language/testdata/delayed-error/nonexisting.qbs +++ b/tests/auto/language/testdata/delayed-error/nonexisting.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property bool enableProduct: true Product { diff --git a/tests/auto/language/testdata/delayed-error/validation.qbs b/tests/auto/language/testdata/delayed-error/validation.qbs index e78c1d9e8..ee9fe05a5 100644 --- a/tests/auto/language/testdata/delayed-error/validation.qbs +++ b/tests/auto/language/testdata/delayed-error/validation.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property bool enableProduct: true Product { diff --git a/tests/auto/language/testdata/dependencyOnAllProfiles.qbs b/tests/auto/language/testdata/dependencyOnAllProfiles.qbs index f0ca56a8a..314a31166 100644 --- a/tests/auto/language/testdata/dependencyOnAllProfiles.qbs +++ b/tests/auto/language/testdata/dependencyOnAllProfiles.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property string profile1 property string profile2 diff --git a/tests/auto/language/testdata/derived-sub-project/DerivedSubProject.qbs b/tests/auto/language/testdata/derived-sub-project/DerivedSubProject.qbs index 313e04f24..391f56140 100644 --- a/tests/auto/language/testdata/derived-sub-project/DerivedSubProject.qbs +++ b/tests/auto/language/testdata/derived-sub-project/DerivedSubProject.qbs @@ -1,4 +1,2 @@ -import qbs - SubProject { } diff --git a/tests/auto/language/testdata/derived-sub-project/project.qbs b/tests/auto/language/testdata/derived-sub-project/project.qbs index 1aadd92ae..f001b422b 100644 --- a/tests/auto/language/testdata/derived-sub-project/project.qbs +++ b/tests/auto/language/testdata/derived-sub-project/project.qbs @@ -1,5 +1,3 @@ -import qbs - Project { DerivedSubProject { filePath: "subproject.qbs" diff --git a/tests/auto/language/testdata/derived-sub-project/subproject.qbs b/tests/auto/language/testdata/derived-sub-project/subproject.qbs index 18dc695f3..bdef20fd8 100644 --- a/tests/auto/language/testdata/derived-sub-project/subproject.qbs +++ b/tests/auto/language/testdata/derived-sub-project/subproject.qbs @@ -1,4 +1,2 @@ -import qbs - Product { } diff --git a/tests/auto/language/testdata/disabled-subproject.qbs b/tests/auto/language/testdata/disabled-subproject.qbs index 3074e5090..41891ef89 100644 --- a/tests/auto/language/testdata/disabled-subproject.qbs +++ b/tests/auto/language/testdata/disabled-subproject.qbs @@ -1,5 +1,3 @@ -import qbs - Project { SubProject { condition: false diff --git a/tests/auto/language/testdata/enum-project-props.qbs b/tests/auto/language/testdata/enum-project-props.qbs index 185ab7c28..8e2927ab7 100644 --- a/tests/auto/language/testdata/enum-project-props.qbs +++ b/tests/auto/language/testdata/enum-project-props.qbs @@ -1,5 +1,3 @@ -import qbs - Project { property string anExistingFile: "dummy.txt" Product { diff --git a/tests/auto/language/testdata/erroneous/ParentItem.qbs b/tests/auto/language/testdata/erroneous/ParentItem.qbs index b90756678..38cee2642 100644 --- a/tests/auto/language/testdata/erroneous/ParentItem.qbs +++ b/tests/auto/language/testdata/erroneous/ParentItem.qbs @@ -1,5 +1,3 @@ -import qbs - Product { property bool cpp readonly property string readOnlyString: "I cannot be changed!" diff --git a/tests/auto/language/testdata/erroneous/ParentWithExport.qbs b/tests/auto/language/testdata/erroneous/ParentWithExport.qbs index 0037d2c0f..d9ed02478 100644 --- a/tests/auto/language/testdata/erroneous/ParentWithExport.qbs +++ b/tests/auto/language/testdata/erroneous/ParentWithExport.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Export { property bool theProp diff --git a/tests/auto/language/testdata/erroneous/conflicting-module-instances.qbs b/tests/auto/language/testdata/erroneous/conflicting-module-instances.qbs index 28033b174..62a08f028 100644 --- a/tests/auto/language/testdata/erroneous/conflicting-module-instances.qbs +++ b/tests/auto/language/testdata/erroneous/conflicting-module-instances.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "conflicting-instances" } } diff --git a/tests/auto/language/testdata/erroneous/conflicting-properties-in-export-items.qbs b/tests/auto/language/testdata/erroneous/conflicting-properties-in-export-items.qbs index 021dc786b..309d1b4ff 100644 --- a/tests/auto/language/testdata/erroneous/conflicting-properties-in-export-items.qbs +++ b/tests/auto/language/testdata/erroneous/conflicting-properties-in-export-items.qbs @@ -1,5 +1,3 @@ -import qbs - ParentWithExport { Export { property string theProp diff --git a/tests/auto/language/testdata/erroneous/conflicting_fileTagsFilter.qbs b/tests/auto/language/testdata/erroneous/conflicting_fileTagsFilter.qbs index 54b3343e4..97e11bb9b 100644 --- a/tests/auto/language/testdata/erroneous/conflicting_fileTagsFilter.qbs +++ b/tests/auto/language/testdata/erroneous/conflicting_fileTagsFilter.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Application { Group { fileTagsFilter: "application" diff --git a/tests/auto/language/testdata/erroneous/dependency_cycle.qbs b/tests/auto/language/testdata/erroneous/dependency_cycle.qbs index dce212d9c..83a6e35f6 100644 --- a/tests/auto/language/testdata/erroneous/dependency_cycle.qbs +++ b/tests/auto/language/testdata/erroneous/dependency_cycle.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "A" diff --git a/tests/auto/language/testdata/erroneous/dependency_cycle2.qbs b/tests/auto/language/testdata/erroneous/dependency_cycle2.qbs index ab7a0d6f4..335355480 100644 --- a/tests/auto/language/testdata/erroneous/dependency_cycle2.qbs +++ b/tests/auto/language/testdata/erroneous/dependency_cycle2.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "A" diff --git a/tests/auto/language/testdata/erroneous/dependency_cycle3.qbs b/tests/auto/language/testdata/erroneous/dependency_cycle3.qbs index ab1629777..3297d5f5a 100644 --- a/tests/auto/language/testdata/erroneous/dependency_cycle3.qbs +++ b/tests/auto/language/testdata/erroneous/dependency_cycle3.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { type: ["a"] diff --git a/tests/auto/language/testdata/erroneous/dependency_cycle4.qbs b/tests/auto/language/testdata/erroneous/dependency_cycle4.qbs index 5d33a59c6..bd3a9feb1 100644 --- a/tests/auto/language/testdata/erroneous/dependency_cycle4.qbs +++ b/tests/auto/language/testdata/erroneous/dependency_cycle4.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "module-a" } } diff --git a/tests/auto/language/testdata/erroneous/duplicate_sources.qbs b/tests/auto/language/testdata/erroneous/duplicate_sources.qbs index 0546ac2e7..c056dc953 100644 --- a/tests/auto/language/testdata/erroneous/duplicate_sources.qbs +++ b/tests/auto/language/testdata/erroneous/duplicate_sources.qbs @@ -1,5 +1,3 @@ -import qbs - Product { files: ["main.cpp"] Group { diff --git a/tests/auto/language/testdata/erroneous/duplicate_sources_wildcards.qbs b/tests/auto/language/testdata/erroneous/duplicate_sources_wildcards.qbs index a51aa26d1..6443590b9 100644 --- a/tests/auto/language/testdata/erroneous/duplicate_sources_wildcards.qbs +++ b/tests/auto/language/testdata/erroneous/duplicate_sources_wildcards.qbs @@ -1,5 +1,3 @@ -import qbs - Product { files: ["*.qbs"] Group { diff --git a/tests/auto/language/testdata/erroneous/importloop1.qbs b/tests/auto/language/testdata/erroneous/importloop1.qbs index 91e8f620f..07a2487c4 100644 --- a/tests/auto/language/testdata/erroneous/importloop1.qbs +++ b/tests/auto/language/testdata/erroneous/importloop1.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import "importloop2.qbs" as X X {} diff --git a/tests/auto/language/testdata/erroneous/importloop2.qbs b/tests/auto/language/testdata/erroneous/importloop2.qbs index c41fe7e9f..a49a331c9 100644 --- a/tests/auto/language/testdata/erroneous/importloop2.qbs +++ b/tests/auto/language/testdata/erroneous/importloop2.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import "importloop1.qbs" as X X {} diff --git a/tests/auto/language/testdata/erroneous/invalid-parameter-rhs.qbs b/tests/auto/language/testdata/erroneous/invalid-parameter-rhs.qbs index 75dc83b3e..6389a9995 100644 --- a/tests/auto/language/testdata/erroneous/invalid-parameter-rhs.qbs +++ b/tests/auto/language/testdata/erroneous/invalid-parameter-rhs.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "prefix2.suffix" } Depends { name: "readonly"; prefix2.suffix.nope: access.will.fail } diff --git a/tests/auto/language/testdata/erroneous/invalid-parameter-type.qbs b/tests/auto/language/testdata/erroneous/invalid-parameter-type.qbs index 6a18a596c..72d075937 100644 --- a/tests/auto/language/testdata/erroneous/invalid-parameter-type.qbs +++ b/tests/auto/language/testdata/erroneous/invalid-parameter-type.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "module_with_parameters" } Depends { diff --git a/tests/auto/language/testdata/erroneous/invalid-property-option.qbs b/tests/auto/language/testdata/erroneous/invalid-property-option.qbs index 6e74faf8a..9c8d592e8 100644 --- a/tests/auto/language/testdata/erroneous/invalid-property-option.qbs +++ b/tests/auto/language/testdata/erroneous/invalid-property-option.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "module-with-wrong-property-option" } } diff --git a/tests/auto/language/testdata/erroneous/invalid-references.qbs b/tests/auto/language/testdata/erroneous/invalid-references.qbs index b224a45ac..6ea32aed8 100644 --- a/tests/auto/language/testdata/erroneous/invalid-references.qbs +++ b/tests/auto/language/testdata/erroneous/invalid-references.qbs @@ -1,5 +1,3 @@ -import qbs - Project { references: "nosuchproject.qbs" } diff --git a/tests/auto/language/testdata/erroneous/invalid_child_item_type.qbs b/tests/auto/language/testdata/erroneous/invalid_child_item_type.qbs index 2341d4b9c..45c426666 100644 --- a/tests/auto/language/testdata/erroneous/invalid_child_item_type.qbs +++ b/tests/auto/language/testdata/erroneous/invalid_child_item_type.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Depends { name: "foo" } } diff --git a/tests/auto/language/testdata/erroneous/invalid_file.qbs b/tests/auto/language/testdata/erroneous/invalid_file.qbs index 18f2b044d..c461b87ef 100644 --- a/tests/auto/language/testdata/erroneous/invalid_file.qbs +++ b/tests/auto/language/testdata/erroneous/invalid_file.qbs @@ -1,5 +1,3 @@ -import qbs - Application { files: ["main.cpp", "other.h"] } diff --git a/tests/auto/language/testdata/erroneous/invalid_property_type.qbs b/tests/auto/language/testdata/erroneous/invalid_property_type.qbs index b9b392736..e8907efff 100644 --- a/tests/auto/language/testdata/erroneous/invalid_property_type.qbs +++ b/tests/auto/language/testdata/erroneous/invalid_property_type.qbs @@ -1,5 +1,3 @@ -import qbs - Product { property nonsense esnesnon } diff --git a/tests/auto/language/testdata/erroneous/mismatching-multiplex-dependency.qbs b/tests/auto/language/testdata/erroneous/mismatching-multiplex-dependency.qbs index 4d9f7a380..f75db3960 100644 --- a/tests/auto/language/testdata/erroneous/mismatching-multiplex-dependency.qbs +++ b/tests/auto/language/testdata/erroneous/mismatching-multiplex-dependency.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "a" diff --git a/tests/auto/language/testdata/erroneous/missing-colon.qbs b/tests/auto/language/testdata/erroneous/missing-colon.qbs index f05a2e6a2..e62eb7cfd 100644 --- a/tests/auto/language/testdata/erroneous/missing-colon.qbs +++ b/tests/auto/language/testdata/erroneous/missing-colon.qbs @@ -1,5 +1,3 @@ -import qbs - CppApplication { cpp.dynamicLibraries { } } diff --git a/tests/auto/language/testdata/erroneous/misused-inherited-property.qbs b/tests/auto/language/testdata/erroneous/misused-inherited-property.qbs index 37ee04158..2a87b66b2 100644 --- a/tests/auto/language/testdata/erroneous/misused-inherited-property.qbs +++ b/tests/auto/language/testdata/erroneous/misused-inherited-property.qbs @@ -1,5 +1,3 @@ -import qbs - ParentItem { cpp.compilerName: "blubb" } diff --git a/tests/auto/language/testdata/erroneous/module-depends-on-product.qbs b/tests/auto/language/testdata/erroneous/module-depends-on-product.qbs index 24e480cd8..a7db9e036 100644 --- a/tests/auto/language/testdata/erroneous/module-depends-on-product.qbs +++ b/tests/auto/language/testdata/erroneous/module-depends-on-product.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "p1" diff --git a/tests/auto/language/testdata/erroneous/modules/module-a/module-a.qbs b/tests/auto/language/testdata/erroneous/modules/module-a/module-a.qbs index e0f24191c..e4ebde40c 100644 --- a/tests/auto/language/testdata/erroneous/modules/module-a/module-a.qbs +++ b/tests/auto/language/testdata/erroneous/modules/module-a/module-a.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "module-b" } } diff --git a/tests/auto/language/testdata/erroneous/modules/module-b/module-b.qbs b/tests/auto/language/testdata/erroneous/modules/module-b/module-b.qbs index fe3eb2b1e..482cdb131 100644 --- a/tests/auto/language/testdata/erroneous/modules/module-b/module-b.qbs +++ b/tests/auto/language/testdata/erroneous/modules/module-b/module-b.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "module-a" } } diff --git a/tests/auto/language/testdata/erroneous/modules/module-with-product-dependency/module-with-product-dependency.qbs b/tests/auto/language/testdata/erroneous/modules/module-with-product-dependency/module-with-product-dependency.qbs index c5fa5c06e..5781bd6de 100644 --- a/tests/auto/language/testdata/erroneous/modules/module-with-product-dependency/module-with-product-dependency.qbs +++ b/tests/auto/language/testdata/erroneous/modules/module-with-product-dependency/module-with-product-dependency.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "p2" } } diff --git a/tests/auto/language/testdata/erroneous/modules/module-with-wrong-property-option/m.qbs b/tests/auto/language/testdata/erroneous/modules/module-with-wrong-property-option/m.qbs index 8ea67f2c5..fb5c86553 100644 --- a/tests/auto/language/testdata/erroneous/modules/module-with-wrong-property-option/m.qbs +++ b/tests/auto/language/testdata/erroneous/modules/module-with-wrong-property-option/m.qbs @@ -1,5 +1,3 @@ -import qbs - Module { property string someProp PropertyOptions { diff --git a/tests/auto/language/testdata/erroneous/modules/no_such_property/no-such-property.qbs b/tests/auto/language/testdata/erroneous/modules/no_such_property/no-such-property.qbs index c836eafdf..a9d64f176 100644 --- a/tests/auto/language/testdata/erroneous/modules/no_such_property/no-such-property.qbs +++ b/tests/auto/language/testdata/erroneous/modules/no_such_property/no-such-property.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "module_with_parameters" } module_with_parameters.noSuchProperty: true diff --git a/tests/auto/language/testdata/erroneous/modules/prefix1/prefix1.qbs b/tests/auto/language/testdata/erroneous/modules/prefix1/prefix1.qbs index 3e67ba10d..84957060c 100644 --- a/tests/auto/language/testdata/erroneous/modules/prefix1/prefix1.qbs +++ b/tests/auto/language/testdata/erroneous/modules/prefix1/prefix1.qbs @@ -1,4 +1,2 @@ -import qbs - Module { } diff --git a/tests/auto/language/testdata/erroneous/modules/prefix1/suffix/suffix.qbs b/tests/auto/language/testdata/erroneous/modules/prefix1/suffix/suffix.qbs index 394794769..218a4feb7 100644 --- a/tests/auto/language/testdata/erroneous/modules/prefix1/suffix/suffix.qbs +++ b/tests/auto/language/testdata/erroneous/modules/prefix1/suffix/suffix.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "prefix1" } } diff --git a/tests/auto/language/testdata/erroneous/modules/prefix2/prefix2.qbs b/tests/auto/language/testdata/erroneous/modules/prefix2/prefix2.qbs index bda21b8d5..a5aaa6f8b 100644 --- a/tests/auto/language/testdata/erroneous/modules/prefix2/prefix2.qbs +++ b/tests/auto/language/testdata/erroneous/modules/prefix2/prefix2.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "prefix2.suffix" } } diff --git a/tests/auto/language/testdata/erroneous/modules/prefix2/suffix/suffix.qbs b/tests/auto/language/testdata/erroneous/modules/prefix2/suffix/suffix.qbs index 3e67ba10d..84957060c 100644 --- a/tests/auto/language/testdata/erroneous/modules/prefix2/suffix/suffix.qbs +++ b/tests/auto/language/testdata/erroneous/modules/prefix2/suffix/suffix.qbs @@ -1,4 +1,2 @@ -import qbs - Module { } diff --git a/tests/auto/language/testdata/erroneous/modules/readonly/readonly.qbs b/tests/auto/language/testdata/erroneous/modules/readonly/readonly.qbs index 07ff9b5c5..da3990dbb 100644 --- a/tests/auto/language/testdata/erroneous/modules/readonly/readonly.qbs +++ b/tests/auto/language/testdata/erroneous/modules/readonly/readonly.qbs @@ -1,5 +1,3 @@ -import qbs - Module { readonly property string readOnlyString: "I cannot be changed!" } diff --git a/tests/auto/language/testdata/erroneous/multiple_properties_in_subproject.qbs b/tests/auto/language/testdata/erroneous/multiple_properties_in_subproject.qbs index 0ecb41b34..04c5fe77f 100644 --- a/tests/auto/language/testdata/erroneous/multiple_properties_in_subproject.qbs +++ b/tests/auto/language/testdata/erroneous/multiple_properties_in_subproject.qbs @@ -1,5 +1,3 @@ -import qbs - Project { SubProject { Properties { condition: false } diff --git a/tests/auto/language/testdata/erroneous/no-configure-in-probe.qbs b/tests/auto/language/testdata/erroneous/no-configure-in-probe.qbs index a4aa3d957..42a36c21f 100644 --- a/tests/auto/language/testdata/erroneous/no-configure-in-probe.qbs +++ b/tests/auto/language/testdata/erroneous/no-configure-in-probe.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Probe { id: hurz diff --git a/tests/auto/language/testdata/erroneous/nonexistentouter.qbs b/tests/auto/language/testdata/erroneous/nonexistentouter.qbs index 6c5899b5d..fb7de461a 100644 --- a/tests/auto/language/testdata/erroneous/nonexistentouter.qbs +++ b/tests/auto/language/testdata/erroneous/nonexistentouter.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { name: outer diff --git a/tests/auto/language/testdata/erroneous/oldQbsVersion.qbs b/tests/auto/language/testdata/erroneous/oldQbsVersion.qbs index fb0915d83..90658e976 100644 --- a/tests/auto/language/testdata/erroneous/oldQbsVersion.qbs +++ b/tests/auto/language/testdata/erroneous/oldQbsVersion.qbs @@ -1,5 +1,3 @@ -import qbs - Project { minimumQbsVersion: "999.5.4" Product { diff --git a/tests/auto/language/testdata/erroneous/original-in-product-property.qbs b/tests/auto/language/testdata/erroneous/original-in-product-property.qbs index 867f3e0e7..cbc1cbe14 100644 --- a/tests/auto/language/testdata/erroneous/original-in-product-property.qbs +++ b/tests/auto/language/testdata/erroneous/original-in-product-property.qbs @@ -1,5 +1,3 @@ -import qbs - Product { property int n: original } diff --git a/tests/auto/language/testdata/erroneous/overwrite-inherited-readonly-property.qbs b/tests/auto/language/testdata/erroneous/overwrite-inherited-readonly-property.qbs index 629f39ae4..35b238a41 100644 --- a/tests/auto/language/testdata/erroneous/overwrite-inherited-readonly-property.qbs +++ b/tests/auto/language/testdata/erroneous/overwrite-inherited-readonly-property.qbs @@ -1,5 +1,3 @@ -import qbs - ParentItem { readOnlyString: "changing the unchangeable" } diff --git a/tests/auto/language/testdata/erroneous/overwrite-readonly-module-property.qbs b/tests/auto/language/testdata/erroneous/overwrite-readonly-module-property.qbs index 3e2f6927d..6b400a5e0 100644 --- a/tests/auto/language/testdata/erroneous/overwrite-readonly-module-property.qbs +++ b/tests/auto/language/testdata/erroneous/overwrite-readonly-module-property.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "readonly" } readonly.readOnlyString: "changing the unchangeable" diff --git a/tests/auto/language/testdata/erroneous/properties-item-with-invalid-condition.qbs b/tests/auto/language/testdata/erroneous/properties-item-with-invalid-condition.qbs index 00e3267c2..5b1a41f1b 100644 --- a/tests/auto/language/testdata/erroneous/properties-item-with-invalid-condition.qbs +++ b/tests/auto/language/testdata/erroneous/properties-item-with-invalid-condition.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "cpp" } Properties { diff --git a/tests/auto/language/testdata/erroneous/references_cycle.qbs b/tests/auto/language/testdata/erroneous/references_cycle.qbs index 6d0960f09..2dba23003 100644 --- a/tests/auto/language/testdata/erroneous/references_cycle.qbs +++ b/tests/auto/language/testdata/erroneous/references_cycle.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { references: ["references_cycle2.qbs"] } diff --git a/tests/auto/language/testdata/erroneous/references_cycle2.qbs b/tests/auto/language/testdata/erroneous/references_cycle2.qbs index 0b0d2734d..20a48a106 100644 --- a/tests/auto/language/testdata/erroneous/references_cycle2.qbs +++ b/tests/auto/language/testdata/erroneous/references_cycle2.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { references: ["references_cycle3.qbs"] } diff --git a/tests/auto/language/testdata/erroneous/references_cycle3.qbs b/tests/auto/language/testdata/erroneous/references_cycle3.qbs index 2a237d154..9af06d473 100644 --- a/tests/auto/language/testdata/erroneous/references_cycle3.qbs +++ b/tests/auto/language/testdata/erroneous/references_cycle3.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { references: ["references_cycle.qbs"] } diff --git a/tests/auto/language/testdata/erroneous/reserved_name_in_import.qbs b/tests/auto/language/testdata/erroneous/reserved_name_in_import.qbs index 3940109d0..d688556a5 100644 --- a/tests/auto/language/testdata/erroneous/reserved_name_in_import.qbs +++ b/tests/auto/language/testdata/erroneous/reserved_name_in_import.qbs @@ -1,4 +1,3 @@ -import qbs import "../idusagebase.qbs" as TextFile Product { } diff --git a/tests/auto/language/testdata/erroneous/rule-without-output-tags.qbs b/tests/auto/language/testdata/erroneous/rule-without-output-tags.qbs new file mode 100644 index 000000000..a05800e81 --- /dev/null +++ b/tests/auto/language/testdata/erroneous/rule-without-output-tags.qbs @@ -0,0 +1,11 @@ +Product { + Rule { + inputs: "input-tag" + prepare: { + var cmd = new JavaScriptCommand; + cmd.silent = true; + cmd.sourceCode = function() {}; + return cmd; + } + } +} diff --git a/tests/auto/language/testdata/erroneous/same-module-prefix1.qbs b/tests/auto/language/testdata/erroneous/same-module-prefix1.qbs index a5275eb15..8aba31c2a 100644 --- a/tests/auto/language/testdata/erroneous/same-module-prefix1.qbs +++ b/tests/auto/language/testdata/erroneous/same-module-prefix1.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "prefix1.suffix" } } diff --git a/tests/auto/language/testdata/erroneous/same-module-prefix2.qbs b/tests/auto/language/testdata/erroneous/same-module-prefix2.qbs index 3c4ec02a4..6679091c2 100644 --- a/tests/auto/language/testdata/erroneous/same-module-prefix2.qbs +++ b/tests/auto/language/testdata/erroneous/same-module-prefix2.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "prefix2" } } diff --git a/tests/auto/language/testdata/erroneous/subproject_cycle.qbs b/tests/auto/language/testdata/erroneous/subproject_cycle.qbs index 0a9cd289f..ff1904ab5 100644 --- a/tests/auto/language/testdata/erroneous/subproject_cycle.qbs +++ b/tests/auto/language/testdata/erroneous/subproject_cycle.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { SubProject { filePath: "subproject_cycle2.qbs" diff --git a/tests/auto/language/testdata/erroneous/subproject_cycle2.qbs b/tests/auto/language/testdata/erroneous/subproject_cycle2.qbs index ab92d76dd..2fe735714 100644 --- a/tests/auto/language/testdata/erroneous/subproject_cycle2.qbs +++ b/tests/auto/language/testdata/erroneous/subproject_cycle2.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { SubProject { filePath: "subproject_cycle3.qbs" diff --git a/tests/auto/language/testdata/erroneous/subproject_cycle3.qbs b/tests/auto/language/testdata/erroneous/subproject_cycle3.qbs index af1e50f5a..288922127 100644 --- a/tests/auto/language/testdata/erroneous/subproject_cycle3.qbs +++ b/tests/auto/language/testdata/erroneous/subproject_cycle3.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { SubProject { filePath: "subproject_cycle.qbs" diff --git a/tests/auto/language/testdata/erroneous/syntax-error-in-probe.qbs b/tests/auto/language/testdata/erroneous/syntax-error-in-probe.qbs index e81274395..a1f1c74ae 100644 --- a/tests/auto/language/testdata/erroneous/syntax-error-in-probe.qbs +++ b/tests/auto/language/testdata/erroneous/syntax-error-in-probe.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Probe { id: hurz diff --git a/tests/auto/language/testdata/erroneous/throw_in_property_binding.qbs b/tests/auto/language/testdata/erroneous/throw_in_property_binding.qbs index fc251b1a4..88deb2299 100644 --- a/tests/auto/language/testdata/erroneous/throw_in_property_binding.qbs +++ b/tests/auto/language/testdata/erroneous/throw_in_property_binding.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { name: { throw "something is wrong"; diff --git a/tests/auto/language/testdata/erroneous/undeclared-parameter1.qbs b/tests/auto/language/testdata/erroneous/undeclared-parameter1.qbs index 14f141678..fb858ef80 100644 --- a/tests/auto/language/testdata/erroneous/undeclared-parameter1.qbs +++ b/tests/auto/language/testdata/erroneous/undeclared-parameter1.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "prefix2.suffix" } Depends { name: "readonly"; prefix2.suffix.nope: "nope" } diff --git a/tests/auto/language/testdata/erroneous/undeclared-parameter2.qbs b/tests/auto/language/testdata/erroneous/undeclared-parameter2.qbs index 074acc1a3..6fe2ce51b 100644 --- a/tests/auto/language/testdata/erroneous/undeclared-parameter2.qbs +++ b/tests/auto/language/testdata/erroneous/undeclared-parameter2.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "myproduct" Depends { name: "readonly"; foo.bar: "bla" } diff --git a/tests/auto/language/testdata/erroneous/undeclared_item.qbs b/tests/auto/language/testdata/erroneous/undeclared_item.qbs index b2edbf013..ab25735b7 100644 --- a/tests/auto/language/testdata/erroneous/undeclared_item.qbs +++ b/tests/auto/language/testdata/erroneous/undeclared_item.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { cpp.defines: ["SUPERCRAZY"] } diff --git a/tests/auto/language/testdata/erroneous/undeclared_module_property_in_module.qbs b/tests/auto/language/testdata/erroneous/undeclared_module_property_in_module.qbs index 092bf143d..421302f22 100644 --- a/tests/auto/language/testdata/erroneous/undeclared_module_property_in_module.qbs +++ b/tests/auto/language/testdata/erroneous/undeclared_module_property_in_module.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "p" Depends { name: "no_such_property" } diff --git a/tests/auto/language/testdata/erroneous/undeclared_property.qbs b/tests/auto/language/testdata/erroneous/undeclared_property.qbs index 1dad5f747..a16ab3b93 100644 --- a/tests/auto/language/testdata/erroneous/undeclared_property.qbs +++ b/tests/auto/language/testdata/erroneous/undeclared_property.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { doesntexist: 123 } diff --git a/tests/auto/language/testdata/erroneous/undeclared_property_in_Properties_item.qbs b/tests/auto/language/testdata/erroneous/undeclared_property_in_Properties_item.qbs index d9bd00ce7..814513b10 100644 --- a/tests/auto/language/testdata/erroneous/undeclared_property_in_Properties_item.qbs +++ b/tests/auto/language/testdata/erroneous/undeclared_property_in_Properties_item.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Properties { condition: true diff --git a/tests/auto/language/testdata/erroneous/undeclared_property_in_export_item.qbs b/tests/auto/language/testdata/erroneous/undeclared_property_in_export_item.qbs index e5fc74b74..badfc7bf3 100644 --- a/tests/auto/language/testdata/erroneous/undeclared_property_in_export_item.qbs +++ b/tests/auto/language/testdata/erroneous/undeclared_property_in_export_item.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "p1" diff --git a/tests/auto/language/testdata/erroneous/undeclared_property_in_export_item2.qbs b/tests/auto/language/testdata/erroneous/undeclared_property_in_export_item2.qbs index 1cb4c42ee..82258ec0f 100644 --- a/tests/auto/language/testdata/erroneous/undeclared_property_in_export_item2.qbs +++ b/tests/auto/language/testdata/erroneous/undeclared_property_in_export_item2.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "p1" diff --git a/tests/auto/language/testdata/erroneous/undeclared_property_in_export_item3.qbs b/tests/auto/language/testdata/erroneous/undeclared_property_in_export_item3.qbs index cd23aefe4..ddeaf01db 100644 --- a/tests/auto/language/testdata/erroneous/undeclared_property_in_export_item3.qbs +++ b/tests/auto/language/testdata/erroneous/undeclared_property_in_export_item3.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "p1" diff --git a/tests/auto/language/testdata/erroneous/undeclared_property_wrapper.qbs b/tests/auto/language/testdata/erroneous/undeclared_property_wrapper.qbs index a5d9b19b3..9ab750765 100644 --- a/tests/auto/language/testdata/erroneous/undeclared_property_wrapper.qbs +++ b/tests/auto/language/testdata/erroneous/undeclared_property_wrapper.qbs @@ -1,5 +1,3 @@ -import qbs - Project { SubProject { filePath: "undeclared_property.qbs" diff --git a/tests/auto/language/testdata/erroneous/wrong-toplevel-item.qbs b/tests/auto/language/testdata/erroneous/wrong-toplevel-item.qbs index 57e60ba4a..b441c2eaf 100644 --- a/tests/auto/language/testdata/erroneous/wrong-toplevel-item.qbs +++ b/tests/auto/language/testdata/erroneous/wrong-toplevel-item.qbs @@ -1,4 +1,2 @@ -import qbs - Artifact { } diff --git a/tests/auto/language/testdata/erroneous/wrongQbsVersionFormat.qbs b/tests/auto/language/testdata/erroneous/wrongQbsVersionFormat.qbs index 36c9fea7c..41b195e75 100644 --- a/tests/auto/language/testdata/erroneous/wrongQbsVersionFormat.qbs +++ b/tests/auto/language/testdata/erroneous/wrongQbsVersionFormat.qbs @@ -1,5 +1,3 @@ -import qbs - Project { minimumQbsVersion: "hfyh1234wat?" } diff --git a/tests/auto/language/testdata/error-in-disabled-product.qbs b/tests/auto/language/testdata/error-in-disabled-product.qbs index 9f9b458a5..1d13412e1 100644 --- a/tests/auto/language/testdata/error-in-disabled-product.qbs +++ b/tests/auto/language/testdata/error-in-disabled-product.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "a" diff --git a/tests/auto/language/testdata/exports.qbs b/tests/auto/language/testdata/exports.qbs index 3f4e3cf49..cc86b1e4a 100644 --- a/tests/auto/language/testdata/exports.qbs +++ b/tests/auto/language/testdata/exports.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import "exports_product.qbs" as ProductWithInheritedExportItem Project { diff --git a/tests/auto/language/testdata/filetags.qbs b/tests/auto/language/testdata/filetags.qbs index b2a85f953..d055b7b1a 100644 --- a/tests/auto/language/testdata/filetags.qbs +++ b/tests/auto/language/testdata/filetags.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { FileTagger { patterns: "*.cpp" diff --git a/tests/auto/language/testdata/groupconditions.qbs b/tests/auto/language/testdata/groupconditions.qbs index 244c80c2c..b7f383d45 100644 --- a/tests/auto/language/testdata/groupconditions.qbs +++ b/tests/auto/language/testdata/groupconditions.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { property bool someTrueProperty: true Product { diff --git a/tests/auto/language/testdata/homeDirectory.qbs b/tests/auto/language/testdata/homeDirectory.qbs index 1ceeb5bbd..f04c173b9 100644 --- a/tests/auto/language/testdata/homeDirectory.qbs +++ b/tests/auto/language/testdata/homeDirectory.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { name: "home" diff --git a/tests/auto/language/testdata/id-uniqueness.qbs b/tests/auto/language/testdata/id-uniqueness.qbs index cfbaf8548..9f1bb7016 100644 --- a/tests/auto/language/testdata/id-uniqueness.qbs +++ b/tests/auto/language/testdata/id-uniqueness.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import "idusagebase.qbs" as DerivedProduct Project { diff --git a/tests/auto/language/testdata/idusage.qbs b/tests/auto/language/testdata/idusage.qbs index c55b47234..9a070cea6 100644 --- a/tests/auto/language/testdata/idusage.qbs +++ b/tests/auto/language/testdata/idusage.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import "idusagebase.qbs" as DerivedProduct Project { diff --git a/tests/auto/language/testdata/import-collection/project.qbs b/tests/auto/language/testdata/import-collection/project.qbs index ee34869b4..056cb3b4d 100644 --- a/tests/auto/language/testdata/import-collection/project.qbs +++ b/tests/auto/language/testdata/import-collection/project.qbs @@ -1,5 +1,3 @@ -import qbs - Project { references: ["product.qbs"] } diff --git a/tests/auto/language/testdata/invalid-overrides.qbs b/tests/auto/language/testdata/invalid-overrides.qbs index 93e6c34c8..af113ec13 100644 --- a/tests/auto/language/testdata/invalid-overrides.qbs +++ b/tests/auto/language/testdata/invalid-overrides.qbs @@ -1,5 +1,3 @@ -import qbs - Project { name: "My.Project" property bool x diff --git a/tests/auto/language/testdata/invalidBindingInDisabledItem.qbs b/tests/auto/language/testdata/invalidBindingInDisabledItem.qbs index e3e03a319..80895a515 100644 --- a/tests/auto/language/testdata/invalidBindingInDisabledItem.qbs +++ b/tests/auto/language/testdata/invalidBindingInDisabledItem.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { name: "product1" diff --git a/tests/auto/language/testdata/module-merging-variant-values/module-merging-variant-values.qbs b/tests/auto/language/testdata/module-merging-variant-values/module-merging-variant-values.qbs index e4bf0ad4f..c633dcc45 100644 --- a/tests/auto/language/testdata/module-merging-variant-values/module-merging-variant-values.qbs +++ b/tests/auto/language/testdata/module-merging-variant-values/module-merging-variant-values.qbs @@ -1,5 +1,3 @@ -import qbs - Product { multiplexByQbsProperties: ["architectures"] qbs.architectures: ["a1", "a2"] diff --git a/tests/auto/language/testdata/module-prioritization-by-search-path/product.qbs b/tests/auto/language/testdata/module-prioritization-by-search-path/product.qbs index 28033b174..62a08f028 100644 --- a/tests/auto/language/testdata/module-prioritization-by-search-path/product.qbs +++ b/tests/auto/language/testdata/module-prioritization-by-search-path/product.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "conflicting-instances" } } diff --git a/tests/auto/language/testdata/module-prioritization-by-search-path/project.qbs b/tests/auto/language/testdata/module-prioritization-by-search-path/project.qbs index 113a5773c..af1fe0e53 100644 --- a/tests/auto/language/testdata/module-prioritization-by-search-path/project.qbs +++ b/tests/auto/language/testdata/module-prioritization-by-search-path/project.qbs @@ -1,5 +1,3 @@ -import qbs - Project { references: ["product.qbs"] } diff --git a/tests/auto/language/testdata/module-property-overrides-per-product.qbs b/tests/auto/language/testdata/module-property-overrides-per-product.qbs index 3ff811080..88fee111a 100644 --- a/tests/auto/language/testdata/module-property-overrides-per-product.qbs +++ b/tests/auto/language/testdata/module-property-overrides-per-product.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { Depends { name: "dummy" } diff --git a/tests/auto/language/testdata/moduleproperties.qbs b/tests/auto/language/testdata/moduleproperties.qbs index d1c7e4e7f..8c9d57f16 100644 --- a/tests/auto/language/testdata/moduleproperties.qbs +++ b/tests/auto/language/testdata/moduleproperties.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { name: "MyProject" property string projectName: name diff --git a/tests/auto/language/testdata/modulepropertiesingroups.qbs b/tests/auto/language/testdata/modulepropertiesingroups.qbs index 5a1e75ab8..e3857bdf4 100644 --- a/tests/auto/language/testdata/modulepropertiesingroups.qbs +++ b/tests/auto/language/testdata/modulepropertiesingroups.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { name: "grouptest" diff --git a/tests/auto/language/testdata/modules/dummy2/dummy2.qbs b/tests/auto/language/testdata/modules/dummy2/dummy2.qbs index b4a223c19..9e47ee7d2 100644 --- a/tests/auto/language/testdata/modules/dummy2/dummy2.qbs +++ b/tests/auto/language/testdata/modules/dummy2/dummy2.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Module { additionalProductTypes: ["tag3"] diff --git a/tests/auto/language/testdata/modules/dummy3_loader/dummy3_loader.qbs b/tests/auto/language/testdata/modules/dummy3_loader/dummy3_loader.qbs index 988f86f11..fc4a3d6b8 100644 --- a/tests/auto/language/testdata/modules/dummy3_loader/dummy3_loader.qbs +++ b/tests/auto/language/testdata/modules/dummy3_loader/dummy3_loader.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Module { Depends { name: "dummy3" } dummy3.loadDummy: true diff --git a/tests/auto/language/testdata/modules/dummyqt/core/dummycore.qbs b/tests/auto/language/testdata/modules/dummyqt/core/dummycore.qbs index c6ec74003..746c7e37b 100644 --- a/tests/auto/language/testdata/modules/dummyqt/core/dummycore.qbs +++ b/tests/auto/language/testdata/modules/dummyqt/core/dummycore.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Module { id: qtcore property int versionMajor: 5 diff --git a/tests/auto/language/testdata/modules/dummyqt/gui/dummygui.qbs b/tests/auto/language/testdata/modules/dummyqt/gui/dummygui.qbs index 52dc82d23..b65d5ca14 100644 --- a/tests/auto/language/testdata/modules/dummyqt/gui/dummygui.qbs +++ b/tests/auto/language/testdata/modules/dummyqt/gui/dummygui.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Module { Depends { name: "dummyqt.core" } property string guiProperty: "guiProperty" diff --git a/tests/auto/language/testdata/modules/dummyqt/network/dummynetwork.qbs b/tests/auto/language/testdata/modules/dummyqt/network/dummynetwork.qbs index 2da3af050..8a685b9a7 100644 --- a/tests/auto/language/testdata/modules/dummyqt/network/dummynetwork.qbs +++ b/tests/auto/language/testdata/modules/dummyqt/network/dummynetwork.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Module { Depends { name: "dummyqt"; submodules: ["core"] } property string networkProperty: "networkProperty" diff --git a/tests/auto/language/testdata/modules/gmod/gmod1/gmod1.qbs b/tests/auto/language/testdata/modules/gmod/gmod1/gmod1.qbs index d3bb92fff..9a9c60871 100644 --- a/tests/auto/language/testdata/modules/gmod/gmod1/gmod1.qbs +++ b/tests/auto/language/testdata/modules/gmod/gmod1/gmod1.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "gmod2" } Depends { name: "gmod4" } diff --git a/tests/auto/language/testdata/modules/gmod2/gmod2.qbs b/tests/auto/language/testdata/modules/gmod2/gmod2.qbs index e221f50b2..dbaad572e 100644 --- a/tests/auto/language/testdata/modules/gmod2/gmod2.qbs +++ b/tests/auto/language/testdata/modules/gmod2/gmod2.qbs @@ -1,5 +1,3 @@ -import qbs - Module { property int prop: 0 property string gmod2_string: "gmod2_string_proto" diff --git a/tests/auto/language/testdata/modules/gmod3/qmod3.qbs b/tests/auto/language/testdata/modules/gmod3/qmod3.qbs index 1c8704b5d..dfd9c8c7b 100644 --- a/tests/auto/language/testdata/modules/gmod3/qmod3.qbs +++ b/tests/auto/language/testdata/modules/gmod3/qmod3.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "gmod2" } property string gmod3_string: "gmod3_string_proto" diff --git a/tests/auto/language/testdata/modules/gmod4/gmod4.qbs b/tests/auto/language/testdata/modules/gmod4/gmod4.qbs index c06f4e965..47c0b7517 100644 --- a/tests/auto/language/testdata/modules/gmod4/gmod4.qbs +++ b/tests/auto/language/testdata/modules/gmod4/gmod4.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "gmod2" } Depends { name: "gmod3" } diff --git a/tests/auto/language/testdata/modules/multiple_backends/backend1.qbs b/tests/auto/language/testdata/modules/multiple_backends/backend1.qbs index 011f96af8..794c67827 100644 --- a/tests/auto/language/testdata/modules/multiple_backends/backend1.qbs +++ b/tests/auto/language/testdata/modules/multiple_backends/backend1.qbs @@ -1,5 +1,3 @@ -import qbs - Module { condition: qbs.targetOS.contains("os1") property string prop: "backend 1" diff --git a/tests/auto/language/testdata/modules/multiple_backends/backend2.qbs b/tests/auto/language/testdata/modules/multiple_backends/backend2.qbs index 93532005e..2073c4d0b 100644 --- a/tests/auto/language/testdata/modules/multiple_backends/backend2.qbs +++ b/tests/auto/language/testdata/modules/multiple_backends/backend2.qbs @@ -1,5 +1,3 @@ -import qbs - Module { condition: qbs.targetOS.contains("os2") property string prop: "backend 2" diff --git a/tests/auto/language/testdata/modules/multiple_backends/backend3.qbs b/tests/auto/language/testdata/modules/multiple_backends/backend3.qbs index fda80b4ad..16228108b 100644 --- a/tests/auto/language/testdata/modules/multiple_backends/backend3.qbs +++ b/tests/auto/language/testdata/modules/multiple_backends/backend3.qbs @@ -1,5 +1,3 @@ -import qbs - Module { condition: qbs.targetOS.contains("os2") && qbs.toolchain.contains("tc") priority: 1 diff --git a/tests/auto/language/testdata/modules/scopemod/scopemod.qbs b/tests/auto/language/testdata/modules/scopemod/scopemod.qbs index ba7dbcbf0..a2c611dde 100644 --- a/tests/auto/language/testdata/modules/scopemod/scopemod.qbs +++ b/tests/auto/language/testdata/modules/scopemod/scopemod.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Module { property int a: 1 property int b: 1 diff --git a/tests/auto/language/testdata/modulescope.qbs b/tests/auto/language/testdata/modulescope.qbs index c127f0c61..c3c9db5d9 100644 --- a/tests/auto/language/testdata/modulescope.qbs +++ b/tests/auto/language/testdata/modulescope.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import "modulescope_base.qbs" as MyProduct Project { diff --git a/tests/auto/language/testdata/modulescope_base.qbs b/tests/auto/language/testdata/modulescope_base.qbs index 16a9875fa..85db4ec16 100644 --- a/tests/auto/language/testdata/modulescope_base.qbs +++ b/tests/auto/language/testdata/modulescope_base.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { Depends { name: "scopemod" } scopemod.h: e * f diff --git a/tests/auto/language/testdata/multiplexed-exports.qbs b/tests/auto/language/testdata/multiplexed-exports.qbs index 923ddc2ab..f98ceff95 100644 --- a/tests/auto/language/testdata/multiplexed-exports.qbs +++ b/tests/auto/language/testdata/multiplexed-exports.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "dep" diff --git a/tests/auto/language/testdata/multiplexing-by-profile/p1.qbs b/tests/auto/language/testdata/multiplexing-by-profile/p1.qbs index 207b5df61..b7abd942a 100644 --- a/tests/auto/language/testdata/multiplexing-by-profile/p1.qbs +++ b/tests/auto/language/testdata/multiplexing-by-profile/p1.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Profile { name: "theProfile" diff --git a/tests/auto/language/testdata/multiplexing-by-profile/p2.qbs b/tests/auto/language/testdata/multiplexing-by-profile/p2.qbs index 13db0afd7..94a0e4769 100644 --- a/tests/auto/language/testdata/multiplexing-by-profile/p2.qbs +++ b/tests/auto/language/testdata/multiplexing-by-profile/p2.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Profile { name: "profile1" diff --git a/tests/auto/language/testdata/multiplexing-by-profile/p3.qbs b/tests/auto/language/testdata/multiplexing-by-profile/p3.qbs index 4c01e7c46..49f998826 100644 --- a/tests/auto/language/testdata/multiplexing-by-profile/p3.qbs +++ b/tests/auto/language/testdata/multiplexing-by-profile/p3.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Profile { name: "profile1" diff --git a/tests/auto/language/testdata/multiplexing-by-profile/p4.qbs b/tests/auto/language/testdata/multiplexing-by-profile/p4.qbs index 84695e85d..c71b78b98 100644 --- a/tests/auto/language/testdata/multiplexing-by-profile/p4.qbs +++ b/tests/auto/language/testdata/multiplexing-by-profile/p4.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Profile { name: "profile1" diff --git a/tests/auto/language/testdata/non-required-products.qbs b/tests/auto/language/testdata/non-required-products.qbs index fb21e609e..6fc2cfe16 100644 --- a/tests/auto/language/testdata/non-required-products.qbs +++ b/tests/auto/language/testdata/non-required-products.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "depender" diff --git a/tests/auto/language/testdata/outerInGroup.qbs b/tests/auto/language/testdata/outerInGroup.qbs index 751392a4d..21136225a 100644 --- a/tests/auto/language/testdata/outerInGroup.qbs +++ b/tests/auto/language/testdata/outerInGroup.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Product { name: "OuterInGroup" diff --git a/tests/auto/language/testdata/overridden-properties-and-prototypes.qbs b/tests/auto/language/testdata/overridden-properties-and-prototypes.qbs index b0b37d804..0f6a1f812 100644 --- a/tests/auto/language/testdata/overridden-properties-and-prototypes.qbs +++ b/tests/auto/language/testdata/overridden-properties-and-prototypes.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "p" Depends { name: "multiple_backends" } diff --git a/tests/auto/language/testdata/parameter-types.qbs b/tests/auto/language/testdata/parameter-types.qbs index 6406d56c9..16415179f 100644 --- a/tests/auto/language/testdata/parameter-types.qbs +++ b/tests/auto/language/testdata/parameter-types.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "foo" diff --git a/tests/auto/language/testdata/productconditions.qbs b/tests/auto/language/testdata/productconditions.qbs index e815cc88e..bc3671134 100644 --- a/tests/auto/language/testdata/productconditions.qbs +++ b/tests/auto/language/testdata/productconditions.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import qbs.Probes Project { diff --git a/tests/auto/language/testdata/productdirectories.qbs b/tests/auto/language/testdata/productdirectories.qbs index dc4315207..ec24352a2 100644 --- a/tests/auto/language/testdata/productdirectories.qbs +++ b/tests/auto/language/testdata/productdirectories.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { name: "MyApp" } diff --git a/tests/auto/language/testdata/profilevaluesandoverriddenvalues.qbs b/tests/auto/language/testdata/profilevaluesandoverriddenvalues.qbs index 1cb88e18f..3aaa0cfa9 100644 --- a/tests/auto/language/testdata/profilevaluesandoverriddenvalues.qbs +++ b/tests/auto/language/testdata/profilevaluesandoverriddenvalues.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Project { Application { name: "product1" diff --git a/tests/auto/language/testdata/properties-block-in-group.qbs b/tests/auto/language/testdata/properties-block-in-group.qbs index c2bfea0a8..b77de7c6b 100644 --- a/tests/auto/language/testdata/properties-block-in-group.qbs +++ b/tests/auto/language/testdata/properties-block-in-group.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "in-group" property bool featureEnabled: true diff --git a/tests/auto/language/testdata/properties-item-in-module.qbs b/tests/auto/language/testdata/properties-item-in-module.qbs index 53c765d49..60f3afea0 100644 --- a/tests/auto/language/testdata/properties-item-in-module.qbs +++ b/tests/auto/language/testdata/properties-item-in-module.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "a"; Depends { name: "dummyqt.core" } } Product { name: "b"; Depends { name: "dummyqt.core" } } diff --git a/tests/auto/language/testdata/propertiesblocks.qbs b/tests/auto/language/testdata/propertiesblocks.qbs index d6a8dee23..34776cfac 100644 --- a/tests/auto/language/testdata/propertiesblocks.qbs +++ b/tests/auto/language/testdata/propertiesblocks.qbs @@ -1,4 +1,3 @@ -import qbs 1.0 import "propertiesblocks_base.qbs" as ProductBase Project { diff --git a/tests/auto/language/testdata/propertiesblocks_base.qbs b/tests/auto/language/testdata/propertiesblocks_base.qbs index d68c5127f..be6e57d65 100644 --- a/tests/auto/language/testdata/propertiesblocks_base.qbs +++ b/tests/auto/language/testdata/propertiesblocks_base.qbs @@ -1,5 +1,3 @@ -import qbs 1.0 - Product { property bool defineBase: true Depends { name: "dummy" } diff --git a/tests/auto/language/testdata/property-assignment-in-exported-group.qbs b/tests/auto/language/testdata/property-assignment-in-exported-group.qbs index d82f50ee6..7d48cf06d 100644 --- a/tests/auto/language/testdata/property-assignment-in-exported-group.qbs +++ b/tests/auto/language/testdata/property-assignment-in-exported-group.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "dep" diff --git a/tests/auto/language/testdata/qbs-properties-in-project-condition.qbs b/tests/auto/language/testdata/qbs-properties-in-project-condition.qbs index d3aa2d2ad..31f648233 100644 --- a/tests/auto/language/testdata/qbs-properties-in-project-condition.qbs +++ b/tests/auto/language/testdata/qbs-properties-in-project-condition.qbs @@ -1,5 +1,3 @@ -import qbs - Project { condition: qbs.targetOS.contains("whatever") diff --git a/tests/auto/language/testdata/qbs-property-convenience-override.qbs b/tests/auto/language/testdata/qbs-property-convenience-override.qbs index d4a8e7279..85f2d2327 100644 --- a/tests/auto/language/testdata/qbs-property-convenience-override.qbs +++ b/tests/auto/language/testdata/qbs-property-convenience-override.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "p" qbs.installPrefix: "/usr/local" diff --git a/tests/auto/language/testdata/qbs1275.qbs b/tests/auto/language/testdata/qbs1275.qbs index 898e1f165..f88d62a71 100644 --- a/tests/auto/language/testdata/qbs1275.qbs +++ b/tests/auto/language/testdata/qbs1275.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "v-bug" diff --git a/tests/auto/language/testdata/recursive-dependencies/recursive-dependencies.qbs b/tests/auto/language/testdata/recursive-dependencies/recursive-dependencies.qbs index 34d7089d3..e63ae5f5b 100644 --- a/tests/auto/language/testdata/recursive-dependencies/recursive-dependencies.qbs +++ b/tests/auto/language/testdata/recursive-dependencies/recursive-dependencies.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "p1" diff --git a/tests/auto/language/testdata/relaxed-error-mode/relaxed-error-mode.qbs b/tests/auto/language/testdata/relaxed-error-mode/relaxed-error-mode.qbs index fa6190ca4..561cda098 100644 --- a/tests/auto/language/testdata/relaxed-error-mode/relaxed-error-mode.qbs +++ b/tests/auto/language/testdata/relaxed-error-mode/relaxed-error-mode.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "recursive depender" diff --git a/tests/auto/language/testdata/required-and-nonrequired-dependencies/complicated.qbs b/tests/auto/language/testdata/required-and-nonrequired-dependencies/complicated.qbs index 2173948f9..2286c4c66 100644 --- a/tests/auto/language/testdata/required-and-nonrequired-dependencies/complicated.qbs +++ b/tests/auto/language/testdata/required-and-nonrequired-dependencies/complicated.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "failing-validation"; required: false } Depends { name: "failing-validation-indirect" } diff --git a/tests/auto/language/testdata/required-and-nonrequired-dependencies/dependency-via-export.qbs b/tests/auto/language/testdata/required-and-nonrequired-dependencies/dependency-via-export.qbs index a4de65cbe..2998308d1 100644 --- a/tests/auto/language/testdata/required-and-nonrequired-dependencies/dependency-via-export.qbs +++ b/tests/auto/language/testdata/required-and-nonrequired-dependencies/dependency-via-export.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "dep" diff --git a/tests/auto/language/testdata/required-and-nonrequired-dependencies/dependency-via-module.qbs b/tests/auto/language/testdata/required-and-nonrequired-dependencies/dependency-via-module.qbs index 74ab675e3..f279cbd87 100644 --- a/tests/auto/language/testdata/required-and-nonrequired-dependencies/dependency-via-module.qbs +++ b/tests/auto/language/testdata/required-and-nonrequired-dependencies/dependency-via-module.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "failing-validation"; required: false } Depends { name: "failing-validation-indirect" } diff --git a/tests/auto/language/testdata/required-and-nonrequired-dependencies/direct-dependencies.qbs b/tests/auto/language/testdata/required-and-nonrequired-dependencies/direct-dependencies.qbs index cf2f0f245..671a19666 100644 --- a/tests/auto/language/testdata/required-and-nonrequired-dependencies/direct-dependencies.qbs +++ b/tests/auto/language/testdata/required-and-nonrequired-dependencies/direct-dependencies.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "failing-validation"; required: false } Depends { name: "failing-validation" } diff --git a/tests/auto/language/testdata/required-and-nonrequired-dependencies/modules/failing-validation-indirect/failing-validation-indirect.qbs b/tests/auto/language/testdata/required-and-nonrequired-dependencies/modules/failing-validation-indirect/failing-validation-indirect.qbs index 45613b584..b715ae68c 100644 --- a/tests/auto/language/testdata/required-and-nonrequired-dependencies/modules/failing-validation-indirect/failing-validation-indirect.qbs +++ b/tests/auto/language/testdata/required-and-nonrequired-dependencies/modules/failing-validation-indirect/failing-validation-indirect.qbs @@ -1,5 +1,3 @@ -import qbs - Module { Depends { name: "failing-validation" } } diff --git a/tests/auto/language/testdata/required-and-nonrequired-dependencies/modules/failing-validation/failing-validation.qbs b/tests/auto/language/testdata/required-and-nonrequired-dependencies/modules/failing-validation/failing-validation.qbs index dcc650b93..f7fdc415f 100644 --- a/tests/auto/language/testdata/required-and-nonrequired-dependencies/modules/failing-validation/failing-validation.qbs +++ b/tests/auto/language/testdata/required-and-nonrequired-dependencies/modules/failing-validation/failing-validation.qbs @@ -1,5 +1,3 @@ -import qbs - Module { validate: { throw "validation error!"; } } diff --git a/tests/auto/language/testdata/required-and-nonrequired-dependencies/required-chain-export-indirect.qbs b/tests/auto/language/testdata/required-and-nonrequired-dependencies/required-chain-export-indirect.qbs index 293f737c0..3b3d86e9d 100644 --- a/tests/auto/language/testdata/required-and-nonrequired-dependencies/required-chain-export-indirect.qbs +++ b/tests/auto/language/testdata/required-and-nonrequired-dependencies/required-chain-export-indirect.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "dep2" diff --git a/tests/auto/language/testdata/required-and-nonrequired-dependencies/required-chain-export.qbs b/tests/auto/language/testdata/required-and-nonrequired-dependencies/required-chain-export.qbs index 6f2ec5566..19921c823 100644 --- a/tests/auto/language/testdata/required-and-nonrequired-dependencies/required-chain-export.qbs +++ b/tests/auto/language/testdata/required-and-nonrequired-dependencies/required-chain-export.qbs @@ -1,5 +1,3 @@ -import qbs - Project { Product { name: "dep" diff --git a/tests/auto/language/testdata/required-and-nonrequired-dependencies/required-chain-module.qbs b/tests/auto/language/testdata/required-and-nonrequired-dependencies/required-chain-module.qbs index ecc800e7b..262d5b6b6 100644 --- a/tests/auto/language/testdata/required-and-nonrequired-dependencies/required-chain-module.qbs +++ b/tests/auto/language/testdata/required-and-nonrequired-dependencies/required-chain-module.qbs @@ -1,5 +1,3 @@ -import qbs - Product { Depends { name: "failing-validation"; required: false } Depends { name: "failing-validation-indirect"; required: false } diff --git a/tests/auto/language/testdata/rfc1034identifier.qbs b/tests/auto/language/testdata/rfc1034identifier.qbs index eb73dc4d6..4d320f899 100644 --- a/tests/auto/language/testdata/rfc1034identifier.qbs +++ b/tests/auto/language/testdata/rfc1034identifier.qbs @@ -1,7 +1,9 @@ -import qbs import qbs.Utilities CppApplication { name: Utilities.rfc1034Identifier("this!has@special#characters$uh-oh,Undersc0r3s_Are.Bad") - bundle.infoPlist: { return {"CFBundleIdentifier": "$(PRODUCT_NAME:rfc1034identifier)"}; } + Properties { + condition: qbs.targetOS.contains("darwin") + bundle.infoPlist: { return {"CFBundleIdentifier": "$(PRODUCT_NAME:rfc1034identifier)"}; } + } } diff --git a/tests/auto/language/testdata/subdir/exports-mylib.qbs b/tests/auto/language/testdata/subdir/exports-mylib.qbs index 51e5b6831..92f39483a 100644 --- a/tests/auto/language/testdata/subdir/exports-mylib.qbs +++ b/tests/auto/language/testdata/subdir/exports-mylib.qbs @@ -1,5 +1,3 @@ -import qbs - StaticLibrary { name: "mylib" Depends { name: "dummy" } diff --git a/tests/auto/language/testdata/subdir2/exports-mylib2.qbs b/tests/auto/language/testdata/subdir2/exports-mylib2.qbs index a0cec6eb0..ac8b9ebe4 100644 --- a/tests/auto/language/testdata/subdir2/exports-mylib2.qbs +++ b/tests/auto/language/testdata/subdir2/exports-mylib2.qbs @@ -1,5 +1,3 @@ -import qbs - StaticLibrary { name: "mylib2" Depends { name: "dummy" } diff --git a/tests/auto/language/testdata/suppressed-and-non-suppressed-errors.qbs b/tests/auto/language/testdata/suppressed-and-non-suppressed-errors.qbs index dd1794a6d..4d5219157 100644 --- a/tests/auto/language/testdata/suppressed-and-non-suppressed-errors.qbs +++ b/tests/auto/language/testdata/suppressed-and-non-suppressed-errors.qbs @@ -1,5 +1,3 @@ -import qbs - Project { CppApplication { name: "mysterious creature" diff --git a/tests/auto/language/testdata/throwing-probe.qbs b/tests/auto/language/testdata/throwing-probe.qbs index 1fe059828..15a953251 100644 --- a/tests/auto/language/testdata/throwing-probe.qbs +++ b/tests/auto/language/testdata/throwing-probe.qbs @@ -1,5 +1,3 @@ -import qbs - Product { name: "theProduct" property bool enableProbe diff --git a/tests/auto/language/testdata/versionCompare.qbs b/tests/auto/language/testdata/versionCompare.qbs index 0a7271d14..8a363bf6e 100644 --- a/tests/auto/language/testdata/versionCompare.qbs +++ b/tests/auto/language/testdata/versionCompare.qbs @@ -1,4 +1,3 @@ -import qbs import qbs.Utilities Product { diff --git a/tests/auto/language/tst_language.cpp b/tests/auto/language/tst_language.cpp index fc16ca582..2bd5b5de8 100644 --- a/tests/auto/language/tst_language.cpp +++ b/tests/auto/language/tst_language.cpp @@ -820,7 +820,7 @@ void TestLanguage::erroneousFiles_data() QTest::newRow("throw_in_property_binding") << "something is wrong"; QTest::newRow("no-configure-in-probe") - << "no-configure-in-probe.qbs:4:5.*Probe.configure must be set"; + << "no-configure-in-probe.qbs:2:5.*Probe.configure must be set"; QTest::newRow("dependency_cycle") << "Cyclic dependencies detected."; QTest::newRow("dependency_cycle2") @@ -864,18 +864,18 @@ void TestLanguage::erroneousFiles_data() << "Conflicting fileTagsFilter in Group items"; QTest::newRow("duplicate_sources") << "Duplicate source file '.*main.cpp'" - ".*duplicate_sources.qbs:4:12.*duplicate_sources.qbs:6:16."; + ".*duplicate_sources.qbs:2:12.*duplicate_sources.qbs:4:16."; QTest::newRow("duplicate_sources_wildcards") << "Duplicate source file '.*duplicate_sources_wildcards.qbs'" - ".*duplicate_sources_wildcards.qbs:4:12" - ".*duplicate_sources_wildcards.qbs:6:16."; + ".*duplicate_sources_wildcards.qbs:2:12" + ".*duplicate_sources_wildcards.qbs:4:16."; QTest::newRow("oldQbsVersion") << "The project requires at least qbs version \\d+\\.\\d+.\\d+, " "but this is qbs version " QBS_VERSION "."; QTest::newRow("wrongQbsVersionFormat") << "The value '.*' of Project.minimumQbsVersion is not a valid version string."; QTest::newRow("properties-item-with-invalid-condition") - << "properties-item-with-invalid-condition.qbs:6:19.*TypeError: Result of expression " + << "properties-item-with-invalid-condition.qbs:4:19.*TypeError: Result of expression " "'cpp.nonexistingproperty'"; QTest::newRow("misused-inherited-property") << "Binding to non-item property"; QTest::newRow("undeclared_property_in_Properties_item") << "Item 'blubb' is not declared"; @@ -890,24 +890,27 @@ void TestLanguage::erroneousFiles_data() QTest::newRow("missing-colon") << "Invalid item 'cpp.dynamicLibraries'. Did you mean to set a module property?"; QTest::newRow("syntax-error-in-probe") - << "syntax-error-in-probe.qbs:6:20.*ReferenceError"; + << "syntax-error-in-probe.qbs:4:20.*ReferenceError"; QTest::newRow("wrong-toplevel-item") - << "wrong-toplevel-item.qbs:3:1.*The top-level item must be of type 'Project' or " + << "wrong-toplevel-item.qbs:1:1.*The top-level item must be of type 'Project' or " "'Product', but it is of type 'Artifact'."; QTest::newRow("conflicting-module-instances") << "There is more than one equally prioritized candidate for module " "'conflicting-instances'."; QTest::newRow("module-depends-on-product") - << "module-with-product-dependency.qbs:4:5.*Modules cannot depend on products."; + << "module-with-product-dependency.qbs:2:5.*Modules cannot depend on products."; QTest::newRow("overwrite-inherited-readonly-property") << "overwrite-inherited-readonly-property.qbs" - ":4:21.*Cannot set read-only property 'readOnlyString'."; + ":2:21.*Cannot set read-only property 'readOnlyString'."; QTest::newRow("overwrite-readonly-module-property") << "overwrite-readonly-module-property.qbs" - ":5:30.*Cannot set read-only property 'readOnlyString'."; + ":3:30.*Cannot set read-only property 'readOnlyString'."; QTest::newRow("original-in-product-property") << "original-in-product-property.qbs" - ":4:21.*The special value 'original' can only be used with module properties."; + ":2:21.*The special value 'original' can only be used with module properties."; + QTest::newRow("rule-without-output-tags") + << "rule-without-output-tags.qbs:2:5.*A rule needs to have Artifact items or " + "a non-empty outputFileTags property."; QTest::newRow("original-in-module-prototype") << "module-with-invalid-original.qbs:2:24.*The special value 'original' cannot be used " "on the right-hand side of a property declaration."; @@ -921,7 +924,7 @@ void TestLanguage::erroneousFiles_data() << "original-in-export-item3.qbs:6:9.*Item 'x.y' is not declared. Did you forget " "to add a Depends item"; QTest::newRow("mismatching-multiplex-dependency") - << "mismatching-multiplex-dependency.qbs:9:5.*Dependency from product " + << "mismatching-multiplex-dependency.qbs:7:5.*Dependency from product " "'b \\{\"architecture\":\"mips\"\\}' to product 'a \\{\"architecture\":\"mips\"\\}'" " not fulfilled."; QTest::newRow("duplicate-multiplex-value") @@ -930,7 +933,7 @@ void TestLanguage::erroneousFiles_data() << "duplicate-multiplex-value2.qbs:3:1.*Duplicate entry 'architecture' in " "Product.multiplexByQbsProperties."; QTest::newRow("invalid-references") - << "invalid-references.qbs:4:17.*Cannot open '.*nosuchproject.qbs'"; + << "invalid-references.qbs:2:17.*Cannot open '.*nosuchproject.qbs'"; } void TestLanguage::erroneousFiles() @@ -1414,8 +1417,8 @@ void TestLanguage::idUniqueness() const QList<ErrorItem> items = e.items(); QCOMPARE(items.size(), 3); QCOMPARE(items.at(0).toString(), QString::fromUtf8("The id 'baseProduct' is not unique.")); - QVERIFY(items.at(1).toString().contains("id-uniqueness.qbs:6:5 First occurrence is here.")); - QVERIFY(items.at(2).toString().contains("id-uniqueness.qbs:9:5 Next occurrence is here.")); + QVERIFY(items.at(1).toString().contains("id-uniqueness.qbs:5:5 First occurrence is here.")); + QVERIFY(items.at(2).toString().contains("id-uniqueness.qbs:8:5 Next occurrence is here.")); } QVERIFY(exceptionCaught); } diff --git a/tests/auto/shared.h b/tests/auto/shared.h index 6f2552774..f40a7dbfb 100644 --- a/tests/auto/shared.h +++ b/tests/auto/shared.h @@ -32,8 +32,10 @@ #include <tools/profile.h> #include <tools/settings.h> +#include <QtCore/qbytearray.h> #include <QtCore/qcryptographichash.h> #include <QtCore/qdatetime.h> +#include <QtCore/qdebug.h> #include <QtCore/qdir.h> #include <QtCore/qfile.h> #include <QtCore/qfileinfo.h> @@ -115,6 +117,79 @@ inline bool directoryExists(const QString &dirPath) return fi.exists() && fi.isDir(); } +struct ReadFileContentResult +{ + QByteArray content; + QString errorString; +}; + +inline ReadFileContentResult readFileContent(const QString &filePath) +{ + ReadFileContentResult result; + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) { + result.errorString = file.errorString(); + return result; + } + result.content = file.readAll(); + return result; +} + +inline QByteArray diffText(const QByteArray &actual, const QByteArray &expected) +{ + QByteArray result; + QList<QByteArray> actualLines = actual.split('\n'); + QList<QByteArray> expectedLines = expected.split('\n'); + int n = 1; + while (!actualLines.isEmpty() && !expectedLines.isEmpty()) { + QByteArray actualLine = actualLines.takeFirst(); + QByteArray expectedLine = expectedLines.takeFirst(); + if (actualLine != expectedLine) { + result += QStringLiteral("%1: actual: %2\n%1:expected: %3\n") + .arg(n, 2) + .arg(QString::fromUtf8(actualLine)) + .arg(QString::fromUtf8(expectedLine)) + .toUtf8(); + } + n++; + } + auto addLines = [&result, &n] (const QList<QByteArray> &lines) { + for (const QByteArray &line : qAsConst(lines)) { + result += QStringLiteral("%1: %2\n").arg(n).arg(QString::fromUtf8(line)); + n++; + } + }; + if (!actualLines.isEmpty()) { + result += "Extra unexpected lines:\n"; + addLines(actualLines); + } + if (!expectedLines.isEmpty()) { + result += "Missing expected lines:\n"; + addLines(expectedLines); + } + return result; +} + +#define READ_TEXT_FILE(filePath, contentVariable) \ + QByteArray contentVariable; \ + { \ + auto c = readFileContent(filePath); \ + QVERIFY2(c.errorString.isEmpty(), \ + qUtf8Printable(QStringLiteral("Cannot open file %1. %2") \ + .arg(filePath, c.errorString))); \ + contentVariable = std::move(c.content); \ + } + +#define TEXT_FILE_COMPARE(actualFilePath, expectedFilePath) \ + { \ + READ_TEXT_FILE(actualFilePath, ba1); \ + READ_TEXT_FILE(expectedFilePath, ba2); \ + if (ba1 != ba2) { \ + QByteArray msg = "File contents differ:\n" + diffText(ba1, ba2); \ + QFAIL(msg.constData()); \ + } \ + } + template <typename T> inline QString prefixedIfNonEmpty(const T &prefix, const QString &str) { diff --git a/tests/benchmarker/benchmarker.qbs b/tests/benchmarker/benchmarker.qbs index 200ab3189..72b535b42 100644 --- a/tests/benchmarker/benchmarker.qbs +++ b/tests/benchmarker/benchmarker.qbs @@ -2,11 +2,11 @@ import qbs QtApplication { name: "qbs_benchmarker" - destinationDirectory: "bin" type: "application" consoleApplication: true cpp.cxxLanguageVersion: "c++14" condition: Qt.concurrent.present + Depends { name: "qbsbuildconfig" } Depends { name: "Qt.concurrent" required: false @@ -24,4 +24,9 @@ QtApplication { "valgrindrunner.cpp", "valgrindrunner.h", ] + Group { + fileTagsFilter: product.type + qbs.install: true + qbs.installDir: qbsbuildconfig.appInstallDir + } } diff --git a/tests/fuzzy-test/fuzzy-test.qbs b/tests/fuzzy-test/fuzzy-test.qbs index 8dc468c4e..539374deb 100644 --- a/tests/fuzzy-test/fuzzy-test.qbs +++ b/tests/fuzzy-test/fuzzy-test.qbs @@ -2,9 +2,9 @@ import qbs QtApplication { name: "qbs_fuzzy-test" - destinationDirectory: "bin" type: "application" consoleApplication: true + Depends { name: "qbsbuildconfig" } cpp.cxxLanguageVersion: "c++14" files: [ "commandlineparser.cpp", @@ -13,4 +13,9 @@ QtApplication { "fuzzytester.h", "main.cpp", ] + Group { + fileTagsFilter: product.type + qbs.install: true + qbs.installDir: qbsbuildconfig.appInstallDir + } } diff --git a/tests/tests.qbs b/tests/tests.qbs index 3a2cd3aa0..52eafb3f0 100644 --- a/tests/tests.qbs +++ b/tests/tests.qbs @@ -1,4 +1,5 @@ import qbs +import qbs.FileInfo Project { references: [ @@ -16,7 +17,7 @@ Project { wrapper: project.autotestWrapper environment: { var env = base; - env.push("QBS_INSTALL_ROOT=" + qbs.installRoot); + env.push("QBS_INSTALL_DIR=" + FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix)); if (qbs.hostOS.contains("windows") && qbs.targetOS.contains("windows")) { var path = ""; for (var i = 0; i < env.length; ++i) { |