aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/man/man.qbs2
-rw-r--r--doc/reference/items/language/rule.qdoc14
-rw-r--r--qbs-resources/imports/QbsLibrary.qbs5
-rw-r--r--qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs1
-rw-r--r--src/lib/corelib/buildgraph/projectbuilddata.cpp5
-rw-r--r--src/lib/corelib/buildgraph/rulesapplicator.cpp43
-rw-r--r--src/lib/corelib/buildgraph/rulesapplicator.h10
-rw-r--r--src/lib/corelib/corelib.qbs2
-rw-r--r--src/lib/corelib/language/builtindeclarations.cpp2
-rw-r--r--src/lib/corelib/language/language.cpp1
-rw-r--r--src/lib/corelib/language/language.h4
-rw-r--r--src/lib/corelib/language/moduleloader.cpp1
-rw-r--r--src/lib/corelib/language/projectresolver.cpp2
-rw-r--r--src/lib/corelib/tools/persistence.cpp2
-rw-r--r--src/lib/corelib/tools/stringconstants.h4
-rw-r--r--src/plugins/generator/generator.pro2
-rw-r--r--src/plugins/generator/makefilegenerator/makefilegenerator.cpp (renamed from src/plugins/generator/makefile/makefilegenerator.cpp)0
-rw-r--r--src/plugins/generator/makefilegenerator/makefilegenerator.h (renamed from src/plugins/generator/makefile/makefilegenerator.h)0
-rw-r--r--src/plugins/generator/makefilegenerator/makefilegenerator.pro (renamed from src/plugins/generator/makefile/makefile.pro)0
-rw-r--r--src/plugins/generator/makefilegenerator/makefilegenerator.qbs (renamed from src/plugins/generator/makefile/makefilegenerator.qbs)0
-rw-r--r--src/plugins/generator/makefilegenerator/makefilegeneratorplugin.cpp (renamed from src/plugins/generator/makefile/makefilegeneratorplugin.cpp)0
-rw-r--r--src/plugins/plugins.qbs2
-rw-r--r--src/plugins/qbsplugin.qbs8
-rw-r--r--tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs2
-rw-r--r--tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs4
-rw-r--r--tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs2
-rw-r--r--tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs2
-rw-r--r--tests/auto/blackbox/testdata/aux-inputs-from-deps/aux-inputs-from-deps.qbs2
-rw-r--r--tests/auto/blackbox/testdata/explicitly-depends-on/explicitly-depends-on.qbs124
-rw-r--r--tests/auto/blackbox/testdata/explicitly-depends-on/modules/module1/module-fish.txt1
-rw-r--r--tests/auto/blackbox/testdata/explicitly-depends-on/modules/module1/module1.qbs9
-rw-r--r--tests/auto/blackbox/testdata/explicitly-depends-on/step1.txt1
-rw-r--r--tests/auto/blackbox/testdata/exports-qbs/tool.qbs2
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp64
-rw-r--r--tests/auto/blackbox/tst_blackbox.h2
35 files changed, 292 insertions, 33 deletions
diff --git a/doc/man/man.qbs b/doc/man/man.qbs
index 44e2f0e12..32f8e624e 100644
--- a/doc/man/man.qbs
+++ b/doc/man/man.qbs
@@ -31,7 +31,9 @@ Product {
Rule {
condition: updateManPage
multiplex: true
+ // TODO: Remove in 1.14.
explicitlyDependsOn: ["application"]
+ property stringList explicitlyDependsOnFromDependencies: ["application"]
inputs: ["man.section"]
Artifact {
filePath: "qbs.1"
diff --git a/doc/reference/items/language/rule.qdoc b/doc/reference/items/language/rule.qdoc
index 200bd94c0..3a14c2fa6 100644
--- a/doc/reference/items/language/rule.qdoc
+++ b/doc/reference/items/language/rule.qdoc
@@ -303,13 +303,23 @@
A list of file tags. Each artifact that matches the file tags is added to
the dependencies of each output node. All artifacts in the current product
- and target artifacts of products that this product depends on are
- considered.
+ are considered.
\nodefaultvalue
*/
/*!
+ \qmlproperty stringList Rule::explicitlyDependsOnFromDependencies
+
+ A list of file tags. Each artifact that matches the file tags is added to
+ the dependencies of each output node. Only target artifacts of products that this product
+ depends on are considered.
+
+ \nodefaultvalue
+ \since Qbs 1.12
+*/
+
+/*!
\qmlproperty script Rule::prepare
A script that prepares the commands to transform the inputs to outputs.
diff --git a/qbs-resources/imports/QbsLibrary.qbs b/qbs-resources/imports/QbsLibrary.qbs
index 736025cbb..f8bc70580 100644
--- a/qbs-resources/imports/QbsLibrary.qbs
+++ b/qbs-resources/imports/QbsLibrary.qbs
@@ -16,11 +16,12 @@ QbsProduct {
cpp.soVersion: version.replace(/\.\d+$/, '')
}
cpp.visibility: "minimal"
- property string visibilityType: Qt.core.staticBuild ? "static" : "dynamic"
+ property string visibilityType: staticBuild ? "static" : "dynamic"
property string headerInstallPrefix: "/include/qbs"
property bool hasExporter: Utilities.versionCompare(qbs.version, "1.12") >= 0
property bool generateQbsModule: install && qbsbuildconfig.generateQbsModules && hasExporter
- property stringList libType: [Qt.core.staticBuild ? "staticlibrary" : "dynamiclibrary"]
+ property bool staticBuild: Qt.core.staticBuild || qbsbuildconfig.staticBuild
+ property stringList libType: [staticBuild ? "staticlibrary" : "dynamiclibrary"]
Depends { name: "Exporter.qbs"; condition: generateQbsModule }
Group {
fileTagsFilter: libType.concat("dynamiclibrary_symlink")
diff --git a/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs b/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs
index 8bd3c617a..7f978d47b 100644
--- a/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs
+++ b/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs
@@ -8,6 +8,7 @@ Module {
property bool installApiHeaders: true
property bool enableBundledQt: true
property bool useBundledQtScript: false
+ property bool staticBuild: false
property string libDirName: "lib"
property string appInstallDir: "bin"
property string libInstallDir: qbs.targetOS.contains("windows") ? "bin" : libDirName
diff --git a/src/lib/corelib/buildgraph/projectbuilddata.cpp b/src/lib/corelib/buildgraph/projectbuilddata.cpp
index 2874fe23c..67228d35d 100644
--- a/src/lib/corelib/buildgraph/projectbuilddata.cpp
+++ b/src/lib/corelib/buildgraph/projectbuilddata.cpp
@@ -390,7 +390,7 @@ static bool areRulesCompatible(const RuleNode *ruleNode, const RuleNode *depende
return true;
if (!dependencyRule->product->fileTags.intersects(outTags))
return false;
- if (ruleNode->rule()->explicitlyDependsOn.intersects(outTags))
+ if (ruleNode->rule()->explicitlyDependsOnFromDependencies.intersects(outTags))
return true;
return ruleNode->rule()->auxiliaryInputs.intersects(outTags);
}
@@ -464,7 +464,8 @@ void BuildDataResolver::connectRulesToDependencies(const ResolvedProductPtr &pro
if (areRulesCompatible(ruleNode, depRuleNode)
|| ((ruleNode->rule()->inputsFromDependencies.contains(installableTag)
|| ruleNode->rule()->auxiliaryInputs.contains(installableTag)
- || ruleNode->rule()->explicitlyDependsOn.contains(installableTag))
+ || ruleNode->rule()->explicitlyDependsOnFromDependencies.contains(
+ installableTag))
&& isRootRuleNode(depRuleNode))) {
connect(ruleNode, depRuleNode);
}
diff --git a/src/lib/corelib/buildgraph/rulesapplicator.cpp b/src/lib/corelib/buildgraph/rulesapplicator.cpp
index 8a908b27c..22c89ea54 100644
--- a/src/lib/corelib/buildgraph/rulesapplicator.cpp
+++ b/src/lib/corelib/buildgraph/rulesapplicator.cpp
@@ -154,7 +154,8 @@ void RulesApplicator::handleRemovedRuleOutputs(const ArtifactSet &inputArtifacts
ArtifactSet RulesApplicator::collectAuxiliaryInputs(const Rule *rule,
const ResolvedProduct *product)
{
- return collectAdditionalInputs(rule->auxiliaryInputs, rule, product);
+ return collectAdditionalInputs(rule->auxiliaryInputs, rule, product,
+ RulesApplicator::CurrentProduct | RulesApplicator::Dependencies);
}
static void copyProperty(const QString &name, const QScriptValue &src, QScriptValue dst)
@@ -298,19 +299,37 @@ ArtifactSet RulesApplicator::collectOldOutputArtifacts(const ArtifactSet &inputA
}
ArtifactSet RulesApplicator::collectAdditionalInputs(const FileTags &tags, const Rule *rule,
- const ResolvedProduct *product)
+ const ResolvedProduct *product,
+ InputsSources inputsSources)
{
ArtifactSet artifacts;
for (const FileTag &fileTag : tags) {
for (Artifact *dependency : product->lookupArtifactsByFileTag(fileTag)) {
- if (!dependency->fileTags().intersects(rule->excludedInputs))
+ // Skip excluded inputs.
+ if (dependency->fileTags().intersects(rule->excludedInputs))
+ continue;
+
+ // Two cases are considered:
+ // 1) An artifact is considered a dependency when it's part of the current product.
+ // 2) An artifact marked with filesAreTargets: true inside a Group inside of a
+ // Module also ends up in the results returned by product->lookupArtifactsByFileTag,
+ // so it should be considered conceptually as a "dependent product artifact".
+ if ((inputsSources.testFlag(RulesApplicator::CurrentProduct)
+ && !dependency->isTargetOfModule())
+ || (inputsSources.testFlag(RulesApplicator::Dependencies)
+ && dependency->isTargetOfModule())
+ ) {
artifacts << dependency;
+ }
}
- for (const ResolvedProductConstPtr &depProduct : product->dependencies) {
- for (Artifact * const ta : depProduct->targetArtifacts()) {
- if (ta->fileTags().contains(fileTag)
- && !ta->fileTags().intersects(rule->excludedInputs)) {
- artifacts << ta;
+
+ if (inputsSources.testFlag(RulesApplicator::Dependencies)) {
+ for (const ResolvedProductConstPtr &depProduct : product->dependencies) {
+ for (Artifact * const ta : depProduct->targetArtifacts()) {
+ if (ta->fileTags().contains(fileTag)
+ && !ta->fileTags().intersects(rule->excludedInputs)) {
+ artifacts << ta;
+ }
}
}
}
@@ -320,7 +339,13 @@ ArtifactSet RulesApplicator::collectAdditionalInputs(const FileTags &tags, const
ArtifactSet RulesApplicator::collectExplicitlyDependsOn()
{
- return collectAdditionalInputs(m_rule->explicitlyDependsOn, m_rule.get(), m_product.get());
+ ArtifactSet first = collectAdditionalInputs(
+ m_rule->explicitlyDependsOn, m_rule.get(), m_product.get(),
+ RulesApplicator::CurrentProduct);
+ ArtifactSet second = collectAdditionalInputs(
+ m_rule->explicitlyDependsOnFromDependencies, m_rule.get(), m_product.get(),
+ RulesApplicator::Dependencies);
+ return first.unite(second);
}
Artifact *RulesApplicator::createOutputArtifactFromRuleArtifact(
diff --git a/src/lib/corelib/buildgraph/rulesapplicator.h b/src/lib/corelib/buildgraph/rulesapplicator.h
index ac4501491..76220f52d 100644
--- a/src/lib/corelib/buildgraph/rulesapplicator.h
+++ b/src/lib/corelib/buildgraph/rulesapplicator.h
@@ -46,6 +46,7 @@
#include <language/forward_decls.h>
#include <logging/logger.h>
+#include <QtCore/qflags.h>
#include <QtCore/qhash.h>
#include <QtCore/qstring.h>
#include <QtScript/qscriptvalue.h>
@@ -75,10 +76,14 @@ public:
const ArtifactSet &artifactsToRemove, const Logger &logger);
static ArtifactSet collectAuxiliaryInputs(const Rule *rule, const ResolvedProduct *product);
+ enum InputsSourceFlag { CurrentProduct, Dependencies };
+ Q_DECLARE_FLAGS(InputsSources, InputsSourceFlag)
+
private:
void doApply(const ArtifactSet &inputArtifacts, QScriptValue &prepareScriptContext);
ArtifactSet collectOldOutputArtifacts(const ArtifactSet &inputArtifacts) const;
ArtifactSet collectExplicitlyDependsOn();
+ ArtifactSet collectExplicitlyDependsOnFromDependencies();
Artifact *createOutputArtifactFromRuleArtifact(const RuleArtifactConstPtr &ruleArtifact,
const ArtifactSet &inputArtifacts, Set<QString> *outputFilePaths);
Artifact *createOutputArtifact(const QString &filePath, const FileTags &fileTags,
@@ -93,7 +98,8 @@ private:
QScriptValue scope() const;
static ArtifactSet collectAdditionalInputs(const FileTags &tags,
- const Rule *rule, const ResolvedProduct *product);
+ const Rule *rule, const ResolvedProduct *product,
+ InputsSources inputsSources);
const ResolvedProductPtr m_product;
const std::unordered_map<QString, const ResolvedProduct *> &m_productsByName;
@@ -108,6 +114,8 @@ private:
Logger m_logger;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(RulesApplicator::InputsSources)
+
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/corelib.qbs b/src/lib/corelib/corelib.qbs
index e1fe4cf9b..900fde759 100644
--- a/src/lib/corelib/corelib.qbs
+++ b/src/lib/corelib/corelib.qbs
@@ -15,7 +15,7 @@ QbsLibrary {
condition: qbsbuildconfig.useBundledQtScript || !Qt.script.present
}
Depends { condition: qbsbuildconfig.enableProjectFileUpdates; name: "Qt.gui" }
- Depends { condition: Qt.core.staticBuild; productTypes: ["qbsplugin"] }
+ Depends { condition: staticBuild; productTypes: ["qbsplugin"] }
name: "qbscore"
cpp.includePaths: base.concat([
".",
diff --git a/src/lib/corelib/language/builtindeclarations.cpp b/src/lib/corelib/language/builtindeclarations.cpp
index 8aac3c24a..4be405112 100644
--- a/src/lib/corelib/language/builtindeclarations.cpp
+++ b/src/lib/corelib/language/builtindeclarations.cpp
@@ -507,6 +507,8 @@ void BuiltinDeclarations::addRuleItem()
PropertyDeclaration::StringList);
item << PropertyDeclaration(StringConstants::explicitlyDependsOnProperty(),
PropertyDeclaration::StringList);
+ item << PropertyDeclaration(StringConstants::explicitlyDependsOnFromDependenciesProperty(),
+ PropertyDeclaration::StringList);
item << prepareScriptProperty();
insert(item);
}
diff --git a/src/lib/corelib/language/language.cpp b/src/lib/corelib/language/language.cpp
index 2acd867a8..ac78b06c5 100644
--- a/src/lib/corelib/language/language.cpp
+++ b/src/lib/corelib/language/language.cpp
@@ -902,6 +902,7 @@ bool operator==(const Rule &r1, const Rule &r2)
&& r1.excludedInputs == r2.excludedInputs
&& r1.inputsFromDependencies == r2.inputsFromDependencies
&& r1.explicitlyDependsOn == r2.explicitlyDependsOn
+ && r1.explicitlyDependsOnFromDependencies == r2.explicitlyDependsOnFromDependencies
&& r1.multiplex == r2.multiplex
&& r1.requiresInputs == r2.requiresInputs
&& r1.alwaysRun == r2.alwaysRun;
diff --git a/src/lib/corelib/language/language.h b/src/lib/corelib/language/language.h
index 96fb83640..05fcfcf46 100644
--- a/src/lib/corelib/language/language.h
+++ b/src/lib/corelib/language/language.h
@@ -414,6 +414,7 @@ public:
FileTags excludedInputs;
FileTags inputsFromDependencies;
FileTags explicitlyDependsOn;
+ FileTags explicitlyDependsOnFromDependencies;
bool multiplex;
bool requiresInputs;
std::vector<RuleArtifactPtr> artifacts; // unused, if outputFileTags/outputArtifactsScript is non-empty
@@ -436,7 +437,8 @@ public:
{
pool.serializationOp<opType>(name, prepareScript, outputArtifactsScript, module, inputs,
outputFileTags, auxiliaryInputs, excludedInputs,
- inputsFromDependencies, explicitlyDependsOn, multiplex,
+ inputsFromDependencies, explicitlyDependsOn,
+ explicitlyDependsOnFromDependencies, multiplex,
requiresInputs, alwaysRun, artifacts);
}
private:
diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp
index 3ebfb38d3..a90f51536 100644
--- a/src/lib/corelib/language/moduleloader.cpp
+++ b/src/lib/corelib/language/moduleloader.cpp
@@ -3025,7 +3025,6 @@ Item *ModuleLoader::loadModuleFile(ProductContext *productContext, const QString
// Module properties that are defined in the profile are used as default values.
const QVariantMap profileModuleProperties
= productContext->moduleProperties.value(fullModuleName).toMap();
- QList<ErrorInfo> unknownProfilePropertyErrors;
for (QVariantMap::const_iterator vmit = profileModuleProperties.begin();
vmit != profileModuleProperties.end(); ++vmit)
{
diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp
index 33fee79b7..8b129c98b 100644
--- a/src/lib/corelib/language/projectresolver.cpp
+++ b/src/lib/corelib/language/projectresolver.cpp
@@ -1194,6 +1194,8 @@ void ProjectResolver::resolveRule(Item *item, ProjectContext *projectContext)
}
rule->explicitlyDependsOn
= m_evaluator->fileTagsValue(item, StringConstants::explicitlyDependsOnProperty());
+ rule->explicitlyDependsOnFromDependencies = m_evaluator->fileTagsValue(
+ item, StringConstants::explicitlyDependsOnFromDependenciesProperty());
rule->module = m_moduleContext ? m_moduleContext->module : projectContext->dummyModule;
if (!rule->multiplex && !rule->declaresInputs()) {
throw ErrorInfo(Tr::tr("Rule has no inputs, but is not a multiplex rule."),
diff --git a/src/lib/corelib/tools/persistence.cpp b/src/lib/corelib/tools/persistence.cpp
index 6d8aadf7e..0dab81440 100644
--- a/src/lib/corelib/tools/persistence.cpp
+++ b/src/lib/corelib/tools/persistence.cpp
@@ -49,7 +49,7 @@
namespace qbs {
namespace Internal {
-static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-116";
+static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-117";
NoBuildGraphError::NoBuildGraphError(const QString &filePath)
: ErrorInfo(Tr::tr("Build graph not found for configuration '%1'. Expected location was '%2'.")
diff --git a/src/lib/corelib/tools/stringconstants.h b/src/lib/corelib/tools/stringconstants.h
index fa0836d2e..f2666e070 100644
--- a/src/lib/corelib/tools/stringconstants.h
+++ b/src/lib/corelib/tools/stringconstants.h
@@ -83,6 +83,9 @@ public:
QBS_STRING_CONSTANT(excludedAuxiliaryInputsProperty, "excludedAuxiliaryInputs")
QBS_STRING_CONSTANT(excludedInputsProperty, "excludedInputs")
static const QString &explicitlyDependsOnProperty() { return explicitlyDependsOn(); }
+ static const QString &explicitlyDependsOnFromDependenciesProperty() {
+ return explicitlyDependsOnFromDependencies();
+ }
static const QString &fileNameProperty() { return fileName(); }
static const QString &filePathProperty() { return filePath(); }
QBS_STRING_CONSTANT(fileTagsFilterProperty, "fileTagsFilter")
@@ -225,6 +228,7 @@ public:
private:
QBS_STRING_CONSTANT(cpp, "cpp")
QBS_STRING_CONSTANT(explicitlyDependsOn, "explicitlyDependsOn")
+ QBS_STRING_CONSTANT(explicitlyDependsOnFromDependencies, "explicitlyDependsOnFromDependencies")
QBS_STRING_CONSTANT(fileName, "fileName")
QBS_STRING_CONSTANT(filePath, "filePath")
QBS_STRING_CONSTANT(inputs, "inputs")
diff --git a/src/plugins/generator/generator.pro b/src/plugins/generator/generator.pro
index f51646541..1607aa14d 100644
--- a/src/plugins/generator/generator.pro
+++ b/src/plugins/generator/generator.pro
@@ -1,2 +1,2 @@
TEMPLATE = subdirs
-SUBDIRS = clangcompilationdb makefile visualstudio
+SUBDIRS = clangcompilationdb makefilegenerator visualstudio
diff --git a/src/plugins/generator/makefile/makefilegenerator.cpp b/src/plugins/generator/makefilegenerator/makefilegenerator.cpp
index 267bd90dc..267bd90dc 100644
--- a/src/plugins/generator/makefile/makefilegenerator.cpp
+++ b/src/plugins/generator/makefilegenerator/makefilegenerator.cpp
diff --git a/src/plugins/generator/makefile/makefilegenerator.h b/src/plugins/generator/makefilegenerator/makefilegenerator.h
index b2b23f081..b2b23f081 100644
--- a/src/plugins/generator/makefile/makefilegenerator.h
+++ b/src/plugins/generator/makefilegenerator/makefilegenerator.h
diff --git a/src/plugins/generator/makefile/makefile.pro b/src/plugins/generator/makefilegenerator/makefilegenerator.pro
index fae962fbb..fae962fbb 100644
--- a/src/plugins/generator/makefile/makefile.pro
+++ b/src/plugins/generator/makefilegenerator/makefilegenerator.pro
diff --git a/src/plugins/generator/makefile/makefilegenerator.qbs b/src/plugins/generator/makefilegenerator/makefilegenerator.qbs
index baabc43e3..baabc43e3 100644
--- a/src/plugins/generator/makefile/makefilegenerator.qbs
+++ b/src/plugins/generator/makefilegenerator/makefilegenerator.qbs
diff --git a/src/plugins/generator/makefile/makefilegeneratorplugin.cpp b/src/plugins/generator/makefilegenerator/makefilegeneratorplugin.cpp
index 01b843a06..01b843a06 100644
--- a/src/plugins/generator/makefile/makefilegeneratorplugin.cpp
+++ b/src/plugins/generator/makefilegenerator/makefilegeneratorplugin.cpp
diff --git a/src/plugins/plugins.qbs b/src/plugins/plugins.qbs
index 392145b7f..dcc1ded87 100644
--- a/src/plugins/plugins.qbs
+++ b/src/plugins/plugins.qbs
@@ -4,7 +4,7 @@ Project {
name: "qbs plugins"
references: [
"generator/clangcompilationdb/clangcompilationdb.qbs",
- "generator/makefile/makefilegenerator.qbs",
+ "generator/makefilegenerator/makefilegenerator.qbs",
"generator/visualstudio/visualstudio.qbs",
"scanner/cpp/cpp.qbs",
"scanner/qt/qt.qbs"
diff --git a/src/plugins/qbsplugin.qbs b/src/plugins/qbsplugin.qbs
index f6a752dc1..269614e11 100644
--- a/src/plugins/qbsplugin.qbs
+++ b/src/plugins/qbsplugin.qbs
@@ -3,16 +3,16 @@ import qbs.FileInfo
QbsProduct {
property bool isForDarwin: qbs.targetOS.contains("darwin")
+ property bool staticBuild: Qt.core.staticBuild || qbsbuildconfig.staticBuild
Depends { name: "cpp" }
Depends { name: "bundle"; condition: isForDarwin }
Depends { name: "Qt.core" }
Depends { name: "qbsbuildconfig" }
- Depends { name: "qbscore"; condition: !Qt.core.staticBuild }
- type: (Qt.core.staticBuild ? ["staticlibrary"]
- : [isForDarwin ? "loadablemodule" : "dynamiclibrary"])
+ Depends { name: "qbscore"; condition: !staticBuild }
+ type: (staticBuild ? ["staticlibrary"] : [isForDarwin ? "loadablemodule" : "dynamiclibrary"])
.concat(["qbsplugin"])
Properties {
- condition: Qt.core.staticBuild
+ condition: staticBuild
cpp.defines: ["QBS_STATIC_LIB"]
}
cpp.includePaths: base.concat(["../../../lib/corelib"])
diff --git a/tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs b/tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs
index 37c4261f4..faa51d3b9 100644
--- a/tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs
+++ b/tests/auto/api/testdata/excluded-inputs/excluded-inputs.qbs
@@ -92,7 +92,7 @@ Project {
}
Rule {
multiplex: true
- explicitlyDependsOn: "the_tag"
+ explicitlyDependsOnFromDependencies: "the_tag"
excludedAuxiliaryInputs: "the_other_tag"
Artifact {
filePath: "dummy3.txt"
diff --git a/tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs b/tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs
index 0ac4a7463..17aa74697 100644
--- a/tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs
+++ b/tests/auto/api/testdata/explicitly-depends-on/explicitly-depends-on.qbs
@@ -20,7 +20,7 @@ Project {
Rule {
inputs: ["mytype.in"]
- explicitlyDependsOn: ["compiler"]
+ explicitlyDependsOnFromDependencies: ["compiler"]
Artifact {
filePath: input.fileName + ".out"
fileTags: product.type
@@ -36,7 +36,7 @@ Project {
Rule {
multiplex: true
- explicitlyDependsOn: ["compiler"]
+ explicitlyDependsOnFromDependencies: ["compiler"]
Artifact {
filePath: "compiler-name.txt"
fileTags: product.type
diff --git a/tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs b/tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs
index d9bd47003..9521f3ae4 100644
--- a/tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs
+++ b/tests/auto/api/testdata/tool-in-module/use-outside-project/modules/thetool/thetool.qbs
@@ -13,7 +13,7 @@ Module {
Rule {
multiplex: true
- explicitlyDependsOn: ["thetool.thetool"]
+ explicitlyDependsOnFromDependencies: ["thetool.thetool"]
Artifact {
filePath: "tool-output.txt"
fileTags: ["thetool.output"]
diff --git a/tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs b/tests/auto/api/testdata/tool-in-module/use-within-project/use-within-project.qbs
index 13b2bb819..bd480fb08 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
@@ -15,7 +15,7 @@ Project {
Depends { name: "cpp" }
Rule {
multiplex: true
- explicitlyDependsOn: ["thetool.thetool"]
+ explicitlyDependsOnFromDependencies: ["thetool.thetool"]
Artifact {
filePath: "tool-output.txt"
fileTags: ["thetool.output"]
diff --git a/tests/auto/blackbox/testdata/aux-inputs-from-deps/aux-inputs-from-deps.qbs b/tests/auto/blackbox/testdata/aux-inputs-from-deps/aux-inputs-from-deps.qbs
index e5be44b76..620ae2ea0 100644
--- a/tests/auto/blackbox/testdata/aux-inputs-from-deps/aux-inputs-from-deps.qbs
+++ b/tests/auto/blackbox/testdata/aux-inputs-from-deps/aux-inputs-from-deps.qbs
@@ -16,7 +16,7 @@ Project {
Depends { name: "dep" }
Rule {
multiplex: true
- explicitlyDependsOn: ["hpp"]
+ explicitlyDependsOnFromDependencies: ["hpp"]
Artifact {
filePath: "dummy.out"
fileTags: ["p.out"]
diff --git a/tests/auto/blackbox/testdata/explicitly-depends-on/explicitly-depends-on.qbs b/tests/auto/blackbox/testdata/explicitly-depends-on/explicitly-depends-on.qbs
new file mode 100644
index 000000000..10cfa089b
--- /dev/null
+++ b/tests/auto/blackbox/testdata/explicitly-depends-on/explicitly-depends-on.qbs
@@ -0,0 +1,124 @@
+import qbs
+import qbs.File
+import qbs.TextFile
+
+Project {
+ // Cases:
+ // step1 + in-product final -> step2 -> step3 -> final => rule cycle
+ // step1 + dependency final -> step2 -> step3 -> final => ok
+ // step1 + module filesAreTargets final -> step2 -> step3 -> final => ok
+
+ name: "proj1"
+ property bool useModule: false
+
+ Product {
+ name: "prod1"
+ type: "final"
+ property bool useExplicitlyDependsOn: false
+ property bool useExplicitlyDependsOnFromDependencies: false
+
+ Depends {
+ condition: !project.useModule
+ name: "prod2"
+ }
+ Depends {
+ condition: project.useModule
+ name: "module1"
+ }
+
+ Group {
+ files: ["step1.txt"]
+ fileTags: ["step1"]
+ }
+
+ Rule {
+ inputs: ["step3"]
+ outputFileTags: ["final"]
+ Artifact {
+ filePath: "final.txt"
+ fileTags: ["final"]
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "step3 -> final";
+ cmd.sourceCode = function() {
+ File.copy(input.filePath, output.filePath);
+ };
+ return cmd;
+ }
+ }
+
+ Rule {
+ inputs: ["step2"]
+ outputFileTags: ["step3"]
+ Artifact {
+ filePath: "step3.txt"
+ fileTags: ["step3"]
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "step2 -> step3";
+ cmd.sourceCode = function() {
+ File.copy(input.filePath, output.filePath);
+ };
+ return cmd;
+ }
+ }
+
+ Rule {
+ inputs: ["step1"]
+ outputFileTags: ["step2"]
+ Artifact {
+ filePath: "step2.txt"
+ fileTags: ["step2"]
+ }
+
+ Properties {
+ condition: useExplicitlyDependsOn
+ explicitlyDependsOn: ["final"]
+ }
+
+ Properties {
+ condition: useExplicitlyDependsOnFromDependencies
+ explicitlyDependsOnFromDependencies: ["final"]
+ }
+
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "step1 -> step2";
+ cmd.sourceCode = function() {
+ console.info("Using explicitlyDependsOnArtifact: "
+ + explicitlyDependsOn["final"][0].fileName)
+ File.copy(input.filePath, output.filePath);
+ };
+ return cmd;
+ }
+ }
+ }
+
+ Product {
+ name: "prod2"
+ type: "final"
+ condition: !project.useModule
+
+ Rule {
+ multiplex: true
+ requiresInputs: false
+ outputFileTags: ["final"]
+ Artifact {
+ filePath: "product-fish.txt"
+ fileTags: ["final"]
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "creating 'product-fish.txt' tagged with 'final'";
+ cmd.sourceCode = function() {
+ var file = new TextFile(output.filePath, TextFile.ReadWrite);
+ file.write("Lots of fish.");
+ file.close()
+ };
+ return cmd;
+ }
+ }
+ }
+}
diff --git a/tests/auto/blackbox/testdata/explicitly-depends-on/modules/module1/module-fish.txt b/tests/auto/blackbox/testdata/explicitly-depends-on/modules/module1/module-fish.txt
new file mode 100644
index 000000000..10b4b7cbe
--- /dev/null
+++ b/tests/auto/blackbox/testdata/explicitly-depends-on/modules/module1/module-fish.txt
@@ -0,0 +1 @@
+Module fish
diff --git a/tests/auto/blackbox/testdata/explicitly-depends-on/modules/module1/module1.qbs b/tests/auto/blackbox/testdata/explicitly-depends-on/modules/module1/module1.qbs
new file mode 100644
index 000000000..f1752b4ed
--- /dev/null
+++ b/tests/auto/blackbox/testdata/explicitly-depends-on/modules/module1/module1.qbs
@@ -0,0 +1,9 @@
+import qbs
+
+Module {
+ Group {
+ filesAreTargets: true
+ fileTags: ["final"]
+ files: ["module-fish.txt"]
+ }
+}
diff --git a/tests/auto/blackbox/testdata/explicitly-depends-on/step1.txt b/tests/auto/blackbox/testdata/explicitly-depends-on/step1.txt
new file mode 100644
index 000000000..45b983be3
--- /dev/null
+++ b/tests/auto/blackbox/testdata/explicitly-depends-on/step1.txt
@@ -0,0 +1 @@
+hi
diff --git a/tests/auto/blackbox/testdata/exports-qbs/tool.qbs b/tests/auto/blackbox/testdata/exports-qbs/tool.qbs
index 0139b7e14..b0078a75c 100644
--- a/tests/auto/blackbox/testdata/exports-qbs/tool.qbs
+++ b/tests/auto/blackbox/testdata/exports-qbs/tool.qbs
@@ -40,7 +40,7 @@ CppApplication {
property var helper2Obj: Helper2
Rule {
inputs: Helper.toolInputs()
- explicitlyDependsOn: toolTags
+ explicitlyDependsOnFromDependencies: toolTags
outputFileTags: parent.outTags
outputArtifacts: [{
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index 62930f54f..a18a735ab 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -4936,6 +4936,70 @@ void TestBlackbox::auxiliaryInputsFromDependencies()
QVERIFY2(m_qbsStdout.contains("generating dummy.out"), m_qbsStdout.constData());
}
+void TestBlackbox::explicitlyDependsOn()
+{
+ QFETCH(QString, useExplicitlyDependsOn);
+ QFETCH(QString, useExplicitlyDependsOnFromDependencies);
+ QFETCH(QString, useModule);
+ QFETCH(bool, expectFailure);
+
+ QDir::setCurrent(testDataDir + "/explicitly-depends-on");
+ QbsRunParameters params("",
+ QStringList("products.prod1.useExplicitlyDependsOn:" + useExplicitlyDependsOn)
+ << "products.prod1.useExplicitlyDependsOnFromDependencies:"
+ + useExplicitlyDependsOnFromDependencies
+ << "projects.proj1.useModule:"
+ + useModule);
+ params.expectFailure = expectFailure;
+
+ rmDirR(relativeBuildDir());
+
+ if (params.expectFailure) {
+ // Build should fail because a rule cycle is created within the product when
+ // explicitlyDependsOn is used.
+ QVERIFY(runQbs(params) != 0);
+ QVERIFY2(m_qbsStderr.contains("Cycle detected in rule dependencies"),
+ m_qbsStderr.constData());
+ } else {
+ // When explicitlyDependsOnFromDependencies is used, build should succeed due to the
+ // "final" tag being pulled in from dependencies.
+ QCOMPARE(runQbs(params), 0);
+
+ if (useModule == QLatin1String("false")) {
+ QVERIFY2(m_qbsStdout.contains("creating 'product-fish.txt' tagged with 'final'"),
+ m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("Using explicitlyDependsOnArtifact: product-fish.txt"),
+ m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("step1 -> step2"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("step2 -> step3"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("step3 -> final"), m_qbsStdout.constData());
+ } else {
+ QVERIFY2(!m_qbsStdout.contains("creating 'product-fish.txt' tagged with 'final'"),
+ m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("Using explicitlyDependsOnArtifact: module-fish.txt"),
+ m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("step1 -> step2"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("step2 -> step3"), m_qbsStdout.constData());
+ QVERIFY2(m_qbsStdout.contains("step3 -> final"), m_qbsStdout.constData());
+ }
+ }
+}
+
+void TestBlackbox::explicitlyDependsOn_data()
+{
+ QTest::addColumn<QString>("useExplicitlyDependsOn");
+ QTest::addColumn<QString>("useExplicitlyDependsOnFromDependencies");
+ QTest::addColumn<QString>("useModule");
+ QTest::addColumn<bool>("expectFailure");
+
+ QTest::newRow("useExplicitlyDependsOn -> causes cycle")
+ << "true" << "false" << "false" << true;
+ QTest::newRow("explicitlyDependsOnFromDependencies + product")
+ << "false" << "true" << "false" << false;
+ QTest::newRow("explicitlyDependsOnFromDependencies + module + filesAreTargets")
+ << "false" << "true" << "true" << false;
+}
+
static bool haveMakeNsis()
{
QStringList regKeys;
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index f3fb1f90d..5a4544bbe 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -97,6 +97,8 @@ private slots:
void erroneousFiles();
void errorInfo();
void escapedLinkerFlags();
+ void explicitlyDependsOn();
+ void explicitlyDependsOn_data();
void exportedDependencyInDisabledProduct();
void exportedDependencyInDisabledProduct_data();
void exportedPropertyInDisabledProduct();