diff options
author | Christian Kandeler <christian.kandeler@digia.com> | 2013-10-02 12:51:29 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@digia.com> | 2013-10-09 12:28:32 +0200 |
commit | 63174f2538c61407d61df48840ed9f7062f3ae0f (patch) | |
tree | ae15f7691eeb17cf75dcc052693c2a7331b8e0bf | |
parent | abd6dad9f0e0f94a32ada3116e7ebf4da830d23b (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.qdoc | 10 | ||||
-rw-r--r-- | doc/reference/items/project.qdoc | 8 | ||||
-rw-r--r-- | src/lib/language/builtindeclarations.cpp | 4 | ||||
-rw-r--r-- | src/lib/language/evaluator.cpp | 4 | ||||
-rw-r--r-- | src/lib/language/evaluator.h | 2 | ||||
-rw-r--r-- | src/lib/language/itemreader.cpp | 21 | ||||
-rw-r--r-- | src/lib/language/itemreader.h | 6 | ||||
-rw-r--r-- | src/lib/language/moduleloader.cpp | 59 | ||||
-rw-r--r-- | src/lib/language/moduleloader.h | 4 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata/subprojects/resources/imports/LibraryType/type.js | 1 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata/subprojects/resources/modules/QtCoreDepender/qtcoredepender.qbs | 5 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata/subprojects/subproject2/subproject3/subproject3.qbs | 6 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata/subprojects/toplevelproject.qbs | 2 |
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"] } |