aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--VERSION2
-rw-r--r--doc/reference/items/convenience/application.qdoc25
-rw-r--r--doc/reference/items/convenience/autotestrunner.qdoc4
-rw-r--r--doc/reference/items/convenience/dynamiclibrary.qdoc49
-rw-r--r--doc/reference/items/convenience/staticlibrary.qdoc28
-rw-r--r--doc/reference/modules/autotest-module.qdoc69
-rw-r--r--doc/reference/modules/texttemplate-module.qdoc118
-rw-r--r--share/qbs/imports/qbs/base/Application.qbs10
-rw-r--r--share/qbs/imports/qbs/base/AutotestRunner.qbs28
-rw-r--r--share/qbs/imports/qbs/base/DynamicLibrary.qbs20
-rw-r--r--share/qbs/imports/qbs/base/NativeBinary.qbs4
-rw-r--r--share/qbs/imports/qbs/base/StaticLibrary.qbs9
-rw-r--r--share/qbs/modules/autotest/autotest.qbs7
-rw-r--r--share/qbs/modules/cpp/GenericGCC.qbs12
-rw-r--r--share/qbs/modules/cpp/windows-msvc.qbs8
-rw-r--r--share/qbs/modules/qbs/common.qbs2
-rw-r--r--share/qbs/modules/texttemplate/texttemplate.qbs64
-rw-r--r--src/app/shared/logging/coloredoutput.cpp12
-rw-r--r--src/app/shared/logging/coloredoutput.h1
-rw-r--r--src/app/shared/logging/consolelogger.cpp2
-rw-r--r--src/lib/corelib/buildgraph/rulesapplicator.cpp37
-rw-r--r--src/lib/corelib/language/artifactproperties.cpp4
-rw-r--r--src/lib/corelib/language/artifactproperties.h2
-rw-r--r--src/lib/corelib/language/projectresolver.cpp82
-rw-r--r--src/lib/corelib/language/scriptengine.cpp7
-rw-r--r--src/lib/corelib/language/scriptengine.h1
-rw-r--r--src/lib/corelib/language/scriptimporter.cpp3
-rw-r--r--src/lib/corelib/language/scriptimporter.h4
-rw-r--r--static-res.pro1
-rw-r--r--tests/auto/api/testdata/build-single-file/build-single-file.qbs7
-rw-r--r--tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs5
-rw-r--r--tests/auto/api/testdata/installed-artifact/installed-artifact.qbs7
-rw-r--r--tests/auto/api/testdata/multi-arch/multi-arch.qbs2
-rw-r--r--tests/auto/api/testdata/process-result/process-result.qbs6
-rw-r--r--tests/auto/api/testdata/recursive-wildcards/recursive-wildcards.qbs1
-rw-r--r--tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs5
-rw-r--r--tests/auto/blackbox/blackbox-android.pro3
-rw-r--r--tests/auto/blackbox/testdata-apple/apple-dmg/apple-dmg.qbs7
-rw-r--r--tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs70
-rw-r--r--tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs56
-rw-r--r--tests/auto/blackbox/testdata-apple/embedInfoPlist/embedInfoPlist.qbs12
-rw-r--r--tests/auto/blackbox/testdata-java/java/vehicles.qbs10
-rw-r--r--tests/auto/blackbox/testdata-qt/cached-qml/cached-qml.qbs9
-rw-r--r--tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs5
-rw-r--r--tests/auto/blackbox/testdata/QTBUG-51237/qtbug-51237.qbs5
-rw-r--r--tests/auto/blackbox/testdata/artifacts-map-race-condition/artifacts-map-race-condition.qbs6
-rw-r--r--tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs4
-rw-r--r--tests/auto/blackbox/testdata/autotests/autotests.qbs6
-rw-r--r--tests/auto/blackbox/testdata/autotests/test1/test1.cpp12
-rw-r--r--tests/auto/blackbox/testdata/autotests/test1/test1.qbs11
-rw-r--r--tests/auto/blackbox/testdata/autotests/test2/test2-resource.txt0
-rw-r--r--tests/auto/blackbox/testdata/autotests/test2/test2.cpp13
-rw-r--r--tests/auto/blackbox/testdata/autotests/test2/test2.qbs11
-rw-r--r--tests/auto/blackbox/testdata/autotests/test3/test3.cpp9
-rw-r--r--tests/auto/blackbox/testdata/autotests/test3/test3.qbs11
-rw-r--r--tests/auto/blackbox/testdata/build-directories/build-directories.qbs10
-rw-r--r--tests/auto/blackbox/testdata/choose-module-instance/gerbil.txt.in4
-rw-r--r--tests/auto/blackbox/testdata/choose-module-instance/modules/texttemplate/texttemplate.qbs49
-rw-r--r--tests/auto/blackbox/testdata/concurrent-executor/concurrent-executor.qbs5
-rw-r--r--tests/auto/blackbox/testdata/discard-unused-data/discard-unused-data.qbs5
-rw-r--r--tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs9
-rw-r--r--tests/auto/blackbox/testdata/env-merging/env-merging.qbs5
-rw-r--r--tests/auto/blackbox/testdata/erroneous/texttemplate-unknown-placeholder/boom.txt.in1
-rw-r--r--tests/auto/blackbox/testdata/erroneous/texttemplate-unknown-placeholder/texttemplate-unknown-placeholder.qbs8
-rw-r--r--tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs2
-rw-r--r--tests/auto/blackbox/testdata/exports-qbs/lib.qbs8
-rw-r--r--tests/auto/blackbox/testdata/exports-qbs/tool.qbs3
-rw-r--r--tests/auto/blackbox/testdata/filetagsfilter-merging/MyApplication.qbs11
-rw-r--r--tests/auto/blackbox/testdata/filetagsfilter-merging/filetagsfilter-merging.qbs29
-rw-r--r--tests/auto/blackbox/testdata/filetagsfilter-merging/main.cpp1
-rw-r--r--tests/auto/blackbox/testdata/install-locations/install-locations.qbs28
-rw-r--r--tests/auto/blackbox/testdata/install-locations/main.cpp1
-rw-r--r--tests/auto/blackbox/testdata/install-locations/thelib.cpp3
-rw-r--r--tests/auto/blackbox/testdata/install-tree/install-tree.qbs1
-rw-r--r--tests/auto/blackbox/testdata/installable-as-auxiliary-input/installable-as-auxiliary-input.qbs1
-rw-r--r--tests/auto/blackbox/testdata/installable/installable.qbs7
-rw-r--r--tests/auto/blackbox/testdata/installed-source-files/installed-source-files.qbs1
-rw-r--r--tests/auto/blackbox/testdata/installed-transformer-output/qbs668.qbs1
-rw-r--r--tests/auto/blackbox/testdata/invalid-install-dir/invalid-install-dir.qbs8
-rw-r--r--tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs5
-rw-r--r--tests/auto/blackbox/testdata/jsextensions-file/file.qbs5
-rw-r--r--tests/auto/blackbox/testdata/jsextensions-fileinfo/fileinfo.qbs5
-rw-r--r--tests/auto/blackbox/testdata/jsextensions-process/process.qbs5
-rw-r--r--tests/auto/blackbox/testdata/jsextensions-textfile/textfile.qbs5
-rw-r--r--tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs12
-rw-r--r--tests/auto/blackbox/testdata/list-properties-with-outer/modules/lower/lower.qbs5
-rw-r--r--tests/auto/blackbox/testdata/makefile-generator/app.qbs6
-rw-r--r--tests/auto/blackbox/testdata/nested-properties/modules/lowerlevel/lower-level.qbs5
-rw-r--r--tests/auto/blackbox/testdata/new-output-artifact/new-output-artifact.qbs1
-rw-r--r--tests/auto/blackbox/testdata/pkg-config-probe-sysroot/modules/themodule/themodule.qbs5
-rw-r--r--tests/auto/blackbox/testdata/pkg-config-probe/modules/themodule/themodule.qbs5
-rw-r--r--tests/auto/blackbox/testdata/probe-in-exported-module/modules/depmodule/depmodule.qbs5
-rw-r--r--tests/auto/blackbox/testdata/probe-in-exported-module/modules/mymodule/mymodule.qbs5
-rw-r--r--tests/auto/blackbox/testdata/probes-and-array-properties/modules/mymodule/mymodule.qbs6
-rw-r--r--tests/auto/blackbox/testdata/property-precedence/modules/leaf/leaf.qbs6
-rw-r--r--tests/auto/blackbox/testdata/recursive_renaming/recursive_renaming.qbs1
-rw-r--r--tests/auto/blackbox/testdata/recursive_wildcards/recursive_wildcards.qbs1
-rw-r--r--tests/auto/blackbox/testdata/response-files/response-files.qbs1
-rw-r--r--tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs33
-rw-r--r--tests/auto/blackbox/testdata/suspicious-calls/copy-command.qbs5
-rw-r--r--tests/auto/blackbox/testdata/suspicious-calls/copy-prepare.qbs5
-rw-r--r--tests/auto/blackbox/testdata/suspicious-calls/direntries-command.qbs5
-rw-r--r--tests/auto/blackbox/testdata/suspicious-calls/direntries-prepare.qbs5
-rw-r--r--tests/auto/blackbox/testdata/symlink-removal/symlink-removal.qbs5
-rw-r--r--tests/auto/blackbox/testdata/system-run-paths/system-run-paths.qbs1
-rw-r--r--tests/auto/blackbox/testdata/texttemplate/cdefgabc.txt.in1
-rw-r--r--tests/auto/blackbox/testdata/texttemplate/expected/lalala.txt1
-rw-r--r--tests/auto/blackbox/testdata/texttemplate/expected/output.txt12
-rw-r--r--tests/auto/blackbox/testdata/texttemplate/output.txt.in12
-rw-r--r--tests/auto/blackbox/testdata/texttemplate/texttemplatetest.qbs26
-rw-r--r--tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs7
-rw-r--r--tests/auto/blackbox/testdata/versionscript/versionscript.qbs12
-rw-r--r--tests/auto/blackbox/testdata/wildcard_renaming/wildcard_renaming.qbs1
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp135
-rw-r--r--tests/auto/blackbox/tst_blackbox.h6
-rw-r--r--tests/auto/blackbox/tst_blackboxapple.cpp6
-rw-r--r--tests/auto/language/testdata/erroneous/rule-without-output-tags.qbs13
-rw-r--r--tests/auto/language/tst_language.cpp3
-rw-r--r--tests/auto/shared.h75
119 files changed, 1115 insertions, 452 deletions
diff --git a/VERSION b/VERSION
index 0eed1a29e..feaae22ba 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.12.0
+1.13.0
diff --git a/doc/reference/items/convenience/application.qdoc b/doc/reference/items/convenience/application.qdoc
index de2bbae48..3c87f51f6 100644
--- a/doc/reference/items/convenience/application.qdoc
+++ b/doc/reference/items/convenience/application.qdoc
@@ -39,9 +39,30 @@
An Application item is a \l{Product} of the \l{Product::}{type}
\c "application".
- It exists for the convenience of project file authors.
-
\note On Android, an Application item instead builds a shared library for
products whose \l{Product::}{consoleApplication} property is set to
\c false.
*/
+
+/*!
+ \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.
+
+ \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/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/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/texttemplate-module.qdoc b/doc/reference/modules/texttemplate-module.qdoc
new file mode 100644
index 000000000..6d42560be
--- /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 outputFileName
+
+ The output file name that is assigned to produced artifacts.
+
+ \defaultvalue Complete base name of the input file
+*/
+
+/*!
+ \qmlproperty string outputTag
+
+ The output tag that is assigned to produced artifacts.
+
+ \defaultvalue \c{"text"}
+*/
diff --git a/share/qbs/imports/qbs/base/Application.qbs b/share/qbs/imports/qbs/base/Application.qbs
index e16a93761..7f26279c8 100644
--- a/share/qbs/imports/qbs/base/Application.qbs
+++ b/share/qbs/imports/qbs/base/Application.qbs
@@ -36,4 +36,14 @@ NativeBinary {
return ["dynamiclibrary", "android.nativelibrary"];
return ["application"];
}
+
+ 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/AutotestRunner.qbs b/share/qbs/imports/qbs/base/AutotestRunner.qbs
index 4f175d662..3b8461167 100644
--- a/share/qbs/imports/qbs/base/AutotestRunner.qbs
+++ b/share/qbs/imports/qbs/base/AutotestRunner.qbs
@@ -32,7 +32,6 @@ import qbs
import qbs.File
import qbs.FileInfo
import qbs.ModUtils
-import qbs.Utilities
Product {
name: "autotest-runner"
@@ -57,11 +56,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 +71,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/DynamicLibrary.qbs b/share/qbs/imports/qbs/base/DynamicLibrary.qbs
index 32d8fec41..4853b9598 100644
--- a/share/qbs/imports/qbs/base/DynamicLibrary.qbs
+++ b/share/qbs/imports/qbs/base/DynamicLibrary.qbs
@@ -32,4 +32,24 @@ 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/NativeBinary.qbs b/share/qbs/imports/qbs/base/NativeBinary.qbs
index 0a772b60c..ce8f458f4 100644
--- a/share/qbs/imports/qbs/base/NativeBinary.qbs
+++ b/share/qbs/imports/qbs/base/NativeBinary.qbs
@@ -33,6 +33,10 @@ 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" }
diff --git a/share/qbs/imports/qbs/base/StaticLibrary.qbs b/share/qbs/imports/qbs/base/StaticLibrary.qbs
index 1609bdcea..be5f7a7c4 100644
--- a/share/qbs/imports/qbs/base/StaticLibrary.qbs
+++ b/share/qbs/imports/qbs/base/StaticLibrary.qbs
@@ -32,4 +32,13 @@ 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/modules/autotest/autotest.qbs b/share/qbs/modules/autotest/autotest.qbs
new file mode 100644
index 000000000..36029df09
--- /dev/null
+++ b/share/qbs/modules/autotest/autotest.qbs
@@ -0,0 +1,7 @@
+import qbs
+
+Module {
+ property stringList arguments
+ property bool allowFailure: false
+ property string workingDir
+}
diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs
index 792e8ef4c..321f3ac71 100644
--- a/share/qbs/modules/cpp/GenericGCC.qbs
+++ b/share/qbs/modules/cpp/GenericGCC.qbs
@@ -390,7 +390,7 @@ CppModule {
|| product.multiplexConfigurationId
Rule {
- id: dynamicLibraryLinker
+ name: "dynamicLibraryLinker"
condition: product.cpp.shouldLink
multiplex: true
inputs: {
@@ -452,7 +452,7 @@ CppModule {
}
Rule {
- id: staticLibraryLinker
+ name: "staticLibraryLinker"
condition: product.cpp.shouldLink
multiplex: true
inputs: ["obj", "linkerscript"]
@@ -494,7 +494,7 @@ CppModule {
}
Rule {
- id: loadableModuleLinker
+ name: "loadableModuleLinker"
condition: product.cpp.shouldLink
multiplex: true
inputs: {
@@ -531,7 +531,7 @@ CppModule {
}
Rule {
- id: applicationLinker
+ name: "applicationLinker"
condition: product.cpp.shouldLink
multiplex: true
inputs: {
@@ -567,7 +567,7 @@ CppModule {
}
Rule {
- id: compiler
+ name: "compiler"
inputs: ["cpp", "c", "objcpp", "objc", "asm_cpp"]
auxiliaryInputs: ["hpp"]
explicitlyDependsOn: ["c_pch", "cpp_pch", "objc_pch", "objcpp_pch"]
@@ -592,7 +592,7 @@ CppModule {
}
Rule {
- id: assembler
+ name: "assembler"
inputs: ["asm"]
Artifact {
diff --git a/share/qbs/modules/cpp/windows-msvc.qbs b/share/qbs/modules/cpp/windows-msvc.qbs
index 3164e08b5..e86200ee3 100644
--- a/share/qbs/modules/cpp/windows-msvc.qbs
+++ b/share/qbs/modules/cpp/windows-msvc.qbs
@@ -170,7 +170,7 @@ CppModule {
}
Rule {
- id: compiler
+ name: "compiler"
inputs: ["cpp", "c"]
auxiliaryInputs: ["hpp"]
explicitlyDependsOn: ["c_pch", "cpp_pch"]
@@ -191,7 +191,7 @@ CppModule {
}
Rule {
- id: applicationLinker
+ name: "applicationLinker"
multiplex: true
inputs: ['obj', 'native.pe.manifest']
inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_app"]
@@ -221,7 +221,7 @@ CppModule {
}
Rule {
- id: dynamicLibraryLinker
+ name: "dynamicLibraryLinker"
multiplex: true
inputs: ['obj', 'native.pe.manifest']
inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_dll"]
@@ -256,7 +256,7 @@ CppModule {
}
Rule {
- id: libtool
+ name: "libtool"
multiplex: true
inputs: ["obj"]
inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
diff --git a/share/qbs/modules/qbs/common.qbs b/share/qbs/modules/qbs/common.qbs
index 86ce27c59..4e96a320b 100644
--- a/share/qbs/modules/qbs/common.qbs
+++ b/share/qbs/modules/qbs/common.qbs
@@ -102,7 +102,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 {
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/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/buildgraph/rulesapplicator.cpp b/src/lib/corelib/buildgraph/rulesapplicator.cpp
index da0e78592..4cb328f2c 100644
--- a/src/lib/corelib/buildgraph/rulesapplicator.cpp
+++ b/src/lib/corelib/buildgraph/rulesapplicator.cpp
@@ -65,6 +65,7 @@
#include <tools/qttools.h>
#include <tools/stringconstants.h>
+#include <QtCore/qcryptographichash.h>
#include <QtCore/qdir.h>
#include <QtScript/qscriptvalueiterator.h>
@@ -218,6 +219,10 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p
outputArtifacts.push_back(outputArtifact);
ruleArtifactArtifactMap.push_back({ ruleArtifact.get(), outputArtifact });
}
+ if (m_rule->artifacts.empty()) {
+ outputArtifacts.push_back(createOutputArtifactFromRuleArtifact(nullptr, inputArtifacts,
+ &outputFilePaths));
+ }
}
if (outputArtifacts.empty())
@@ -348,18 +353,34 @@ Artifact *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,
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/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp
index 4af79a5ce..ff74f845a 100644
--- a/src/lib/corelib/language/projectresolver.cpp
+++ b/src/lib/corelib/language/projectresolver.cpp
@@ -97,7 +97,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;
QHash<QString, CodeLocation> sourceArtifactLocations;
GroupConstPtr currentGroup;
@@ -692,19 +692,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 +727,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 +770,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) {
@@ -1161,19 +1174,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());
diff --git a/src/lib/corelib/language/scriptengine.cpp b/src/lib/corelib/language/scriptengine.cpp
index e983ae945..a1661faf4 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();
}
diff --git a/src/lib/corelib/language/scriptengine.h b/src/lib/corelib/language/scriptengine.h
index 11ed51a49..6349744e0 100644
--- a/src/lib/corelib/language/scriptengine.h
+++ b/src/lib/corelib/language/scriptengine.h
@@ -299,6 +299,7 @@ private:
QScriptClass *m_modulePropertyScriptClass;
QScriptClass *m_productPropertyScriptClass = nullptr;
QHash<JsImport, QScriptValue> m_jsImportCache;
+ std::unordered_map<QString, QScriptValue> m_jsFileCache;
bool m_propertyCacheEnabled;
bool m_active;
QHash<PropertyCacheKey, QVariant> m_propertyCache;
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/static-res.pro b/static-res.pro
index b35836ece..a01b3a83b 100644
--- a/static-res.pro
+++ b/static-res.pro
@@ -21,6 +21,7 @@ qbsres.commands = \
-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/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..6389713d9 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
@@ -2,6 +2,7 @@ import qbs
import qbs.TextFile
CppApplication {
+ consoleApplication: true
files: ["ignored1.cpp", "ignored2.cpp", "compiled.cpp"]
cpp.includePaths: [buildDirectory]
@@ -10,10 +11,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/infinite-loop-process/infinite-loop.qbs b/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs
index 6155baf28..fb09b9a97 100644
--- a/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs
+++ b/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs
@@ -14,10 +14,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/installed-artifact/installed-artifact.qbs b/tests/auto/api/testdata/installed-artifact/installed-artifact.qbs
index e2d18b2ea..4a355c385 100644
--- a/tests/auto/api/testdata/installed-artifact/installed-artifact.qbs
+++ b/tests/auto/api/testdata/installed-artifact/installed-artifact.qbs
@@ -18,11 +18,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/multi-arch/multi-arch.qbs b/tests/auto/api/testdata/multi-arch/multi-arch.qbs
index d54809a41..99d9aa817 100644
--- a/tests/auto/api/testdata/multi-arch/multi-arch.qbs
+++ b/tests/auto/api/testdata/multi-arch/multi-arch.qbs
@@ -14,6 +14,7 @@ Project {
files: "host+target.input"
fileTags: "input"
}
+ qbs.installPrefix: ""
Group {
fileTagsFilter: "output"
qbs.install: true
@@ -28,6 +29,7 @@ Project {
files: "host-tool.input"
fileTags: "input"
}
+ qbs.installPrefix: ""
Group {
fileTagsFilter: "output"
qbs.install: 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..24fc595bc 100644
--- a/tests/auto/api/testdata/process-result/process-result.qbs
+++ b/tests/auto/api/testdata/process-result/process-result.qbs
@@ -15,11 +15,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/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/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..bbeb29664 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
@@ -3,12 +3,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/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/testdata-apple/apple-dmg/apple-dmg.qbs b/tests/auto/blackbox/testdata-apple/apple-dmg/apple-dmg.qbs
index 3bccebfd0..010e5f7c7 100644
--- a/tests/auto/blackbox/testdata-apple/apple-dmg/apple-dmg.qbs
+++ b/tests/auto/blackbox/testdata-apple/apple-dmg/apple-dmg.qbs
@@ -18,12 +18,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 ae2fcd402..ea67b6e44 100644
--- a/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs
+++ b/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs
@@ -17,11 +17,8 @@ Project {
aggregate: false
multiplexByQbsProperties: []
- Group {
- fileTagsFilter: ["bundle.content"]
- qbs.install: true
- qbs.installSourceBase: product.buildDirectory
- }
+ install: true
+ installDir: ""
}
CppApplication {
@@ -38,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 {
@@ -58,11 +52,8 @@ Project {
aggregate: false
multiplexByQbsProperties: []
- Group {
- fileTagsFilter: ["bundle.content"]
- qbs.install: true
- qbs.installSourceBase: product.buildDirectory
- }
+ install: true
+ installDir: ""
}
CppApplication {
@@ -74,11 +65,8 @@ Project {
cpp.rpaths: [cpp.rpathOrigin + "/../../../"]
cpp.minimumMacosVersion: "10.5"
- Group {
- fileTagsFilter: ["bundle.content"]
- qbs.install: true
- qbs.installSourceBase: product.buildDirectory
- }
+ install: true
+ installDir: ""
}
CppApplication {
@@ -91,11 +79,8 @@ Project {
cpp.minimumMacosVersion: "10.5"
qbs.architectures: ["x86", "x86_64"]
- Group {
- fileTagsFilter: ["bundle.content"]
- qbs.install: true
- qbs.installSourceBase: product.buildDirectory
- }
+ install: true
+ installDir: ""
}
CppApplication {
@@ -109,11 +94,8 @@ Project {
qbs.architectures: ["x86", "x86_64"]
qbs.buildVariants: ["debug", "profile"]
- Group {
- fileTagsFilter: ["bundle.content"]
- qbs.install: true
- qbs.installSourceBase: product.buildDirectory
- }
+ install: true
+ installDir: ""
}
DynamicLibrary {
@@ -127,11 +109,8 @@ Project {
qbs.architectures: ["x86", "x86_64"]
qbs.buildVariants: ["release", "debug", "profile"]
- Group {
- fileTagsFilter: ["bundle.content"]
- qbs.install: true
- qbs.installSourceBase: product.buildDirectory
- }
+ install: true
+ installDir: ""
}
DynamicLibrary {
@@ -145,11 +124,8 @@ Project {
qbs.architectures: ["x86", "x86_64"]
qbs.buildVariants: ["debug", "profile"]
- Group {
- fileTagsFilter: ["bundle.content"]
- qbs.install: true
- qbs.installSourceBase: product.buildDirectory
- }
+ install: true
+ installDir: ""
}
DynamicLibrary {
@@ -162,11 +138,8 @@ Project {
cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)]
qbs.architectures: ["x86", "x86_64"]
qbs.buildVariants: ["debug", "profile"]
- Group {
- fileTagsFilter: ["bundle.content"]
- qbs.install: true
- qbs.installSourceBase: product.buildDirectory
- }
+ install: true
+ installDir: ""
}
DynamicLibrary {
Depends { name: "cpp" }
@@ -177,10 +150,7 @@ Project {
cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)]
qbs.architectures: ["x86", "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..13a205730 100644
--- a/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs
+++ b/tests/auto/blackbox/testdata-apple/bundle-structure/bundle-structure.qbs
@@ -17,11 +17,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 +34,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 +51,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 +64,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 +77,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 +90,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 +103,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 +116,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/embedInfoPlist/embedInfoPlist.qbs b/tests/auto/blackbox/testdata-apple/embedInfoPlist/embedInfoPlist.qbs
index c0d77aefd..87f6c1750 100644
--- a/tests/auto/blackbox/testdata-apple/embedInfoPlist/embedInfoPlist.qbs
+++ b/tests/auto/blackbox/testdata-apple/embedInfoPlist/embedInfoPlist.qbs
@@ -13,10 +13,8 @@ Project {
bundle.infoPlist: ({
"QBS": "org.qt-project.qbs.testdata.embedInfoPlist"
})
- Group {
- fileTagsFilter: product.type
- qbs.install: true
- }
+ install: true
+ installDir: ""
}
DynamicLibrary {
@@ -30,10 +28,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-java/java/vehicles.qbs b/tests/auto/blackbox/testdata-java/java/vehicles.qbs
index 86d1f7d32..4051bb6e4 100644
--- a/tests/auto/blackbox/testdata-java/java/vehicles.qbs
+++ b/tests/auto/blackbox/testdata-java/java/vehicles.qbs
@@ -14,10 +14,9 @@ Project {
name: "native"
files: ["engine.c"]
- Group {
- fileTagsFilter: ["dynamiclibrary"]
- qbs.install: true
- }
+ qbs.installPrefix: ""
+ install: true
+ installDir: ""
}
JavaClassCollection {
@@ -44,6 +43,7 @@ Project {
name: "random_stuff"
files: ["RandomStuff.java"]
+ qbs.installPrefix: ""
Group {
fileTagsFilter: ["java.jar"]
qbs.install: true
@@ -78,6 +78,7 @@ Project {
java.manifestClassPath: [product.targetName + ".jar"]
}
+ qbs.installPrefix: ""
Group {
fileTagsFilter: ["java.jar"]
qbs.install: true
@@ -98,6 +99,7 @@ Project {
return mf;
}
+ qbs.installPrefix: ""
Group {
fileTagsFilter: ["java.jar"]
qbs.install: true
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..397c2a691 100644
--- a/tests/auto/blackbox/testdata-qt/cached-qml/cached-qml.qbs
+++ b/tests/auto/blackbox/testdata-qt/cached-qml/cached-qml.qbs
@@ -3,9 +3,13 @@ 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 +20,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/qtscxml/qtscxml.qbs b/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs
index e010e76e6..4a26550b7 100644
--- a/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs
+++ b/tests/auto/blackbox/testdata-qt/qtscxml/qtscxml.qbs
@@ -29,10 +29,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/QTBUG-51237/qtbug-51237.qbs b/tests/auto/blackbox/testdata/QTBUG-51237/qtbug-51237.qbs
index 6edea9dc6..33539a5a1 100644
--- a/tests/auto/blackbox/testdata/QTBUG-51237/qtbug-51237.qbs
+++ b/tests/auto/blackbox/testdata/QTBUG-51237/qtbug-51237.qbs
@@ -5,10 +5,7 @@ Product {
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/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..af568ae45 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
@@ -5,7 +5,7 @@ Product {
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 +24,7 @@ Product {
}
Rule {
multiplex: true
- Artifact { filePath: "helperdummy"; fileTags: "helper" }
+ outputFileTags: "helper"
prepare: {
var cmd = new JavaScriptCommand();
cmd.description = "helper";
@@ -55,7 +55,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/autotest-with-dependencies/autotest-with-dependencies.qbs b/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs
index 6850ee138..682b4c029 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
@@ -6,18 +6,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..b08bc425c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/autotests/autotests.qbs
@@ -0,0 +1,6 @@
+import qbs
+
+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..78326994d
--- /dev/null
+++ b/tests/auto/blackbox/testdata/autotests/test1/test1.qbs
@@ -0,0 +1,11 @@
+import qbs
+
+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..0f110e1e7
--- /dev/null
+++ b/tests/auto/blackbox/testdata/autotests/test2/test2.qbs
@@ -0,0 +1,11 @@
+import qbs
+
+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..3c7b734e3
--- /dev/null
+++ b/tests/auto/blackbox/testdata/autotests/test3/test3.qbs
@@ -0,0 +1,11 @@
+import qbs
+
+CppApplication {
+ name: "test3"
+ type: base.concat("autotest")
+
+ Depends { name: "autotest" }
+ autotest.allowFailure: true
+
+ files: "test3.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..60a4e76dd 100644
--- a/tests/auto/blackbox/testdata/build-directories/build-directories.qbs
+++ b/tests/auto/blackbox/testdata/build-directories/build-directories.qbs
@@ -6,10 +6,7 @@ Project {
type: "blubb1"
Rule {
multiplex: true
- Artifact {
- filePath: "dummy1.txt"
- fileTags: product.type
- }
+ outputFileTags: "blubb1"
prepare: {
var cmd = new JavaScriptCommand();
cmd.silent = true;
@@ -26,10 +23,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/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/concurrent-executor/concurrent-executor.qbs b/tests/auto/blackbox/testdata/concurrent-executor/concurrent-executor.qbs
index 9031890bd..99fec93f2 100644
--- a/tests/auto/blackbox/testdata/concurrent-executor/concurrent-executor.qbs
+++ b/tests/auto/blackbox/testdata/concurrent-executor/concurrent-executor.qbs
@@ -52,10 +52,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/discard-unused-data/discard-unused-data.qbs b/tests/auto/blackbox/testdata/discard-unused-data/discard-unused-data.qbs
index 6f433cf63..b7cca4fa8 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
@@ -14,10 +14,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/dynamic-library-in-module/Dll.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs
index 0f897df67..565402a31 100644
--- a/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs
+++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs
@@ -9,8 +9,9 @@ DynamicLibrary {
cpp.minimumMacosVersion: "10.5" // 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/env-merging/env-merging.qbs b/tests/auto/blackbox/testdata/env-merging/env-merging.qbs
index 7f3f73550..884dc4745 100644
--- a/tests/auto/blackbox/testdata/env-merging/env-merging.qbs
+++ b/tests/auto/blackbox/testdata/env-merging/env-merging.qbs
@@ -12,10 +12,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/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..3ad31a609
--- /dev/null
+++ b/tests/auto/blackbox/testdata/erroneous/texttemplate-unknown-placeholder/texttemplate-unknown-placeholder.qbs
@@ -0,0 +1,8 @@
+import qbs
+
+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/exports-pkgconfig/exports-pkgconfig.qbs b/tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs
index 7934dc3c9..674f78c94 100644
--- a/tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs
+++ b/tests/auto/blackbox/testdata/exports-pkgconfig/exports-pkgconfig.qbs
@@ -85,6 +85,8 @@ Project {
Depends { name: "cpp" }
cpp.defines: ["SECONDLIB"]
+ qbs.installPrefix: ""
+
Depends { name: "TheFirstLib" }
Export {
diff --git a/tests/auto/blackbox/testdata/exports-qbs/lib.qbs b/tests/auto/blackbox/testdata/exports-qbs/lib.qbs
index 6ae0885d5..54f524c23 100644
--- a/tests/auto/blackbox/testdata/exports-qbs/lib.qbs
+++ b/tests/auto/blackbox/testdata/exports-qbs/lib.qbs
@@ -28,11 +28,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..01521405f 100644
--- a/tests/auto/blackbox/testdata/exports-qbs/tool.qbs
+++ b/tests/auto/blackbox/testdata/exports-qbs/tool.qbs
@@ -11,6 +11,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 +26,6 @@ CppApplication {
Group {
fileTagsFilter: ["application"]
- qbs.install: true
- qbs.installDir: "bin"
fileTags: toolTags
}
Group {
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..1bd215cc6
--- /dev/null
+++ b/tests/auto/blackbox/testdata/filetagsfilter-merging/MyApplication.qbs
@@ -0,0 +1,11 @@
+import qbs
+
+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..ae1342bff
--- /dev/null
+++ b/tests/auto/blackbox/testdata/filetagsfilter-merging/filetagsfilter-merging.qbs
@@ -0,0 +1,29 @@
+import qbs
+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/install-locations/install-locations.qbs b/tests/auto/blackbox/testdata/install-locations/install-locations.qbs
new file mode 100644
index 000000000..7bdb3f396
--- /dev/null
+++ b/tests/auto/blackbox/testdata/install-locations/install-locations.qbs
@@ -0,0 +1,28 @@
+import qbs
+
+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-tree/install-tree.qbs b/tests/auto/blackbox/testdata/install-tree/install-tree.qbs
index cbd7300d6..69571d58a 100644
--- a/tests/auto/blackbox/testdata/install-tree/install-tree.qbs
+++ b/tests/auto/blackbox/testdata/install-tree/install-tree.qbs
@@ -2,6 +2,7 @@ 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..75ff10c80 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
@@ -34,6 +34,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..eeb0875ad 100644
--- a/tests/auto/blackbox/testdata/installable/installable.qbs
+++ b/tests/auto/blackbox/testdata/installable/installable.qbs
@@ -5,15 +5,14 @@ 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..fca3fcca3 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
@@ -3,6 +3,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..244f80abe 100644
--- a/tests/auto/blackbox/testdata/installed-transformer-output/qbs668.qbs
+++ b/tests/auto/blackbox/testdata/installed-transformer-output/qbs668.qbs
@@ -4,6 +4,7 @@ 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/invalid-install-dir/invalid-install-dir.qbs b/tests/auto/blackbox/testdata/invalid-install-dir/invalid-install-dir.qbs
index f4a608904..ffa92dabb 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
@@ -3,9 +3,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/jsextensions-binaryfile/binaryfile.qbs b/tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs
index 7d3ada851..bf6d4a4cf 100644
--- a/tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs
+++ b/tests/auto/blackbox/testdata/jsextensions-binaryfile/binaryfile.qbs
@@ -5,10 +5,7 @@ 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..93b61d38d 100644
--- a/tests/auto/blackbox/testdata/jsextensions-file/file.qbs
+++ b/tests/auto/blackbox/testdata/jsextensions-file/file.qbs
@@ -7,10 +7,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..99d872b19 100644
--- a/tests/auto/blackbox/testdata/jsextensions-fileinfo/fileinfo.qbs
+++ b/tests/auto/blackbox/testdata/jsextensions-fileinfo/fileinfo.qbs
@@ -6,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-process/process.qbs b/tests/auto/blackbox/testdata/jsextensions-process/process.qbs
index c9c832ba4..730468b3a 100644
--- a/tests/auto/blackbox/testdata/jsextensions-process/process.qbs
+++ b/tests/auto/blackbox/testdata/jsextensions-process/process.qbs
@@ -13,10 +13,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-textfile/textfile.qbs b/tests/auto/blackbox/testdata/jsextensions-textfile/textfile.qbs
index ef433a1e4..44c142745 100644
--- a/tests/auto/blackbox/testdata/jsextensions-textfile/textfile.qbs
+++ b/tests/auto/blackbox/testdata/jsextensions-textfile/textfile.qbs
@@ -5,10 +5,7 @@ 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/linkerscripts/linkerscripts.qbs b/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs
index 42b3884ea..1601baf3c 100644
--- a/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs
+++ b/tests/auto/blackbox/testdata/linkerscripts/linkerscripts.qbs
@@ -12,10 +12,7 @@ DynamicLibrary {
Rule {
multiplex: true
- Artifact {
- filePath: "dummy.txt"
- fileTags: ["custom"]
- }
+ outputFileTags: "custom"
prepare: {
var cmd = new JavaScriptCommand();
cmd.silent = true;
@@ -26,8 +23,7 @@ DynamicLibrary {
}
}
- Group {
- fileTagsFilter: ["dynamiclibrary"]
- qbs.install: true
- }
+ qbs.installPrefix: ""
+ install: true
+ installDir: ""
}
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..6f9597788 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
@@ -5,10 +5,7 @@ Module {
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/makefile-generator/app.qbs b/tests/auto/blackbox/testdata/makefile-generator/app.qbs
index 103f71ecf..c0f423d5c 100644
--- a/tests/auto/blackbox/testdata/makefile-generator/app.qbs
+++ b/tests/auto/blackbox/testdata/makefile-generator/app.qbs
@@ -14,9 +14,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/nested-properties/modules/lowerlevel/lower-level.qbs b/tests/auto/blackbox/testdata/nested-properties/modules/lowerlevel/lower-level.qbs
index 6b2d00587..60ddc219b 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
@@ -7,10 +7,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/new-output-artifact/new-output-artifact.qbs b/tests/auto/blackbox/testdata/new-output-artifact/new-output-artifact.qbs
index 10e0e4305..fa70aee8d 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
@@ -9,6 +9,7 @@ Product {
files: ["input.txt"]
fileTags: ["input"]
}
+ qbs.installPrefix: ""
Group {
fileTagsFilter: product.type
qbs.install: true
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..ecbfd6c9d 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
@@ -11,10 +11,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/modules/themodule/themodule.qbs b/tests/auto/blackbox/testdata/pkg-config-probe/modules/themodule/themodule.qbs
index 81dfa955f..8edd218c3 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
@@ -18,10 +18,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/probe-in-exported-module/modules/depmodule/depmodule.qbs b/tests/auto/blackbox/testdata/probe-in-exported-module/modules/depmodule/depmodule.qbs
index b880d6dac..a9a27edb4 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
@@ -6,10 +6,7 @@ Module {
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..622dcf0ec 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
@@ -12,10 +12,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/probes-and-array-properties/modules/mymodule/mymodule.qbs b/tests/auto/blackbox/testdata/probes-and-array-properties/modules/mymodule/mymodule.qbs
index 6479bdfac..b76cffa00 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
@@ -15,11 +15,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/property-precedence/modules/leaf/leaf.qbs b/tests/auto/blackbox/testdata/property-precedence/modules/leaf/leaf.qbs
index 1ccc95939..741174eb2 100644
--- a/tests/auto/blackbox/testdata/property-precedence/modules/leaf/leaf.qbs
+++ b/tests/auto/blackbox/testdata/property-precedence/modules/leaf/leaf.qbs
@@ -6,11 +6,7 @@ Module {
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/recursive_renaming/recursive_renaming.qbs b/tests/auto/blackbox/testdata/recursive_renaming/recursive_renaming.qbs
index 5c2c4ec48..0ed6fa72f 100644
--- a/tests/auto/blackbox/testdata/recursive_renaming/recursive_renaming.qbs
+++ b/tests/auto/blackbox/testdata/recursive_renaming/recursive_renaming.qbs
@@ -1,6 +1,7 @@
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..dc993ae23 100644
--- a/tests/auto/blackbox/testdata/recursive_wildcards/recursive_wildcards.qbs
+++ b/tests/auto/blackbox/testdata/recursive_wildcards/recursive_wildcards.qbs
@@ -3,6 +3,7 @@ import qbs.TextFile
Product {
type: ["txt.out"]
+ qbs.installPrefix: ""
Group {
files: "dir/**"
qbs.install: true
diff --git a/tests/auto/blackbox/testdata/response-files/response-files.qbs b/tests/auto/blackbox/testdata/response-files/response-files.qbs
index 73eb720fe..1e1e75314 100644
--- a/tests/auto/blackbox/testdata/response-files/response-files.qbs
+++ b/tests/auto/blackbox/testdata/response-files/response-files.qbs
@@ -13,6 +13,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/setup-run-environment/setup-run-environment.qbs b/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs
index 9f841effd..8a5312d75 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
@@ -8,12 +8,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 +40,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 +57,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/suspicious-calls/copy-command.qbs b/tests/auto/blackbox/testdata/suspicious-calls/copy-command.qbs
index e01435fc0..f913a8efb 100644
--- a/tests/auto/blackbox/testdata/suspicious-calls/copy-command.qbs
+++ b/tests/auto/blackbox/testdata/suspicious-calls/copy-command.qbs
@@ -9,10 +9,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-prepare.qbs b/tests/auto/blackbox/testdata/suspicious-calls/copy-prepare.qbs
index b6098e8de..b3d402062 100644
--- a/tests/auto/blackbox/testdata/suspicious-calls/copy-prepare.qbs
+++ b/tests/auto/blackbox/testdata/suspicious-calls/copy-prepare.qbs
@@ -9,10 +9,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/direntries-command.qbs b/tests/auto/blackbox/testdata/suspicious-calls/direntries-command.qbs
index d15351c25..bb96aa1dc 100644
--- a/tests/auto/blackbox/testdata/suspicious-calls/direntries-command.qbs
+++ b/tests/auto/blackbox/testdata/suspicious-calls/direntries-command.qbs
@@ -9,10 +9,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-prepare.qbs b/tests/auto/blackbox/testdata/suspicious-calls/direntries-prepare.qbs
index 6f7320110..bc439125e 100644
--- a/tests/auto/blackbox/testdata/suspicious-calls/direntries-prepare.qbs
+++ b/tests/auto/blackbox/testdata/suspicious-calls/direntries-prepare.qbs
@@ -9,10 +9,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/symlink-removal/symlink-removal.qbs b/tests/auto/blackbox/testdata/symlink-removal/symlink-removal.qbs
index fc47c450f..a2f450082 100644
--- a/tests/auto/blackbox/testdata/symlink-removal/symlink-removal.qbs
+++ b/tests/auto/blackbox/testdata/symlink-removal/symlink-removal.qbs
@@ -5,10 +5,7 @@ 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-run-paths/system-run-paths.qbs b/tests/auto/blackbox/testdata/system-run-paths/system-run-paths.qbs
index 81778d6f7..7f9fa3000 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
@@ -6,6 +6,7 @@ Project {
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..8b312e7c6
--- /dev/null
+++ b/tests/auto/blackbox/testdata/texttemplate/texttemplatetest.qbs
@@ -0,0 +1,26 @@
+import qbs
+
+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/variant-suffix/variant-suffix.qbs b/tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs
index b919f84eb..a1dff378e 100644
--- a/tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs
+++ b/tests/auto/blackbox/testdata/variant-suffix/variant-suffix.qbs
@@ -22,11 +22,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/versionscript/versionscript.qbs b/tests/auto/blackbox/testdata/versionscript/versionscript.qbs
index 0309d3e06..5af798f5f 100644
--- a/tests/auto/blackbox/testdata/versionscript/versionscript.qbs
+++ b/tests/auto/blackbox/testdata/versionscript/versionscript.qbs
@@ -12,10 +12,7 @@ DynamicLibrary {
Rule {
multiplex: true
- Artifact {
- filePath: "dummy.txt"
- fileTags: ["custom"]
- }
+ outputFileTags: "custom"
prepare: {
var cmd = new JavaScriptCommand();
cmd.silent = true;
@@ -26,8 +23,7 @@ DynamicLibrary {
}
}
- Group {
- fileTagsFilter: ["dynamiclibrary"]
- qbs.install: true
- }
+ qbs.installPrefix: ""
+ install: true
+ installDir: ""
}
diff --git a/tests/auto/blackbox/testdata/wildcard_renaming/wildcard_renaming.qbs b/tests/auto/blackbox/testdata/wildcard_renaming/wildcard_renaming.qbs
index 4cb2c071c..68043f991 100644
--- a/tests/auto/blackbox/testdata/wildcard_renaming/wildcard_renaming.qbs
+++ b/tests/auto/blackbox/testdata/wildcard_renaming/wildcard_renaming.qbs
@@ -1,6 +1,7 @@
import qbs 1.0
Product {
+ qbs.installPrefix: ""
Group {
qbs.install: true
files: "*"
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index 6987ae662..9022bd975 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -258,6 +258,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);
@@ -460,11 +473,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()
@@ -3155,6 +3164,8 @@ 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'";
}
void TestBlackbox::erroneousFiles()
@@ -3373,12 +3384,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");
}
void TestBlackbox::exportsQbs()
@@ -3486,6 +3493,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");
@@ -3494,6 +3512,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");
@@ -3898,7 +3969,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";
@@ -3930,7 +4001,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) {
@@ -5082,6 +5153,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");
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index 35ba2c5b7..a2c021140 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();
@@ -111,6 +113,7 @@ private slots:
void exportsQbs();
void externalLibs();
void fileDependencies();
+ void fileTagsFilterMerging();
void generatedArtifactAsInputToDynamicRule();
void generator();
void generator_data();
@@ -133,6 +136,8 @@ private slots:
void installDuplicatesNoError();
void installedSourceFiles();
void installedTransformerOutput();
+ void installLocations_data();
+ void installLocations();
void installPackage();
void installRootFromProjectFile();
void installTree();
@@ -248,6 +253,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_blackboxapple.cpp b/tests/auto/blackbox/tst_blackboxapple.cpp
index 6fc526cd8..64aca99f1 100644
--- a/tests/auto/blackbox/tst_blackboxapple.cpp
+++ b/tests/auto/blackbox/tst_blackboxapple.cpp
@@ -77,7 +77,7 @@ void TestBlackboxApple::initTestCase()
void TestBlackboxApple::appleMultiConfig()
{
QDir::setCurrent(testDataDir + "/apple-multiconfig");
- QCOMPARE(runQbs(), 0);
+ QCOMPARE(runQbs(QbsRunParameters(QStringList{"qbs.installPrefix:''"})), 0);
QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Contents/MacOS/singleapp").isExecutable());
QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Contents/Info.plist").isRegularFile());
@@ -285,7 +285,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
@@ -624,7 +624,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/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..316448858
--- /dev/null
+++ b/tests/auto/language/testdata/erroneous/rule-without-output-tags.qbs
@@ -0,0 +1,13 @@
+import qbs
+
+Product {
+ Rule {
+ inputs: "input-tag"
+ prepare: {
+ var cmd = new JavaScriptCommand;
+ cmd.silent = true;
+ cmd.sourceCode = function() {};
+ return cmd;
+ }
+ }
+}
diff --git a/tests/auto/language/tst_language.cpp b/tests/auto/language/tst_language.cpp
index f52c6ec9c..f3c510049 100644
--- a/tests/auto/language/tst_language.cpp
+++ b/tests/auto/language/tst_language.cpp
@@ -830,6 +830,9 @@ void TestLanguage::erroneousFiles_data()
QTest::newRow("original-in-product-property")
<< "original-in-product-property.qbs"
":4:21.*The special value 'original' can only be used with module properties.";
+ QTest::newRow("rule-without-output-tags")
+ << "rule-without-output-tags.qbs:4:5.*A rule needs to have Artifact items or "
+ "a non-empty outputFileTags property.";
QTest::newRow("mismatching-multiplex-dependency")
<< "mismatching-multiplex-dependency.qbs:9:5.*Dependency from product "
"'b \\{\"architecture\":\"mips\"\\}' to product 'a \\{\"architecture\":\"mips\"\\}'"
diff --git a/tests/auto/shared.h b/tests/auto/shared.h
index b7a3e2b11..e049511ab 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>
@@ -103,6 +105,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)
{