aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@digia.com>2013-10-02 12:51:29 +0200
committerChristian Kandeler <christian.kandeler@digia.com>2013-10-09 12:28:32 +0200
commit63174f2538c61407d61df48840ed9f7062f3ae0f (patch)
treeae15f7691eeb17cf75dcc052693c2a7331b8e0bf
parentabd6dad9f0e0f94a32ada3116e7ebf4da830d23b (diff)
Introduce new project/product property "qbsSearchPaths".
This extends preferences.qbsPath and allows to use project-specific imports. It also deprecates the "moduleSearchPaths" property, which becomes redundant now. Change-Id: I66ff8aa57f6b2657211e3f4541909b2572c6d613 Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
-rw-r--r--doc/reference/items/product.qdoc10
-rw-r--r--doc/reference/items/project.qdoc8
-rw-r--r--src/lib/language/builtindeclarations.cpp4
-rw-r--r--src/lib/language/evaluator.cpp4
-rw-r--r--src/lib/language/evaluator.h2
-rw-r--r--src/lib/language/itemreader.cpp21
-rw-r--r--src/lib/language/itemreader.h6
-rw-r--r--src/lib/language/moduleloader.cpp59
-rw-r--r--src/lib/language/moduleloader.h4
-rw-r--r--tests/auto/blackbox/testdata/subprojects/resources/imports/LibraryType/type.js1
-rw-r--r--tests/auto/blackbox/testdata/subprojects/resources/modules/QtCoreDepender/qtcoredepender.qbs5
-rw-r--r--tests/auto/blackbox/testdata/subprojects/subproject2/subproject3/subproject3.qbs6
-rw-r--r--tests/auto/blackbox/testdata/subprojects/toplevelproject.qbs2
13 files changed, 104 insertions, 28 deletions
diff --git a/doc/reference/items/product.qdoc b/doc/reference/items/product.qdoc
index 814bd1266..3172e06c9 100644
--- a/doc/reference/items/product.qdoc
+++ b/doc/reference/items/product.qdoc
@@ -118,12 +118,12 @@
\li If true, a console application is generated. If false, a GUI application is generated.
Only takes effect on Windows.
\row
- \li moduleSearchPaths
+ \li qbsSearchPaths
\li stringList
- \li \c project.moduleSearchPaths
- \li The paths that are searched when looking for a module this product depends on.
- For more information, see \l{Project Item}. Setting this
- property here will overwrite the default value inherited from the project.
+ \li project.qbsSearchPaths
+ \li See the documentation of the \l {Project Item} property of the same name.
+ Setting this property here will overwrite the default value inherited from
+ the project, so use the \c concat() function if you want to add something.
\endtable
The following properties are automatically set by qbs and usually are not changed by the user:
diff --git a/doc/reference/items/project.qdoc b/doc/reference/items/project.qdoc
index 9280ba4b0..5d8ca35cc 100644
--- a/doc/reference/items/project.qdoc
+++ b/doc/reference/items/project.qdoc
@@ -73,14 +73,12 @@
\li Whether the project is enabled. If false, no products or sub-projects will be
collected.
\row
- \li moduleSearchPaths
+ \li qbsSearchPaths
\li stringList
\li empty
- \li The paths that are searched when looking for a module a product depends on.
+ \li These paths are searched for imports and modules in addition to the ones listed
+ in \c{preferences.qbsPath}.
All products in the project inherit this value by default.
- In addition to what is given here, Qbs will also look in the directory where
- the Qbs file defining this project is located, as well as in the paths
- listed in the \c preferences.qbsPath setting.
\row
\li references
\li path list
diff --git a/src/lib/language/builtindeclarations.cpp b/src/lib/language/builtindeclarations.cpp
index 9ff9c7b03..df4d464f1 100644
--- a/src/lib/language/builtindeclarations.cpp
+++ b/src/lib/language/builtindeclarations.cpp
@@ -273,6 +273,8 @@ void BuiltinDeclarations::addProductItem()
PropertyDeclaration::PropertyNotAvailableInConfig);
properties += PropertyDeclaration(QLatin1String("moduleSearchPaths"),
PropertyDeclaration::Variant);
+ properties += PropertyDeclaration(QLatin1String("qbsSearchPaths"),
+ PropertyDeclaration::StringList);
properties += PropertyDeclaration(QLatin1String("version"), PropertyDeclaration::String);
m_builtins[QLatin1String("Product")] = properties;
}
@@ -286,6 +288,8 @@ void BuiltinDeclarations::addProjectItem()
PropertyDeclaration::PropertyNotAvailableInConfig);
properties += PropertyDeclaration(QLatin1String("moduleSearchPaths"),
PropertyDeclaration::Variant, PropertyDeclaration::PropertyNotAvailableInConfig);
+ properties += PropertyDeclaration(QLatin1String("qbsSearchPaths"),
+ PropertyDeclaration::StringList, PropertyDeclaration::PropertyNotAvailableInConfig);
m_builtins[QLatin1String("Project")] = properties;
}
diff --git a/src/lib/language/evaluator.cpp b/src/lib/language/evaluator.cpp
index 256f38e24..0ef394bfd 100644
--- a/src/lib/language/evaluator.cpp
+++ b/src/lib/language/evaluator.cpp
@@ -144,9 +144,11 @@ static QStringList toStringList(const QScriptValue &scriptValue,
return QStringList();
}
-QStringList Evaluator::stringListValue(const Item *item, const QString &name)
+QStringList Evaluator::stringListValue(const Item *item, const QString &name, bool *propertyWasSet)
{
QScriptValue v = property(item, name);
+ if (propertyWasSet)
+ *propertyWasSet = v.isValid() && !v.isUndefined();
handleEvaluationError(item, name, v);
return toStringList(v, item, name);
}
diff --git a/src/lib/language/evaluator.h b/src/lib/language/evaluator.h
index 7ca89dba4..99f5ce1bf 100644
--- a/src/lib/language/evaluator.h
+++ b/src/lib/language/evaluator.h
@@ -60,7 +60,7 @@ public:
FileTags fileTagsValue(const Item *item, const QString &name);
QString stringValue(const Item *item, const QString &name,
const QString &defaultValue = QString(), bool *propertyWasSet = 0);
- QStringList stringListValue(const Item *item, const QString &name);
+ QStringList stringListValue(const Item *item, const QString &name, bool *propertyWasSet = 0);
QScriptValue scriptValue(const Item *item);
QScriptValue fileScope(const FileContextConstPtr &file);
diff --git a/src/lib/language/itemreader.cpp b/src/lib/language/itemreader.cpp
index 1c2bd6de0..65fca476a 100644
--- a/src/lib/language/itemreader.cpp
+++ b/src/lib/language/itemreader.cpp
@@ -110,9 +110,28 @@ void ItemReader::setSearchPaths(const QStringList &searchPaths)
m_searchPaths = searchPaths;
}
+void ItemReader::pushExtraSearchPaths(const QStringList &extraSearchPaths)
+{
+ m_extraSearchPaths.push(extraSearchPaths);
+}
+
+void ItemReader::popExtraSearchPaths()
+{
+ m_extraSearchPaths.pop();
+}
+
+QStringList ItemReader::searchPaths() const
+{
+ QStringList paths = m_searchPaths;
+ if (!m_extraSearchPaths.isEmpty())
+ paths += m_extraSearchPaths.top();
+ return paths;
+}
+
Item *ItemReader::readFile(const QString &filePath)
{
- return internalReadFile(filePath).rootItem;
+ Item * const item = internalReadFile(filePath).rootItem;
+ return item;
}
QSet<QString> ItemReader::filesRead() const
diff --git a/src/lib/language/itemreader.h b/src/lib/language/itemreader.h
index d444c9064..fdc1ba397 100644
--- a/src/lib/language/itemreader.h
+++ b/src/lib/language/itemreader.h
@@ -35,6 +35,7 @@
#include <QHash>
#include <QSet>
+#include <QStack>
#include <QStringList>
namespace qbs {
@@ -76,7 +77,9 @@ public:
void setPool(ItemPool *pool) { m_pool = pool; }
void setSearchPaths(const QStringList &searchPaths);
- const QStringList &searchPaths() const { return m_searchPaths; }
+ void pushExtraSearchPaths(const QStringList &extraSearchPaths);
+ void popExtraSearchPaths();
+ QStringList searchPaths() const;
Item *readFile(const QString &filePath);
@@ -89,6 +92,7 @@ private:
BuiltinDeclarations *m_builtins;
Logger m_logger;
QStringList m_searchPaths;
+ QStack<QStringList> m_extraSearchPaths;
QHash<const Item *, QSet<JSSourceValuePtr> > m_conditionalValuesPerScopeItem;
class ASTCache;
diff --git a/src/lib/language/moduleloader.cpp b/src/lib/language/moduleloader.cpp
index 0a21d5b00..fd3b9a5dd 100644
--- a/src/lib/language/moduleloader.cpp
+++ b/src/lib/language/moduleloader.cpp
@@ -80,6 +80,11 @@ void ModuleLoader::setProgressObserver(ProgressObserver *progressObserver)
m_progressObserver = progressObserver;
}
+static void addExtraModuleSearchPath(QStringList &list, const QString &searchPath)
+{
+ list += FileInfo::resolvePath(searchPath, moduleSearchSubDir);
+}
+
void ModuleLoader::setSearchPaths(const QStringList &searchPaths)
{
m_reader->setSearchPaths(searchPaths);
@@ -87,7 +92,7 @@ void ModuleLoader::setSearchPaths(const QStringList &searchPaths)
m_moduleDirListCache.clear();
m_moduleSearchPaths.clear();
foreach (const QString &path, searchPaths)
- m_moduleSearchPaths += FileInfo::resolvePath(path, moduleSearchSubDir);
+ addExtraModuleSearchPath(m_moduleSearchPaths, path);
}
ModuleLoaderResult ModuleLoader::load(const QString &filePath,
@@ -123,9 +128,11 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult, Item *item,
return;
ProjectContext projectContext;
projectContext.result = loadResult;
- projectContext.extraSearchPaths = readExtraSearchPaths(item);
- projectContext.extraSearchPaths += FileInfo::resolvePath(item->file()->dirPath(),
+ projectContext.extraModuleSearchPaths = readExtraModuleSearchPaths(item);
+ projectContext.extraModuleSearchPaths += FileInfo::resolvePath(item->file()->dirPath(),
moduleSearchSubDir);
+ projectContext.extraSearchPaths = readExtraSearchPaths(item);
+ m_reader->pushExtraSearchPaths(projectContext.extraSearchPaths);
projectContext.item = item;
ItemValuePtr itemValue = ItemValue::create(item);
projectContext.scope = Item::create(m_pool);
@@ -173,6 +180,8 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult, Item *item,
subItem->location());
}
}
+
+ m_reader->popExtraSearchPaths();
}
void ModuleLoader::handleProduct(ProjectContext *projectContext, Item *item)
@@ -183,7 +192,15 @@ void ModuleLoader::handleProduct(ProjectContext *projectContext, Item *item)
ProductContext productContext;
productContext.project = projectContext;
- productContext.extraSearchPaths = readExtraSearchPaths(item);
+ productContext.extraModuleSearchPaths = readExtraModuleSearchPaths(item);
+ bool extraSearchPathsSet = false;
+ const QStringList extraSearchPaths = readExtraSearchPaths(item, &extraSearchPathsSet);
+ if (extraSearchPathsSet) { // Inherit from project if not set in product itself.
+ productContext.extraSearchPaths = extraSearchPaths;
+ m_reader->pushExtraSearchPaths(extraSearchPaths);
+ } else {
+ productContext.extraSearchPaths = projectContext->extraSearchPaths;
+ }
productContext.item = item;
ItemValuePtr itemValue = ItemValue::create(item);
productContext.scope = Item::create(m_pool);
@@ -211,6 +228,8 @@ void ModuleLoader::handleProduct(ProjectContext *projectContext, Item *item)
mergeExportItems(&productContext);
projectContext->result->productInfos.insert(item, productContext.info);
+ if (extraSearchPathsSet)
+ m_reader->popExtraSearchPaths();
}
void ModuleLoader::handleSubProject(ModuleLoader::ProjectContext *projectContext, Item *item,
@@ -537,10 +556,12 @@ Item *ModuleLoader::loadModule(ProductContext *productContext, Item *item,
return moduleInstance;
}
- const QStringList extraSearchPaths = productContext->extraSearchPaths.isEmpty()
- ? productContext->project->extraSearchPaths : productContext->extraSearchPaths;
+ QStringList extraModuleSearchPaths = productContext->extraModuleSearchPaths.isEmpty()
+ ? productContext->project->extraModuleSearchPaths : productContext->extraModuleSearchPaths;
+ foreach (const QString &searchPath, productContext->extraSearchPaths)
+ addExtraModuleSearchPath(extraModuleSearchPaths, searchPath);
Item *modulePrototype = searchAndLoadModuleFile(productContext, dependsItemLocation,
- moduleName, extraSearchPaths);
+ moduleName, extraModuleSearchPaths);
if (!modulePrototype)
return 0;
instantiateModule(productContext, item, moduleInstance, modulePrototype, moduleName);
@@ -877,12 +898,27 @@ bool ModuleLoader::checkItemCondition(Item *item)
return m_evaluator->boolValue(item, QLatin1String("condition"), true);
}
-QStringList ModuleLoader::readExtraSearchPaths(Item *item)
+QStringList ModuleLoader::readExtraModuleSearchPaths(Item *item)
{
QStringList result;
const QStringList paths = m_evaluator->stringListValue(item,
QLatin1String("moduleSearchPaths"));
const ValueConstPtr prop = item->property(QLatin1String("moduleSearchPaths"));
+ if (!paths.isEmpty()) {
+ m_logger.printWarning(ErrorInfo(Tr::tr("The 'moduleSearchPaths' property is deprecated. "
+ "Use 'qbsSearchPaths' instead."), prop->location()));
+ }
+ foreach (const QString &path, paths)
+ result += FileInfo::resolvePath(FileInfo::path(prop->location().fileName()), path);
+ return result;
+}
+
+QStringList ModuleLoader::readExtraSearchPaths(Item *item, bool *wasSet)
+{
+ QStringList result;
+ const QString propertyName = QLatin1String("qbsSearchPaths");
+ const QStringList paths = m_evaluator->stringListValue(item, propertyName, wasSet);
+ const ValueConstPtr prop = item->property(propertyName);
foreach (const QString &path, paths)
result += FileInfo::resolvePath(FileInfo::path(prop->location().fileName()), path);
return result;
@@ -902,9 +938,10 @@ void ModuleLoader::copyProperties(const Item *sourceProject, Item *targetProject
= sourceProject->propertyDeclarations().constBegin();
it != sourceProject->propertyDeclarations().constEnd(); ++it) {
- // We must not inherit built-in properties such as "name", but "moduleSearchPaths" is
- // an exception.
- if (it.key() == QLatin1String("moduleSearchPaths")) {
+ // We must not inherit built-in properties such as "name", but "moduleSearchPaths"
+ // and "qbsSearchPaths" are exceptions.
+ if (it.key() == QLatin1String("moduleSearchPaths")
+ || it.key() == QLatin1String("qbsSearchPaths")) {
const JSSourceValueConstPtr &v
= targetProject->property(it.key()).dynamicCast<const JSSourceValue>();
QBS_ASSERT(v, continue);
diff --git a/src/lib/language/moduleloader.h b/src/lib/language/moduleloader.h
index 426123489..1e7f3b785 100644
--- a/src/lib/language/moduleloader.h
+++ b/src/lib/language/moduleloader.h
@@ -116,6 +116,7 @@ private:
Item *item;
Item *scope;
+ QStringList extraModuleSearchPaths; // TODO: Remove in 1.2
QStringList extraSearchPaths;
QMap<QString, Item *> moduleItemCache;
};
@@ -175,7 +176,8 @@ private:
void resolveProbe(Item *parent, Item *probe);
void checkCancelation() const;
bool checkItemCondition(Item *item);
- QStringList readExtraSearchPaths(Item *item);
+ QStringList readExtraModuleSearchPaths(Item *item);
+ QStringList readExtraSearchPaths(Item *item, bool *wasSet = 0);
void copyProperties(const Item *sourceProject, Item *targetProject);
Item *wrapWithProject(Item *item);
static QString findExistingModulePath(const QString &searchPath,
diff --git a/tests/auto/blackbox/testdata/subprojects/resources/imports/LibraryType/type.js b/tests/auto/blackbox/testdata/subprojects/resources/imports/LibraryType/type.js
new file mode 100644
index 000000000..cb07f8e5b
--- /dev/null
+++ b/tests/auto/blackbox/testdata/subprojects/resources/imports/LibraryType/type.js
@@ -0,0 +1 @@
+function type() { return "dynamiclibrary"; }
diff --git a/tests/auto/blackbox/testdata/subprojects/resources/modules/QtCoreDepender/qtcoredepender.qbs b/tests/auto/blackbox/testdata/subprojects/resources/modules/QtCoreDepender/qtcoredepender.qbs
new file mode 100644
index 000000000..03d649309
--- /dev/null
+++ b/tests/auto/blackbox/testdata/subprojects/resources/modules/QtCoreDepender/qtcoredepender.qbs
@@ -0,0 +1,5 @@
+import qbs
+
+Module {
+ Depends { name: "Qt.core" }
+}
diff --git a/tests/auto/blackbox/testdata/subprojects/subproject2/subproject3/subproject3.qbs b/tests/auto/blackbox/testdata/subprojects/subproject2/subproject3/subproject3.qbs
index afee6996d..acdf1d7e6 100644
--- a/tests/auto/blackbox/testdata/subprojects/subproject2/subproject3/subproject3.qbs
+++ b/tests/auto/blackbox/testdata/subprojects/subproject2/subproject3/subproject3.qbs
@@ -1,12 +1,14 @@
import qbs
+import LibraryType
Project {
condition: false
property string libNameSuffix: "blubb"
- DynamicLibrary {
+ Product {
name: project.libNamePrefix + project.libNameSuffix
+ type: LibraryType.type()
Depends { name: "cpp" }
- Depends { name: "Qt.core" }
+ Depends { name: "QtCoreDepender" }
cpp.defines: "MY_EXPORT=Q_DECL_EXPORT"
files: "testlib.cpp"
Export { Depends { name: "Qt.core" } }
diff --git a/tests/auto/blackbox/testdata/subprojects/toplevelproject.qbs b/tests/auto/blackbox/testdata/subprojects/toplevelproject.qbs
index a32c13d0d..84a2a211f 100644
--- a/tests/auto/blackbox/testdata/subprojects/toplevelproject.qbs
+++ b/tests/auto/blackbox/testdata/subprojects/toplevelproject.qbs
@@ -14,4 +14,6 @@ Project {
files: "subproject1/main.cpp"
}
}
+
+ qbsSearchPaths: ["resources"]
}