2011-04-27 10:05:43 +00:00
|
|
|
/****************************************************************************
|
|
|
|
**
|
2016-01-15 12:36:27 +00:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2011-04-27 10:05:43 +00:00
|
|
|
**
|
|
|
|
** This file is part of the qmake application of the Qt Toolkit.
|
|
|
|
**
|
2016-01-15 12:36:27 +00:00
|
|
|
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
2012-09-19 12:28:29 +00:00
|
|
|
** 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
|
2015-01-28 08:44:43 +00:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
2016-01-15 12:36:27 +00:00
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2012-09-19 12:28:29 +00:00
|
|
|
**
|
2016-01-15 12:36:27 +00:00
|
|
|
** GNU General Public License Usage
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2011-04-27 10:05:43 +00:00
|
|
|
**
|
|
|
|
** $QT_END_LICENSE$
|
|
|
|
**
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifndef MAKEFILE_H
|
|
|
|
#define MAKEFILE_H
|
|
|
|
|
|
|
|
#include "option.h"
|
|
|
|
#include "project.h"
|
|
|
|
#include "makefiledeps.h"
|
|
|
|
#include <qtextstream.h>
|
|
|
|
#include <qlist.h>
|
|
|
|
#include <qhash.h>
|
|
|
|
#include <qfileinfo.h>
|
|
|
|
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
|
|
|
|
#ifdef Q_OS_WIN32
|
|
|
|
#define QT_POPEN _popen
|
2016-06-16 13:38:22 +00:00
|
|
|
#define QT_POPEN_READ "rb"
|
2011-04-27 10:05:43 +00:00
|
|
|
#define QT_PCLOSE _pclose
|
|
|
|
#else
|
|
|
|
#define QT_POPEN popen
|
2016-06-16 13:38:22 +00:00
|
|
|
#define QT_POPEN_READ "r"
|
2011-04-27 10:05:43 +00:00
|
|
|
#define QT_PCLOSE pclose
|
|
|
|
#endif
|
|
|
|
|
|
|
|
struct ReplaceExtraCompilerCacheKey;
|
|
|
|
|
|
|
|
class MakefileGenerator : protected QMakeSourceFileInfo
|
|
|
|
{
|
|
|
|
QString spec;
|
2019-05-10 09:06:46 +00:00
|
|
|
bool no_io = false;
|
2019-01-11 10:31:24 +00:00
|
|
|
bool resolveDependenciesInFrameworks = false;
|
2011-04-27 10:05:43 +00:00
|
|
|
QHash<QString, bool> init_compiler_already;
|
2013-02-28 11:40:16 +00:00
|
|
|
QString makedir, chkexists;
|
2019-07-30 12:31:50 +00:00
|
|
|
QString fullBuildArgs();
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
//internal caches
|
|
|
|
mutable QHash<QString, QMakeLocalFileName> depHeuristicsCache;
|
|
|
|
mutable QHash<QString, QStringList> dependsCache;
|
|
|
|
mutable QHash<ReplaceExtraCompilerCacheKey, QString> extraCompilerVariablesCache;
|
|
|
|
|
2014-11-20 15:20:16 +00:00
|
|
|
public:
|
|
|
|
// We can't make it visible to VCFilter in VS2008 except by making it public or directly friending it.
|
|
|
|
enum ReplaceFor { NoShell, LocalShell, TargetShell };
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
protected:
|
2013-03-06 13:53:36 +00:00
|
|
|
enum TARG_MODE { TARG_UNIX_MODE, TARG_MAC_MODE, TARG_WIN_MODE } target_mode;
|
2012-04-17 10:15:39 +00:00
|
|
|
|
2012-09-06 10:21:38 +00:00
|
|
|
ProStringList createObjectList(const ProStringList &sources);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
//makefile style generator functions
|
2012-08-20 11:04:39 +00:00
|
|
|
void writeObj(QTextStream &, const char *src);
|
2012-09-06 10:21:38 +00:00
|
|
|
void writeInstalls(QTextStream &t, bool noBuild=false);
|
2011-04-27 10:05:43 +00:00
|
|
|
void writeHeader(QTextStream &t);
|
|
|
|
void writeSubDirs(QTextStream &t);
|
2012-05-18 14:59:22 +00:00
|
|
|
void writeMakeQmake(QTextStream &t, bool noDummyQmakeAll = false);
|
2018-12-14 19:13:44 +00:00
|
|
|
void writeExportedVariables(QTextStream &t);
|
2011-04-27 10:05:43 +00:00
|
|
|
void writeExtraVariables(QTextStream &t);
|
|
|
|
void writeExtraTargets(QTextStream &t);
|
2019-01-11 10:27:19 +00:00
|
|
|
QString resolveDependency(const QDir &outDir, const QString &file);
|
2020-01-02 13:28:39 +00:00
|
|
|
void callExtraCompilerDependCommand(const ProString &extraCompiler,
|
2019-05-28 20:11:24 +00:00
|
|
|
const QString &tmp_dep_cmd, const QString &inpf,
|
2019-09-20 06:20:47 +00:00
|
|
|
const QString &tmp_out, bool dep_lines, QStringList *deps,
|
2020-01-02 12:51:19 +00:00
|
|
|
bool existingDepsOnly,
|
|
|
|
bool checkCommandAvailability = false);
|
2011-04-27 10:05:43 +00:00
|
|
|
void writeExtraCompilerTargets(QTextStream &t);
|
|
|
|
void writeExtraCompilerVariables(QTextStream &t);
|
2013-08-26 17:51:57 +00:00
|
|
|
bool writeDummyMakefile(QTextStream &t);
|
2011-04-27 10:05:43 +00:00
|
|
|
virtual bool writeMakefile(QTextStream &t);
|
2014-01-17 17:26:00 +00:00
|
|
|
virtual void writeDefaultVariables(QTextStream &t);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QString pkgConfigPrefix() const;
|
|
|
|
QString pkgConfigFileName(bool fixify=true);
|
|
|
|
QString pkgConfigFixPath(QString) const;
|
|
|
|
void writePkgConfigFile(); // for pkg-config
|
|
|
|
|
|
|
|
//generating subtarget makefiles
|
|
|
|
struct SubTarget
|
|
|
|
{
|
|
|
|
QString name;
|
|
|
|
QString in_directory, out_directory;
|
|
|
|
QString profile, target, makefile;
|
2012-09-06 10:21:38 +00:00
|
|
|
ProStringList depends;
|
2011-04-27 10:05:43 +00:00
|
|
|
};
|
|
|
|
enum SubTargetFlags {
|
|
|
|
SubTargetInstalls=0x01,
|
|
|
|
SubTargetOrdered=0x02,
|
|
|
|
SubTargetSkipDefaultVariables=0x04,
|
|
|
|
SubTargetSkipDefaultTargets=0x08,
|
|
|
|
|
|
|
|
SubTargetsNoFlags=0x00
|
|
|
|
};
|
|
|
|
QList<MakefileGenerator::SubTarget*> findSubDirsSubTargets() const;
|
2012-05-18 20:13:51 +00:00
|
|
|
void writeSubTargetCall(QTextStream &t,
|
|
|
|
const QString &in_directory, const QString &in, const QString &out_directory, const QString &out,
|
2012-04-25 15:12:53 +00:00
|
|
|
const QString &out_directory_cdin, const QString &makefilein);
|
2011-05-03 07:52:30 +00:00
|
|
|
virtual void writeSubMakeCall(QTextStream &t, const QString &outDirectory_cdin,
|
2012-04-25 15:12:53 +00:00
|
|
|
const QString &makeFileIn);
|
2014-01-17 17:26:00 +00:00
|
|
|
virtual void writeSubTargets(QTextStream &t, QList<SubTarget*> subtargets, int flags);
|
2019-02-01 09:54:30 +00:00
|
|
|
virtual ProStringList extraSubTargetDependencies() { return {}; }
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
//extra compiler interface
|
2012-09-06 10:21:38 +00:00
|
|
|
bool verifyExtraCompiler(const ProString &c, const QString &f);
|
2014-11-20 15:20:16 +00:00
|
|
|
virtual QString replaceExtraCompilerVariables(const QString &, const QStringList &, const QStringList &, ReplaceFor forShell);
|
|
|
|
inline QString replaceExtraCompilerVariables(const QString &val, const QString &in, const QString &out, ReplaceFor forShell)
|
|
|
|
{ return replaceExtraCompilerVariables(val, QStringList(in), QStringList(out), forShell); }
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
//interface to the source file info
|
2018-08-02 21:34:53 +00:00
|
|
|
QMakeLocalFileName fixPathForFile(const QMakeLocalFileName &, bool) override;
|
|
|
|
QMakeLocalFileName findFileForDep(const QMakeLocalFileName &, const QMakeLocalFileName &) override;
|
|
|
|
QFileInfo findFileInfo(const QMakeLocalFileName &) override;
|
2019-05-10 09:06:46 +00:00
|
|
|
QMakeProject *project = nullptr;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
//escape
|
2018-06-08 19:18:11 +00:00
|
|
|
virtual QString escapeFilePath(const QString &path) const = 0;
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString escapeFilePath(const ProString &path) const;
|
2011-04-27 10:05:43 +00:00
|
|
|
QStringList escapeFilePaths(const QStringList &paths) const;
|
2012-09-06 10:21:38 +00:00
|
|
|
ProStringList escapeFilePaths(const ProStringList &paths) const;
|
2018-06-08 19:18:11 +00:00
|
|
|
virtual QString escapeDependencyPath(const QString &path) const;
|
2015-02-06 14:30:02 +00:00
|
|
|
ProString escapeDependencyPath(const ProString &path) const;
|
2011-04-27 10:05:43 +00:00
|
|
|
QStringList escapeDependencyPaths(const QStringList &paths) const;
|
2012-09-06 10:21:38 +00:00
|
|
|
ProStringList escapeDependencyPaths(const ProStringList &paths) const;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2018-06-08 14:00:44 +00:00
|
|
|
QStringList finalizeDependencyPaths(const QStringList &paths) const;
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
//initialization
|
|
|
|
void verifyCompilers();
|
|
|
|
virtual void init();
|
|
|
|
void initOutPaths();
|
|
|
|
struct Compiler
|
|
|
|
{
|
|
|
|
QString variable_in;
|
|
|
|
enum CompilerFlag {
|
qmake: Allow extra compilers to have the makefile depend on its inputs
And enable this configuration option for the resource compiler. This
results in a re-run of qmake whenever you touch a qrc file, which is
needed to keep the dependencies up to date. Otherwise you might end
up in the situation where you add a file to a qrc, edit the file some
time later, but a rebuild does not regenerate a cpp file and compile
that, so the final binary is stale.
Technically this dependency problem is present for all source files,
and qrc files are no different than any cpp file that you add a new
header #include to, or adding a Q_OBJECT macro to a header. To pick
up these changes we have to re-run qmake, so that qmake can run its
internal dependency checking, and any extra compiler dependency
commands.
The reason we're making this change for rcc files it that conceptually
people treat them as a "project" files, and expect them to behave similarly
to .pro or .pri files, in that editing the file will invalidate the
makefile. In practice this is often what happens when adding new
headers, as you touch the project file when changing the HEADERS
variable.
Task-number: QTBUG-13334
Change-Id: If69149678e7fba6d812d31dcc17877427f9a6122
Reviewed-by: Simon Hausmann <simon.hausmann@nokia.com>
Reviewed-by: Kai Koehne <kai.koehne@nokia.com>
2011-11-24 15:03:19 +00:00
|
|
|
CompilerNoFlags = 0x00,
|
|
|
|
CompilerBuiltin = 0x01,
|
|
|
|
CompilerNoCheckDeps = 0x02,
|
|
|
|
CompilerRemoveNoExist = 0x04,
|
|
|
|
CompilerAddInputsAsMakefileDeps = 0x08
|
2011-04-27 10:05:43 +00:00
|
|
|
};
|
|
|
|
uint flags, type;
|
|
|
|
};
|
2015-07-22 10:03:02 +00:00
|
|
|
friend class QTypeInfo<Compiler>;
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
void initCompiler(const Compiler &comp);
|
|
|
|
enum VPATHFlag {
|
|
|
|
VPATH_NoFlag = 0x00,
|
|
|
|
VPATH_WarnMissingFiles = 0x01,
|
|
|
|
VPATH_RemoveMissingFiles = 0x02,
|
|
|
|
VPATH_NoFixify = 0x04
|
|
|
|
};
|
2012-09-06 10:21:38 +00:00
|
|
|
ProStringList findFilesInVPATH(ProStringList l, uchar flags, const QString &var="");
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
inline int findExecutable(const QStringList &cmdline)
|
|
|
|
{ int ret; canExecute(cmdline, &ret); return ret; }
|
|
|
|
bool canExecute(const QStringList &cmdline, int *argv0) const;
|
|
|
|
inline bool canExecute(const QString &cmdline) const
|
2018-08-02 22:22:24 +00:00
|
|
|
{ return canExecute(cmdline.split(' '), nullptr); }
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
bool mkdir(const QString &dir) const;
|
|
|
|
QString mkdir_p_asstring(const QString &dir, bool escape=true) const;
|
|
|
|
|
2012-06-26 13:32:17 +00:00
|
|
|
QString specdir();
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
//subclasses can use these to query information about how the generator was "run"
|
2017-01-03 18:10:14 +00:00
|
|
|
QString buildArgs(bool withExtra);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
virtual QStringList &findDependencies(const QString &file);
|
|
|
|
virtual bool doDepends() const { return Option::mkfile::do_deps; }
|
|
|
|
|
2012-08-20 11:04:39 +00:00
|
|
|
void filterIncludedFiles(const char *);
|
2015-11-11 18:21:27 +00:00
|
|
|
void processSources() {
|
2011-04-27 10:05:43 +00:00
|
|
|
filterIncludedFiles("SOURCES");
|
|
|
|
filterIncludedFiles("GENERATED_SOURCES");
|
|
|
|
}
|
|
|
|
|
|
|
|
//for installs
|
|
|
|
virtual QString defaultInstall(const QString &);
|
2016-01-14 12:01:39 +00:00
|
|
|
virtual QString installRoot() const;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
//for prl
|
|
|
|
QString prlFileName(bool fixify=true);
|
|
|
|
void writePrlFile();
|
2018-07-09 18:02:27 +00:00
|
|
|
bool processPrlFile(QString &, bool baseOnly);
|
2011-04-27 10:05:43 +00:00
|
|
|
virtual void writePrlFile(QTextStream &);
|
|
|
|
|
|
|
|
//make sure libraries are found
|
2015-08-17 17:33:52 +00:00
|
|
|
virtual bool findLibraries(bool linkPrl, bool mergeLflags);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
//for retrieving values and lists of values
|
2013-12-07 19:35:18 +00:00
|
|
|
virtual QString var(const ProKey &var) const;
|
|
|
|
QString varGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const;
|
|
|
|
QString varList(const ProKey &var) const;
|
2014-11-14 20:12:56 +00:00
|
|
|
QString fixFileVarGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const;
|
2015-02-06 14:30:02 +00:00
|
|
|
QString fileVarList(const ProKey &var) const;
|
|
|
|
QString fileVarGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const;
|
|
|
|
QString fileVar(const ProKey &var) const;
|
|
|
|
QString depVar(const ProKey &var) const;
|
2013-12-07 19:35:18 +00:00
|
|
|
QString val(const ProStringList &varList) const;
|
|
|
|
QString val(const QStringList &varList) const;
|
|
|
|
QString valGlue(const QStringList &varList, const QString &before, const QString &glue, const QString &after) const;
|
|
|
|
QString valGlue(const ProStringList &varList, const QString &before, const QString &glue, const QString &after) const;
|
|
|
|
QString valList(const QStringList &varList) const;
|
|
|
|
QString valList(const ProStringList &varList) const;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QString filePrefixRoot(const QString &, const QString &);
|
|
|
|
|
2015-09-23 12:57:05 +00:00
|
|
|
enum LibFlagType { LibFlagLib, LibFlagPath, LibFlagFile, LibFlagOther };
|
|
|
|
virtual LibFlagType parseLibFlag(const ProString &flag, ProString *arg);
|
2015-02-06 14:30:02 +00:00
|
|
|
ProStringList fixLibFlags(const ProKey &var);
|
|
|
|
virtual ProString fixLibFlag(const ProString &lib);
|
|
|
|
|
2015-04-13 19:18:36 +00:00
|
|
|
public:
|
2011-04-27 10:05:43 +00:00
|
|
|
//file fixification to unify all file names into a single pattern
|
2015-04-13 19:18:36 +00:00
|
|
|
enum FileFixifyType {
|
|
|
|
FileFixifyFromIndir = 0,
|
|
|
|
FileFixifyFromOutdir = 1,
|
|
|
|
FileFixifyToOutDir = 0,
|
|
|
|
FileFixifyToIndir = 2,
|
|
|
|
FileFixifyBackwards = FileFixifyFromOutdir | FileFixifyToIndir,
|
|
|
|
FileFixifyDefault = 0,
|
|
|
|
FileFixifyAbsolute = 4,
|
|
|
|
FileFixifyRelative = 8
|
|
|
|
};
|
|
|
|
Q_DECLARE_FLAGS(FileFixifyTypes, FileFixifyType)
|
|
|
|
protected:
|
|
|
|
QString fileFixify(const QString &file, FileFixifyTypes fix = FileFixifyDefault, bool canon = true) const;
|
|
|
|
QStringList fileFixify(const QStringList &files, FileFixifyTypes fix = FileFixifyDefault, bool canon = true) const;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2013-01-10 23:30:41 +00:00
|
|
|
QString installMetaFile(const ProKey &replace_rule, const QString &src, const QString &dst);
|
|
|
|
|
2018-06-28 15:57:53 +00:00
|
|
|
virtual bool processPrlFileBase(QString &origFile, const QStringRef &origName,
|
|
|
|
const QStringRef &fixedBase, int slashOff);
|
|
|
|
bool processPrlFileCore(QString &origFile, const QStringRef &origName,
|
|
|
|
const QString &fixedFile);
|
2019-11-04 14:54:24 +00:00
|
|
|
void createResponseFile(const QString &fileName, const ProStringList &objList);
|
2018-06-28 15:57:53 +00:00
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
public:
|
|
|
|
QMakeProject *projectFile() const;
|
|
|
|
void setProjectFile(QMakeProject *p);
|
|
|
|
|
|
|
|
void setNoIO(bool o);
|
|
|
|
bool noIO() const;
|
|
|
|
|
|
|
|
inline bool exists(QString file) const { return fileInfo(file).exists(); }
|
|
|
|
QFileInfo fileInfo(QString file) const;
|
|
|
|
|
|
|
|
static MakefileGenerator *create(QMakeProject *);
|
|
|
|
virtual bool write();
|
|
|
|
virtual bool writeProjectMakefile();
|
|
|
|
virtual bool supportsMetaBuild() { return true; }
|
|
|
|
virtual bool supportsMergedBuilds() { return false; }
|
|
|
|
virtual bool mergeBuildProject(MakefileGenerator * /*other*/) { return false; }
|
|
|
|
virtual bool openOutput(QFile &, const QString &build) const;
|
2012-05-03 18:50:19 +00:00
|
|
|
bool isWindowsShell() const { return Option::dir_sep == QLatin1String("\\"); }
|
2013-11-20 12:53:04 +00:00
|
|
|
QString shellQuote(const QString &str);
|
2019-07-31 11:53:24 +00:00
|
|
|
virtual ProKey fullTargetVariable() const;
|
2011-04-27 10:05:43 +00:00
|
|
|
};
|
2015-07-22 10:03:02 +00:00
|
|
|
Q_DECLARE_TYPEINFO(MakefileGenerator::Compiler, Q_MOVABLE_TYPE);
|
2015-04-13 19:18:36 +00:00
|
|
|
Q_DECLARE_OPERATORS_FOR_FLAGS(MakefileGenerator::FileFixifyTypes)
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
inline void MakefileGenerator::setNoIO(bool o)
|
|
|
|
{ no_io = o; }
|
|
|
|
|
|
|
|
inline bool MakefileGenerator::noIO() const
|
|
|
|
{ return no_io; }
|
|
|
|
|
|
|
|
inline QString MakefileGenerator::defaultInstall(const QString &)
|
|
|
|
{ return QString(""); }
|
|
|
|
|
2016-01-14 12:01:39 +00:00
|
|
|
inline QString MakefileGenerator::installRoot() const
|
|
|
|
{ return QStringLiteral("$(INSTALL_ROOT)"); }
|
|
|
|
|
2015-08-17 17:33:52 +00:00
|
|
|
inline bool MakefileGenerator::findLibraries(bool, bool)
|
2011-04-27 10:05:43 +00:00
|
|
|
{ return true; }
|
|
|
|
|
2014-11-20 15:20:16 +00:00
|
|
|
struct ReplaceExtraCompilerCacheKey
|
|
|
|
{
|
|
|
|
mutable uint hash;
|
|
|
|
QString var, in, out, pwd;
|
|
|
|
MakefileGenerator::ReplaceFor forShell;
|
|
|
|
ReplaceExtraCompilerCacheKey(const QString &v, const QStringList &i, const QStringList &o, MakefileGenerator::ReplaceFor s);
|
|
|
|
bool operator==(const ReplaceExtraCompilerCacheKey &f) const;
|
|
|
|
inline uint hashCode() const {
|
|
|
|
if (!hash)
|
|
|
|
hash = (uint)forShell ^ qHash(var) ^ qHash(in) ^ qHash(out) /*^ qHash(pwd)*/;
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
inline uint qHash(const ReplaceExtraCompilerCacheKey &f) { return f.hashCode(); }
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
QT_END_NAMESPACE
|
|
|
|
|
|
|
|
#endif // MAKEFILE_H
|