2011-04-27 10:05:43 +00:00
|
|
|
/****************************************************************************
|
|
|
|
**
|
2016-01-15 12:36:27 +00:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
2016-01-21 02:33:50 +00:00
|
|
|
** Copyright (C) 2016 Intel Corporation.
|
2016-01-15 12:36:27 +00:00
|
|
|
** 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$
|
|
|
|
**
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "unixmake.h"
|
|
|
|
#include "option.h"
|
|
|
|
#include "meta.h"
|
2020-04-03 15:11:36 +00:00
|
|
|
#include <qregularexpression.h>
|
2011-04-27 10:05:43 +00:00
|
|
|
#include <qbytearray.h>
|
|
|
|
#include <qfile.h>
|
|
|
|
#include <qdir.h>
|
|
|
|
#include <qdebug.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
2021-08-17 15:11:20 +00:00
|
|
|
#include <tuple>
|
|
|
|
#include <utility>
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
|
|
|
|
void
|
|
|
|
UnixMakefileGenerator::writePrlFile(QTextStream &t)
|
|
|
|
{
|
|
|
|
MakefileGenerator::writePrlFile(t);
|
2019-06-03 12:59:16 +00:00
|
|
|
const ProString tmplt = project->first("TEMPLATE");
|
|
|
|
if (tmplt != "lib" && tmplt != "aux")
|
|
|
|
return;
|
2011-04-27 10:05:43 +00:00
|
|
|
// libtool support
|
2019-06-03 12:59:16 +00:00
|
|
|
if (project->isActiveConfig("create_libtool")) {
|
2015-08-18 16:07:57 +00:00
|
|
|
writeLibtoolFile();
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
// pkg-config support
|
2019-06-03 12:59:16 +00:00
|
|
|
if (project->isActiveConfig("create_pc"))
|
2011-04-27 10:05:43 +00:00
|
|
|
writePkgConfigFile();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
UnixMakefileGenerator::writeMakefile(QTextStream &t)
|
|
|
|
{
|
|
|
|
|
|
|
|
writeHeader(t);
|
2013-08-26 17:51:57 +00:00
|
|
|
if (writeDummyMakefile(t))
|
2011-04-27 10:05:43 +00:00
|
|
|
return true;
|
|
|
|
|
2014-11-27 13:49:16 +00:00
|
|
|
if (project->first("TEMPLATE") == "app" ||
|
|
|
|
project->first("TEMPLATE") == "lib" ||
|
|
|
|
project->first("TEMPLATE") == "aux") {
|
2011-04-27 10:05:43 +00:00
|
|
|
writeMakeParts(t);
|
|
|
|
return MakefileGenerator::writeMakefile(t);
|
2014-11-27 13:49:16 +00:00
|
|
|
} else if (project->first("TEMPLATE") == "subdirs") {
|
2011-04-27 10:05:43 +00:00
|
|
|
MakefileGenerator::writeSubDirs(t);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-01-17 17:26:00 +00:00
|
|
|
void
|
|
|
|
UnixMakefileGenerator::writeDefaultVariables(QTextStream &t)
|
|
|
|
{
|
|
|
|
MakefileGenerator::writeDefaultVariables(t);
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "TAR = " << var("QMAKE_TAR") << Qt::endl;
|
|
|
|
t << "COMPRESS = " << var("QMAKE_GZIP") << Qt::endl;
|
2014-01-17 17:26:00 +00:00
|
|
|
|
|
|
|
if (project->isEmpty("QMAKE_DISTNAME")) {
|
|
|
|
ProString distname = project->first("QMAKE_ORIG_TARGET");
|
|
|
|
if (!project->isActiveConfig("no_dist_version"))
|
|
|
|
distname += project->first("VERSION");
|
|
|
|
project->values("QMAKE_DISTNAME") = distname;
|
|
|
|
}
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "DISTNAME = " << fileVar("QMAKE_DISTNAME") << Qt::endl;
|
2014-01-17 17:26:00 +00:00
|
|
|
|
|
|
|
if (project->isEmpty("QMAKE_DISTDIR"))
|
|
|
|
project->values("QMAKE_DISTDIR") = project->first("QMAKE_DISTNAME");
|
|
|
|
t << "DISTDIR = " << escapeFilePath(fileFixify(
|
|
|
|
(project->isEmpty("OBJECTS_DIR") ? ProString(".tmp/") : project->first("OBJECTS_DIR")) + project->first("QMAKE_DISTDIR"),
|
2019-04-30 10:51:36 +00:00
|
|
|
FileFixifyFromOutdir | FileFixifyAbsolute)) << Qt::endl;
|
2014-01-17 17:26:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
UnixMakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubTarget*> targets, int flags)
|
|
|
|
{
|
|
|
|
MakefileGenerator::writeSubTargets(t, targets, flags);
|
|
|
|
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "dist: distdir FORCE" << Qt::endl;
|
2014-01-17 17:26:00 +00:00
|
|
|
t << "\t(cd `dirname $(DISTDIR)` && $(TAR) $(DISTNAME).tar $(DISTNAME) && $(COMPRESS) $(DISTNAME).tar)"
|
|
|
|
" && $(MOVE) `dirname $(DISTDIR)`/$(DISTNAME).tar.gz . && $(DEL_FILE) -r $(DISTDIR)";
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2014-01-17 17:26:00 +00:00
|
|
|
|
|
|
|
t << "distdir:";
|
|
|
|
for (int target = 0; target < targets.size(); ++target) {
|
|
|
|
SubTarget *subtarget = targets.at(target);
|
|
|
|
t << " " << subtarget->target << "-distdir";
|
|
|
|
}
|
|
|
|
t << " FORCE\n\t"
|
|
|
|
<< mkdir_p_asstring("$(DISTDIR)", false) << "\n\t"
|
2019-04-30 10:51:36 +00:00
|
|
|
<< "$(COPY_FILE) --parents " << fileVar("DISTFILES") << " $(DISTDIR)" << Option::dir_sep << Qt::endl << Qt::endl;
|
2014-01-17 17:26:00 +00:00
|
|
|
|
|
|
|
const QString abs_source_path = project->first("QMAKE_ABSOLUTE_SOURCE_PATH").toQString();
|
|
|
|
for (int target = 0; target < targets.size(); ++target) {
|
|
|
|
SubTarget *subtarget = targets.at(target);
|
|
|
|
QString in_directory = subtarget->in_directory;
|
|
|
|
if (!in_directory.isEmpty() && !in_directory.endsWith(Option::dir_sep))
|
|
|
|
in_directory += Option::dir_sep;
|
|
|
|
QString out_directory = subtarget->out_directory;
|
|
|
|
if (!out_directory.isEmpty() && !out_directory.endsWith(Option::dir_sep))
|
|
|
|
out_directory += Option::dir_sep;
|
|
|
|
if (!abs_source_path.isEmpty() && out_directory.startsWith(abs_source_path))
|
|
|
|
out_directory = Option::output_dir + out_directory.mid(abs_source_path.length());
|
|
|
|
|
|
|
|
QString dist_directory = out_directory;
|
|
|
|
if (dist_directory.endsWith(Option::dir_sep))
|
|
|
|
dist_directory.chop(Option::dir_sep.length());
|
|
|
|
if (!dist_directory.startsWith(Option::dir_sep))
|
|
|
|
dist_directory.prepend(Option::dir_sep);
|
|
|
|
|
2020-04-03 09:49:27 +00:00
|
|
|
QString out_directory_cdin = out_directory.isEmpty() ? QString("\n\t")
|
2015-02-06 14:30:02 +00:00
|
|
|
: "\n\tcd " + escapeFilePath(out_directory) + " && ";
|
|
|
|
QString makefilein = " -e -f " + escapeFilePath(subtarget->makefile)
|
|
|
|
+ " distdir DISTDIR=$(DISTDIR)" + escapeFilePath(dist_directory);
|
2014-01-17 17:26:00 +00:00
|
|
|
|
|
|
|
QString out = subtarget->makefile;
|
|
|
|
QString in = escapeFilePath(fileFixify(in_directory + subtarget->profile, FileFixifyAbsolute));
|
|
|
|
if (out.startsWith(in_directory))
|
|
|
|
out.remove(0, in_directory.length());
|
|
|
|
|
|
|
|
t << subtarget->target << "-distdir: FORCE";
|
2015-02-06 14:30:02 +00:00
|
|
|
writeSubTargetCall(t, in_directory, in, out_directory, escapeFilePath(out),
|
2014-01-17 17:26:00 +00:00
|
|
|
out_directory_cdin, makefilein);
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl;
|
2014-01-17 17:26:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-05 07:45:42 +00:00
|
|
|
static QString rfc1034Identifier(const QString &str)
|
|
|
|
{
|
|
|
|
QString s = str;
|
|
|
|
for (QChar &ch : s) {
|
|
|
|
const char c = ch.toLatin1();
|
|
|
|
|
|
|
|
const bool okChar = (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z')
|
|
|
|
|| (c >= 'a' && c <= 'z') || c == '-' || c == '.';
|
|
|
|
if (!okChar)
|
|
|
|
ch = QChar::fromLatin1('-');
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2019-05-09 08:42:03 +00:00
|
|
|
static QString escapeDir(const QString &dir)
|
|
|
|
{
|
|
|
|
// When building on non-MSys MinGW, the path ends with a backslash, which
|
|
|
|
// GNU make will interpret that as a line continuation. Doubling the backslash
|
|
|
|
// avoids the problem, at the cost of the variable containing *both* backslashes.
|
|
|
|
if (dir.endsWith('\\'))
|
|
|
|
return dir + '\\';
|
|
|
|
return dir;
|
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
void
|
|
|
|
UnixMakefileGenerator::writeMakeParts(QTextStream &t)
|
|
|
|
{
|
|
|
|
bool do_incremental = (project->isActiveConfig("incremental") &&
|
|
|
|
!project->values("QMAKE_INCREMENTAL").isEmpty() &&
|
|
|
|
(!project->values("QMAKE_APP_FLAG").isEmpty() ||
|
|
|
|
(!project->isActiveConfig("staticlib")))),
|
|
|
|
src_incremental=false;
|
|
|
|
|
2013-07-11 13:43:32 +00:00
|
|
|
ProStringList &bundledFiles = project->values("QMAKE_BUNDLED_FILES");
|
|
|
|
|
2018-12-14 19:13:44 +00:00
|
|
|
writeExportedVariables(t);
|
|
|
|
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "####### Compiler, tools and options\n\n";
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "CC = " << var("QMAKE_CC") << Qt::endl;
|
|
|
|
t << "CXX = " << var("QMAKE_CXX") << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
t << "DEFINES = "
|
|
|
|
<< varGlue("PRL_EXPORT_DEFINES","-D"," -D"," ")
|
2019-04-30 10:51:36 +00:00
|
|
|
<< varGlue("DEFINES","-D"," -D","") << Qt::endl;
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "CFLAGS = " << var("QMAKE_CFLAGS") << " $(DEFINES)\n";
|
|
|
|
t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " $(DEFINES)\n";
|
2015-01-09 12:42:57 +00:00
|
|
|
t << "INCPATH =";
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
2012-09-06 10:21:38 +00:00
|
|
|
const ProStringList &incs = project->values("INCLUDEPATH");
|
2011-04-27 10:05:43 +00:00
|
|
|
for(int i = 0; i < incs.size(); ++i) {
|
2015-02-06 14:30:02 +00:00
|
|
|
const ProString &inc = incs.at(i);
|
2013-12-09 18:56:31 +00:00
|
|
|
if (inc.isEmpty())
|
|
|
|
continue;
|
|
|
|
|
2020-06-03 10:06:01 +00:00
|
|
|
t << " -I" << escapeFilePath(inc);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!project->isEmpty("QMAKE_FRAMEWORKPATH_FLAGS"))
|
|
|
|
t << " " << var("QMAKE_FRAMEWORKPATH_FLAGS");
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-05-24 22:41:44 +00:00
|
|
|
writeDefaultVariables(t);
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isActiveConfig("staticlib")) {
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "LINK = " << var("QMAKE_LINK") << Qt::endl;
|
|
|
|
t << "LFLAGS = " << var("QMAKE_LFLAGS") << Qt::endl;
|
2018-10-08 16:24:14 +00:00
|
|
|
t << "LIBS = $(SUBLIBS) " << fixLibFlags("LIBS").join(' ') << ' '
|
|
|
|
<< fixLibFlags("LIBS_PRIVATE").join(' ') << ' '
|
|
|
|
<< fixLibFlags("QMAKE_LIBS").join(' ') << ' '
|
2019-04-30 10:51:36 +00:00
|
|
|
<< fixLibFlags("QMAKE_LIBS_PRIVATE").join(' ') << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "AR = " << var("QMAKE_AR") << Qt::endl;
|
|
|
|
t << "RANLIB = " << var("QMAKE_RANLIB") << Qt::endl;
|
|
|
|
t << "SED = " << var("QMAKE_STREAM_EDITOR") << Qt::endl;
|
|
|
|
t << "STRIP = " << var("QMAKE_STRIP") << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "####### Output directory\n\n";
|
2015-02-06 14:30:02 +00:00
|
|
|
// This is used in commands by some .prf files.
|
2011-04-27 10:05:43 +00:00
|
|
|
if (! project->values("OBJECTS_DIR").isEmpty())
|
2019-06-14 09:56:56 +00:00
|
|
|
t << "OBJECTS_DIR = " << escapeDir(fileVar("OBJECTS_DIR")) << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
else
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "OBJECTS_DIR = ./\n";
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
/* files */
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "####### Files\n\n";
|
2015-02-06 14:30:02 +00:00
|
|
|
// This is used by the dist target.
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "SOURCES = " << fileVarList("SOURCES") << ' ' << fileVarList("GENERATED_SOURCES") << Qt::endl;
|
2019-11-04 14:54:24 +00:00
|
|
|
auto objectParts = writeObjectsPart(t, do_incremental);
|
|
|
|
src_incremental = objectParts.first;
|
2011-04-27 10:05:43 +00:00
|
|
|
if(do_incremental && !src_incremental)
|
|
|
|
do_incremental = false;
|
2013-12-19 14:12:00 +00:00
|
|
|
t << "DIST = " << valList(fileFixify(project->values("DISTFILES").toQStringList())) << " "
|
2019-04-30 10:51:36 +00:00
|
|
|
<< fileVarList("HEADERS") << ' ' << fileVarList("SOURCES") << Qt::endl;
|
|
|
|
t << "QMAKE_TARGET = " << fileVar("QMAKE_ORIG_TARGET") << Qt::endl;
|
2019-06-14 09:56:56 +00:00
|
|
|
t << "DESTDIR = " << escapeDir(fileVar("DESTDIR")) << Qt::endl;
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "TARGET = " << fileVar("TARGET") << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
if(project->isActiveConfig("plugin")) {
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "TARGETD = " << fileVar("TARGET") << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
} else if(!project->isActiveConfig("staticlib") && project->values("QMAKE_APP_FLAG").isEmpty()) {
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "TARGETA = " << fileVar("TARGETA") << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_BUNDLE")) {
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "TARGETD = " << fileVar("TARGET_x.y") << Qt::endl;
|
|
|
|
t << "TARGET0 = " << fileVar("TARGET_") << Qt::endl;
|
2014-04-23 14:26:26 +00:00
|
|
|
} else if (!project->isActiveConfig("unversioned_libname")) {
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "TARGET0 = " << fileVar("TARGET_") << Qt::endl;
|
2014-04-23 14:26:26 +00:00
|
|
|
if (project->isEmpty("QMAKE_HPUX_SHLIB")) {
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "TARGETD = " << fileVar("TARGET_x.y.z") << Qt::endl;
|
|
|
|
t << "TARGET1 = " << fileVar("TARGET_x") << Qt::endl;
|
|
|
|
t << "TARGET2 = " << fileVar("TARGET_x.y") << Qt::endl;
|
2014-04-23 14:26:26 +00:00
|
|
|
} else {
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "TARGETD = " << fileVar("TARGET_x") << Qt::endl;
|
2014-04-23 14:26:26 +00:00
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
writeExtraCompilerVariables(t);
|
|
|
|
writeExtraVariables(t);
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
// blasted includes
|
2012-09-06 10:21:38 +00:00
|
|
|
const ProStringList &qeui = project->values("QMAKE_EXTRA_INCLUDES");
|
|
|
|
ProStringList::ConstIterator it;
|
2011-04-27 10:05:43 +00:00
|
|
|
for(it = qeui.begin(); it != qeui.end(); ++it)
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "include " << escapeDependencyPath(*it) << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
/* rules */
|
2015-06-16 15:14:53 +00:00
|
|
|
t << "first:" << (!project->isActiveConfig("no_default_goal_deps") ? " all" : "") << "\n";
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
if(include_deps) {
|
2011-10-24 11:37:30 +00:00
|
|
|
if (project->isActiveConfig("gcc_MD_depends")) {
|
2012-09-06 10:21:38 +00:00
|
|
|
ProStringList objects = project->values("OBJECTS");
|
|
|
|
for (ProStringList::Iterator it = objects.begin(); it != objects.end(); ++it) {
|
2020-04-03 15:11:36 +00:00
|
|
|
QString d_file = (*it).toQString().replace(QRegularExpression(Option::obj_ext + "$"), ".d");
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "-include " << escapeDependencyPath(d_file) << Qt::endl;
|
2012-09-06 10:21:38 +00:00
|
|
|
project->values("QMAKE_DISTCLEAN") << d_file;
|
2011-10-24 11:37:30 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
QString cmd=var("QMAKE_CFLAGS_DEPS") + " ";
|
|
|
|
cmd += varGlue("DEFINES","-D"," -D","") + varGlue("PRL_EXPORT_DEFINES"," -D"," -D","");
|
|
|
|
if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH"))
|
2015-02-06 14:30:02 +00:00
|
|
|
cmd += " -I" + fileVar("QMAKE_ABSOLUTE_SOURCE_PATH") + ' ';
|
|
|
|
cmd += " $(INCPATH) " + fileVarGlue("DEPENDPATH", "-I", " -I", "");
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString odir;
|
2011-10-24 11:37:30 +00:00
|
|
|
if(!project->values("OBJECTS_DIR").isEmpty())
|
|
|
|
odir = project->first("OBJECTS_DIR");
|
2015-02-06 14:30:02 +00:00
|
|
|
QString odird = escapeDependencyPath(odir.toQString());
|
2011-10-11 18:27:22 +00:00
|
|
|
|
2011-10-24 11:37:30 +00:00
|
|
|
QString pwd = escapeFilePath(fileFixify(qmake_getpwd()));
|
2011-10-11 18:27:22 +00:00
|
|
|
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "###### Dependencies\n\n";
|
2015-02-06 14:30:02 +00:00
|
|
|
t << odird << ".deps/%.d: " << pwd << "/%.cpp\n\t";
|
2011-10-24 11:37:30 +00:00
|
|
|
if(project->isActiveConfig("echo_depend_creation"))
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "@echo Creating depend for $<\n\t";
|
2013-11-18 15:12:13 +00:00
|
|
|
t << mkdir_p_asstring("$(@D)", false) << "\n\t"
|
2013-07-04 09:25:16 +00:00
|
|
|
<< "@$(CXX) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@\n\n";
|
2011-10-24 11:37:30 +00:00
|
|
|
|
2015-02-06 14:30:02 +00:00
|
|
|
t << odird << ".deps/%.d: " << pwd << "/%.c\n\t";
|
2011-10-24 11:37:30 +00:00
|
|
|
if(project->isActiveConfig("echo_depend_creation"))
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "@echo Creating depend for $<\n\t";
|
2013-11-18 15:12:13 +00:00
|
|
|
t << mkdir_p_asstring("$(@D)", false) << "\n\t"
|
2013-07-04 09:25:16 +00:00
|
|
|
<< "@$(CC) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@\n\n";
|
2011-10-24 11:37:30 +00:00
|
|
|
|
2018-08-02 22:22:24 +00:00
|
|
|
static const char * const src[] = { "SOURCES", "GENERATED_SOURCES", nullptr };
|
2012-08-20 11:04:39 +00:00
|
|
|
for (int x = 0; src[x]; x++) {
|
2012-09-06 10:21:38 +00:00
|
|
|
const ProStringList &l = project->values(src[x]);
|
|
|
|
for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
|
2011-10-24 11:37:30 +00:00
|
|
|
if(!(*it).isEmpty()) {
|
|
|
|
QString d_file;
|
|
|
|
for(QStringList::Iterator cit = Option::c_ext.begin();
|
|
|
|
cit != Option::c_ext.end(); ++cit) {
|
|
|
|
if((*it).endsWith((*cit))) {
|
2012-09-06 10:21:38 +00:00
|
|
|
d_file = (*it).left((*it).length() - (*cit).length()).toQString();
|
2011-04-27 10:05:43 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-10-24 11:37:30 +00:00
|
|
|
if(d_file.isEmpty()) {
|
|
|
|
for(QStringList::Iterator cppit = Option::cpp_ext.begin();
|
|
|
|
cppit != Option::cpp_ext.end(); ++cppit) {
|
|
|
|
if((*it).endsWith((*cppit))) {
|
2012-09-06 10:21:38 +00:00
|
|
|
d_file = (*it).left((*it).length() - (*cppit).length()).toQString();
|
2011-10-24 11:37:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-10-11 18:27:22 +00:00
|
|
|
|
2011-10-24 11:37:30 +00:00
|
|
|
if(!d_file.isEmpty()) {
|
2015-04-13 19:18:36 +00:00
|
|
|
d_file = odir + ".deps/" + fileFixify(d_file, FileFixifyBackwards) + ".d";
|
2015-02-06 14:30:02 +00:00
|
|
|
QString d_file_d = escapeDependencyPath(d_file);
|
2020-04-03 15:11:36 +00:00
|
|
|
QStringList deps = findDependencies((*it).toQString()).filter(QRegularExpression(
|
2011-10-24 11:37:30 +00:00
|
|
|
"((^|/)" + Option::h_moc_mod + "|" + Option::cpp_moc_ext + "$)"));
|
|
|
|
if(!deps.isEmpty())
|
2019-04-30 10:51:36 +00:00
|
|
|
t << d_file_d << ": " << finalizeDependencyPaths(deps).join(' ') << Qt::endl;
|
|
|
|
t << "-include " << d_file_d << Qt::endl;
|
2011-10-24 11:37:30 +00:00
|
|
|
project->values("QMAKE_DISTCLEAN") += d_file;
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "####### Build rules\n\n";
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->values("SUBLIBS").isEmpty()) {
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString libdir = "tmp/";
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("SUBLIBS_DIR"))
|
|
|
|
libdir = project->first("SUBLIBS_DIR");
|
|
|
|
t << "SUBLIBS = ";
|
2012-09-06 10:21:38 +00:00
|
|
|
const ProStringList &l = project->values("SUBLIBS");
|
|
|
|
for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it)
|
2015-02-06 14:30:02 +00:00
|
|
|
t << escapeFilePath(libdir + project->first("QMAKE_PREFIX_STATICLIB") + (*it) + '.'
|
|
|
|
+ project->first("QMAKE_EXTENSION_STATICLIB")) << ' ';
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2015-02-06 14:30:02 +00:00
|
|
|
QString target_deps;
|
2013-03-11 17:00:34 +00:00
|
|
|
if ((project->isActiveConfig("depend_prl") || project->isActiveConfig("fast_depend_prl"))
|
|
|
|
&& !project->isEmpty("QMAKE_PRL_INTERNAL_FILES")) {
|
2012-09-06 10:21:38 +00:00
|
|
|
const ProStringList &l = project->values("QMAKE_PRL_INTERNAL_FILES");
|
|
|
|
ProStringList::ConstIterator it;
|
2011-04-27 10:05:43 +00:00
|
|
|
for(it = l.begin(); it != l.end(); ++it) {
|
2019-04-04 14:47:29 +00:00
|
|
|
QMakeMetaInfo libinfo;
|
2012-09-06 10:21:38 +00:00
|
|
|
if (libinfo.readLib((*it).toQString()) && !libinfo.isEmpty("QMAKE_PRL_BUILD_DIR")) {
|
|
|
|
ProString dir;
|
2011-04-27 10:05:43 +00:00
|
|
|
int slsh = (*it).lastIndexOf(Option::dir_sep);
|
|
|
|
if(slsh != -1)
|
|
|
|
dir = (*it).left(slsh + 1);
|
|
|
|
QString targ = dir + libinfo.first("QMAKE_PRL_TARGET");
|
2015-02-06 14:30:02 +00:00
|
|
|
QString targ_d = escapeDependencyPath(targ);
|
|
|
|
target_deps += ' ' + targ_d;
|
|
|
|
t << targ_d;
|
2013-03-11 17:00:34 +00:00
|
|
|
if (project->isActiveConfig("fast_depend_prl"))
|
|
|
|
t << ":\n\t@echo \"Creating '";
|
|
|
|
else
|
|
|
|
t << ": FORCE\n\t@echo \"Creating/updating '";
|
2013-07-04 09:25:16 +00:00
|
|
|
t << targ << "'\"\n\t"
|
2015-02-06 14:30:02 +00:00
|
|
|
<< "(cd " << escapeFilePath(libinfo.first("QMAKE_PRL_BUILD_DIR")) << ';'
|
2013-07-04 09:25:16 +00:00
|
|
|
<< "$(MAKE))\n";
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-02-06 14:30:02 +00:00
|
|
|
QString deps = escapeDependencyPath(fileFixify(Option::output.fileName()));
|
2014-09-25 15:54:16 +00:00
|
|
|
QString allDeps;
|
2012-08-15 17:41:22 +00:00
|
|
|
if (!project->values("QMAKE_APP_FLAG").isEmpty() || project->first("TEMPLATE") == "aux") {
|
2012-09-06 10:21:38 +00:00
|
|
|
QString destdir = project->first("DESTDIR").toQString();
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_BUNDLE")) {
|
2012-09-06 10:21:38 +00:00
|
|
|
QString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION").toQString();
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!bundle_loc.isEmpty() && !bundle_loc.startsWith("/"))
|
|
|
|
bundle_loc.prepend("/");
|
|
|
|
if(!bundle_loc.endsWith("/"))
|
|
|
|
bundle_loc += "/";
|
|
|
|
destdir += project->first("QMAKE_BUNDLE") + bundle_loc;
|
|
|
|
}
|
|
|
|
if(do_incremental) {
|
|
|
|
//incremental target
|
|
|
|
QString incr_target = var("TARGET") + "_incremental";
|
|
|
|
if(incr_target.indexOf(Option::dir_sep) != -1)
|
|
|
|
incr_target = incr_target.right(incr_target.length() -
|
|
|
|
(incr_target.lastIndexOf(Option::dir_sep) + 1));
|
|
|
|
QString incr_deps, incr_objs;
|
|
|
|
if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") {
|
|
|
|
QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext;
|
2015-02-06 14:30:02 +00:00
|
|
|
QString incr_target_dir_d = escapeDependencyPath(incr_target_dir);
|
|
|
|
QString incr_target_dir_f = escapeFilePath(incr_target_dir);
|
2011-04-27 10:05:43 +00:00
|
|
|
//actual target
|
2015-02-06 14:30:02 +00:00
|
|
|
t << incr_target_dir_d << ": $(OBJECTS)\n\t"
|
|
|
|
<< "ld -r -o " << incr_target_dir_f << " $(OBJECTS)\n";
|
2011-04-27 10:05:43 +00:00
|
|
|
//communicated below
|
2015-02-06 14:30:02 +00:00
|
|
|
deps.prepend(incr_target_dir_d + ' ');
|
2011-04-27 10:05:43 +00:00
|
|
|
incr_deps = "$(INCREMENTAL_OBJECTS)";
|
|
|
|
if(!incr_objs.isEmpty())
|
|
|
|
incr_objs += " ";
|
2015-02-06 14:30:02 +00:00
|
|
|
incr_objs += incr_target_dir_f;
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
|
|
|
//actual target
|
|
|
|
QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." +
|
2014-11-27 13:49:16 +00:00
|
|
|
project->first("QMAKE_EXTENSION_SHLIB");
|
2015-02-06 14:30:02 +00:00
|
|
|
QString incr_target_dir_d = escapeDependencyPath(incr_target_dir);
|
|
|
|
QString incr_target_dir_f = escapeFilePath(incr_target_dir);
|
2011-04-27 10:05:43 +00:00
|
|
|
QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " ";
|
|
|
|
if(project->isActiveConfig("debug"))
|
|
|
|
incr_lflags += var("QMAKE_LFLAGS_DEBUG");
|
2013-11-18 20:39:08 +00:00
|
|
|
else if (project->isActiveConfig("debug_info"))
|
|
|
|
incr_lflags += var("QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO");
|
2011-04-27 10:05:43 +00:00
|
|
|
else
|
|
|
|
incr_lflags += var("QMAKE_LFLAGS_RELEASE");
|
2015-02-06 14:30:02 +00:00
|
|
|
t << incr_target_dir_d << ": $(INCREMENTAL_OBJECTS)\n\t";
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!destdir.isEmpty())
|
|
|
|
t << "\n\t" << mkdir_p_asstring(destdir) << "\n\t";
|
2015-02-06 14:30:02 +00:00
|
|
|
t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir_f <<
|
2013-07-04 09:25:16 +00:00
|
|
|
" $(INCREMENTAL_OBJECTS)\n";
|
2011-04-27 10:05:43 +00:00
|
|
|
//communicated below
|
|
|
|
if(!destdir.isEmpty()) {
|
|
|
|
if(!incr_objs.isEmpty())
|
|
|
|
incr_objs += " ";
|
2015-02-06 14:30:02 +00:00
|
|
|
incr_objs += "-L" + escapeFilePath(destdir);
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
|
|
|
if(!incr_objs.isEmpty())
|
|
|
|
incr_objs += " ";
|
2015-02-06 14:30:02 +00:00
|
|
|
incr_objs += "-L" + escapeFilePath(qmake_getpwd());
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
if(!incr_objs.isEmpty())
|
|
|
|
incr_objs += " ";
|
2015-02-06 14:30:02 +00:00
|
|
|
incr_objs += " -l" + escapeFilePath(incr_target);
|
|
|
|
deps.prepend(incr_target_dir_d + ' ');
|
2011-04-27 10:05:43 +00:00
|
|
|
incr_deps = "$(OBJECTS)";
|
|
|
|
}
|
|
|
|
|
|
|
|
//real target
|
2015-02-06 14:30:02 +00:00
|
|
|
t << var("TARGET") << ": " << depVar("PRE_TARGETDEPS") << ' ' << incr_deps << ' ' << target_deps
|
|
|
|
<< ' ' << depVar("POST_TARGETDEPS") << "\n\t";
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!destdir.isEmpty())
|
|
|
|
t << "\n\t" << mkdir_p_asstring(destdir) << "\n\t";
|
|
|
|
if(!project->isEmpty("QMAKE_PRE_LINK"))
|
|
|
|
t << var("QMAKE_PRE_LINK") << "\n\t";
|
2013-01-30 14:58:00 +00:00
|
|
|
t << "$(LINK) $(LFLAGS) " << var("QMAKE_LINK_O_FLAG") << "$(TARGET) " << incr_deps << " " << incr_objs << " $(OBJCOMP) $(LIBS)";
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_POST_LINK"))
|
|
|
|
t << "\n\t" << var("QMAKE_POST_LINK");
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
2018-07-10 19:04:48 +00:00
|
|
|
t << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) "
|
2015-02-06 14:30:02 +00:00
|
|
|
<< target_deps << ' ' << depVar("POST_TARGETDEPS") << "\n\t";
|
2012-08-15 17:41:22 +00:00
|
|
|
if (project->first("TEMPLATE") != "aux") {
|
|
|
|
if (!destdir.isEmpty())
|
|
|
|
t << mkdir_p_asstring(destdir) << "\n\t";
|
|
|
|
if (!project->isEmpty("QMAKE_PRE_LINK"))
|
|
|
|
t << var("QMAKE_PRE_LINK") << "\n\t";
|
2019-11-04 14:54:24 +00:00
|
|
|
t << "$(LINK) $(LFLAGS) " << var("QMAKE_LINK_O_FLAG") << "$(TARGET) "
|
|
|
|
<< objectParts.second << " $(OBJCOMP) $(LIBS)";
|
2012-08-15 17:41:22 +00:00
|
|
|
if (!project->isEmpty("QMAKE_POST_LINK"))
|
|
|
|
t << "\n\t" << var("QMAKE_POST_LINK");
|
|
|
|
}
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2018-07-10 19:04:48 +00:00
|
|
|
allDeps = ' ' + depVar("TARGET");
|
2011-04-27 10:05:43 +00:00
|
|
|
} else if(!project->isActiveConfig("staticlib")) {
|
2015-02-06 14:30:02 +00:00
|
|
|
QString destdir_r = project->first("DESTDIR").toQString(), incr_deps;
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_BUNDLE")) {
|
2012-09-06 10:21:38 +00:00
|
|
|
QString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION").toQString();
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!bundle_loc.isEmpty() && !bundle_loc.startsWith("/"))
|
|
|
|
bundle_loc.prepend("/");
|
|
|
|
if(!bundle_loc.endsWith("/"))
|
|
|
|
bundle_loc += "/";
|
2015-02-06 14:30:02 +00:00
|
|
|
destdir_r += project->first("QMAKE_BUNDLE") + bundle_loc;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2015-02-06 14:30:02 +00:00
|
|
|
QString destdir_d = escapeDependencyPath(destdir_r);
|
|
|
|
QString destdir = escapeFilePath(destdir_r);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
if(do_incremental) {
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString s_ext = project->first("QMAKE_EXTENSION_SHLIB");
|
2011-04-27 10:05:43 +00:00
|
|
|
QString incr_target = var("QMAKE_ORIG_TARGET").replace(
|
2020-04-03 15:11:36 +00:00
|
|
|
QRegularExpression("\\." + s_ext), "").replace(QRegularExpression("^lib"), "") + "_incremental";
|
2011-04-27 10:05:43 +00:00
|
|
|
if(incr_target.indexOf(Option::dir_sep) != -1)
|
|
|
|
incr_target = incr_target.right(incr_target.length() -
|
|
|
|
(incr_target.lastIndexOf(Option::dir_sep) + 1));
|
|
|
|
|
|
|
|
if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") {
|
2015-02-06 14:30:02 +00:00
|
|
|
QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext;
|
|
|
|
QString incr_target_dir_d = escapeDependencyPath(incr_target_dir);
|
|
|
|
QString incr_target_dir_f = escapeFilePath(incr_target_dir);
|
2011-04-27 10:05:43 +00:00
|
|
|
//actual target
|
|
|
|
const QString link_deps = "$(OBJECTS) ";
|
2015-02-06 14:30:02 +00:00
|
|
|
t << incr_target_dir_d << ": " << link_deps << "\n\t"
|
2019-04-30 10:51:36 +00:00
|
|
|
<< "ld -r -o " << incr_target_dir_f << ' ' << link_deps << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
//communicated below
|
2012-09-06 10:21:38 +00:00
|
|
|
ProStringList &cmd = project->values("QMAKE_LINK_SHLIB_CMD");
|
2016-02-04 14:12:03 +00:00
|
|
|
cmd[0] = cmd.at(0).toQString().replace(QLatin1String("$(OBJECTS) "), QLatin1String("$(INCREMENTAL_OBJECTS)")); //ick
|
2015-02-06 14:30:02 +00:00
|
|
|
cmd.append(incr_target_dir_f);
|
|
|
|
deps.prepend(incr_target_dir_d + ' ');
|
2011-04-27 10:05:43 +00:00
|
|
|
incr_deps = "$(INCREMENTAL_OBJECTS)";
|
|
|
|
} else {
|
|
|
|
//actual target
|
2015-02-06 14:30:02 +00:00
|
|
|
QString incr_target_dir = destdir_r + "lib" + incr_target + '.' + s_ext;
|
|
|
|
QString incr_target_dir_d = escapeDependencyPath(incr_target_dir);
|
|
|
|
QString incr_target_dir_f = escapeFilePath(incr_target_dir);
|
2011-04-27 10:05:43 +00:00
|
|
|
QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " ";
|
|
|
|
if(!project->isEmpty("QMAKE_LFLAGS_INCREMENTAL"))
|
|
|
|
incr_lflags += var("QMAKE_LFLAGS_INCREMENTAL") + " ";
|
|
|
|
if(project->isActiveConfig("debug"))
|
|
|
|
incr_lflags += var("QMAKE_LFLAGS_DEBUG");
|
2013-11-18 20:39:08 +00:00
|
|
|
else if (project->isActiveConfig("debug_info"))
|
|
|
|
incr_lflags += var("QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO");
|
2011-04-27 10:05:43 +00:00
|
|
|
else
|
|
|
|
incr_lflags += var("QMAKE_LFLAGS_RELEASE");
|
2015-02-06 14:30:02 +00:00
|
|
|
t << incr_target_dir_d << ": $(INCREMENTAL_OBJECTS)\n\t";
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!destdir.isEmpty())
|
2013-11-20 17:16:54 +00:00
|
|
|
t << mkdir_p_asstring(destdir, false) << "\n\t";
|
2015-02-06 14:30:02 +00:00
|
|
|
t << "$(LINK) " << incr_lflags << ' ' << var("QMAKE_LINK_O_FLAG") << incr_target_dir_f <<
|
2013-07-04 09:25:16 +00:00
|
|
|
" $(INCREMENTAL_OBJECTS)\n";
|
2011-04-27 10:05:43 +00:00
|
|
|
//communicated below
|
2012-09-06 10:21:38 +00:00
|
|
|
ProStringList &cmd = project->values("QMAKE_LINK_SHLIB_CMD");
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!destdir.isEmpty())
|
|
|
|
cmd.append(" -L" + destdir);
|
2015-02-06 14:30:02 +00:00
|
|
|
cmd.append(" -l" + escapeFilePath(incr_target));
|
|
|
|
deps.prepend(incr_target_dir_d + ' ');
|
2011-04-27 10:05:43 +00:00
|
|
|
incr_deps = "$(OBJECTS)";
|
|
|
|
}
|
|
|
|
|
|
|
|
//real target
|
2018-07-10 19:04:48 +00:00
|
|
|
t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS") << ' '
|
2015-02-06 14:30:02 +00:00
|
|
|
<< incr_deps << " $(SUBLIBS) " << target_deps << ' ' << depVar("POST_TARGETDEPS");
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
2020-01-15 11:56:15 +00:00
|
|
|
ProStringList &cmd = project->values("QMAKE_LINK_SHLIB_CMD");
|
|
|
|
cmd[0] = cmd.at(0).toQString().replace(QLatin1String("$(OBJECTS)"), objectParts.second);
|
2018-07-10 19:04:48 +00:00
|
|
|
t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS")
|
2011-04-27 10:05:43 +00:00
|
|
|
<< " $(OBJECTS) $(SUBLIBS) $(OBJCOMP) " << target_deps
|
2015-02-06 14:30:02 +00:00
|
|
|
<< ' ' << depVar("POST_TARGETDEPS");
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2018-07-10 19:04:48 +00:00
|
|
|
allDeps = ' ' + destdir_d + depVar("TARGET");
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!destdir.isEmpty())
|
2013-11-20 17:16:54 +00:00
|
|
|
t << "\n\t" << mkdir_p_asstring(destdir, false);
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_PRE_LINK"))
|
|
|
|
t << "\n\t" << var("QMAKE_PRE_LINK");
|
|
|
|
|
2015-08-18 16:07:57 +00:00
|
|
|
if (project->isActiveConfig("plugin")) {
|
2011-04-27 10:05:43 +00:00
|
|
|
t << "\n\t"
|
2013-07-04 09:25:16 +00:00
|
|
|
<< "-$(DEL_FILE) $(TARGET)\n\t"
|
2011-04-27 10:05:43 +00:00
|
|
|
<< var("QMAKE_LINK_SHLIB_CMD");
|
|
|
|
if(!destdir.isEmpty())
|
|
|
|
t << "\n\t"
|
2018-07-03 13:10:57 +00:00
|
|
|
<< "-$(MOVE) $(TARGET) " << destdir << "$(TARGET)";
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_POST_LINK"))
|
|
|
|
t << "\n\t" << var("QMAKE_POST_LINK");
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
} else if(!project->isEmpty("QMAKE_BUNDLE")) {
|
2018-07-10 19:04:48 +00:00
|
|
|
bundledFiles << destdir_r + var("TARGET");
|
2011-04-27 10:05:43 +00:00
|
|
|
t << "\n\t"
|
2013-07-04 09:25:16 +00:00
|
|
|
<< "-$(DEL_FILE) $(TARGET) $(TARGET0) $(DESTDIR)$(TARGET0)\n\t"
|
2011-04-27 10:05:43 +00:00
|
|
|
<< var("QMAKE_LINK_SHLIB_CMD") << "\n\t"
|
|
|
|
<< mkdir_p_asstring("\"`dirname $(DESTDIR)$(TARGETD)`\"", false) << "\n\t"
|
2013-07-04 09:25:16 +00:00
|
|
|
<< "-$(MOVE) $(TARGET) $(DESTDIR)$(TARGETD)\n\t"
|
2016-02-16 06:29:01 +00:00
|
|
|
<< mkdir_p_asstring("\"`dirname $(DESTDIR)$(TARGET0)`\"", false) << "\n\t";
|
|
|
|
if (!project->isActiveConfig("shallow_bundle"))
|
|
|
|
t << varGlue("QMAKE_LN_SHLIB", "-", " ",
|
|
|
|
" Versions/Current/$(TARGET) $(DESTDIR)$(TARGET0)") << "\n\t";
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_POST_LINK"))
|
|
|
|
t << "\n\t" << var("QMAKE_POST_LINK");
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
} else if(project->isEmpty("QMAKE_HPUX_SHLIB")) {
|
2014-04-23 14:26:26 +00:00
|
|
|
t << "\n\t";
|
|
|
|
|
|
|
|
if (!project->isActiveConfig("unversioned_libname"))
|
|
|
|
t << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)";
|
|
|
|
else
|
|
|
|
t << "-$(DEL_FILE) $(TARGET)";
|
|
|
|
|
|
|
|
t << "\n\t" << var("QMAKE_LINK_SHLIB_CMD");
|
|
|
|
|
|
|
|
if (!project->isActiveConfig("unversioned_libname")) {
|
|
|
|
t << "\n\t"
|
|
|
|
<< varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)") << "\n\t"
|
|
|
|
<< varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t"
|
|
|
|
<< varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)");
|
|
|
|
}
|
|
|
|
if (!destdir.isEmpty()) {
|
2011-04-27 10:05:43 +00:00
|
|
|
t << "\n\t"
|
|
|
|
<< "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t"
|
2018-07-03 13:10:57 +00:00
|
|
|
<< "-$(MOVE) $(TARGET) " << destdir << "$(TARGET)";
|
2014-04-23 14:26:26 +00:00
|
|
|
|
|
|
|
if (!project->isActiveConfig("unversioned_libname")) {
|
|
|
|
t << "\n\t"
|
|
|
|
<< "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t"
|
|
|
|
<< "-$(DEL_FILE) " << destdir << "$(TARGET1)\n\t"
|
|
|
|
<< "-$(DEL_FILE) " << destdir << "$(TARGET2)\n\t"
|
2018-07-03 13:10:57 +00:00
|
|
|
<< "-$(MOVE) $(TARGET0) " << destdir << "$(TARGET0)\n\t"
|
|
|
|
<< "-$(MOVE) $(TARGET1) " << destdir << "$(TARGET1)\n\t"
|
|
|
|
<< "-$(MOVE) $(TARGET2) " << destdir << "$(TARGET2)";
|
2014-04-23 14:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_POST_LINK"))
|
|
|
|
t << "\n\t" << var("QMAKE_POST_LINK");
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
|
|
|
t << "\n\t"
|
2013-07-04 09:25:16 +00:00
|
|
|
<< "-$(DEL_FILE) $(TARGET) $(TARGET0)\n\t"
|
2011-04-27 10:05:43 +00:00
|
|
|
<< var("QMAKE_LINK_SHLIB_CMD") << "\n\t";
|
|
|
|
t << varGlue("QMAKE_LN_SHLIB",""," "," $(TARGET) $(TARGET0)");
|
|
|
|
if(!destdir.isEmpty())
|
|
|
|
t << "\n\t"
|
|
|
|
<< "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t"
|
|
|
|
<< "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t"
|
2018-07-03 13:10:57 +00:00
|
|
|
<< "-$(MOVE) $(TARGET) " << destdir << "$(TARGET)\n\t"
|
|
|
|
<< "-$(MOVE) $(TARGET0) " << destdir << "$(TARGET0)\n\t";
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_POST_LINK"))
|
|
|
|
t << "\n\t" << var("QMAKE_POST_LINK");
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
if (! project->isActiveConfig("plugin")) {
|
2018-07-10 19:04:48 +00:00
|
|
|
t << "staticlib: " << depVar("TARGETA") << "\n\n";
|
|
|
|
t << depVar("TARGETA") << ": " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) $(OBJCOMP)";
|
2011-04-27 10:05:43 +00:00
|
|
|
if(do_incremental)
|
|
|
|
t << " $(INCREMENTAL_OBJECTS)";
|
2017-01-17 21:55:07 +00:00
|
|
|
t << ' ' << depVar("POST_TARGETDEPS") << "\n\t";
|
|
|
|
if (!project->isEmpty("QMAKE_PRE_LINK"))
|
|
|
|
t << var("QMAKE_PRE_LINK") << "\n\t";
|
|
|
|
t << "-$(DEL_FILE) $(TARGETA) \n\t"
|
2011-04-27 10:05:43 +00:00
|
|
|
<< var("QMAKE_AR_CMD");
|
|
|
|
if(do_incremental)
|
|
|
|
t << " $(INCREMENTAL_OBJECTS)";
|
2017-01-17 21:55:07 +00:00
|
|
|
if (!project->isEmpty("QMAKE_POST_LINK"))
|
|
|
|
t << "\n\t" << var("QMAKE_POST_LINK");
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_RANLIB"))
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "\n\t$(RANLIB) $(TARGETA)";
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
} else {
|
2015-02-06 14:30:02 +00:00
|
|
|
QString destdir_r = project->first("DESTDIR").toQString();
|
|
|
|
QString destdir_d = escapeDependencyPath(destdir_r);
|
|
|
|
QString destdir = escapeFilePath(destdir_r);
|
2018-10-08 15:07:59 +00:00
|
|
|
allDeps = ' ' + destdir_d + depVar("TARGET");
|
|
|
|
t << "staticlib: " << destdir_d << "$(TARGET)\n\n"
|
|
|
|
<< destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS")
|
|
|
|
<< " $(OBJECTS) $(OBJCOMP) " << depVar("POST_TARGETDEPS") << "\n\t";
|
|
|
|
if (!destdir.isEmpty())
|
|
|
|
t << mkdir_p_asstring(destdir, false) << "\n\t";
|
|
|
|
if (!project->isEmpty("QMAKE_PRE_LINK"))
|
|
|
|
t << var("QMAKE_PRE_LINK") << "\n\t";
|
|
|
|
t << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t"
|
|
|
|
<< var("QMAKE_AR_CMD") << "\n";
|
|
|
|
if (!project->isEmpty("QMAKE_POST_LINK"))
|
|
|
|
t << "\t" << var("QMAKE_POST_LINK") << "\n";
|
|
|
|
if (!project->isEmpty("QMAKE_RANLIB"))
|
|
|
|
t << "\t$(RANLIB) " << destdir << "$(TARGET)\n";
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
writeMakeQmake(t);
|
|
|
|
if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isActiveConfig("no_autoqmake")) {
|
2012-12-21 19:48:14 +00:00
|
|
|
QStringList meta_files;
|
2015-08-18 16:07:57 +00:00
|
|
|
if (project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib") { //libtool
|
2011-04-27 10:05:43 +00:00
|
|
|
meta_files += libtoolFileName();
|
|
|
|
}
|
|
|
|
if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib") { //pkg-config
|
|
|
|
meta_files += pkgConfigFileName();
|
|
|
|
}
|
|
|
|
if(!meta_files.isEmpty())
|
2013-07-04 09:25:16 +00:00
|
|
|
t << escapeDependencyPaths(meta_files).join(" ") << ": \n\t"
|
2019-04-30 10:51:36 +00:00
|
|
|
<< "@$(QMAKE) -prl " << escapeFilePath(project->projectFile()) << ' ' << buildArgs(true) << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
2014-09-25 14:46:15 +00:00
|
|
|
if (!project->isEmpty("QMAKE_BUNDLE")) {
|
2014-09-25 15:14:40 +00:00
|
|
|
QHash<QString, QString> symlinks;
|
2014-09-25 17:10:19 +00:00
|
|
|
ProStringList &alldeps = project->values("ALL_DEPS");
|
2014-09-25 14:48:44 +00:00
|
|
|
QString bundle_dir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/";
|
2014-09-25 14:46:15 +00:00
|
|
|
if (!project->first("QMAKE_PKGINFO").isEmpty()) {
|
2015-02-06 14:30:02 +00:00
|
|
|
ProString pkginfo = project->first("QMAKE_PKGINFO");
|
|
|
|
ProString pkginfo_f = escapeFilePath(pkginfo);
|
|
|
|
ProString pkginfo_d = escapeDependencyPath(pkginfo);
|
2014-09-25 17:06:21 +00:00
|
|
|
bundledFiles << pkginfo;
|
2014-09-25 17:10:19 +00:00
|
|
|
alldeps << pkginfo;
|
2014-09-25 14:48:44 +00:00
|
|
|
QString destdir = bundle_dir + "Contents";
|
2015-02-06 14:30:02 +00:00
|
|
|
t << pkginfo_d << ": \n\t";
|
2014-09-25 14:46:15 +00:00
|
|
|
if (!destdir.isEmpty())
|
|
|
|
t << mkdir_p_asstring(destdir) << "\n\t";
|
2015-02-06 14:30:02 +00:00
|
|
|
t << "@$(DEL_FILE) " << pkginfo_f << "\n\t"
|
2014-09-25 14:46:15 +00:00
|
|
|
<< "@echo \"APPL"
|
|
|
|
<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO")
|
|
|
|
? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4))
|
2019-04-30 10:51:36 +00:00
|
|
|
<< "\" > " << pkginfo_f << Qt::endl;
|
2014-09-25 14:46:15 +00:00
|
|
|
}
|
|
|
|
if (!project->first("QMAKE_BUNDLE_RESOURCE_FILE").isEmpty()) {
|
2015-02-06 14:30:02 +00:00
|
|
|
ProString resources = project->first("QMAKE_BUNDLE_RESOURCE_FILE");
|
|
|
|
ProString resources_f = escapeFilePath(resources);
|
|
|
|
ProString resources_d = escapeDependencyPath(resources);
|
2014-09-25 14:46:15 +00:00
|
|
|
bundledFiles << resources;
|
2014-09-25 17:10:19 +00:00
|
|
|
alldeps << resources;
|
2014-09-25 14:48:44 +00:00
|
|
|
QString destdir = bundle_dir + "Contents/Resources";
|
2015-02-06 14:30:02 +00:00
|
|
|
t << resources_d << ": \n\t";
|
2011-04-27 10:05:43 +00:00
|
|
|
t << mkdir_p_asstring(destdir) << "\n\t";
|
2015-02-06 14:30:02 +00:00
|
|
|
t << "@touch " << resources_f << "\n\t\n";
|
2014-09-25 14:46:15 +00:00
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
//copy the plist
|
2014-09-25 17:10:19 +00:00
|
|
|
while (!project->isActiveConfig("no_plist")) { // 'while' just to be able to 'break'
|
2015-03-11 00:02:54 +00:00
|
|
|
QString info_plist = project->first("QMAKE_INFO_PLIST").toQString();
|
|
|
|
if (info_plist.isEmpty()) {
|
|
|
|
info_plist = escapeFilePath(specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"));
|
2015-03-31 08:03:31 +00:00
|
|
|
} else if (!exists(Option::normalizePath(info_plist))) {
|
2014-09-25 17:10:19 +00:00
|
|
|
warn_msg(WarnLogic, "Could not resolve Info.plist: '%s'. Check if QMAKE_INFO_PLIST points to a valid file.",
|
|
|
|
info_plist.toLatin1().constData());
|
|
|
|
break;
|
2015-03-11 00:02:54 +00:00
|
|
|
} else {
|
|
|
|
info_plist = escapeFilePath(fileFixify(info_plist));
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2016-08-18 10:16:15 +00:00
|
|
|
bool isFramework = project->first("TEMPLATE") == "lib"
|
|
|
|
&& !project->isActiveConfig("plugin")
|
|
|
|
&& project->isActiveConfig("lib_bundle");
|
2016-02-16 06:29:01 +00:00
|
|
|
bool isShallowBundle = project->isActiveConfig("shallow_bundle");
|
2015-05-12 12:01:14 +00:00
|
|
|
QString info_plist_out = bundle_dir +
|
2016-02-16 06:29:01 +00:00
|
|
|
(!isShallowBundle
|
|
|
|
? (isFramework
|
|
|
|
? ("Versions/" + project->first("QMAKE_FRAMEWORK_VERSION") + "/Resources/")
|
2020-04-03 09:49:27 +00:00
|
|
|
: QString("Contents/"))
|
2016-02-16 06:29:01 +00:00
|
|
|
: QString())
|
|
|
|
+ "Info.plist";
|
2013-10-30 15:20:35 +00:00
|
|
|
bundledFiles << info_plist_out;
|
2014-09-25 17:10:19 +00:00
|
|
|
alldeps << info_plist_out;
|
2013-10-30 15:20:35 +00:00
|
|
|
QString destdir = info_plist_out.section(Option::dir_sep, 0, -2);
|
2015-02-06 14:30:02 +00:00
|
|
|
t << escapeDependencyPath(info_plist_out) << ": \n\t";
|
|
|
|
info_plist_out = escapeFilePath(info_plist_out);
|
2013-10-30 15:20:35 +00:00
|
|
|
if (!destdir.isEmpty())
|
2015-08-17 13:34:18 +00:00
|
|
|
t << mkdir_p_asstring(destdir) << "\n\t";
|
2013-10-30 15:20:35 +00:00
|
|
|
ProStringList commonSedArgs;
|
2014-09-22 09:24:13 +00:00
|
|
|
if (!project->values("VERSION").isEmpty()) {
|
2017-11-21 07:49:34 +00:00
|
|
|
const ProString shortVersion =
|
|
|
|
project->first("VER_MAJ") + "." +
|
|
|
|
project->first("VER_MIN");
|
|
|
|
commonSedArgs << "-e \"s,@SHORT_VERSION@," << shortVersion << ",g\" ";
|
|
|
|
commonSedArgs << "-e \"s,\\$${QMAKE_SHORT_VERSION}," << shortVersion << ",g\" ";
|
|
|
|
const ProString fullVersion =
|
|
|
|
project->first("VER_MAJ") + "." +
|
|
|
|
project->first("VER_MIN") + "." +
|
|
|
|
project->first("VER_PAT");
|
|
|
|
commonSedArgs << "-e \"s,@FULL_VERSION@," << fullVersion << ",g\" ";
|
|
|
|
commonSedArgs << "-e \"s,\\$${QMAKE_FULL_VERSION}," << fullVersion << ",g\" ";
|
2014-09-22 09:24:13 +00:00
|
|
|
}
|
2017-11-21 07:49:34 +00:00
|
|
|
const ProString typeInfo = project->isEmpty("QMAKE_PKGINFO_TYPEINFO")
|
|
|
|
? QString::fromLatin1("????")
|
|
|
|
: project->first("QMAKE_PKGINFO_TYPEINFO").left(4);
|
|
|
|
commonSedArgs << "-e \"s,@TYPEINFO@," << typeInfo << ",g\" ";
|
|
|
|
commonSedArgs << "-e \"s,\\$${QMAKE_PKGINFO_TYPEINFO}," << typeInfo << ",g\" ";
|
2014-10-14 13:05:23 +00:00
|
|
|
|
|
|
|
QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString();
|
|
|
|
if (bundlePrefix.isEmpty())
|
|
|
|
bundlePrefix = "com.yourcompany";
|
|
|
|
if (bundlePrefix.endsWith("."))
|
|
|
|
bundlePrefix.chop(1);
|
|
|
|
QString bundleIdentifier = bundlePrefix + "." + var("QMAKE_BUNDLE");
|
|
|
|
if (bundleIdentifier.endsWith(".app"))
|
|
|
|
bundleIdentifier.chop(4);
|
|
|
|
if (bundleIdentifier.endsWith(".framework"))
|
|
|
|
bundleIdentifier.chop(10);
|
2015-08-10 09:41:54 +00:00
|
|
|
// replace invalid bundle id characters
|
2018-01-05 07:45:42 +00:00
|
|
|
bundleIdentifier = rfc1034Identifier(bundleIdentifier);
|
2014-10-14 13:05:23 +00:00
|
|
|
commonSedArgs << "-e \"s,@BUNDLEIDENTIFIER@," << bundleIdentifier << ",g\" ";
|
2017-11-21 07:49:34 +00:00
|
|
|
commonSedArgs << "-e \"s,\\$${PRODUCT_BUNDLE_IDENTIFIER}," << bundleIdentifier << ",g\" ";
|
|
|
|
|
|
|
|
commonSedArgs << "-e \"s,\\$${MACOSX_DEPLOYMENT_TARGET},"
|
|
|
|
<< project->first("QMAKE_MACOSX_DEPLOYMENT_TARGET").toQString() << ",g\" ";
|
|
|
|
commonSedArgs << "-e \"s,\\$${IPHONEOS_DEPLOYMENT_TARGET},"
|
|
|
|
<< project->first("QMAKE_IPHONEOS_DEPLOYMENT_TARGET").toQString() << ",g\" ";
|
|
|
|
commonSedArgs << "-e \"s,\\$${TVOS_DEPLOYMENT_TARGET},"
|
|
|
|
<< project->first("QMAKE_TVOS_DEPLOYMENT_TARGET").toQString() << ",g\" ";
|
|
|
|
commonSedArgs << "-e \"s,\\$${WATCHOS_DEPLOYMENT_TARGET},"
|
|
|
|
<< project->first("QMAKE_WATCHOS_DEPLOYMENT_TARGET").toQString() << ",g\" ";
|
2014-10-14 13:05:23 +00:00
|
|
|
|
2019-04-16 06:32:33 +00:00
|
|
|
QString launchScreen = var("QMAKE_IOS_LAUNCH_SCREEN");
|
|
|
|
if (launchScreen.isEmpty())
|
|
|
|
launchScreen = QLatin1String("LaunchScreen");
|
|
|
|
else
|
|
|
|
launchScreen = QFileInfo(launchScreen).baseName();
|
|
|
|
commonSedArgs << "-e \"s,\\$${IOS_LAUNCH_SCREEN}," << launchScreen << ",g\" ";
|
|
|
|
|
2015-05-12 12:01:14 +00:00
|
|
|
if (!isFramework) {
|
2016-02-18 09:01:38 +00:00
|
|
|
ProString app_bundle_name = var("QMAKE_APPLICATION_BUNDLE_NAME");
|
|
|
|
if (app_bundle_name.isEmpty())
|
|
|
|
app_bundle_name = var("QMAKE_ORIG_TARGET");
|
|
|
|
|
|
|
|
ProString plugin_bundle_name = var("QMAKE_PLUGIN_BUNDLE_NAME");
|
|
|
|
if (plugin_bundle_name.isEmpty())
|
|
|
|
plugin_bundle_name = var("QMAKE_ORIG_TARGET");
|
|
|
|
|
2013-10-30 15:20:35 +00:00
|
|
|
QString icon = fileFixify(var("ICON"));
|
|
|
|
t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
|
|
|
|
<< "@sed ";
|
2016-01-26 13:38:54 +00:00
|
|
|
for (const ProString &arg : qAsConst(commonSedArgs))
|
2013-10-30 15:20:35 +00:00
|
|
|
t << arg;
|
2017-11-21 07:49:34 +00:00
|
|
|
const QString iconName = icon.section(Option::dir_sep, -1);
|
|
|
|
t << "-e \"s,@ICON@," << iconName << ",g\" "
|
|
|
|
<< "-e \"s,\\$${ASSETCATALOG_COMPILER_APPICON_NAME}," << iconName << ",g\" "
|
2016-02-18 09:01:38 +00:00
|
|
|
<< "-e \"s,@EXECUTABLE@," << app_bundle_name << ",g\" "
|
|
|
|
<< "-e \"s,@LIBRARY@," << plugin_bundle_name << ",g\" "
|
2017-11-21 07:49:34 +00:00
|
|
|
<< "-e \"s,\\$${EXECUTABLE_NAME}," << (app_bundle_name.isEmpty() ? app_bundle_name : plugin_bundle_name) << ",g\" "
|
|
|
|
<< "-e \"s,@TYPEINFO@,"<< typeInfo << ",g\" "
|
|
|
|
<< "-e \"s,\\$${QMAKE_PKGINFO_TYPEINFO},"<< typeInfo << ",g\" "
|
2019-04-30 10:51:36 +00:00
|
|
|
<< "" << info_plist << " >" << info_plist_out << Qt::endl;
|
2013-10-30 15:20:35 +00:00
|
|
|
//copy the icon
|
|
|
|
if (!project->isEmpty("ICON")) {
|
|
|
|
QString dir = bundle_dir + "Contents/Resources/";
|
2015-02-06 14:30:02 +00:00
|
|
|
const QString icon_path = dir + icon.section(Option::dir_sep, -1);
|
|
|
|
QString icon_path_f = escapeFilePath(icon_path);
|
2013-10-30 15:20:35 +00:00
|
|
|
bundledFiles << icon_path;
|
2014-09-25 17:10:19 +00:00
|
|
|
alldeps << icon_path;
|
2015-02-06 14:30:02 +00:00
|
|
|
t << escapeDependencyPath(icon_path) << ": " << escapeDependencyPath(icon) << "\n\t"
|
2013-10-30 15:20:35 +00:00
|
|
|
<< mkdir_p_asstring(dir) << "\n\t"
|
2015-02-06 14:30:02 +00:00
|
|
|
<< "@$(DEL_FILE) " << icon_path_f << "\n\t"
|
2019-04-30 10:51:36 +00:00
|
|
|
<< "@$(COPY_FILE) " << escapeFilePath(icon) << ' ' << icon_path_f << Qt::endl;
|
2013-10-30 15:20:35 +00:00
|
|
|
}
|
|
|
|
} else {
|
2016-02-18 09:01:38 +00:00
|
|
|
ProString lib_bundle_name = var("QMAKE_FRAMEWORK_BUNDLE_NAME");
|
|
|
|
if (lib_bundle_name.isEmpty())
|
|
|
|
lib_bundle_name = var("QMAKE_ORIG_TARGET");
|
|
|
|
|
2016-02-16 06:29:01 +00:00
|
|
|
if (!isShallowBundle)
|
|
|
|
symlinks[bundle_dir + "Resources"] = "Versions/Current/Resources";
|
2013-10-30 15:20:35 +00:00
|
|
|
t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
|
|
|
|
<< "@sed ";
|
2016-01-26 13:38:54 +00:00
|
|
|
for (const ProString &arg : qAsConst(commonSedArgs))
|
2013-10-30 15:20:35 +00:00
|
|
|
t << arg;
|
2016-02-18 09:01:38 +00:00
|
|
|
t << "-e \"s,@LIBRARY@," << lib_bundle_name << ",g\" "
|
2017-11-21 07:49:34 +00:00
|
|
|
<< "-e \"s,\\$${EXECUTABLE_NAME}," << lib_bundle_name << ",g\" "
|
|
|
|
<< "-e \"s,@TYPEINFO@," << typeInfo << ",g\" "
|
|
|
|
<< "-e \"s,\\$${QMAKE_PKGINFO_TYPEINFO}," << typeInfo << ",g\" "
|
2019-04-30 10:51:36 +00:00
|
|
|
<< "" << info_plist << " >" << info_plist_out << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2014-09-25 17:10:19 +00:00
|
|
|
break;
|
2013-10-30 15:20:35 +00:00
|
|
|
} // project->isActiveConfig("no_plist")
|
2011-04-27 10:05:43 +00:00
|
|
|
//copy other data
|
|
|
|
if(!project->isEmpty("QMAKE_BUNDLE_DATA")) {
|
2012-09-06 10:21:38 +00:00
|
|
|
const ProStringList &bundle_data = project->values("QMAKE_BUNDLE_DATA");
|
2011-04-27 10:05:43 +00:00
|
|
|
for(int i = 0; i < bundle_data.count(); i++) {
|
2012-09-06 10:21:38 +00:00
|
|
|
const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files"));
|
2011-04-27 10:05:43 +00:00
|
|
|
QString path = bundle_dir;
|
2012-09-06 10:21:38 +00:00
|
|
|
const ProKey pkey(bundle_data[i] + ".path");
|
2016-02-16 06:29:01 +00:00
|
|
|
if (!project->isActiveConfig("shallow_bundle")) {
|
|
|
|
const ProKey vkey(bundle_data[i] + ".version");
|
|
|
|
if (!project->isEmpty(vkey)) {
|
|
|
|
QString version = project->first(vkey) + "/" +
|
|
|
|
project->first("QMAKE_FRAMEWORK_VERSION") + "/";
|
|
|
|
ProString name = project->first(pkey);
|
|
|
|
int pos = name.indexOf('/');
|
|
|
|
if (pos > 0)
|
|
|
|
name = name.mid(0, pos);
|
|
|
|
symlinks[Option::fixPathToTargetOS(path + name)] =
|
|
|
|
project->first(vkey) + "/Current/" + name;
|
|
|
|
path += version;
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2012-09-06 10:21:38 +00:00
|
|
|
path += project->first(pkey).toQString();
|
2014-11-24 15:02:38 +00:00
|
|
|
path = Option::fixPathToTargetOS(path);
|
2011-04-27 10:05:43 +00:00
|
|
|
for(int file = 0; file < files.count(); file++) {
|
2012-09-06 10:21:38 +00:00
|
|
|
QString fn = files.at(file).toQString();
|
|
|
|
QString src = fileFixify(fn, FileFixifyAbsolute);
|
2011-04-27 10:05:43 +00:00
|
|
|
if (!QFile::exists(src))
|
2018-04-12 13:20:15 +00:00
|
|
|
src = fileFixify(fn, FileFixifyFromOutdir);
|
|
|
|
else
|
|
|
|
src = fileFixify(fn);
|
2015-02-06 14:30:02 +00:00
|
|
|
QString dst = path + Option::dir_sep + fileInfo(fn).fileName();
|
2013-07-11 13:43:32 +00:00
|
|
|
bundledFiles << dst;
|
2014-09-25 17:10:19 +00:00
|
|
|
alldeps << dst;
|
2015-02-06 14:30:02 +00:00
|
|
|
t << escapeDependencyPath(dst) << ": " << escapeDependencyPath(src) << "\n\t"
|
2011-04-27 10:05:43 +00:00
|
|
|
<< mkdir_p_asstring(path) << "\n\t";
|
2015-02-06 14:30:02 +00:00
|
|
|
src = escapeFilePath(src);
|
|
|
|
dst = escapeFilePath(dst);
|
2012-09-06 10:21:38 +00:00
|
|
|
QFileInfo fi(fileInfo(fn));
|
2011-04-27 10:05:43 +00:00
|
|
|
if(fi.isDir())
|
|
|
|
t << "@$(DEL_FILE) -r " << dst << "\n\t"
|
2019-04-30 10:51:36 +00:00
|
|
|
<< "@$(COPY_DIR) " << src << " " << dst << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
else
|
|
|
|
t << "@$(DEL_FILE) " << dst << "\n\t"
|
2019-04-30 10:51:36 +00:00
|
|
|
<< "@$(COPY_FILE) " << src << " " << dst << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-05-20 08:46:09 +00:00
|
|
|
if (!symlinks.isEmpty()) {
|
2015-05-20 08:48:20 +00:00
|
|
|
QString bundle_dir_f = escapeFilePath(bundle_dir);
|
|
|
|
QHash<QString, QString>::ConstIterator symIt = symlinks.constBegin(),
|
|
|
|
symEnd = symlinks.constEnd();
|
|
|
|
for (; symIt != symEnd; ++symIt) {
|
|
|
|
bundledFiles << symIt.key();
|
|
|
|
alldeps << symIt.key();
|
|
|
|
t << escapeDependencyPath(symIt.key()) << ":\n\t"
|
|
|
|
<< mkdir_p_asstring(bundle_dir) << "\n\t"
|
2019-04-30 10:51:36 +00:00
|
|
|
<< "@$(SYMLINK) " << escapeFilePath(symIt.value()) << ' ' << bundle_dir_f << Qt::endl;
|
2015-05-20 08:48:20 +00:00
|
|
|
}
|
|
|
|
|
2016-02-16 06:29:01 +00:00
|
|
|
if (!project->isActiveConfig("shallow_bundle")) {
|
|
|
|
QString currentLink = bundle_dir + "Versions/Current";
|
|
|
|
QString currentLink_f = escapeDependencyPath(currentLink);
|
|
|
|
bundledFiles << currentLink;
|
|
|
|
alldeps << currentLink;
|
|
|
|
t << currentLink_f << ": $(MAKEFILE)\n\t"
|
|
|
|
<< mkdir_p_asstring(bundle_dir + "Versions") << "\n\t"
|
|
|
|
<< "@-$(DEL_FILE) " << currentLink_f << "\n\t"
|
|
|
|
<< "@$(SYMLINK) " << project->first("QMAKE_FRAMEWORK_VERSION")
|
2019-04-30 10:51:36 +00:00
|
|
|
<< ' ' << currentLink_f << Qt::endl;
|
2016-02-16 06:29:01 +00:00
|
|
|
}
|
2015-04-27 16:13:34 +00:00
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << "all: " << deps
|
2014-09-29 13:06:40 +00:00
|
|
|
<< valGlue(escapeDependencyPaths(project->values("ALL_DEPS")), " \\\n\t\t", " \\\n\t\t", "")
|
2019-04-30 10:51:36 +00:00
|
|
|
<< allDeps << Qt::endl << Qt::endl;
|
2014-09-25 15:54:16 +00:00
|
|
|
|
2014-01-17 17:26:00 +00:00
|
|
|
t << "dist: distdir FORCE\n\t";
|
|
|
|
t << "(cd `dirname $(DISTDIR)` && $(TAR) $(DISTNAME).tar $(DISTNAME) && $(COMPRESS) $(DISTNAME).tar)"
|
|
|
|
" && $(MOVE) `dirname $(DISTDIR)`" << Option::dir_sep << "$(DISTNAME).tar.gz ."
|
|
|
|
" && $(DEL_FILE) -r $(DISTDIR)";
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2014-01-17 17:26:00 +00:00
|
|
|
|
|
|
|
t << "distdir: FORCE\n\t"
|
|
|
|
<< mkdir_p_asstring("$(DISTDIR)", false) << "\n\t"
|
2019-04-30 10:51:36 +00:00
|
|
|
<< "$(COPY_FILE) --parents $(DIST) $(DISTDIR)" << Option::dir_sep << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_EXTRA_COMPILERS")) {
|
2012-09-06 10:21:38 +00:00
|
|
|
const ProStringList &quc = project->values("QMAKE_EXTRA_COMPILERS");
|
|
|
|
for (ProStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) {
|
|
|
|
const ProStringList &var = project->values(ProKey(*it + ".input"));
|
|
|
|
for (ProStringList::ConstIterator var_it = var.begin(); var_it != var.end(); ++var_it) {
|
|
|
|
const ProStringList &val = project->values((*var_it).toKey());
|
2011-04-27 10:05:43 +00:00
|
|
|
if(val.isEmpty())
|
|
|
|
continue;
|
2015-02-06 14:30:02 +00:00
|
|
|
t << "\t$(COPY_FILE) --parents " << escapeFilePaths(val).join(' ')
|
2019-04-30 10:51:36 +00:00
|
|
|
<< " $(DISTDIR)" << Option::dir_sep << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!project->isEmpty("TRANSLATIONS"))
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "\t$(COPY_FILE) --parents " << fileVar("TRANSLATIONS") << " $(DISTDIR)" << Option::dir_sep << Qt::endl;
|
|
|
|
t << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2015-02-06 14:30:02 +00:00
|
|
|
QString clean_targets = " compiler_clean " + depVar("CLEAN_DEPS");
|
2011-04-27 10:05:43 +00:00
|
|
|
if(do_incremental) {
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "incrclean:\n";
|
2011-04-27 10:05:43 +00:00
|
|
|
if(src_incremental)
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJECTS)\n";
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
t << "clean:" << clean_targets << "\n\t";
|
|
|
|
if(!project->isEmpty("OBJECTS")) {
|
2015-08-18 16:07:57 +00:00
|
|
|
t << "-$(DEL_FILE) $(OBJECTS)\n\t";
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) {
|
2012-09-06 10:21:38 +00:00
|
|
|
ProStringList precomp_files;
|
|
|
|
ProString precomph_out_dir;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
if(!project->isEmpty("PRECOMPILED_DIR"))
|
|
|
|
precomph_out_dir = project->first("PRECOMPILED_DIR");
|
|
|
|
precomph_out_dir += project->first("QMAKE_ORIG_TARGET");
|
2019-05-28 18:07:11 +00:00
|
|
|
precomph_out_dir += project->first("QMAKE_PCH_OUTPUT_EXT");
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
if (project->isActiveConfig("icc_pch_style")) {
|
|
|
|
// icc style
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString pchBaseName = project->first("QMAKE_ORIG_TARGET");
|
2017-04-11 21:54:53 +00:00
|
|
|
ProStringList pchArchs = project->values("QMAKE_PCH_ARCHS");
|
|
|
|
if (pchArchs.isEmpty())
|
|
|
|
pchArchs << ProString(); // normal single-arch PCH
|
|
|
|
for (const ProString &arch : qAsConst(pchArchs)) {
|
|
|
|
ProString pchOutput;
|
|
|
|
if (!project->isEmpty("PRECOMPILED_DIR"))
|
|
|
|
pchOutput = project->first("PRECOMPILED_DIR");
|
|
|
|
pchOutput += pchBaseName + project->first("QMAKE_PCH_OUTPUT_EXT");
|
|
|
|
if (!arch.isEmpty())
|
|
|
|
pchOutput = ProString(pchOutput.toQString().replace(
|
|
|
|
QStringLiteral("${QMAKE_PCH_ARCH}"), arch.toQString()));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2017-04-11 21:54:53 +00:00
|
|
|
ProString sourceFile = pchOutput + Option::cpp_ext.first();
|
|
|
|
ProString objectFile = createObjectList(ProStringList(sourceFile)).first();
|
|
|
|
precomp_files << precomph_out_dir << sourceFile << objectFile;
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
|
|
|
// gcc style (including clang_pch_style)
|
|
|
|
precomph_out_dir += Option::dir_sep;
|
|
|
|
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString header_prefix = project->first("QMAKE_PRECOMP_PREFIX");
|
|
|
|
ProString header_suffix = project->isActiveConfig("clang_pch_style")
|
2011-04-27 10:05:43 +00:00
|
|
|
? project->first("QMAKE_PCH_OUTPUT_EXT") : "";
|
|
|
|
|
2016-01-26 13:38:54 +00:00
|
|
|
for (const ProString &compiler : project->values("QMAKE_BUILTIN_COMPILERS")) {
|
Distinguish between Objective-C and Objective-C++ sources
Instead of lumping both Objective-C (.m) and Objective-C++ (.mm) sources
into the same pile, passing them on to the same compiler as for C++ (CXX),
with the C++ flags (CXXFLAGS), we follow Apple's lead and treat them as
variants of the C and C++ languages separately, so that Objective-C
sources are built with CC and with CFLAGS, and Objective-C++ sources
with CXX, and CXXFLAGS.
This lets us remove a lot of duplicated flags and definitions from the
QMAKE_OBJECTIVE_CFLAGS variable, which in 99% of the cases just matched
the C++ equivalent. The remaining Objective-C/C++ flags are added to
CFLAGS/CXXFLAGS, as the compiler will just ignore them when running in
C/C++ mode. This matches Xcode, which also doesn't have a separate build
setting for Objective-C/C++ flags.
The Makefile qmake generator has been rewritten to support Objective-C/C++
fully, by not assuming that we're just iterating over the C and C++
extensions when dealing with compilation rules, precompiled headers, etc.
There's some duplicated logic in this code, as inherent by qmake's already
duplicated code paths, but this can be cleaned up when C++11 support is
mandatory and we can use lambda functions.
Task-number: QTBUG-36575
Change-Id: I4f06576d5f49e939333a2e03d965da54119e5e31
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
2015-10-02 11:54:33 +00:00
|
|
|
if (project->isEmpty(ProKey("QMAKE_" + compiler + "FLAGS_PRECOMPILE")))
|
|
|
|
continue;
|
|
|
|
ProString language = project->first(ProKey("QMAKE_LANGUAGE_" + compiler));
|
|
|
|
if (language.isEmpty())
|
|
|
|
continue;
|
|
|
|
|
2016-08-23 22:16:42 +00:00
|
|
|
ProStringList pchArchs = project->values("QMAKE_PCH_ARCHS");
|
|
|
|
if (pchArchs.isEmpty())
|
|
|
|
pchArchs << ProString(); // normal single-arch PCH
|
|
|
|
for (const ProString &arch : qAsConst(pchArchs)) {
|
2019-11-12 20:56:09 +00:00
|
|
|
QString file = precomph_out_dir + header_prefix + language + header_suffix;
|
2016-08-23 22:16:42 +00:00
|
|
|
if (!arch.isEmpty())
|
2019-11-12 20:56:09 +00:00
|
|
|
file.replace(QStringLiteral("${QMAKE_PCH_ARCH}"), arch.toQString());
|
|
|
|
precomp_files += file;
|
2016-08-23 22:16:42 +00:00
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
2015-02-06 14:30:02 +00:00
|
|
|
t << "-$(DEL_FILE) " << escapeFilePaths(precomp_files).join(' ') << "\n\t";
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
if(src_incremental)
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "-$(DEL_FILE) $(INCREMENTAL_OBJECTS)\n\t";
|
2015-02-06 14:30:02 +00:00
|
|
|
t << fileVarGlue("QMAKE_CLEAN","-$(DEL_FILE) "," ","\n\t")
|
2013-07-04 09:25:16 +00:00
|
|
|
<< "-$(DEL_FILE) *~ core *.core\n"
|
2019-04-30 10:51:36 +00:00
|
|
|
<< fileVarGlue("CLEAN_FILES","\t-$(DEL_FILE) "," ","") << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString destdir = project->first("DESTDIR");
|
|
|
|
if (!destdir.isEmpty() && !destdir.endsWith(Option::dir_sep))
|
2011-04-27 10:05:43 +00:00
|
|
|
destdir += Option::dir_sep;
|
2015-02-06 14:30:02 +00:00
|
|
|
t << "distclean: clean " << depVar("DISTCLEAN_DEPS") << '\n';
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_BUNDLE")) {
|
|
|
|
QString bundlePath = escapeFilePath(destdir + project->first("QMAKE_BUNDLE"));
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "\t-$(DEL_FILE) -r " << bundlePath << Qt::endl;
|
2015-04-23 11:41:42 +00:00
|
|
|
} else if (project->isActiveConfig("staticlib") || project->isActiveConfig("plugin")) {
|
2015-02-06 14:30:02 +00:00
|
|
|
t << "\t-$(DEL_FILE) " << escapeFilePath(destdir) << "$(TARGET) \n";
|
2015-04-23 11:41:42 +00:00
|
|
|
} else if (project->values("QMAKE_APP_FLAG").isEmpty()) {
|
2015-02-06 14:30:02 +00:00
|
|
|
destdir = escapeFilePath(destdir);
|
2013-07-04 09:25:16 +00:00
|
|
|
t << "\t-$(DEL_FILE) " << destdir << "$(TARGET) \n";
|
2014-04-23 14:26:26 +00:00
|
|
|
if (!project->isActiveConfig("unversioned_libname")) {
|
|
|
|
t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) "
|
|
|
|
<< destdir << "$(TARGET2) $(TARGETA)\n";
|
|
|
|
} else {
|
|
|
|
t << "\t-$(DEL_FILE) $(TARGETA)\n";
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
2014-11-20 16:39:43 +00:00
|
|
|
t << "\t-$(DEL_FILE) $(TARGET) \n";
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2015-02-06 14:30:02 +00:00
|
|
|
t << fileVarGlue("QMAKE_DISTCLEAN","\t-$(DEL_FILE) "," ","\n");
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
2014-11-24 18:51:32 +00:00
|
|
|
QString ofile = fileFixify(Option::output.fileName());
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!ofile.isEmpty())
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "\t-$(DEL_FILE) " << escapeFilePath(ofile) << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2019-04-30 10:51:36 +00:00
|
|
|
t << Qt::endl << Qt::endl;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2013-12-11 03:27:39 +00:00
|
|
|
t << "####### Sub-libraries\n\n";
|
|
|
|
if (!project->values("SUBLIBS").isEmpty()) {
|
|
|
|
ProString libdir = "tmp/";
|
|
|
|
if (!project->isEmpty("SUBLIBS_DIR"))
|
|
|
|
libdir = project->first("SUBLIBS_DIR");
|
|
|
|
const ProStringList &l = project->values("SUBLIBS");
|
|
|
|
for (it = l.begin(); it != l.end(); ++it)
|
2015-02-06 14:30:02 +00:00
|
|
|
t << escapeDependencyPath(libdir + project->first("QMAKE_PREFIX_STATICLIB") + (*it) + '.'
|
|
|
|
+ project->first("QMAKE_EXTENSION_STATICLIB")) << ":\n\t"
|
2019-04-30 10:51:36 +00:00
|
|
|
<< var(ProKey("MAKELIB" + *it)) << Qt::endl << Qt::endl;
|
2013-12-11 03:27:39 +00:00
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) {
|
2012-09-06 10:21:38 +00:00
|
|
|
QString pchInput = project->first("PRECOMPILED_HEADER").toQString();
|
2013-12-11 03:28:26 +00:00
|
|
|
t << "###### Precompiled headers\n";
|
2016-01-26 13:38:54 +00:00
|
|
|
for (const ProString &compiler : project->values("QMAKE_BUILTIN_COMPILERS")) {
|
2016-08-23 22:16:42 +00:00
|
|
|
QString pchOutputDir;
|
Distinguish between Objective-C and Objective-C++ sources
Instead of lumping both Objective-C (.m) and Objective-C++ (.mm) sources
into the same pile, passing them on to the same compiler as for C++ (CXX),
with the C++ flags (CXXFLAGS), we follow Apple's lead and treat them as
variants of the C and C++ languages separately, so that Objective-C
sources are built with CC and with CFLAGS, and Objective-C++ sources
with CXX, and CXXFLAGS.
This lets us remove a lot of duplicated flags and definitions from the
QMAKE_OBJECTIVE_CFLAGS variable, which in 99% of the cases just matched
the C++ equivalent. The remaining Objective-C/C++ flags are added to
CFLAGS/CXXFLAGS, as the compiler will just ignore them when running in
C/C++ mode. This matches Xcode, which also doesn't have a separate build
setting for Objective-C/C++ flags.
The Makefile qmake generator has been rewritten to support Objective-C/C++
fully, by not assuming that we're just iterating over the C and C++
extensions when dealing with compilation rules, precompiled headers, etc.
There's some duplicated logic in this code, as inherent by qmake's already
duplicated code paths, but this can be cleaned up when C++11 support is
mandatory and we can use lambda functions.
Task-number: QTBUG-36575
Change-Id: I4f06576d5f49e939333a2e03d965da54119e5e31
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
2015-10-02 11:54:33 +00:00
|
|
|
QString pchFlags = var(ProKey("QMAKE_" + compiler + "FLAGS_PRECOMPILE"));
|
2011-04-27 10:05:43 +00:00
|
|
|
if(pchFlags.isEmpty())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
QString cflags;
|
Distinguish between Objective-C and Objective-C++ sources
Instead of lumping both Objective-C (.m) and Objective-C++ (.mm) sources
into the same pile, passing them on to the same compiler as for C++ (CXX),
with the C++ flags (CXXFLAGS), we follow Apple's lead and treat them as
variants of the C and C++ languages separately, so that Objective-C
sources are built with CC and with CFLAGS, and Objective-C++ sources
with CXX, and CXXFLAGS.
This lets us remove a lot of duplicated flags and definitions from the
QMAKE_OBJECTIVE_CFLAGS variable, which in 99% of the cases just matched
the C++ equivalent. The remaining Objective-C/C++ flags are added to
CFLAGS/CXXFLAGS, as the compiler will just ignore them when running in
C/C++ mode. This matches Xcode, which also doesn't have a separate build
setting for Objective-C/C++ flags.
The Makefile qmake generator has been rewritten to support Objective-C/C++
fully, by not assuming that we're just iterating over the C and C++
extensions when dealing with compilation rules, precompiled headers, etc.
There's some duplicated logic in this code, as inherent by qmake's already
duplicated code paths, but this can be cleaned up when C++11 support is
mandatory and we can use lambda functions.
Task-number: QTBUG-36575
Change-Id: I4f06576d5f49e939333a2e03d965da54119e5e31
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
2015-10-02 11:54:33 +00:00
|
|
|
if (compiler == "C" || compiler == "OBJC")
|
2011-04-27 10:05:43 +00:00
|
|
|
cflags += " $(CFLAGS)";
|
|
|
|
else
|
Distinguish between Objective-C and Objective-C++ sources
Instead of lumping both Objective-C (.m) and Objective-C++ (.mm) sources
into the same pile, passing them on to the same compiler as for C++ (CXX),
with the C++ flags (CXXFLAGS), we follow Apple's lead and treat them as
variants of the C and C++ languages separately, so that Objective-C
sources are built with CC and with CFLAGS, and Objective-C++ sources
with CXX, and CXXFLAGS.
This lets us remove a lot of duplicated flags and definitions from the
QMAKE_OBJECTIVE_CFLAGS variable, which in 99% of the cases just matched
the C++ equivalent. The remaining Objective-C/C++ flags are added to
CFLAGS/CXXFLAGS, as the compiler will just ignore them when running in
C/C++ mode. This matches Xcode, which also doesn't have a separate build
setting for Objective-C/C++ flags.
The Makefile qmake generator has been rewritten to support Objective-C/C++
fully, by not assuming that we're just iterating over the C and C++
extensions when dealing with compilation rules, precompiled headers, etc.
There's some duplicated logic in this code, as inherent by qmake's already
duplicated code paths, but this can be cleaned up when C++11 support is
mandatory and we can use lambda functions.
Task-number: QTBUG-36575
Change-Id: I4f06576d5f49e939333a2e03d965da54119e5e31
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
2015-10-02 11:54:33 +00:00
|
|
|
cflags += " $(CXXFLAGS)";
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2016-08-23 22:16:42 +00:00
|
|
|
ProStringList pchArchs = project->values("QMAKE_PCH_ARCHS");
|
|
|
|
if (pchArchs.isEmpty())
|
|
|
|
pchArchs << ProString(); // normal single-arch PCH
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString pchBaseName = project->first("QMAKE_ORIG_TARGET");
|
|
|
|
ProString pchOutput;
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("PRECOMPILED_DIR"))
|
|
|
|
pchOutput = project->first("PRECOMPILED_DIR");
|
|
|
|
pchOutput += pchBaseName;
|
2019-05-28 18:07:11 +00:00
|
|
|
pchOutput += project->first("QMAKE_PCH_OUTPUT_EXT");
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2017-04-11 21:54:53 +00:00
|
|
|
if (!project->isActiveConfig("icc_pch_style")) {
|
2011-04-27 10:05:43 +00:00
|
|
|
// gcc style (including clang_pch_style)
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString header_prefix = project->first("QMAKE_PRECOMP_PREFIX");
|
|
|
|
ProString header_suffix = project->isActiveConfig("clang_pch_style")
|
2011-04-27 10:05:43 +00:00
|
|
|
? project->first("QMAKE_PCH_OUTPUT_EXT") : "";
|
|
|
|
pchOutput += Option::dir_sep;
|
2016-08-23 22:16:42 +00:00
|
|
|
pchOutputDir = pchOutput.toQString();
|
Distinguish between Objective-C and Objective-C++ sources
Instead of lumping both Objective-C (.m) and Objective-C++ (.mm) sources
into the same pile, passing them on to the same compiler as for C++ (CXX),
with the C++ flags (CXXFLAGS), we follow Apple's lead and treat them as
variants of the C and C++ languages separately, so that Objective-C
sources are built with CC and with CFLAGS, and Objective-C++ sources
with CXX, and CXXFLAGS.
This lets us remove a lot of duplicated flags and definitions from the
QMAKE_OBJECTIVE_CFLAGS variable, which in 99% of the cases just matched
the C++ equivalent. The remaining Objective-C/C++ flags are added to
CFLAGS/CXXFLAGS, as the compiler will just ignore them when running in
C/C++ mode. This matches Xcode, which also doesn't have a separate build
setting for Objective-C/C++ flags.
The Makefile qmake generator has been rewritten to support Objective-C/C++
fully, by not assuming that we're just iterating over the C and C++
extensions when dealing with compilation rules, precompiled headers, etc.
There's some duplicated logic in this code, as inherent by qmake's already
duplicated code paths, but this can be cleaned up when C++11 support is
mandatory and we can use lambda functions.
Task-number: QTBUG-36575
Change-Id: I4f06576d5f49e939333a2e03d965da54119e5e31
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
2015-10-02 11:54:33 +00:00
|
|
|
|
|
|
|
QString language = project->first(ProKey("QMAKE_LANGUAGE_" + compiler)).toQString();
|
|
|
|
if (language.isEmpty())
|
2011-04-27 10:05:43 +00:00
|
|
|
continue;
|
Distinguish between Objective-C and Objective-C++ sources
Instead of lumping both Objective-C (.m) and Objective-C++ (.mm) sources
into the same pile, passing them on to the same compiler as for C++ (CXX),
with the C++ flags (CXXFLAGS), we follow Apple's lead and treat them as
variants of the C and C++ languages separately, so that Objective-C
sources are built with CC and with CFLAGS, and Objective-C++ sources
with CXX, and CXXFLAGS.
This lets us remove a lot of duplicated flags and definitions from the
QMAKE_OBJECTIVE_CFLAGS variable, which in 99% of the cases just matched
the C++ equivalent. The remaining Objective-C/C++ flags are added to
CFLAGS/CXXFLAGS, as the compiler will just ignore them when running in
C/C++ mode. This matches Xcode, which also doesn't have a separate build
setting for Objective-C/C++ flags.
The Makefile qmake generator has been rewritten to support Objective-C/C++
fully, by not assuming that we're just iterating over the C and C++
extensions when dealing with compilation rules, precompiled headers, etc.
There's some duplicated logic in this code, as inherent by qmake's already
duplicated code paths, but this can be cleaned up when C++11 support is
mandatory and we can use lambda functions.
Task-number: QTBUG-36575
Change-Id: I4f06576d5f49e939333a2e03d965da54119e5e31
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
2015-10-02 11:54:33 +00:00
|
|
|
|
|
|
|
pchOutput += header_prefix + language + header_suffix;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2016-02-04 14:12:03 +00:00
|
|
|
pchFlags.replace(QLatin1String("${QMAKE_PCH_INPUT}"), escapeFilePath(pchInput))
|
2016-08-23 22:16:42 +00:00
|
|
|
.replace(QLatin1String("${QMAKE_PCH_OUTPUT_BASE}"), escapeFilePath(pchBaseName.toQString()));
|
|
|
|
for (const ProString &arch : qAsConst(pchArchs)) {
|
|
|
|
auto pchArchOutput = pchOutput.toQString();
|
|
|
|
if (!arch.isEmpty())
|
|
|
|
pchArchOutput.replace(QStringLiteral("${QMAKE_PCH_ARCH}"), arch.toQString());
|
|
|
|
|
2017-04-11 21:54:53 +00:00
|
|
|
const auto pchFilePath_d = escapeDependencyPath(pchArchOutput);
|
|
|
|
if (!arch.isEmpty()) {
|
|
|
|
t << pchFilePath_d << ": " << "EXPORT_ARCH_ARGS = -arch " << arch << "\n\n";
|
|
|
|
t << pchFilePath_d << ": "
|
|
|
|
<< "EXPORT_QMAKE_XARCH_CFLAGS = $(EXPORT_QMAKE_XARCH_CFLAGS_" << arch << ")" << "\n\n";
|
|
|
|
t << pchFilePath_d << ": "
|
|
|
|
<< "EXPORT_QMAKE_XARCH_LFLAGS = $(EXPORT_QMAKE_XARCH_LFLAGS_" << arch << ")" << "\n\n";
|
|
|
|
}
|
|
|
|
t << pchFilePath_d << ": " << escapeDependencyPath(pchInput) << ' '
|
2018-06-08 14:00:44 +00:00
|
|
|
<< finalizeDependencyPaths(findDependencies(pchInput)).join(" \\\n\t\t");
|
2017-04-11 21:54:53 +00:00
|
|
|
if (project->isActiveConfig("icc_pch_style")) {
|
|
|
|
QString sourceFile = pchArchOutput + Option::cpp_ext.first();
|
|
|
|
QString sourceFile_f = escapeFilePath(sourceFile);
|
|
|
|
QString objectFile = createObjectList(ProStringList(sourceFile)).first().toQString();
|
|
|
|
|
|
|
|
pchFlags.replace(QLatin1String("${QMAKE_PCH_TEMP_SOURCE}"), sourceFile_f)
|
|
|
|
.replace(QLatin1String("${QMAKE_PCH_TEMP_OBJECT}"), escapeFilePath(objectFile));
|
|
|
|
|
|
|
|
t << "\n\techo \"// Automatically generated, do not modify\" > " << sourceFile_f
|
|
|
|
<< "\n\trm -f " << escapeFilePath(pchArchOutput);
|
|
|
|
} else {
|
2019-11-12 20:56:09 +00:00
|
|
|
QString outDir = pchOutputDir;
|
|
|
|
if (!arch.isEmpty())
|
|
|
|
outDir.replace(QStringLiteral("${QMAKE_PCH_ARCH}"), arch.toQString());
|
|
|
|
t << "\n\t" << mkdir_p_asstring(outDir);
|
2016-08-23 22:16:42 +00:00
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2016-08-23 22:16:42 +00:00
|
|
|
auto pchArchFlags = pchFlags;
|
|
|
|
pchArchFlags.replace(QLatin1String("${QMAKE_PCH_OUTPUT}"), escapeFilePath(pchArchOutput));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2016-08-23 22:16:42 +00:00
|
|
|
QString compilerExecutable;
|
|
|
|
if (compiler == "C" || compiler == "OBJC")
|
|
|
|
compilerExecutable = "$(CC)";
|
|
|
|
else
|
|
|
|
compilerExecutable = "$(CXX)";
|
|
|
|
|
|
|
|
// compile command
|
2019-04-30 10:51:36 +00:00
|
|
|
t << "\n\t" << compilerExecutable << cflags << " $(INCPATH) " << pchArchFlags << Qt::endl << Qt::endl;
|
2016-08-23 22:16:42 +00:00
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
writeExtraTargets(t);
|
|
|
|
writeExtraCompilerTargets(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
void UnixMakefileGenerator::init2()
|
|
|
|
{
|
|
|
|
if(project->isEmpty("QMAKE_FRAMEWORK_VERSION"))
|
2014-11-27 13:49:16 +00:00
|
|
|
project->values("QMAKE_FRAMEWORK_VERSION").append(project->first("VER_MAJ"));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2015-04-22 17:37:48 +00:00
|
|
|
if (project->first("TEMPLATE") == "aux") {
|
2019-08-13 11:41:38 +00:00
|
|
|
project->values("PRL_TARGET") = {
|
|
|
|
project->first("QMAKE_PREFIX_STATICLIB") +
|
|
|
|
project->first("TARGET")
|
|
|
|
};
|
2015-04-22 17:37:48 +00:00
|
|
|
} else if (!project->values("QMAKE_APP_FLAG").isEmpty()) {
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!project->isEmpty("QMAKE_BUNDLE")) {
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION");
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!bundle_loc.isEmpty() && !bundle_loc.startsWith("/"))
|
|
|
|
bundle_loc.prepend("/");
|
|
|
|
if(!bundle_loc.endsWith("/"))
|
|
|
|
bundle_loc += "/";
|
|
|
|
project->values("TARGET").first().prepend(project->first("QMAKE_BUNDLE") + bundle_loc);
|
|
|
|
}
|
|
|
|
if(!project->isEmpty("TARGET"))
|
|
|
|
project->values("TARGET").first().prepend(project->first("DESTDIR"));
|
|
|
|
} else if (project->isActiveConfig("staticlib")) {
|
2018-08-23 18:21:24 +00:00
|
|
|
project->values("PRL_TARGET") =
|
|
|
|
project->values("TARGET").first().prepend(project->first("QMAKE_PREFIX_STATICLIB"));
|
2011-04-27 10:05:43 +00:00
|
|
|
project->values("TARGET").first() += "." + project->first("QMAKE_EXTENSION_STATICLIB");
|
|
|
|
if(project->values("QMAKE_AR_CMD").isEmpty())
|
2015-09-15 16:21:11 +00:00
|
|
|
project->values("QMAKE_AR_CMD").append("$(AR) $(DESTDIR)$(TARGET) $(OBJECTS)");
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
|
|
|
project->values("TARGETA").append(project->first("DESTDIR") + project->first("QMAKE_PREFIX_STATICLIB")
|
|
|
|
+ project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_STATICLIB"));
|
|
|
|
|
2012-09-06 10:21:38 +00:00
|
|
|
ProStringList &ar_cmd = project->values("QMAKE_AR_CMD");
|
|
|
|
if (!ar_cmd.isEmpty())
|
2016-02-04 14:12:03 +00:00
|
|
|
ar_cmd[0] = ar_cmd.at(0).toQString().replace(QLatin1String("(TARGET)"), QLatin1String("(TARGETA)"));
|
2011-04-27 10:05:43 +00:00
|
|
|
else
|
2012-09-06 10:21:38 +00:00
|
|
|
ar_cmd.append("$(AR) $(TARGETA) $(OBJECTS)");
|
2015-08-18 16:07:57 +00:00
|
|
|
if (!project->isEmpty("QMAKE_BUNDLE")) {
|
2019-09-27 13:38:48 +00:00
|
|
|
project->values("PRL_TARGET").prepend(project->first("QMAKE_BUNDLE") +
|
|
|
|
"/Versions/" + project->first("QMAKE_FRAMEWORK_VERSION") +
|
|
|
|
"/Resources/" + project->first("TARGET"));
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION");
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!bundle_loc.isEmpty() && !bundle_loc.startsWith("/"))
|
|
|
|
bundle_loc.prepend("/");
|
|
|
|
if(!bundle_loc.endsWith("/"))
|
|
|
|
bundle_loc += "/";
|
2016-02-16 06:29:01 +00:00
|
|
|
const QString target = project->first("QMAKE_BUNDLE") +
|
|
|
|
bundle_loc + project->first("TARGET");
|
|
|
|
project->values("TARGET_").append(target);
|
|
|
|
if (!project->isActiveConfig("shallow_bundle")) {
|
|
|
|
project->values("TARGET_x.y").append(project->first("QMAKE_BUNDLE") +
|
|
|
|
"/Versions/" +
|
|
|
|
project->first("QMAKE_FRAMEWORK_VERSION") +
|
|
|
|
bundle_loc + project->first("TARGET"));
|
|
|
|
} else {
|
|
|
|
project->values("TARGET_x.y").append(target);
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
} else if(project->isActiveConfig("plugin")) {
|
|
|
|
QString prefix;
|
|
|
|
if(!project->isActiveConfig("no_plugin_name_prefix"))
|
|
|
|
prefix = "lib";
|
2018-08-23 18:21:24 +00:00
|
|
|
project->values("PRL_TARGET").prepend(prefix + project->first("TARGET"));
|
2011-04-27 10:05:43 +00:00
|
|
|
project->values("TARGET_x.y.z").append(prefix +
|
|
|
|
project->first("TARGET") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_PLUGIN"));
|
|
|
|
if(project->isActiveConfig("lib_version_first"))
|
|
|
|
project->values("TARGET_x").append(prefix + project->first("TARGET") + "." +
|
|
|
|
project->first("VER_MAJ") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_PLUGIN"));
|
|
|
|
else
|
|
|
|
project->values("TARGET_x").append(prefix + project->first("TARGET") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_PLUGIN") +
|
|
|
|
"." + project->first("VER_MAJ"));
|
|
|
|
project->values("TARGET") = project->values("TARGET_x.y.z");
|
|
|
|
} else if (!project->isEmpty("QMAKE_HPUX_SHLIB")) {
|
2018-08-23 18:21:24 +00:00
|
|
|
project->values("PRL_TARGET").prepend("lib" + project->first("TARGET"));
|
2011-04-27 10:05:43 +00:00
|
|
|
project->values("TARGET_").append("lib" + project->first("TARGET") + ".sl");
|
|
|
|
if(project->isActiveConfig("lib_version_first"))
|
|
|
|
project->values("TARGET_x").append("lib" + project->first("VER_MAJ") + "." +
|
|
|
|
project->first("TARGET"));
|
|
|
|
else
|
|
|
|
project->values("TARGET_x").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("VER_MAJ"));
|
|
|
|
project->values("TARGET") = project->values("TARGET_x");
|
|
|
|
} else if (!project->isEmpty("QMAKE_AIX_SHLIB")) {
|
2018-08-23 18:21:24 +00:00
|
|
|
project->values("PRL_TARGET").prepend("lib" + project->first("TARGET"));
|
2011-04-27 10:05:43 +00:00
|
|
|
project->values("TARGET_").append(project->first("QMAKE_PREFIX_STATICLIB") + project->first("TARGET")
|
|
|
|
+ "." + project->first("QMAKE_EXTENSION_STATICLIB"));
|
|
|
|
if(project->isActiveConfig("lib_version_first")) {
|
|
|
|
project->values("TARGET_x").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("VER_MAJ") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_SHLIB"));
|
|
|
|
project->values("TARGET_x.y").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("VER_MAJ") +
|
|
|
|
"." + project->first("VER_MIN") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_SHLIB"));
|
|
|
|
project->values("TARGET_x.y.z").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("VER_MAJ") + "." +
|
|
|
|
project->first("VER_MIN") + "." +
|
|
|
|
project->first("VER_PAT") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_SHLIB"));
|
|
|
|
} else {
|
|
|
|
project->values("TARGET_x").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_SHLIB") +
|
|
|
|
"." + project->first("VER_MAJ"));
|
|
|
|
project->values("TARGET_x.y").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_SHLIB") +
|
|
|
|
"." + project->first("VER_MAJ") +
|
|
|
|
"." + project->first("VER_MIN"));
|
|
|
|
project->values("TARGET_x.y.z").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_SHLIB") + "." +
|
|
|
|
project->first("VER_MAJ") + "." +
|
|
|
|
project->first("VER_MIN") + "." +
|
|
|
|
project->first("VER_PAT"));
|
|
|
|
}
|
|
|
|
project->values("TARGET") = project->values("TARGET_x.y.z");
|
|
|
|
} else {
|
2018-08-23 18:21:24 +00:00
|
|
|
project->values("PRL_TARGET").prepend("lib" + project->first("TARGET"));
|
2011-04-27 10:05:43 +00:00
|
|
|
project->values("TARGET_").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_SHLIB"));
|
|
|
|
if(project->isActiveConfig("lib_version_first")) {
|
|
|
|
project->values("TARGET_x").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("VER_MAJ") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_SHLIB"));
|
|
|
|
project->values("TARGET_x.y").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("VER_MAJ") +
|
|
|
|
"." + project->first("VER_MIN") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_SHLIB"));
|
|
|
|
project->values("TARGET_x.y.z").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("VER_MAJ") + "." +
|
|
|
|
project->first("VER_MIN") + "." +
|
|
|
|
project->first("VER_PAT") + "." +
|
2014-11-27 13:49:16 +00:00
|
|
|
project->first("QMAKE_EXTENSION_SHLIB"));
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
|
|
|
project->values("TARGET_x").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_SHLIB") +
|
|
|
|
"." + project->first("VER_MAJ"));
|
|
|
|
project->values("TARGET_x.y").append("lib" + project->first("TARGET") + "." +
|
|
|
|
project->first("QMAKE_EXTENSION_SHLIB")
|
|
|
|
+ "." + project->first("VER_MAJ") +
|
|
|
|
"." + project->first("VER_MIN"));
|
|
|
|
project->values("TARGET_x.y.z").append("lib" + project->first("TARGET") +
|
|
|
|
"." +
|
2014-11-27 13:49:16 +00:00
|
|
|
project->first(
|
|
|
|
"QMAKE_EXTENSION_SHLIB") + "." +
|
2011-04-27 10:05:43 +00:00
|
|
|
project->first("VER_MAJ") + "." +
|
|
|
|
project->first("VER_MIN") + "." +
|
|
|
|
project->first("VER_PAT"));
|
|
|
|
}
|
2014-04-23 14:26:26 +00:00
|
|
|
if (project->isActiveConfig("unversioned_libname"))
|
|
|
|
project->values("TARGET") = project->values("TARGET_");
|
|
|
|
else
|
|
|
|
project->values("TARGET") = project->values("TARGET_x.y.z");
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
if (!project->values("QMAKE_LFLAGS_SONAME").isEmpty()) {
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString soname;
|
2011-04-27 10:05:43 +00:00
|
|
|
if(project->isActiveConfig("plugin")) {
|
|
|
|
if(!project->values("TARGET").isEmpty())
|
|
|
|
soname += project->first("TARGET");
|
|
|
|
} else if(!project->isEmpty("QMAKE_BUNDLE")) {
|
|
|
|
soname += project->first("TARGET_x.y");
|
2013-07-22 11:09:21 +00:00
|
|
|
} else if(project->isActiveConfig("unversioned_soname")) {
|
|
|
|
soname = "lib" + project->first("QMAKE_ORIG_TARGET")
|
|
|
|
+ "." + project->first("QMAKE_EXTENSION_SHLIB");
|
2011-04-27 10:05:43 +00:00
|
|
|
} else if(!project->values("TARGET_x").isEmpty()) {
|
|
|
|
soname += project->first("TARGET_x");
|
|
|
|
}
|
|
|
|
if(!soname.isEmpty()) {
|
|
|
|
if(project->isActiveConfig("absolute_library_soname") &&
|
|
|
|
project->values("INSTALLS").indexOf("target") != -1 &&
|
|
|
|
!project->isEmpty("target.path")) {
|
2012-09-06 10:21:38 +00:00
|
|
|
QString instpath = Option::fixPathToTargetOS(project->first("target.path").toQString());
|
2011-04-27 10:05:43 +00:00
|
|
|
if(!instpath.endsWith(Option::dir_sep))
|
|
|
|
instpath += Option::dir_sep;
|
|
|
|
soname.prepend(instpath);
|
2014-08-06 16:53:05 +00:00
|
|
|
} else if (!project->isEmpty("QMAKE_SONAME_PREFIX")) {
|
|
|
|
QString sonameprefix = project->first("QMAKE_SONAME_PREFIX").toQString();
|
2015-06-05 14:49:25 +00:00
|
|
|
if (!sonameprefix.startsWith('@'))
|
2014-08-06 16:53:05 +00:00
|
|
|
sonameprefix = Option::fixPathToTargetOS(sonameprefix, false);
|
|
|
|
if (!sonameprefix.endsWith(Option::dir_sep))
|
|
|
|
sonameprefix += Option::dir_sep;
|
|
|
|
soname.prepend(sonameprefix);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
project->values("QMAKE_LFLAGS_SONAME").first() += escapeFilePath(soname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (project->values("QMAKE_LINK_SHLIB_CMD").isEmpty())
|
|
|
|
project->values("QMAKE_LINK_SHLIB_CMD").append(
|
2013-01-30 14:58:00 +00:00
|
|
|
"$(LINK) $(LFLAGS) " + project->first("QMAKE_LINK_O_FLAG") + "$(TARGET) $(OBJECTS) $(LIBS) $(OBJCOMP)");
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2015-04-22 17:37:48 +00:00
|
|
|
if (!project->values("QMAKE_APP_FLAG").isEmpty() || project->first("TEMPLATE") == "aux") {
|
2011-04-27 10:05:43 +00:00
|
|
|
project->values("QMAKE_CFLAGS") += project->values("QMAKE_CFLAGS_APP");
|
|
|
|
project->values("QMAKE_CXXFLAGS") += project->values("QMAKE_CXXFLAGS_APP");
|
|
|
|
project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_APP");
|
|
|
|
} else if (project->isActiveConfig("dll")) {
|
|
|
|
if(!project->isActiveConfig("plugin") || !project->isActiveConfig("plugin_no_share_shlib_cflags")) {
|
|
|
|
project->values("QMAKE_CFLAGS") += project->values("QMAKE_CFLAGS_SHLIB");
|
|
|
|
project->values("QMAKE_CXXFLAGS") += project->values("QMAKE_CXXFLAGS_SHLIB");
|
|
|
|
}
|
|
|
|
if (project->isActiveConfig("plugin")) {
|
|
|
|
project->values("QMAKE_CFLAGS") += project->values("QMAKE_CFLAGS_PLUGIN");
|
|
|
|
project->values("QMAKE_CXXFLAGS") += project->values("QMAKE_CXXFLAGS_PLUGIN");
|
|
|
|
project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_PLUGIN");
|
2015-08-18 16:07:57 +00:00
|
|
|
if (project->isActiveConfig("plugin_with_soname"))
|
2011-04-27 10:05:43 +00:00
|
|
|
project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_SONAME");
|
|
|
|
} else {
|
|
|
|
project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_SHLIB");
|
|
|
|
if(!project->isEmpty("QMAKE_LFLAGS_COMPAT_VERSION")) {
|
|
|
|
if(project->isEmpty("COMPAT_VERSION"))
|
|
|
|
project->values("QMAKE_LFLAGS") += QString(project->first("QMAKE_LFLAGS_COMPAT_VERSION") +
|
|
|
|
project->first("VER_MAJ") + "." +
|
|
|
|
project->first("VER_MIN"));
|
|
|
|
else
|
|
|
|
project->values("QMAKE_LFLAGS") += QString(project->first("QMAKE_LFLAGS_COMPAT_VERSION") +
|
|
|
|
project->first("COMPATIBILITY_VERSION"));
|
|
|
|
}
|
|
|
|
if(!project->isEmpty("QMAKE_LFLAGS_VERSION")) {
|
|
|
|
project->values("QMAKE_LFLAGS") += QString(project->first("QMAKE_LFLAGS_VERSION") +
|
|
|
|
project->first("VER_MAJ") + "." +
|
|
|
|
project->first("VER_MIN") + "." +
|
|
|
|
project->first("VER_PAT"));
|
|
|
|
}
|
2015-08-18 16:07:57 +00:00
|
|
|
project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_SONAME");
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-24 11:37:30 +00:00
|
|
|
if (include_deps && project->isActiveConfig("gcc_MD_depends")) {
|
2020-06-03 10:06:01 +00:00
|
|
|
ProString MD_flag("-MD");
|
2013-12-11 04:10:10 +00:00
|
|
|
project->values("QMAKE_CFLAGS") += MD_flag;
|
|
|
|
project->values("QMAKE_CXXFLAGS") += MD_flag;
|
2011-10-24 11:37:30 +00:00
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QString
|
|
|
|
UnixMakefileGenerator::libtoolFileName(bool fixify)
|
|
|
|
{
|
|
|
|
QString ret = var("TARGET");
|
|
|
|
int slsh = ret.lastIndexOf(Option::dir_sep);
|
|
|
|
if(slsh != -1)
|
|
|
|
ret = ret.right(ret.length() - slsh - 1);
|
|
|
|
int dot = ret.indexOf('.');
|
|
|
|
if(dot != -1)
|
|
|
|
ret = ret.left(dot);
|
|
|
|
ret += Option::libtool_ext;
|
|
|
|
if(!project->isEmpty("QMAKE_LIBTOOL_DESTDIR"))
|
|
|
|
ret.prepend(project->first("QMAKE_LIBTOOL_DESTDIR") + Option::dir_sep);
|
|
|
|
if(fixify) {
|
|
|
|
if(QDir::isRelativePath(ret) && !project->isEmpty("DESTDIR"))
|
2012-09-06 10:21:38 +00:00
|
|
|
ret.prepend(project->first("DESTDIR").toQString());
|
2015-04-13 19:18:36 +00:00
|
|
|
ret = fileFixify(ret, FileFixifyBackwards);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2021-08-17 15:11:20 +00:00
|
|
|
static std::pair<ProStringList, ProStringList>
|
|
|
|
splitFrameworksAndLibs(const ProStringList &linkArgs)
|
|
|
|
{
|
|
|
|
std::pair<ProStringList, ProStringList> result;
|
|
|
|
bool frameworkArg = false;
|
|
|
|
for (auto arg : linkArgs) {
|
|
|
|
if (frameworkArg) {
|
|
|
|
frameworkArg = false;
|
|
|
|
result.second += arg;
|
|
|
|
} else if (arg == "-framework") {
|
|
|
|
frameworkArg = true;
|
|
|
|
result.second += arg;
|
|
|
|
} else {
|
|
|
|
result.first += arg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
void
|
|
|
|
UnixMakefileGenerator::writeLibtoolFile()
|
|
|
|
{
|
2019-07-31 08:55:14 +00:00
|
|
|
auto fixDependencyLibs
|
|
|
|
= [this](const ProStringList &libs)
|
|
|
|
{
|
|
|
|
ProStringList result;
|
|
|
|
for (auto lib : libs) {
|
|
|
|
auto fi = fileInfo(lib.toQString());
|
|
|
|
if (fi.isAbsolute()) {
|
|
|
|
const QString libDirArg = "-L" + fi.path();
|
|
|
|
if (!result.contains(libDirArg))
|
|
|
|
result += libDirArg;
|
|
|
|
QString namespec = fi.fileName();
|
|
|
|
int dotPos = namespec.lastIndexOf('.');
|
|
|
|
if (dotPos != -1 && namespec.startsWith("lib")) {
|
|
|
|
namespec.truncate(dotPos);
|
|
|
|
namespec.remove(0, 3);
|
|
|
|
} else {
|
|
|
|
debug_msg(1, "Ignoring dependency library %s",
|
|
|
|
lib.toLatin1().constData());
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
result += "-l" + namespec;
|
|
|
|
} else {
|
|
|
|
result += lib;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
QString fname = libtoolFileName(), lname = fname;
|
2019-07-31 08:55:14 +00:00
|
|
|
debug_msg(1, "Writing libtool file %s", fname.toLatin1().constData());
|
2011-04-27 10:05:43 +00:00
|
|
|
mkdir(fileInfo(fname).path());
|
|
|
|
int slsh = lname.lastIndexOf(Option::dir_sep);
|
|
|
|
if(slsh != -1)
|
|
|
|
lname = lname.right(lname.length() - slsh - 1);
|
|
|
|
QFile ft(fname);
|
|
|
|
if(!ft.open(QIODevice::WriteOnly))
|
|
|
|
return;
|
2015-04-23 11:43:30 +00:00
|
|
|
QString ffname(fileFixify(fname));
|
|
|
|
project->values("ALL_DEPS").append(ffname);
|
|
|
|
project->values("QMAKE_DISTCLEAN").append(ffname);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QTextStream t(&ft);
|
|
|
|
t << "# " << lname << " - a libtool library file\n";
|
2012-09-12 17:27:09 +00:00
|
|
|
t << "# Generated by qmake/libtool (" QMAKE_VERSION_STR ") (Qt "
|
2015-02-03 07:18:29 +00:00
|
|
|
<< QT_VERSION_STR << ")";
|
2014-01-13 14:48:44 +00:00
|
|
|
t << "\n";
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
t << "# The name that we can dlopen(3).\n"
|
2015-02-06 14:30:02 +00:00
|
|
|
<< "dlname='" << fileVar(project->isActiveConfig("plugin") ? "TARGET" : "TARGET_x")
|
2011-04-27 10:05:43 +00:00
|
|
|
<< "'\n\n";
|
|
|
|
|
|
|
|
t << "# Names of this library.\n";
|
|
|
|
t << "library_names='";
|
|
|
|
if(project->isActiveConfig("plugin")) {
|
2015-02-06 14:30:02 +00:00
|
|
|
t << fileVar("TARGET");
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
|
|
|
if (project->isEmpty("QMAKE_HPUX_SHLIB"))
|
2015-02-06 14:30:02 +00:00
|
|
|
t << fileVar("TARGET_x.y.z") << ' ';
|
|
|
|
t << fileVar("TARGET_x") << ' ' << fileVar("TARGET_");
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
t << "'\n\n";
|
|
|
|
|
|
|
|
t << "# The name of the static archive.\n"
|
2015-02-06 14:30:02 +00:00
|
|
|
<< "old_library='" << escapeFilePath(lname.left(lname.length()-Option::libtool_ext.length()))
|
|
|
|
<< ".a'\n\n";
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
t << "# Libraries that this one depends upon.\n";
|
2019-07-31 08:55:14 +00:00
|
|
|
static const ProKey libVars[] = { "LIBS", "QMAKE_LIBS" };
|
2012-09-06 10:21:38 +00:00
|
|
|
ProStringList libs;
|
2019-07-31 08:55:14 +00:00
|
|
|
for (auto var : libVars)
|
|
|
|
libs += fixLibFlags(var);
|
2021-08-17 15:11:20 +00:00
|
|
|
ProStringList frameworks;
|
|
|
|
std::tie(libs, frameworks) = splitFrameworksAndLibs(libs);
|
2019-07-31 08:55:14 +00:00
|
|
|
t << "dependency_libs='" << fixDependencyLibs(libs).join(' ') << "'\n\n";
|
2021-08-17 15:11:20 +00:00
|
|
|
if (!frameworks.isEmpty()) {
|
|
|
|
t << "# Frameworks that this library depends upon.\n";
|
|
|
|
t << "inherited_linker_flags='" << frameworks.join(' ') << "'\n\n";
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
t << "# Version information for " << lname << "\n";
|
|
|
|
int maj = project->first("VER_MAJ").toInt();
|
|
|
|
int min = project->first("VER_MIN").toInt();
|
|
|
|
int pat = project->first("VER_PAT").toInt();
|
|
|
|
t << "current=" << (10*maj + min) << "\n" // best I can think of
|
|
|
|
<< "age=0\n"
|
|
|
|
<< "revision=" << pat << "\n\n";
|
|
|
|
|
|
|
|
t << "# Is this an already installed library.\n"
|
|
|
|
"installed=yes\n\n"; // ###
|
|
|
|
|
|
|
|
t << "# Files to dlopen/dlpreopen.\n"
|
|
|
|
"dlopen=''\n"
|
|
|
|
"dlpreopen=''\n\n";
|
|
|
|
|
2012-09-06 10:21:38 +00:00
|
|
|
ProString install_dir = project->first("QMAKE_LIBTOOL_LIBDIR");
|
2011-04-27 10:05:43 +00:00
|
|
|
if(install_dir.isEmpty())
|
|
|
|
install_dir = project->first("target.path");
|
|
|
|
if(install_dir.isEmpty())
|
|
|
|
install_dir = project->first("DESTDIR");
|
|
|
|
t << "# Directory that this library needs to be installed in:\n"
|
2012-09-06 10:21:38 +00:00
|
|
|
"libdir='" << Option::fixPathToTargetOS(install_dir.toQString(), false) << "'\n";
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
2019-11-04 14:54:24 +00:00
|
|
|
std::pair<bool, QString> UnixMakefileGenerator::writeObjectsPart(QTextStream &t, bool do_incremental)
|
|
|
|
{
|
|
|
|
bool src_incremental = false;
|
|
|
|
QString objectsLinkLine;
|
|
|
|
const ProStringList &objs = project->values("OBJECTS");
|
|
|
|
if (do_incremental) {
|
|
|
|
const ProStringList &incrs = project->values("QMAKE_INCREMENTAL");
|
|
|
|
ProStringList incrs_out;
|
|
|
|
t << "OBJECTS = ";
|
|
|
|
for (ProStringList::ConstIterator objit = objs.begin(); objit != objs.end(); ++objit) {
|
|
|
|
bool increment = false;
|
|
|
|
for (ProStringList::ConstIterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) {
|
2020-04-15 08:52:51 +00:00
|
|
|
auto regexp = QRegularExpression::fromWildcard((*incrit).toQString(), Qt::CaseSensitive,
|
|
|
|
QRegularExpression::UnanchoredWildcardConversion);
|
|
|
|
if ((*objit).toQString().contains(regexp)) {
|
2019-11-04 14:54:24 +00:00
|
|
|
increment = true;
|
|
|
|
incrs_out.append((*objit));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!increment)
|
|
|
|
t << "\\\n\t\t" << (*objit);
|
|
|
|
}
|
|
|
|
if (incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done!
|
2019-12-05 09:44:37 +00:00
|
|
|
t << escapeFilePaths(incrs_out).join(QString(" \\\n\t\t")) << Qt::endl;
|
2019-11-04 14:54:24 +00:00
|
|
|
} else if (!incrs_out.count()) {
|
2019-12-05 09:44:37 +00:00
|
|
|
t << Qt::endl;
|
2019-11-04 14:54:24 +00:00
|
|
|
} else {
|
|
|
|
src_incremental = true;
|
2019-12-05 09:44:37 +00:00
|
|
|
t << Qt::endl;
|
2019-11-04 14:54:24 +00:00
|
|
|
t << "INCREMENTAL_OBJECTS = "
|
2019-12-05 09:44:37 +00:00
|
|
|
<< escapeFilePaths(incrs_out).join(QString(" \\\n\t\t")) << Qt::endl;
|
2019-11-04 14:54:24 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const ProString &objMax = project->first("QMAKE_LINK_OBJECT_MAX");
|
|
|
|
// Used all over the place in both deps and commands.
|
|
|
|
if (objMax.isEmpty() || project->values("OBJECTS").count() < objMax.toInt()) {
|
|
|
|
objectsLinkLine = "$(OBJECTS)";
|
|
|
|
} else {
|
2019-12-22 07:36:31 +00:00
|
|
|
const QString ld_response_file = createResponseFile(
|
|
|
|
fileVar("OBJECTS_DIR") + var("QMAKE_LINK_OBJECT_SCRIPT"), objs);
|
2019-11-04 14:54:24 +00:00
|
|
|
objectsLinkLine = "@" + escapeFilePath(ld_response_file);
|
|
|
|
}
|
2019-12-05 09:44:37 +00:00
|
|
|
t << "OBJECTS = " << valList(escapeDependencyPaths(objs)) << Qt::endl;
|
2019-11-04 14:54:24 +00:00
|
|
|
}
|
|
|
|
return std::make_pair(src_incremental, objectsLinkLine);
|
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
QT_END_NAMESPACE
|