/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Build Suite. ** ** 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 Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ****************************************************************************/ #ifndef QBS_LANGUAGE_H #define QBS_LANGUAGE_H #include "filetags.h" #include "forward_decls.h" #include "jsimports.h" #include "propertymapinternal.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE class QScriptEngine; QT_END_NAMESPACE namespace qbs { namespace Internal { class BuildGraphLoader; class BuildGraphVisitor; class FileTagger : public PersistentObject { public: static FileTaggerPtr create() { return FileTaggerPtr(new FileTagger); } static FileTaggerPtr create(const QStringList &patterns, const FileTags &fileTags) { return FileTaggerPtr(new FileTagger(patterns, fileTags)); } const QList &patterns() const { return m_patterns; } const FileTags &fileTags() const { return m_fileTags; } private: FileTagger(const QStringList &patterns, const FileTags &fileTags); FileTagger() {} void setPatterns(const QStringList &patterns); void load(PersistentPool &); void store(PersistentPool &) const; QList m_patterns; FileTags m_fileTags; }; class TagScanner : public PersistentObject { public: static TagScannerPtr create() { return TagScannerPtr(new TagScanner); } void init(const CodeLocation &location, const QString &name, const FileTags &inTags, const FileTags &outTags, const ScriptFunctionConstPtr &scanScript) { m_location = location; m_name = name; m_inputTags = inTags; m_outputTags = outTags; m_scanScript = scanScript; } const CodeLocation &location() const { return m_location; } const QString &name() const { return m_name; } const FileTags &inputTags() const { return m_inputTags; } const FileTags &outputTags() const { return m_outputTags; } const ScriptFunctionConstPtr &scanScript() const { return m_scanScript; } void setDependencies(const QList &deps) { m_dependencies = deps; } const QList &dependencies() const { return m_dependencies; } private: TagScanner() {} void load(PersistentPool &pool); void store(PersistentPool &pool) const; CodeLocation m_location; QString m_name; FileTags m_inputTags; FileTags m_outputTags; ScriptFunctionConstPtr m_scanScript; QList m_dependencies; }; class RuleArtifact : public PersistentObject { public: static RuleArtifactPtr create() { return RuleArtifactPtr(new RuleArtifact); } QString fileName; FileTags fileTags; bool alwaysUpdated; class Binding { public: QStringList name; QString code; CodeLocation location; }; QVector bindings; private: RuleArtifact() : alwaysUpdated(true) {} void load(PersistentPool &pool); void store(PersistentPool &pool) const; }; uint qHash(const RuleArtifact::Binding &b); bool operator==(const RuleArtifact::Binding &b1, const RuleArtifact::Binding &b2); inline bool operator!=(const RuleArtifact::Binding &b1, const RuleArtifact::Binding &b2) { return !(b1 == b2); } bool operator==(const RuleArtifact &a1, const RuleArtifact &a2); inline bool operator!=(const RuleArtifact &a1, const RuleArtifact &a2) { return !(a1 == a2); } class SourceArtifact : public PersistentObject { public: static SourceArtifactPtr create() { return SourceArtifactPtr(new SourceArtifact); } QString absoluteFilePath; FileTags fileTags; bool overrideFileTags; PropertyMapPtr properties; private: SourceArtifact() : overrideFileTags(true) {} void load(PersistentPool &pool); void store(PersistentPool &pool) const; }; bool operator==(const SourceArtifact &sa1, const SourceArtifact &sa2); inline bool operator!=(const SourceArtifact &sa1, const SourceArtifact &sa2) { return !(sa1 == sa2); } bool sourceArtifactSetsAreEqual(const QList &l1, const QList &l2); class SourceWildCards : public PersistentObject { public: typedef QSharedPointer Ptr; typedef QSharedPointer ConstPtr; static Ptr create() { return Ptr(new SourceWildCards); } QSet expandPatterns(const GroupConstPtr &group, const QString &baseDir) const; // TODO: Use back pointer to Group instead? QString prefix; QStringList patterns; QStringList excludePatterns; QList files; private: SourceWildCards() {} QSet expandPatterns(const GroupConstPtr &group, const QStringList &patterns, const QString &baseDir) const; void expandPatterns(QSet &result, const GroupConstPtr &group, const QStringList &parts, const QString &baseDir) const; void load(PersistentPool &pool); void store(PersistentPool &pool) const; }; class ResolvedGroup : public PersistentObject { public: static GroupPtr create() { return GroupPtr(new ResolvedGroup); } CodeLocation location; QString name; bool enabled; QString prefix; QList files; SourceWildCards::Ptr wildcards; PropertyMapPtr properties; FileTags fileTags; bool overrideTags; QList allFiles() const; private: ResolvedGroup() : enabled(true) {} void load(PersistentPool &pool); void store(PersistentPool &pool) const; }; class ResolvedFileContext : public PersistentObject { public: static ResolvedFileContextPtr create() { return ResolvedFileContextPtr(new ResolvedFileContext); } QString filePath; QStringList jsExtensions; JsImports jsImports; private: ResolvedFileContext() {} void load(PersistentPool &pool); void store(PersistentPool &pool) const; }; bool operator==(const ResolvedFileContext &a, const ResolvedFileContext &b); inline bool operator!=(const ResolvedFileContext &a, const ResolvedFileContext &b) { return !(a == b); } class ScriptFunction : public PersistentObject { public: static ScriptFunctionPtr create() { return ScriptFunctionPtr(new ScriptFunction); } QString sourceCode; QStringList argumentNames; CodeLocation location; ResolvedFileContextConstPtr fileContext; mutable QScriptValue scriptFunction; // cache private: ScriptFunction() {} void load(PersistentPool &); void store(PersistentPool &) const; }; bool operator==(const ScriptFunction &a, const ScriptFunction &b); inline bool operator!=(const ScriptFunction &a, const ScriptFunction &b) { return !(a == b); } class ResolvedModule : public PersistentObject { public: static ResolvedModulePtr create() { return ResolvedModulePtr(new ResolvedModule); } QString name; QStringList moduleDependencies; ScriptFunctionPtr setupBuildEnvironmentScript; ScriptFunctionPtr setupRunEnvironmentScript; private: ResolvedModule() {} void load(PersistentPool &pool); void store(PersistentPool &pool) const; }; bool operator==(const ResolvedModule &m1, const ResolvedModule &m2); inline bool operator!=(const ResolvedModule &m1, const ResolvedModule &m2) { return !(m1 == m2); } /** * Per default each rule is a "non-multiplex rule". * * A "multiplex rule" creates one transformer that takes all * input artifacts with the matching input file tag and creates * one or more artifacts. (e.g. linker rule) * * A "non-multiplex rule" creates one transformer per matching input file. */ class Rule : public PersistentObject { public: static RulePtr create() { return RulePtr(new Rule); } ResolvedModuleConstPtr module; ScriptFunctionPtr script; FileTags inputs; FileTags auxiliaryInputs; FileTags usings; FileTags explicitlyDependsOn; bool multiplex; QList artifacts; // members that we don't need to save int ruleGraphId; QString toString() const; FileTags outputFileTags() const; private: Rule() : multiplex(false), ruleGraphId(-1) {} void load(PersistentPool &pool); void store(PersistentPool &pool) const; }; bool operator==(const Rule &r1, const Rule &r2); inline bool operator!=(const Rule &r1, const Rule &r2) { return !(r1 == r2); } bool ruleListsAreEqual(const QList &l1, const QList &l2); class ResolvedTransformer : public PersistentObject { public: static ResolvedTransformerPtr create() { return ResolvedTransformerPtr(new ResolvedTransformer); } ResolvedModuleConstPtr module; QStringList inputs; QList outputs; ScriptFunctionPtr transform; FileTags explicitlyDependsOn; private: ResolvedTransformer() {} void load(PersistentPool &pool); void store(PersistentPool &pool) const; }; bool operator==(const ResolvedTransformer &t1, const ResolvedTransformer &t2); inline bool operator!=(const ResolvedTransformer &t1, const ResolvedTransformer &t2) { return !(t1 == t2); } bool transformerListsAreEqual(const QList &l1, const QList &l2); class TopLevelProject; class ScriptEngine; class ResolvedProduct : public PersistentObject { public: static ResolvedProductPtr create() { return ResolvedProductPtr(new ResolvedProduct); } ~ResolvedProduct(); bool enabled; FileTags fileTags; FileTags additionalFileTags; QString name; QString targetName; QString sourceDirectory; QString destinationDirectory; CodeLocation location; WeakPointer project; PropertyMapPtr properties; QSet rules; QSet dependencies; QList fileTaggers; QList tagScanners; QList modules; QList transformers; QList groups; QList artifactProperties; QScopedPointer buildData; mutable QProcessEnvironment buildEnvironment; // must not be saved mutable QProcessEnvironment runEnvironment; // must not be saved QHash executablePathCache; void accept(BuildGraphVisitor *visitor) const; QList allFiles() const; QList allEnabledFiles() const; FileTags fileTagsForFileName(const QString &fileName) const; void setupBuildEnvironment(ScriptEngine *scriptEngine, const QProcessEnvironment &env) const; void setupRunEnvironment(ScriptEngine *scriptEngine, const QProcessEnvironment &env) const; const QList &topSortedRules() const; TopLevelProject *topLevelProject() const; QStringList generatedFiles(const QString &baseFile, const FileTags &tags) const; private: ResolvedProduct(); void load(PersistentPool &pool); void store(PersistentPool &pool) const; }; class ResolvedProject : public PersistentObject { public: static ResolvedProjectPtr create() { return ResolvedProjectPtr(new ResolvedProject); } QString name; CodeLocation location; bool enabled; QList products; QList subProjects; WeakPointer parentProject; virtual void accept(BuildGraphVisitor *visitor) const; void setProjectProperties(const QVariantMap &config) { m_projectProperties = config; } const QVariantMap &projectProperties() const { return m_projectProperties; } TopLevelProject *topLevelProject(); QList allSubProjects() const; QList allProducts() const; protected: ResolvedProject(); void load(PersistentPool &pool); void store(PersistentPool &pool) const; private: QVariantMap m_projectProperties; TopLevelProject *m_topLevelProject; }; class TopLevelProject : public ResolvedProject { friend class BuildGraphLoader; public: ~TopLevelProject(); static TopLevelProjectPtr create() { return TopLevelProjectPtr(new TopLevelProject); } static QString deriveId(const QVariantMap &config); static QString deriveBuildDirectory(const QString &buildRoot, const QString &id); QString buildDirectory; // Not saved QProcessEnvironment environment; QVariantMap platformEnvironment; QHash usedEnvironment; // Environment variables requested by the project while resolving. QHash fileExistsResults; // Results of calls to "File.exists()". QScopedPointer buildData; bool locked; QSet buildSystemFiles; void accept(BuildGraphVisitor *visitor) const; void setBuildConfiguration(const QVariantMap &config); const QVariantMap &buildConfiguration() const { return m_buildConfiguration; } QString id() const { return m_id; } QString buildGraphFilePath() const; void store(const Logger &logger) const; private: TopLevelProject(); void load(PersistentPool &pool); void store(PersistentPool &pool) const; QString m_id; QVariantMap m_buildConfiguration; }; bool artifactPropertyListsAreEqual(const QList &l1, const QList &l2); } // namespace Internal } // namespace qbs QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(qbs::Internal::JsImport, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(qbs::Internal::RuleArtifact::Binding, Q_MOVABLE_TYPE); QT_END_NAMESPACE #endif // QBS_LANGUAGE_H