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 "qmakeprojectmanager_global.h"
29 
30 #include <projectexplorer/abstractprocessstep.h>
31 
32 #include <utils/aspects.h>
33 #include <utils/commandline.h>
34 
35 #include <memory>
36 
37 QT_BEGIN_NAMESPACE
38 class QComboBox;
39 class QLabel;
40 class QLineEdit;
41 class QPlainTextEdit;
42 class QListWidget;
43 QT_END_NAMESPACE
44 
45 namespace ProjectExplorer {
46 class Abi;
47 class ArgumentsAspect;
48 } // namespace ProjectExplorer
49 
50 namespace QtSupport { class BaseQtVersion; }
51 
52 namespace QmakeProjectManager {
53 class QmakeBuildConfiguration;
54 class QmakeBuildSystem;
55 
56 namespace Internal {
57 
58 class QMakeStepFactory : public ProjectExplorer::BuildStepFactory
59 {
60 public:
61     QMakeStepFactory();
62 };
63 
64 } // namespace Internal
65 
66 class QMAKEPROJECTMANAGER_EXPORT QMakeStepConfig
67 {
68 public:
69     // TODO remove, does nothing
70     enum TargetArchConfig { NoArch, X86, X86_64, PowerPC, PowerPC64 };
71 
72     enum OsType { NoOsType, IphoneSimulator, IphoneOS };
73 
74     // TODO remove, does nothing
75     static TargetArchConfig targetArchFor(const ProjectExplorer::Abi &targetAbi,
76                                           const QtSupport::BaseQtVersion *version);
77     static OsType osTypeFor(const ProjectExplorer::Abi &targetAbi, const QtSupport::BaseQtVersion *version);
78 
79     QStringList toArguments() const;
80 
81     // Actual data
82     QString sysRoot;
83     QString targetTriple;
84     // TODO remove, does nothing
85     TargetArchConfig archConfig = NoArch;
86     OsType osType = NoOsType;
87     Utils::TriState separateDebugInfo;
88     Utils::TriState linkQmlDebuggingQQ2;
89     Utils::TriState useQtQuickCompiler;
90 };
91 
92 
93 inline bool operator ==(const QMakeStepConfig &a, const QMakeStepConfig &b) {
94     return std::tie(a.archConfig, a.osType, a.linkQmlDebuggingQQ2)
95                == std::tie(b.archConfig, b.osType, b.linkQmlDebuggingQQ2)
96             && std::tie(a.useQtQuickCompiler, a.separateDebugInfo)
97                == std::tie(b.useQtQuickCompiler, b.separateDebugInfo);
98 }
99 
100 inline bool operator !=(const QMakeStepConfig &a, const QMakeStepConfig &b) {
101     return !(a == b);
102 }
103 
104 inline QDebug operator<<(QDebug dbg, const QMakeStepConfig &c)
105 {
106    dbg << c.archConfig << c.osType
107        << (c.linkQmlDebuggingQQ2 == Utils::TriState::Enabled)
108        << (c.useQtQuickCompiler == Utils::TriState::Enabled)
109        << (c.separateDebugInfo == Utils::TriState::Enabled);
110    return dbg;
111 }
112 
113 class QMAKEPROJECTMANAGER_EXPORT QMakeStep : public ProjectExplorer::AbstractProcessStep
114 {
115     Q_OBJECT
116     friend class Internal::QMakeStepFactory;
117 
118 public:
119     QMakeStep(ProjectExplorer::BuildStepList *parent, Utils::Id id);
120 
121     QmakeBuildConfiguration *qmakeBuildConfiguration() const;
122     QmakeBuildSystem *qmakeBuildSystem() const;
123     bool init() override;
124     void setupOutputFormatter(Utils::OutputFormatter *formatter) override;
125     void doRun() override;
126     QWidget *createConfigWidget() override;
127     void setForced(bool b);
128 
129     enum class ArgumentFlag {
130         OmitProjectPath = 0x01,
131         Expand = 0x02
132     };
133     Q_DECLARE_FLAGS(ArgumentFlags, ArgumentFlag);
134 
135     // the complete argument line
136     QString allArguments(const QtSupport::BaseQtVersion *v,
137                          ArgumentFlags flags = ArgumentFlags()) const;
138     QMakeStepConfig deducedArguments() const;
139     // arguments passed to the pro file parser
140     QStringList parserArguments();
141     // arguments set by the user
142     QString userArguments() const;
143     void setUserArguments(const QString &arguments);
144     // Extra arguments for qmake and pro file parser. Not user editable via UI.
145     QStringList extraArguments() const;
146     void setExtraArguments(const QStringList &args);
147     /* Extra arguments for pro file parser only. Not user editable via UI.
148      * This function is used in 3rd party plugin SailfishOS. */
149     QStringList extraParserArguments() const;
150     void setExtraParserArguments(const QStringList &args);
151     QString mkspec() const;
152 
153     Utils::FilePath makeCommand() const;
154     QString makeArguments(const QString &makefile) const;
155     QString effectiveQMakeCall() const;
156 
157     QVariantMap toMap() const override;
158 
159 protected:
160     bool fromMap(const QVariantMap &map) override;
161     void processStartupFailed() override;
162     bool processSucceeded(int exitCode, QProcess::ExitStatus status) override;
163 
164 private:
165     void doCancel() override;
166     void finish(bool success) override;
167 
168     void startOneCommand(const Utils::CommandLine &command);
169     void runNextCommand();
170 
171     // slots for handling buildconfiguration/step signals
172     void qtVersionChanged();
173     void qmakeBuildConfigChanged();
174     void linkQmlDebuggingLibraryChanged();
175     void useQtQuickCompilerChanged();
176     void separateDebugInfoChanged();
177     void abisChanged();
178 
179     // slots for dealing with user changes in our UI
180     void qmakeArgumentsLineEdited();
181     void buildConfigurationSelected();
182     void askForRebuild(const QString &title);
183 
184     void recompileMessageBoxFinished(int button);
185 
186     void updateAbiWidgets();
187     void updateEffectiveQMakeCall();
188 
189     Utils::CommandLine m_qmakeCommand;
190     Utils::CommandLine m_makeCommand;
191     ProjectExplorer::ArgumentsAspect *m_userArgs = nullptr;
192     // Extra arguments for qmake and pro file parser
193     QStringList m_extraArgs;
194     // Extra arguments for pro file parser only
195     QStringList m_extraParserArgs;
196 
197     // last values
198     enum class State { IDLE = 0, RUN_QMAKE, RUN_MAKE_QMAKE_ALL, POST_PROCESS };
199     bool m_wasSuccess = true;
200     State m_nextState = State::IDLE;
201     bool m_forced = false;
202     bool m_needToRunQMake = false; // set in init(), read in run()
203 
204     bool m_runMakeQmake = false;
205     bool m_scriptTemplate = false;
206     QStringList m_selectedAbis;
207     Utils::OutputFormatter *m_outputFormatter = nullptr;
208 
209     bool m_ignoreChange = false;
210 
211     QLabel *abisLabel = nullptr;
212     Utils::SelectionAspect *m_buildType = nullptr;
213     Utils::StringAspect *m_effectiveCall = nullptr;
214     QListWidget *abisListWidget = nullptr;
215 };
216 
217 } // namespace QmakeProjectManager
218 
219 Q_DECLARE_OPERATORS_FOR_FLAGS(QmakeProjectManager::QMakeStep::ArgumentFlags);
220