introduce ability to build projects for the host system
when qmake runs into the new option(host_build) command, it will restart the project evaluation with a host spec. the new default host spec is called default-host (gasp!). it is overridden with the pre-exising -spec / -platform option, while the new -xspec / -xplatform option overrides the pre-existing default spec. specifying -spec but not -xspec will set the xspec, too, so the behavior is backwards-compatible. same for the XQMAKESPEC override read from .qmake.cache and the environment variable. the cleaner solution would be adding -hostspec, to be symmetrical with the override semantics, but that would deviate from configure in turn. Change-Id: I4297c873780af16ab7928421b434ce0f1d3820da Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com>
This commit is contained in:
parent
528192a78b
commit
14bbab09c1
12
configure
vendored
12
configure
vendored
@ -3491,8 +3491,9 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ];
|
|||||||
mv -f "$QMAKE_QCONFIG_H" "$QCONFIG_H"
|
mv -f "$QMAKE_QCONFIG_H" "$QCONFIG_H"
|
||||||
|
|
||||||
#mkspecs/default is used as a (gasp!) default mkspec so QMAKESPEC needn't be set once configured
|
#mkspecs/default is used as a (gasp!) default mkspec so QMAKESPEC needn't be set once configured
|
||||||
rm -rf mkspecs/default
|
rm -rf mkspecs/default mkspecs/default-host
|
||||||
ln -s `echo $XQMAKESPEC | sed "s,^${relpath}/mkspecs/,,"` mkspecs/default
|
ln -s `echo $XQMAKESPEC | sed "s,^${relpath}/mkspecs/,,"` mkspecs/default
|
||||||
|
ln -s `echo $QMAKESPEC | sed "s,^${relpath}/mkspecs/,,"` mkspecs/default-host
|
||||||
mkdir -p "$outpath/qmake" || exit
|
mkdir -p "$outpath/qmake" || exit
|
||||||
# fix makefiles
|
# fix makefiles
|
||||||
for mkfile in GNUmakefile Makefile; do
|
for mkfile in GNUmakefile Makefile; do
|
||||||
@ -5906,9 +5907,14 @@ EOF
|
|||||||
|
|
||||||
#dump the qmake spec
|
#dump the qmake spec
|
||||||
if [ -d "$outpath/mkspecs/$XPLATFORM" ]; then
|
if [ -d "$outpath/mkspecs/$XPLATFORM" ]; then
|
||||||
echo "QMAKESPEC = \$\$QT_BUILD_TREE/mkspecs/$XPLATFORM" >> "$CACHEFILE.tmp"
|
echo "XQMAKESPEC = \$\$QT_BUILD_TREE/mkspecs/$XPLATFORM" >> "$CACHEFILE.tmp"
|
||||||
else
|
else
|
||||||
echo "QMAKESPEC = $XPLATFORM" >> "$CACHEFILE.tmp"
|
echo "XQMAKESPEC = $XPLATFORM" >> "$CACHEFILE.tmp"
|
||||||
|
fi
|
||||||
|
if [ -d "$outpath/mkspecs/$PLATFORM" ]; then
|
||||||
|
echo "QMAKESPEC = \$\$QT_BUILD_TREE/mkspecs/$PLATFORM" >> "$CACHEFILE.tmp"
|
||||||
|
else
|
||||||
|
echo "QMAKESPEC = $PLATFORM" >> "$CACHEFILE.tmp"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# replace .qmake.cache if it differs from the newly created temp file
|
# replace .qmake.cache if it differs from the newly created temp file
|
||||||
|
@ -2193,7 +2193,9 @@ QString MakefileGenerator::buildArgs(const QString &outdir)
|
|||||||
if(!Option::mkfile::do_dep_heuristics)
|
if(!Option::mkfile::do_dep_heuristics)
|
||||||
ret += " -nodependheuristics";
|
ret += " -nodependheuristics";
|
||||||
if(!Option::mkfile::qmakespec_commandline.isEmpty())
|
if(!Option::mkfile::qmakespec_commandline.isEmpty())
|
||||||
ret += " -spec " + specdir(outdir);
|
ret += " -spec " + specdir(outdir, 1);
|
||||||
|
if (!Option::mkfile::xqmakespec_commandline.isEmpty())
|
||||||
|
ret += " -xspec " + specdir(outdir, 0);
|
||||||
if (Option::target_mode_overridden) {
|
if (Option::target_mode_overridden) {
|
||||||
if (Option::target_mode == Option::TARG_MACX_MODE)
|
if (Option::target_mode == Option::TARG_MACX_MODE)
|
||||||
ret += " -macx";
|
ret += " -macx";
|
||||||
@ -3046,13 +3048,14 @@ QStringList
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
MakefileGenerator::specdir(const QString &outdir)
|
MakefileGenerator::specdir(const QString &outdir, int host_build)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
if(!spec.isEmpty())
|
if(!spec.isEmpty())
|
||||||
return spec;
|
return spec;
|
||||||
#endif
|
#endif
|
||||||
spec = fileFixify(Option::mkfile::qmakespec, outdir);
|
spec = fileFixify((host_build >= 0 ? bool(host_build) : project->isHostBuild())
|
||||||
|
? Option::mkfile::qmakespec : Option::mkfile::xqmakespec, outdir);
|
||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ protected:
|
|||||||
|
|
||||||
//subclasses can use these to query information about how the generator was "run"
|
//subclasses can use these to query information about how the generator was "run"
|
||||||
QString buildArgs(const QString &outdir=QString());
|
QString buildArgs(const QString &outdir=QString());
|
||||||
QString specdir(const QString &outdir=QString());
|
QString specdir(const QString &outdir = QString(), int host_build = -1);
|
||||||
|
|
||||||
virtual QStringList &findDependencies(const QString &file);
|
virtual QStringList &findDependencies(const QString &file);
|
||||||
virtual bool doDepends() const { return Option::mkfile::do_deps; }
|
virtual bool doDepends() const { return Option::mkfile::do_deps; }
|
||||||
|
@ -649,12 +649,15 @@ nextfile:
|
|||||||
t << _slnProjConfBeg;
|
t << _slnProjConfBeg;
|
||||||
for(QList<VcsolutionDepend*>::Iterator it = solution_cleanup.begin(); it != solution_cleanup.end(); ++it) {
|
for(QList<VcsolutionDepend*>::Iterator it = solution_cleanup.begin(); it != solution_cleanup.end(); ++it) {
|
||||||
QString platform = is64Bit ? "x64" : "Win32";
|
QString platform = is64Bit ? "x64" : "Win32";
|
||||||
|
QString xplatform = platform;
|
||||||
if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"))
|
if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"))
|
||||||
platform = project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")";
|
xplatform = project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")";
|
||||||
t << "\n\t\t" << (*it)->uuid << QString(_slnProjDbgConfTag1).arg(platform) << platform;
|
if (!project->isHostBuild())
|
||||||
t << "\n\t\t" << (*it)->uuid << QString(_slnProjDbgConfTag2).arg(platform) << platform;
|
platform = xplatform;
|
||||||
t << "\n\t\t" << (*it)->uuid << QString(_slnProjRelConfTag1).arg(platform) << platform;
|
t << "\n\t\t" << (*it)->uuid << QString(_slnProjDbgConfTag1).arg(xplatform) << platform;
|
||||||
t << "\n\t\t" << (*it)->uuid << QString(_slnProjRelConfTag2).arg(platform) << platform;
|
t << "\n\t\t" << (*it)->uuid << QString(_slnProjDbgConfTag2).arg(xplatform) << platform;
|
||||||
|
t << "\n\t\t" << (*it)->uuid << QString(_slnProjRelConfTag1).arg(xplatform) << platform;
|
||||||
|
t << "\n\t\t" << (*it)->uuid << QString(_slnProjRelConfTag2).arg(xplatform) << platform;
|
||||||
}
|
}
|
||||||
t << _slnProjConfEnd;
|
t << _slnProjConfEnd;
|
||||||
t << _slnExtSections;
|
t << _slnExtSections;
|
||||||
@ -858,7 +861,7 @@ void VcprojGenerator::initProject()
|
|||||||
}
|
}
|
||||||
|
|
||||||
vcProject.Keyword = project->first("VCPROJ_KEYWORD");
|
vcProject.Keyword = project->first("VCPROJ_KEYWORD");
|
||||||
if (project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) {
|
if (project->isHostBuild() || project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) {
|
||||||
vcProject.PlatformName = (is64Bit ? "x64" : "Win32");
|
vcProject.PlatformName = (is64Bit ? "x64" : "Win32");
|
||||||
} else {
|
} else {
|
||||||
vcProject.PlatformName = project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")";
|
vcProject.PlatformName = project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")";
|
||||||
@ -922,7 +925,7 @@ void VcprojGenerator::initConfiguration()
|
|||||||
if (conf.Name.isEmpty())
|
if (conf.Name.isEmpty())
|
||||||
conf.Name = isDebug ? "Debug" : "Release";
|
conf.Name = isDebug ? "Debug" : "Release";
|
||||||
conf.ConfigurationName = conf.Name;
|
conf.ConfigurationName = conf.Name;
|
||||||
if (project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) {
|
if (project->isHostBuild() || project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) {
|
||||||
conf.Name += (is64Bit ? "|x64" : "|Win32");
|
conf.Name += (is64Bit ? "|x64" : "|Win32");
|
||||||
} else {
|
} else {
|
||||||
conf.Name += "|" + project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")";
|
conf.Name += "|" + project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")";
|
||||||
@ -948,7 +951,7 @@ void VcprojGenerator::initConfiguration()
|
|||||||
initPreBuildEventTools();
|
initPreBuildEventTools();
|
||||||
initPostBuildEventTools();
|
initPostBuildEventTools();
|
||||||
// Only deploy for CE projects
|
// Only deploy for CE projects
|
||||||
if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"))
|
if (!project->isHostBuild() && !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"))
|
||||||
initDeploymentTool();
|
initDeploymentTool();
|
||||||
initPreLinkEventTools();
|
initPreLinkEventTools();
|
||||||
|
|
||||||
@ -1084,7 +1087,7 @@ void VcprojGenerator::initPostBuildEventTools()
|
|||||||
|
|
||||||
QString signature = !project->isEmpty("SIGNATURE_FILE") ? var("SIGNATURE_FILE") : var("DEFAULT_SIGNATURE");
|
QString signature = !project->isEmpty("SIGNATURE_FILE") ? var("SIGNATURE_FILE") : var("DEFAULT_SIGNATURE");
|
||||||
bool useSignature = !signature.isEmpty() && !project->isActiveConfig("staticlib") &&
|
bool useSignature = !signature.isEmpty() && !project->isActiveConfig("staticlib") &&
|
||||||
!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH");
|
!project->isHostBuild() && !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH");
|
||||||
if (useSignature) {
|
if (useSignature) {
|
||||||
conf.postBuild.CommandLine.prepend(
|
conf.postBuild.CommandLine.prepend(
|
||||||
QLatin1String("signtool sign /F ") + signature + QLatin1String(" \"$(TargetPath)\""));
|
QLatin1String("signtool sign /F ") + signature + QLatin1String(" \"$(TargetPath)\""));
|
||||||
@ -1578,7 +1581,8 @@ QString VcprojGenerator::findTemplate(QString file)
|
|||||||
{
|
{
|
||||||
QString ret;
|
QString ret;
|
||||||
if(!exists((ret = file)) &&
|
if(!exists((ret = file)) &&
|
||||||
!exists((ret = QString(Option::mkfile::qmakespec + "/" + file))) &&
|
!exists((ret = QString((project->isHostBuild()
|
||||||
|
? Option::mkfile::qmakespec : Option::mkfile::xqmakespec) + '/' + file))) &&
|
||||||
!exists((ret = QString(QLibraryInfo::location(QLibraryInfo::HostDataPath) + "/win32-msvc.net/" + file))) &&
|
!exists((ret = QString(QLibraryInfo::location(QLibraryInfo::HostDataPath) + "/win32-msvc.net/" + file))) &&
|
||||||
!exists((ret = QString(QLibraryInfo::location(QLibraryInfo::HostDataPath) + "/win32-msvc2002/" + file))) &&
|
!exists((ret = QString(QLibraryInfo::location(QLibraryInfo::HostDataPath) + "/win32-msvc2002/" + file))) &&
|
||||||
!exists((ret = QString(QLibraryInfo::location(QLibraryInfo::HostDataPath) + "/win32-msvc2003/" + file))) &&
|
!exists((ret = QString(QLibraryInfo::location(QLibraryInfo::HostDataPath) + "/win32-msvc2003/" + file))) &&
|
||||||
|
@ -107,6 +107,7 @@ QStringList Option::projfile::project_dirs;
|
|||||||
|
|
||||||
//QMAKE_GENERATE_MAKEFILE stuff
|
//QMAKE_GENERATE_MAKEFILE stuff
|
||||||
QString Option::mkfile::qmakespec;
|
QString Option::mkfile::qmakespec;
|
||||||
|
QString Option::mkfile::xqmakespec;
|
||||||
int Option::mkfile::cachefile_depth = -1;
|
int Option::mkfile::cachefile_depth = -1;
|
||||||
bool Option::mkfile::do_deps = true;
|
bool Option::mkfile::do_deps = true;
|
||||||
bool Option::mkfile::do_mocs = true;
|
bool Option::mkfile::do_mocs = true;
|
||||||
@ -117,6 +118,7 @@ bool Option::mkfile::do_cache = true;
|
|||||||
QString Option::mkfile::cachefile;
|
QString Option::mkfile::cachefile;
|
||||||
QStringList Option::mkfile::project_files;
|
QStringList Option::mkfile::project_files;
|
||||||
QString Option::mkfile::qmakespec_commandline;
|
QString Option::mkfile::qmakespec_commandline;
|
||||||
|
QString Option::mkfile::xqmakespec_commandline;
|
||||||
|
|
||||||
static Option::QMAKE_MODE default_mode(QString progname)
|
static Option::QMAKE_MODE default_mode(QString progname)
|
||||||
{
|
{
|
||||||
@ -327,6 +329,9 @@ Option::parseCommandLine(int argc, char **argv, int skip)
|
|||||||
} else if(opt == "platform" || opt == "spec") {
|
} else if(opt == "platform" || opt == "spec") {
|
||||||
Option::mkfile::qmakespec = cleanSpec(argv[++x]);
|
Option::mkfile::qmakespec = cleanSpec(argv[++x]);
|
||||||
Option::mkfile::qmakespec_commandline = argv[x];
|
Option::mkfile::qmakespec_commandline = argv[x];
|
||||||
|
} else if (opt == "xplatform" || opt == "xspec") {
|
||||||
|
Option::mkfile::xqmakespec = cleanSpec(argv[++x]);
|
||||||
|
Option::mkfile::xqmakespec_commandline = argv[x];
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "***Unknown option -%s\n", opt.toLatin1().constData());
|
fprintf(stderr, "***Unknown option -%s\n", opt.toLatin1().constData());
|
||||||
return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
|
return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
|
||||||
@ -381,6 +386,9 @@ Option::parseCommandLine(int argc, char **argv, int skip)
|
|||||||
if (!user_configs.isEmpty())
|
if (!user_configs.isEmpty())
|
||||||
Option::before_user_vars += "CONFIG += " + user_configs.join(" ");
|
Option::before_user_vars += "CONFIG += " + user_configs.join(" ");
|
||||||
|
|
||||||
|
if (Option::mkfile::xqmakespec.isEmpty())
|
||||||
|
Option::mkfile::xqmakespec = Option::mkfile::qmakespec;
|
||||||
|
|
||||||
return Option::QMAKE_CMDLINE_SUCCESS;
|
return Option::QMAKE_CMDLINE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,8 +544,13 @@ Option::init(int argc, char **argv)
|
|||||||
//last chance for defaults
|
//last chance for defaults
|
||||||
if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
|
if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
|
||||||
Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
|
Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
|
||||||
if(Option::mkfile::qmakespec.isNull() || Option::mkfile::qmakespec.isEmpty())
|
if (Option::mkfile::xqmakespec.isEmpty())
|
||||||
|
Option::mkfile::xqmakespec = QString::fromLocal8Bit(qgetenv("XQMAKESPEC").constData());
|
||||||
|
if (Option::mkfile::qmakespec.isEmpty()) {
|
||||||
Option::mkfile::qmakespec = QString::fromLocal8Bit(qgetenv("QMAKESPEC").constData());
|
Option::mkfile::qmakespec = QString::fromLocal8Bit(qgetenv("QMAKESPEC").constData());
|
||||||
|
if (Option::mkfile::xqmakespec.isEmpty())
|
||||||
|
Option::mkfile::xqmakespec = Option::mkfile::qmakespec;
|
||||||
|
}
|
||||||
|
|
||||||
//try REALLY hard to do it for them, lazy..
|
//try REALLY hard to do it for them, lazy..
|
||||||
if(Option::mkfile::project_files.isEmpty()) {
|
if(Option::mkfile::project_files.isEmpty()) {
|
||||||
|
@ -196,6 +196,7 @@ struct Option
|
|||||||
//QMAKE_GENERATE_MAKEFILE options
|
//QMAKE_GENERATE_MAKEFILE options
|
||||||
struct mkfile {
|
struct mkfile {
|
||||||
static QString qmakespec;
|
static QString qmakespec;
|
||||||
|
static QString xqmakespec;
|
||||||
static bool do_cache;
|
static bool do_cache;
|
||||||
static bool do_deps;
|
static bool do_deps;
|
||||||
static bool do_mocs;
|
static bool do_mocs;
|
||||||
@ -206,6 +207,7 @@ struct Option
|
|||||||
static int cachefile_depth;
|
static int cachefile_depth;
|
||||||
static QStringList project_files;
|
static QStringList project_files;
|
||||||
static QString qmakespec_commandline;
|
static QString qmakespec_commandline;
|
||||||
|
static QString xqmakespec_commandline;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -531,7 +531,7 @@ static void qmake_error_msg(const QString &msg)
|
|||||||
1) features/(unix|win32|macx)/
|
1) features/(unix|win32|macx)/
|
||||||
2) features/
|
2) features/
|
||||||
*/
|
*/
|
||||||
QStringList qmake_feature_paths(QMakeProperty *prop=0)
|
QStringList qmake_feature_paths(QMakeProperty *prop, bool host_build)
|
||||||
{
|
{
|
||||||
const QString mkspecs_concat = QLatin1String("/mkspecs");
|
const QString mkspecs_concat = QLatin1String("/mkspecs");
|
||||||
const QString base_concat = QLatin1String("/features");
|
const QString base_concat = QLatin1String("/features");
|
||||||
@ -578,12 +578,13 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0)
|
|||||||
feature_roots << ((*it) + mkspecs_concat + (*concat_it));
|
feature_roots << ((*it) + mkspecs_concat + (*concat_it));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!Option::mkfile::qmakespec.isEmpty()) {
|
QString *specp = host_build ? &Option::mkfile::qmakespec : &Option::mkfile::xqmakespec;
|
||||||
|
if (!specp->isEmpty()) {
|
||||||
// The spec is already platform-dependent, so no subdirs here.
|
// The spec is already platform-dependent, so no subdirs here.
|
||||||
feature_roots << Option::mkfile::qmakespec + base_concat;
|
feature_roots << *specp + base_concat;
|
||||||
|
|
||||||
// Also check directly under the root directory of the mkspecs collection
|
// Also check directly under the root directory of the mkspecs collection
|
||||||
QFileInfo specfi(Option::mkfile::qmakespec);
|
QFileInfo specfi(*specp);
|
||||||
QDir specrootdir(specfi.absolutePath());
|
QDir specrootdir(specfi.absolutePath());
|
||||||
while (!specrootdir.isRoot()) {
|
while (!specrootdir.isRoot()) {
|
||||||
const QString specrootpath = specrootdir.path();
|
const QString specrootpath = specrootdir.path();
|
||||||
@ -629,16 +630,7 @@ QMakeProject::~QMakeProject()
|
|||||||
{
|
{
|
||||||
if(own_prop)
|
if(own_prop)
|
||||||
delete prop;
|
delete prop;
|
||||||
for(QHash<QString, FunctionBlock*>::iterator it = replaceFunctions.begin(); it != replaceFunctions.end(); ++it) {
|
cleanup();
|
||||||
if(!it.value()->deref())
|
|
||||||
delete it.value();
|
|
||||||
}
|
|
||||||
replaceFunctions.clear();
|
|
||||||
for(QHash<QString, FunctionBlock*>::iterator it = testFunctions.begin(); it != testFunctions.end(); ++it) {
|
|
||||||
if(!it.value()->deref())
|
|
||||||
delete it.value();
|
|
||||||
}
|
|
||||||
testFunctions.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -653,14 +645,29 @@ QMakeProject::init(QMakeProperty *p)
|
|||||||
own_prop = false;
|
own_prop = false;
|
||||||
}
|
}
|
||||||
recursive = false;
|
recursive = false;
|
||||||
|
host_build = false;
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QMakeProject::cleanup()
|
||||||
|
{
|
||||||
|
for (QHash<QString, FunctionBlock*>::iterator it = replaceFunctions.begin(); it != replaceFunctions.end(); ++it)
|
||||||
|
if (!it.value()->deref())
|
||||||
|
delete it.value();
|
||||||
|
replaceFunctions.clear();
|
||||||
|
for (QHash<QString, FunctionBlock*>::iterator it = testFunctions.begin(); it != testFunctions.end(); ++it)
|
||||||
|
if (!it.value()->deref())
|
||||||
|
delete it.value();
|
||||||
|
testFunctions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Duplicate project. It is *not* allowed to call the complex read() functions on the copy.
|
// Duplicate project. It is *not* allowed to call the complex read() functions on the copy.
|
||||||
QMakeProject::QMakeProject(QMakeProject *p, const QHash<QString, QStringList> *_vars)
|
QMakeProject::QMakeProject(QMakeProject *p, const QHash<QString, QStringList> *_vars)
|
||||||
{
|
{
|
||||||
init(p->properties());
|
init(p->properties());
|
||||||
vars = _vars ? *_vars : p->variables();
|
vars = _vars ? *_vars : p->variables();
|
||||||
|
host_build = p->host_build;
|
||||||
for(QHash<QString, FunctionBlock*>::iterator it = p->replaceFunctions.begin(); it != p->replaceFunctions.end(); ++it) {
|
for(QHash<QString, FunctionBlock*>::iterator it = p->replaceFunctions.begin(); it != p->replaceFunctions.end(); ++it) {
|
||||||
it.value()->ref();
|
it.value()->ref();
|
||||||
replaceFunctions.insert(it.key(), it.value());
|
replaceFunctions.insert(it.key(), it.value());
|
||||||
@ -680,6 +687,7 @@ QMakeProject::reset()
|
|||||||
iterator = 0;
|
iterator = 0;
|
||||||
function = 0;
|
function = 0;
|
||||||
backslashWarned = false;
|
backslashWarned = false;
|
||||||
|
need_restart = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -1226,6 +1234,8 @@ QMakeProject::read(QTextStream &file, QHash<QString, QStringList> &place)
|
|||||||
}
|
}
|
||||||
s = "";
|
s = "";
|
||||||
numLines = 0;
|
numLines = 0;
|
||||||
|
if (need_restart)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1271,7 +1281,7 @@ QMakeProject::read(const QString &file, QHash<QString, QStringList> &place)
|
|||||||
if(!using_stdin)
|
if(!using_stdin)
|
||||||
qfile.close();
|
qfile.close();
|
||||||
}
|
}
|
||||||
if(scope_blocks.count() != 1) {
|
if (!need_restart && scope_blocks.count() != 1) {
|
||||||
qmake_error_msg("Unterminated conditional block at end of file");
|
qmake_error_msg("Unterminated conditional block at end of file");
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
@ -1290,6 +1300,7 @@ QMakeProject::read(const QString &project, uchar cmd)
|
|||||||
bool
|
bool
|
||||||
QMakeProject::read(uchar cmd)
|
QMakeProject::read(uchar cmd)
|
||||||
{
|
{
|
||||||
|
again:
|
||||||
if ((cmd & ReadSetup) && base_vars.isEmpty()) {
|
if ((cmd & ReadSetup) && base_vars.isEmpty()) {
|
||||||
// hack to get the Option stuff in there
|
// hack to get the Option stuff in there
|
||||||
base_vars["QMAKE_EXT_CPP"] = Option::cpp_ext;
|
base_vars["QMAKE_EXT_CPP"] = Option::cpp_ext;
|
||||||
@ -1320,8 +1331,13 @@ QMakeProject::read(uchar cmd)
|
|||||||
Option::mkfile::cachefile.clear();
|
Option::mkfile::cachefile.clear();
|
||||||
goto no_cache;
|
goto no_cache;
|
||||||
}
|
}
|
||||||
if (Option::mkfile::qmakespec.isEmpty() && !cache["QMAKESPEC"].isEmpty())
|
if (Option::mkfile::xqmakespec.isEmpty() && !cache["XQMAKESPEC"].isEmpty())
|
||||||
|
Option::mkfile::xqmakespec = cache["XQMAKESPEC"].first();
|
||||||
|
if (Option::mkfile::qmakespec.isEmpty() && !cache["QMAKESPEC"].isEmpty()) {
|
||||||
Option::mkfile::qmakespec = cache["QMAKESPEC"].first();
|
Option::mkfile::qmakespec = cache["QMAKESPEC"].first();
|
||||||
|
if (Option::mkfile::xqmakespec.isEmpty())
|
||||||
|
Option::mkfile::xqmakespec = Option::mkfile::qmakespec;
|
||||||
|
}
|
||||||
|
|
||||||
if (Option::output_dir.startsWith(project_build_root))
|
if (Option::output_dir.startsWith(project_build_root))
|
||||||
Option::mkfile::cachefile_depth =
|
Option::mkfile::cachefile_depth =
|
||||||
@ -1355,9 +1371,10 @@ QMakeProject::read(uchar cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{ // parse mkspec
|
{ // parse mkspec
|
||||||
QString qmakespec = Option::mkfile::qmakespec;
|
QString *specp = host_build ? &Option::mkfile::qmakespec : &Option::mkfile::xqmakespec;
|
||||||
|
QString qmakespec = *specp;
|
||||||
if (qmakespec.isEmpty())
|
if (qmakespec.isEmpty())
|
||||||
qmakespec = "default";
|
qmakespec = host_build ? "default-host" : "default";
|
||||||
if (QDir::isRelativePath(qmakespec)) {
|
if (QDir::isRelativePath(qmakespec)) {
|
||||||
QStringList mkspec_roots = qmake_mkspec_paths();
|
QStringList mkspec_roots = qmake_mkspec_paths();
|
||||||
debug_msg(2, "Looking for mkspec %s in (%s)", qmakespec.toLatin1().constData(),
|
debug_msg(2, "Looking for mkspec %s in (%s)", qmakespec.toLatin1().constData(),
|
||||||
@ -1367,7 +1384,7 @@ QMakeProject::read(uchar cmd)
|
|||||||
QString mkspec = (*it) + QLatin1Char('/') + qmakespec;
|
QString mkspec = (*it) + QLatin1Char('/') + qmakespec;
|
||||||
if (QFile::exists(mkspec)) {
|
if (QFile::exists(mkspec)) {
|
||||||
found_mkspec = true;
|
found_mkspec = true;
|
||||||
Option::mkfile::qmakespec = qmakespec = mkspec;
|
*specp = qmakespec = mkspec;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1441,6 +1458,11 @@ QMakeProject::read(uchar cmd)
|
|||||||
pfile += Option::pro_ext;
|
pfile += Option::pro_ext;
|
||||||
if(!read(pfile, vars))
|
if(!read(pfile, vars))
|
||||||
return false;
|
return false;
|
||||||
|
if (need_restart) {
|
||||||
|
base_vars.clear();
|
||||||
|
cleanup();
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd & ReadSetup) {
|
if (cmd & ReadSetup) {
|
||||||
@ -1537,7 +1559,7 @@ QMakeProject::resolveSpec(QString *spec, const QString &qmakespec)
|
|||||||
{
|
{
|
||||||
if (spec->isEmpty()) {
|
if (spec->isEmpty()) {
|
||||||
*spec = QFileInfo(qmakespec).fileName();
|
*spec = QFileInfo(qmakespec).fileName();
|
||||||
if (*spec == "default") {
|
if (*spec == "default" || *spec == "default-host") {
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
int l = readlink(qmakespec.toLatin1().constData(), buffer, 1023);
|
int l = readlink(qmakespec.toLatin1().constData(), buffer, 1023);
|
||||||
@ -1586,9 +1608,14 @@ QMakeProject::isActiveConfig(const QString &x, bool regex, QHash<QString, QStrin
|
|||||||
return Option::target_mode == Option::TARG_WIN_MODE;
|
return Option::target_mode == Option::TARG_WIN_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (x == "host_build")
|
||||||
|
return host_build ? "true" : "false";
|
||||||
|
|
||||||
//mkspecs
|
//mkspecs
|
||||||
static QString spec;
|
static QString hspec, xspec;
|
||||||
resolveSpec(&spec, Option::mkfile::qmakespec);
|
resolveSpec(&hspec, Option::mkfile::qmakespec);
|
||||||
|
resolveSpec(&xspec, Option::mkfile::xqmakespec);
|
||||||
|
const QString &spec = host_build ? hspec : xspec;
|
||||||
QRegExp re(x, Qt::CaseSensitive, QRegExp::Wildcard);
|
QRegExp re(x, Qt::CaseSensitive, QRegExp::Wildcard);
|
||||||
if((regex && re.exactMatch(spec)) || (!regex && spec == x))
|
if((regex && re.exactMatch(spec)) || (!regex && spec == x))
|
||||||
return true;
|
return true;
|
||||||
@ -1646,9 +1673,10 @@ QMakeProject::doProjectInclude(QString file, uchar flags, QHash<QString, QString
|
|||||||
file += Option::prf_ext;
|
file += Option::prf_ext;
|
||||||
validateModes(); // init dir_sep
|
validateModes(); // init dir_sep
|
||||||
if(file.indexOf(QLatin1Char('/')) == -1 || !QFile::exists(file)) {
|
if(file.indexOf(QLatin1Char('/')) == -1 || !QFile::exists(file)) {
|
||||||
static QStringList *feature_roots = 0;
|
static QStringList *all_feature_roots[2] = { 0, 0 };
|
||||||
|
QStringList *&feature_roots = all_feature_roots[host_build];
|
||||||
if(!feature_roots) {
|
if(!feature_roots) {
|
||||||
feature_roots = new QStringList(qmake_feature_paths(prop));
|
feature_roots = new QStringList(qmake_feature_paths(prop, host_build));
|
||||||
qmakeAddCacheClear(qmakeDeleteCacheClear<QStringList>, (void**)&feature_roots);
|
qmakeAddCacheClear(qmakeDeleteCacheClear<QStringList>, (void**)&feature_roots);
|
||||||
}
|
}
|
||||||
debug_msg(2, "Looking for feature '%s' in (%s)", file.toLatin1().constData(),
|
debug_msg(2, "Looking for feature '%s' in (%s)", file.toLatin1().constData(),
|
||||||
@ -2742,6 +2770,11 @@ QMakeProject::doProjectTest(QString func, QList<QStringList> args_list, QHash<QS
|
|||||||
}
|
}
|
||||||
if (args.first() == "recursive") {
|
if (args.first() == "recursive") {
|
||||||
recursive = true;
|
recursive = true;
|
||||||
|
} else if (args.first() == "host_build") {
|
||||||
|
if (!host_build && isActiveConfig("cross_compile")) {
|
||||||
|
host_build = true;
|
||||||
|
need_restart = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s:%d: unrecognized option() argument '%s'.\n",
|
fprintf(stderr, "%s:%d: unrecognized option() argument '%s'.\n",
|
||||||
parser.file.toLatin1().constData(), parser.line_no,
|
parser.file.toLatin1().constData(), parser.line_no,
|
||||||
|
@ -79,6 +79,8 @@ class QMakeProject
|
|||||||
QHash<QString, FunctionBlock*> testFunctions, replaceFunctions;
|
QHash<QString, FunctionBlock*> testFunctions, replaceFunctions;
|
||||||
|
|
||||||
bool recursive;
|
bool recursive;
|
||||||
|
bool host_build;
|
||||||
|
bool need_restart;
|
||||||
bool own_prop;
|
bool own_prop;
|
||||||
bool backslashWarned;
|
bool backslashWarned;
|
||||||
QString pfile;
|
QString pfile;
|
||||||
@ -107,6 +109,7 @@ class QMakeProject
|
|||||||
bool doVariableReplace(QString &str, QHash<QString, QStringList> &place);
|
bool doVariableReplace(QString &str, QHash<QString, QStringList> &place);
|
||||||
QStringList doVariableReplaceExpand(const QString &str, QHash<QString, QStringList> &place, bool *ok=0);
|
QStringList doVariableReplaceExpand(const QString &str, QHash<QString, QStringList> &place, bool *ok=0);
|
||||||
void init(QMakeProperty *);
|
void init(QMakeProperty *);
|
||||||
|
void cleanup();
|
||||||
QStringList &values(const QString &v, QHash<QString, QStringList> &place);
|
QStringList &values(const QString &v, QHash<QString, QStringList> &place);
|
||||||
void validateModes();
|
void validateModes();
|
||||||
void resolveSpec(QString *spec, const QString &qmakespec);
|
void resolveSpec(QString *spec, const QString &qmakespec);
|
||||||
@ -160,6 +163,7 @@ public:
|
|||||||
QHash<QString, QStringList> &variables(); // No compat mapping and magic, obviously
|
QHash<QString, QStringList> &variables(); // No compat mapping and magic, obviously
|
||||||
|
|
||||||
bool isRecursive() const { return recursive; }
|
bool isRecursive() const { return recursive; }
|
||||||
|
bool isHostBuild() const { return host_build; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class MakefileGenerator;
|
friend class MakefileGenerator;
|
||||||
|
18
qtbase.pro
18
qtbase.pro
@ -118,15 +118,17 @@ INSTALLS += configtests
|
|||||||
mkspecs.path = $$[QT_HOST_DATA]/mkspecs
|
mkspecs.path = $$[QT_HOST_DATA]/mkspecs
|
||||||
mkspecs.files = $$OUT_PWD/mkspecs/qconfig.pri $$OUT_PWD/mkspecs/qmodule.pri $$OUT_PWD/mkspecs/qdevice.pri $$files($$PWD/mkspecs/*)
|
mkspecs.files = $$OUT_PWD/mkspecs/qconfig.pri $$OUT_PWD/mkspecs/qmodule.pri $$OUT_PWD/mkspecs/qdevice.pri $$files($$PWD/mkspecs/*)
|
||||||
mkspecs.files -= $$PWD/mkspecs/modules
|
mkspecs.files -= $$PWD/mkspecs/modules
|
||||||
unix {
|
unix {
|
||||||
DEFAULT_QMAKESPEC = $$QMAKESPEC
|
DEFAULT_QMAKESPEC = $$replace(QMAKESPEC, ^.*mkspecs/, )
|
||||||
DEFAULT_QMAKESPEC ~= s,^.*mkspecs/,,g
|
DEFAULT_XQMAKESPEC = $$replace(XQMAKESPEC, ^.*mkspecs/, )
|
||||||
mkspecs.commands += $(DEL_FILE) $(INSTALL_ROOT)$$mkspecs.path/default; $(SYMLINK) $$DEFAULT_QMAKESPEC $(INSTALL_ROOT)$$mkspecs.path/default
|
mkspecs.commands = \
|
||||||
mkspecs.files -= $$PWD/mkspecs/default
|
$(DEL_FILE) $(INSTALL_ROOT)$$mkspecs.path/default-host $(INSTALL_ROOT)$$mkspecs.path/default; \
|
||||||
}
|
$(SYMLINK) $$DEFAULT_QMAKESPEC $(INSTALL_ROOT)$$mkspecs.path/default-host && \
|
||||||
win32:!equals(OUT_PWD, $$PWD) {
|
$(SYMLINK) $$DEFAULT_XQMAKESPEC $(INSTALL_ROOT)$$mkspecs.path/default
|
||||||
|
mkspecs.files -= $$PWD/mkspecs/default-host $$PWD/mkspecs/default
|
||||||
|
} else:!equals(OUT_PWD, $$PWD) {
|
||||||
# When shadow building on Windows, the default mkspec only exists in the build tree.
|
# When shadow building on Windows, the default mkspec only exists in the build tree.
|
||||||
mkspecs.files += $$OUT_PWD/mkspecs/default
|
mkspecs.files += $$OUT_PWD/mkspecs/default-host $$OUT_PWD/mkspecs/default
|
||||||
}
|
}
|
||||||
INSTALLS += mkspecs
|
INSTALLS += mkspecs
|
||||||
|
|
||||||
|
@ -2583,13 +2583,18 @@ void Configure::generateCachefile()
|
|||||||
moduleStream << "QMAKE_INCDIR_QT = $$QT_BUILD_TREE" << fixSeparators("/include", true) << endl;
|
moduleStream << "QMAKE_INCDIR_QT = $$QT_BUILD_TREE" << fixSeparators("/include", true) << endl;
|
||||||
moduleStream << "QMAKE_LIBDIR_QT = $$QT_BUILD_TREE" << fixSeparators("/lib", true) << endl;
|
moduleStream << "QMAKE_LIBDIR_QT = $$QT_BUILD_TREE" << fixSeparators("/lib", true) << endl;
|
||||||
|
|
||||||
|
QString hostSpec = dictionary[ "QMAKESPEC" ];
|
||||||
QString targetSpec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : dictionary[ "QMAKESPEC" ];
|
QString targetSpec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : hostSpec;
|
||||||
QString mkspec_path = fixSeparators(sourcePath + "/mkspecs/" + targetSpec);
|
QString xmkspec_path = fixSeparators(sourcePath + "/mkspecs/" + targetSpec);
|
||||||
|
if (QFile::exists(xmkspec_path))
|
||||||
|
moduleStream << "XQMAKESPEC = " << escapeSeparators(xmkspec_path) << endl;
|
||||||
|
else
|
||||||
|
moduleStream << "XQMAKESPEC = " << fixSeparators(targetSpec, true) << endl;
|
||||||
|
QString mkspec_path = fixSeparators(sourcePath + "/mkspecs/" + hostSpec);
|
||||||
if (QFile::exists(mkspec_path))
|
if (QFile::exists(mkspec_path))
|
||||||
moduleStream << "QMAKESPEC = " << escapeSeparators(mkspec_path) << endl;
|
moduleStream << "QMAKESPEC = " << escapeSeparators(mkspec_path) << endl;
|
||||||
else
|
else
|
||||||
moduleStream << "QMAKESPEC = " << fixSeparators(targetSpec, true) << endl;
|
moduleStream << "QMAKESPEC = " << fixSeparators(hostSpec, true) << endl;
|
||||||
|
|
||||||
if (dictionary["QT_EDITION"] != "QT_EDITION_OPENSOURCE")
|
if (dictionary["QT_EDITION"] != "QT_EDITION_OPENSOURCE")
|
||||||
moduleStream << "DEFINES *= QT_EDITION=QT_EDITION_DESKTOP" << endl;
|
moduleStream << "DEFINES *= QT_EDITION=QT_EDITION_DESKTOP" << endl;
|
||||||
@ -3109,7 +3114,8 @@ void Configure::generateConfigfiles()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString spec = dictionary.contains("XQMAKESPEC") ? dictionary["XQMAKESPEC"] : dictionary["QMAKESPEC"];
|
QString spec = dictionary.contains("XQMAKESPEC") ? dictionary["XQMAKESPEC"] : dictionary["QMAKESPEC"];
|
||||||
if (!copySpec("default", "", spec))
|
if (!copySpec("default", "", spec)
|
||||||
|
|| !copySpec("default-host", "host ", dictionary["QMAKESPEC"]))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Generate the new qconfig.cpp file
|
// Generate the new qconfig.cpp file
|
||||||
|
Loading…
Reference in New Issue
Block a user