1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #pragma once
27 
28 #include "projectexplorer_export.h"
29 #include "projectconfiguration.h"
30 #include "task.h"
31 
32 #include <utils/environment.h>
33 #include <utils/fileutils.h>
34 
35 namespace Utils { class MacroExpander; }
36 
37 namespace ProjectExplorer {
38 
39 namespace Internal { class BuildConfigurationPrivate; }
40 
41 class BuildDirectoryAspect;
42 class BuildInfo;
43 class BuildSystem;
44 class BuildStepList;
45 class Kit;
46 class NamedWidget;
47 class Node;
48 class RunConfiguration;
49 class Target;
50 
51 class PROJECTEXPLORER_EXPORT BuildConfiguration : public ProjectConfiguration
52 {
53     Q_OBJECT
54 
55 protected:
56     friend class BuildConfigurationFactory;
57     explicit BuildConfiguration(Target *target, Utils::Id id);
58 
59 public:
60     ~BuildConfiguration() override;
61 
62     Utils::FilePath buildDirectory() const;
63     Utils::FilePath rawBuildDirectory() const;
64     void setBuildDirectory(const Utils::FilePath &dir);
65 
66     virtual BuildSystem *buildSystem() const;
67 
68     virtual NamedWidget *createConfigWidget();
69     virtual QList<NamedWidget *> createSubConfigWidgets();
70 
71     // Maybe the BuildConfiguration is not the best place for the environment
72     Utils::Environment baseEnvironment() const;
73     QString baseEnvironmentText() const;
74     Utils::Environment environment() const;
75     void setUserEnvironmentChanges(const Utils::EnvironmentItems &diff);
76     Utils::EnvironmentItems userEnvironmentChanges() const;
77     bool useSystemEnvironment() const;
78     void setUseSystemEnvironment(bool b);
79 
80     virtual void addToEnvironment(Utils::Environment &env) const;
81 
82     const QList<Utils::Id> customParsers() const;
83     void setCustomParsers(const QList<Utils::Id> &parsers);
84 
85     BuildStepList *buildSteps() const;
86     BuildStepList *cleanSteps() const;
87 
88     void appendInitialBuildStep(Utils::Id id);
89     void appendInitialCleanStep(Utils::Id id);
90 
91     bool fromMap(const QVariantMap &map) override;
92     QVariantMap toMap() const override;
93 
94     bool isEnabled() const;
95     QString disabledReason() const;
96 
97     virtual bool regenerateBuildFiles(Node *node);
98 
99     virtual void restrictNextBuild(const RunConfiguration *rc);
100 
101     enum BuildType {
102         Unknown,
103         Debug,
104         Profile,
105         Release
106     };
107     virtual BuildType buildType() const;
108 
109     static QString buildTypeName(BuildType type);
110 
111     bool isActive() const;
112 
113     void updateCacheAndEmitEnvironmentChanged();
114 
115     ProjectExplorer::BuildDirectoryAspect *buildDirectoryAspect() const;
116     void setConfigWidgetDisplayName(const QString &display);
117     void setBuildDirectoryHistoryCompleter(const QString &history);
118     void setConfigWidgetHasFrame(bool configWidgetHasFrame);
119     void setBuildDirectorySettingsKey(const QString &key);
120 
121     void addConfigWidgets(const std::function<void (NamedWidget *)> &adder);
122 
123     void doInitialize(const BuildInfo &info);
124 
125     Utils::MacroExpander *macroExpander() const;
126 
127     bool createBuildDirectory();
128 
129 signals:
130     void environmentChanged();
131     void buildDirectoryChanged();
132     void enabledChanged();
133     void buildTypeChanged();
134 
135 protected:
136     void setInitializer(const std::function<void(const BuildInfo &info)> &initializer);
137 
138 private:
139     void emitBuildDirectoryChanged();
140     Internal::BuildConfigurationPrivate *d = nullptr;
141 };
142 
143 class PROJECTEXPLORER_EXPORT BuildConfigurationFactory
144 {
145 protected:
146     BuildConfigurationFactory();
147     BuildConfigurationFactory(const BuildConfigurationFactory &) = delete;
148     BuildConfigurationFactory &operator=(const BuildConfigurationFactory &) = delete;
149 
150     virtual ~BuildConfigurationFactory(); // Needed for dynamic_casts in importers.
151 
152 public:
153     // List of build information that can be used to create a new build configuration via
154     // "Add Build Configuration" button.
155     const QList<BuildInfo> allAvailableBuilds(const Target *parent) const;
156 
157     // List of build information that can be used to initially set up a new build configuration.
158     const QList<BuildInfo>
159         allAvailableSetups(const Kit *k, const Utils::FilePath &projectPath) const;
160 
161     BuildConfiguration *create(Target *parent, const BuildInfo &info) const;
162 
163     static BuildConfiguration *restore(Target *parent, const QVariantMap &map);
164     static BuildConfiguration *clone(Target *parent, const BuildConfiguration *source);
165 
166     static BuildConfigurationFactory *find(const Kit *k, const Utils::FilePath &projectPath);
167     static BuildConfigurationFactory *find(Target *parent);
168 
169     using IssueReporter = std::function<Tasks(Kit *, const QString &, const QString &)>;
170     void setIssueReporter(const IssueReporter &issueReporter);
171     const Tasks reportIssues(ProjectExplorer::Kit *kit,
172                              const QString &projectPath, const QString &buildDir) const;
173 
174 protected:
175     using BuildGenerator
176         = std::function<QList<BuildInfo>(const Kit *, const Utils::FilePath &, bool)>;
177     void setBuildGenerator(const BuildGenerator &buildGenerator);
178 
179     bool supportsTargetDeviceType(Utils::Id id) const;
180     void setSupportedProjectType(Utils::Id id);
181     void setSupportedProjectMimeTypeName(const QString &mimeTypeName);
182     void addSupportedTargetDeviceType(Utils::Id id);
183     void setDefaultDisplayName(const QString &defaultDisplayName);
184 
185     using BuildConfigurationCreator = std::function<BuildConfiguration *(Target *)>;
186 
187     template <class BuildConfig>
registerBuildConfiguration(Utils::Id buildConfigId)188     void registerBuildConfiguration(Utils::Id buildConfigId)
189     {
190         m_creator = [buildConfigId](Target *t) { return new BuildConfig(t, buildConfigId); };
191         m_buildConfigId = buildConfigId;
192     }
193 
194 private:
195     bool canHandle(const ProjectExplorer::Target *t) const;
196 
197     BuildConfigurationCreator m_creator;
198     Utils::Id m_buildConfigId;
199     Utils::Id m_supportedProjectType;
200     QList<Utils::Id> m_supportedTargetDeviceTypes;
201     QString m_supportedProjectMimeTypeName;
202     IssueReporter m_issueReporter;
203     BuildGenerator m_buildGenerator;
204 };
205 
206 } // namespace ProjectExplorer
207