source: trunk/qmake/generators/makefile.h@ 973

Last change on this file since 973 was 973, checked in by Dmitry A. Kuminov, 14 years ago

qmake: Make MakefileGenerator::writeHeader() virtual.

This lets generators have additional definitions common to
all generated makefiles in a single place. This is used by
e.g. the OS/2 GNUMAKE generator.

File size: 12.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the qmake application of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef MAKEFILE_H
43#define MAKEFILE_H
44
45#include "option.h"
46#include "project.h"
47#include "makefiledeps.h"
48#include <qtextstream.h>
49#include <qlist.h>
50#include <qhash.h>
51#include <qfileinfo.h>
52
53QT_BEGIN_NAMESPACE
54
55#ifdef Q_OS_WIN32
56#define QT_POPEN _popen
57#define QT_PCLOSE _pclose
58#else
59#define QT_POPEN popen
60#define QT_PCLOSE pclose
61#endif
62
63struct ReplaceExtraCompilerCacheKey
64{
65 mutable uint hash;
66 QString var, in, out, pwd;
67 ReplaceExtraCompilerCacheKey(const QString &v, const QStringList &i, const QStringList &o);
68 bool operator==(const ReplaceExtraCompilerCacheKey &f) const;
69 inline uint hashCode() const {
70 if(!hash)
71 hash = qHash(var) | qHash(in) | qHash(out) /*| qHash(pwd)*/;
72 return hash;
73 }
74};
75inline uint qHash(const ReplaceExtraCompilerCacheKey &f) { return f.hashCode(); }
76
77struct ReplaceExtraCompilerCacheKey;
78
79class MakefileGenerator : protected QMakeSourceFileInfo
80{
81 QString spec;
82 bool init_opath_already, init_already, no_io;
83 QHash<QString, bool> init_compiler_already;
84 QString build_args(const QString &outdir=QString());
85 void checkMultipleDefinition(const QString &, const QString &);
86
87 //internal caches
88 mutable QHash<QString, QMakeLocalFileName> depHeuristicsCache;
89 mutable QHash<QString, QStringList> dependsCache;
90 mutable QHash<ReplaceExtraCompilerCacheKey, QString> extraCompilerVariablesCache;
91
92protected:
93 QStringList createObjectList(const QStringList &sources);
94
95 //makefile style generator functions
96 void writeObj(QTextStream &, const QString &src);
97 void writeInstalls(QTextStream &t, const QString &installs, bool noBuild=false);
98 virtual void writeHeader(QTextStream &t);
99 void writeSubDirs(QTextStream &t);
100 void writeMakeQmake(QTextStream &t);
101 void writeExtraVariables(QTextStream &t);
102 void writeExtraTargets(QTextStream &t);
103 void writeExtraCompilerTargets(QTextStream &t);
104 void writeExtraCompilerVariables(QTextStream &t);
105 virtual bool writeStubMakefile(QTextStream &t);
106 virtual bool writeMakefile(QTextStream &t);
107
108 //generating subtarget makefiles
109 struct SubTarget
110 {
111 QString name;
112 QString in_directory, out_directory;
113 QString profile, target, makefile;
114 QStringList depends;
115 };
116 enum SubTargetFlags {
117 SubTargetInstalls=0x01,
118 SubTargetOrdered=0x02,
119 SubTargetSkipDefaultVariables=0x04,
120 SubTargetSkipDefaultTargets=0x08,
121
122 SubTargetsNoFlags=0x00
123 };
124 QList<MakefileGenerator::SubTarget*> findSubDirsSubTargets() const;
125 void writeSubTargets(QTextStream &t, QList<SubTarget*> subtargets, int flags);
126
127 //extra compiler interface
128 bool verifyExtraCompiler(const QString &c, const QString &f);
129 virtual QString replaceExtraCompilerVariables(const QString &, const QStringList &, const QStringList &);
130 inline QString replaceExtraCompilerVariables(const QString &val, const QString &in, const QString &out)
131 { return replaceExtraCompilerVariables(val, QStringList(in), QStringList(out)); }
132
133 //interface to the source file info
134 QMakeLocalFileName fixPathForFile(const QMakeLocalFileName &, bool);
135 QMakeLocalFileName findFileForDep(const QMakeLocalFileName &, const QMakeLocalFileName &);
136 QFileInfo findFileInfo(const QMakeLocalFileName &);
137 QMakeProject *project;
138
139 //escape
140 virtual QString unescapeFilePath(const QString &path) const;
141 virtual QStringList unescapeFilePaths(const QStringList &path) const;
142 virtual QString escapeFilePath(const QString &path) const { return path; }
143 virtual QString escapeDependencyPath(const QString &path) const { return escapeFilePath(path); }
144 QStringList escapeFilePaths(const QStringList &paths) const;
145 QStringList escapeDependencyPaths(const QStringList &paths) const;
146
147 //initialization
148 void verifyCompilers();
149 virtual void init();
150 void initOutPaths();
151 struct Compiler
152 {
153 QString variable_in;
154 enum CompilerFlag {
155 CompilerNoFlags = 0x00,
156 CompilerBuiltin = 0x01,
157 CompilerNoCheckDeps = 0x02,
158 CompilerRemoveNoExist = 0x04
159 };
160 uint flags, type;
161 };
162 void initCompiler(const Compiler &comp);
163 enum VPATHFlag {
164 VPATH_NoFlag = 0x00,
165 VPATH_WarnMissingFiles = 0x01,
166 VPATH_RemoveMissingFiles = 0x02,
167 VPATH_NoFixify = 0x04
168 };
169 QStringList findFilesInVPATH(QStringList l, uchar flags, const QString &var="");
170
171 inline int findExecutable(const QStringList &cmdline)
172 { int ret; canExecute(cmdline, &ret); return ret; }
173 bool canExecute(const QStringList &cmdline, int *argv0) const;
174 inline bool canExecute(const QString &cmdline) const
175 { return canExecute(cmdline.split(' '), 0); }
176
177 bool mkdir(const QString &dir) const;
178 QString mkdir_p_asstring(const QString &dir, bool escape=true) const;
179
180 //subclasses can use these to query information about how the generator was "run"
181 QString buildArgs(const QString &outdir=QString());
182 QString specdir(const QString &outdir=QString());
183
184 virtual QStringList &findDependencies(const QString &file);
185 virtual bool doDepends() const { return Option::mkfile::do_deps; }
186
187 void filterIncludedFiles(const QString &);
188 virtual void processSources() {
189 filterIncludedFiles("SOURCES");
190 filterIncludedFiles("GENERATED_SOURCES");
191 }
192
193 //for cross-platform dependent directories
194 virtual void usePlatformDir();
195
196 //for installs
197 virtual QString defaultInstall(const QString &);
198
199 //for prl
200 QString prlFileName(bool fixify=true);
201 void writePrlFile();
202 bool processPrlFile(QString &);
203 virtual void processPrlVariable(const QString &, const QStringList &);
204 virtual void processPrlFiles();
205 virtual void writePrlFile(QTextStream &);
206
207 //make sure libraries are found
208 virtual bool findLibraries();
209
210 //for retrieving values and lists of values
211 virtual QString var(const QString &var);
212 QString varGlue(const QString &var, const QString &before, const QString &glue, const QString &after);
213 QString varList(const QString &var);
214 QString val(const QStringList &varList);
215 QString valGlue(const QStringList &varList, const QString &before, const QString &glue, const QString &after);
216 QString valList(const QStringList &varList);
217
218 QString filePrefixRoot(const QString &, const QString &);
219
220 //file fixification to unify all file names into a single pattern
221 enum FileFixifyType { FileFixifyAbsolute, FileFixifyRelative, FileFixifyDefault };
222 QString fileFixify(const QString& file, const QString &out_dir=QString(),
223 const QString &in_dir=QString(), FileFixifyType fix=FileFixifyDefault, bool canon=true) const;
224 inline QString fileFixify(const QString& file, FileFixifyType fix, bool canon=true) const
225 { return fileFixify(file, QString(), QString(), fix, canon); }
226 QStringList fileFixify(const QStringList& files, const QString &out_dir=QString(),
227 const QString &in_dir=QString(), FileFixifyType fix=FileFixifyDefault, bool canon=true) const;
228 inline QStringList fileFixify(const QStringList& files, FileFixifyType fix, bool canon=true) const
229 { return fileFixify(files, QString(), QString(), fix, canon); }
230
231public:
232 MakefileGenerator();
233 virtual ~MakefileGenerator();
234 QMakeProject *projectFile() const;
235 void setProjectFile(QMakeProject *p);
236
237 void setNoIO(bool o);
238 bool noIO() const;
239
240 inline bool exists(QString file) const { return fileInfo(file).exists(); }
241 QFileInfo fileInfo(QString file) const;
242
243 static MakefileGenerator *create(QMakeProject *);
244 virtual bool write();
245 virtual bool writeProjectMakefile();
246 virtual bool supportsMetaBuild() { return true; }
247 virtual bool supportsMergedBuilds() { return false; }
248 virtual bool mergeBuildProject(MakefileGenerator * /*other*/) { return false; }
249 virtual bool openOutput(QFile &, const QString &build) const;
250 virtual bool isDosLikeShell() const { return Option::host_mode == Option::HOST_WIN_MODE ||
251 Option::host_mode == Option::HOST_OS2_MODE; }
252 virtual bool isForSymbianSbsv2() const { return false; } // FIXME: killme - i'm ugly!
253
254 /* The next one is to avoid having SymbianCommonGenerator as a virtually
255 inherited class of this class. Instead it is without a base class
256 (avoiding the virtual inheritance problem), and is allowed to use
257 functions defined in here.
258
259 To illustrate:
260 +-------------------+
261 | MakefileGenerator |
262 +-------------------+
263 ^ ^
264 | |
265 | X <-- Avoid this inheritance
266 | |
267 +------------------------+ +------------------------+
268 | UnixMakefileGenerator | | SymbianCommonGenerator |
269 | or | | |
270 | NmakeMakefileGenerator | | |
271 +------------------------+ +------------------------+
272 ^ ^
273 | |
274 | |
275 | |
276 +-----------------------------+
277 | SymbianMakefileTemplate<> |
278 +-----------------------------+
279
280 We want to avoid the famous diamond problem, because if we have that, we need
281 virtual inheritance, which not all compilers like. Therefore, we break the
282 link as illustrated. Instead, we have a pointer to MakefileGenerator inside
283 SymbianCommonGenerator, and allows full access by making it a friend here.
284 */
285 friend class SymbianCommonGenerator;
286};
287
288inline void MakefileGenerator::setNoIO(bool o)
289{ no_io = o; }
290
291inline bool MakefileGenerator::noIO() const
292{ return no_io; }
293
294inline QString MakefileGenerator::defaultInstall(const QString &)
295{ return QString(""); }
296
297inline bool MakefileGenerator::findLibraries()
298{ return true; }
299
300inline MakefileGenerator::~MakefileGenerator()
301{ }
302
303QT_END_NAMESPACE
304
305#endif // MAKEFILE_H
Note: See TracBrowser for help on using the repository browser.