author | zecke <zecke> | 2004-07-15 17:36:57 (UTC) |
---|---|---|
committer | zecke <zecke> | 2004-07-15 17:36:57 (UTC) |
commit | 323e9a7472a110b4befba7320540263147505bae (patch) (side-by-side diff) | |
tree | 14c810bdb9c0603a30356b17b4bdf9ccb72741c6 /qmake/generators | |
parent | aa292b322f1ecb43dd8f4e3cd295855730dd9f59 (diff) | |
download | opie-323e9a7472a110b4befba7320540263147505bae.zip opie-323e9a7472a110b4befba7320540263147505bae.tar.gz opie-323e9a7472a110b4befba7320540263147505bae.tar.bz2 |
Manually updatet to qmake1.06a which includes support for precompiled
headers.
Opies 'PRO' keyword was already reintroduced
25 files changed, 4562 insertions, 1958 deletions
diff --git a/qmake/generators/mac/metrowerks_xml.cpp b/qmake/generators/mac/metrowerks_xml.cpp index 125749d..baaeeec 100644 --- a/qmake/generators/mac/metrowerks_xml.cpp +++ b/qmake/generators/mac/metrowerks_xml.cpp @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of MetrowerksMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -43,5 +41,5 @@ #include <stdlib.h> #include <time.h> -#ifdef Q_OS_MAC +#if !defined(QWS) && defined(Q_OS_MAC) #include <Carbon/Carbon.h> #include <sys/types.h> @@ -49,5 +47,4 @@ #endif - MetrowerksMakefileGenerator::MetrowerksMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE) { @@ -608,5 +605,5 @@ MetrowerksMakefileGenerator::init() QString -MetrowerksMakefileGenerator::findTemplate(QString file) +MetrowerksMakefileGenerator::findTemplate(const QString &file) { QString ret; @@ -622,5 +619,5 @@ bool MetrowerksMakefileGenerator::createFork(const QString &f) { -#if defined(Q_OS_MACX) +#if !defined(QWS) && defined(Q_OS_MACX) FSRef fref; FSSpec fileSpec; @@ -665,5 +662,5 @@ MetrowerksMakefileGenerator::fixifyToMacPath(QString &p, QString &v, bool ) if(st_volume.isEmpty()) { st_volume = var("QMAKE_VOLUMENAME"); -#ifdef Q_OS_MAC +#if !defined(QWS) && defined(Q_OS_MACX) if(st_volume.isEmpty()) { uchar foo[512]; @@ -734,5 +731,5 @@ MetrowerksMakefileGenerator::processPrlFiles() QString lib = opt.right(opt.length() - 2), prl; for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { - prl = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::prl_ext; + prl = mdd->local_dir + Option::dir_sep + "lib" + lib; if(processPrlFile(prl)) { if(prl.startsWith(mdd->local_dir)) @@ -752,5 +749,5 @@ MetrowerksMakefileGenerator::processPrlFiles() opt = (*it); QString prl = "/System/Library/Frameworks/" + opt + - ".framework/" + opt + Option::prl_ext; + ".framework/" + opt; if(processPrlFile(prl)) ret = TRUE; diff --git a/qmake/generators/mac/metrowerks_xml.h b/qmake/generators/mac/metrowerks_xml.h index ae3cfae..0aa3615 100644 --- a/qmake/generators/mac/metrowerks_xml.h +++ b/qmake/generators/mac/metrowerks_xml.h @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of MetrowerksMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -35,6 +33,7 @@ ** **********************************************************************/ -#ifndef __METROWERKSMAKE_H__ -#define __METROWERKSMAKE_H__ + +#ifndef __METROWERKS_XML_H__ +#define __METROWERKS_XML_H__ #include "makefile.h" @@ -51,5 +50,5 @@ class MetrowerksMakefileGenerator : public MakefileGenerator bool writeMakefile(QTextStream &); - QString findTemplate(QString file); + QString findTemplate(const QString &file); void init(); public: @@ -67,3 +66,3 @@ inline MetrowerksMakefileGenerator::~MetrowerksMakefileGenerator() { } -#endif /* __METROWERKSMAKE_H__ */ +#endif /* __METROWERKS_XML_H__ */ diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index b46005b..9d1286e 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of ProjectBuilderMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -38,4 +36,5 @@ #include "pbuilder_pbx.h" #include "option.h" +#include "meta.h" #include <qdir.h> #include <qdict.h> @@ -43,4 +42,5 @@ #include <stdlib.h> #include <time.h> +#include "qtmd5.h" #ifdef Q_OS_UNIX # include <sys/types.h> @@ -50,5 +50,4 @@ // Note: this is fairly hacky, but it does the job... - ProjectBuilderMakefileGenerator::ProjectBuilderMakefileGenerator(QMakeProject *p) : UnixMakefileGenerator(p) { @@ -68,14 +67,208 @@ ProjectBuilderMakefileGenerator::writeMakefile(QTextStream &t) project->variables()["MAKEFILE"].clear(); project->variables()["MAKEFILE"].append("Makefile"); - if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") { + if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") return writeMakeParts(t); - } else if(project->first("TEMPLATE") == "subdirs") { - writeSubdirs(t, FALSE); - return TRUE; - } + else if(project->first("TEMPLATE") == "subdirs") + return writeSubdirs(t, FALSE); return FALSE; } bool +ProjectBuilderMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) +{ + QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"), + QDir::currentDirPath()); + QFile mkwrapf(mkwrap); + if(mkwrapf.open(IO_WriteOnly | IO_Translate)) { + debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1()); + QTextStream mkwrapt(&mkwrapf); + UnixMakefileGenerator::writeSubdirs(mkwrapt, direct); + } + + //HEADER + t << "// !$*UTF8*$!" << "\n" + << "{" << "\n" + << "\t" << "archiveVersion = 1;" << "\n" + << "\t" << "classes = {" << "\n" << "\t" << "};" << "\n" + << "\t" << "objectVersion = " << pbuilderVersion() << ";" << "\n" + << "\t" << "objects = {" << endl; + + //SUBDIRS + QStringList subdirs = project->variables()["SUBDIRS"]; + QString oldpwd = QDir::currentDirPath(); + QMap<QString, QStringList> groups; + for(QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it) { + QFileInfo fi(Option::fixPathToLocalOS((*it), TRUE)); + if(fi.exists()) { + if(fi.isDir()) { + QString profile = (*it); + if(!profile.endsWith(Option::dir_sep)) + profile += Option::dir_sep; + profile += fi.baseName() + ".pro"; + subdirs.append(profile); + } else { + QMakeProject tmp_proj; + QString dir = fi.dirPath(), fn = fi.fileName(); + if(!dir.isEmpty()) { + if(!QDir::setCurrent(dir)) + fprintf(stderr, "Cannot find directory: %s\n", dir.latin1()); + } + if(tmp_proj.read(fn, oldpwd)) { + if(Option::debug_level) { + QMap<QString, QStringList> &vars = tmp_proj.variables(); + for(QMap<QString, QStringList>::Iterator it = vars.begin(); + it != vars.end(); ++it) { + if(it.key().left(1) != "." && !it.data().isEmpty()) + debug_msg(1, "%s: %s === %s", fn.latin1(), it.key().latin1(), + it.data().join(" :: ").latin1()); + } + } + if(tmp_proj.first("TEMPLATE") == "subdirs") { + subdirs += fileFixify(tmp_proj.variables()["SUBDIRS"]); + } else if(tmp_proj.first("TEMPLATE") == "app" || tmp_proj.first("TEMPLATE") == "lib") { + QString pbxproj = QDir::currentDirPath() + Option::dir_sep + tmp_proj.first("TARGET") + projectSuffix(); + if(!QFile::exists(pbxproj)) { + warn_msg(WarnLogic, "Ignored (not found) '%s'", pbxproj.latin1()); + goto nextfile; // # Dirty! + } + project->variables()["QMAKE_PBX_SUBDIRS"] += pbxproj; + //PROJECTREF + { + bool in_root = TRUE; + QString name = QDir::currentDirPath(); + QString project_key = keyFor(pbxproj + "_PROJECTREF"); + if(project->isActiveConfig("flat")) { + QString flat_file = fileFixify(name, oldpwd, Option::output_dir, TRUE); + if(flat_file.find(Option::dir_sep) != -1) { + QStringList dirs = QStringList::split(Option::dir_sep, flat_file); + name = dirs.back(); + } + } else { + QString flat_file = fileFixify(name, oldpwd, Option::output_dir, TRUE); + if(QDir::isRelativePath(flat_file) && flat_file.find(Option::dir_sep) != -1) { + QString last_grp("QMAKE_PBX_HEIR_GROUP"); + QStringList dirs = QStringList::split(Option::dir_sep, flat_file); + name = dirs.back(); + for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { + QString new_grp(last_grp + Option::dir_sep + (*dir_it)), new_grp_key(keyFor(new_grp)); + if(dir_it == dirs.begin()) { + if(!groups.contains(new_grp)) + project->variables()["QMAKE_PBX_GROUPS"].append(new_grp_key); + } else { + if(!groups[last_grp].contains(new_grp_key)) + groups[last_grp] += new_grp_key; + } + last_grp = new_grp; + } + groups[last_grp] += project_key; + in_root = FALSE; + } + } + if(in_root) + project->variables()["QMAKE_PBX_GROUPS"] += project_key; + t << "\t\t" << project_key << " = {" << "\n" + << "\t\t\t" << "isa = PBXFileReference;" << "\n" + << "\t\t\t" << "name = " << tmp_proj.first("TARGET") << ";" << "\n" + << "\t\t\t" << "path = " << pbxproj << ";" << "\n" + << "\t\t\t" << "refType = 0;" << "\n" + << "\t\t\t" << "sourceTree = \"<absolute>\";" << "\n" + << "\t\t" << "};" << "\n"; + //PRODUCTGROUP + t << "\t\t" << keyFor(pbxproj + "_PRODUCTGROUP") << " = {" << "\n" + << "\t\t\t" << "children = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXGroup;" << "\n" + << "\t\t\t" << "name = Products;" << "\n" + << "\t\t\t" << "refType = 4;" << "\n" + << "\t\t\t" << "sourceTree = \"<group>\";" << "\n" + << "\t\t" << "};" << "\n"; + } + } + } +nextfile: + QDir::setCurrent(oldpwd); + } + } + } + for(QMap<QString, QStringList>::Iterator grp_it = groups.begin(); grp_it != groups.end(); ++grp_it) { + t << "\t\t" << keyFor(grp_it.key()) << " = {" << "\n" + << "\t\t\t" << "isa = PBXGroup;" << "\n" + << "\t\t\t" << "children = (" << "\n" + << valGlue(grp_it.data(), "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "name = \"" << grp_it.key().section(Option::dir_sep, -1) << "\";" << "\n" + << "\t\t\t" << "refType = 4;" << "\n" + << "\t\t" << "};" << "\n"; + } + + //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER + //BUILDSTYLE + QString active_buildstyle; +#if 0 + for(int as_release = 0; as_release < 2; as_release++) +#else + bool as_release = !project->isActiveConfig("debug"); +#endif + { + QString key = keyFor("QMAKE_PBX_" + QString(as_release ? "RELEASE" : "DEBUG")); + if(project->isActiveConfig("debug") != as_release) + active_buildstyle = key; + project->variables()["QMAKE_PBX_BUILDSTYLES"].append(key); + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << "buildRules = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n" + << "\t\t\t\t" << "COPY_PHASE_STRIP = " << (as_release ? "YES" : "NO") << ";" << "\n"; + if(as_release) + t << "\t\t\t\t" << "DEBUGGING_SYMBOLS = NO;" << "\n"; + t << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "isa = PBXBuildStyle;" << "\n" + << "\t\t\t" << "name = " << (as_release ? "Deployment" : "Development") << ";" << "\n" + << "\t\t" << "};" << "\n"; + } + + //ROOT_GROUP + t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {" << "\n" + << "\t\t\t" << "children = (" << "\n" + << varGlue("QMAKE_PBX_GROUPS", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXGroup;" << "\n" + << "\t\t\t" << "refType = 4;" << "\n" + << "\t\t\t" << "sourceTree = \"<group>\";" << "\n" + << "\t\t" << "};" << "\n"; + + //ROOT + t << "\t\t" << keyFor("QMAKE_PBX_ROOT") << " = {" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n" + << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "buildStyles = (" << "\n" + << varGlue("QMAKE_PBX_BUILDSTYLES", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXProject;" << "\n" + << "\t\t\t" << "mainGroup = " << keyFor("QMAKE_PBX_ROOT_GROUP") << ";" << "\n" + << "\t\t\t" << "projectDirPath = \"\";" << "\n" + << "\t\t\t" << "projectReferences = (" << "\n"; + { + QStringList &libdirs = project->variables()["QMAKE_PBX_SUBDIRS"]; + for(QStringList::Iterator it = libdirs.begin(); it != libdirs.end(); ++it) + t << "\t\t\t\t" << "{" << "\n" + << "\t\t\t\t\t" << "ProductGroup = " << keyFor((*it) + "_PRODUCTGROUP") << ";" << "\n" + << "\t\t\t\t\t" << "ProjectRef = " << keyFor((*it) + "_PROJECTREF") << ";" << "\n" + << "\t\t\t\t" << "}," << "\n"; + } + t << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "targets = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t" << "};" << "\n"; + + //FOOTER + t << "\t" << "};" << "\n" + << "\t" << "rootObject = " << keyFor("QMAKE_PBX_ROOT") << ";" << "\n" + << "}" << endl; + + return TRUE; +} + +bool ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) { @@ -108,5 +301,5 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString phase_key = keyFor("QMAKE_PBX_MAKEQMAKE_BUILDPHASE"); mkfile = fileFixify(mkfile, QDir::currentDirPath()); - project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key); + project->variables()["QMAKE_PBX_PRESCRIPT_BUILDPHASES"].append(phase_key); t << "\t\t" << phase_key << " = {" << "\n" << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" @@ -127,58 +320,116 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) //DUMP SOURCES QMap<QString, QStringList> groups; - QString srcs[] = { "SOURCES", "SRCMOC", "UICIMPLS", QString::null }; + QString srcs[] = { "HEADERS", "SOURCES", "SRCMOC", "UICIMPLS", "QMAKE_IMAGE_COLLECTION", + "FORMS", "QMAKE_INTERNAL_INCLUDED_FILES", QString::null }; for(i = 0; !srcs[i].isNull(); i++) { tmp = project->variables()[srcs[i]]; + if(srcs[i] == "QMAKE_INTERNAL_INCLUDED_FILES") { + QString pfile = project->projectFile(); + if(pfile != "(stdin)") + tmp.prepend(pfile); + } QStringList &src_list = project->variables()["QMAKE_PBX_" + srcs[i]]; + QStringList &root_group_list = project->variables()["QMAKE_PBX_GROUPS"]; + + //hard coded groups.. + QString src_group; + if(srcs[i] == "SOURCES") + src_group = "Sources"; + else if(srcs[i] == "HEADERS") + src_group = "Headers"; + else if(srcs[i] == "SRCMOC") + src_group = "Sources [moc]"; + else if(srcs[i] == "UICIMPLS" || srcs[i] == "FORMS") + src_group = "Sources [uic]"; + else if(srcs[i] == "QMAKE_IMAGE_COLLECTION") + src_group = "Sources [images]"; + else if(srcs[i] == "QMAKE_INTERNAL_INCLUDED_FILES") + src_group = "Sources [qmake]"; + for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) { - QString file = fileFixify((*it)); - if(file.endsWith(Option::moc_ext)) - continue; - bool in_root = TRUE; - QString src_key = keyFor(file); - if(!project->isActiveConfig("flat")) { - QString flat_file = fileFixify(file, QDir::currentDirPath(), Option::output_dir, TRUE); - if(QDir::isRelativePath(flat_file) && flat_file.find(Option::dir_sep) != -1) { - QString last_grp("QMAKE_PBX_" + srcs[i] + "_HEIR_GROUP"); - QStringList dirs = QStringList::split(Option::dir_sep, flat_file); - dirs.pop_back(); //remove the file portion as it will be added via src_key - for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { - QString new_grp(last_grp + Option::dir_sep + (*dir_it)), - new_grp_key(keyFor(new_grp)), last_grp_key(keyFor(last_grp)); - if(dir_it == dirs.begin()) { - if(!groups.contains(new_grp)) - project->variables()["QMAKE_PBX_" + srcs[i]].append(new_grp_key); - } else { - groups[last_grp] += new_grp_key; + QStringList files = (*it); + bool buildable = TRUE; + if(srcs[i] == "FORMS") { + QString form_dot_h = (*it) + Option::h_ext.first(); + if(QFile::exists(form_dot_h)) + files += form_dot_h; + buildable = FALSE; + } else if(srcs[i] == "HEADERS" || srcs[i] == "QMAKE_INTERNAL_INCLUDED_FILES") { + buildable = FALSE; + } + + files = fileFixify(files); + for(QStringList::Iterator file_it = files.begin(); file_it != files.end(); ++file_it) { + QString file = (*file_it); + if(file.length() >= 2 && (file[0] == '"' || file[0] == '\'') && file[(int) file.length()-1] == file[0]) + file = file.mid(1, file.length()-2); + if(file.endsWith(Option::cpp_moc_ext) || file.endsWith(Option::prl_ext)) + continue; + bool in_root = TRUE; + QString src_key = keyFor(file), name = file; + if(project->isActiveConfig("flat")) { + QString flat_file = fileFixify(file, QDir::currentDirPath(), Option::output_dir, TRUE); + if(flat_file.find(Option::dir_sep) != -1) { + QStringList dirs = QStringList::split(Option::dir_sep, flat_file); + name = dirs.back(); + } + } else { + QString flat_file = fileFixify(file, QDir::currentDirPath(), Option::output_dir, TRUE); + if(QDir::isRelativePath(flat_file) && flat_file.find(Option::dir_sep) != -1) { + QString last_grp("QMAKE_PBX_" + src_group + "_HEIR_GROUP"); + QStringList dirs = QStringList::split(Option::dir_sep, flat_file); + name = dirs.back(); + dirs.pop_back(); //remove the file portion as it will be added via src_key + for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { + QString new_grp(last_grp + Option::dir_sep + (*dir_it)), new_grp_key(keyFor(new_grp)); + if(dir_it == dirs.begin()) { + if(!src_list.contains(new_grp_key)) + src_list.append(new_grp_key); + } else { + if(!groups[last_grp].contains(new_grp_key)) + groups[last_grp] += new_grp_key; + } + last_grp = new_grp; + } + groups[last_grp] += src_key; + in_root = FALSE; + } + } + if(in_root) + src_list.append(src_key); + //source reference + t << "\t\t" << src_key << " = {" << "\n" + << "\t\t\t" << "isa = PBXFileReference;" << "\n" + << "\t\t\t" << "name = \"" << name << "\";" << "\n" + << "\t\t\t" << "path = \"" << file << "\";" << "\n" + << "\t\t\t" << "refType = " << reftypeForFile(file) << ";" << "\n"; + if (ideType() == MAC_XCODE) { + QString filetype; + for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { + if(file.endsWith((*cppit))) { + filetype = "sourcecode.cpp.cpp"; + break; } - last_grp = new_grp; } - groups[last_grp] += src_key; - in_root = FALSE; + if(!filetype.isNull()) + t << "\t\t\t" << "lastKnownFileType = " << filetype << ";" << "\n"; + } + t << "\t\t" << "};" << "\n"; + if(buildable) { //build reference + QString obj_key = file + ".o"; + obj_key = keyFor(obj_key); + t << "\t\t" << obj_key << " = {" << "\n" + << "\t\t\t" << "fileRef = " << src_key << ";" << "\n" + << "\t\t\t" << "isa = PBXBuildFile;" << "\n" + << "\t\t\t" << "settings = {" << "\n" + << "\t\t\t\t" << "ATTRIBUTES = (" << "\n" + << "\t\t\t\t" << ");" << "\n" + << "\t\t\t" << "};" << "\n" + << "\t\t" << "};" << "\n"; + project->variables()["QMAKE_PBX_OBJ"].append(obj_key); } } - if(in_root) - src_list.append(src_key); - //source reference - t << "\t\t" << src_key << " = {" << "\n" - << "\t\t\t" << "isa = PBXFileReference;" << "\n" - << "\t\t\t" << "path = \"" << file << "\";" << "\n" - << "\t\t\t" << "refType = " << reftypeForFile(file) << ";" << "\n" - << "\t\t" << "};" << "\n"; - //build reference - QString obj_key = file + ".o"; - obj_key = keyFor(obj_key); - t << "\t\t" << obj_key << " = {" << "\n" - << "\t\t\t" << "fileRef = " << src_key << ";" << "\n" - << "\t\t\t" << "isa = PBXBuildFile;" << "\n" - << "\t\t\t" << "settings = {" << "\n" - << "\t\t\t\t" << "ATTRIBUTES = (" << "\n" - << "\t\t\t\t" << ");" << "\n" - << "\t\t\t" << "};" << "\n" - << "\t\t" << "};" << "\n"; - project->variables()["QMAKE_PBX_OBJ"].append(obj_key); } if(!src_list.isEmpty()) { - QString grp; if(srcs[i] == "SOURCES") { if(project->first("TEMPLATE") == "app" && !project->isEmpty("RC_FILE")) { //Icon @@ -197,24 +448,13 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t" << "};" << "\n"; } - grp = "Sources"; - } else if(srcs[i] == "SRCMOC") { - grp = "Mocables"; - } else if(srcs[i] == "UICIMPLS") { - grp = "UICables"; } - QString grp_key = keyFor(grp); - project->variables()["QMAKE_PBX_GROUPS"].append(grp_key); - t << "\t\t" << grp_key << " = {" << "\n" - << "\t\t\t" << "children = (" << "\n" - << varGlue("QMAKE_PBX_" + srcs[i], "\t\t\t\t", ",\n\t\t\t\t", "\n") - << "\t\t\t" << ");" << "\n" - << "\t\t\t" << "isa = PBXGroup;" << "\n" - << "\t\t\t" << "name = " << grp << ";" << "\n" - << "\t\t\t" << "refType = 4;" << "\n" - << "\t\t" << "};" << "\n"; + + QString src_group_key = keyFor(src_group); + if(root_group_list.findIndex(src_group_key) == -1) + root_group_list += src_group_key; + groups[src_group] += src_list; } } - for(QMap<QString, QStringList>::Iterator grp_it = groups.begin(); - grp_it != groups.end(); ++grp_it) { + for(QMap<QString, QStringList>::Iterator grp_it = groups.begin(); grp_it != groups.end(); ++grp_it) { t << "\t\t" << keyFor(grp_it.key()) << " = {" << "\n" << "\t\t\t" << "isa = PBXGroup;" << "\n" @@ -237,6 +477,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QTextStream mkt(&mkf); writeHeader(mkt); - mkt << "MOC = " << var("QMAKE_MOC") << endl; - mkt << "UIC = " << var("QMAKE_UIC") << endl; + mkt << "MOC = " << Option::fixPathToTargetOS(var("QMAKE_MOC")) << endl; + mkt << "UIC = " << Option::fixPathToTargetOS(var("QMAKE_UIC")) << endl; mkt << "LEX = " << var("QMAKE_LEX") << endl; mkt << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl; @@ -246,4 +486,5 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) mkt << "MOVE = " << var("QMAKE_MOVE") << endl << endl; mkt << "FORMS = " << varList("UICIMPLS") << endl; + mkt << "IMAGES = " << varList("QMAKE_IMAGE_COLLECTION") << endl; mkt << "MOCS = " << varList("SRCMOC") << endl; mkt << "PARSERS ="; @@ -265,6 +506,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } mkt << "\n"; - mkt << "preprocess: $(FORMS) $(MOCS) $(PARSERS)" << endl; - mkt << "preprocess_clean: mocclean uiclean parser_clean" << endl << endl; + mkt << "preprocess: $(FORMS) $(MOCS) $(PARSERS) $(IMAGES)" << endl; + mkt << "clean preprocess_clean: mocclean uiclean parser_clean" << endl << endl; mkt << "mocclean:" << "\n"; if(!project->isEmpty("SRCMOC")) @@ -273,4 +514,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("UICIMPLS")) mkt << "\t-rm -f $(FORMS)" << "\n"; + if(!project->isEmpty("QMAKE_IMAGE_COLLECTION")) + mkt << "\t-rm -f $(IMAGES)" << "\n"; mkt << "parser_clean:" << "\n"; if(!project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES")) @@ -282,34 +525,29 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) writeYaccSrc(mkt, "YACCSOURCES"); writeLexSrc(mkt, "LEXSOURCES"); + writeImageSrc(mkt, "QMAKE_IMAGE_COLLECTION"); mkf.close(); } - QString target_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET"); mkfile = fileFixify(mkfile, QDir::currentDirPath()); - t << "\t\t" << target_key << " = {" << "\n" - << "\t\t\t" << "buildArgumentsString = \"-f " << mkfile << "\";" << "\n" - << "\t\t\t" << "buildPhases = (" << "\n" + QString phase_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET"); +// project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key); + project->variables()["QMAKE_PBX_PRESCRIPT_BUILDPHASES"].append(phase_key); + t << "\t\t" << phase_key << " = {" << "\n" + << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" + << "\t\t\t" << "files = (" << "\n" << "\t\t\t" << ");" << "\n" - << "\t\t\t" << "buildSettings = {" << "\n" - << "\t\t\t" << "};" << "\n" - << "\t\t\t" << "buildToolPath = \"/usr/bin/gnumake\";"<< "\n" - << "\t\t\t" << "buildWorkingDirectory = \"" << QDir::currentDirPath() << "\";" << "\n" - << "\t\t\t" << "dependencies = (" << "\n" + << "\t\t\t" << "generatedFileNames = (" << "\n" + << varGlue("QMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n") << "\t\t\t" << ");" << "\n" - << "\t\t\t" << "isa = PBXLegacyTarget;" << "\n" - << "\t\t\t" << "name = QtPreprocessors;" << "\n" - << "\t\t\t" << "productName = QtPreprocessors;" << "\n" - << "\t\t\t" << "settingsToExpand = 6;" << "\n" - << "\t\t\t" << "settingsToPassInEnvironment = 287;" << "\n" - << "\t\t\t" << "settingsToPassOnCommandLine = 280;" << "\n" - << "\t\t\t" << "shouldsUseHeadermap = 0;" << "\n" + << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n" + << "\t\t\t" << "name = \"Qt Preprocessors\";" << "\n" + << "\t\t\t" << "neededFileNames = (" << "\n" + << varGlue("QMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "shellPath = /bin/sh;" << "\n" + << "\t\t\t" << "shellScript = \"make -C " << QDir::currentDirPath() << + " -f " << mkfile << "\";" << "\n" << "\t\t" << "};" << "\n"; + } - QString target_depend_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET_DEPEND"); - project->variables()["QMAKE_PBX_TARGETDEPENDS"].append(target_depend_key); - t << "\t\t" << target_depend_key << " = {" << "\n" - << "\t\t\t" << "isa = PBXTargetDependency;" << "\n" - << "\t\t\t" << "target = " << target_key << ";" << "\n" - << "\t\t" << "};" << "\n"; - } //SOURCE BUILDPHASE if(!project->isEmpty("QMAKE_PBX_OBJ")) { @@ -328,5 +566,5 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES QStringList &libdirs = project->variables()["QMAKE_PBX_LIBPATHS"]; - QString libs[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null }; + QString libs[] = { "QMAKE_LFLAGS", "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null }; for(i = 0; !libs[i].isNull(); i++) { tmp = project->variables()[libs[i]]; @@ -334,8 +572,13 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) bool remove = FALSE; QString library, name, opt = (*it).stripWhiteSpace(); + if(opt.length() >= 2 && (opt[0] == '"' || opt[0] == '\'') && opt[(int) opt.length()-1] == opt[0]) + opt = opt.mid(1, opt.length()-2); if(opt.startsWith("-L")) { QString r = opt.right(opt.length() - 2); fixEnvVariables(r); libdirs.append(r); + } else if(opt == "-prebind") { + project->variables()["QMAKE_DO_PREBINDING"].append("TRUE"); + remove = TRUE; } else if(opt.startsWith("-l")) { name = opt.right(opt.length() - 2); @@ -343,5 +586,5 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) for(QStringList::Iterator lit = libdirs.begin(); lit != libdirs.end(); ++lit) { if(project->isActiveConfig("link_prl")) { - /* This isn't real nice, but it is real useful. This looks in a prl + /* This isn't real nice, but it is real usefull. This looks in a prl for what the library will ultimately be called so we can stick it in the ProjectFile. If the prl format ever changes (not likely) then @@ -350,16 +593,15 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) things in days to come? --Sam */ - QString prl_file = (*lit) + Option::dir_sep + lib + Option::prl_ext; - if(QFile::exists(prl_file)) { - QMakeProject proj; - if(proj.read(prl_file, QDir::currentDirPath())) { - if(!proj.isEmpty("QMAKE_PRL_TARGET")) { - library = (*lit) + Option::dir_sep + proj.first("QMAKE_PRL_TARGET"); + QString lib_file = (*lit) + Option::dir_sep + lib; + if(QMakeMetaInfo::libExists(lib_file)) { + QMakeMetaInfo libinfo; + if(libinfo.readLib(lib_file)) { + if(!libinfo.isEmpty("QMAKE_PRL_TARGET")) { + library = (*lit) + Option::dir_sep + libinfo.first("QMAKE_PRL_TARGET"); debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)", - opt.latin1(), prl_file.latin1(), library.latin1()); + opt.latin1(), lib_file.latin1(), library.latin1()); remove = TRUE; } } - } } @@ -393,4 +635,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } } + } else if(opt == "-undefined") { + ++it; //the next option is not a library.. } else if(opt.left(1) != "-") { remove = TRUE; @@ -454,5 +698,5 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString phase_key = keyFor("QMAKE_PBX_SUBLIBS_BUILDPHASE"); mkfile = fileFixify(mkfile, QDir::currentDirPath()); - project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key); + project->variables()["QMAKE_PBX_PRESCRIPT_BUILDPHASES"].append(phase_key); t << "\t\t" << phase_key << " = {" << "\n" << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" @@ -499,6 +743,5 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t" << "};" << "\n"; } - if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console") && - project->first("TEMPLATE") == "app") { //BUNDLE RESOURCES + if(!project->isActiveConfig("console") && project->first("TEMPLATE") == "app") { //BUNDLE RESOURCES QString grp("Bundle Resources"), key = keyFor(grp); project->variables()["QMAKE_PBX_BUILDPHASES"].append(key); @@ -512,19 +755,4 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t" << "};" << "\n"; } - - //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER - //PRODUCTS - { - QString grp("Products"), key = keyFor(grp); - project->variables()["QMAKE_PBX_GROUPS"].append(key); - t << "\t\t" << key << " = {" << "\n" - << "\t\t\t" << "children = (" << "\n" - << "\t\t\t\t" << keyFor("QMAKE_PBX_REFERENCE") << "\n" - << "\t\t\t" << ");" << "\n" - << "\t\t\t" << "isa = PBXGroup;" << "\n" - << "\t\t\t" << "name = Products;" << "\n" - << "\t\t\t" << "refType = 4;" << "\n" - << "\t\t" << "};" << "\n"; - } { //INSTALL BUILDPHASE (sh script) QString targ = project->first("TARGET"); @@ -541,5 +769,5 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) targ += ".app"; - } else if(!project->isActiveConfig("staticlib") && + } else if(!project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin") && !project->isActiveConfig("frameworklib")) { QString li[] = { "TARGET_", "TARGET_x", "TARGET_x.y", QString::null }; @@ -560,5 +788,5 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(project->first("TEMPLATE") == "app") { targ = project->first("TARGET"); - if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { + if(!project->isActiveConfig("console")) { targ += ".app"; cpflags += "-r "; @@ -569,22 +797,24 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) else targ = project->first("TARGET_"); - int slsh = targ.findRev(Option::dir_sep); - if(slsh != -1) - targ = targ.right(targ.length() - slsh - 1); } - QTextStream sht(&shf); + int slsh = targ.findRev(Option::dir_sep); + if(slsh != -1) + targ = targ.right(targ.length() - slsh - 1); + QString dstdir = project->first("DESTDIR"); fixEnvVariables(dstdir); + QTextStream sht(&shf); sht << "#!/bin/sh" << endl; //copy the actual target - sht << "OUT_TARG=\"" << targ << "\"\n" - << "[ -z \"$BUILD_ROOT\" ] || OUT_TARG=\"${BUILD_ROOT}/${OUT_TARG}\"" << endl; - sht << "[ \"$OUT_TARG\" = \"" + sht << "OUT_TARG=\"${TARGET_BUILD_DIR}/${FULL_PRODUCT_NAME}\"\n" + << "if [ -e \"$OUT_TARG\" ]; then" << "\n" + << " [ \"$OUT_TARG\" = \"" << (dstdir.isEmpty() ? QDir::currentDirPath() + QDir::separator(): dstdir) << targ << "\" ] || " << "[ \"$OUT_TARG\" = \"" << targ << "\" ] || " - << "cp -r \"$OUT_TARG\" " << "\"" << dstdir << targ << "\"" << endl; + << "cp -r \"$OUT_TARG\" " << "\"" << dstdir << targ << "\"" << "\n" + << "fi" << endl; //rename as a framework - if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("frameworklib")) + if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("frameworklib") && !project->isActiveConfig("plugin")) sht << "ln -sf \"" << targ << "\" " << "\"" << dstdir << targ << "\"" << endl; //create all the version symlinks (just to be like unixmake) @@ -601,5 +831,5 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key); t << "\t\t" << phase_key << " = {" << "\n" - << "\t\t\t" << "buildActionMask = 8;" << "\n" //only on install! + << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" << "\t\t\t" << "files = (" << "\n" << "\t\t\t" << ");" << "\n" @@ -615,4 +845,43 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } } + if(/*ideType() == MAC_XCODE &&*/ !project->isEmpty("QMAKE_PBX_PRESCRIPT_BUILDPHASES") && 0) { + // build reference + t << "\t\t" << keyFor("QMAKE_PBX_PRESCRIPT_BUILDREFERENCE") << " = {" << "\n" + << "\t\t\t" << "includeInIndex = 0;" << "\n" + << "\t\t\t" << "isa = PBXFileReference;" << "\n" + << "\t\t\t" << "path = preprocessor.out;" << "\n" + << "\t\t\t" << "refType = 3;" << "\n" + << "\t\t\t" << "sourceTree = BUILT_PRODUCTS_DIR;" << "\n" + << "\t\t" << "};" << "\n"; + project->variables()["QMAKE_PBX_PRODUCTS"].append(keyFor("QMAKE_PBX_PRESCRIPTS_BUILDREFERENCE")); + //build phase + QString prescript_key = keyFor("QMAKE_PBX_PRESCRIPTS_BUILDPHASE"); + project->variables()["QMAKE_PBX_TARGETS"].append(prescript_key); + t << "\t\t" << prescript_key << " = {" << "\n" + << "\t\t\t" << "buildPhases = (" << "\n" + << varGlue("QMAKE_PBX_PRESCRIPT_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "buildRules = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n" + << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "dependencies = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXNativeTarget;" << "\n" + << "\t\t\t" << "name = \"Qt Preprocessor Steps\";" << "\n" + << "\t\t\t" << "productName = \"Qt Preprocessor Steps\";" << "\n" + << "\t\t\t" << "productReference = " << keyFor("QMAKE_PBX_PRESCRIPTS_BUILDREFERENCE") << ";" << "\n" + << "\t\t\t" << "productType = \"com.apple.product-type.tool\";" << "\n" + << "\t\t" << "};" << "\n"; + //dependency + t << "\t\t" << keyFor("QMAKE_PBX_PRESCRIPTS_DEPENDENCY") << " = {" << "\n" + << "\t\t\t" << "isa = PBXTargetDependency;" << "\n" + << "\t\t\t" << "target = " << keyFor("QMAKE_PBX_PRESCRIPTS_BUILDPHASE") << ";" << "\n" + << "\t\t" << "};" << "\n"; + project->variables()["QMAKE_PBX_TARGET_DEPENDS"].append(keyFor("QMAKE_PBX_PRESCRIPTS_DEPENDENCY")); + project->variables()["QMAKE_PBX_PRESCRIPT_BUILDPHASES"].clear(); //these are already consumed above + } + + //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER //ROOT_GROUP t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {" << "\n" @@ -626,5 +895,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t" << "};" << "\n"; //REFERENCE - t << "\t\t" << keyFor("QMAKE_PBX_REFERENCE") << " = {" << "\n"; + project->variables()["QMAKE_PBX_PRODUCTS"].append(keyFor(pbx_dir + "QMAKE_PBX_REFERENCE")); + t << "\t\t" << keyFor(pbx_dir + "QMAKE_PBX_REFERENCE") << " = {" << "\n" + << "\t\t\t" << "fallbackIsa = PBXFileReference;" << "\n"; if(project->first("TEMPLATE") == "app") { QString targ = project->first("QMAKE_ORIG_TARGET"); @@ -654,14 +925,33 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) lib = lib.right(lib.length() - slsh - 1); t << "\t\t\t" << "isa = PBXLibraryReference;" << "\n" + << "\t\t\t" << "expectedFileType = \"compiled.mach-o.dylib\";" << "\n" << "\t\t\t" << "path = " << lib << ";\n" - << "\t\t\t" << "refType = " << reftypeForFile(lib) << ";" << "\n"; + << "\t\t\t" << "refType = " << 3/*reftypeForFile(lib)*/ << ";" << "\n" + << "\t\t\t" << "sourceTree = BUILT_PRODUCTS_DIR" << ";" << "\n"; } t << "\t\t" << "};" << "\n"; + { //Products group + QString grp("Products"), key = keyFor(grp); + project->variables()["QMAKE_PBX_GROUPS"].append(key); + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << "children = (" << "\n" + << varGlue("QMAKE_PBX_PRODUCTS", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXGroup;" << "\n" + << "\t\t\t" << "name = Products;" << "\n" + << "\t\t\t" << "refType = 4;" << "\n" + << "\t\t" << "};" << "\n"; + } //TARGET - t << "\t\t" << keyFor("QMAKE_PBX_TARGET") << " = {" << "\n" + QString target_key = keyFor("QMAKE_PBX_TARGET"); + project->variables()["QMAKE_PBX_TARGETS"].append(target_key); + t << "\t\t" << target_key << " = {" << "\n" << "\t\t\t" << "buildPhases = (" << "\n" + << varGlue("QMAKE_PBX_PRESCRIPT_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", ",\n") << varGlue("QMAKE_PBX_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", "\n") << "\t\t\t" << ");" << "\n" << "\t\t\t" << "buildSettings = {" << "\n" + << "\t\t\t\t" << "CC = \"" << fixEnvsList("QMAKE_CC") << "\";" << "\n" + << "\t\t\t\t" << "CPLUSPLUS = \"" << fixEnvsList("QMAKE_CXX") << "\";" << "\n" << "\t\t\t\t" << "FRAMEWORK_SEARCH_PATHS = \"\";" << "\n" << "\t\t\t\t" << "HEADER_SEARCH_PATHS = \"" << fixEnvsList("INCLUDEPATH") << " " << fixEnvs(specdir()) << "\";" << "\n" @@ -669,14 +959,44 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t\t" << "OPTIMIZATION_CFLAGS = \"\";" << "\n" << "\t\t\t\t" << "OTHER_CFLAGS = \"" << - fixEnvsList("QMAKE_CFLAGS") << varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") << - varGlue("DEFINES"," -D"," -D","") << "\";" << "\n" + fixEnvsList("QMAKE_CFLAGS") << fixQuotes(varGlue("PRL_EXPORT_DEFINES"," -D"," -D","")) << + fixQuotes(varGlue("DEFINES"," -D"," -D","")) << "\";" << "\n" << "\t\t\t\t" << "LEXFLAGS = \"" << var("QMAKE_LEXFLAGS") << "\";" << "\n" << "\t\t\t\t" << "YACCFLAGS = \"" << var("QMAKE_YACCFLAGS") << "\";" << "\n" << "\t\t\t\t" << "OTHER_CPLUSPLUSFLAGS = \"" << - fixEnvsList("QMAKE_CXXFLAGS") << varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") << - varGlue("DEFINES"," -D"," -D","") << "\";" << "\n" + fixEnvsList("QMAKE_CXXFLAGS") << fixQuotes(varGlue("PRL_EXPORT_DEFINES"," -D"," -D","")) << + fixQuotes(varGlue("DEFINES"," -D"," -D","")) << "\";" << "\n" << "\t\t\t\t" << "OTHER_REZFLAGS = \"\";" << "\n" << "\t\t\t\t" << "SECTORDER_FLAGS = \"\";" << "\n" - << "\t\t\t\t" << "WARNING_CFLAGS = \"\";" << "\n"; + << "\t\t\t\t" << "WARNING_CFLAGS = \"\";" << "\n" + << "\t\t\t\t" << "PREBINDING = " << (project->isEmpty("QMAKE_DO_PREBINDING") ? "NO" : "YES") << ";" << "\n"; + if(!project->isEmpty("PRECOMPILED_HEADER")) { + if (ideType() == MAC_XCODE) { + t << "\t\t\t\t" << "GCC_PRECOMPILE_PREFIX_HEADER = \"YES\";" << "\n" + << "\t\t\t\t" << "GCC_PREFIX_HEADER = \"" << project->first("PRECOMPILED_HEADER") << "\";" << "\n"; + } else { + t << "\t\t\t\t" << "PRECOMPILE_PREFIX_HEADER = \"YES\";" << "\n" + << "\t\t\t\t" << "PREFIX_HEADER = \"" << project->first("PRECOMPILED_HEADER") << "\";" << "\n"; + } + } + if(project->first("TEMPLATE") == "app") { + QString plist = fileFixify(project->first("QMAKE_INFO_PLIST")); + if(plist.isEmpty()) + plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"); + if(QFile::exists(plist)) { + QFile plist_in_file(plist); + if(plist_in_file.open(IO_ReadOnly)) { + QTextStream plist_in(&plist_in_file); + QString plist_in_text = plist_in.read(); + plist_in_text = plist_in_text.replace("@ICON@", (project->isEmpty("RC_FILE") ? QString("") : project->first("RC_FILE").section(Option::dir_sep, -1))); + plist_in_text = plist_in_text.replace("@EXECUTABLE@", project->first("QMAKE_ORIG_TARGET")); + QFile plist_out_file("Info.plist"); + if(plist_out_file.open(IO_WriteOnly | IO_Translate)) { + QTextStream plist_out(&plist_out_file); + plist_out << plist_in_text; + t << "\t\t\t\t" << "INFOPLIST_FILE = \"Info.plist\";" << "\n"; + } + } + } + } #if 1 t << "\t\t\t\t" << "BUILD_ROOT = \"" << QDir::currentDirPath() << "\";" << "\n"; @@ -686,94 +1006,148 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) fixEnvsList("QMAKE_LFLAGS") << " " << fixEnvsList("QMAKE_LIBDIR_FLAGS") << " " << fixEnvsList("QMAKE_LIBS") << "\";" << "\n"; + if(!project->isEmpty("DESTDIR")) { + QString dir = project->first("DESTDIR"); + if (QDir::isRelativePath(dir)) + dir.prepend(QDir::currentDirPath() + Option::dir_sep); + t << "\t\t\t\t" << "INSTALL_DIR = \"" << dir << "\";" << "\n"; + } + if ( project->first("TEMPLATE") == "lib") { + t << "\t\t\t\t" << "INSTALL_PATH = \"" << "\";" << "\n"; + } + if(!project->isEmpty("VERSION") && project->first("VERSION") != "0.0.0") { + t << "\t\t\t\t" << "DYLIB_CURRENT_VERSION = \"" << project->first("VER_MAJ") << "." + << project->first("VER_MIN") << "." << project->first("VER_PAT") << "\";" << "\n"; + if(project->isEmpty("COMPAT_VERSION")) + t << "\t\t\t\t" << "DYLIB_COMPATIBILITY_VERSION = \"" << project->first("VER_MAJ") << "." + << project->first("VER_MIN") << "\";" << "\n"; + } + if(!project->isEmpty("COMPAT_VERSION")) + t << "\t\t\t\t" << "DYLIB_COMPATIBILITY_VERSION = \"" << project->first("COMPAT_VERSION") << "\";" << "\n"; + + if(ideType() == MAC_XCODE) { + if(!project->isEmpty("OBJECTS_DIR")) + t << "\t\t\t\t" << "OBJROOT = \"" << project->first("OBJECTS_DIR") << "\";" << "\n"; + } +#if 0 if(!project->isEmpty("DESTDIR")) - t << "\t\t\t\t" << "INSTALL_PATH = \"" << project->first("DESTDIR") << "\";" << "\n"; - if(!project->isEmpty("VERSION") && project->first("VERSION") != "0.0.0") - t << "\t\t\t\t" << "DYLIB_CURRENT_VERSION = \"" << project->first("VERSION") << "\";" << "\n"; - if(!project->isEmpty("OBJECTS_DIR")) - t << "\t\t\t\t" << "OBJECT_FILE_DIR = \"" << project->first("OBJECTS_DIR") << "\";" << "\n"; + t << "\t\t\t\t" << "SYMROOT = \"" << project->first("DESTDIR") << "\";" << "\n"; + else + t << "\t\t\t\t" << "SYMROOT = \"" << QDir::currentDirPath() << "\";" << "\n"; +#endif if(project->first("TEMPLATE") == "app") { - if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) + if(ideType() == MAC_PBUILDER && !project->isActiveConfig("console")) t << "\t\t\t\t" << "WRAPPER_EXTENSION = app;" << "\n"; t << "\t\t\t\t" << "PRODUCT_NAME = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n"; } else { - QString lib = project->first("QMAKE_ORIG_TARGET"); if(!project->isActiveConfig("plugin") && project->isActiveConfig("staticlib")) { t << "\t\t\t\t" << "LIBRARY_STYLE = STATIC;" << "\n"; - lib = project->first("TARGET"); } else { t << "\t\t\t\t" << "LIBRARY_STYLE = DYNAMIC;" << "\n"; - if(!project->isActiveConfig("frameworklib")) { - if(project->isActiveConfig("plugin")) - lib = project->first("TARGET"); - else - lib = project->first("TARGET_"); - } } - int slsh = lib.findRev(Option::dir_sep); - if(slsh != -1) - lib = lib.right(lib.length() - slsh - 1); + QString lib = project->first("QMAKE_ORIG_TARGET"); + if (!project->isActiveConfig("frameworklib") && !project->isActiveConfig("staticlib")) + lib.prepend("lib"); t << "\t\t\t\t" << "PRODUCT_NAME = " << lib << ";" << "\n"; } tmp = project->variables()["QMAKE_PBX_VARS"]; - for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) - t << "\t\t\t\t" << (*it) << " = \"" << getenv((*it)) << "\";" << "\n"; + for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) { + QString var = (*it), val = getenv(var); + if(!val && var == "TB") + val = "/usr/bin/"; + t << "\t\t\t\t" << var << " = \"" << val << "\";" << "\n"; + } t << "\t\t\t" << "};" << "\n" << "\t\t\t" << "conditionalBuildSettings = {" << "\n" << "\t\t\t" << "};" << "\n" << "\t\t\t" << "dependencies = (" << "\n" - << varGlue("QMAKE_PBX_TARGETDEPENDS", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << varGlue("QMAKE_PBX_TARGET_DEPENDS", "\t\t\t\t", ",\n\t\t\t\t", "\n") << "\t\t\t" << ");" << "\n" - << "\t\t\t" << "productReference = " << keyFor("QMAKE_PBX_REFERENCE") << ";" << "\n" + << "\t\t\t" << "productReference = " << keyFor(pbx_dir + "QMAKE_PBX_REFERENCE") << ";" << "\n" << "\t\t\t" << "shouldUseHeadermap = 1;" << "\n"; + if(ideType() == MAC_XCODE) + t << "\t\t\t" << "isa = PBXNativeTarget;" << "\n"; if(project->first("TEMPLATE") == "app") { - if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { - t << "\t\t\t" << "isa = PBXApplicationTarget;" << "\n" - << "\t\t\t" << "productSettingsXML = " << "\"" << "<?xml version=" - << "\\\"1.0\\\" encoding=" << "\\\"UTF-8\\\"" << "?>" << "\n" - << "\t\t\t\t" << "<!DOCTYPE plist SYSTEM \\\"file://localhost/System/" - << "Library/DTDs/PropertyList.dtd\\\">" << "\n" - << "\t\t\t\t" << "<plist version=\\\"0.9\\\">" << "\n" - << "\t\t\t\t" << "<dict>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundleDevelopmentRegion</key>" << "\n" - << "\t\t\t\t\t" << "<string>English</string>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundleExecutable</key>" << "\n" - << "\t\t\t\t\t" << "<string>" << project->first("QMAKE_ORIG_TARGET") << "</string>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundleIconFile</key>" << "\n" - << "\t\t\t\t\t" << "<string>" << var("RC_FILE").section(Option::dir_sep, -1) << "</string>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundleInfoDictionaryVersion</key>" << "\n" - << "\t\t\t\t\t" << "<string>6.0</string>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundlePackageType</key>" << "\n" - << "\t\t\t\t\t" << "<string>APPL</string>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundleSignature</key>" << "\n" - << "\t\t\t\t\t" << "<string>????</string>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundleVersion</key>" << "\n" - << "\t\t\t\t\t" << "<string>0.1</string>" << "\n" - << "\t\t\t\t\t" << "<key>CSResourcesFileMapped</key>" << "\n" - << "\t\t\t\t\t" << "<true/>" << "\n" - << "\t\t\t\t" << "</dict>" << "\n" - << "\t\t\t\t" << "</plist>" << "\";" << "\n"; + if(project->isActiveConfig("console")) { + if(ideType() == MAC_XCODE) + t << "\t\t\t" << "productType = \"com.apple.product-type.tool\";" << "\n"; + else + t << "\t\t\t" << "isa = PBXToolTarget;" << "\n"; } else { - t << "\t\t\t" << "isa = PBXToolTarget;" << "\n"; + if(ideType() == MAC_XCODE) + t << "\t\t\t" << "productType = \"com.apple.product-type.application\";" << "\n"; + else + t << "\t\t\t" << "isa = PBXApplicationReference;" << "\n"; + t << "\t\t\t" << "productSettingsXML = \""; + bool read_plist = false; + if(QFile::exists("Info.plist")) { + QFile plist("Info.plist"); + if(plist.open(IO_ReadOnly)) { + read_plist = true; + QTextStream stream(&plist); + while(!stream.eof()) + t << stream.readLine().replace('"', "\\\"") << endl; + } + } + if(!read_plist) { + t << "<?xml version=" + << "\\\"1.0\\\" encoding=" << "\\\"UTF-8\\\"" << "?>" << "\n" + << "\t\t\t\t" << "<!DOCTYPE plist SYSTEM \\\"file://localhost/System/" + << "Library/DTDs/PropertyList.dtd\\\">" << "\n" + << "\t\t\t\t" << "<plist version=\\\"0.9\\\">" << "\n" + << "\t\t\t\t" << "<dict>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundleDevelopmentRegion</key>" << "\n" + << "\t\t\t\t\t" << "<string>English</string>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundleExecutable</key>" << "\n" + << "\t\t\t\t\t" << "<string>" << project->first("QMAKE_ORIG_TARGET") << "</string>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundleIconFile</key>" << "\n" + << "\t\t\t\t\t" << "<string>" << var("RC_FILE").section(Option::dir_sep, -1) << "</string>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundleInfoDictionaryVersion</key>" << "\n" + << "\t\t\t\t\t" << "<string>6.0</string>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundlePackageType</key>" << "\n" + << "\t\t\t\t\t" << "<string>APPL</string>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundleSignature</key>" << "\n" + //Although the output below looks strange it is to avoid the trigraph ??< + << "\t\t\t\t\t" << "<string>????" << "</string>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundleVersion</key>" << "\n" + << "\t\t\t\t\t" << "<string>0.1</string>" << "\n" + << "\t\t\t\t\t" << "<key>CSResourcesFileMapped</key>" << "\n" + << "\t\t\t\t\t" << "<true/>" << "\n" + << "\t\t\t\t" << "</dict>" << "\n" + << "\t\t\t\t" << "</plist>"; + } } + t << "\";" << "\n"; t << "\t\t\t" << "name = \"" << project->first("QMAKE_ORIG_TARGET") << "\";" << "\n" << "\t\t\t" << "productName = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n"; } else { QString lib = project->first("QMAKE_ORIG_TARGET"); - if(!project->isActiveConfig("frameworklib")) + if(!project->isActiveConfig("frameworklib") && !project->isActiveConfig("staticlib")) lib.prepend("lib"); - t << "\t\t\t" << "isa = PBXLibraryTarget;" << "\n" - << "\t\t\t" << "name = \"" << lib << "\";" << "\n" + t << "\t\t\t" << "name = \"" << lib << "\";" << "\n" << "\t\t\t" << "productName = " << lib << ";" << "\n"; + if(ideType() == MAC_XCODE) { + if(project->isActiveConfig("staticlib")) + t << "\t\t\t" << "productType = \"com.apple.product-type.library.static\";" << "\n"; + else + t << "\t\t\t" << "productType = \"com.apple.product-type.library.dynamic\";" << "\n"; + } else { + t << "\t\t\t" << "isa = PBXLibraryTarget;" << "\n"; + } } + t << "\t\t\t" << "startupPath = \"<<ProjectDirectory>>\";" << "\n"; if(!project->isEmpty("DESTDIR")) t << "\t\t\t" << "productInstallPath = \"" << project->first("DESTDIR") << "\";" << "\n"; t << "\t\t" << "};" << "\n"; //DEBUG/RELEASE - for(i = 0; i < 2; i++) { - bool as_release = !i; - if(project->isActiveConfig("debug")) - as_release = i; - QString key = "QMAKE_PBX_" + QString(as_release ? "RELEASE" : "DEBUG"); - key = keyFor(key); + QString active_buildstyle; +#if 0 + for(int as_release = 0; as_release < 2; as_release++) +#else + bool as_release = !project->isActiveConfig("debug"); +#endif + { + QString key = keyFor("QMAKE_PBX_" + QString(as_release ? "RELEASE" : "DEBUG")); + if(project->isActiveConfig("debug") != as_release) + active_buildstyle = key; project->variables()["QMAKE_PBX_BUILDSTYLES"].append(key); t << "\t\t" << key << " = {" << "\n" @@ -782,6 +1156,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << "buildSettings = {" << "\n" << "\t\t\t\t" << "COPY_PHASE_STRIP = " << (as_release ? "YES" : "NO") << ";" << "\n"; - if(as_release) + if(as_release) { t << "\t\t\t\t" << "DEBUGGING_SYMBOLS = NO;" << "\n"; + } else { + t << "\t\t\t\t" << "GCC_ENABLE_FIX_AND_CONTINUE = " + << (project->isActiveConfig("no_fix_and_continue") ? "NO" : "YES") << ";" << "\n" + << "\t\t\t\t" << "GCC_GENERATE_DEBUGGING_SYMBOLS = YES;" << "\n" + << "\t\t\t\t" << "GCC_OPTIMIZATION_LEVEL = 0;" << "\n" + << "\t\t\t\t" << "ZERO_LINK =" + << (project->isActiveConfig("no_zero_link") ? "NO" : "YES") << ";" << "\n"; + } t << "\t\t\t" << "};" << "\n" << "\t\t\t" << "isa = PBXBuildStyle;" << "\n" @@ -794,8 +1176,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << varGlue("QMAKE_PBX_BUILDSTYLES", "\t\t\t\t", ",\n\t\t\t\t", "\n") << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "hasScannedForEncodings = 1;" << "\n" << "\t\t\t" << "isa = PBXProject;" << "\n" << "\t\t\t" << "mainGroup = " << keyFor("QMAKE_PBX_ROOT_GROUP") << ";" << "\n" + << "\t\t\t" << "projectDirPath = \"\";" << "\n" << "\t\t\t" << "targets = (" << "\n" - << "\t\t\t\t" << keyFor("QMAKE_PBX_TARGET") << "\n" + << varGlue("QMAKE_PBX_TARGETS", "\t\t\t\t", ",\n\t\t\t\t", "\n") << "\t\t\t" << ");" << "\n" << "\t\t" << "};" << "\n"; @@ -806,24 +1190,26 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "}" << endl; - QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"), - QDir::currentDirPath()); - QFile mkwrapf(mkwrap); - if(mkwrapf.open(IO_WriteOnly | IO_Translate)) { - debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1()); - QTextStream mkwrapt(&mkwrapf); - writeHeader(mkwrapt); - const char *cleans = "uiclean mocclean preprocess_clean "; - mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n" - << "all:" << "\n\t" - << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild") << "\n" - << "install: all" << "\n\t" - << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild install") << "\n" - << "distclean clean: preprocess_clean" << "\n\t" - << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild clean") << "\n" - << (!did_preprocess ? cleans : "") << ":" << "\n"; - if(did_preprocess) - mkwrapt << cleans << ":" << "\n\t" - << "make -f " - << pbx_dir << Option::dir_sep << "qt_preprocess.mak $@" << endl; + if(project->isActiveConfig("generate_pbxbuild_makefile")) { + QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"), + QDir::currentDirPath()); + QFile mkwrapf(mkwrap); + if(mkwrapf.open(IO_WriteOnly | IO_Translate)) { + debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1()); + QTextStream mkwrapt(&mkwrapf); + writeHeader(mkwrapt); + const char *cleans = "uiclean mocclean preprocess_clean "; + mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n" + << "all:" << "\n\t" + << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << "\n" + << "install: all" << "\n\t" + << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " install\n" + << "distclean clean: preprocess_clean" << "\n\t" + << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " clean" << "\n" + << (!did_preprocess ? cleans : "") << ":" << "\n"; + if(did_preprocess) + mkwrapt << cleans << ":" << "\n\t" + << "make -f " + << pbx_dir << Option::dir_sep << "qt_preprocess.mak $@" << endl; + } } return TRUE; @@ -831,5 +1217,13 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString -ProjectBuilderMakefileGenerator::fixEnvs(QString file) +ProjectBuilderMakefileGenerator::fixQuotes(const QString &val) +{ + QString ret(val); + ret = ret.replace(QRegExp("('|\")"), "\\\\1"); + return ret; +} + +QString +ProjectBuilderMakefileGenerator::fixEnvs(const QString &file) { QRegExp reg_var("\\$\\((.*)\\)"); @@ -843,5 +1237,5 @@ ProjectBuilderMakefileGenerator::fixEnvs(QString file) QString -ProjectBuilderMakefileGenerator::fixEnvsList(QString where) +ProjectBuilderMakefileGenerator::fixEnvsList(const QString &where) { QString ret; @@ -857,30 +1251,13 @@ ProjectBuilderMakefileGenerator::fixEnvsList(QString where) QString -ProjectBuilderMakefileGenerator::keyFor(QString block) +ProjectBuilderMakefileGenerator::keyFor(const QString &block) { -#if 0 //This make this code much easier to debug.. - return block; +#if 1 //This make this code much easier to debug.. + if(project->isActiveConfig("no_pb_munge_key")) + return block; #endif - QString ret; if(!keys.contains(block)) { -#if 0 - static unsigned int r = 0; - ret.sprintf("%024x", ++r); -#else //not really necesary, but makes it look more interesting.. - static struct { unsigned int a1, a2, a3; } r = { 0, 0, 0 }; - if(!r.a1 && !r.a2 && !r.a3) { - r.a1 = rand(); - r.a2 = rand(); - r.a3 = rand(); - } - switch(rand() % 3) { - case 0: ++r.a1; break; - case 1: ++r.a2; break; - case 2: ++r.a3; break; - } - ret.sprintf("%08x%08x%08x", r.a1, r.a2, r.a3); -#endif - ret = ret.upper(); + ret = qtMD5(block.utf8()).left(24).upper(); keys.insert(block, ret); } else { @@ -893,26 +1270,25 @@ bool ProjectBuilderMakefileGenerator::openOutput(QFile &file) const { - if(project->first("TEMPLATE") != "subdirs") { - QFileInfo fi(file); - if(fi.extension() != "pbxproj" || file.name().isEmpty()) { - QString output = file.name(); - if(fi.isDir()) - output += QDir::separator(); - if(fi.extension() != "pbproj") { - if(file.name().isEmpty() || fi.isDir()) - output += project->first("TARGET"); - output += QString(".pbproj") + QDir::separator(); - } else if(output[(int)output.length() - 1] != QDir::separator()) { - output += QDir::separator(); - } - output += QString("project.pbxproj"); - file.setName(output); + if(QDir::isRelativePath(file.name())) + file.setName(Option::output_dir + file.name()); //pwd when qmake was run + QFileInfo fi(file); + if(fi.extension() != "pbxproj" || file.name().isEmpty()) { + QString output = file.name(); + if(fi.isDir()) + output += QDir::separator(); + if(!output.endsWith(projectSuffix())) { + if(file.name().isEmpty() || fi.isDir()) + output += project->first("TARGET"); + output += projectSuffix() + QDir::separator(); + } else if(output[(int)output.length() - 1] != QDir::separator()) { + output += QDir::separator(); } - bool ret = UnixMakefileGenerator::openOutput(file); - ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1); - Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2); - return ret; + output += QString("project.pbxproj"); + file.setName(output); } - return UnixMakefileGenerator::openOutput(file); + bool ret = UnixMakefileGenerator::openOutput(file); + ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1); + Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2); + return ret; } @@ -929,8 +1305,12 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const if(project->isEmpty("QMAKE_PBUILDER_VERSION")) { QString version, version_plist = project->first("QMAKE_PBUILDER_VERSION_PLIST"); - if(version_plist.isEmpty()) - version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist"; - else + if(version_plist.isEmpty()) { + if(ideType() == MAC_XCODE && QFile::exists("/Developer/Applications/Xcode.app/Contents/version.plist")) + version_plist = "/Developer/Applications/Xcode.app/Contents/version.plist"; + else + version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist"; + } else { version_plist = version_plist.replace(QRegExp("\""), ""); + } QFile version_file(version_plist); if(version_file.open(IO_ReadOnly)) { @@ -955,9 +1335,13 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const } version_file.close(); - } else debug_msg(1, "pbuilder: version.plist: Failure to open %s", version_plist.latin1()); - if(version.startsWith("2.0")) - ret = "38"; - else if(version == "1.1") - ret = "34"; + } else { debug_msg(1, "pbuilder: version.plist: Failure to open %s", version_plist.latin1()); } + if(version_plist.contains("Xcode")) { + ret = "39"; + } else { + if(version.startsWith("2.")) + ret = "38"; + else if(version == "1.1") + ret = "34"; + } } else { ret = project->first("QMAKE_PBUILDER_VERSION"); @@ -975,9 +1359,38 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const } -QString -ProjectBuilderMakefileGenerator::reftypeForFile(QString where) +int +ProjectBuilderMakefileGenerator::reftypeForFile(const QString &where) { + int ret = 0; //absolute is the default.. if(QDir::isRelativePath(where)) - return "4"; //relative - return "0"; //absolute + ret = 4; //relative + return ret; +} + +ProjectBuilderMakefileGenerator::IDE_TYPE +ProjectBuilderMakefileGenerator::ideType() const +{ + if(!project->isActiveConfig("no_pbx_xcode") && + (QFile::exists("/Developer/Applications/Xcode.app") || project->isActiveConfig("pbx_xcode"))) + return ProjectBuilderMakefileGenerator::MAC_XCODE; + return ProjectBuilderMakefileGenerator::MAC_PBUILDER; +} + +QString +ProjectBuilderMakefileGenerator::projectSuffix() const +{ + if(ideType() == MAC_XCODE) + return ".xcode"; + return ".pbproj"; +} + +QString +ProjectBuilderMakefileGenerator::pbxbuild() +{ + if(QFile::exists("/usr/bin/pbbuild")) + return "pbbuild"; + if(QFile::exists("/usr/bin/xcodebuild")) + return "xcodebuild"; + return (ideType() == MAC_XCODE ? "xcodebuild" : "pbxbuild"); } + diff --git a/qmake/generators/mac/pbuilder_pbx.h b/qmake/generators/mac/pbuilder_pbx.h index ec2e1be..4ffb9a8 100644 --- a/qmake/generators/mac/pbuilder_pbx.h +++ b/qmake/generators/mac/pbuilder_pbx.h @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of ProjectBuilderMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -35,6 +33,7 @@ ** **********************************************************************/ -#ifndef __PBUILDERMAKE_H__ -#define __PBUILDERMAKE_H__ + +#ifndef __PBUILDER_PBX_H__ +#define __PBUILDER_PBX_H__ #include "unixmake.h" @@ -44,12 +43,19 @@ class ProjectBuilderMakefileGenerator : public UnixMakefileGenerator QString pbx_dir; int pbuilderVersion() const; + bool writeSubdirs(QTextStream &, bool); bool writeMakeParts(QTextStream &); bool writeMakefile(QTextStream &); + QString pbxbuild(); QMap<QString, QString> keys; - QString keyFor(QString file); - QString fixEnvs(QString file); - QString fixEnvsList(QString where); - QString reftypeForFile(QString file); + QString keyFor(const QString &file); + QString fixQuotes(const QString &val); + QString fixEnvs(const QString &file); + QString fixEnvsList(const QString &where); + int reftypeForFile(const QString &where); + QString projectSuffix() const; + + enum IDE_TYPE { MAC_XCODE, MAC_PBUILDER }; + IDE_TYPE ideType() const; public: @@ -59,4 +65,5 @@ public: virtual bool openOutput(QFile &) const; protected: + bool doPrecompiledHeaders() const { return FALSE; } virtual bool doDepends() const { return FALSE; } //never necesary }; @@ -66,3 +73,3 @@ inline ProjectBuilderMakefileGenerator::~ProjectBuilderMakefileGenerator() -#endif /* __PBUILDERMAKE_H__ */ +#endif /* __PBUILDER_PBX_H__ */ diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index c12375d..5ce387f 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of MakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -38,4 +36,5 @@ #include "makefile.h" #include "option.h" +#include "meta.h" #include <qdir.h> #include <qfile.h> @@ -59,6 +58,7 @@ #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif +#define QMAKE_EOL(x) (x == '\r' || x == '\n') -static QString mkdir_p_asstring(const QString &dir) +QString mkdir_p_asstring(const QString &dir) { QString ret = "@$(CHK_DIR_EXISTS) \"" + dir + "\" "; @@ -75,5 +75,4 @@ static bool createDir(const QString& fullPath) if(QFile::exists(fullPath)) return FALSE; - QDir dirTmp; bool ret = TRUE; @@ -143,5 +142,5 @@ MakefileGenerator::generateMocList(const QString &fn_target) if(total_size_read >= x) { if(*(big_buffer + x) == '/') { //c++ style comment - for( ;x < total_size_read && *(big_buffer + x) != '\n'; x++); + for( ;x < total_size_read && !QMAKE_EOL(*(big_buffer + x)); x++); line_count++; } else if(*(big_buffer + x) == '*') { //c style comment @@ -161,5 +160,5 @@ MakefileGenerator::generateMocList(const QString &fn_target) break; } - } else if(*(big_buffer + x) == '\n') { + } else if(QMAKE_EOL(*(big_buffer + x))) { line_count++; } @@ -188,5 +187,5 @@ MakefileGenerator::generateMocList(const QString &fn_target) if(interesting) { *(big_buffer+x+len) = '\0'; - debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", fn_target.latin1(), + debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", fn_target.latin1(), line_count, big_buffer+x); @@ -201,5 +200,5 @@ MakefileGenerator::generateMocList(const QString &fn_target) bool cpp_ext = FALSE; - for(QStringList::Iterator cppit = Option::cpp_ext.begin(); + for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { if((cpp_ext = (fn_target.right(ext_len) == (*cppit)))) @@ -207,12 +206,12 @@ MakefileGenerator::generateMocList(const QString &fn_target) } if(cpp_ext) { - mocFile += fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + Option::moc_ext; + mocFile += Option::cpp_moc_mod + fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + Option::cpp_moc_ext; project->variables()["_SRCMOC"].append(mocFile); } else if(project->variables()["HEADERS"].findIndex(fn_target) != -1) { - for(QStringList::Iterator hit = Option::h_ext.begin(); + for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) { if((fn_target.right(ext_len) == (*hit))) { - mocFile += Option::moc_mod + fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + - Option::cpp_ext.first(); + mocFile += Option::h_moc_mod + fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + + Option::h_moc_ext; logicWarn(mocFile, "SOURCES"); project->variables()["_HDRMOC"].append(mocFile); @@ -233,5 +232,5 @@ MakefileGenerator::generateMocList(const QString &fn_target) while(x < total_size_read && SYMBOL_CHAR(*(big_buffer+x))) x++; - if(*(big_buffer+x) == '\n') + if(QMAKE_EOL(*(big_buffer+x))) line_count++; } @@ -244,7 +243,9 @@ bool MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const QString &f, bool recurse) { - QStringList &fndeps = findDependencies(f); - if(!fndeps.isEmpty()) + if(processedDependencies(f)) return TRUE; + setProcessedDependencies(f, TRUE); + + QStringList &fndeps = findDependencies(f); QString fn = fileFixify(f, QDir::currentDirPath(), Option::output_dir); fn = Option::fixPathToLocalOS(fn, FALSE); @@ -284,5 +285,5 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const if(total_size_read >= x) { if(*(big_buffer + x) == '/') { //c++ style comment - for( ; x < total_size_read && *(big_buffer + x) != '\n'; x++); + for( ; x < total_size_read && !QMAKE_EOL(*(big_buffer + x)); x++); } else if(*(big_buffer + x) == '*') { //c style comment for( ; x < total_size_read; x++) { @@ -292,5 +293,5 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const break; } - } else if(*(big_buffer + x) == '\n') { + } else if(QMAKE_EOL(*(big_buffer + x))) { line_count++; } @@ -299,4 +300,7 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const } } + while(x < total_size_read && //Skip spaces + (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t')) + x++; if(*(big_buffer + x) == '#') { x++; @@ -319,5 +323,6 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const int inc_len; - for(inc_len = 0; *(big_buffer + x + inc_len) != term; inc_len++); + for(inc_len = 0; *(big_buffer + x + inc_len) != term && + !QMAKE_EOL(*(big_buffer + x + inc_len)); inc_len++); *(big_buffer + x + inc_len) = '\0'; inc = big_buffer + x; @@ -326,19 +331,21 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const x < total_size_read && (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t'); x++); - char term = '\n'; + char term = 0; if(*(big_buffer + x) == '"') term = '"'; if(*(big_buffer + x) == '\'') term = '\''; - if(term != '\n') + if(term) x++; int msg_len; - for(msg_len = 0; *(big_buffer + x + msg_len) != term; msg_len++); + for(msg_len = 0; (term && *(big_buffer + x + msg_len) != term) && + !QMAKE_EOL(*(big_buffer + x + msg_len)); msg_len++); + const char saved_term = *(big_buffer + x + msg_len); *(big_buffer + x + msg_len) = '\0'; QString msg = big_buffer + x; debug_msg(0, "%s:%d qmake_warning -- %s", fix_env_fn.latin1(), line_count, msg.latin1()); - *(big_buffer + x + msg_len) = term; //put it back + *(big_buffer + x + msg_len) = saved_term; //put it back } } @@ -352,9 +359,29 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const if(total_size_read >= x + 12 && !strncmp(big_buffer + x, "includehint", 11) && (*(big_buffer + x + 11) == ' ' || *(big_buffer + x + 11) == '>')) { - for(x += 12; *(big_buffer + x) != '>'; x++); + for(x += 11; *(big_buffer + x) != '>'; x++); int inc_len = 0; for(x += 1 ; *(big_buffer + x + inc_len) != '<'; inc_len++); *(big_buffer + x + inc_len) = '\0'; inc = big_buffer + x; + } else if(total_size_read >= x + 13 && !strncmp(big_buffer + x, "customwidget", 12) && + (*(big_buffer + x + 12) == ' ' || *(big_buffer + x + 12) == '>')) { + for(x += 13; *(big_buffer + x) != '>'; x++); //skip up to > + while(x < total_size_read) { + for(x++; *(big_buffer + x) != '<'; x++); //skip up to < + x++; + if(total_size_read >= x + 7 && !strncmp(big_buffer+x, "header", 6) && + (*(big_buffer + x + 6) == ' ' || *(big_buffer + x + 6) == '>')) { + for(x += 7; *(big_buffer + x) != '>'; x++); //skip up to > + int inc_len = 0; + for(x += 1 ; *(big_buffer + x + inc_len) != '<'; inc_len++); + *(big_buffer + x + inc_len) = '\0'; + inc = big_buffer + x; + break; + } else if(total_size_read >= x + 14 && !strncmp(big_buffer+x, "/customwidget", 13) && + (*(big_buffer + x + 13) == ' ' || *(big_buffer + x + 13) == '>')) { + x += 14; + break; + } + } } else if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include", 7) && (*(big_buffer + x + 7) == ' ' || *(big_buffer + x + 7) == '>')) { @@ -418,5 +445,4 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const continue; } - QString fqn; if(project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH") && @@ -424,4 +450,8 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const fqn = fndir + inc; goto handle_fqn; + } else if(project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH") && + !stat(inc, &fst) && !S_ISDIR(fst.st_mode)) { + fqn = inc; + goto handle_fqn; } else { if((Option::target_mode == Option::TARG_MAC9_MODE && inc.find(':')) || @@ -447,4 +477,5 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const if(depHeuristics.contains(inc)) { fqn = depHeuristics[inc]; + from_source_dir = FALSE; } else if(Option::mkfile::do_dep_heuristics) { //some heuristics.. //is it a file from a .ui? @@ -467,7 +498,7 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const fqn += Option::dir_sep; fqn += inc_file; - from_source_dir = FALSE; //uics go in the output_dir (so don't fix them) + from_source_dir = FALSE; //uics go in the output_dir (so don't fix them) fqn = fileFixify(fqn, QDir::currentDirPath(), Option::output_dir); - goto handle_fqn; + goto cache_fqn; } } @@ -489,5 +520,7 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const if(s == lhs) { fqn = d + inc; - goto handle_fqn; + from_source_dir = FALSE; //uics go in the output_dir (so don't fix them) + fqn = fileFixify(fqn, QDir::currentDirPath(), Option::output_dir); + goto cache_fqn; } } @@ -510,11 +543,14 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const if(s == lhs) { fqn = d + inc; - goto handle_fqn; + from_source_dir = FALSE; //uics go in the output_dir (so don't fix them) + fqn = fileFixify(fqn, QDir::currentDirPath(), Option::output_dir); + goto cache_fqn; } } } } - if(mocAware() && //is it a moc file? - (inc.endsWith(Option::cpp_ext.first()) || inc.endsWith(Option::moc_ext))) { + if( mocAware() && //is it a moc file? + ( inc.endsWith(Option::cpp_ext.first()) || inc.endsWith(Option::cpp_moc_ext) ) + || ( (Option::cpp_ext.first() != Option::h_moc_ext) && inc.endsWith(Option::h_moc_ext) )) { QString mocs[] = { QString("_HDRMOC"), QString("_SRCMOC"), QString::null }; for(int moc = 0; !mocs[moc].isNull(); moc++) { @@ -528,6 +564,6 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const project->variables()["_SRCMOC"].append((*it)); l.remove(it); - } else if(!findMocSource(fqn).endsWith(fn)) { - /* Not really a very good test, but this will at least avoid + } else if(!findMocSource(fqn).endsWith(fileFixify(fn))) { + /* Not really a very good test, but this will at least avoid confusion if it really does happen (since tmake/qmake previously didn't even allow this the test is mostly accurate) */ @@ -537,9 +573,15 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const } from_source_dir = FALSE; //mocs go in the output_dir (so don't fix them) - goto handle_fqn; + goto cache_fqn; } } } } + fqn = findDependency(inc); //all else fails.. + cache_fqn: + if(from_source_dir) { + fqn = fileFixify(fqn); + from_source_dir = FALSE; + } depHeuristics.insert(inc, fqn); } @@ -556,5 +598,5 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const } //read past new line now.. - for( ; x < total_size_read && (*(big_buffer + x) != '\n'); x++); + for( ; x < total_size_read && !QMAKE_EOL(*(big_buffer + x)); x++); line_count++; } @@ -564,6 +606,6 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const generateDependencies(dirs, (*fnit), recurse); QStringList &deplist = findDependencies((*fnit)); - for(QStringList::Iterator it = deplist.begin(); it != deplist.end(); ++it) - if(fndeps.findIndex((*it)) == -1) + for(QStringList::Iterator it = deplist.begin(); it != deplist.end(); ++it) + if(fndeps.findIndex((*it)) == -1 && (*it) != fn) fndeps.append((*it)); } @@ -607,8 +649,12 @@ MakefileGenerator::initOutPaths() QString dirs[] = { QString("OBJECTS_DIR"), QString("MOC_DIR"), QString("UI_HEADERS_DIR"), QString("UI_SOURCES_DIR"), QString("UI_DIR"), QString("DESTDIR"), - QString("SUBLIBS_DIR"), QString::null }; + QString("SUBLIBS_DIR"), QString("DLLDESTDIR"), QString::null }; for(int x = 0; dirs[x] != QString::null; x++) { if ( !v[dirs[x]].isEmpty() ) { QString orig_path = v[dirs[x]].first(); +#ifdef Q_WS_WIN + // We don't want to add a separator for DLLDESTDIR on Windows + if (!(dirs[x] == "DLLDESTDIR")) +#endif { QString &path = v[dirs[x]].first(); @@ -662,4 +708,9 @@ MakefileGenerator::initOutPaths() } } + if ( !v["DESTDIR"].isEmpty() ) { + QDir d(v["DESTDIR"].first()); + if(Option::fixPathToLocalOS(d.absPath()) == Option::fixPathToLocalOS(Option::output_dir)) + v.remove("DESTDIR"); + } QDir::current().cd( currentDir ); } @@ -675,10 +726,15 @@ MakefileGenerator::init() QMap<QString, QStringList> &v = project->variables(); QString paths[] = { QString("SOURCES"), QString("FORMS"), QString("YACCSOURCES"), QString("INCLUDEPATH"), - QString("HEADERS"), QString("HEADERS_ORIG"), - QString("LEXSOURCES"), QString("QMAKE_INTERNAL_INCLUDED_FILES"), QString::null }; + QString("HEADERS"), QString("HEADERS_ORIG"), QString("LEXSOURCES"), + QString("QMAKE_INTERNAL_INCLUDED_FILES"), + QString("PRECOMPILED_HEADER"), QString::null }; for(int y = 0; paths[y] != QString::null; y++) { QStringList &l = v[paths[y]]; - if(!l.isEmpty()) - l = fileFixify(l); + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + if ((*it).isEmpty()) + continue; + if(QFile::exists((*it))) + (*it) = fileFixify((*it)); + } } @@ -762,4 +818,5 @@ MakefileGenerator::init() files.join(" :: ").latin1()); findDependencies(file) = files; + setProcessedDependencies(file, TRUE); } } @@ -810,17 +867,17 @@ MakefileGenerator::init() if(!noIO()) { QString sources[] = { QString("OBJECTS"), QString("LEXSOURCES"), QString("YACCSOURCES"), - QString("HEADERS"), QString("SOURCES"), QString("FORMS"), - QString::null }; + QString("HEADERS"), QString("SOURCES"), QString("FORMS"), + QString("PRECOMPILED_HEADER"), QString::null }; depHeuristics.clear(); bool write_cache = FALSE, read_cache = QFile::exists(cache_file); - for(int x = 0; sources[x] != QString::null; x++) { + int x; + for(x = 0; sources[x] != QString::null; x++) { QStringList vpath, &l = v[sources[x]]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { if(!(*val_it).isEmpty()) { - QString file = Option::fixPathToLocalOS((*val_it)); - QStringList file_list(file); + QString file = fileFixify((*val_it), QDir::currentDirPath(), Option::output_dir); if(!QFile::exists(file)) { bool found = FALSE; - if(QDir::isRelativePath(file)) { + if(QDir::isRelativePath((*val_it))) { if(vpath.isEmpty()) vpath = v["VPATH_" + sources[x]] + v["VPATH"] + @@ -859,11 +916,10 @@ MakefileGenerator::init() continue; } else { - file_list.clear(); for(int i = 0; i < (int)d.count(); i++) { - file_list.append(dir + d[i]); + QString file = fileFixify(dir + d[i]); if(i == (int)d.count() - 1) - (*val_it) = dir + d[i]; + (*val_it) = file; else - l.insert(val_it, dir + d[i]); + l.insert(val_it, file); } } @@ -877,42 +933,44 @@ MakefileGenerator::init() } } - for(QStringList::Iterator file_it = file_list.begin(); - file_it != file_list.end(); ++file_it) { - QString file_list_file = fileFixify((*file_it)); - bool found_cache_moc = FALSE, found_cache_dep = FALSE; - if(read_cache && Option::output.name() != "-" && - project->isActiveConfig("qmake_cache")) { - if(!findDependencies(file_list_file).isEmpty()) - found_cache_dep = TRUE; - if(cache_found_files[(*file_it)] == (void *)2) - found_cache_moc = TRUE; - if(!found_cache_moc || !found_cache_dep) - write_cache = TRUE; - } - /* Do moc before dependency checking since some includes can come from - moc_*.cpp files */ - if(found_cache_moc) { - QString moc = findMocDestination(file_list_file); - if(!moc.isEmpty()) { - for(QStringList::Iterator cppit = Option::cpp_ext.begin(); - cppit != Option::cpp_ext.end(); ++cppit) { - if(file_list_file.endsWith((*cppit))) { - QStringList &deps = findDependencies(file_list_file); - if(!deps.contains(moc)) - deps.append(moc); - break; - } - } + } + } + } + for(x = 0; sources[x] != QString::null; x++) { + QStringList &l = v[sources[x]]; + for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { + bool found_cache_moc = FALSE, found_cache_dep = FALSE; + if(read_cache && Option::output.name() != "-" && + project->isActiveConfig("qmake_cache")) { + if(processedDependencies((*val_it))) + found_cache_dep = TRUE; + if(cache_found_files[(*val_it)] == (void *)2) + found_cache_moc = TRUE; + if(!found_cache_moc || !found_cache_dep) + write_cache = TRUE; + } + /* Do moc before dependency checking since some includes can come from + moc_*.cpp files */ + if(found_cache_moc) { + QString fixed_file(fileFixify((*val_it), QDir::currentDirPath(), Option::output_dir)); + QString moc = findMocDestination(fixed_file); + if(!moc.isEmpty()) { + for(QStringList::Iterator cppit = Option::cpp_ext.begin(); + cppit != Option::cpp_ext.end(); ++cppit) { + if(fixed_file.endsWith((*cppit))) { + QStringList &deps = findDependencies(fixed_file); + if(!deps.contains(moc)) + deps.append(moc); + break; } - } else if(mocAware() && (sources[x] == "SOURCES" || sources[x] == "HEADERS") && - (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || - Option::mkfile::do_mocs)) { - generateMocList((*file_it)); - } - if(!found_cache_dep && sources[x] != "OBJECTS") { - debug_msg(5, "Looking for dependencies for %s", (*file_it).latin1()); - generateDependencies(deplist, (*file_it), doDepends()); } } + } else if(mocAware() && (sources[x] == "SOURCES" || sources[x] == "HEADERS") && + (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || + Option::mkfile::do_mocs)) { + generateMocList((*val_it)); + } + if(!found_cache_dep && sources[x] != "OBJECTS") { + debug_msg(5, "Looking for dependencies for %s", (*val_it).latin1()); + generateDependencies(deplist, (*val_it), doDepends()); } } @@ -933,5 +991,5 @@ MakefileGenerator::init() for(QMap<QString, QStringList>::Iterator it = depends.begin(); it != depends.end(); ++it) - cachet << depKeyMap[it.key()] << " = " << it.data().join(" ") << endl; + cachet << dependencyKey(it.key()) << " = " << it.data().join(" ") << endl; cachet << "[mocable]" << endl; QString mc, moc_sources[] = { QString("HEADERS"), QString("SOURCES"), QString::null }; @@ -1054,5 +1112,5 @@ MakefileGenerator::init() if(decl.isEmpty() && !project->isEmpty("UI_HEADERS_DIR")) decl = project->first("UI_HEADERS_DIR"); - if(!decl.isEmpty() || (project->isEmpty("UI_HEADERS_DIR") && + if(!decl.isEmpty() || (project->isEmpty("UI_HEADERS_DIR") && !project->isEmpty("UI_SOURCES_DIR")) ) { QString d = fi.dirPath(); @@ -1073,8 +1131,8 @@ MakefileGenerator::init() } impl = fileFixify(impl, QDir::currentDirPath(), Option::output_dir); - if(!impl.isEmpty()) + if(!impl.isEmpty() && !impl.endsWith(Option::dir_sep)) impl += Option::dir_sep; impl += fi.baseName(TRUE) + Option::cpp_ext.first(); - if(Option::output_dir != QDir::currentDirPath() && + if(Option::output_dir != QDir::currentDirPath() && project->isEmpty("UI_DIR") && project->isEmpty("UI_HEADERS_DIR")) { QString decl_fixed = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); @@ -1085,5 +1143,5 @@ MakefileGenerator::init() } decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); - if(!decl.isEmpty()) + if(!decl.isEmpty() && !decl.endsWith(Option::dir_sep)) decl += Option::dir_sep; decl += fi.baseName(TRUE) + Option::h_ext.first(); @@ -1094,5 +1152,5 @@ MakefileGenerator::init() findDependencies(impl).append(decl); - QString mocable = Option::moc_mod + fi.baseName(TRUE) + Option::cpp_ext.first(); + QString mocable = Option::h_moc_mod + fi.baseName(TRUE) + Option::h_moc_ext; if(!v["MOC_DIR"].isEmpty()) mocable.prepend(v["MOC_DIR"].first()); @@ -1107,4 +1165,12 @@ MakefileGenerator::init() } + //Translation files + if(!project->isEmpty("TRANSLATIONS")) { + QStringList &trf = project->variables()["TRANSLATIONS"]; + for(QStringList::Iterator it = trf.begin(); it != trf.end(); ++it) { + (*it) = Option::fixPathToLocalOS((*it)); + } + } + //Image files if(!project->isEmpty("IMAGES")) { @@ -1133,5 +1199,5 @@ MakefileGenerator::init() v["OBJECTS"] += (v["IMAGEOBJECTS"] = createObjectList("QMAKE_IMAGE_COLLECTION")); } - if(Option::output_dir != QDir::currentDirPath()) + if(Option::output_dir != QDir::currentDirPath()) project->variables()["INCLUDEPATH"].append(fileFixify(Option::output_dir, Option::output_dir, Option::output_dir)); @@ -1141,5 +1207,6 @@ MakefileGenerator::init() if(!project->isEmpty("MOC_DIR")) project->variables()["INCLUDEPATH"].append(project->first("MOC_DIR")); - v["OBJMOC"] = createObjectList("_HDRMOC") + createObjectList("_UIMOC"); + if ( Option::h_moc_ext == Option::cpp_ext.first() ) + v["OBJMOC"] = createObjectList("_HDRMOC") + createObjectList("_UIMOC"); QStringList &l = v["SRCMOC"]; @@ -1150,4 +1217,22 @@ MakefileGenerator::init() } } + + QString fixpaths[] = { QString("PRE_TARGETDEPS"), QString("POST_TARGETDEPS"), QString::null }; + for(int path = 0; !fixpaths[path].isNull(); path++) { + QStringList &l = v[fixpaths[path]]; + for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { + if(!(*val_it).isEmpty()) + (*val_it) = Option::fixPathToTargetOS((*val_it), FALSE); + } + } + + // Make sure the INCLUDEPATH doesn't contain any empty(/null) entries + QStringList &ipl = project->variables()["INCLUDEPATH"]; + for(QStringList::Iterator ipl_it = ipl.begin(); ipl_it != ipl.end();) { + if ((*ipl_it).isEmpty()) + ipl_it = ipl.remove(ipl_it); + else + ++ipl_it; + } } @@ -1156,8 +1241,8 @@ MakefileGenerator::processPrlFile(QString &file) { bool ret = FALSE, try_replace_file=FALSE; - QString prl_file; - if(file.endsWith(Option::prl_ext)) { + QString meta_file, orig_file = file; + if(QMakeMetaInfo::libExists(file)) { try_replace_file = TRUE; - prl_file = file; + meta_file = file; file = ""; } else { @@ -1166,10 +1251,10 @@ MakefileGenerator::processPrlFile(QString &file) if(ext != -1) tmp = tmp.left(ext); - prl_file = tmp + Option::prl_ext; + meta_file = tmp; } - prl_file = fileFixify(prl_file); - if(!QFile::exists(fileFixify(prl_file, QDir::currentDirPath(), Option::output_dir)) && + meta_file = fileFixify(meta_file); + if(!QMakeMetaInfo::libExists(fileFixify(meta_file, QDir::currentDirPath(), Option::output_dir)) && project->isActiveConfig("qt")) { - QString stem = prl_file, dir, extn; + QString stem = meta_file, dir, extn; int slsh = stem.findRev('/'), hadlib = 0; if(slsh != -1) { @@ -1191,37 +1276,51 @@ MakefileGenerator::processPrlFile(QString &file) else stem += "-mt"; //try the thread case - prl_file = dir; + meta_file = dir; if(hadlib) - prl_file += "lib"; - prl_file += stem + extn; + meta_file += "lib"; + meta_file += stem + extn; try_replace_file = TRUE; } } - QString real_prl_file = Option::fixPathToLocalOS(prl_file); - if(project->variables()["QMAKE_PRL_INTERNAL_FILES"].findIndex(prl_file) != -1) { + QString real_meta_file = Option::fixPathToLocalOS(meta_file); + if(project->variables()["QMAKE_PRL_INTERNAL_FILES"].findIndex(QMakeMetaInfo::findLib(meta_file)) != -1) { ret = TRUE; - } else if(!real_prl_file.isEmpty() && - QFile::exists(fileFixify(real_prl_file, QDir::currentDirPath(), Option::output_dir))) { - project->variables()["QMAKE_PRL_INTERNAL_FILES"].append(prl_file); - QMakeProject proj; - debug_msg(1, "Processing PRL file: %s", real_prl_file.latin1()); - if(!proj.read(fileFixify(real_prl_file, QDir::currentDirPath(), Option::output_dir), - QDir::currentDirPath(), TRUE)) { - fprintf(stderr, "Error processing prl file: %s\n", real_prl_file.latin1()); - } else { - ret = TRUE; - QMap<QString, QStringList> &vars = proj.variables(); - for( QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) - processPrlVariable(it.key(), it.data()); - if(try_replace_file && !proj.isEmpty("QMAKE_PRL_TARGET")) { - QString dir; - int slsh = real_prl_file.findRev(Option::dir_sep); - if(slsh != -1) - dir = real_prl_file.left(slsh+1); - file = dir + proj.first("QMAKE_PRL_TARGET"); + } else if(!meta_file.isEmpty()) { + QString f = fileFixify(real_meta_file, QDir::currentDirPath(), Option::output_dir); + if(QMakeMetaInfo::libExists(f)) { + QMakeMetaInfo libinfo; + debug_msg(1, "Processing PRL file: %s", real_meta_file.latin1()); + if(!libinfo.readLib(f)) { + fprintf(stderr, "Error processing meta file: %s\n", real_meta_file.latin1()); + } else if(project->isActiveConfig("no_read_prl_" + libinfo.type().lower())) { + debug_msg(2, "Ignored meta file %s [%s]", real_meta_file.latin1(), libinfo.type().latin1()); + } else { + ret = TRUE; + QMap<QString, QStringList> &vars = libinfo.variables(); + for( QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) + processPrlVariable(it.key(), it.data()); + if(try_replace_file && !libinfo.isEmpty("QMAKE_PRL_TARGET")) { + QString dir; + int slsh = real_meta_file.findRev(Option::dir_sep); + if(slsh != -1) + dir = real_meta_file.left(slsh+1); + file = libinfo.first("QMAKE_PRL_TARGET"); + if(QDir::isRelativePath(file)) + file.prepend(dir); + } } } - if(ret) - project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"].append(prl_file); + if(ret) { + QString mf = QMakeMetaInfo::findLib(meta_file); + project->variables()["QMAKE_PRL_INTERNAL_FILES"].append(mf); + project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"].append(mf); + } + } + if(try_replace_file && file.isEmpty()) { +#if 0 + warn_msg(WarnLogic, "Found prl [%s] file with no target [%s]!", meta_file.latin1(), + orig_file.latin1()); +#endif + file = orig_file; } return ret; @@ -1297,4 +1396,8 @@ MakefileGenerator::writePrlFile(QTextStream &t) if(!project->isEmpty("PRL_EXPORT_DEFINES")) t << "QMAKE_PRL_DEFINES = " << project->variables()["PRL_EXPORT_DEFINES"].join(" ") << endl; + if(!project->isEmpty("PRL_EXPORT_CFLAGS")) + t << "QMAKE_PRL_CFLAGS = " << project->variables()["PRL_EXPORT_CFLAGS"].join(" ") << endl; + if(!project->isEmpty("PRL_EXPORT_CXXFLAGS")) + t << "QMAKE_PRL_CXXFLAGS = " << project->variables()["PRL_EXPORT_CXXFLAGS"].join(" ") << endl; if(!project->isEmpty("CONFIG")) t << "QMAKE_PRL_CONFIG = " << project->variables()["CONFIG"].join(" ") << endl; @@ -1317,8 +1420,10 @@ bool MakefileGenerator::write() { + usePlatformDir(); init(); findLibraries(); if((Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || //write prl Option::qmake_mode == Option::QMAKE_GENERATE_PRL) && + project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty() && project->isActiveConfig("create_prl") && project->first("TEMPLATE") == "lib" && !project->isActiveConfig("plugin")) { @@ -1347,5 +1452,5 @@ MakefileGenerator::write() processPrlFiles(); - if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || + if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || //write prl file Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) { QTextStream t(&Option::output); @@ -1355,4 +1460,59 @@ MakefileGenerator::write() } +// Manipulate directories, so it's possible to build +// several cross-platform targets concurrently +void +MakefileGenerator::usePlatformDir() +{ + QString pltDir(project->first("QMAKE_PLATFORM_DIR")); + if(pltDir.isEmpty()) + return; + char sep = QDir::separator(); + QString slashPltDir = sep + pltDir; + + QString filePath = project->first("DESTDIR"); + project->variables()["DESTDIR"] = filePath + + (filePath.isEmpty() ? pltDir : slashPltDir); + + filePath = project->first("DLLDESTDIR"); + project->variables()["DLLDESTDIR"] = filePath + + (filePath.isEmpty() ? pltDir : slashPltDir); + + filePath = project->first("OBJECTS_DIR"); + project->variables()["OBJECTS_DIR"] = filePath + + (filePath.isEmpty() ? pltDir : slashPltDir); + + filePath = project->first("QMAKE_LIBDIR_QT"); + project->variables()["QMAKE_LIBDIR_QT"] = filePath + + (filePath.isEmpty() ? pltDir : slashPltDir); + + filePath = project->first("QMAKE_LIBS_QT"); + int fpi = filePath.findRev(sep); + if (fpi == -1) + project->variables()["QMAKE_LIBS_QT"].prepend(pltDir + sep); + else + project->variables()["QMAKE_LIBS_QT"] = filePath.left(fpi) + + slashPltDir + + filePath.mid(fpi); + + filePath = project->first("QMAKE_LIBS_QT_THREAD"); + fpi = filePath.findRev(sep); + if (fpi == -1) + project->variables()["QMAKE_LIBS_QT_THREAD"].prepend(pltDir + sep); + else + project->variables()["QMAKE_LIBS_QT_THREAD"] = filePath.left(fpi) + + slashPltDir + + filePath.mid(fpi); + + filePath = project->first("QMAKE_LIBS_QT_ENTRY"); + fpi = filePath.findRev(sep); + if (fpi == -1) + project->variables()["QMAKE_LIBS_QT_ENTRY"].prepend(pltDir + sep); + else + project->variables()["QMAKE_LIBS_QT_ENTRY"] = filePath.left(fpi) + + slashPltDir + + filePath.mid(fpi); +} + void MakefileGenerator::writeObj(QTextStream &t, const QString &obj, const QString &src) @@ -1373,5 +1533,5 @@ MakefileGenerator::writeObj(QTextStream &t, const QString &obj, const QString &s QStringList deps = findDependencies((*sit)); for(QStringList::Iterator dit = deps.begin(); dit != deps.end(); dit++) { - if((*dit).endsWith(Option::moc_ext)) + if((*dit).endsWith(Option::cpp_moc_ext)) odep += (*dit) + " "; else @@ -1407,6 +1567,6 @@ MakefileGenerator::writeObj(QTextStream &t, const QString &obj, const QString &s } if (!use_implicit_rule && !project->isEmpty(comp)) { - QString p = var(comp); - p.replace(stringSrc, (*sit)); + QString p = var(comp), srcf(*sit); + p.replace(stringSrc, srcf); p.replace(stringObj, (*oit)); t << "\n\t" << p; @@ -1422,14 +1582,12 @@ MakefileGenerator::writeUicSrc(QTextStream &t, const QString &ui) QStringList &uil = project->variables()[ui]; for(QStringList::Iterator it = uil.begin(); it != uil.end(); it++) { - QString deps = findDependencies((*it)).join(" \\\n\t\t"), decl, impl; + QString decl, impl; { QString tmp = (*it), impl_dir, decl_dir; decl = tmp.replace(QRegExp("\\" + Option::ui_ext + "$"), Option::h_ext.first()); - decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); - int dlen = decl.findRev(Option::dir_sep) + 1; + int dlen = decl.findRev(Option::dir_sep) + 1; tmp = (*it); impl = tmp.replace(QRegExp("\\" + Option::ui_ext + "$"), Option::cpp_ext.first()); - impl = fileFixify(impl, QDir::currentDirPath(), Option::output_dir); - int ilen = decl.findRev(Option::dir_sep) + 1; + int ilen = decl.findRev(Option::dir_sep) + 1; if(!project->isEmpty("UI_DIR")) { impl_dir = project->first("UI_DIR"); @@ -1445,24 +1603,30 @@ MakefileGenerator::writeUicSrc(QTextStream &t, const QString &ui) impl = project->first("UI_SOURCES_DIR") + impl.right(impl.length() - ilen); } - } - if(decl_dir.isEmpty()) - decl_dir = decl.left(dlen); - if(impl_dir.isEmpty()) - impl_dir = impl.left(ilen); - if(!impl_dir.isEmpty()) - createDir(Option::output_dir + Option::dir_sep + impl_dir); - if(!decl_dir.isEmpty() && decl_dir != impl_dir) - createDir(Option::output_dir + Option::dir_sep + decl_dir); - } - t << decl << ": " << (*it) << " " << deps << "\n\t" + } + impl = fileFixify(impl, QDir::currentDirPath(), Option::output_dir); + decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); + if(decl_dir.isEmpty()) + decl_dir = decl.section(Option::dir_sep,0,-2); + if(impl_dir.isEmpty()) + impl_dir = impl.section(Option::dir_sep,0,-2); + if (QDir::isRelativePath(impl_dir)) + impl_dir.prepend(Option::output_dir + Option::dir_sep); + if (QDir::isRelativePath(decl_dir)) + decl_dir.prepend(Option::output_dir + Option::dir_sep); + createDir(impl_dir); + createDir(decl_dir); + } + QStringList deps = findDependencies((*it)); + deps.remove(decl); //avoid circular dependencies.. + t << decl << ": " << (*it) << " " << deps.join(" \\\n\t\t") << "\n\t" << "$(UIC) " << (*it) << " -o " << decl << endl << endl; QString mildDecl = decl; - int k = mildDecl.findRev( Option::dir_sep ); + int k = mildDecl.findRev(Option::dir_sep); if ( k != -1 ) mildDecl = mildDecl.mid( k + 1 ); - - t << impl << ": " << decl << " " << (*it) << " " << deps << "\n\t" - << "$(UIC) " << (*it) << " -i " << mildDecl << " -o " << impl << endl << endl; + t << impl << ": " << decl << " " << (*it) << " " << deps.join(" \\\n\t\t") << "\n\t" + << "$(UIC)"; + t << " " << (*it) << " -i " << mildDecl << " -o " << impl << endl << endl; } } @@ -1478,5 +1642,6 @@ MakefileGenerator::writeMocObj(QTextStream &t, const QString &obj, const QString for( ;sit != srcl.end() && oit != objl.end(); oit++, sit++) { QString hdr = findMocSource((*sit)); - t << (*oit) << ": " << (*sit) << " " + t << (*oit) << ": " + << (*sit) << " " << findDependencies((*sit)).join(" \\\n\t\t") << " " << hdr << " " << findDependencies(hdr).join(" \\\n\t\t"); bool use_implicit_rule = !project->isEmpty("QMAKE_RUN_CXX_IMP"); @@ -1491,6 +1656,6 @@ MakefileGenerator::writeMocObj(QTextStream &t, const QString &obj, const QString } if (!use_implicit_rule && !project->isEmpty("QMAKE_RUN_CXX")) { - QString p = var("QMAKE_RUN_CXX"); - p.replace(stringSrc, (*sit)); + QString p = var("QMAKE_RUN_CXX"), srcf(*sit); + p.replace(stringSrc, srcf); p.replace(stringObj, (*oit)); t << "\n\t" << p; @@ -1513,5 +1678,6 @@ MakefileGenerator::writeMocSrc(QTextStream &t, const QString &src) deps += (*it); t << m << ": " << deps << "\n\t" - << "$(MOC) " << (*it) << " -o " << m << endl << endl; + << "$(MOC)"; + t << " " << (*it) << " -o " << m << endl << endl; } } @@ -1546,5 +1712,8 @@ MakefileGenerator::writeYaccSrc(QTextStream &t, const QString &src) if(!project->isActiveConfig("yacc_no_name_mangle")) { mangle = fi.baseName(TRUE); - yaccflags += " -p " + mangle; + if(!project->isEmpty("QMAKE_YACCFLAGS_MANGLE")) + yaccflags += " " + var("QMAKE_YACCFLAGS_MANGLE").replace(stringBase, mangle); + else + yaccflags += " -p " + mangle; } QString out_h = default_out_h, out_c = default_out_c; @@ -1622,7 +1791,7 @@ MakefileGenerator::writeImageObj(QTextStream &t, const QString &obj) } if(!use_implicit_rule && !project->isEmpty("QMAKE_RUN_CXX")) { - QString p = var("QMAKE_RUN_CXX"); - p.replace( stringSrc, src); - p.replace( stringObj, (*oit)); + QString p = var("QMAKE_RUN_CXX"), srcf(src); + p.replace(stringSrc, srcf); + p.replace(stringObj, (*oit)); t << "\n\t" << p; } @@ -1662,5 +1831,6 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString pvar = (*it) + ".path"; - if(project->variables()[pvar].isEmpty()) { + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_path") == -1 && + project->variables()[pvar].isEmpty()) { warn_msg(WarnLogic, "%s is not defined: install target not created\n", pvar.latin1()); continue; @@ -1670,11 +1840,11 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) const QString root = "$(INSTALL_ROOT)"; QString target, dst= fileFixify(project->variables()[pvar].first()); -#ifndef Q_WS_WIN if(dst.right(1) != Option::dir_sep) dst += Option::dir_sep; -#endif - QStringList tmp, &uninst = project->variables()[(*it) + ".uninstall"]; + QStringList tmp, uninst = project->variables()[(*it) + ".uninstall"]; //other tmp = project->variables()[(*it) + ".extra"]; + if(tmp.isEmpty()) + tmp = project->variables()[(*it) + ".commands"]; //to allow compatible name if(!tmp.isEmpty()) { do_default = FALSE; @@ -1704,9 +1874,14 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) if(!target.isEmpty()) target += "\t"; - target += QString(fi.isDir() ? "-$(COPY_DIR)" : "-$(COPY_FILE)") + " \"" + - Option::fixPathToTargetOS(fileFixify(wild), FALSE) + "\" \"" + root + dst + "\"\n"; + QString cmd = QString(fi.isDir() ? "-$(INSTALL_DIR)" : "-$(INSTALL_FILE)") + " \"" + + Option::fixPathToTargetOS(fileFixify(wild, QString::null, + QString::null, FALSE, FALSE), FALSE) + + "\" \"" + root + dst + "\"\n"; + target += cmd; if(!project->isActiveConfig("debug") && !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) - target += QString("\t-") + var("QMAKE_STRIP") + " \"" + root + fileFixify(dst + filestr) + "\"\n"; + target += QString("\t-") + var("QMAKE_STRIP") + " \"" + + root + fileFixify(dst + filestr, QString::null, QString::null, FALSE, FALSE) + + "\"\n"; if(!uninst.isEmpty()) uninst.append("\n\t"); @@ -1717,7 +1892,8 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) QString("-$(DEL_FILE) -r") #endif - + " \"" + root + fileFixify(dst + filestr) + "\""); + + " \"" + root + fileFixify(dst + filestr, QString::null, QString::null, FALSE, FALSE) + "\""); continue; } + fixEnvVariables(dirstr); QDir dir(dirstr, filestr); //wild for(uint x = 0; x < dir.count(); x++) { @@ -1733,23 +1909,40 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) QString("-$(DEL_FILE) -r") #endif - + " \"" + root + fileFixify(dst + file) + "\""); - QFileInfo fi(file); + + " \"" + root + fileFixify(dst + file, QString::null, QString::null, FALSE, FALSE) + + "\""); + QFileInfo fi(Option::fixPathToTargetOS(fileFixify(dirstr + file), TRUE)); if(!target.isEmpty()) target += "\t"; - target += QString(fi.isDir() ? "-$(COPY_DIR)" : "-$(COPY_FILE)") + " \"" + - Option::fixPathToTargetOS(fileFixify(dirstr + file), FALSE) + - "\" \"" + root + fileFixify(dst) + "\"\n"; + QString cmd = QString(fi.isDir() ? "-$(INSTALL_DIR)" : "-$(INSTALL_FILE)") + " \"" + + Option::fixPathToTargetOS(fileFixify(dirstr + file, QString::null, + QString::null, FALSE, FALSE), FALSE) + + "\" \"" + root + dst + "\"\n"; + target += cmd; if(!project->isActiveConfig("debug") && !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) - target += QString("\t-") + var("QMAKE_STRIP") + " \"" + root + fileFixify(dst + file) + "\"\n"; + target += QString("\t-") + var("QMAKE_STRIP") + " \"" + + root + fileFixify(dst + file, QString::null, QString::null, FALSE, FALSE) + + "\"\n"; } } } //default? - if(do_default) + if(do_default) { target = defaultInstall((*it)); + uninst = project->variables()[(*it) + ".uninstall"]; + } if(!target.isEmpty()) { - t << "install_" << (*it) << ": " << "\n\t"; + t << "install_" << (*it) << ": all "; + const QStringList &deps = project->variables()[(*it) + ".depends"]; + if(!deps.isEmpty()) { + for(QStringList::ConstIterator dep_it = deps.begin(); dep_it != deps.end(); ++dep_it) { + QString targ = var((*dep_it) + ".target"); + if(targ.isEmpty()) + targ = (*dep_it); + t << targ; + } + } + t << "\n\t"; const QStringList &dirs = project->variables()[pvar]; for(QStringList::ConstIterator pit = dirs.begin(); pit != dirs.end(); ++pit) { @@ -1762,18 +1955,22 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) } t << target << endl << endl; - all_installs += QString("install_") + (*it) + " "; if(!uninst.isEmpty()) { t << "uninstall_" << (*it) << ": " << "\n\t" << uninst.join("") << "\n\t" << "-$(DEL_DIR) \"" << ( root + dst ) << "\"" << endl << endl; - all_uninstalls += "uninstall_" + (*it) + " "; } t << endl; + + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_default_install") == -1) { + all_installs += QString("install_") + (*it) + " "; + if(!uninst.isEmpty()) + all_uninstalls += "uninstall_" + (*it) + " "; + } } else { debug_msg(1, "no definition for install %s: install target not created",(*it).latin1()); } } - t << "install: all " << all_installs << "\n\n"; - t << "uninstall: " << all_uninstalls << "\n\n"; + t << "install: " << all_installs << " " << var("INSTALLDEPS") << "\n\n"; + t << "uninstall: " << all_uninstalls << " " << var("UNINSTALLDEPS") << "\n\n"; } @@ -1972,6 +2169,10 @@ MakefileGenerator::writeMakeQmake(QTextStream &t) if(Option::mkfile::do_cache) t << fileFixify(Option::mkfile::cachefile) << " "; - if(!specdir().isEmpty()) - t << specdir() << Option::dir_sep << "qmake.conf" << " "; + if(!specdir().isEmpty()) { + if (QFile::exists(Option::fixPathToLocalOS(specdir()+QDir::separator()+"qmake.conf"))) + t << specdir() << Option::dir_sep << "qmake.conf" << " "; + else if (QFile::exists(Option::fixPathToLocalOS(specdir()+QDir::separator()+"tmake.conf"))) + t << specdir() << Option::dir_sep << "tmake.conf" << " "; + } t << project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"].join(" \\\n\t\t") << "\n\t" << qmake <<endl; @@ -1987,5 +2188,6 @@ MakefileGenerator::writeMakeQmake(QTextStream &t) QStringList -MakefileGenerator::fileFixify(const QStringList& files, const QString &out_dir, const QString &in_dir, bool force_fix) const +MakefileGenerator::fileFixify(const QStringList& files, const QString &out_dir, const QString &in_dir, + bool force_fix, bool canon) const { if(files.isEmpty()) @@ -1994,5 +2196,5 @@ MakefileGenerator::fileFixify(const QStringList& files, const QString &out_dir, for(QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) { if(!(*it).isEmpty()) - ret << fileFixify((*it), out_dir, in_dir, force_fix); + ret << fileFixify((*it), out_dir, in_dir, force_fix, canon); } return ret; @@ -2000,12 +2202,16 @@ MakefileGenerator::fileFixify(const QStringList& files, const QString &out_dir, QString -MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const QString &in_d, bool force_fix) const +MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, + const QString &in_d, bool force_fix, bool canon) const { - if(file0.isEmpty()) + if(file0.isEmpty()) return file0; QString key = file0; - if(!in_d.isEmpty() || !out_d.isEmpty() || force_fix) - key.prepend(in_d + "--" + out_d + "--" + QString::number((int)force_fix) + "-"); - if(fileFixed.contains(key)) + if(QDir::isRelativePath(file0)) + key.prepend(QDir::currentDirPath() + "--"); + if(!in_d.isEmpty() || !out_d.isEmpty() || force_fix || !canon) + key.prepend(in_d + "--" + out_d + "--" + QString::number((int)force_fix) + "--" + + QString::number((int)canon) + "-"); + if(fileFixed.contains(key)) return fileFixed[key]; @@ -2028,5 +2234,5 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const if(!force_fix && project->isActiveConfig("no_fixpath")) { if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) { //absoluteify it - QString qfile = Option::fixPathToLocalOS(file); + QString qfile = Option::fixPathToLocalOS(file, TRUE, canon); if(QDir::isRelativePath(file)) { //already absolute QFileInfo fi(qfile); @@ -2036,12 +2242,15 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const } } else { //fix it.. - QString qfile(Option::fixPathToLocalOS(file, TRUE)), in_dir(in_d), out_dir(out_d); + QString qfile(Option::fixPathToLocalOS(file, TRUE, canon)), in_dir(in_d), out_dir(out_d); { - if(out_dir.isNull()) - out_dir = Option::output_dir; + if(out_dir.isNull() || QDir::isRelativePath(out_dir)) + out_dir.prepend(Option::output_dir + QDir::separator()); if(out_dir == ".") out_dir = QDir::currentDirPath(); - if(in_dir.isEmpty() || in_dir == ".") + if(in_dir.isEmpty() || QDir::isRelativePath(in_dir)) + in_dir.prepend(QDir::currentDirPath() + QDir::separator()); + if(in_dir == ".") in_dir = QDir::currentDirPath(); + if(!QDir::isRelativePath(in_dir) || !QDir::isRelativePath(out_dir)) { QFileInfo in_fi(in_dir); @@ -2066,11 +2275,11 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const file.prepend(in_dir); } - file = Option::fixPathToTargetOS(file, FALSE); - if(QFile::exists(file) && file == Option::fixPathToTargetOS(file, TRUE)) { + file = Option::fixPathToTargetOS(file, FALSE, canon); + if(canon && QFile::exists(file) && file == Option::fixPathToTargetOS(file, TRUE, canon)) { QString real_file = QDir(file).canonicalPath(); if(!real_file.isEmpty()) file = real_file; } - QString match_dir = Option::fixPathToTargetOS(out_dir, FALSE); + QString match_dir = Option::fixPathToTargetOS(out_dir, FALSE, canon); if(file == match_dir) { file = ""; @@ -2101,10 +2310,11 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const } } - file = Option::fixPathToTargetOS(file, FALSE); + file = Option::fixPathToTargetOS(file, FALSE, canon); if(file.isEmpty()) file = "."; if(!quote.isNull()) file = quote + file + quote; - debug_msg(3, "Fixed %s :: to :: %s (%d)", orig_file.latin1(), file.latin1(), depth); + debug_msg(3, "Fixed %s :: to :: %s (%d) [%s::%s]", orig_file.latin1(), file.latin1(), depth, + in_d.latin1(), out_d.latin1()); ((MakefileGenerator*)this)->fileFixed.insert(key, file); return file; @@ -2139,14 +2349,33 @@ void MakefileGenerator::logicWarn(const QString &f, const QString &w) } +QString +MakefileGenerator::dependencyKey(const QString &file) const +{ + QString key = file; + Option::fixPathToTargetOS(key); + if(key.find(Option::dir_sep)) + key = key.right(key.length() - key.findRev(Option::dir_sep) - 1); + return key; +} + +void +MakefileGenerator::setProcessedDependencies(const QString &file, bool b) +{ + depProcessed[dependencyKey(file)] = b; +} + +bool +MakefileGenerator::processedDependencies(const QString &file) +{ + QString key = dependencyKey(file); + if(!depProcessed.contains(key)) + return FALSE; + return depProcessed[key]; +} + QStringList &MakefileGenerator::findDependencies(const QString &file) { - QString key = file; - Option::fixPathToTargetOS(key); - if(key.find(Option::dir_sep)) - key = key.right(key.length() - key.findRev(Option::dir_sep) - 1); - if(!depKeyMap.contains(key)) - depKeyMap.insert(key, file); - return depends[key]; + return depends[dependencyKey(file)]; } @@ -2158,6 +2387,6 @@ MakefileGenerator::specdir() return spec; spec = Option::mkfile::qmakespec; - const char *d = getenv("QTDIR"); - if(d) { +#if 0 + if(const char *d = getenv("QTDIR")) { QString qdir = Option::fixPathToTargetOS(QString(d)); if(qdir.endsWith(QString(QChar(QDir::separator())))) @@ -2173,4 +2402,7 @@ MakefileGenerator::specdir() } } +#else + spec = Option::fixPathToTargetOS(spec); +#endif return spec; } @@ -2182,4 +2414,6 @@ MakefileGenerator::openOutput(QFile &file) const QString outdir; if(!file.name().isEmpty()) { + if(QDir::isRelativePath(file.name())) + file.setName(Option::output_dir + file.name()); //pwd when qmake was run QFileInfo fi(file); if(fi.isDir()) diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 4fdabe8..e818089 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of MakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -42,4 +40,10 @@ #include <qtextstream.h> +#ifdef Q_OS_WIN32 +#define QT_POPEN _popen +#else +#define QT_POPEN popen +#endif + class MakefileGenerator { @@ -48,5 +52,7 @@ class MakefileGenerator QStringList createObjectList(const QString &var); QString build_args(); - QMap<QString, QString> depHeuristics, depKeyMap, fileFixed; + QString dependencyKey(const QString &file) const; + QMap<QString, bool> depProcessed; + QMap<QString, QString> depHeuristics, fileFixed; QMap<QString, QString> mocablesToMOC, mocablesFromMOC; QMap<QString, QStringList> depends; @@ -82,5 +88,5 @@ protected: QString findMocSource(const QString &moc_file) const; QString findMocDestination(const QString &src_file) const; - QStringList &findDependencies(const QString &file); + virtual QStringList &findDependencies(const QString &file); void setNoIO(bool o); @@ -98,4 +104,7 @@ protected: virtual void init(); + //for cross-platform dependent directories + virtual void usePlatformDir(); + //for installs virtual QString defaultInstall(const QString &); @@ -109,6 +118,10 @@ protected: //make sure libraries are found virtual bool findLibraries(); + virtual QString findDependency(const QString &); - QString var(const QString &var); + void setProcessedDependencies(const QString &file, bool b); + bool processedDependencies(const QString &file); + + virtual QString var(const QString &var); QString varGlue(const QString &var, const QString &before, const QString &glue, const QString &after); QString varList(const QString &var); @@ -119,7 +132,7 @@ protected: QString fileFixify(const QString& file, const QString &out_dir=QString::null, - const QString &in_dir=QString::null, bool force_fix=FALSE) const; + const QString &in_dir=QString::null, bool force_fix=FALSE, bool canon=TRUE) const; QStringList fileFixify(const QStringList& files, const QString &out_dir=QString::null, - const QString &in_dir=QString::null, bool force_fix=FALSE) const; + const QString &in_dir=QString::null, bool force_fix=FALSE, bool canon=TRUE) const; public: MakefileGenerator(QMakeProject *p); @@ -127,5 +140,5 @@ public: static MakefileGenerator *create(QMakeProject *); - bool write(); + virtual bool write(); virtual bool openOutput(QFile &) const; }; @@ -167,7 +180,11 @@ inline bool MakefileGenerator::findLibraries() { return TRUE; } +inline QString MakefileGenerator::findDependency(const QString &) +{ return QString(""); } + inline MakefileGenerator::~MakefileGenerator() { } +QString mkdir_p_asstring(const QString &dir); #endif /* __MAKEFILE_H__ */ diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp index 1515216..1c17379 100644 --- a/qmake/generators/projectgenerator.cpp +++ b/qmake/generators/projectgenerator.cpp @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of ProjectGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -158,4 +156,5 @@ ProjectGenerator::init() if(Option::projfile::do_pwd) dirs.prepend("."); + const QString out_file = fileFixify(Option::output.name()); for(QStringList::Iterator pd = dirs.begin(); pd != dirs.end(); pd++) { if(QFile::exists((*pd))) { @@ -172,10 +171,13 @@ ProjectGenerator::init() d.setFilter(QDir::Files); for(int i = 0; i < (int)d.count(); i++) { - QString nd = newdir + QDir::separator() + d[i]; + QString nd = newdir; + if(nd == ".") + nd = ""; + else if(!nd.isEmpty() && !nd.endsWith(QString(QChar(QDir::separator())))) + nd += QDir::separator(); + nd += d[i]; fileFixify(nd); - if(d[i] != "." && d[i] != ".." && !subdirs.contains(nd)) { - if(newdir + d[i] != Option::output_dir + Option::output.name()) - subdirs.append(nd); - } + if(d[i] != "." && d[i] != ".." && !subdirs.contains(nd) && !out_file.endsWith(nd)) + subdirs.append(nd); } } @@ -325,5 +327,5 @@ ProjectGenerator::init() } } - if(!found && (*val_it).endsWith(Option::moc_ext)) + if(!found && (*val_it).endsWith(Option::cpp_moc_ext)) found = TRUE; if(found) @@ -392,5 +394,5 @@ ProjectGenerator::addFile(QString file) if(s != -1) dir = file.left(s+1); - if(file.mid(dir.length(), Option::moc_mod.length()) == Option::moc_mod) + if(file.mid(dir.length(), Option::h_moc_mod.length()) == Option::h_moc_mod) return FALSE; @@ -436,5 +438,5 @@ ProjectGenerator::addFile(QString file) QString -ProjectGenerator::getWritableVar(const QString &v, bool /*fixPath*/) +ProjectGenerator::getWritableVar(const QString &v, bool fixPath) { QStringList &vals = project->variables()[v]; @@ -456,8 +458,12 @@ ProjectGenerator::getWritableVar(const QString &v, bool /*fixPath*/) join = vals.join(" \\\n" + spaces); } +#if 0 // ### Commented out for now so that project generation works. - // Sam: can you look at why this was needed? - /* if(fixPath) - join = join.replace("\\", "/");*/ + // Sam: it had to do with trailing \'s (ie considered continuation lines) + if(fixPath) + join = join.replace("\\", "/"); +#else + Q_UNUSED(fixPath); +#endif return ret + join + "\n"; } diff --git a/qmake/generators/projectgenerator.h b/qmake/generators/projectgenerator.h index 055a784..bebb259 100644 --- a/qmake/generators/projectgenerator.h +++ b/qmake/generators/projectgenerator.h @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of ProjectGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index e274481..caaddee 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. -** -** Created : 970521 +** Implementation of UnixMakefileGenerator class. ** ** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -79,8 +77,22 @@ UnixMakefileGenerator::init() } } + if( project->isEmpty("QMAKE_CFLAGS_PRECOMPILE")) + project->variables()["QMAKE_CFLAGS_PRECOMPILE"].append("-x c-header -c"); + if( project->isEmpty("QMAKE_CXXFLAGS_PRECOMPILE")) + project->variables()["QMAKE_CXXFLAGS_PRECOMPILE"].append("-x c++-header -c"); + if( project->isEmpty("QMAKE_CFLAGS_USE_PRECOMPILE")) + project->variables()["QMAKE_CFLAGS_USE_PRECOMPILE"].append("-include"); + if( project->isEmpty("QMAKE_EXTENSION_PLUGIN") ) + project->variables()["QMAKE_EXTENSION_PLUGIN"].append(project->first("QMAKE_EXTENSION_SHLIB")); if( project->isEmpty("QMAKE_COPY_FILE") ) - project->variables()["QMAKE_COPY_FILE"].append( "$(COPY) -p" ); + project->variables()["QMAKE_COPY_FILE"].append( "$(COPY)" ); if( project->isEmpty("QMAKE_COPY_DIR") ) - project->variables()["QMAKE_COPY_DIR"].append( "$(COPY) -pR" ); + project->variables()["QMAKE_COPY_DIR"].append( "$(COPY) -R" ); + if( project->isEmpty("QMAKE_INSTALL_FILE") ) + project->variables()["QMAKE_INSTALL_FILE"].append( "$(COPY_FILE)" ); + if( project->isEmpty("QMAKE_INSTALL_DIR") ) + project->variables()["QMAKE_INSTALL_DIR"].append( "$(COPY_DIR)" ); + if( project->isEmpty("QMAKE_LIBTOOL") ) + project->variables()["QMAKE_LIBTOOL"].append( "libtool --silent" ); //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET if(!project->isEmpty("TARGET")) { @@ -104,6 +116,5 @@ UnixMakefileGenerator::init() (!project->isEmpty("QMAKE_LIB_FLAG") && project->isActiveConfig("dll")) || is_qt; - if(!project->isActiveConfig("global_init_link_order")) - project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; + project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; if ( (!project->isEmpty("QMAKE_LIB_FLAG") && !project->isActiveConfig("staticlib") ) || (project->isActiveConfig("qt") && project->isActiveConfig( "plugin" ) )) { @@ -138,19 +149,20 @@ UnixMakefileGenerator::init() if(!project->isEmpty("QMAKE_LIBDIR")) { if ( !project->isEmpty("QMAKE_RPATH") ) - project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR", " " + var("QMAKE_RPATH"), - " " + var("QMAKE_RPATH"), ""); + project->variables()["QMAKE_LFLAGS"] += varGlue("QMAKE_LIBDIR", " " + var("QMAKE_RPATH"), + " " + var("QMAKE_RPATH"), ""); project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue( "QMAKE_LIBDIR", "-L", " -L", "" ); } - if ( extern_libs && (project->isActiveConfig("qt") || project->isActiveConfig("opengl")) ) { - if(configs.findIndex("x11lib") == -1) - configs.append("x11lib"); - if ( project->isActiveConfig("opengl") && configs.findIndex("x11inc") == -1 ) - configs.append("x11inc"); + if ( project->isActiveConfig("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); } - if ( project->isActiveConfig("x11") ) { - if(configs.findIndex("x11lib") == -1) - configs.append("x11lib"); - if(configs.findIndex("x11inc") == -1) - configs.append("x11inc"); + if ( project->isActiveConfig("qtopiainc") ) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"]; + if ( project->isActiveConfig("qtopialib") ) { + if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA")) + project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QTOPIA", "-L", " -L", ""); + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"]; } if ( project->isActiveConfig("qt") ) { @@ -164,11 +176,15 @@ UnixMakefileGenerator::init() project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG"); if ( !is_qt ) { - if ( !project->isEmpty("QMAKE_LIBDIR_QT") ) { - if ( !project->isEmpty("QMAKE_RPATH") ) - project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", " " + var("QMAKE_RPATH"), - " " + var("QMAKE_RPATH"), ""); - project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", "-L", " -L", ""); + if ( !project->isEmpty("QMAKE_RPATH") ) { + if ( !project->isEmpty("QMAKE_RTLDIR_QT") ) + project->variables()["QMAKE_LFLAGS"] += varGlue("QMAKE_RTLDIR_QT", " " + var("QMAKE_RPATH"), + " " + var("QMAKE_RPATH"), ""); + else if ( !project->isEmpty("QMAKE_LIBDIR_QT") ) + project->variables()["QMAKE_LFLAGS"] += varGlue("QMAKE_LIBDIR_QT", " " + var("QMAKE_RPATH"), + " " + var("QMAKE_RPATH"), ""); } - if (project->isActiveConfig("thread") && !project->isEmpty("QMAKE_LIBS_QT_THREAD")) + if ( !project->isEmpty("QMAKE_LIBDIR_QT") ) + project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", "-L", " -L", ""); + if ( project->isActiveConfig("thread") && !project->isEmpty("QMAKE_LIBS_QT_THREAD") ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; else @@ -176,5 +192,5 @@ UnixMakefileGenerator::init() } } - if ( project->isActiveConfig("opengl") ) { + if ( project->isActiveConfig("opengl") && !project->isActiveConfig("dlopen_opengl")) { project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"]; if(!project->isEmpty("QMAKE_LIBDIR_OPENGL")) @@ -185,6 +201,16 @@ UnixMakefileGenerator::init() project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; } - if(project->isActiveConfig("global_init_link_order")) - project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; + if ( extern_libs && (project->isActiveConfig("qt") || project->isActiveConfig("opengl")) ) { + if(configs.findIndex("x11lib") == -1) + configs.append("x11lib"); + if ( project->isActiveConfig("opengl") && configs.findIndex("x11inc") == -1 ) + configs.append("x11inc"); + } + if ( project->isActiveConfig("x11") ) { + if(configs.findIndex("x11lib") == -1) + configs.append("x11lib"); + if(configs.findIndex("x11inc") == -1) + configs.append("x11inc"); + } if ( project->isActiveConfig("x11inc") ) project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_X11"]; @@ -201,8 +227,12 @@ UnixMakefileGenerator::init() if(project->isActiveConfig("qt")) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT"); - if ( !project->isEmpty("QMAKE_CFLAGS_THREAD")) + if ( !project->isEmpty("QMAKE_CFLAGS_THREAD")) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"]; - if( !project->isEmpty("QMAKE_CXXFLAGS_THREAD")) + project->variables()["PRL_EXPORT_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"]; + } + if( !project->isEmpty("QMAKE_CXXFLAGS_THREAD")) { project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"]; + project->variables()["PRL_EXPORT_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"]; + } project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_THREAD"]; project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_THREAD"]; @@ -212,15 +242,15 @@ UnixMakefileGenerator::init() if ( project->isActiveConfig("moc") ) setMocAware(TRUE); - if ( project->isEmpty("QMAKE_RUN_CC") ) - project->variables()["QMAKE_RUN_CC"].append("$(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src"); - if ( project->isEmpty("QMAKE_RUN_CC_IMP") ) - project->variables()["QMAKE_RUN_CC_IMP"].append("$(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<"); - if ( project->isEmpty("QMAKE_RUN_CXX") ) - project->variables()["QMAKE_RUN_CXX"].append("$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src"); - if ( project->isEmpty("QMAKE_RUN_CXX_IMP") ) - project->variables()["QMAKE_RUN_CXX_IMP"].append("$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<"); - project->variables()["QMAKE_FILETAGS"] += QStringList::split("HEADERS SOURCES TARGET DESTDIR", " "); - if ( !project->isEmpty("PRECOMPH") ) { - initOutPaths(); // Need to fix MOC_DIR since we do this before init() + QString compile_flag = var("QMAKE_COMPILE_FLAG"); + if(compile_flag.isEmpty()) + compile_flag = "-c"; + if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) { + QString prefix_flags = project->first("QMAKE_CFLAGS_PREFIX_INCLUDE"); + if(prefix_flags.isEmpty()) + prefix_flags = "-include"; + compile_flag += " " + prefix_flags + " " + project->first("QMAKE_ORIG_TARGET"); + } + if(!project->isEmpty("ALLMOC_HEADER")) { + initOutPaths(); // Need to fix outdirs since we do this before init() (because we could add to SOURCES et al) QString allmoc = fileFixify(project->first("MOC_DIR") + "/allmoc.cpp", QDir::currentDirPath(), Option::output_dir); project->variables()["SOURCES"].prepend(allmoc); @@ -228,6 +258,17 @@ UnixMakefileGenerator::init() project->variables()["HEADERS"].clear(); } + if ( project->isEmpty("QMAKE_RUN_CC") ) + project->variables()["QMAKE_RUN_CC"].append("$(CC) " + compile_flag + " $(CFLAGS) $(INCPATH) -o $obj $src"); + if ( project->isEmpty("QMAKE_RUN_CC_IMP") ) + project->variables()["QMAKE_RUN_CC_IMP"].append("$(CC) " + compile_flag + " $(CFLAGS) $(INCPATH) -o $@ $<"); + if ( project->isEmpty("QMAKE_RUN_CXX") ) + project->variables()["QMAKE_RUN_CXX"].append("$(CXX) " + compile_flag + " $(CXXFLAGS) $(INCPATH) -o $obj $src"); + if ( project->isEmpty("QMAKE_RUN_CXX_IMP") ) + project->variables()["QMAKE_RUN_CXX_IMP"].append("$(CXX) " + compile_flag + " $(CXXFLAGS) $(INCPATH) -o $@ $<"); + project->variables()["QMAKE_FILETAGS"] += QStringList::split("HEADERS SOURCES TARGET DESTDIR", " "); if( project->isActiveConfig("GNUmake") && !project->isEmpty("QMAKE_CFLAGS_DEPS")) include_deps = TRUE; //do not generate deps + if(project->isActiveConfig("compile_libtool")) + Option::obj_ext = ".lo"; //override the .o MakefileGenerator::init(); @@ -241,8 +282,10 @@ UnixMakefileGenerator::init() project->variables()["ALL_DEPS"] += project->first("QMAKE_PKGINFO"); - QString plist = specdir() + QDir::separator() + "Info.plist." + - project->first("TEMPLATE"); + QString plist = fileFixify(project->first("QMAKE_INFO_PLIST")); + if(plist.isEmpty()) + plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"); if(QFile::exists(Option::fixPathToLocalOS(plist))) { - project->variables()["QMAKE_INFO_PLIST"].append(plist); + if(project->isEmpty("QMAKE_INFO_PLIST")) + project->variables()["QMAKE_INFO_PLIST"].append(plist); project->variables()["QMAKE_INFO_PLIST_OUT"].append(project->first("DESTDIR") + "../Info.plist"); @@ -284,47 +327,103 @@ UnixMakefileGenerator::init() } } + + if(project->isActiveConfig("compile_libtool")) { + const QString libtoolify[] = { "QMAKE_RUN_CC", "QMAKE_RUN_CC_IMP", + "QMAKE_RUN_CXX", "QMAKE_RUN_CXX_IMP", + "QMAKE_LINK_THREAD", "QMAKE_LINK", "QMAKE_AR_CMD", "QMAKE_LINK_SHLIB_CMD", + QString::null }; + for(int i = 0; !libtoolify[i].isNull(); i++) { + QStringList &l = project->variables()[libtoolify[i]]; + if(!l.isEmpty()) { + QString libtool_flags, comp_flags; + if(libtoolify[i].startsWith("QMAKE_LINK") || libtoolify[i] == "QMAKE_AR_CMD") { + libtool_flags += " --mode=link"; + if(project->isActiveConfig("staticlib")) { + libtool_flags += " -static"; + } else { + if(!project->isEmpty("QMAKE_LIB_FLAG")) { + int maj = project->first("VER_MAJ").toInt(); + int min = project->first("VER_MIN").toInt(); + int pat = project->first("VER_PAT").toInt(); + comp_flags += " -version-info " + QString::number(10*maj + min) + + ":" + QString::number(pat) + ":0"; + if(libtoolify[i] != "QMAKE_AR_CMD") { + QString rpath = Option::output_dir; + if(!project->isEmpty("DESTDIR")) { + rpath = project->first("DESTDIR"); + if(QDir::isRelativePath(rpath)) + rpath.prepend(Option::output_dir + Option::dir_sep); + } + comp_flags += " -rpath " + Option::fixPathToTargetOS(rpath, FALSE); + } + } + } + if(project->isActiveConfig("plugin")) + libtool_flags += " -module"; + } else { + libtool_flags += " --mode=compile"; + } + l.first().prepend("$(LIBTOOL)" + libtool_flags + " "); + if(!comp_flags.isEmpty()) + l.first() += comp_flags; + } + } + } } QStringList -UnixMakefileGenerator::uniqueSetLFlags(const QStringList &list1, QStringList &list2) +UnixMakefileGenerator::combineSetLFlags(const QStringList &list1, const QStringList &list2) { + if(project->isActiveConfig("no_smart_library_merge")) + return list1 + list2; + QStringList ret; - for(QStringList::ConstIterator it = list1.begin(); it != list1.end(); ++it) { - bool unique = TRUE; - if((*it).startsWith("-")) { - if((*it).startsWith("-l") || (*it).startsWith("-L")) { - unique = list2.findIndex((*it)) == -1; - } else if(project->isActiveConfig("macx") && (*it).startsWith("-framework")) { - int as_one = TRUE; - QString framework_in; - if((*it).length() > 11) { - framework_in = (*it).mid(11); - } else { - if(it != list1.end()) { - ++it; - as_one = FALSE; - framework_in = (*it); + for(int i = 0; i < 2; i++) { + const QStringList *lst = i ? &list2 : &list1; + for(QStringList::ConstIterator it = lst->begin(); it != lst->end(); ++it) { + if((*it).startsWith("-")) { + if((*it).startsWith("-L")) { + if(ret.findIndex((*it)) == -1) + ret.append((*it)); + } else if((*it).startsWith("-l")) { + while(1) { + QStringList::Iterator idx = ret.find((*it)); + if(idx == ret.end()) + break; + ret.remove(idx); } - } - if(!framework_in.isEmpty()) { - for(QStringList::ConstIterator outit = list2.begin(); outit != list2.end(); ++outit) { - if((*outit).startsWith("-framework")) { - QString framework_out; - if((*outit).length() > 11) { - framework_out = (*outit).mid(11); - } else { - if(it != list2.end()) { - ++outit; - framework_out = (*outit); + ret.append((*it)); + } else if(project->isActiveConfig("macx") && (*it).startsWith("-framework")) { + int as_one = TRUE; + QString framework_in; + if((*it).length() > 11) { + framework_in = (*it).mid(11); + } else { + if(it != lst->end()) { + ++it; + as_one = FALSE; + framework_in = (*it); + } + } + if(!framework_in.isEmpty()) { + for(QStringList::Iterator outit = ret.begin(); outit != ret.end(); ++outit) { + if((*outit).startsWith("-framework")) { + int found = 0; + if((*outit).length() > 11) { + if(framework_in == (*outit).mid(11)) + found = 1; + } else { + if(it != lst->end()) { + ++outit; + if(framework_in == (*outit)) { + --outit; + found = 2; + } + } } - } - if(framework_out == framework_in) { - unique = FALSE; - break; + for(int i = 0; i < found; i++) + outit = ret.remove(outit); } } - } - if(unique) { - unique = FALSE; //because I'm about to just insert it myself if(as_one) { ret.append("-framework " + framework_in); @@ -334,27 +433,105 @@ UnixMakefileGenerator::uniqueSetLFlags(const QStringList &list1, QStringList &li } } + } else { +#if 1 + while(1) { + QStringList::Iterator idx = ret.find((*it)); + if(idx == ret.end()) + break; + ret.remove(idx); + } +#endif + ret.append((*it)); } - } else { - unique = (list2.findIndex((*it)) == -1); + } else /*if(QFile::exists((*it)))*/ { + while(1) { + QStringList::Iterator idx = ret.find((*it)); + if(idx == ret.end()) + break; + ret.remove(idx); + } + ret.append((*it)); } - } else if(QFile::exists((*it))) { - unique = (list2.findIndex((*it)) == -1); } - if(unique) - ret.append((*it)); } return ret; } - void UnixMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l) { if(var == "QMAKE_PRL_LIBS") - project->variables()["QMAKE_CURRENT_PRL_LIBS"] += uniqueSetLFlags(l, project->variables()["QMAKE_LIBS"]); + project->variables()["QMAKE_CURRENT_PRL_LIBS"] = combineSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"] + + project->variables()["QMAKE_LIBS"], l); else MakefileGenerator::processPrlVariable(var, l); } +QString +UnixMakefileGenerator::findDependency(const QString &dep) +{ + QStringList::Iterator it; + { + QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"]; + for(it = qut.begin(); it != qut.end(); ++it) { + QString targ = var((*it) + ".target"); + if(targ.isEmpty()) + targ = (*it); + if(targ.endsWith(dep)) + return targ; + } + } + { + QStringList &quc = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QString out = tmp_out; + QFileInfo fi(Option::fixPathToLocalOS((*input))); + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(out.endsWith(dep)) + return out; + } + } + } + } + return MakefileGenerator::findDependency(dep); +} + +QStringList +&UnixMakefileGenerator::findDependencies(const QString &file) +{ + QStringList &ret = MakefileGenerator::findDependencies(file); + // Note: The QMAKE_IMAGE_COLLECTION file have all images + // as dependency, so don't add precompiled header then + if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER") + && file != project->first("QMAKE_IMAGE_COLLECTION")) { + QString header_prefix = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep; + header_prefix += project->first("QMAKE_PRECOMP_PREFIX"); + if(file.endsWith(".c")) { + QString precomp_h = header_prefix + "c"; + if(!ret.contains(precomp_h)) + ret += precomp_h; + } else { + for(QStringList::Iterator it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) { + if(file.endsWith(*it)) { + QString precomp_h = header_prefix + "c++"; + if(!ret.contains(precomp_h)) + ret += precomp_h; + break; + } + } + } + } + return ret; +} + bool UnixMakefileGenerator::findLibraries() @@ -401,5 +578,5 @@ UnixMakefileGenerator::findLibraries() } if(!stub.isEmpty()) { - const QString modifs[] = { "-mt", QString::null }; + const QString modifs[] = { "", "-mt", QString::null }; for(int modif = 0; !modifs[modif].isNull(); modif++) { bool found = FALSE; @@ -432,6 +609,16 @@ UnixMakefileGenerator::findLibraries() } } + if(!found && project->isActiveConfig("compile_libtool")) { + for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { + if(QFile::exists(mdd->local_dir + Option::dir_sep + "lib" + stub + modifs[modif] + Option::libtool_ext)) { + (*it) = mdd->real_dir + Option::dir_sep + "lib" + stub + modifs[modif] + Option::libtool_ext; + found = TRUE; + break; + } + } + } if(found) break; + } } @@ -441,4 +628,12 @@ UnixMakefileGenerator::findLibraries() } +QString linkLib(const QString &file, const QString &libName) { + QString ret; + QRegExp reg("^.*lib(" + libName + "[^./=]*).*$"); + if(reg.exactMatch(file)) + ret = "-l" + reg.cap(1); + return ret; +} + void UnixMakefileGenerator::processPrlFiles() @@ -454,5 +649,5 @@ UnixMakefileGenerator::processPrlFiles() for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { project->variables()["QMAKE_CURRENT_PRL_LIBS"].clear(); - QString opt = (*it).stripWhiteSpace();; + QString opt = (*it).stripWhiteSpace(); if(opt.startsWith("-")) { if(opt.startsWith("-L")) { @@ -462,14 +657,20 @@ UnixMakefileGenerator::processPrlFiles() l.replace("\"",""))); } else if(opt.startsWith("-l") && !processed[opt]) { - QString lib = opt.right(opt.length() - 2), prl; + QString lib = opt.right(opt.length() - 2); for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { - prl = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::prl_ext; + if(!project->isActiveConfig("compile_libtool")) { //give them the .libs.. + QString la = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::libtool_ext; + if(QFile::exists(la) && QFile::exists(mdd->local_dir + Option::dir_sep + ".libs")) { + l_out.append("-L" + mdd->real_dir + Option::dir_sep + ".libs"); + libdirs.append(new MakefileDependDir(mdd->real_dir + Option::dir_sep + ".libs", + mdd->local_dir + Option::dir_sep + ".libs")); + } + } + + QString prl = mdd->local_dir + Option::dir_sep + "lib" + lib; if(processPrlFile(prl)) { if(prl.startsWith(mdd->local_dir)) prl.replace(0, mdd->local_dir.length(), mdd->real_dir); - QRegExp reg("^.*lib(" + lib + "[^./=]*)\\..*$"); - if(reg.exactMatch(prl)) - prl = "-l" + reg.cap(1); - opt = prl; + opt = linkLib(prl, lib); processed.insert(opt, (void*)1); ret = TRUE; @@ -485,5 +686,5 @@ UnixMakefileGenerator::processPrlFiles() } QString prl = "/System/Library/Frameworks/" + opt + - ".framework/" + opt + Option::prl_ext; + ".framework/" + opt; if(processPrlFile(prl)) ret = TRUE; @@ -492,13 +693,18 @@ UnixMakefileGenerator::processPrlFiles() if(!opt.isEmpty()) l_out.append(opt); - l_out += uniqueSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"], l_out); + l_out = combineSetLFlags(l_out, project->variables()["QMAKE_CURRENT_PRL_LIBS"]); } else { - if(!processed[opt] && processPrlFile(opt)) { - processed.insert(opt, (void*)1); - ret = TRUE; + QString lib = opt; + if(!processed[lib] && processPrlFile(lib)) { + processed.insert(lib, (void*)1); + ret = TRUE; } +#if 0 + if(ret) + opt = linkLib(lib, ""); +#endif if(!opt.isEmpty()) - l_out.append(opt); - l_out += uniqueSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"], l_out); + l_out.append(opt); + l_out = combineSetLFlags(l_out, project->variables()["QMAKE_CURRENT_PRL_LIBS"]); } } @@ -538,5 +744,6 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } } else if(project->first("TEMPLATE") == "lib") { - if(project->isActiveConfig("create_prl") && !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) { + if(project->isActiveConfig("create_prl") && !project->isActiveConfig("no_install_prl") && + !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) { QString dst_prl = project->first("QMAKE_INTERNAL_PRL_FILE"); int slsh = dst_prl.findRev('/'); @@ -544,9 +751,56 @@ UnixMakefileGenerator::defaultInstall(const QString &t) dst_prl = dst_prl.right(dst_prl.length() - slsh - 1); dst_prl = root + targetdir + dst_prl; - ret += "-$(COPY) \"" + project->first("QMAKE_INTERNAL_PRL_FILE") + "\" \"" + dst_prl + "\""; + ret += "-$(INSTALL_FILE) \"" + project->first("QMAKE_INTERNAL_PRL_FILE") + "\" \"" + dst_prl + "\""; if(!uninst.isEmpty()) uninst.append("\n\t"); uninst.append("-$(DEL_FILE) \"" + dst_prl + "\""); } + if(project->isActiveConfig("create_libtool") && !project->isActiveConfig("compile_libtool")) { + QString src_lt = var("QMAKE_ORIG_TARGET"); + int slsh = src_lt.findRev(Option::dir_sep); + if(slsh != -1) + src_lt = src_lt.right(src_lt.length() - slsh); + int dot = src_lt.find('.'); + if(dot != -1) + src_lt = src_lt.left(dot); + src_lt += Option::libtool_ext; + src_lt.prepend("lib"); + QString dst_lt = root + targetdir + src_lt; + if(!project->isEmpty("DESTDIR")) { + src_lt.prepend(var("DESTDIR")); + src_lt = Option::fixPathToLocalOS(fileFixify(src_lt, + QDir::currentDirPath(), Option::output_dir)); + } + if(!ret.isEmpty()) + ret += "\n\t"; + ret += "-$(INSTALL_FILE) \"" + src_lt + "\" \"" + dst_lt + "\""; + if(!uninst.isEmpty()) + uninst.append("\n\t"); + uninst.append("-$(DEL_FILE) \"" + dst_lt + "\""); + } + if(project->isActiveConfig("create_pc")) { + QString src_pc = var("QMAKE_ORIG_TARGET"); + int slsh = src_pc.findRev(Option::dir_sep); + if(slsh != -1) + src_pc = src_pc.right(src_pc.length() - slsh); + int dot = src_pc.find('.'); + if(dot != -1) + src_pc = src_pc.left(dot); + src_pc += ".pc"; + QString d = root + targetdir + "pkgconfig" + Option::dir_sep; + QString dst_pc = d + src_pc; + if(!project->isEmpty("DESTDIR")) { + src_pc.prepend(var("DESTDIR")); + src_pc = Option::fixPathToLocalOS(fileFixify(src_pc, + QDir::currentDirPath(), Option::output_dir)); + } + if(!ret.isEmpty()) + ret += "\n\t"; + ret += mkdir_p_asstring(d) + "\n\t"; + ret += "-$(INSTALL_FILE) \"" + src_pc + "\" \"" + dst_pc + "\""; + if(!uninst.isEmpty()) + uninst.append("\n\t"); + uninst.append("-$(DEL_FILE) \"" + dst_pc + "\""); + } if ( project->isEmpty("QMAKE_CYGWIN_SHLIB") ) { if ( !project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin") ) { @@ -559,42 +813,62 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } } - QString src_targ = target; - if(!destdir.isEmpty()) - src_targ = Option::fixPathToTargetOS(destdir + target, FALSE); - QString dst_targ = root + fileFixify(targetdir + target); - if(!ret.isEmpty()) - ret += "\n\t"; - ret += QString(resource ? "-$(COPY_DIR)" : "-$(COPY)") + " \"" + - src_targ + "\" \"" + dst_targ + "\""; - if(!project->isActiveConfig("debug") && !project->isEmpty("QMAKE_STRIP")) { - ret += "\n\t-" + var("QMAKE_STRIP"); - if(!project->isEmpty("QMAKE_STRIPFLAGS_LIB") && project->first("TEMPLATE") == "lib") - ret += " " + var("QMAKE_STRIPFLAGS_LIB"); + + if(!resource && project->isActiveConfig("compile_libtool")) { + QString src_targ = target; + if(src_targ == "$(TARGET)") + src_targ = "$(TARGETL)"; + QString dst_dir = fileFixify(targetdir); + if(QDir::isRelativePath(dst_dir)) + dst_dir = Option::fixPathToTargetOS(Option::output_dir + Option::dir_sep + dst_dir); + ret = "-$(LIBTOOL) --mode=install cp \"" + src_targ + "\" \"" + root + dst_dir + "\""; + uninst.append("-$(LIBTOOL) --mode=uninstall \"" + src_targ + "\""); + } else { + QString src_targ = target; + if(!destdir.isEmpty()) + src_targ = Option::fixPathToTargetOS(destdir + target, FALSE); + QString dst_targ = root + fileFixify(targetdir + target, + QDir::currentDirPath(), Option::output_dir); + if(!ret.isEmpty()) + ret += "\n\t"; if(resource) - ret = " \"" + dst_targ + "/Contents/MacOS/$(QMAKE_TARGET)\""; + ret += "$(DEL_FILE) -r \"" + dst_targ + "\"" + "\n\t"; + if(!ret.isEmpty()) + ret += "\n\t"; + ret += QString(resource ? "-$(INSTALL_DIR)" : "-$(INSTALL_FILE)") + " \"" + + src_targ + "\" \"" + dst_targ + "\""; + if(!project->isActiveConfig("debug") && !project->isEmpty("QMAKE_STRIP") && + (project->first("TEMPLATE") != "lib" || !project->isActiveConfig("staticlib"))) { + ret += "\n\t-" + var("QMAKE_STRIP"); + if(project->first("TEMPLATE") == "lib" && !project->isEmpty("QMAKE_STRIPFLAGS_LIB")) + ret += " " + var("QMAKE_STRIPFLAGS_LIB"); + else if(project->first("TEMPLATE") == "app" && !project->isEmpty("QMAKE_STRIPFLAGS_APP")) + ret += " " + var("QMAKE_STRIPFLAGS_APP"); + if(resource) + ret = " \"" + dst_targ + "/Contents/MacOS/$(QMAKE_TARGET)\""; + else + ret += " \"" + dst_targ + "\""; + } + if(!uninst.isEmpty()) + uninst.append("\n\t"); + if(resource) + uninst.append("-$(DEL_FILE) -r \"" + dst_targ + "\""); else - ret += " \"" + dst_targ + "\""; - } - if(!uninst.isEmpty()) - uninst.append("\n\t"); - if(resource) - uninst.append("-$(DEL_FILE) -r \"" + dst_targ + "\""); - else - uninst.append("-$(DEL_FILE) \"" + dst_targ + "\""); - if(!links.isEmpty()) { - for(QStringList::Iterator it = links.begin(); it != links.end(); it++) { - if(Option::target_mode == Option::TARG_WIN_MODE || - Option::target_mode == Option::TARG_MAC9_MODE) { - } else if(Option::target_mode == Option::TARG_UNIX_MODE || - Option::target_mode == Option::TARG_MACX_MODE) { - QString link = Option::fixPathToTargetOS(destdir + (*it), FALSE); - int lslash = link.findRev(Option::dir_sep); - if(lslash != -1) - link = link.right(link.length() - (lslash + 1)); - QString dst_link = root + fileFixify(targetdir + link); - ret += "\n\t-$(SYMLINK) \"$(TARGET)\" \"" + dst_link + "\""; - if(!uninst.isEmpty()) - uninst.append("\n\t"); - uninst.append("-$(DEL_FILE) \"" + dst_link + "\""); + uninst.append("-$(DEL_FILE) \"" + dst_targ + "\""); + if(!links.isEmpty()) { + for(QStringList::Iterator it = links.begin(); it != links.end(); it++) { + if(Option::target_mode == Option::TARG_WIN_MODE || + Option::target_mode == Option::TARG_MAC9_MODE) { + } else if(Option::target_mode == Option::TARG_UNIX_MODE || + Option::target_mode == Option::TARG_MACX_MODE) { + QString link = Option::fixPathToTargetOS(destdir + (*it), FALSE); + int lslash = link.findRev(Option::dir_sep); + if(lslash != -1) + link = link.right(link.length() - (lslash + 1)); + QString dst_link = root + targetdir + link; + ret += "\n\t-$(SYMLINK) \"$(TARGET)\" \"" + dst_link + "\""; + if(!uninst.isEmpty()) + uninst.append("\n\t"); + uninst.append("-$(DEL_FILE) \"" + dst_link + "\""); + } } } @@ -602,3 +876,2 @@ UnixMakefileGenerator::defaultInstall(const QString &t) return ret; } - diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h index 3d00214..91ec3b1 100644 --- a/qmake/generators/unix/unixmake.h +++ b/qmake/generators/unix/unixmake.h @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of UnixMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -35,4 +33,5 @@ ** **********************************************************************/ + #ifndef __UNIXMAKE_H__ #define __UNIXMAKE_H__ @@ -44,5 +43,13 @@ class UnixMakefileGenerator : public MakefileGenerator bool init_flag, include_deps; bool writeMakefile(QTextStream &); - QStringList uniqueSetLFlags(const QStringList &list1, QStringList &list2); + void writeExtraVariables(QTextStream &); + QString libtoolFileName(); + void writeLibtoolFile(); // for libtool + QString pkgConfigPrefix() const; + QString pkgConfigFileName(); + QString pkgConfigFixPath(QString) const; + void writePkgConfigFile(); // for pkg-config + QStringList combineSetLFlags(const QStringList &list1, const QStringList &list2); + void writePrlFile(QTextStream &); public: @@ -51,4 +58,5 @@ public: protected: + virtual bool doPrecompiledHeaders() const { return project->isActiveConfig("precompile_header"); } virtual bool doDepends() const { return !include_deps && MakefileGenerator::doDepends(); } virtual QString defaultInstall(const QString &); @@ -57,4 +65,6 @@ protected: virtual bool findLibraries(); + virtual QString findDependency(const QString &); + virtual QStringList &findDependencies(const QString &); virtual void init(); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index d8a4a0d..21348a6 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ ** -** Definition of ________ class. ** -** Created : 970521 +** Implementation of UnixMakefileGenerator class. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -38,4 +36,5 @@ #include "unixmake.h" #include "option.h" +#include "meta.h" #include <qregexp.h> #include <qfile.h> @@ -43,4 +42,5 @@ #include <time.h> +QString mkdir_p_asstring(const QString &dir); UnixMakefileGenerator::UnixMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE), include_deps(FALSE) @@ -49,10 +49,34 @@ UnixMakefileGenerator::UnixMakefileGenerator(QMakeProject *p) : MakefileGenerato } +void +UnixMakefileGenerator::writePrlFile(QTextStream &t) +{ + MakefileGenerator::writePrlFile(t); + // libtool support + if(project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib") { //write .la + if(project->isActiveConfig("compile_libtool")) + warn_msg(WarnLogic, "create_libtool specified with compile_libtool can lead to conflicting .la\n" + "formats, create_libtool has been disabled\n"); + else + writeLibtoolFile(); + } + // pkg-config support + if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib") + writePkgConfigFile(); +} + bool UnixMakefileGenerator::writeMakefile(QTextStream &t) { + writeHeader(t); if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { - t << "all clean:" << "\n\t" + t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; + { //write the extra unix targets.. + QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"]; + for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it) + t << *it << " "; + } + t << "all clean install distclean mocables uninstall uicables:" << "\n\t" << "@echo \"Some of the required modules (" << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t" @@ -74,11 +98,33 @@ UnixMakefileGenerator::writeMakefile(QTextStream &t) void +UnixMakefileGenerator::writeExtraVariables(QTextStream &t) +{ + bool first = TRUE; + QMap<QString, QStringList> &vars = project->variables(); + QStringList &exports = project->variables()["QMAKE_EXTRA_UNIX_VARIABLES"]; + for(QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) { + for(QStringList::Iterator exp_it = exports.begin(); exp_it != exports.end(); ++exp_it) { + QRegExp rx((*exp_it), FALSE, TRUE); + if(rx.exactMatch(it.key())) { + if(first) { + t << "\n####### Custom Variables" << endl; + first = FALSE; + } + t << "EXPORT_" << it.key() << " = " << it.data().join(" ") << endl; + } + } + } + if(!first) + t << endl; +} + +void UnixMakefileGenerator::writeMakeParts(QTextStream &t) { - QString deps = fileFixify(Option::output.name()), prl; + QString deps = fileFixify(Option::output.name()), target_deps, prl; bool do_incremental = (project->isActiveConfig("incremental") && !project->variables()["QMAKE_INCREMENTAL"].isEmpty() && (!project->variables()["QMAKE_APP_FLAG"].isEmpty() || - !project->isActiveConfig("staticlib"))), + !project->isActiveConfig("staticlib"))), src_incremental=FALSE, moc_incremental=FALSE; @@ -136,7 +182,12 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "TAR = " << var("QMAKE_TAR") << endl; t << "GZIP = " << var("QMAKE_GZIP") << endl; + if(project->isActiveConfig("compile_libtool")) + t << "LIBTOOL = " << var("QMAKE_LIBTOOL") << endl; t << "COPY = " << var("QMAKE_COPY") << endl; t << "COPY_FILE= " << var("QMAKE_COPY_FILE") << endl; t << "COPY_DIR = " << var("QMAKE_COPY_DIR") << endl; + t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl; + t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "SYMLINK = " << var("QMAKE_SYMBOLIC_LINK") << endl; @@ -221,7 +272,23 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(do_incremental && !moc_incremental && !src_incremental) do_incremental = FALSE; + if(!project->isEmpty("QMAKE_EXTRA_UNIX_COMPILERS")) { + t << "OBJCOMP = " << varList("OBJCOMP") << endl; + target_deps += " $(OBJCOMP)"; + + QStringList &comps = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"]; + for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) { + QStringList &vars = project->variables()[(*compit) + ".variables"]; + for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) { + QStringList vals = project->variables()[(*varit)]; + if(!vals.isEmpty()) + t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << endl; + } + } + } t << "DIST = " << valList(fileFixify(project->variables()["DISTFILES"])) << endl; t << "QMAKE_TARGET = " << var("QMAKE_ORIG_TARGET") << endl; t << "DESTDIR = " << var("DESTDIR") << endl; + if(project->isActiveConfig("compile_libtool")) + t << "TARGETL = " << var("TARGET_la") << endl; t << "TARGET = " << var("TARGET") << endl; if(project->isActiveConfig("plugin") ) { @@ -239,7 +306,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } } + writeExtraVariables(t); t << endl; - // blasted incldues + // blasted includes QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"]; QStringList::Iterator it; @@ -250,5 +318,5 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "first: all" << endl; t << "####### Implicit rules" << endl << endl; - t << ".SUFFIXES: .c"; + t << ".SUFFIXES: .c " << Option::obj_ext; QStringList::Iterator cppit; for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) @@ -256,6 +324,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << endl << endl; for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) - t << (*cppit) << ".o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".c.o:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; + t << (*cppit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".c" << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; if(include_deps) { @@ -279,5 +347,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << "@$(CC) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl; - QString src[] = { "SOURCES", "UICIMPLS", "SRCMOC", QString::null }; for(int x = 0; !src[x].isNull(); x++) { @@ -299,8 +366,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!d_file.isEmpty()) { d_file = odir + ".deps/" + d_file + ".d"; - QStringList deps = findDependencies((*it)).grep(QRegExp(Option::moc_ext + "$")); + QStringList deps = findDependencies((*it)).grep(QRegExp(Option::cpp_moc_ext + "$")); if(!deps.isEmpty()) t << d_file << ": " << deps.join(" ") << endl; - t << "-include " << d_file << endl; + t << var("QMAKE_CFLAGS_USE_PRECOMPILE") << " " << d_file << endl; } } @@ -324,15 +391,15 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) QStringList::Iterator it; for(it = l.begin(); it != l.end(); ++it) { - QMakeProject proj; - if(proj.read((*it), QDir::currentDirPath()) && !proj.isEmpty("QMAKE_PRL_BUILD_DIR")) { + QMakeMetaInfo libinfo; + if(libinfo.readLib((*it)) && !libinfo.isEmpty("QMAKE_PRL_BUILD_DIR")) { QString dir; int slsh = (*it).findRev(Option::dir_sep); if(slsh != -1) dir = (*it).left(slsh + 1); - QString targ = dir + proj.first("QMAKE_PRL_TARGET"); + QString targ = dir + libinfo.first("QMAKE_PRL_TARGET"); deps += " " + targ; t << targ << ":" << "\n\t" << "@echo \"Creating '" << targ << "'\"" << "\n\t" - << "(cd " << proj.first("QMAKE_PRL_BUILD_DIR") << ";" + << "(cd " << libinfo.first("QMAKE_PRL_BUILD_DIR") << ";" << "$(MAKE) )" << endl; } @@ -393,5 +460,5 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) //real target - t << var("TARGET") << ": " << var("PRE_TARGETDEPS") << " " << incr_deps + t << var("TARGET") << ": " << var("PRE_TARGETDEPS") << " " << incr_deps << " " << target_deps << " " << var("POST_TARGETDEPS") << "\n\t"; if(!destdir.isEmpty()) @@ -399,5 +466,5 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_PRE_LINK")) t << var("QMAKE_PRE_LINK") << "\n\t"; - t << "$(LINK) $(LFLAGS) -o $(TARGET) " << incr_deps << " " << incr_objs << " $(LIBS)"; + t << "$(LINK) $(LFLAGS) -o $(TARGET) " << incr_deps << " " << incr_objs << " $(OBJCOMP) $(LIBS)"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); @@ -407,11 +474,11 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << endl << endl; - t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " - << var("POST_TARGETDEPS") << "\n\t"; + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << target_deps << " " << var("POST_TARGETDEPS") << "\n\t"; if(!destdir.isEmpty()) t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; if(!project->isEmpty("QMAKE_PRE_LINK")) t << var("QMAKE_PRE_LINK") << "\n\t"; - t << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)"; + t << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(OBJCOMP) $(LIBS)"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); @@ -469,11 +536,12 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) //real target - t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") << " " - << incr_deps << " $(SUBLIBS) " << var("POST_TARGETDEPS"); + t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") << " " + << incr_deps << " $(SUBLIBS) " << target_deps << " " << var("POST_TARGETDEPS"); } else { t << "all: " << deps << " " << varGlue("ALL_DEPS",""," ","") << " " << var("DESTDIR_TARGET") << endl << endl; - t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") - << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) " << var("POST_TARGETDEPS"); + t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") + << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) $(OBJCOMP) " << target_deps + << " " << var("POST_TARGETDEPS"); } if(!destdir.isEmpty()) @@ -482,5 +550,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "\n\t" << var("QMAKE_PRE_LINK"); - if(project->isActiveConfig("plugin")) { + if(project->isActiveConfig("compile_libtool")) { + t << "\n\t" + << var("QMAKE_LINK_SHLIB_CMD"); + } else if(project->isActiveConfig("plugin")) { t << "\n\t" << "-$(DEL_FILE) $(TARGET)" << "\n\t" @@ -527,5 +598,5 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if (! project->isActiveConfig("plugin")) { t << "staticlib: $(TARGETA)" << endl << endl; - t << "$(TARGETA): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC)"; + t << "$(TARGETA): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(OBJCOMP)"; if(do_incremental) t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"; @@ -540,10 +611,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } } else { - t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << var("DESTDIR") << "$(TARGET) " + t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << var("DESTDIR") << "$(TARGET) " << varGlue("QMAKE_AR_SUBLIBS", var("DESTDIR"), " " + var("DESTDIR"), "") << "\n\n" << "staticlib: " << var("DESTDIR") << "$(TARGET)" << "\n\n"; if(project->isEmpty("QMAKE_AR_SUBLIBS")) { - t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") - << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("POST_TARGETDEPS") << "\n\t"; + t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") + << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(OBJCOMP) " << var("POST_TARGETDEPS") << "\n\t"; if(!project->isEmpty("DESTDIR")) { QString destdir = project->first("DESTDIR"); @@ -556,23 +627,24 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_RANLIB")) t << "\t" << "$(RANLIB) $(TARGET)" << "\n"; - if(!project->isEmpty("DESTDIR")) + if(!project->isEmpty("DESTDIR")) t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)" << "\n" << "\t" << "-$(MOVE) $(TARGET) " << var("DESTDIR") << "\n"; } else { int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(); - QStringList objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"], + QStringList objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"] + + project->variables()["OBJCOMP"], libs = project->variables()["QMAKE_AR_SUBLIBS"]; libs.prepend("$(TARGET)"); - for(QStringList::Iterator libit = libs.begin(), objit = objs.begin(); + for(QStringList::Iterator libit = libs.begin(), objit = objs.begin(); libit != libs.end(); ++libit) { QStringList build; - for(int cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++) + for(int cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++) build << (*objit); QString ar; if((*libit) == "$(TARGET)") { - t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") + t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) " << var("POST_TARGETDEPS") << valList(build) << "\n\t"; ar = project->variables()["QMAKE_AR_CMD"].first(); - ar = ar.replace("$(OBJMOC)", "").replace("$(OBJECTS)", + ar = ar.replace("$(OBJMOC)", "").replace("$(OBJECTS)", build.join(" ")); } else { @@ -590,5 +662,5 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_RANLIB")) t << "\t" << "$(RANLIB) " << (*libit) << "\n"; - if(!project->isEmpty("DESTDIR")) + if(!project->isEmpty("DESTDIR")) t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << (*libit) << "\n" << "\t" << "-$(MOVE) " << (*libit) << " " << var("DESTDIR") << "\n"; @@ -598,5 +670,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } - t << "mocables: $(SRCMOC)" << endl << endl; + t << "mocables: $(SRCMOC)" << endl + << "uicables: $(UICDECLS) $(UICIMPLS)" << endl << endl; if(!project->isActiveConfig("no_mocdepend")) { @@ -604,13 +677,35 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) //moc itself shouldn't have this dependency - this is a little kludgy but it is //better than the alternative for now. - QString moc = project->first("QMAKE_MOC"), target = project->first("TARGET"); + QString moc = project->first("QMAKE_MOC"), target = project->first("TARGET"), + moc_dir = "$(QTDIR)/src/moc"; + if(!project->isEmpty("QMAKE_MOC_SRC")) + moc_dir = project->first("QMAKE_MOC_SRC"); fixEnvVariables(target); fixEnvVariables(moc); - if(target != moc) + if(target != moc) t << "$(MOC): \n\t" - << "( cd $(QTDIR)/src/moc ; $(MAKE) )" << endl << endl; + << "( cd " << moc_dir << " && $(MAKE) )" << endl << endl; } writeMakeQmake(t); + if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isActiveConfig("no_autoqmake")) { + QString meta_files; + if(project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib" && + !project->isActiveConfig("compile_libtool")) { //libtool + if(!meta_files.isEmpty()) + meta_files += " "; + meta_files += libtoolFileName(); + } + if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib") { //pkg-config + if(!meta_files.isEmpty()) + meta_files += " "; + meta_files += pkgConfigFileName(); + } + if(!meta_files.isEmpty()) { + QStringList files = fileFixify(Option::mkfile::project_files); + t << meta_files << ": " << "\n\t" + << "@$(QMAKE) -prl " << buildArgs() << " " << files.join(" ") << endl; + } + } if(!project->first("QMAKE_PKGINFO").isEmpty()) { @@ -625,5 +720,5 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->first("QMAKE_INFO_PLIST").isEmpty()) { QString info_plist = project->first("QMAKE_INFO_PLIST"), - info_plist_out = project->first("QMAKE_INFO_PLIST_OUT"); + info_plist_out = project->first("QMAKE_INFO_PLIST_OUT"); QString destdir = project->first("DESTDIR"); t << info_plist_out << ": " << "\n\t"; @@ -631,10 +726,12 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "@test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; t << "@$(DEL_FILE) " << info_plist_out << "\n\t" - << "@cp \"" << info_plist << "\" \"" << info_plist_out << "\"" << endl; + << "@sed -e \"s,@ICON@,application.icns,g\" -e \"s,@EXECUTABLE@," << var("QMAKE_ORIG_TARGET") + << ",g\" \"" << info_plist << "\" >\"" << info_plist_out << "\"" << endl; if(!project->first("RC_FILE").isEmpty()) { QString dir = destdir + "../Resources/"; - t << dir << "application.icns:" << "\n\t" + t << dir << "application.icns: " << var("RC_FILE") << "\n\t" << "@test -d " << dir << " || mkdir -p " << dir << "\n\t" - << "@cp " << var("RC_FILE") << " " << dir << "application.icns" << endl; + << "@$(DEL_FILE) " << dir << "application.icns" << "\n\t" + << "@$(COPY_FILE) " << var("RC_FILE") << " " << dir << "application.icns" << endl; } } @@ -649,9 +746,11 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("TRANSLATIONS")) t << "$(COPY_FILE) --parents " << var("TRANSLATIONS") << " " << ddir_c << Option::dir_sep << " && "; + if(!project->isEmpty("IMAGES")) + t << "$(COPY_FILE) --parents " << var("IMAGES") << " " << ddir_c << Option::dir_sep << " && "; if(!project->isEmpty("FORMS")) { QStringList &forms = project->variables()["FORMS"], ui_headers; for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) { QString ui_h = fileFixify((*formit) + Option::h_ext.first()); - if(QFile::exists(ui_h) ) + if(QFile::exists(ui_h) ) ui_headers << ui_h; } @@ -667,6 +766,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) QString clean_targets; + t << "mocclean:" << "\n"; if(mocAware()) { - t << "mocclean:" << "\n"; if(!objMoc.isEmpty() || !srcMoc.isEmpty() || moc_incremental) { if(!objMoc.isEmpty()) @@ -698,6 +797,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; - clean << dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first(); - clean << dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first(); + clean << ( dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first() ); + clean << ( dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first() ); } if(!clean.isEmpty()) { @@ -718,5 +817,5 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; - clean << dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first(); + clean << ( dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first() ); } if(!clean.isEmpty()) { @@ -736,6 +835,16 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "clean:" << clean_targets << "\n\t"; - if(!project->isEmpty("OBJECTS")) - t << "-$(DEL_FILE) $(OBJECTS) " << "\n\t"; + if(!project->isEmpty("OBJECTS")) { + if(project->isActiveConfig("compile_libtool")) + t << "-$(LIBTOOL) --mode=clean $(DEL_FILE) $(OBJECTS)" << "\n\t"; + else + t << "-$(DEL_FILE) $(OBJECTS)" << "\n\t"; + } + if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) { + QString header_prefix = project->first("QMAKE_PRECOMP_PREFIX"); + QString precomph_out_dir = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep; + t << "-$(DEL_FILE) " << precomph_out_dir << header_prefix + "c " + << precomph_out_dir << header_prefix << "c++" << "\n\t"; + } if(!project->isEmpty("IMAGES")) t << varGlue("QMAKE_IMAGE_COLLECTION", "\t-$(DEL_FILE) ", " ", "") << "\n\t"; @@ -763,29 +872,53 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) t << "\t-$(DEL_FILE) -r " << destdir.section(Option::dir_sep, 0, -4) << "\n"; + else if(project->isActiveConfig("compile_libtool")) + t << "\t-$(LIBTOOL) --mode=clean $(DEL_FILE) " << "$(TARGET)" << "\n"; else t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << "$(TARGET)" << "\n"; if(!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty() && - !project->isActiveConfig("plugin")) + !project->isActiveConfig("plugin") && !project->isActiveConfig("compile_libtool")) t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " << destdir << "$(TARGET2) $(TARGETA)" << "\n"; t << endl << endl; - if ( !project->isEmpty("PRECOMPH") ) { + if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER") ) { + QString precomph = fileFixify(project->first("PRECOMPILED_HEADER")); + t << "###### Prefix headers" << endl; + QString comps[] = { "C", "CXX", QString::null }; + for(int i = 0; !comps[i].isNull(); i++) { + QString flags = var("QMAKE_" + comps[i] + "FLAGS_PRECOMPILE"); + flags += " $(" + comps[i] + "FLAGS)"; + + QString header_prefix = project->first("QMAKE_PRECOMP_PREFIX"); + QString outdir = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep, outfile = outdir; + QString compiler; + if(comps[i] == "C") { + outfile += header_prefix + "c"; + compiler = "$(CC) "; + } else { + outfile += header_prefix + "c++"; + compiler = "$(CXX) "; + } + t << outfile << ": " << precomph << " " << findDependencies(precomph).join(" \\\n\t\t") + << "\n\t" << "test -d " << outdir << " || mkdir -p " << outdir + << "\n\t" << compiler << flags << " $(INCPATH) " << precomph << " -o " << outfile << endl << endl; + } + } + if(!project->isEmpty("ALLMOC_HEADER")) { QString outdir = project->first("MOC_DIR"); - QString qt_dot_h = Option::fixPathToLocalOS(project->first("PRECOMPH")); - t << "###### Combined headers" << endl << endl; - //XXX - t << outdir << "allmoc.cpp: " << qt_dot_h << " " + QString precomph = fileFixify(project->first("ALLMOC_HEADER")); + t << "###### Combined headers" << endl << endl + << outdir << "allmoc.cpp: " << precomph << " " << varList("HEADERS_ORIG") << "\n\t" - << "echo '#include \"" << qt_dot_h << "\"' >" << outdir << "allmoc.cpp" << "\n\t" + << "echo '#include \"" << precomph << "\"' >" << outdir << "allmoc.cpp" << "\n\t" << "$(CXX) -E -DQT_MOC_CPP -DQT_NO_STL $(CXXFLAGS) $(INCPATH) >" << outdir << "allmoc.h " - << outdir << "allmoc.cpp" << "\n\t" + << outdir << "allmoc.cpp" << "\n\t" << "$(MOC) -o " << outdir << "allmoc.cpp " << outdir << "allmoc.h" << "\n\t" << "perl -pi -e 's{#include \"allmoc.h\"}{#define QT_H_CPP\\n#include \"" - << qt_dot_h << "\"}' " << outdir << "allmoc.cpp" << "\n\t" + << precomph << "\"}' " << outdir << "allmoc.cpp" << "\n\t" << "$(DEL_FILE) " << outdir << "allmoc.h" << endl << endl; } - // blasted user defined targets + // user defined targets QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"]; for(it = qut.begin(); it != qut.end(); ++it) { @@ -801,7 +934,57 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) deps += " " + dep; } + if(project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; t << targ << ":" << deps << "\n\t" << cmd << endl << endl; } + // user defined compilers + QStringList &quc = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + QString tmp_dep = project->variables()[(*it) + ".depends"].join(" "); + QStringList &vars = project->variables()[(*it) + ".variables"]; + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out, cmd = tmp_cmd, deps; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + cmd.replace("${QMAKE_FILE_BASE}", fi.baseName()); + cmd.replace("${QMAKE_FILE_OUT}", out); + cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3) + cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); + if(!tmp_dep.isEmpty()) { + char buff[256]; + QString dep_cmd = tmp_dep; + dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) { + while(!feof(proc)) { + int read_in = int(fread(buff, 1, 255, proc)); + if(!read_in) + break; + int l = 0; + for(int i = 0; i < read_in; i++) { + if(buff[i] == '\n' || buff[i] == ' ') { + deps += " " + QCString(buff+l, (i - l) + 1); + l = i; + } + } + } + fclose(proc); + } + } + t << out << ": " << in << deps << "\n\t" + << cmd << endl << endl; + } + } + } t <<"FORCE:" << endl << endl; } @@ -815,4 +998,10 @@ void UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) { + // blasted includes + QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"]; + for(QStringList::Iterator qeui_it = qeui.begin(); qeui_it != qeui.end(); ++qeui_it) + t << "include " << (*qeui_it) << endl; + writeExtraVariables(t); + QPtrList<SubDir> subdirs; { @@ -833,4 +1022,6 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) } } else { + if(!file.isEmpty()) + sd->profile = file.section(Option::dir_sep, -1) + ".pro"; sd->directory = file; } @@ -858,6 +1049,10 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) t << "QMAKE = " << var("QMAKE") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; + t << "CHK_DIR_EXISTS= " << var("QMAKE_CHK_DIR_EXISTS") << endl; + t << "MKDIR = " << var("QMAKE_MKDIR") << endl; + t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl; t << "SUBTARGETS = "; // subdirectory targets are sub-directory - for( it.toFirst(); it.current(); ++it) + for( it.toFirst(); it.current(); ++it) t << " \\\n\t\t" << it.current()->target; t << endl << endl; @@ -875,6 +1070,8 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) t << mkfile << ": " << "\n\t"; if(have_dir) - t << "cd " << (*it)->directory << " && "; - t << "$(QMAKE) " << (*it)->profile << buildArgs() << out << endl; + t << mkdir_p_asstring((*it)->directory) << "\n\t" + << "cd " << (*it)->directory << " && "; + QString profile = fileFixify((*it)->profile, (*it)->directory, (*it)->directory); + t << "$(QMAKE) " << profile << buildArgs() << out << endl; //actually compile t << (*it)->target << ": " << mkfile << " FORCE" << "\n\t"; @@ -888,5 +1085,5 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) QString tar = it.current()->target; ++it; - if (it.current()) + if (it.current()) t << it.current()->target << ": " << tar << endl; } @@ -897,5 +1094,6 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) if(project->isEmpty("SUBDIRS")) { - t << "all qmake_all distclean install uiclean mocclean lexclean yaccclean clean: FORCE" << endl; + t << "all qmake_all distclean uicables mocables install_subdirs uninstall_subdirs" + << " uiclean mocclean lexclean yaccclean clean " << var("SUBDIR_TARGETS") << ": FORCE" << endl; } else { t << "all: $(SUBTARGETS)" << endl; @@ -911,9 +1109,10 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) if(!(*it)->directory.isEmpty()) t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; "; - t << "grep \"^qmake_all:\" " << (*it)->makefile + t << "grep \"^qmake_all:\" " << (*it)->makefile << " && $(MAKE) -f " << (*it)->makefile << " qmake_all" << "; ) || true"; } t << endl; - t << "clean uninstall install uiclean mocclean lexclean yaccclean: qmake_all FORCE"; + t << "clean uicables mocables uiclean mocclean lexclean yaccclean " + << var("SUBDIR_TARGETS") << ": qmake_all FORCE"; for( it.toFirst(); it.current(); ++it) { t << "\n\t ( "; @@ -923,4 +1122,20 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) } t << endl; + t << "uninstall_subdirs: qmake_all FORCE"; + for( it.toFirst(); it.current(); ++it) { + t << "\n\t ( "; + if(!(*it)->directory.isEmpty()) + t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; "; + t << "$(MAKE) -f " << (*it)->makefile << " uninstall" << "; ) || true"; + } + t << endl; + t << "install_subdirs: qmake_all FORCE"; + for( it.toFirst(); it.current(); ++it) { + t << "\n\t ( "; + if(!(*it)->directory.isEmpty()) + t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; "; + t << "$(MAKE) -f " << (*it)->makefile << " install" << "; ) || true"; + } + t << endl; t << "distclean: qmake_all FORCE"; for( it.toFirst(); it.current(); ++it) { @@ -932,4 +1147,29 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) t << endl << endl; } + + //installations + project->variables()["INSTALLDEPS"] += "install_subdirs"; + project->variables()["UNINSTALLDEPS"] += "uninstall_subdirs"; + writeInstalls(t, "INSTALLS"); + + // user defined targets + QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"]; + for(QStringList::Iterator qut_it = qut.begin(); qut_it != qut.end(); ++qut_it) { + QString targ = var((*qut_it) + ".target"), + cmd = var((*qut_it) + ".commands"), deps; + if(targ.isEmpty()) + targ = (*qut_it); + QStringList &deplist = project->variables()[(*qut_it) + ".depends"]; + for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) { + QString dep = var((*dep_it) + ".target"); + if(dep.isEmpty()) + dep = (*dep_it); + deps += " " + dep; + } + if(project->variables()[(*qut_it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; + t << targ << ":" << deps << "\n\t" + << cmd << endl << endl; + } t <<"FORCE:" << endl << endl; } @@ -968,18 +1208,24 @@ void UnixMakefileGenerator::init2() } else { project->variables()["TARGETA"].append(project->first("DESTDIR") + "lib" + project->first("TARGET") + ".a"); + if( project->isActiveConfig("compile_libtool") ) + project->variables()["TARGET_la"] = project->first("DESTDIR") + "lib" + project->first("TARGET") + Option::libtool_ext; + if ( !project->variables()["QMAKE_AR_CMD"].isEmpty() ) project->variables()["QMAKE_AR_CMD"].first().replace("(TARGET)","(TARGETA)"); else project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGETA) $(OBJECTS) $(OBJMOC)"); - if( project->isActiveConfig("plugin") ) { + if( project->isActiveConfig("compile_libtool") ) { + project->variables()["TARGET"] = project->variables()["TARGET_la"]; + } else if( project->isActiveConfig("plugin") ) { project->variables()["TARGET_x.y.z"].append("lib" + - project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB")); + project->first("TARGET") + "." + + project->first("QMAKE_EXTENSION_PLUGIN")); if(project->isActiveConfig("lib_version_first")) project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + - project->first("VER_MAJ") + "." + - project->first("QMAKE_EXTENSION_SHLIB")); + project->first("VER_MAJ") + "." + + project->first("QMAKE_EXTENSION_PLUGIN")); else project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + - project->first("QMAKE_EXTENSION_SHLIB") + + project->first("QMAKE_EXTENSION_PLUGIN") + "." + project->first("VER_MAJ")); @@ -990,8 +1236,8 @@ void UnixMakefileGenerator::init2() project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".sl"); if(project->isActiveConfig("lib_version_first")) - project->variables()["TARGET_x"].append("lib" + project->first("VER_MAJ") + "." + + project->variables()["TARGET_x"].append("lib" + project->first("VER_MAJ") + "." + project->first("TARGET")); else - project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + + project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ")); project->variables()["TARGET"] = project->variables()["TARGET_x"]; @@ -1076,20 +1322,42 @@ void UnixMakefileGenerator::init2() if ( project->variables()["QMAKE_LINK_SHLIB_CMD"].isEmpty() ) project->variables()["QMAKE_LINK_SHLIB_CMD"].append( - "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)"); + "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) $(OBJCOMP)"); } if(project->isEmpty("QMAKE_SYMBOLIC_LINK")) project->variables()["QMAKE_SYMBOLIC_LINK"].append("ln -sf"); if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { - project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SHAPP"]; + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_APP"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_APP"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_APP"]; } else if ( project->isActiveConfig("dll") ) { - project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_SHLIB"]; - project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_SHLIB"]; + if( !project->isActiveConfig("plugin") || !project->isActiveConfig("plugin_no_share_shlib_cflags")) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_SHLIB"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_SHLIB"]; + } if ( project->isActiveConfig("plugin") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_PLUGIN"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_PLUGIN"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PLUGIN"]; - if( !project->isActiveConfig("plugin_no_soname") ) + if( project->isActiveConfig("plugin_with_soname") && !project->isActiveConfig("compile_libtool")) project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"]; } else { project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SHLIB"]; - project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"]; + if(!project->isEmpty("QMAKE_LFLAGS_COMPAT_VERSION")) { + if(project->isEmpty("COMPAT_VERSION")) + project->variables()["QMAKE_LFLAGS"] += QString(project->first("QMAKE_LFLAGS_COMPAT_VERSION") + + project->first("VER_MAJ") + "." + + project->first("VER_MIN")); + else + project->variables()["QMAKE_LFLAGS"] += QString(project->first("QMAKE_LFLAGS_COMPAT_VERSION") + + project->first("COMPATIBILITY_VERSION")); + } + if(!project->isEmpty("QMAKE_LFLAGS_VERSION")) { + project->variables()["QMAKE_LFLAGS"] += QString(project->first("QMAKE_LFLAGS_VERSION") + + project->first("VER_MAJ") + "." + + project->first("VER_MIN") + "." + + project->first("VER_PAT")); + } + if(!project->isActiveConfig("compile_libtool")) + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"]; } QString destdir = project->first("DESTDIR"); @@ -1108,3 +1376,213 @@ void UnixMakefileGenerator::init2() } } + QStringList &quc = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"]; + for(QStringList::Iterator it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + if(tmp_out.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1) + project->variables()["OBJCOMP"] += out; + } + } + } +} + +QString +UnixMakefileGenerator::libtoolFileName() +{ + QString ret = var("TARGET"); + int slsh = ret.findRev(Option::dir_sep); + if(slsh != -1) + ret = ret.right(ret.length() - slsh); + int dot = ret.find('.'); + if(dot != -1) + ret = ret.left(dot); + ret += Option::libtool_ext; + if(!project->isEmpty("DESTDIR")) + ret.prepend(var("DESTDIR")); + return ret; +} + +void +UnixMakefileGenerator::writeLibtoolFile() +{ + QString fname = libtoolFileName(), lname = fname; + int slsh = lname.findRev(Option::dir_sep); + if(slsh != -1) + lname = lname.right(lname.length() - slsh - 1); + QFile ft(fname); + if(!ft.open(IO_WriteOnly)) + return; + project->variables()["ALL_DEPS"].append(fname); + + QTextStream t(&ft); + t << "# " << lname << " - a libtool library file\n"; + time_t now = time(NULL); + t << "# Generated by qmake/libtool (" << qmake_version() << ") (Qt " + << QT_VERSION_STR << ") on: " << ctime(&now) << "\n"; + + t << "# The name that we can dlopen(3).\n" + << "dlname='" << var(project->isActiveConfig("plugin") ? "TARGET" : "TARGET_x") + << "'\n\n"; + + t << "# Names of this library.\n"; + t << "library_names='"; + if(project->isActiveConfig("plugin")) { + t << var("TARGET"); + } else { + if (project->isEmpty("QMAKE_HPUX_SHLIB")) + t << var("TARGET_x.y.z") << " "; + t << var("TARGET_x") << " " << var("TARGET_"); + } + t << "'\n\n"; + + t << "# The name of the static archive.\n" + << "old_library='" << lname.left(lname.length()-Option::libtool_ext.length()) << ".a'\n\n"; + + t << "# Libraries that this one depends upon.\n"; + QStringList libs; + if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) + libs = project->variables()["QMAKE_INTERNAL_PRL_LIBS"]; + else + libs << "QMAKE_LIBS"; //obvious one + t << "dependency_libs='"; + for(QStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it) + t << project->variables()[(*it)].join(" ") << " "; + t << "'\n\n"; + + 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"; + + QString 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" + "libdir='" << Option::fixPathToTargetOS(install_dir, FALSE) << "'\n"; +} + +QString +UnixMakefileGenerator::pkgConfigFileName() +{ + QString ret = var("TARGET"); + int slsh = ret.findRev(Option::dir_sep); + if(slsh != -1) + ret = ret.right(ret.length() - slsh); + if(ret.startsWith("lib")) + ret = ret.mid(3); + int dot = ret.find('.'); + if(dot != -1) + ret = ret.left(dot); + ret += Option::pkgcfg_ext; + if(!project->isEmpty("DESTDIR")) { + ret.prepend(var("DESTDIR")); + ret = Option::fixPathToLocalOS(fileFixify(ret,QDir::currentDirPath(), Option::output_dir)); + } + return ret; +} + +QString +UnixMakefileGenerator::pkgConfigPrefix() const +{ + if(!project->isEmpty("QMAKE_PKGCONFIG_PREFIX")) + return project->first("QMAKE_PKGCONFIG_PREFIX"); + return qInstallPath(); +} + +QString +UnixMakefileGenerator::pkgConfigFixPath(QString path) const +{ + QString prefix = pkgConfigPrefix(); + if(path.startsWith(prefix)) + path = path.replace(prefix, "${prefix}"); + return path; +} + +void +UnixMakefileGenerator::writePkgConfigFile() // ### does make sense only for libqt so far +{ + QString fname = pkgConfigFileName(), lname = fname; + int slsh = lname.findRev(Option::dir_sep); + if(slsh != -1) + lname = lname.right(lname.length() - slsh - 1); + QFile ft(fname); + if(!ft.open(IO_WriteOnly)) + return; + project->variables()["ALL_DEPS"].append(fname); + QTextStream t(&ft); + + QString prefix = pkgConfigPrefix(); + QString libDir = project->first("QMAKE_PKGCONFIG_LIBDIR"); + if(libDir.isEmpty()) + libDir = prefix + "/lib"; + QString includeDir = project->first("QMAKE_PKGCONFIG_INCDIR"); + if(includeDir.isEmpty()) + includeDir = prefix + "/include"; + + t << "prefix=" << prefix << endl; + t << "exec_prefix=${prefix}\n" + << "libdir=" << pkgConfigFixPath(libDir) << "\n" + << "includedir=" << pkgConfigFixPath(includeDir) << endl; + // non-standard entry. Provides useful info normally only + // contained in the internal .qmake.cache file + t << varGlue("CONFIG", "qt_config=", " ", "") << endl << endl; + + t << "Name: Qt" << endl; + QString desc = project->first("QMAKE_PKGCONFIG_DESCRIPTION"); + if(desc.isEmpty()) { + desc = project->first("TARGET").lower(); + desc.replace(0, 1, desc[0].upper()); + if(project->first("TEMPLATE") == "lib") { + if(project->isActiveConfig("plugin")) + desc += " Plugin"; + else + desc += " Library"; + } else if(project->first("TEMPLATE") == "app") { + desc += " Application"; + } + } + t << "Description: " << desc << endl; + t << "Version: " << project->first("VERSION") << endl; + + // libs + QStringList libs; + if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) + libs = project->variables()["QMAKE_INTERNAL_PRL_LIBS"]; + else + libs << "QMAKE_LIBS"; //obvious one + if(project->isActiveConfig("thread")) + libs << "QMAKE_LFLAGS_THREAD"; //not sure about this one, but what about things like -pthread? + t << "Libs: -L${libdir} -l" << lname.left(lname.length()-Option::libtool_ext.length()) << " "; + for(QStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it) + t << project->variables()[(*it)].join(" ") << " "; + t << endl; + + // flags + // ### too many + t << "Cflags: " + // << var("QMAKE_CXXFLAGS") << " " + << varGlue("PRL_EXPORT_DEFINES","-D"," -D"," ") + << project->variables()["PRL_EXPORT_CXXFLAGS"].join(" ") + // << varGlue("DEFINES","-D"," -D"," ") + << " -I${includedir}"; } diff --git a/qmake/generators/win32/borland_bmake.cpp b/qmake/generators/win32/borland_bmake.cpp index 26eea88..12607cf 100644 --- a/qmake/generators/win32/borland_bmake.cpp +++ b/qmake/generators/win32/borland_bmake.cpp @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** NmakeMakefileGenerator of BorlandMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -84,8 +82,8 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << "LEX = " << var("QMAKE_LEX") << endl; t << "YACC = " << var("QMAKE_YACC") << endl; - t << "CFLAGS = " << var("QMAKE_CFLAGS") << " " + t << "CFLAGS = " << var("QMAKE_CFLAGS") << " " << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " << varGlue("DEFINES","-D"," -D","") << endl; - t << "CXXFLAGS= " << var("QMAKE_CXXFLAGS") << " " + t << "CXXFLAGS= " << var("QMAKE_CXXFLAGS") << " " << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " << varGlue("DEFINES","-D"," -D","") << endl; @@ -115,9 +113,9 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << "LIB = " << var("QMAKE_LIB") << endl; } - t << "MOC = " << (project->isEmpty("QMAKE_MOC") ? QString("moc") : + t << "MOC = " << (project->isEmpty("QMAKE_MOC") ? QString("moc") : Option::fixPathToTargetOS(var("QMAKE_MOC"), FALSE)) << endl; - t << "UIC = " << (project->isEmpty("QMAKE_UIC") ? QString("uic") : + t << "UIC = " << (project->isEmpty("QMAKE_UIC") ? QString("uic") : Option::fixPathToTargetOS(var("QMAKE_UIC"), FALSE)) << endl; - t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : + t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : Option::fixPathToTargetOS(var("QMAKE_QMAKE"), FALSE)) << endl; t << "IDC = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") : @@ -135,4 +133,6 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; t << "MKDIR = " << var("QMAKE_MKDIR") << endl; + t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl; t << endl; @@ -146,4 +146,21 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << "SRCMOC = " << varList("SRCMOC") << endl; t << "OBJMOC = " << varList("OBJMOC") << endl; + + QString extraCompilerDeps; + if(!project->isEmpty("QMAKE_EXTRA_WIN_COMPILERS")) { + t << "OBJCOMP = " << varList("OBJCOMP") << endl; + extraCompilerDeps += " $(OBJCOMP) "; + + QStringList &comps = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) { + QStringList &vars = project->variables()[(*compit) + ".variables"]; + for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) { + QStringList vals = project->variables()[(*varit)]; + if(!vals.isEmpty()) + t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << endl; + } + } + } + t << "DIST = " << varList("DISTFILES") << endl; t << "TARGET = " @@ -163,16 +180,17 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << "####### Build rules" << endl << endl; - t << "all: " << varGlue("ALL_DEPS",""," "," ") << " $(TARGET)" << endl << endl; - t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " - << var("POST_TARGETDEPS"); + t << "all: " << fileFixify(Option::output.name()) << " " << varGlue("ALL_DEPS"," "," "," ") << " $(TARGET)" << endl << endl; + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << extraCompilerDeps << var("POST_TARGETDEPS"); if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { t << "\n\t" << "$(LINK) @&&|" << "\n\t" << "$(LFLAGS) $(OBJECTS) $(OBJMOC),$(TARGET),,$(LIBS),$(DEF_FILE),$(RES_FILE)"; } else { - t << "\n\t-del $(TARGET)" + t << "\n\t-$(DEL_FILE) $(TARGET)" << "\n\t" << "$(LIB) $(TARGET) @&&|" << " \n+" << project->variables()["OBJECTS"].join(" \\\n+") << " \\\n+" << project->variables()["OBJMOC"].join(" \\\n+"); } + t << extraCompilerDeps; t << endl << "|" << endl; @@ -183,5 +201,5 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) QStringList dlldirs = project->variables()["DLLDESTDIR"]; for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { - t << "\n\t" << "-copy $(TARGET) " << *dlldir; + t << "\n\t" << "-$(COPY_FILE) \"$(TARGET)\" " << *dlldir; } } @@ -193,12 +211,12 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) if ( project->isActiveConfig("dll")) { - t << "\n\t" << ("-$(IDC) $(TARGET) /idl tmp\\" + targetfilename + ".idl -version " + version); - t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"); - t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /idl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" ); } else { - t << "\n\t" << ("-$(TARGET) -dumpidl tmp\\" + targetfilename + ".idl -version " + version); - t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"); - t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb"); + t << "\n\t" << ("-$(TARGET) -dumpidl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); t << "\n\t" << ("-$(TARGET) -regserver"); } @@ -210,30 +228,58 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) << var("QMAKE_RC") << " " << var("RC_FILE") << endl << endl; } - t << "mocables: $(SRCMOC)" << endl << endl; + t << "mocables: $(SRCMOC)" << endl + << "uicables: $(UICIMPLS) $(UICDECLS)" << endl << endl; writeMakeQmake(t); + QStringList dist_files = Option::mkfile::project_files; + if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES")) + dist_files += project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"]; + if(!project->isEmpty("TRANSLATIONS")) + dist_files << var("TRANSLATIONS"); + if(!project->isEmpty("FORMS")) { + QStringList &forms = project->variables()["FORMS"]; + for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) { + QString ui_h = fileFixify((*formit) + Option::h_ext.first()); + if(QFile::exists(ui_h) ) + dist_files << ui_h; + } + } t << "dist:" << "\n\t" - << "$(ZIP) " << var("PROJECT") << ".zip " << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" - << endl << endl; + << "$(ZIP) " << var("QMAKE_ORIG_TARGET") << ".zip " << "$(SOURCES) $(HEADERS) $(DIST) $(FORMS) " + << dist_files.join(" ") << " " << var("TRANSLATIONS") << " " << var("IMAGES") << endl << endl; + + t << "uiclean:"; + QString uiclean = varGlue("UICDECLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + varGlue("UICIMPLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ",""); + if ( uiclean.isEmpty() ) { + // Borland make does not like an empty command section + uiclean = "\n\t@cd ."; + } + t << uiclean << endl; + + t << "mocclean:"; + QString mocclean = varGlue("SRCMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + varGlue("OBJMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ",""); + if ( mocclean.isEmpty() ) { + // Borland make does not like an empty command section + mocclean = "\n\t@cd ."; + } + t << mocclean << endl; - t << "clean:\n" - << varGlue("OBJECTS","\t-del ","\n\t-del ","") - << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","") - << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","") - << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","") - << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","") - << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","") - << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ",""); + t << "clean: uiclean mocclean" + << varGlue("OBJECTS","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("CLEAN_FILES","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ",""); if ( project->isActiveConfig("activeqt")) { - t << ("\n\t-del tmp\\" + targetfilename + ".*"); - t << "\n\t-del tmp\\dump.*"; + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".idl"); + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".tlb"); } if(!project->isEmpty("IMAGES")) - t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", ""); + t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-$(DEL_FILE) ", "\n\t-$(DEL_FILE) ", ""); + t << endl; - // blasted user defined targets + // user defined targets + QStringList::Iterator it; QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; - for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) { + for(it = qut.begin(); it != qut.end(); ++it) { QString targ = var((*it) + ".target"), cmd = var((*it) + ".commands"), deps; @@ -247,4 +293,7 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) deps += " " + dep; } + if(!project->variables()["QMAKE_NOFORCE"].isEmpty() && + project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; t << "\n\n" << targ << ":" << deps << "\n\t" << cmd; @@ -253,6 +302,55 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << endl << endl; + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + QString tmp_dep = project->variables()[(*it) + ".depends"].join(" "); + QStringList &vars = project->variables()[(*it) + ".variables"]; + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out, cmd = tmp_cmd, deps; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + cmd.replace("${QMAKE_FILE_BASE}", fi.baseName()); + cmd.replace("${QMAKE_FILE_OUT}", out); + cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3) + cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); + if(!tmp_dep.isEmpty()) { + char buff[256]; + QString dep_cmd = tmp_dep; + dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) { + while(!feof(proc)) { + int read_in = int(fread(buff, 1, 255, proc)); + if(!read_in) + break; + int l = 0; + for(int i = 0; i < read_in; i++) { + if(buff[i] == '\n' || buff[i] == ' ') { + deps += " " + QCString(buff+l, (i - l) + 1); + l = i; + } + } + } + fclose(proc); + } + } + t << out << ": " << in << deps << "\n\t" + << cmd << endl << endl; + } + } + } + t << endl; + t << "distclean: clean" - << "\n\t-del $(TARGET)" + << "\n\t-$(DEL_FILE) $(TARGET)" << endl << endl; } @@ -266,5 +364,5 @@ BorlandMakefileGenerator::init() project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; - + /* this should probably not be here, but I'm using it to wrap the .t files */ if(project->first("TEMPLATE") == "app") @@ -280,5 +378,10 @@ BorlandMakefileGenerator::init() return; } - + + if(project->isEmpty("QMAKE_INSTALL_FILE")) + project->variables()["QMAKE_INSTALL_FILE"].append("$(COPY_FILE)"); + if(project->isEmpty("QMAKE_INSTALL_DIR")) + project->variables()["QMAKE_INSTALL_DIR"].append("$(COPY_DIR)"); + bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qtmt"QTDLL_POSTFIX); QStringList &configs = project->variables()["CONFIG"]; @@ -287,4 +390,10 @@ BorlandMakefileGenerator::init() if (project->isActiveConfig("qt_dll")) if(configs.findIndex("qt") == -1) configs.append("qt"); + if ( project->isActiveConfig("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); + } if ( project->isActiveConfig("qt") ) { if ( project->isActiveConfig("plugin") ) { @@ -315,5 +424,5 @@ BorlandMakefileGenerator::init() } if(project->isActiveConfig("qt")) { - if ( project->isActiveConfig("thread") ) + if ( project->isActiveConfig("thread") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT"); if ( project->isActiveConfig("accessibility" ) ) @@ -326,7 +435,7 @@ BorlandMakefileGenerator::init() if ( project->isActiveConfig("thread") ) { if ( project->isActiveConfig("dll") ) { - project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"]; - project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"]; - } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"]; + } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DBG"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"]; @@ -357,9 +466,16 @@ BorlandMakefileGenerator::init() project->variables()["CONFIG"].append("windows"); } + if ( project->isActiveConfig("qtopiainc") ) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"]; + if ( project->isActiveConfig("qtopialib") ) { + if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA")) + project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QTOPIA"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"]; + } if ( project->isActiveConfig("qt") ) { project->variables()["CONFIG"].append("moc"); project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"]; - if ( !project->isActiveConfig("debug") ) + if ( !project->isActiveConfig("debug") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG"); if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { @@ -469,8 +585,23 @@ BorlandMakefileGenerator::init() } project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; + // Update -lname to name.lib, and -Ldir to + QStringList &libList = project->variables()["QMAKE_LIBS"]; + for( QStringList::Iterator stIt = libList.begin(); stIt != libList.end(); ) { + QString s = *stIt; + if( s.startsWith( "-l" ) ) { + stIt = libList.remove( stIt ); + stIt = libList.insert( stIt, s.mid( 2 ) + ".lib" ); + } else if( s.startsWith( "-L" ) ) { + stIt = libList.remove( stIt ); + project->variables()["QMAKE_LIBDIR"].append(QDir::convertSeparators(s.mid( 2 ))); + } else { + stIt++; + } + } project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH"); QStringList &l = project->variables()["QMAKE_FILETAGS"]; - for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QStringList::Iterator it; + for(it = l.begin(); it != l.end(); ++it) { QStringList &gdmf = project->variables()[(*it)]; for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner) @@ -487,4 +618,5 @@ BorlandMakefileGenerator::init() project->variables()["RES_FILE"].first().replace(".rc",".res"); project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["CLEAN_FILES"] += project->variables()["RES_FILE"]; } MakefileGenerator::init(); @@ -507,3 +639,23 @@ BorlandMakefileGenerator::init() project->first("DESTDIR") + project->first("TARGET") + tdsPostfix ); } + + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + if(tmp_out.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1) + project->variables()["OBJCOMP"] += out; + } + } + } } diff --git a/qmake/generators/win32/borland_bmake.h b/qmake/generators/win32/borland_bmake.h index 5ffed58..700e7f7 100644 --- a/qmake/generators/win32/borland_bmake.h +++ b/qmake/generators/win32/borland_bmake.h @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of BorlandMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -35,4 +33,5 @@ ** **********************************************************************/ + #ifndef __BORLAND_BMAKE_H__ #define __BORLAND_BMAKE_H__ diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index 7f58a55..c693d6a 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -1,524 +1,708 @@ -/****************************************************************************
-** $Id$
-**
-** Definition of ________ class.
-**
-** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
-**
-** This file is part of the network module of the Qt GUI Toolkit.
-**
-** This file may be distributed under the terms of the Q Public License
-** as defined by Trolltech AS of Norway and appearing in the file
-** LICENSE.QPL included in the packaging of this file.
-**
-** This file may be distributed and/or modified under the terms of the
-** GNU General Public License version 2 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.
-**
-** Licensees holding valid Qt Enterprise Edition licenses may use this
-** file in accordance with the Qt Commercial License Agreement provided
-** with the Software.
-**
-** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
-** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-**
-** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
-** information about Qt Commercial License Agreements.
-** See http://www.trolltech.com/qpl/ for QPL licensing information.
-** See http://www.trolltech.com/gpl/ for GPL licensing information.
-**
-** Contact info@trolltech.com if any conditions of this licensing are
-** not clear to you.
-**
-**********************************************************************/
-
-#include "mingw_make.h"
-#include "option.h"
-#include <qregexp.h>
-#include <qdir.h>
-#include <stdlib.h>
-#include <time.h>
-
-
-MingwMakefileGenerator::MingwMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE)
-{
- Option::obj_ext = ".o";
-}
-
-bool
-MingwMakefileGenerator::writeMakefile(QTextStream &t)
-{
- writeHeader(t);
- if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
- t << "all clean:" << "\n\t"
- << "@echo \"Some of the required modules ("
- << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t"
- << "@echo \"Skipped.\"" << endl << endl;
- writeMakeQmake(t);
- return TRUE;
- }
-
- if(project->first("TEMPLATE") == "app" ||
- project->first("TEMPLATE") == "lib") {
- writeMingwParts(t);
- return MakefileGenerator::writeMakefile(t);
- }
- else if(project->first("TEMPLATE") == "subdirs") {
- writeSubDirs(t);
- return TRUE;
- }
- return FALSE;
-}
-
-void
-MingwMakefileGenerator::writeMingwParts(QTextStream &t)
-{
- t << "####### Compiler, tools and options" << endl << endl;
- t << "CC = " << var("QMAKE_CC") << endl;
- t << "CXX = " << var("QMAKE_CXX") << endl;
- t << "LEX = " << var("QMAKE_LEX") << endl;
- t << "YACC = " << var("QMAKE_YACC") << endl;
- t << "CFLAGS = " << var("QMAKE_CFLAGS") << " "
- << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
- << varGlue("DEFINES","-D"," -D","") << endl;
- t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " "
- << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
- << varGlue("DEFINES","-D"," -D","") << endl;
- t << "LEXFLAGS =" << var("QMAKE_LEXFLAGS") << endl;
- t << "YACCFLAGS =" << var("QMAKE_YACCFLAGS") << endl;
-
- t << "INCPATH = ";
- QStringList &incs = project->variables()["INCLUDEPATH"];
- for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) {
- QString inc = (*incit);
- inc.replace(QRegExp("\\\\$"), "\\\\");
- inc.replace(QRegExp("\""), "");
- t << " -I" << inc ;
- }
- t << " -I" << specdir()
- << endl;
- if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
- t << "LINK = " << var("QMAKE_LINK") << endl;
- t << "LFLAGS = ";
- if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() )
- t << varGlue("QMAKE_LIBDIR","-L",";","") << " ";
- t << var("QMAKE_LFLAGS") << endl;
- t << "LIBS = " << var("QMAKE_LIBS").replace(QRegExp("(\\slib|^lib)")," -l") << endl;
- }
- else {
- t << "LIB = " << var("QMAKE_LIB") << endl;
- }
- t << "MOC = " << (project->isEmpty("QMAKE_MOC") ? QString("moc") :
- Option::fixPathToTargetOS(var("QMAKE_MOC"), FALSE)) << endl;
- t << "UIC = " << (project->isEmpty("QMAKE_UIC") ? QString("uic") :
- Option::fixPathToTargetOS(var("QMAKE_UIC"), FALSE)) << endl;
- t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") :
- Option::fixPathToTargetOS(var("QMAKE_QMAKE"), FALSE)) << endl;
- t << "IDC = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") :
- Option::fixPathToTargetOS(var("QMAKE_IDC"), FALSE)) << endl;
- t << "IDL = " << (project->isEmpty("QMAKE_IDL") ? QString("midl") :
- Option::fixPathToTargetOS(var("QMAKE_IDL"), FALSE)) << endl;
- t << "ZIP = " << var("QMAKE_ZIP") << endl;
- t << "DEF_FILE = " << varList("DEF_FILE") << endl;
- t << "COPY_FILE = " << var("QMAKE_COPY") << endl;
- t << "COPY_DIR = " << var("QMAKE_COPY") << endl;
- t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
- t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl;
- t << "MOVE = " << var("QMAKE_MOVE") << endl;
- t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl;
- t << "MKDIR = " << var("QMAKE_MKDIR") << endl;
- t << endl;
-
- t << "####### Output directory" << endl << endl;
- if (! project->variables()["OBJECTS_DIR"].isEmpty())
- t << "OBJECTS_DIR = " << var("OBJECTS_DIR").replace(QRegExp("\\\\$"),"") << endl;
- else
- t << "OBJECTS_DIR = . " << endl;
- if (! project->variables()["MOC_DIR"].isEmpty())
- t << "MOC_DIR = " << var("MOC_DIR").replace(QRegExp("\\\\$"),"") << endl;
- else
- t << "MOC_DIR = . " << endl;
- t << endl;
-
- t << "####### Files" << endl << endl;
- t << "HEADERS = " << varList("HEADERS") << endl;
- t << "SOURCES = " << varList("SOURCES") << endl;
-// t << "OBJECTS = " << varList("OBJECTS").replace(QRegExp("\\.obj"),".o") << endl;
- t << "OBJECTS = " << varList("OBJECTS") << endl;
- t << "FORMS = " << varList("FORMS") << endl;
- t << "UICDECLS = " << varList("UICDECLS") << endl;
- t << "UICIMPLS = " << varList("UICIMPLS") << endl;
- t << "SRCMOC = " << varList("SRCMOC") << endl;
- t << "OBJMOC = " << varList("OBJMOC") << endl;
-// t << "OBJMOC = " << varList("OBJMOC").replace(QRegExp("\\.obj"),".o") << endl;
- t << "DIST = " << varList("DISTFILES") << endl;
- t << "TARGET = ";
- if( !project->variables()[ "DESTDIR" ].isEmpty() )
- t << varGlue("TARGET",project->first("DESTDIR"),"",project->first("TARGET_EXT"));
- else
- t << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first();
- t << endl;
- t << endl;
-
- t << "####### Implicit rules" << endl << endl;
- t << ".SUFFIXES: .cpp .cxx .cc .C .c" << endl << endl;
- t << ".cpp.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
- t << ".cxx.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
- t << ".cc.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
- t << ".C.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
- t << ".c.o:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl;
-
- t << "####### Build rules" << endl << endl;
- t << "all: " << "$(OBJECTS_DIR) " << "$(MOC_DIR) " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl;
- t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) "
- << var("POST_TARGETDEPS");
- if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
- t << "\n\t" << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)";
- } else {
- t << "\n\t" << "$(LIB) $(TARGET) $(OBJECTS) $(OBJMOC)";
- }
-
- if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) {
- QStringList dlldirs = project->variables()["DLLDESTDIR"];
- for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) {
- t << "\n\t" << "copy $(TARGET) " << *dlldir;
- }
- }
- QString targetfilename = project->variables()["TARGET"].first();
- if(project->isActiveConfig("activeqt")) {
- QString version = project->variables()["VERSION"].first();
- if ( version.isEmpty() )
- version = "1.0";
-
- if ( project->isActiveConfig("dll")) {
- t << "\n\t" << ("-$(IDC) $(TARGET) /idl tmp\\" + targetfilename + ".idl -version " + version);
- t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl");
- t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb");
- t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" );
- } else {
- t << "\n\t" << ("-$(TARGET) -dumpidl tmp\\" + targetfilename + ".idl -version " + version);
- t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl");
- t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb");
- t << "\n\t" << "-$(TARGET) -regserver";
- }
- }
- t << endl << endl;
-
- if(!project->variables()["RC_FILE"].isEmpty()) {
- t << var("RES_FILE") << ": " << var("RC_FILE") << "\n\t"
- << var("QMAKE_RC") << " -i " << var("RC_FILE") << " -o " << var("RC_FILE").replace(QRegExp("\\.rc"),".o") << endl << endl;
- }
- project->variables()["RES_FILE"].first().replace(QRegExp("\\.rc"),".o");
-
- t << "mocables: $(SRCMOC)" << endl << endl;
-
- t << "$(OBJECTS_DIR):" << "\n\t"
- << "@if not exist $(OBJECTS_DIR) mkdir $(OBJECTS_DIR)" << endl << endl;
-
- t << "$(MOC_DIR):" << "\n\t"
- << "@if not exist $(MOC_DIR) mkdir $(MOC_DIR)" << endl << endl;
-
- writeMakeQmake(t);
-
- t << "dist:" << "\n\t"
- << "$(ZIP) " << var("PROJECT") << ".zip "
- << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" << endl << endl;
-
- t << "clean:"
- << varGlue("OBJECTS","\n\t-del ","\n\t-del ","").replace(QRegExp("\\.obj"),".o")
- << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","")
- << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","").replace(QRegExp("\\.obj"),".o")
- << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","")
- << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","")
- << "\n\t-del $(TARGET)"
- << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","")
- << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ","");
- if ( project->isActiveConfig("activeqt")) {
- t << ("\n\t-del tmp\\" + targetfilename + ".*");
- t << "\n\t-del tmp\\dump.*";
- }
- if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty())
- t << "\n\t-del " << var("DLLDESTDIR") << "\\" << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first();
- if(!project->isEmpty("IMAGES"))
- t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", "");
-
- // blasted user defined targets
- QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"];
- for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) {
- QString targ = var((*it) + ".target"),
- cmd = var((*it) + ".commands"), deps;
- if(targ.isEmpty())
- targ = (*it);
- QStringList &deplist = project->variables()[(*it) + ".depends"];
- for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) {
- QString dep = var((*dep_it) + ".target");
- if(dep.isEmpty())
- dep = (*dep_it);
- deps += " " + dep;
- }
- t << "\n\n" << targ << ":" << deps << "\n\t"
- << cmd;
- }
-
- t << endl << endl;
-}
-
-
-void
-MingwMakefileGenerator::init()
-{
- if(init_flag)
- return;
- init_flag = TRUE;
-
- /* this should probably not be here, but I'm using it to wrap the .t files */
- if(project->first("TEMPLATE") == "app")
- project->variables()["QMAKE_APP_FLAG"].append("1");
- else if(project->first("TEMPLATE") == "lib")
- project->variables()["QMAKE_LIB_FLAG"].append("1");
- else if(project->first("TEMPLATE") == "subdirs") {
- MakefileGenerator::init();
- if(project->variables()["MAKEFILE"].isEmpty())
- project->variables()["MAKEFILE"].append("Makefile");
- if(project->variables()["QMAKE"].isEmpty())
- project->variables()["QMAKE"].append("qmake");
- return;
- }
-
- bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX);
- project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
-
- // LIBS defined in Profile comes first for gcc
- project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
-
- QString targetfilename = project->variables()["TARGET"].first();
- QStringList &configs = project->variables()["CONFIG"];
- if (project->isActiveConfig("qt") && project->isActiveConfig("shared"))
- project->variables()["DEFINES"].append("QT_DLL");
- if (project->isActiveConfig("qt_dll"))
- if(configs.findIndex("qt") == -1) configs.append("qt");
- if ( project->isActiveConfig("qt") ) {
- if ( project->isActiveConfig( "plugin" ) ) {
- project->variables()["CONFIG"].append("dll");
- if(project->isActiveConfig("qt"))
- project->variables()["DEFINES"].append("QT_PLUGIN");
- }
- if ( (project->variables()["DEFINES"].findIndex("QT_NODLL") == -1) &&
- ((project->variables()["DEFINES"].findIndex("QT_MAKEDLL") != -1 ||
- project->variables()["DEFINES"].findIndex("QT_DLL") != -1) ||
- (getenv("QT_DLL") && !getenv("QT_NODLL"))) ) {
- project->variables()["QMAKE_QT_DLL"].append("1");
- if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() )
- project->variables()["CONFIG"].append("dll");
- }
- if ( project->isActiveConfig("thread") )
- project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT");
- if ( project->isActiveConfig("accessibility" ) )
- project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT");
- if ( project->isActiveConfig("tablet") )
- project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT");
- }
- if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
- project->variables()["CONFIG"].remove("staticlib");
- project->variables()["QMAKE_APP_OR_DLL"].append("1");
- } else {
- project->variables()["CONFIG"].append("staticlib");
- }
- if ( project->isActiveConfig("warn_off") ) {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"];
- } else if ( project->isActiveConfig("warn_on") ) {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"];
- }
- if ( project->isActiveConfig("debug") ) {
- if ( project->isActiveConfig("thread") ) {
- // use the DLL RT even here
- if ( project->variables()["DEFINES"].contains("QT_DLL") ) {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"];
- } else {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DBG"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"];
- }
- }
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"];
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"];
- } else {
- if ( project->isActiveConfig("thread") ) {
- if ( project->variables()["DEFINES"].contains("QT_DLL") ) {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLL"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"];
- } else {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT"];
- }
- }
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"];
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"];
- }
-
- if ( !project->variables()["QMAKE_INCDIR"].isEmpty())
- project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"];
- if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") )
- project->variables()["CONFIG"].append("windows");
- if ( project->isActiveConfig("qt") ) {
- project->variables()["CONFIG"].append("moc");
- project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"];
- project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"];
- if ( !project->isActiveConfig("debug") )
- project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG");
- if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) {
- if ( !project->variables()["QMAKE_QT_DLL"].isEmpty()) {
- project->variables()["DEFINES"].append("QT_MAKEDLL");
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_QT_DLL"];
- }
- } else {
- if(project->isActiveConfig("thread"))
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
- else
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
- if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
- int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt");
- if ( hver == -1 )
- hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt");
- if(hver != -1) {
- QString ver;
- ver.sprintf("libqt-%s" QTDLL_POSTFIX "%d.a", (project->isActiveConfig("thread") ? "-mt" : ""), hver);
- QStringList &libs = project->variables()["QMAKE_LIBS"];
-// @@@HGTODO maybe we must change the replace regexp if we understand what's going on
- for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit)
- (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver);
- }
- }
- if ( project->isActiveConfig( "activeqt" ) ) {
- project->variables().remove("QMAKE_LIBS_QT_ENTRY");
- project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib";
- if ( project->isActiveConfig( "dll" ) )
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"];
- }
- if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) {
- project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"];
- }
- }
- }
- if ( project->isActiveConfig("opengl") ) {
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"];
- }
- if ( project->isActiveConfig("dll") ) {
- project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE_DLL"];
- project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE_DLL"];
- project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE_DLL"];
- project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS_DLL"];
- if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty()) {
- project->variables()["TARGET_EXT"].append(
- QStringList::split('.',project->first("VERSION")).join("") + ".dll");
- } else {
- project->variables()["TARGET_EXT"].append(".dll");
- }
- } else {
- project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE"];
- project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE"];
- project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE"];
- project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS"];
- if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty()) {
- project->variables()["TARGET_EXT"].append(".exe");
- } else {
- project->variables()["TARGET_EXT"].append(".a");
- project->variables()["QMAKE_LFLAGS"].append("-static");
- if(project->variables()["TARGET"].first().left(3) != "lib")
- project->variables()["TARGET"].first().prepend("lib");
- }
- }
- if ( project->isActiveConfig("windows") ) {
- if ( project->isActiveConfig("console") ) {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"];
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"];
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"];
- } else {
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"];
- }
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"];
- } else {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"];
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"];
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"];
- }
-
- if ( project->isActiveConfig("moc") )
- setMocAware(TRUE);
- project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ',
- "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH");
- QStringList &l = project->variables()["QMAKE_FILETAGS"];
- for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
- QStringList &gdmf = project->variables()[(*it)];
- for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner)
- (*inner) = Option::fixPathToTargetOS((*inner), FALSE);
- }
-
- if ( project->isActiveConfig("dll") )
- project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,--out-implib,") + project->first("DESTDIR") + "\\lib"+ project->first("TARGET") + ".a");
-
- if ( !project->variables()["DEF_FILE"].isEmpty() )
- project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,--output-def,") + project->first("DEF_FILE"));
-// if(!project->isActiveConfig("incremental"))
-// project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no"));
-
-#if 0
- if ( !project->variables()["VERSION"].isEmpty() ) {
- QString version = project->variables()["VERSION"][0];
- int firstDot = version.find( "." );
- QString major = version.left( firstDot );
- QString minor = version.right( version.length() - firstDot - 1 );
- minor.replace( ".", "" );
- project->variables()["QMAKE_LFLAGS"].append( "/VERSION:" + major + "." + minor );
- }
-#endif
- if ( !project->variables()["RC_FILE"].isEmpty()) {
- if ( !project->variables()["RES_FILE"].isEmpty()) {
- fprintf(stderr, "Both .rc and .res file specified.\n");
- fprintf(stderr, "Please specify one of them, not both.");
- exit(666);
- }
- project->variables()["RES_FILE"] = project->variables()["RC_FILE"];
- project->variables()["RES_FILE"].first().replace(".rc",".o");
- project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"];
- }
- if ( !project->variables()["RES_FILE"].isEmpty())
- project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"];
-
- MakefileGenerator::init();
- if ( !project->variables()["VERSION"].isEmpty()) {
- QStringList l = QStringList::split('.', project->first("VERSION"));
- project->variables()["VER_MAJ"].append(l[0]);
- project->variables()["VER_MIN"].append(l[1]);
- }
- if(project->isActiveConfig("dll")) {
- project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") +"lib" + project->first("TARGET") + ".a");
- }
-}
-
-void
-MingwMakefileGenerator::writeSubDirs(QTextStream &t)
-{
- QString qs ;
- QTextStream ts (&qs, IO_WriteOnly) ;
- Win32MakefileGenerator::writeSubDirs( ts ) ;
- QRegExp rx("(\\n\\tcd [^\\n\\t]+)(\\n\\t.+)\\n\\t@cd ..") ;
- rx.setMinimal(true);
- int pos = 0 ;
- while ( -1 != (pos = rx.search( qs, pos)))
- {
- QString qsMatch = rx.cap(2);
- qsMatch.replace("\n\t"," && \\\n\t");
- qs.replace(pos+rx.cap(1).length(), rx.cap(2).length(), qsMatch );
- pos += (rx.cap(1).length()+qsMatch.length());
- }
- t << qs ;
-}
+/**************************************************************************** +** +** +** Implementation of MingwMakefileGenerator class. +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of qmake. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition licenses may use this +** file in accordance with the Qt Commercial License Agreement provided +** with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "mingw_make.h" +#include "option.h" +#include <qregexp.h> +#include <qdir.h> +#include <stdlib.h> +#include <time.h> + + +MingwMakefileGenerator::MingwMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) +{ + Option::obj_ext = ".o"; +} + +bool +MingwMakefileGenerator::findLibraries() // todo - pascal +{ + return TRUE; +} + +bool +MingwMakefileGenerator::writeMakefile(QTextStream &t) +{ + writeHeader(t); + if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { + t << "all clean:" << "\n\t" + << "@echo \"Some of the required modules (" + << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t" + << "@echo \"Skipped.\"" << endl << endl; + writeMakeQmake(t); + return TRUE; + } + + if(project->first("TEMPLATE") == "app" || + project->first("TEMPLATE") == "lib") { + writeMingwParts(t); + return MakefileGenerator::writeMakefile(t); + } + else if(project->first("TEMPLATE") == "subdirs") { + writeSubDirs(t); + return TRUE; + } + return FALSE; + } + +void createLdObjectScriptFile(const QString & fileName, QStringList & objList) +{ + QString filePath = Option::output_dir + QDir::separator() + fileName; + QFile file(filePath); + if (file.open(IO_WriteOnly | IO_Translate )) { + QTextStream t(&file); + t << "INPUT(" << endl; + for (QStringList::Iterator it = objList.begin(); it != objList.end(); ++it ) { + t << *it << endl; + } + t << ");" << endl; + file.close(); + } +} + +void +MingwMakefileGenerator::writeMingwParts(QTextStream &t) +{ + t << "####### Compiler, tools and options" << endl << endl; + t << "CC = " << var("QMAKE_CC") << endl; + t << "CXX = " << var("QMAKE_CXX") << endl; + t << "LEX = " << var("QMAKE_LEX") << endl; + t << "YACC = " << var("QMAKE_YACC") << endl; + t << "CFLAGS = " << var("QMAKE_CFLAGS") << " " + << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " + << varGlue("DEFINES","-D"," -D","") << endl; + t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " " + << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " + << varGlue("DEFINES","-D"," -D","") << endl; + t << "LEXFLAGS =" << var("QMAKE_LEXFLAGS") << endl; + t << "YACCFLAGS =" << var("QMAKE_YACCFLAGS") << endl; + + t << "INCPATH = "; + QStringList &incs = project->variables()["INCLUDEPATH"]; + for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) { + QString inc = (*incit); + inc.replace(QRegExp("\\\\$"), "\\\\"); + inc.replace(QRegExp("\""), ""); + t << " -I" << "\"" << inc << "\""; + } + t << " -I" << "\"" << specdir() << "\"" << endl; + if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { + t << "LINK = " << var("QMAKE_LINK") << endl; + t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl; + t << "LIBS = "; + if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) + t << varGlue("QMAKE_LIBDIR","-L\"","\" -L\"","\"") << " "; + t << var("QMAKE_LIBS").replace(QRegExp("(\\slib|^lib)")," -l") << endl; + } + else { + t << "LIB = " << var("QMAKE_LIB") << endl; + } + t << "MOC = " << (project->isEmpty("QMAKE_MOC") ? QString("moc") : + Option::fixPathToTargetOS(var("QMAKE_MOC"), FALSE)) << endl; + t << "UIC = " << (project->isEmpty("QMAKE_UIC") ? QString("uic") : + Option::fixPathToTargetOS(var("QMAKE_UIC"), FALSE)) << endl; + t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : + Option::fixPathToTargetOS(var("QMAKE_QMAKE"), FALSE)) << endl; + t << "IDC = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") : + Option::fixPathToTargetOS(var("QMAKE_IDC"), FALSE)) << endl; + t << "IDL = " << (project->isEmpty("QMAKE_IDL") ? QString("midl") : + Option::fixPathToTargetOS(var("QMAKE_IDL"), FALSE)) << endl; + t << "ZIP = " << var("QMAKE_ZIP") << endl; + t << "DEF_FILE = " << varList("DEF_FILE") << endl; + t << "COPY_FILE = " << var("QMAKE_COPY") << endl; + t << "COPY_DIR = " << var("QMAKE_COPY") << endl; + t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; + t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; + t << "MOVE = " << var("QMAKE_MOVE") << endl; + t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; + t << "MKDIR = " << var("QMAKE_MKDIR") << endl; + t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl; + t << endl; + + t << "####### Output directory" << endl << endl; + if (! project->variables()["OBJECTS_DIR"].isEmpty()) + t << "OBJECTS_DIR = " << var("OBJECTS_DIR").replace(QRegExp("\\\\$"),"") << endl; + else + t << "OBJECTS_DIR = . " << endl; + if (! project->variables()["MOC_DIR"].isEmpty()) + t << "MOC_DIR = " << var("MOC_DIR").replace(QRegExp("\\\\$"),"") << endl; + else + t << "MOC_DIR = . " << endl; + t << endl; + + t << "####### Files" << endl << endl; + t << "HEADERS = " << varList("HEADERS") << endl; + t << "SOURCES = " << varList("SOURCES") << endl; + QString objectsLinkLine; + if (!project->variables()["QMAKE_APP_OR_DLL"].isEmpty() && + project->variables()["OBJECTS"].count() > var("QMAKE_LINK_OBJECT_MAX").toUInt()) { + createLdObjectScriptFile(var("QMAKE_LINK_OBJECT_SCRIPT"), project->variables()["OBJECTS"]); + objectsLinkLine = var("QMAKE_LINK_OBJECT_SCRIPT"); + } else { + objectsLinkLine = "$(OBJECTS)"; + } + t << "OBJECTS = " << varList("OBJECTS") << endl; + t << "FORMS = " << varList("FORMS") << endl; + t << "UICDECLS = " << varList("UICDECLS") << endl; + t << "UICIMPLS = " << varList("UICIMPLS") << endl; + t << "SRCMOC = " << varList("SRCMOC") << endl; + QString objmocLinkLine; + if (!project->variables()["QMAKE_APP_OR_DLL"].isEmpty() && + project->variables()["OBJMOC"].count() > var("QMAKE_LINK_OBJECT_MAX").toUInt()) { + createLdObjectScriptFile(var("QMAKE_LINK_OBJMOC_SCRIPT"), project->variables()["OBJMOC"]); + objmocLinkLine = var("QMAKE_LINK_OBJMOC_SCRIPT"); + } else { + objmocLinkLine = "$(OBJMOC)"; + } + t << "OBJMOC = " << varList("OBJMOC") << endl; + QString extraCompilerDeps; + if(!project->isEmpty("QMAKE_EXTRA_WIN_COMPILERS")) { + t << "OBJCOMP = " << varList("OBJCOMP") << endl; + extraCompilerDeps += " $(OBJCOMP) "; + + QStringList &comps = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) { + QStringList &vars = project->variables()[(*compit) + ".variables"]; + for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) { + QStringList vals = project->variables()[(*varit)]; + if(!vals.isEmpty()) + t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << endl; + } + } + } + + t << "DIST = " << varList("DISTFILES") << endl; + t << "TARGET = "; + if( !project->variables()[ "DESTDIR" ].isEmpty() ) + t << varGlue("TARGET",project->first("DESTDIR"),"",project->first("TARGET_EXT")); + else + t << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first(); + t << endl; + t << endl; + + t << "####### Implicit rules" << endl << endl; + t << ".SUFFIXES: .cpp .cxx .cc .C .c" << endl << endl; + t << ".cpp.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".cxx.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".cc.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".C.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".c.o:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; + + t << "####### Build rules" << endl << endl; + t << "all: " << "$(OBJECTS_DIR) " << "$(MOC_DIR) " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl; + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << extraCompilerDeps << var("POST_TARGETDEPS"); + if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { + t << "\n\t" << "$(LINK) $(LFLAGS) -o $(TARGET) " << objectsLinkLine << " " << objmocLinkLine << " $(LIBS)"; + } else { + t << "\n\t" << "$(LIB) $(TARGET) " << objectsLinkLine << " " << objmocLinkLine; + } + t << extraCompilerDeps; + if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) { + QStringList dlldirs = project->variables()["DLLDESTDIR"]; + for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { + t << "\n\t" << "$(COPY_FILE) \"$(TARGET)\" " << *dlldir; + } + } + QString targetfilename = project->variables()["TARGET"].first(); + if(project->isActiveConfig("activeqt")) { + QString version = project->variables()["VERSION"].first(); + if ( version.isEmpty() ) + version = "1.0"; + + if ( project->isActiveConfig("dll")) { + t << "\n\t" << ("-$(IDC) $(TARGET) /idl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" ); + } else { + t << "\n\t" << ("-$(TARGET) -dumpidl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << "-$(TARGET) -regserver"; + } + } + t << endl << endl; + + if(!project->variables()["RC_FILE"].isEmpty()) { + t << var("RES_FILE") << ": " << var("RC_FILE") << "\n\t" + << var("QMAKE_RC") << " -i " << var("RC_FILE") << " -o " << var("RC_FILE").replace(QRegExp("\\.rc"),".o") << " --include-dir=" << QFileInfo(var("RC_FILE")).dirPath() << endl << endl; + } + project->variables()["RES_FILE"].first().replace(QRegExp("\\.rc"),".o"); + + t << "mocables: $(SRCMOC)" << endl << endl; + + t << "$(OBJECTS_DIR):" << "\n\t" + << "@if not exist $(OBJECTS_DIR) $(MKDIR) $(OBJECTS_DIR)" << endl << endl; + + t << "$(MOC_DIR):" << "\n\t" + << "@if not exist $(MOC_DIR) $(MKDIR) $(MOC_DIR)" << endl << endl; + + writeMakeQmake(t); + + t << "dist:" << "\n\t" + << "$(ZIP) " << var("PROJECT") << ".zip " + << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" << endl << endl; + + t << "clean:" + << varGlue("OBJECTS","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","").replace(QRegExp("\\.obj"),".o") + << varGlue("SRCMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("OBJMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","").replace(QRegExp("\\.obj"),".o") + << varGlue("UICDECLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("UICIMPLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << "\n\t-$(DEL_FILE) $(TARGET)" + << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("CLEAN_FILES","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ",""); + if ( project->isActiveConfig("activeqt")) { + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".idl"); + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + } + if(!project->isEmpty("IMAGES")) + t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-$(DEL_FILE) ", "\n\t-$(DEL_FILE) ", ""); + + // user defined targets + QStringList::Iterator it; + QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; + + for(it = qut.begin(); it != qut.end(); ++it) { + QString targ = var((*it) + ".target"), + cmd = var((*it) + ".commands"), deps; + if(targ.isEmpty()) + targ = (*it); + QStringList &deplist = project->variables()[(*it) + ".depends"]; + for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) { + QString dep = var((*dep_it) + ".target"); + if(dep.isEmpty()) + dep = (*dep_it); + deps += " " + dep; + } + t << "\n\n" << targ << ":" << deps << "\n\t" + << cmd; + } + + t << endl << endl; + + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + QString tmp_dep = project->variables()[(*it) + ".depends"].join(" "); + QStringList &vars = project->variables()[(*it) + ".variables"]; + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out, cmd = tmp_cmd, deps; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + cmd.replace("${QMAKE_FILE_BASE}", fi.baseName()); + cmd.replace("${QMAKE_FILE_OUT}", out); + cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3) + cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); + if(!tmp_dep.isEmpty()) { + char buff[256]; + QString dep_cmd = tmp_dep; + dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) { + while(!feof(proc)) { + int read_in = int(fread(buff, 1, 255, proc)); + if(!read_in) + break; + int l = 0; + for(int i = 0; i < read_in; i++) { + if(buff[i] == '\n' || buff[i] == ' ') { + deps += " " + QCString(buff+l, (i - l) + 1); + l = i; + } + } + } + fclose(proc); + } + } + t << out << ": " << in << deps << "\n\t" + << cmd << endl << endl; + } + } + } + t << endl; +} + + +void +MingwMakefileGenerator::init() +{ + if(init_flag) + return; + init_flag = TRUE; + + /* this should probably not be here, but I'm using it to wrap the .t files */ + if(project->first("TEMPLATE") == "app") + project->variables()["QMAKE_APP_FLAG"].append("1"); + else if(project->first("TEMPLATE") == "lib") + project->variables()["QMAKE_LIB_FLAG"].append("1"); + else if(project->first("TEMPLATE") == "subdirs") { + MakefileGenerator::init(); + if(project->variables()["MAKEFILE"].isEmpty()) + project->variables()["MAKEFILE"].append("Makefile"); + if(project->variables()["QMAKE"].isEmpty()) + project->variables()["QMAKE"].append("qmake"); + return; + } + + if(project->isEmpty("QMAKE_INSTALL_FILE")) + project->variables()["QMAKE_INSTALL_FILE"].append("$(COPY_FILE)"); + if(project->isEmpty("QMAKE_INSTALL_DIR")) + project->variables()["QMAKE_INSTALL_DIR"].append("$(COPY_DIR)"); + + bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX); + project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; + + // LIBS defined in Profile comes first for gcc + project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; + + QString targetfilename = project->variables()["TARGET"].first(); + QStringList &configs = project->variables()["CONFIG"]; + + if (project->isActiveConfig("qt") && project->isActiveConfig("shared")) + project->variables()["DEFINES"].append("QT_DLL"); + + if (project->isActiveConfig("qt_dll")) + if (configs.findIndex("qt") == -1) + configs.append("qt"); + + if ( project->isActiveConfig("qt") ) { + if ( project->isActiveConfig( "plugin" ) ) { + project->variables()["CONFIG"].append("dll"); + if(project->isActiveConfig("qt")) + project->variables()["DEFINES"].append("QT_PLUGIN"); + } + if ( (project->variables()["DEFINES"].findIndex("QT_NODLL") == -1) && + ((project->variables()["DEFINES"].findIndex("QT_MAKEDLL") != -1 || + project->variables()["DEFINES"].findIndex("QT_DLL") != -1) || + (getenv("QT_DLL") && !getenv("QT_NODLL"))) ) { + project->variables()["QMAKE_QT_DLL"].append("1"); + if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) + project->variables()["CONFIG"].append("dll"); + } + if ( project->isActiveConfig("thread") ) + project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT"); + if ( project->isActiveConfig("accessibility" ) ) + project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT"); + if ( project->isActiveConfig("tablet") ) + project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT"); + } + + if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { + project->variables()["CONFIG"].remove("staticlib"); + project->variables()["QMAKE_APP_OR_DLL"].append("1"); + } else { + project->variables()["CONFIG"].append("staticlib"); + } + + if ( project->isActiveConfig("warn_off") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"]; + } else if ( project->isActiveConfig("warn_on") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"]; + } + + if ( project->isActiveConfig("debug") ) { + if ( project->isActiveConfig("thread") ) { + // use the DLL RT even here + if ( project->variables()["DEFINES"].contains("QT_DLL") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DBG"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"]; + } + } + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"]; + } else { + if ( project->isActiveConfig("thread") ) { + if ( project->variables()["DEFINES"].contains("QT_DLL") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLL"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT"]; + } + } + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"]; + } + + if ( !project->variables()["QMAKE_INCDIR"].isEmpty()) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"]; + + if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") ) + project->variables()["CONFIG"].append("windows"); + + if ( project->isActiveConfig("qt") ) { + project->variables()["CONFIG"].append("moc"); + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; + project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"]; + if ( !project->isActiveConfig("debug") ) + project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG"); + if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { + if ( !project->variables()["QMAKE_QT_DLL"].isEmpty()) { + project->variables()["DEFINES"].append("QT_MAKEDLL"); + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_QT_DLL"]; + } + } else { + + if(project->isActiveConfig("thread")) + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; + else + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; + if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { + int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt"); + if ( hver == -1 ) + hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt"); + if(hver != -1) { + QString ver; + ver.sprintf("libqt-%s" QTDLL_POSTFIX "%d.a", (project->isActiveConfig("thread") ? "-mt" : ""), hver); + QStringList &libs = project->variables()["QMAKE_LIBS"]; +// @@@HGTODO maybe we must change the replace regexp if we understand what's going on + for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) + (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver); + } + } + if ( project->isActiveConfig( "activeqt" ) ) { + project->variables().remove("QMAKE_LIBS_QT_ENTRY"); + project->variables()["QMAKE_LIBS_QT_ENTRY"] = "-lqaxserver"; + if ( project->isActiveConfig( "dll" ) ) { + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"]; + } + } + if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) { + project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"]; + } + + // QMAKE_LIBS_QT_ENTRY should be first on the link line as it needs qt + project->variables()["QMAKE_LIBS"].remove(project->variables()["QMAKE_LIBS_QT_ENTRY"].first()); + project->variables()["QMAKE_LIBS"].prepend(project->variables()["QMAKE_LIBS_QT_ENTRY"].first()); + + } + } + + if ( project->isActiveConfig("opengl") ) { + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"]; + } + + if ( project->isActiveConfig("dll") ) { + project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE_DLL"]; + project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE_DLL"]; + project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE_DLL"]; + project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS_DLL"]; + if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty()) { + project->variables()["TARGET_EXT"].append( + QStringList::split('.',project->first("VERSION")).join("") + ".dll"); + } else { + project->variables()["TARGET_EXT"].append(".dll"); + } + } else { + project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE"]; + project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE"]; + project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE"]; + project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS"]; + if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty()) { + project->variables()["TARGET_EXT"].append(".exe"); + } else { + project->variables()["TARGET_EXT"].append(".a"); + project->variables()["QMAKE_LFLAGS"].append("-static"); + if(project->variables()["TARGET"].first().left(3) != "lib") + project->variables()["TARGET"].first().prepend("lib"); + } + } + + if ( project->isActiveConfig("windows") ) { + if ( project->isActiveConfig("console") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; + } else { + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"]; + } + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; + } + + if ( project->isActiveConfig("exceptions") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_OFF"]; + } + + if ( project->isActiveConfig("rtti") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_OFF"]; + } + + if ( project->isActiveConfig("moc") ) + setMocAware(TRUE); + + // add -L libs to libdir + QStringList &libs = project->variables()["QMAKE_LIBS"]; + for ( QStringList::Iterator libit = libs.begin(); libit != libs.end(); ) { + if ( (*libit).startsWith( "-L" ) ) { + project->variables()["QMAKE_LIBDIR"] += (*libit).mid(2); + libit = libs.remove( libit ); + } else { + ++libit; + } + } + + project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', + "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH"); + QStringList &l = project->variables()["QMAKE_FILETAGS"]; + QStringList::Iterator it; + for(it = l.begin(); it != l.end(); ++it) { + QStringList &gdmf = project->variables()[(*it)]; + for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner) + (*inner) = Option::fixPathToTargetOS((*inner), FALSE); + } + + if ( project->isActiveConfig("dll") ) { + QString destDir = ""; + if (!project->first("DESTDIR").isEmpty()) + destDir = project->first("DESTDIR") + Option::dir_sep; + project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,--out-implib,") + + destDir + "lib" + project->first("TARGET") + ".a"); + } + + if ( !project->variables()["DEF_FILE"].isEmpty() ) + project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,") + project->first("DEF_FILE")); +// if(!project->isActiveConfig("incremental")) +// project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no")); + +#if 0 + if ( !project->variables()["VERSION"].isEmpty() ) { + QString version = project->variables()["VERSION"][0]; + int firstDot = version.find( "." ); + QString major = version.left( firstDot ); + QString minor = version.right( version.length() - firstDot - 1 ); + minor.replace( ".", "" ); + project->variables()["QMAKE_LFLAGS"].append( "/VERSION:" + major + "." + minor ); + } +#endif + + if ( !project->variables()["RC_FILE"].isEmpty()) { + if ( !project->variables()["RES_FILE"].isEmpty()) { + fprintf(stderr, "Both .rc and .res file specified.\n"); + fprintf(stderr, "Please specify one of them, not both."); + exit(666); + } + project->variables()["RES_FILE"] = project->variables()["RC_FILE"]; + project->variables()["RES_FILE"].first().replace(".rc",".o"); + project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["CLEAN_FILES"] += project->variables()["RES_FILE"]; + } + + if ( !project->variables()["RES_FILE"].isEmpty()) + project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"]; + + MakefileGenerator::init(); + + if ( !project->variables()["VERSION"].isEmpty()) { + QStringList l = QStringList::split('.', project->first("VERSION")); + project->variables()["VER_MAJ"].append(l[0]); + project->variables()["VER_MIN"].append(l[1]); + } + + if(project->isActiveConfig("dll")) { + project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") +"lib" + project->first("TARGET") + ".a"); + } + + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + if(tmp_out.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1) + project->variables()["OBJCOMP"] += out; + } + } + } +} + +void +MingwMakefileGenerator::writeSubDirs(QTextStream &t) +{ + QString qs ; + QTextStream ts (&qs, IO_WriteOnly) ; + Win32MakefileGenerator::writeSubDirs( ts ) ; + QRegExp rx("(\\n\\tcd [^\\n\\t]+)(\\n\\t.+)\\n\\t@cd ..") ; + rx.setMinimal(TRUE); + int pos = 0 ; + while ( -1 != (pos = rx.search( qs, pos))) + { + QString qsMatch = rx.cap(2); + qsMatch.replace("\n\t"," && \\\n\t"); + qs.replace(pos+rx.cap(1).length(), rx.cap(2).length(), qsMatch ); + pos += (rx.cap(1).length()+qsMatch.length()); + } + t << qs ; +} diff --git a/qmake/generators/win32/mingw_make.h b/qmake/generators/win32/mingw_make.h index c00bf1b..d971e3a 100644 --- a/qmake/generators/win32/mingw_make.h +++ b/qmake/generators/win32/mingw_make.h @@ -1,58 +1,61 @@ -/****************************************************************************
-** $Id$
-**
-** Definition of ________ class.
-**
-** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
-**
-** This file is part of the network module of the Qt GUI Toolkit.
-**
-** This file may be distributed under the terms of the Q Public License
-** as defined by Trolltech AS of Norway and appearing in the file
-** LICENSE.QPL included in the packaging of this file.
-**
-** This file may be distributed and/or modified under the terms of the
-** GNU General Public License version 2 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.
-**
-** Licensees holding valid Qt Enterprise Edition licenses may use this
-** file in accordance with the Qt Commercial License Agreement provided
-** with the Software.
-**
-** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
-** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-**
-** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
-** information about Qt Commercial License Agreements.
-** See http://www.trolltech.com/qpl/ for QPL licensing information.
-** See http://www.trolltech.com/gpl/ for GPL licensing information.
-**
-** Contact info@trolltech.com if any conditions of this licensing are
-** not clear to you.
-**
-**********************************************************************/
-#ifndef __MINGW_MAKE_H__
-#define __MINGW_MAKE_H__
-
-#include "winmakefile.h"
-
-class MingwMakefileGenerator : public Win32MakefileGenerator
-{
- bool init_flag;
- void writeMingwParts(QTextStream &);
- void writeSubDirs(QTextStream &t) ;
-
- bool writeMakefile(QTextStream &);
- void init();
-
-public:
- MingwMakefileGenerator(QMakeProject *p);
- ~MingwMakefileGenerator();
-
-};
-
-inline MingwMakefileGenerator::~MingwMakefileGenerator()
-{ }
-
-#endif /* __MINGW_MAKE_H__ */
+/**************************************************************************** +** +** +** Definition of MingwMakefileGenerator class. +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of qmake. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition licenses may use this +** file in accordance with the Qt Commercial License Agreement provided +** with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef __MINGW_MAKE_H__ +#define __MINGW_MAKE_H__ + +#include "winmakefile.h" + +class MingwMakefileGenerator : public Win32MakefileGenerator +{ + bool init_flag; + void writeMingwParts(QTextStream &); + void writeSubDirs(QTextStream &t) ; + + bool writeMakefile(QTextStream &); + void init(); + + virtual bool findLibraries(); + +public: + MingwMakefileGenerator(QMakeProject *p); + ~MingwMakefileGenerator(); + +}; + +inline MingwMakefileGenerator::~MingwMakefileGenerator() +{ } + +#endif /* __MINGW_MAKE_H__ */ diff --git a/qmake/generators/win32/msvc_dsp.cpp b/qmake/generators/win32/msvc_dsp.cpp index 3fa0496..d2abac6 100644 --- a/qmake/generators/win32/msvc_dsp.cpp +++ b/qmake/generators/win32/msvc_dsp.cpp @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of DspMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -79,4 +77,6 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) dspfile = project->first("MSVCDSP_TEMPLATE"); } + if (dspfile.startsWith("\"") && dspfile.endsWith("\"")) + dspfile = dspfile.mid(1, dspfile.length() - 2); QString dspfile_loc = findTemplate(dspfile); @@ -88,4 +88,28 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) QTextStream dsp(&file); + QString platform = "Win32"; + if ( !project->variables()["QMAKE_PLATFORM"].isEmpty() ) + platform = varGlue("QMAKE_PLATFORM", "", " ", ""); + + // Setup PCH variables + precompH = project->first("PRECOMPILED_HEADER"); + QString namePCH = QFileInfo(precompH).fileName(); + usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header"); + if (usePCH) { + // Created files + QString origTarget = project->first("QMAKE_ORIG_TARGET"); + origTarget.replace(QRegExp("-"), "_"); + precompObj = "\"$(IntDir)\\" + origTarget + Option::obj_ext + "\""; + precompPch = "\"$(IntDir)\\" + origTarget + ".pch\""; + // Add PRECOMPILED_HEADER to HEADERS + if (!project->variables()["HEADERS"].contains(precompH)) + project->variables()["HEADERS"] += precompH; + // Add precompile compiler options + project->variables()["PRECOMPILED_FLAGS_REL"] = "/Yu\"" + namePCH + "\" /FI\"" + namePCH + "\" "; + project->variables()["PRECOMPILED_FLAGS_DEB"] = "/Yu\"" + namePCH + "\" /FI\"" + namePCH + "\" "; + // Return to variable pool + project->variables()["PRECOMPILED_OBJECT"] = precompObj; + project->variables()["PRECOMPILED_PCH"] = precompPch; + } int rep; QString line; @@ -112,5 +136,7 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) beginGroupForFile((*it), t); t << "# Begin Source File\n\nSOURCE=" << (*it) << endl; - if ( project->isActiveConfig("moc") && (*it).endsWith(Option::moc_ext)) { + if (usePCH && (*it).endsWith(".c")) + t << "# SUBTRACT CPP /FI\"" << namePCH << "\" /Yu\"" << namePCH << "\" /Fp" << endl; + if ( project->isActiveConfig("moc") && (*it).endsWith(Option::cpp_moc_ext)) { QString base = (*it); base.replace(QRegExp("\\..*$"), "").upper(); @@ -125,6 +151,6 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) t << "USERDEP_" << base << "=\".\\" << findMocSource((*it)) << "\" \"$(QTDIR)\\bin\\moc.exe\"" << endl << endl; - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF " << endl << endl; } @@ -147,23 +173,75 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) // beginGroupForFile((*it), t); t << "# Begin Source File\n\nSOURCE=" << (*it) << endl << endl; - if ( project->isActiveConfig("moc") && !findMocDestination((*it)).isEmpty()) { - QString base = (*it); + QString compilePCH; + QStringList customDependencies; + QString createMOC; + QString buildCmdsR, buildCmdsD; + QString buildCmds = "\nBuildCmds= \\\n"; + // Create unique baseID + QString base = (*it); + { base.replace(QRegExp("\\..*$"), "").upper(); base.replace(QRegExp("[^a-zA-Z]"), "_"); + } + if (usePCH && precompH.endsWith(*it)) { + QString basicBuildCmd = QString("\tcl.exe /TP /W3 /FD /c /D \"WIN32\" /Yc /Fp\"%1\" /Fo\"%2\" %3 %4 %5 %6 %7 %8 %9 /D \"") + .arg(precompPch) + .arg(precompObj) + .arg(var("MSVCDSP_INCPATH")) + .arg(var("MSVCDSP_DEFINES")) + .arg(var("MSVCDSP_CXXFLAGS")); + buildCmdsR = basicBuildCmd + .arg("/D \"NDEBUG\"") + .arg(var("QMAKE_CXXFLAGS_RELEASE")) + .arg(var("MSVCDSP_MTDEF")) + .arg(var("MSVCDSP_RELDEFS")); + buildCmdsD = basicBuildCmd + .arg("/D \"_DEBUG\" /Od") + .arg(var("QMAKE_CXXFLAGS_DEBUG")) + .arg(var("MSVCDSP_MTDEFD")) + .arg(var("MSVCDSP_DEBUG_OPT")); + if (project->first("TEMPLATE") == "vcapp") { // App + buildCmdsR += var("MSVCDSP_WINCONDEF"); + buildCmdsD += var("MSVCDSP_WINCONDEF"); + } else if (project->isActiveConfig("dll")) { // Dll + buildCmdsR += "_WINDOWS\" /D \"_USRDLL"; + buildCmdsD += "_WINDOWS\" /D \"_USRDLL"; + } else { // Lib + buildCmdsR += "_LIB"; + buildCmdsD += "_LIB"; + } + buildCmdsR += "\" /Fd\"$(IntDir)\\\\\" " + (*it) + " \\\n"; + buildCmdsD += "\" /Fd\"$(IntDir)\\\\\" " + (*it) + " \\\n"; + + compilePCH = precompPch + " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n $(BuildCmds)\n\n"; + QStringList &tmp = findDependencies(precompH); + if(!tmp.isEmpty()) // Got Deps for PCH + customDependencies += tmp; + } + if (project->isActiveConfig("moc") && !findMocDestination((*it)).isEmpty()) { QString mocpath = var( "QMAKE_MOC" ); mocpath = mocpath.replace( QRegExp( "\\..*$" ), "" ) + " "; - - QString build = "\n\n# Begin Custom Build - Moc'ing " + (*it) + - "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + findMocDestination((*it)) + - "\"" " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n" - "\t" + mocpath + (*it) + " -o " + - findMocDestination((*it)) + "\n\n" "# End Custom Build\n\n"; - - t << "USERDEP_" << base << "=\"$(QTDIR)\\bin\\moc.exe\"" << endl << endl; - - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" - << build << "!ENDIF " << endl << endl; + buildCmds += "\t" + mocpath + (*it) + " -o " + findMocDestination((*it)) + " \\\n"; + createMOC = "\"" + findMocDestination((*it)) + "\" : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n $(BuildCmds)\n\n"; + customDependencies += "\"$(QTDIR)\\bin\\moc.exe\""; + } + if (!createMOC.isEmpty() || !compilePCH.isEmpty()) { + bool doMOC = !createMOC.isEmpty(); + bool doPCH = !compilePCH.isEmpty(); + QString build = "\n\n# Begin Custom Build - "+ + QString(doMOC?"Moc'ing ":"") + + QString((doMOC&&doPCH)?" and ":"") + + QString(doPCH?"Creating PCH cpp from ":"") + + (*it) + "...\nInputPath=.\\" + (*it) + "\n\n" + + buildCmds + "%1\n" + + createMOC + + compilePCH + + "# End Custom Build\n\n"; + + t << "USERDEP_" << base << "=" << valGlue(customDependencies, "\"", "\" \"", "\"") << endl << endl; + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build.arg(buildCmdsR) + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build.arg(buildCmdsD) + << "!ENDIF " << endl << endl; } t << "# End Source File" << endl; @@ -253,5 +331,5 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) // beginGroupForFile((*it), t); t << "# Begin Source File\n\nSOURCE=" << (*it) << endl; - if ( project->isActiveConfig("moc") && (*it).endsWith(Option::moc_ext)) { + if ( project->isActiveConfig("moc") && (*it).endsWith(Option::cpp_moc_ext)) { QString base = (*it); base.replace(QRegExp("\\..*$"), "").upper(); @@ -266,6 +344,6 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) t << "USERDEP_" << base << "=\".\\" << findMocSource((*it)) << "\" \"$(QTDIR)\\bin\\moc.exe\"" << endl << endl; - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF " << endl << endl; } @@ -388,5 +466,6 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) " -o " + uiHeadersDir + fname + ".h \\\n" "\t" + uicpath + base + " -i " + fname + ".h -o " + uiSourcesDir + fname + ".cpp \\\n" - "\t" + mocpath + uiHeadersDir + fname + ".h -o " + mocFile + "moc_" + fname + ".cpp \\\n"; + "\t" + mocpath + " " + uiHeadersDir + + fname + ".h -o " + mocFile + Option::h_moc_mod + fname + Option::h_moc_ext + " \\\n"; build.append("\n\"" + uiHeadersDir + fname + ".h\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" @@ -394,11 +473,11 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) "\"" + uiSourcesDir + fname + ".cpp\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" "\t$(BuildCmds)\n\n" - "\"" + mocFile + "moc_" + fname + ".cpp\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" + "\"" + mocFile + Option::h_moc_mod + fname + Option::h_moc_ext + "\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" "\t$(BuildCmds)\n\n"); build.append("# End Custom Build\n\n"); - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF \n\n" << "# End Source File" << endl; } @@ -430,6 +509,6 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) "\tcopy lex.yy.c " + fname + "\n\n" + "# End Custom Build\n\n"; - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF \n\n" << build @@ -466,6 +545,6 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) "# End Custom Build\n\n"; - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF \n\n" << "# End Source File" << endl; @@ -533,4 +612,5 @@ DspMakefileGenerator::init() } + /* this should probably not be here, but I'm using it to wrap the .t files */ if(project->first("TEMPLATE") == "vcapp" ) @@ -549,4 +629,10 @@ DspMakefileGenerator::init() if (project->isActiveConfig("qt_dll")) if(configs.findIndex("qt") == -1) configs.append("qt"); + if ( project->isActiveConfig("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); + } if ( project->isActiveConfig("qt") ) { if ( project->isActiveConfig( "plugin" ) ) { @@ -582,4 +668,12 @@ DspMakefileGenerator::init() } + if ( project->isActiveConfig("qtopiainc") ) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"]; + if ( project->isActiveConfig("qtopialib") ) { + if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA")) + project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QTOPIA"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"]; + } + if ( project->isActiveConfig("qt") ) { project->variables()["CONFIG"].append("moc"); @@ -635,4 +729,6 @@ DspMakefileGenerator::init() if ( !project->first("OBJECTS_DIR").isEmpty() ) project->variables()["MSVCDSP_OBJECTSDIRREL"] = project->first("OBJECTS_DIR"); + else + project->variables()["MSVCDSP_OBJECTSDIRREL"] = "Release"; project->variables()["MSVCDSP_OBJECTSDIRDEB"] = "Debug"; if ( !project->first("DESTDIR").isEmpty() ) @@ -671,4 +767,8 @@ DspMakefileGenerator::init() } if ( project->isActiveConfig("dll") ) { + project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE_DLL"]; + project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE_DLL"]; + project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE_DLL"]; + project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS_DLL"]; if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { QString ver_xyz(project->first("VERSION")); @@ -679,4 +779,8 @@ DspMakefileGenerator::init() } } else { + project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE"]; + project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE"]; + project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE"]; + project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS"]; if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) project->variables()["TARGET_EXT"].append(".exe"); @@ -685,4 +789,21 @@ DspMakefileGenerator::init() } + if ( project->isActiveConfig("windows") ) { + if ( project->isActiveConfig("console") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; + } else { + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"]; + } + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; + } + project->variables()["MSVCDSP_VER"] = "6.00"; project->variables()["MSVCDSP_DEBUG_OPT"] = "/GZ /ZI"; @@ -733,10 +854,8 @@ DspMakefileGenerator::init() project->variables()["MSVCDSP_WINCONDEF"].append("_CONSOLE"); project->variables()["MSVCDSP_DSPTYPE"].append("0x0103"); - project->variables()["MSVCDSP_SUBSYSTEM"].append("console"); } else { project->variables()["MSVCDSP_CONSOLE"].clear(); project->variables()["MSVCDSP_WINCONDEF"].append("_WINDOWS"); project->variables()["MSVCDSP_DSPTYPE"].append("0x0101"); - project->variables()["MSVCDSP_SUBSYSTEM"].append("windows"); } } else { @@ -749,5 +868,18 @@ DspMakefileGenerator::init() project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"]; + + processPrlFiles(); + // Update -lname to name.lib, + QStringList &libs2 = project->variables()["QMAKE_LIBS"]; + for ( QStringList::Iterator libit2 = libs2.begin(); libit2 != libs2.end(); ++libit2 ) { + if ( (*libit2).startsWith( "-l" ) ) { + (*libit2) = (*libit2).mid( 2 ) + ".lib"; + } else if ( (*libit2).startsWith( "-L" ) ) { + project->variables()["QMAKE_LIBDIR"] += (*libit2).mid(2); + libit2 = libs2.remove( libit2 ); + } + } + project->variables()["MSVCDSP_LFLAGS" ] += project->variables()["QMAKE_LFLAGS"]; if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) @@ -757,5 +889,7 @@ DspMakefileGenerator::init() project->variables()["MSVCDSP_DEFINES"].append(varGlue("PRL_EXPORT_DEFINES","/D ","" " /D ","")); - processPrlFiles(); + if (!project->variables()["RES_FILE"].isEmpty()) + project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"]; + QStringList &libs = project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) { @@ -769,4 +903,6 @@ DspMakefileGenerator::init() QString inc = (*incit); inc.replace("\"", ""); + if(inc.endsWith("\\")) // Remove trailing \'s from paths + inc.truncate(inc.length()-1); project->variables()["MSVCDSP_INCPATH"].append("/I \"" + inc + "\""); } @@ -821,13 +957,10 @@ DspMakefileGenerator::init() if ( version.isEmpty() ) version = "1.0"; - - project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".idl" ); - project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".tlb" ); - project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".midl" ); + project->variables()["MSVCDSP_IDLSOURCES"].append( var("OBJECTS_DIR") + targetfilename + ".idl" ); if ( project->isActiveConfig( "dll" ) ) { activeQtStepPreCopyDll += - "\t" + idc + " %1 -idl tmp\\" + targetfilename + ".idl -version " + version + - "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" - "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb"; + "\t" + idc + " %1 -idl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version + + "\t" + idl + " /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb" + + "\t" + idc + " %2 /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"; activeQtStepPostCopyDll += "\t" + idc + " %1 /regserver\n"; @@ -842,7 +975,7 @@ DspMakefileGenerator::init() } else { activeQtStepPreCopyDll += - "\t%1 -dumpidl tmp\\" + targetfilename + ".idl -version " + version + - "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" - "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb"; + "\t%1 -dumpidl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version + + "\t" + idl + " /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb" + + "\t" + idc + " %2 /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"; activeQtStepPostCopyDll += "\t%1 -regserver\n"; @@ -882,5 +1015,5 @@ DspMakefileGenerator::init() project->variables()["SOURCES"].append( *it + ".h" ); } - project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCDSP_LIBS"; + project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCDSP_LIBS"; } @@ -920,5 +1053,4 @@ DspMakefileGenerator::beginGroupForFile(QString file, QTextStream &t, if(project->isActiveConfig("flat")) return; - fileFixify(file, QDir::currentDirPath(), QDir::currentDirPath(), TRUE); file = file.section(Option::dir_sep, 0, -2); @@ -932,11 +1064,14 @@ DspMakefileGenerator::beginGroupForFile(QString file, QTextStream &t, return; } - if(file.startsWith(currentGroup)) - file = file.mid(currentGroup.length()); + + QString tempFile = file; + if(tempFile.startsWith(currentGroup)) + tempFile = tempFile.mid(currentGroup.length()); int dirSep = currentGroup.findRev( Option::dir_sep ); - while( !file.startsWith( currentGroup ) && dirSep != -1 ) { + + while( !tempFile.startsWith( currentGroup ) && dirSep != -1 ) { currentGroup.truncate( dirSep ); dirSep = currentGroup.findRev( Option::dir_sep ); - if ( !file.startsWith( currentGroup ) && dirSep != -1 ) + if ( !tempFile.startsWith( currentGroup ) && dirSep != -1 ) t << "\n# End Group\n"; } @@ -945,4 +1080,5 @@ DspMakefileGenerator::beginGroupForFile(QString file, QTextStream &t, currentGroup = ""; } + QStringList dirs = QStringList::split(Option::dir_sep, file.right( file.length() - currentGroup.length() ) ); for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { @@ -974,4 +1110,6 @@ DspMakefileGenerator::openOutput(QFile &file) const QString outdir; if(!file.name().isEmpty()) { + if(QDir::isRelativePath(file.name())) + file.setName(Option::output_dir + file.name()); //pwd when qmake was run QFileInfo fi(file); if(fi.isDir()) diff --git a/qmake/generators/win32/msvc_dsp.h b/qmake/generators/win32/msvc_dsp.h index 3a7d18e..0e86539 100644 --- a/qmake/generators/win32/msvc_dsp.h +++ b/qmake/generators/win32/msvc_dsp.h @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of DspMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -35,4 +33,5 @@ ** **********************************************************************/ + #ifndef __MSVC_DSP_H__ #define __MSVC_DSP_H__ @@ -63,4 +62,8 @@ protected: virtual void processPrlVariable(const QString &, const QStringList &); virtual bool findLibraries(); + + QString precompH, + precompObj, precompPch; + bool usePCH; }; diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index ecef34d..528cb19 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of NmakeMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -44,5 +42,4 @@ #include <time.h> - NmakeMakefileGenerator::NmakeMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) { @@ -55,4 +52,9 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) writeHeader(t); if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { + { //write the extra unix targets.. + QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; + for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it) + t << *it << " "; + } t << "all clean:" << "\n\t" << "@echo \"Some of the required modules (" @@ -75,4 +77,22 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) } +QStringList +&NmakeMakefileGenerator::findDependencies(const QString &file) +{ + QStringList &aList = MakefileGenerator::findDependencies(file); + // Note: The QMAKE_IMAGE_COLLECTION file have all images + // as dependency, so don't add precompiled header then + if (file == project->first("QMAKE_IMAGE_COLLECTION")) + return aList; + for(QStringList::Iterator it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) { + if(file.endsWith(*it)) { + if(!aList.contains(precompH)) + aList += precompH; + break; + } + } + return aList; +} + void NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) @@ -96,6 +116,6 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) { QString inc = (*incit); - inc.replace(QRegExp("\\\\$"), "\\\\"); - inc.replace("\"", ""); + if (inc.endsWith("\\")) + inc.truncate(inc.length()-1); t << " -I\"" << inc << "\""; } @@ -112,6 +132,6 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) { QString lib = (*libit); - lib.replace(QRegExp("\\\\$"), "\\\\"); - lib.replace(QRegExp("\""), ""); + if (lib.endsWith("\\")) + lib.truncate(lib.length()-1); t << " \"" << lib << "\""; } @@ -139,4 +159,6 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; t << "MKDIR = " << var("QMAKE_MKDIR") << endl; + t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl; t << endl; @@ -150,4 +172,21 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) t << "SRCMOC = " << varList("SRCMOC") << endl; t << "OBJMOC = " << varList("OBJMOC") << endl; + + QString extraCompilerDeps; + if(!project->isEmpty("QMAKE_EXTRA_WIN_COMPILERS")) { + t << "OBJCOMP = " << varList("OBJCOMP") << endl; + extraCompilerDeps += " $(OBJCOMP) "; + + QStringList &comps = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) { + QStringList &vars = project->variables()[(*compit) + ".variables"]; + for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) { + QStringList vals = project->variables()[(*varit)]; + if(!vals.isEmpty()) + t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << endl; + } + } + } + t << "DIST = " << varList("DISTFILES") << endl; t << "TARGET = "; @@ -165,4 +204,5 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) t << " " << (*cppit); t << endl << endl; + if(!project->isActiveConfig("no_batch")) { // Batchmode doesn't use the non implicit rules QMAKE_RUN_CXX & QMAKE_RUN_CC @@ -172,10 +212,12 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) QDict<void> source_directories; source_directories.insert(".", (void*)1); - if(!project->isEmpty("MOC_DIR")) - source_directories.insert(project->first("MOC_DIR"), (void*)1); - if(!project->isEmpty("UI_SOURCES_DIR")) - source_directories.insert(project->first("UI_SOURCES_DIR"), (void*)1); - else if(!project->isEmpty("UI_DIR")) - source_directories.insert(project->first("UI_DIR"), (void*)1); + QString directories[] = { QString("MOC_DIR"), QString("UI_SOURCES_DIR"), QString("UI_DIR"), QString::null }; + for(int y = 0; !directories[y].isNull(); y++) { + QString dirTemp = project->first(directories[y]); + if (dirTemp.endsWith("\\")) + dirTemp.truncate(dirTemp.length()-1); + if(!dirTemp.isEmpty()) + source_directories.insert(dirTemp, (void*)1); + } QString srcs[] = { QString("SOURCES"), QString("UICIMPLS"), QString("SRCMOC"), QString::null }; for(int x = 0; !srcs[x].isNull(); x++) { @@ -207,7 +249,7 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) t << "####### Build rules" << endl << endl; - t << "all: " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl; - t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " - << var("POST_TARGETDEPS"); + t << "all: " << fileFixify(Option::output.name()) << " " << varGlue("ALL_DEPS"," "," "," ") << "$(TARGET)" << endl << endl; + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << extraCompilerDeps << var("POST_TARGETDEPS"); if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { t << "\n\t" << "$(LINK) $(LFLAGS) /OUT:$(TARGET) @<< " << "\n\t " @@ -217,4 +259,5 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) << "$(OBJECTS) $(OBJMOC)"; } + t << extraCompilerDeps; t << endl << "<<" << endl; if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) @@ -223,5 +266,5 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) QStringList dlldirs = project->variables()["DLLDESTDIR"]; for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { - t << "\n\t" << "-copy $(TARGET) " << *dlldir; + t << "\n\t" << "-$(COPY_FILE) \"$(TARGET)\" " << *dlldir; } } @@ -233,12 +276,12 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) if ( project->isActiveConfig("dll")) { - t << "\n\t" << ("-$(IDC) $(TARGET) /idl tmp\\" + targetfilename + ".idl -version " + version); - t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"); - t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /idl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" ); } else { - t << "\n\t" << ("-$(TARGET) -dumpidl tmp\\" + targetfilename + ".idl -version " + version); - t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"); - t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb"); + t << "\n\t" << ("-$(TARGET) -dumpidl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); t << "\n\t" << "-$(TARGET) -regserver"; } @@ -251,31 +294,51 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) } - t << "mocables: $(SRCMOC)" << endl << endl; + t << "mocables: $(SRCMOC)" << endl + << "uicables: $(UICIMPLS) $(UICDECLS)" << endl << endl; writeMakeQmake(t); + QStringList dist_files = Option::mkfile::project_files; + if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES")) + dist_files += project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"]; + if(!project->isEmpty("TRANSLATIONS")) + dist_files << var("TRANSLATIONS"); + if(!project->isEmpty("FORMS")) { + QStringList &forms = project->variables()["FORMS"]; + for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) { + QString ui_h = fileFixify((*formit) + Option::h_ext.first()); + if(QFile::exists(ui_h) ) + dist_files << ui_h; + } + } t << "dist:" << "\n\t" - << "$(ZIP) " << var("PROJECT") << ".zip " - << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" << endl << endl; - - t << "clean:" - << varGlue("OBJECTS","\n\t-del ","\n\t-del ","") - << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","") - << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","") - << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","") - << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","") - << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","") - << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ",""); - + << "$(ZIP) " << var("QMAKE_ORIG_TARGET") << ".zip " << "$(SOURCES) $(HEADERS) $(DIST) $(FORMS) " + << dist_files.join(" ") << " " << var("TRANSLATIONS") << " " << var("IMAGES") << endl << endl; + + t << "uiclean:" + << varGlue("UICDECLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("UICIMPLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") << endl; + + t << "mocclean:" + << varGlue("SRCMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("OBJMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") << endl; + + t << "clean: uiclean mocclean" + << varGlue("OBJECTS","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","\n") + << varGlue("CLEAN_FILES","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","\n"); if ( project->isActiveConfig("activeqt")) { - t << ("\n\t-del tmp\\" + targetfilename + ".*"); - t << "\n\t-del tmp\\dump.*"; + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".idl"); + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".tlb"); } if(!project->isEmpty("IMAGES")) - t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", ""); + t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-$(DEL_FILE) ", "\n\t-$(DEL_FILE) ", ""); + t << endl; + + // user defined targets - // blasted user defined targets + QStringList::Iterator it; QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; - for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) { + for(it = qut.begin(); it != qut.end(); ++it) { QString targ = var((*it) + ".target"), cmd = var((*it) + ".commands"), deps; @@ -289,15 +352,103 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) deps += " " + dep; } + if(!project->variables()["QMAKE_NOFORCE"].isEmpty() && + project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; t << "\n\n" << targ << ":" << deps << "\n\t" << cmd; } - t << endl << endl; + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + QString tmp_dep = project->variables()[(*it) + ".depends"].join(" "); + QStringList &vars = project->variables()[(*it) + ".variables"]; + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out, cmd = tmp_cmd, deps; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + cmd.replace("${QMAKE_FILE_BASE}", fi.baseName()); + cmd.replace("${QMAKE_FILE_OUT}", out); + cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3) + cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); + if(!tmp_dep.isEmpty()) { + char buff[256]; + QString dep_cmd = tmp_dep; + dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) { + while(!feof(proc)) { + int read_in = int(fread(buff, 1, 255, proc)); + if(!read_in) + break; + int l = 0; + for(int i = 0; i < read_in; i++) { + if(buff[i] == '\n' || buff[i] == ' ') { + deps += " " + QCString(buff+l, (i - l) + 1); + l = i; + } + } + } + fclose(proc); + } + } + t << out << ": " << in << deps << "\n\t" + << cmd << endl << endl; + } + } + } + t << endl; + + if(project->variables()["QMAKE_NOFORCE"].isEmpty()) + t << "FORCE:" << endl << endl; + t << "distclean: clean" - << "\n\t-del $(TARGET)" + << "\n\t-$(DEL_FILE) $(TARGET)" << endl << endl; + + // precompiled header + if(usePCH) { + QString precompRule = QString("-c -Yc -Fp%1 -Fo%2").arg(precompPch).arg(precompObj); + t << precompObj << ": " << precompH << " " << findDependencies(precompH).join(" \\\n\t\t") + << "\n\t" << "$(CXX) " + precompRule +" $(CXXFLAGS) $(INCPATH) -TP " << precompH << endl << endl; + } } +QString +NmakeMakefileGenerator::var(const QString &value) +{ + if (usePCH) { + if ((value == "QMAKE_RUN_CXX_IMP_BATCH" + || value == "QMAKE_RUN_CXX_IMP" + || value == "QMAKE_RUN_CXX")) { + QFileInfo precompHInfo(precompH); + QString precompRule = QString("-c -FI%1 -Yu%2 -Fp%3") + .arg(precompHInfo.fileName()) + .arg(precompHInfo.fileName()) + .arg(precompPch); + QString p = MakefileGenerator::var(value); + p.replace("-c", precompRule); + // Cannot use -Gm with -FI & -Yu, as this gives an + // internal compiler error, on the newer compilers + p.remove("-Gm"); + return p; + } else if (value == "QMAKE_CXXFLAGS") { + // Remove internal compiler error option + return MakefileGenerator::var(value).remove("-Gm"); + } + } + + // Normal val + return MakefileGenerator::var(value); +} void @@ -322,4 +473,9 @@ NmakeMakefileGenerator::init() } + if(project->isEmpty("QMAKE_INSTALL_FILE")) + project->variables()["QMAKE_INSTALL_FILE"].append("$(COPY_FILE)"); + if(project->isEmpty("QMAKE_INSTALL_DIR")) + project->variables()["QMAKE_INSTALL_DIR"].append("$(COPY_DIR)"); + bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX); project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; @@ -331,4 +487,10 @@ NmakeMakefileGenerator::init() if (project->isActiveConfig("qt_dll")) if(configs.findIndex("qt") == -1) configs.append("qt"); + if ( project->isActiveConfig("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); + } if ( project->isActiveConfig("qt") ) { if ( project->isActiveConfig( "plugin" ) ) { @@ -402,4 +564,11 @@ NmakeMakefileGenerator::init() if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") ) project->variables()["CONFIG"].append("windows"); + if ( project->isActiveConfig("qtopiainc") ) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"]; + if ( project->isActiveConfig("qtopialib") ) { + if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA")) + project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QTOPIA"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"]; + } if ( project->isActiveConfig("qt") ) { project->variables()["CONFIG"].append("moc"); @@ -509,8 +678,24 @@ NmakeMakefileGenerator::init() setMocAware(TRUE); project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; + + QStringList &libList = project->variables()["QMAKE_LIBS"]; + for( QStringList::Iterator stIt = libList.begin(); stIt != libList.end(); ) { + QString s = *stIt; + if( s.startsWith( "-l" ) ) { + stIt = libList.remove( stIt ); + stIt = libList.insert( stIt, s.mid( 2 ) + ".lib" ); + } else if( s.startsWith( "-L" ) ) { + stIt = libList.remove( stIt ); + project->variables()["QMAKE_LIBDIR"].append(QDir::convertSeparators(s.mid( 2 ))); + } else { + stIt++; + } + } + project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH"); QStringList &l = project->variables()["QMAKE_FILETAGS"]; - for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QStringList::Iterator it; + for(it = l.begin(); it != l.end(); ++it) { QStringList &gdmf = project->variables()[(*it)]; for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner) @@ -540,9 +725,28 @@ NmakeMakefileGenerator::init() project->variables()["RES_FILE"].first().replace(".rc",".res"); project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["CLEAN_FILES"] += project->variables()["RES_FILE"]; } if ( !project->variables()["RES_FILE"].isEmpty()) project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"]; + // Base class init! MakefileGenerator::init(); + + // Setup PCH variables + precompH = project->first("PRECOMPILED_HEADER"); + usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header"); + if (usePCH) { + // Created files + precompObj = var("OBJECTS_DIR") + project->first("TARGET") + "_pch" + Option::obj_ext; + precompPch = var("OBJECTS_DIR") + project->first("TARGET") + "_pch.pch"; + // Add linking of precompObj (required for whole precompiled classes) + project->variables()["OBJECTS"] += precompObj; + // Add pch file to cleanup + project->variables()["QMAKE_CLEAN"] += precompPch; + // Return to variable pool + project->variables()["PRECOMPILED_OBJECT"] = precompObj; + project->variables()["PRECOMPILED_PCH"] = precompPch; + } + if ( !project->variables()["VERSION"].isEmpty()) { QStringList l = QStringList::split('.', project->first("VERSION")); @@ -559,4 +763,25 @@ NmakeMakefileGenerator::init() project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + version + ".ilk"); project->variables()["QMAKE_CLEAN"].append("vc*.pdb"); + project->variables()["QMAKE_CLEAN"].append("vc*.idb"); + } + + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + if(tmp_out.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1) + project->variables()["OBJCOMP"] += out; + } + } } } diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h index 579fc35..f2996cd 100644 --- a/qmake/generators/win32/msvc_nmake.h +++ b/qmake/generators/win32/msvc_nmake.h @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of NmakeMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -35,4 +33,5 @@ ** **********************************************************************/ + #ifndef __MSVC_NMAKE_H__ #define __MSVC_NMAKE_H__ @@ -48,4 +47,10 @@ class NmakeMakefileGenerator : public Win32MakefileGenerator void init(); +protected: + QStringList &findDependencies(const QString &file); + QString var(const QString &value); + QString precompH, precompObj, precompPch; + bool usePCH; + public: NmakeMakefileGenerator(QMakeProject *p); diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 7ffe4f7..a672c2d 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -1,10 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of VCProject class. ** -** Copyright (C) 2002 Trolltech AS. All rights reserved. +** Copyright (C) 2002-2003 Trolltech AS. All rights reserved. ** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -38,19 +38,5 @@ #include <qtextstream.h> #include <qstringlist.h> -#include <quuid.h> - -#if defined(Q_OS_WIN32) -#include <objbase.h> -#ifndef GUID_DEFINED -#define GUID_DEFINED -typedef struct _GUID -{ - ulong Data1; - ushort Data2; - ushort Data3; - uchar Data4[8]; -} GUID; -#endif -#endif +#include <qfileinfo.h> // XML Tags --------------------------------------------------------- @@ -282,5 +268,4 @@ struct XPair { // void streamSPair( QTextStream &strm, const char *n, const QString &s ) - // Streaming operators for property Pairs --------------------------- QTextStream &operator<<( QTextStream &strm, const TPair &prop ) @@ -319,5 +304,5 @@ QTextStream &operator<<( QTextStream &strm, const SPair &prop ) { if ( !prop.value.isEmpty() ) - strm << prop.name << prop.value.latin1() << "\""; + strm << prop.name << QString(prop.value).remove("\"") << "\""; return strm; } @@ -335,5 +320,5 @@ VCCLCompilerTool::VCCLCompilerTool() BasicRuntimeChecks( runtimeBasicCheckNone ), BrowseInformation( brInfoNone ), - BufferSecurityCheck( unset ), + BufferSecurityCheck( _False ), CallingConvention( callConventionDefault ), CompileAs( compileAsDefault ), @@ -347,5 +332,5 @@ VCCLCompilerTool::VCCLCompilerTool() EnableFunctionLevelLinking( unset ), EnableIntrinsicFunctions( unset ), - ExceptionHandling( unset ), + ExceptionHandling( _False ), ExpandAttributedSource( unset ), FavorSizeOrSpeed( favorNone ), @@ -355,11 +340,12 @@ VCCLCompilerTool::VCCLCompilerTool() IgnoreStandardIncludePath( unset ), ImproveFloatingPointConsistency( unset ), - InlineFunctionExpansion( expandOnlyInline ), + InlineFunctionExpansion( expandDefault ), KeepComments( unset ), MinimalRebuild( unset ), OmitFramePointers( unset ), - Optimization( optimizeDisabled ), + Optimization( optimizeCustom ), OptimizeForProcessor( procOptimizeBlended ), OptimizeForWindowsApplication( unset ), + ProgramDataBaseFileName( "" ), RuntimeLibrary( rtMultiThreaded ), RuntimeTypeInfo( unset ), @@ -372,5 +358,5 @@ VCCLCompilerTool::VCCLCompilerTool() TurnOffAssemblyGeneration( unset ), UndefineAllPreprocessorDefinitions( unset ), - UsePrecompiledHeader( pchGenerateAuto ), + UsePrecompiledHeader( pchNone ), WarnAsError( unset ), WarningLevel( warningLevel_0 ), @@ -396,5 +382,5 @@ QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) if ( tool.CompileAsManaged != managedDefault ) strm << EPair( _CompileAsManaged, tool.CompileAsManaged ); strm << TPair( _CompileOnly, tool.CompileOnly ); - strm << EPair( _DebugInformationFormat, tool.DebugInformationFormat ); + if ( tool.DebugInformationFormat != debugUnknown ) strm << EPair( _DebugInformationFormat, tool.DebugInformationFormat ); strm << TPair( _DefaultCharIsUnsigned, tool.DefaultCharIsUnsigned ); strm << TPair( _Detect64BitPortabilityProblems, tool.Detect64BitPortabilityProblems ); @@ -410,14 +396,14 @@ QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) strm << XPair( _ForcedIncludeFiles, tool.ForcedIncludeFiles ); strm << XPair( _ForcedUsingFiles, tool.ForcedUsingFiles ); - strm << EPair( _GeneratePreprocessedFile, tool.GeneratePreprocessedFile ); + if ( tool.GeneratePreprocessedFile != preprocessUnknown)strm << EPair( _GeneratePreprocessedFile, tool.GeneratePreprocessedFile ); strm << TPair( _GlobalOptimizations, tool.GlobalOptimizations ); strm << TPair( _IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath ); strm << TPair( _ImproveFloatingPointConsistency, tool.ImproveFloatingPointConsistency ); - strm << EPair( _InlineFunctionExpansion, tool.InlineFunctionExpansion ); + if ( tool.InlineFunctionExpansion != expandDefault ) strm << EPair( _InlineFunctionExpansion, tool.InlineFunctionExpansion ); strm << TPair( _KeepComments, tool.KeepComments ); strm << TPair( _MinimalRebuild, tool.MinimalRebuild ); strm << SPair( _ObjectFile, tool.ObjectFile ); strm << TPair( _OmitFramePointers, tool.OmitFramePointers ); - strm << EPair( _Optimization, tool.Optimization ); + if ( tool.Optimization != optimizeDefault ) strm << EPair( _Optimization, tool.Optimization ); if ( tool.OptimizeForProcessor != procOptimizeBlended ) strm << EPair( _OptimizeForProcessor, tool.OptimizeForProcessor ); strm << TPair( _OptimizeForWindowsApplication, tool.OptimizeForWindowsApplication ); @@ -426,6 +412,6 @@ QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) strm << SPair( _PrecompiledHeaderThrough, tool.PrecompiledHeaderThrough ); strm << XPair( _PreprocessorDefinitions, tool.PreprocessorDefinitions ); - strm << SPair( _ProgramDataBaseFileName, tool.ProgramDataBaseFileName ); - strm << EPair( _RuntimeLibrary, tool.RuntimeLibrary ); + if ( !tool.ProgramDataBaseFileName.isNull() ) strm << _ProgramDataBaseFileName << tool.ProgramDataBaseFileName.latin1() << "\""; + if ( tool.RuntimeLibrary != rtUnknown ) strm << EPair( _RuntimeLibrary, tool.RuntimeLibrary ); strm << TPair( _RuntimeTypeInfo, tool.RuntimeTypeInfo ); strm << TPair( _ShowIncludes, tool.ShowIncludes ); @@ -442,5 +428,5 @@ QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) strm << EPair( _UsePrecompiledHeader, tool.UsePrecompiledHeader ); strm << TPair( _WarnAsError, tool.WarnAsError ); - strm << EPair( _WarningLevel, tool.WarningLevel ); + if ( tool.WarningLevel != warningLevelUnknown ) strm << EPair( _WarningLevel, tool.WarningLevel ); strm << TPair( _WholeProgramOptimization, tool.WholeProgramOptimization ); strm << "/>"; @@ -475,5 +461,5 @@ bool VCCLCompilerTool::parseOption( const char* option ) found = FALSE; break; } - AdditionalUsingDirectories += option+2; + AdditionalUsingDirectories += option+3; break; case 'C': @@ -481,9 +467,11 @@ bool VCCLCompilerTool::parseOption( const char* option ) break; case 'D': - PreprocessorDefinitions += option+1; + PreprocessorDefinitions += option+2; break; case 'E': if ( second == 'H' ) { - if ( third == 'a' || third == 'c' || third == 's' ) { + if ( third == 'a' + || (third == 'c' && fourth != 's') + || (third == 's' && fourth != 'c') ) { // ExceptionHandling must be false, or it will override // with an /EHsc option @@ -491,4 +479,9 @@ bool VCCLCompilerTool::parseOption( const char* option ) AdditionalOptions += option; break; + } else if ( (third == 'c' && fourth == 's') + || (third == 's' && fourth == 'c') ) { + ExceptionHandling = _True; + AdditionalOptions += option; + break; } found = FALSE; break; @@ -592,4 +585,7 @@ bool VCCLCompilerTool::parseOption( const char* option ) break; case 'X': + // ExceptionHandling == true will override with + // an /EHsc option, which is correct with /GX + ExceptionHandling = _True; // Fall-through case 'Z': case 'e': @@ -955,8 +951,8 @@ VCLinkerTool::VCLinkerTool() IgnoreAllDefaultLibraries( unset ), IgnoreEmbeddedIDL( unset ), - IgnoreImportLibrary( unset ), + IgnoreImportLibrary( _True ), LargeAddressAware( addrAwareDefault ), LinkDLL( unset ), - LinkIncremental( linkIncrementalYes ), + LinkIncremental( linkIncrementalDefault ), LinkTimeCodeGeneration( unset ), MapExports( unset ), @@ -1020,5 +1016,5 @@ QTextStream &operator<<( QTextStream &strm, const VCLinkerTool &tool ) if ( tool.OptimizeReferences != optReferencesDefault ) strm << EPair( _OptimizeReferences, tool.OptimizeReferences ); strm << SPair( _OutputFile, tool.OutputFile ); - strm << SPair( _ProgramDatabaseFile, tool.ProgramDatabaseFile ); + strm << _ProgramDatabaseFile << tool.ProgramDatabaseFile << "\""; strm << TPair( _RegisterOutput, tool.RegisterOutput ); strm << TPair( _ResourceOnlyDLL, tool.ResourceOnlyDLL ); @@ -1708,7 +1704,7 @@ QTextStream &operator<<( QTextStream &strm, const VCCustomBuildTool &tool ) strm << SPair( _ToolName, tool.ToolName ); strm << XPair( _AdditionalDependencies4, tool.AdditionalDependencies, ";" ); - strm << SPair( _CommandLine4, tool.CommandLine ); + strm << XPair( _CommandLine4, tool.CommandLine, "\n" ); strm << SPair( _Description4, tool.Description ); - strm << SPair( _Outputs4, tool.Outputs ); + strm << XPair( _Outputs4, tool.Outputs, ";" ); strm << SPair( _ToolPath, tool.ToolPath ); strm << "/>"; @@ -1827,41 +1823,37 @@ VCFilter::VCFilter() : ParseFiles( unset ) { + useCustomBuildTool = FALSE; + useCompilerTool = FALSE; } -void VCFilter::generateMOC( QTextStream &strm, QString str ) const +void VCFilter::addMOCstage( QTextStream &strm, QString filename ) { - QString mocOutput = Project->findMocDestination( str ); + QString mocOutput = Project->findMocDestination( filename ); QString mocApp = Project->var( "QMAKE_MOC" ); - if( mocOutput.isEmpty() ) { + if( mocOutput.isEmpty() && filename.endsWith(".moc") ) { // In specialcases we DO moc .cpp files // when the result is an .moc file - if ( !str.endsWith(".moc") ) - return; - mocOutput = str; - str = Project->findMocSource( mocOutput ); + mocOutput = filename; + filename = Project->findMocSource( mocOutput ); } - strm << _begFileConfiguration; - strm << _Name5; - strm << Config->Name; - strm << "\">"; - strm << _begTool5; - strm << _VCCustomBuildTool; - strm << _Description6; - strm << "Moc'ing " << str << "...\""; - strm << _CommandLine6; - strm << mocApp; - strm << " " << str << " -o " << mocOutput << "\""; - strm << _AdditionalDependencies6; - strm << mocApp << "\""; - strm << _Outputs6; - strm << mocOutput << "\""; - strm << "/>"; - strm << _endFileConfiguration; + if (mocOutput.isEmpty()) + return; + + CustomBuildTool = VCCustomBuildTool(); + useCustomBuildTool = TRUE; + CustomBuildTool.Description = "Moc'ing " + filename + "..."; + CustomBuildTool.CommandLine += (mocApp + " " + + filename + " -o " + mocOutput); + CustomBuildTool.AdditionalDependencies = mocApp; + CustomBuildTool.Outputs += mocOutput; } -void VCFilter::generateUIC( QTextStream &strm, const QString& str ) const +void VCFilter::addUICstage( QTextStream &strm, QString str ) { + CustomBuildTool = VCCustomBuildTool(); + useCustomBuildTool = TRUE; + QString uicApp = Project->var("QMAKE_UIC"); QString mocApp = Project->var( "QMAKE_MOC" ); @@ -1896,25 +1888,101 @@ void VCFilter::generateUIC( QTextStream &strm, const QString& str ) const fname.truncate( dot ); - strm << _begFileConfiguration; - strm << _Name5; - strm << Config->Name; - strm << "\">"; - strm << _begTool5; - strm << _VCCustomBuildTool; - strm << _Description6; - strm << "Uic'ing " << str << "...\""; - strm << _CommandLine6; - strm << uicApp << " " << str << " -o " << uiHeaders << fname << ".h && "; // Create .h from .ui file - strm << uicApp << " " << str << " -i " << fname << ".h -o " << uiSources << fname << ".cpp && "; // Create .cpp from .ui file - strm << mocApp << " " << uiHeaders << fname << ".h -o " << mocDir << "moc_" << fname << ".cpp\""; - strm << _AdditionalDependencies6; - strm << mocApp << ";" << uicApp << "\""; - strm << _Outputs6; - strm << uiHeaders << fname << ".h;" << uiSources << fname << ".cpp;" << mocDir << "moc_" << fname << ".cpp\""; - strm << "/>"; - strm << _endFileConfiguration; + if ( mocDir.isEmpty() ) + mocDir = pname; + + CustomBuildTool.Description = ("Uic'ing " + str + "...\""); + CustomBuildTool.CommandLine += // Create .h from .ui file + uicApp + " " + str + " -o " + uiHeaders + fname + ".h"; + CustomBuildTool.CommandLine += // Create .cpp from .ui file + uicApp + " " + str + " -i " + fname + ".h -o " + uiSources + fname + ".cpp"; + CustomBuildTool.CommandLine += // Moc the headerfile + mocApp + " " + uiHeaders + fname + ".h -o " + mocDir + Option::h_moc_mod + fname + Option::h_moc_ext; + + CustomBuildTool.AdditionalDependencies += mocApp; + CustomBuildTool.AdditionalDependencies += uicApp; + CustomBuildTool.Outputs += + uiHeaders + fname + ".h;" + uiSources + fname + ".cpp;" + mocDir + Option::h_moc_mod + fname + Option::h_moc_ext; } -QTextStream &operator<<( QTextStream &strm, const VCFilter &tool ) +void VCFilter::modifyPCHstage( QTextStream &strm, QString str ) +{ + bool isCFile = str.endsWith(".c"); + bool isHFile = (str.endsWith(".h") && str == Project->precompH); + + if (!isCFile && !isHFile) + return; + + CompilerTool = VCCLCompilerTool(); + useCompilerTool = TRUE; + + // Unset some default options + CompilerTool.BufferSecurityCheck = unset; + CompilerTool.DebugInformationFormat = debugUnknown; + CompilerTool.ExceptionHandling = unset; + CompilerTool.GeneratePreprocessedFile = preprocessUnknown; + CompilerTool.Optimization = optimizeDefault; + CompilerTool.ProgramDataBaseFileName = QString::null; + CompilerTool.RuntimeLibrary = rtUnknown; + CompilerTool.WarningLevel = warningLevelUnknown; + + // Setup PCH options + CompilerTool.UsePrecompiledHeader = (isCFile ? pchNone : pchCreateUsingSpecific); + CompilerTool.PrecompiledHeaderThrough = "$(NOINHERIT)"; + CompilerTool.ForcedIncludeFiles = "$(NOINHERIT)"; +} + +bool VCFilter::addIMGstage( QTextStream &strm, QString str ) +{ + bool isCorH = FALSE; + if (str.endsWith(".c") || str.endsWith(".rc")) + isCorH = TRUE; + QStringList::Iterator it; + for(it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) + if(str.endsWith(*it)) + isCorH = TRUE; + for(it = Option::h_ext.begin(); it != Option::h_ext.end(); ++it) + if(str.endsWith(*it)) + isCorH = TRUE; + + QString collectionName = Project->project->first("QMAKE_IMAGE_COLLECTION"); + if (str.isEmpty() || isCorH || collectionName.isEmpty()) + return FALSE; + + CustomBuildTool = VCCustomBuildTool(); + useCustomBuildTool = TRUE; + + // Some projects (like designer core) may have too many images to + // call uic directly. Therefor we have to create a temporary + // file, with the image list, and call uic with the -f option. + QString tmpFileCmd = "echo "; + QString tmpImageFilename = ".imgcol"; + QStringList& list = Project->project->variables()["IMAGES"]; + bool firstOutput = TRUE; + it = list.begin(); + while( it!=list.end() ) { + tmpFileCmd += (*it) + " "; + ++it; + if (tmpFileCmd.length()>250 || it==list.end()) { + CustomBuildTool.CommandLine += tmpFileCmd + + (firstOutput?"> ":">> ") + + tmpImageFilename; + tmpFileCmd = "echo "; + firstOutput = FALSE; + } + } + + QString uicApp = Project->var("QMAKE_UIC"); + CustomBuildTool.Description = ("Generate imagecollection"); + CustomBuildTool.CommandLine += + uicApp + " -embed " + Project->project->first("QMAKE_ORIG_TARGET") + + " -f .imgcol -o " + collectionName; + CustomBuildTool.AdditionalDependencies += uicApp; + CustomBuildTool.AdditionalDependencies += list; + CustomBuildTool.Outputs = collectionName; + CustomBuildTool.Outputs += tmpImageFilename; + return TRUE; +} + +QTextStream &operator<<( QTextStream &strm, VCFilter &tool ) { if ( tool.Files.count() == 0 ) @@ -1926,15 +1994,75 @@ QTextStream &operator<<( QTextStream &strm, const VCFilter &tool ) strm << SPair( _Filter, tool.Filter ); strm << ">"; + + bool resourceBuild = FALSE; + int currentLevels = 0; + QStringList currentDirs; for ( QStringList::ConstIterator it = tool.Files.begin(); it != tool.Files.end(); ++it ) { + if ( !tool.flat_files ) { + QStringList newDirs = QStringList::split('\\',(*it)); + newDirs.pop_back(); // Skip the filename + + int newLevels = int(newDirs.count()); + int equalLevels = 0; + for (int i = 0; i<currentLevels; i++, equalLevels++ ) + if (currentDirs[i] != newDirs[i]) + break; + int closeFilters = currentLevels - equalLevels; + int openFilters = newLevels - equalLevels; + + // close previous non-equal filter + while ( closeFilters-- ) + strm << _endFilter; + + // open new non-equal filters + newLevels = 0; + while ( openFilters-- ) { + strm << _begFilter; + strm << SPair( _Name3, newDirs[equalLevels + newLevels] ); + strm << _Filter << "\">"; // Blank filter + ++newLevels; + } + currentDirs = newDirs; + currentLevels = int(newDirs.count()); + } + + tool.useCustomBuildTool = FALSE; + tool.useCompilerTool = FALSE; + // Add UIC, MOC and PCH stages to file + if ( tool.CustomBuild == moc ) + tool.addMOCstage( strm, *it ); + else if ( tool.CustomBuild == uic ) + tool.addUICstage( strm, *it ); + else if ( tool.CustomBuild == resource ) { + if (!resourceBuild) + resourceBuild = tool.addIMGstage(strm, *it); + } + if (tool.Project->usePCH) + tool.modifyPCHstage( strm, *it ); + strm << _begFile; strm << SPair( _RelativePath, *it ); strm << ">"; - if ( tool.CustomBuild == moc ) - tool.generateMOC( strm, *it ); - else if ( tool.CustomBuild == uic ) - tool.generateUIC( strm, *it ); + // Output custom build and compiler options + // for all configurations + if (tool.useCustomBuildTool || tool.useCompilerTool) { + for ( uint i = 0; i < tool.Config->count(); i++ ) { + strm << _begFileConfiguration; + strm << _Name5; + strm << (*tool.Config)[i].Name; + strm << "\">"; + if (tool.useCustomBuildTool) + strm << tool.CustomBuildTool; + if (tool.useCompilerTool) + strm << tool.CompilerTool; + strm << _endFileConfiguration; + } + } strm << _endFile; } - + // close remaining open filters, in non-flat mode + while ( !tool.flat_files && currentLevels-- ) { + strm << _endFilter; + } strm << _endFilter; return strm; @@ -1944,15 +2072,7 @@ QTextStream &operator<<( QTextStream &strm, const VCFilter &tool ) VCProject::VCProject() { -#if defined(Q_WS_WIN32) - GUID guid; - QUuid uniqueId; - HRESULT h = CoCreateGuid( &guid ); - if ( h == S_OK ) - uniqueId = QUuid( guid ); - ProjectGUID = uniqueId.toString(); -#else - // Qt doesn't support GUID on other platforms yet - ProjectGUID = ""; -#endif + VCConfiguration conf; + Configuration += conf ; // Release + //Configuration += conf ; // Debug added later, after Release init } @@ -1974,15 +2094,16 @@ QTextStream &operator<<( QTextStream &strm, const VCProject &tool ) strm << _endPlatforms; strm << _begConfigurations; - strm << tool.Configuration; + for ( uint i = 0; i < tool.Configuration.count(); i++ ) + strm << tool.Configuration[i]; strm << _endConfigurations; strm << _begFiles; - strm << tool.SourceFiles; - strm << tool.HeaderFiles; - strm << tool.MOCFiles; - strm << tool.UICFiles; - strm << tool.FormFiles; - strm << tool.TranslationFiles; - strm << tool.LexYaccFiles; - strm << tool.ResourceFiles; + strm << (VCFilter&)tool.SourceFiles; + strm << (VCFilter&)tool.HeaderFiles; + strm << (VCFilter&)tool.MOCFiles; + strm << (VCFilter&)tool.UICFiles; + strm << (VCFilter&)tool.FormFiles; + strm << (VCFilter&)tool.TranslationFiles; + strm << (VCFilter&)tool.LexYaccFiles; + strm << (VCFilter&)tool.ResourceFiles; strm << _endFiles; strm << _begGlobals; diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 1dca68d..9ce38d2 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -1,10 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of VCProject class. ** -** Copyright (C) 2002 Trolltech AS. All rights reserved. +** Copyright (C) 2002-2003 Trolltech AS. All rights reserved. ** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -33,4 +33,5 @@ ** **********************************************************************/ + #ifndef __MSVC_OBJECTMODEL_H__ #define __MSVC_OBJECTMODEL_H__ @@ -57,5 +58,6 @@ enum customBuildCheck { moc, uic, - lexyacc + lexyacc, + resource }; enum triState { @@ -115,4 +117,5 @@ enum ConfigurationTypes { }; enum debugOption { + debugUnknown = -1, debugDisabled, debugOldStyleInfo, @@ -241,5 +244,6 @@ enum inlineExpansionOption { expandDisable, expandOnlyInline, - expandAnySuitable + expandAnySuitable, + expandDefault // Not useful number, but stops the output }; enum linkIncrementalType { @@ -297,5 +301,6 @@ enum optimizeOption { optimizeMaxSpeed, optimizeFull, - optimizeCustom + optimizeCustom, + optimizeDefault // Not useful number, but stops the output }; enum optRefType { @@ -316,4 +321,5 @@ enum pchOption { }; enum preprocessOption { + preprocessUnknown = -1, preprocessNo, preprocessYes, @@ -331,4 +337,5 @@ enum RemoteDebuggerType { }; enum runtimeLibraryOption { + rtUnknown = -1, rtMultiThreaded, rtMultiThreadedDebug, @@ -380,4 +387,5 @@ enum useOfMfc { }; enum warningLevelOption { + warningLevelUnknown = -1, warningLevel_0, warningLevel_1, @@ -612,7 +620,7 @@ public: // Variables QStringList AdditionalDependencies; - QString CommandLine; + QStringList CommandLine; QString Description; - QString Outputs; + QStringList Outputs; QString ToolName; QString ToolPath; @@ -720,6 +728,8 @@ public: VCFilter(); ~VCFilter(){} - void generateMOC( QTextStream &strm, QString str ) const; - void generateUIC( QTextStream &strm, const QString& str ) const; + void addMOCstage( QTextStream &strm, QString str ); + void addUICstage( QTextStream &strm, QString str ); + bool addIMGstage( QTextStream &strm, QString str ); + void modifyPCHstage( QTextStream &strm, QString str ); // Variables @@ -729,6 +739,11 @@ public: QStringList Files; VcprojGenerator* Project; - VCConfiguration* Config; + QValueList<VCConfiguration> *Config; customBuildCheck CustomBuild; + bool useCustomBuildTool; + VCCustomBuildTool CustomBuildTool; + bool useCompilerTool; + VCCLCompilerTool CompilerTool; + bool flat_files; }; @@ -749,5 +764,5 @@ public: // XML sub-parts - VCConfiguration Configuration; + QValueList<VCConfiguration> Configuration; VCFilter SourceFiles; VCFilter HeaderFiles; @@ -768,5 +783,5 @@ QTextStream &operator<<( QTextStream &, const VCResourceCompilerTool & ); QTextStream &operator<<( QTextStream &, const VCEventTool & ); QTextStream &operator<<( QTextStream &, const VCConfiguration & ); -QTextStream &operator<<( QTextStream &, const VCFilter & ); +QTextStream &operator<<( QTextStream &, VCFilter & ); QTextStream &operator<<( QTextStream &, const VCProject & ); diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index d2cbc31..aa8fe16 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of VcprojGenerator class. +** Implementation of VcprojGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -38,4 +36,5 @@ #include "msvc_vcproj.h" #include "option.h" +#include "qtmd5.h" // SG's MD5 addon #include <qdir.h> #include <qregexp.h> @@ -43,21 +42,60 @@ #include <quuid.h> #include <stdlib.h> +#include <qsettings.h> + +//#define DEBUG_SOLUTION_GEN +//#define DEBUG_PROJECT_GEN + +// Registry keys for .NET version detection ------------------------- +const char* _regNet2002 = "Microsoft\\VisualStudio\\7.0\\Setup\\VC\\ProductDir"; +const char* _regNet2003 = "Microsoft\\VisualStudio\\7.1\\Setup\\VC\\ProductDir"; -#if defined(Q_OS_WIN32) -#include <objbase.h> -#ifndef GUID_DEFINED -#define GUID_DEFINED -typedef struct _GUID +bool use_net2003_version() { - ulong Data1; - ushort Data2; - ushort Data3; - uchar Data4[8]; -} GUID; -#endif +#ifndef Q_OS_WIN32 + return FALSE; // Always generate 7.0 versions on other platforms +#else + // Only search for the version once + static int current_version = -1; + if (current_version!=-1) + return (current_version==71); + + // Fallback to .NET 2002 + current_version = 70; + + // Get registry entries for both versions + bool ok = false; + QSettings setting; + QString path2002 = setting.readEntry(_regNet2002); + QString path2003 = setting.readEntry(_regNet2003); + + if ( path2002.isNull() || path2003.isNull() ) { + // Only have one MSVC, so use that one + current_version = (path2003.isNull() ? 70 : 71); + } else { + // Have both, so figure out the current + QString paths = getenv("PATH"); + QStringList pathlist = QStringList::split(";", paths.lower()); + + path2003 = path2003.lower(); + QStringList::iterator it; + for(it=pathlist.begin(); it!=pathlist.end(); ++it) { + if ((*it).contains(path2003)) { + current_version = 71; + } else if ((*it).contains(path2002) + && current_version == 71) { + fprintf( stderr, "Both .NET 2002 & .NET 2003 directories for VC found in you PATH variable!\nFallback to .NET 2002 project generation" ); + current_version = 70; + break; + } + } + } + return (current_version==71); #endif +}; // Flatfile Tags ---------------------------------------------------- -const char* _snlHeader = "Microsoft Visual Studio Solution File, Format Version 7.00"; +const char* _slnHeader70 = "Microsoft Visual Studio Solution File, Format Version 7.00"; +const char* _slnHeader71 = "Microsoft Visual Studio Solution File, Format Version 8.00"; // The following UUID _may_ change for later servicepacks... // If so we need to search through the registry at @@ -67,20 +105,23 @@ const char* _snlHeader = "Microsoft Visual Studio Solution File, Format Version // Use the hardcoded value for now so projects generated on other // platforms are actually usable. -const char* _snlMSVCvcprojGUID = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; -const char* _snlProjectBeg = "\nProject(\""; -const char* _snlProjectMid = "\") = "; -const char* _snlProjectEnd = "\nEndProject"; -const char* _snlGlobalBeg = "\nGlobal"; -const char* _snlGlobalEnd = "\nEndGlobal"; -const char* _snlSolutionConf = "\n\tGlobalSection(SolutionConfiguration) = preSolution" - "\n\t\tConfigName.0 = Release" +const char* _slnMSVCvcprojGUID = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; +const char* _slnProjectBeg = "\nProject(\""; +const char* _slnProjectMid = "\") = "; +const char* _slnProjectEnd = "\nEndProject"; +const char* _slnGlobalBeg = "\nGlobal"; +const char* _slnGlobalEnd = "\nEndGlobal"; +const char* _slnSolutionConf = "\n\tGlobalSection(SolutionConfiguration) = preSolution" + "\n\t\tConfigName.0 = Debug" + "\n\t\tConfigName.1 = Release" "\n\tEndGlobalSection"; -const char* _snlProjDepBeg = "\n\tGlobalSection(ProjectDependencies) = postSolution"; -const char* _snlProjDepEnd = "\n\tEndGlobalSection"; -const char* _snlProjConfBeg = "\n\tGlobalSection(ProjectConfiguration) = postSolution"; -const char* _snlProjConfTag1 = ".Release.ActiveCfg = Release|Win32"; -const char* _snlProjConfTag2 = ".Release.Build.0 = Release|Win32"; -const char* _snlProjConfEnd = "\n\tEndGlobalSection"; -const char* _snlExtSections = "\n\tGlobalSection(ExtensibilityGlobals) = postSolution" +const char* _slnProjDepBeg = "\n\tGlobalSection(ProjectDependencies) = postSolution"; +const char* _slnProjDepEnd = "\n\tEndGlobalSection"; +const char* _slnProjConfBeg = "\n\tGlobalSection(ProjectConfiguration) = postSolution"; +const char* _slnProjRelConfTag1 = ".Release.ActiveCfg = Release|Win32"; +const char* _slnProjRelConfTag2 = ".Release.Build.0 = Release|Win32"; +const char* _slnProjDbgConfTag1 = ".Debug.ActiveCfg = Debug|Win32"; +const char* _slnProjDbgConfTag2 = ".Debug.Build.0 = Debug|Win32"; +const char* _slnProjConfEnd = "\n\tEndGlobalSection"; +const char* _slnExtSections = "\n\tGlobalSection(ExtensibilityGlobals) = postSolution" "\n\tEndGlobalSection" "\n\tGlobalSection(ExtensibilityAddIns) = postSolution" @@ -127,7 +168,37 @@ struct VcsolutionDepend { QString vcprojFile, orig_target, target; ::target targetType; + bool debugBuild; QStringList dependencies; }; +QUuid VcprojGenerator::getProjectUUID(const QString &filename) +{ + bool validUUID = true; + + // Read GUID from variable-space + QUuid uuid = project->first("GUID"); + + // If none, create one based on the MD5 of absolute project path + if (uuid.isNull() || !filename.isNull()) { + QString abspath = filename.isNull()?project->first("QMAKE_MAKEFILE"):filename; + qtMD5(abspath.utf8(), (unsigned char*)(&uuid)); + validUUID = !uuid.isNull(); + uuid.data4[0] = (uuid.data4[0] & 0x3F) | 0x80; // UV_DCE variant + uuid.data3 = (uuid.data3 & 0x0FFF) | (QUuid::Name<<12); + } + + // If still not valid, generate new one, and suggest adding to .pro + if (uuid.isNull() || !validUUID) { + uuid = QUuid::createUuid(); + fprintf(stderr, + "qmake couldn't create a GUID based on filepath, and we couldn't\nfind a valid GUID in the .pro file (Consider adding\n'GUID = %s' to the .pro file)\n", + uuid.toString().upper().latin1()); + } + + // Store GUID in variable-space + project->values("GUID") = uuid.toString().upper(); + return uuid; +} + QUuid VcprojGenerator::increaseUUID( const QUuid &id ) { @@ -164,22 +235,15 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) } - t << _snlHeader; - QUuid solutionGUID; -#if defined(Q_WS_WIN32) - GUID guid; - HRESULT h = CoCreateGuid( &guid ); - if ( h == S_OK ) - solutionGUID = QUuid( guid ); -#else - // Qt doesn't support GUID on other platforms yet, - // so we use the all-zero uuid, and increase that. -#endif - + t << (use_net2003_version() ? _slnHeader71 : _slnHeader70); QDict<VcsolutionDepend> solution_depends; + QPtrList<VcsolutionDepend> solution_cleanup; solution_cleanup.setAutoDelete(TRUE); + + QStringList subdirs = project->variables()["SUBDIRS"]; QString oldpwd = QDir::currentDirPath(); + for(QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it) { QFileInfo fi(Option::fixPathToLocalOS((*it), TRUE)); @@ -200,6 +264,5 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) if(tmp_proj.read(fn, oldpwd)) { if(tmp_proj.first("TEMPLATE") == "vcsubdirs") { - QStringList tmp_subdirs = fileFixify(tmp_proj.variables()["SUBDIRS"]); - subdirs += tmp_subdirs; + subdirs += fileFixify(tmp_proj.variables()["SUBDIRS"]); } else if(tmp_proj.first("TEMPLATE") == "vcapp" || tmp_proj.first("TEMPLATE") == "vclib") { // Initialize a 'fake' project to get the correct variables @@ -224,5 +287,5 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) // doesn't allow it to be created. Skip to next... if(!QFile::exists(QDir::currentDirPath() + Option::dir_sep + vcproj)) { - qDebug( "Ignored (not found) '%s'", QString(QDir::currentDirPath() + Option::dir_sep + vcproj).latin1() ); + warn_msg(WarnLogic, "Ignored (not found) '%s'", QString(QDir::currentDirPath() + Option::dir_sep + vcproj).latin1() ); goto nextfile; // # Dirty! } @@ -231,41 +294,58 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) newDep->vcprojFile = fileFixify(vcproj); newDep->orig_target = tmp_proj.first("QMAKE_ORIG_TARGET"); - newDep->target = tmp_proj.first("TARGET").section(Option::dir_sep, -1); + newDep->target = tmp_proj.first("MSVCPROJ_TARGET").section(Option::dir_sep, -1); newDep->targetType = tmp_vcproj.projectTarget; - { - static QUuid uuid = solutionGUID; - uuid = increaseUUID( uuid ); - newDep->uuid = uuid.toString().upper(); - } + newDep->debugBuild = tmp_proj.isActiveConfig("debug"); + newDep->uuid = getProjectUUID(Option::fixPathToLocalOS(QDir::currentDirPath() + QDir::separator() + vcproj)).toString().upper(); + + // We want to store it as the .lib name. if(newDep->target.endsWith(".dll")) newDep->target = newDep->target.left(newDep->target.length()-3) + "lib"; + + // All projects using Forms are dependent on uic.exe if(!tmp_proj.isEmpty("FORMS")) newDep->dependencies << "uic.exe"; - { - QStringList where("QMAKE_LIBS"); - if(!tmp_proj.isEmpty("QMAKE_INTERNAL_PRL_LIBS")) - where = tmp_proj.variables()["QMAKE_INTERNAL_PRL_LIBS"]; - for(QStringList::iterator wit = where.begin(); - wit != where.end(); ++wit) { - QStringList &l = tmp_proj.variables()[(*wit)]; - for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { - QString opt = (*it); - if(!opt.startsWith("/")) //Not a switch - newDep->dependencies << opt.section(Option::dir_sep, -1); + + // Add all unknown libs to the deps + QStringList where("QMAKE_LIBS"); + if(!tmp_proj.isEmpty("QMAKE_INTERNAL_PRL_LIBS")) + where = tmp_proj.variables()["QMAKE_INTERNAL_PRL_LIBS"]; + for(QStringList::iterator wit = where.begin(); + wit != where.end(); ++wit) { + QStringList &l = tmp_proj.variables()[(*wit)]; + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QString opt = (*it); + if(!opt.startsWith("/") && // Not a switch + opt != newDep->target && // Not self + opt != "opengl32.lib" && // We don't care about these libs + opt != "glu32.lib" && // to make depgen alittle faster + opt != "kernel32.lib" && + opt != "user32.lib" && + opt != "gdi32.lib" && + opt != "comdlg32.lib" && + opt != "advapi32.lib" && + opt != "shell32.lib" && + opt != "ole32.lib" && + opt != "oleaut32.lib" && + opt != "uuid.lib" && + opt != "imm32.lib" && + opt != "winmm.lib" && + opt != "wsock32.lib" && + opt != "winspool.lib" && + opt != "delayimp.lib" ) + { + newDep->dependencies << opt.section(Option::dir_sep, -1); } } } +#ifdef DEBUG_SOLUTION_GEN + qDebug( "Deps for %20s: [%s]", newDep->target.latin1(), newDep->dependencies.join(" :: " ).latin1() ); +#endif solution_cleanup.append(newDep); solution_depends.insert(newDep->target, newDep); - { - QRegExp libVersion("[0-9]{3,3}\\.lib$"); - if(libVersion.search(newDep->target) != -1) - solution_depends.insert(newDep->target.left(newDep->target.length() - - libVersion.matchedLength()) + ".lib", newDep); - } - t << _snlProjectBeg << _snlMSVCvcprojGUID << _snlProjectMid + t << _slnProjectBeg << _slnMSVCvcprojGUID << _slnProjectMid << "\"" << newDep->orig_target << "\", \"" << newDep->vcprojFile << "\", \"" << newDep->uuid << "\""; - t << _snlProjectEnd; + t << _slnProjectEnd; } } @@ -275,28 +355,33 @@ nextfile: } } - t << _snlGlobalBeg; - t << _snlSolutionConf; - t << _snlProjDepBeg; + t << _slnGlobalBeg; + t << _slnSolutionConf; + t << _slnProjDepBeg; + + // Figure out dependencies for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) { + if(solution_cleanup.current()->targetType == StaticLib) + continue; // Shortcut, Static libs are not dep. int cnt = 0; for(QStringList::iterator dit = solution_cleanup.current()->dependencies.begin(); dit != solution_cleanup.current()->dependencies.end(); - ++dit) { - VcsolutionDepend *vc; - if((vc=solution_depends[*dit])) { - if(solution_cleanup.current()->targetType != StaticLib || vc->targetType == Application) - t << "\n\t\t" << solution_cleanup.current()->uuid << "." << cnt++ << " = " << vc->uuid; - } + ++dit) + { + VcsolutionDepend *vc = solution_depends[*dit]; + if(vc) + t << "\n\t\t" << solution_cleanup.current()->uuid << "." << cnt++ << " = " << vc->uuid; } } - t << _snlProjDepEnd; - t << _snlProjConfBeg; + t << _slnProjDepEnd; + t << _slnProjConfBeg; for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) { - t << "\n\t\t" << solution_cleanup.current()->uuid << _snlProjConfTag1; - t << "\n\t\t" << solution_cleanup.current()->uuid << _snlProjConfTag2; + t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjDbgConfTag1; + t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjDbgConfTag2; + t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjRelConfTag1; + t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjRelConfTag2; } - t << _snlProjConfEnd; - t << _snlExtSections; - t << _snlGlobalEnd; + t << _slnProjConfEnd; + t << _slnExtSections; + t << _slnGlobalEnd; } @@ -370,4 +455,22 @@ void VcprojGenerator::init() projectTarget = SharedLib; } + + // Setup PCH variables + precompH = project->first("PRECOMPILED_HEADER"); + usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header"); + if (usePCH) { + precompHFilename = QFileInfo(precompH).fileName(); + // Created files + QString origTarget = project->first("QMAKE_ORIG_TARGET"); + precompObj = origTarget + Option::obj_ext; + precompPch = origTarget + ".pch"; + // Add PRECOMPILED_HEADER to HEADERS + if (!project->variables()["HEADERS"].contains(precompH)) + project->variables()["HEADERS"] += precompH; + // Return to variable pool + project->variables()["PRECOMPILED_OBJECT"] = precompObj; + project->variables()["PRECOMPILED_PCH"] = precompPch; + } + initProject(); // Fills the whole project with proper data } @@ -390,6 +493,7 @@ void VcprojGenerator::initProject() // Own elements ----------------------------- vcProject.Name = project->first("QMAKE_ORIG_TARGET"); - vcProject.Version = "7.00"; - vcProject.PlatformName = ( vcProject.Configuration.idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32" ); + vcProject.Version = use_net2003_version() ? "7.10" : "7.00"; + vcProject.ProjectGUID = getProjectUUID().toString().upper(); + vcProject.PlatformName = ( vcProject.Configuration[0].idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32" ); // These are not used by Qt, but may be used by customers vcProject.SccProjectName = project->first("SCCPROJECTNAME"); @@ -413,33 +517,35 @@ void VcprojGenerator::initConfiguration() switch ( projectTarget ) { case SharedLib: - vcProject.Configuration.ConfigurationType = typeDynamicLibrary; + vcProject.Configuration[0].ConfigurationType = typeDynamicLibrary; break; case StaticLib: - vcProject.Configuration.ConfigurationType = typeStaticLibrary; + vcProject.Configuration[0].ConfigurationType = typeStaticLibrary; break; case Application: default: - vcProject.Configuration.ConfigurationType = typeApplication; + vcProject.Configuration[0].ConfigurationType = typeApplication; break; } - vcProject.Configuration.Name = ( project->isActiveConfig( "debug" ) ? "Debug|" : "Release|" ); - vcProject.Configuration.Name += ( vcProject.Configuration.idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32" ); - vcProject.Configuration.ATLMinimizesCRunTimeLibraryUsage = ( project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True ); - vcProject.Configuration.BuildBrowserInformation = triState( temp.isEmpty() ? (short)unset : temp.toShort() ); + + // Release version of the Configuration --------------- + VCConfiguration &RConf = vcProject.Configuration[0]; + RConf.Name = "Release"; + RConf.Name += ( RConf.idl.TargetEnvironment == midlTargetWin64 ? "|Win64" : "|Win32" ); + RConf.ATLMinimizesCRunTimeLibraryUsage = ( project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True ); + RConf.BuildBrowserInformation = triState( temp.isEmpty() ? (short)unset : temp.toShort() ); temp = project->first("CharacterSet"); - vcProject.Configuration.CharacterSet = charSet( temp.isEmpty() ? (short)charSetNotSet : temp.toShort() ); - vcProject.Configuration.DeleteExtensionsOnClean = project->first("DeleteExtensionsOnClean"); - vcProject.Configuration.ImportLibrary = vcProject.Configuration.linker.ImportLibrary; - vcProject.Configuration.IntermediateDirectory = project->first("OBJECTS_DIR"); -// temp = (projectTarget == StaticLib) ? project->first("DESTDIR"):project->first("DLLDESTDIR"); - vcProject.Configuration.OutputDirectory = "."; //( temp.isEmpty() ? QString(".") : temp ); - vcProject.Configuration.PrimaryOutput = project->first("PrimaryOutput"); - vcProject.Configuration.WholeProgramOptimization = vcProject.Configuration.compiler.WholeProgramOptimization; + RConf.CharacterSet = charSet( temp.isEmpty() ? (short)charSetNotSet : temp.toShort() ); + RConf.DeleteExtensionsOnClean = project->first("DeleteExtensionsOnClean"); + RConf.ImportLibrary = RConf.linker.ImportLibrary; + RConf.IntermediateDirectory = project->first("OBJECTS_DIR"); + RConf.OutputDirectory = "."; + RConf.PrimaryOutput = project->first("PrimaryOutput"); + RConf.WholeProgramOptimization = RConf.compiler.WholeProgramOptimization; temp = project->first("UseOfATL"); if ( !temp.isEmpty() ) - vcProject.Configuration.UseOfATL = useOfATL( temp.toShort() ); + RConf.UseOfATL = useOfATL( temp.toShort() ); temp = project->first("UseOfMfc"); if ( !temp.isEmpty() ) - vcProject.Configuration.UseOfMfc = useOfMfc( temp.toShort() ); + RConf.UseOfMfc = useOfMfc( temp.toShort() ); // Configuration does not need parameters from @@ -449,4 +555,37 @@ void VcprojGenerator::initConfiguration() initPostBuildEventTools(); initPreLinkEventTools(); + + // Debug version of the Configuration ----------------- + VCConfiguration DConf = vcProject.Configuration[0]; // Create copy configuration for debug + DConf.Name = "Debug"; + DConf.Name += ( DConf.idl.TargetEnvironment == midlTargetWin64 ? "|Win64" : "|Win32" ); + + // Set definite values in both configurations + DConf.compiler.PreprocessorDefinitions.remove("NDEBUG"); + RConf.compiler.PreprocessorDefinitions += "NDEBUG"; + RConf.linker.GenerateDebugInformation = _False; + DConf.linker.GenerateDebugInformation = _True; + + // Modify configurations, based on Qt build + if ( project->isActiveConfig("debug") ) { + RConf.IntermediateDirectory = + RConf.compiler.AssemblerListingLocation = + RConf.compiler.ObjectFile = "Release\\"; + RConf.librarian.OutputFile = + RConf.linker.OutputFile = RConf.IntermediateDirectory + "\\" + project->first("MSVCPROJ_TARGET"); + RConf.linker.parseOptions(project->variables()["QMAKE_LFLAGS_RELEASE"]); + RConf.compiler.parseOptions(project->variables()["QMAKE_CFLAGS_RELEASE"]); + } else { + DConf.IntermediateDirectory = + DConf.compiler.AssemblerListingLocation = + DConf.compiler.ObjectFile = "Debug\\"; + DConf.librarian.OutputFile = + DConf.linker.OutputFile = DConf.IntermediateDirectory + "\\" + project->first("MSVCPROJ_TARGET"); + DConf.linker.DelayLoadDLLs.clear(); + DConf.compiler.parseOptions(project->variables()["QMAKE_CFLAGS_DEBUG"]); + } + + // Add Debug configuration to project + vcProject.Configuration += DConf; } @@ -457,34 +596,47 @@ void VcprojGenerator::initCompilerTool() placement = ".\\"; - vcProject.Configuration.compiler.AssemblerListingLocation = placement ; - vcProject.Configuration.compiler.ProgramDataBaseFileName = placement ; - vcProject.Configuration.compiler.ObjectFile = placement ; - vcProject.Configuration.compiler.PrecompiledHeaderFile = placement + project->first("QMAKE_ORIG_TARGET") + ".pch"; + VCConfiguration &RConf = vcProject.Configuration[0]; + RConf.compiler.AssemblerListingLocation = placement ; + RConf.compiler.ProgramDataBaseFileName = ".\\" ; + RConf.compiler.ObjectFile = placement ; + // PCH + if ( usePCH ) { + RConf.compiler.UsePrecompiledHeader = pchUseUsingSpecific; + RConf.compiler.PrecompiledHeaderFile = "$(IntDir)\\" + precompPch; + RConf.compiler.PrecompiledHeaderThrough = precompHFilename; + RConf.compiler.ForcedIncludeFiles = precompHFilename; + // Minimal build option triggers an Internal Compiler Error + // when used in conjunction with /FI and /Yu, so remove it + project->variables()["QMAKE_CFLAGS_DEBUG"].remove("-Gm"); + project->variables()["QMAKE_CFLAGS_DEBUG"].remove("/Gm"); + project->variables()["QMAKE_CXXFLAGS_DEBUG"].remove("-Gm"); + project->variables()["QMAKE_CXXFLAGS_DEBUG"].remove("/Gm"); + } if ( project->isActiveConfig("debug") ){ // Debug version - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_DEBUG"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_DEBUG"] ); if ( project->isActiveConfig("thread") ) { if ( (projectTarget == Application) || (projectTarget == StaticLib) ) - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DBG"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DBG"] ); else - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"] ); } else { - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_ST_DBG"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DBG"] ); } } else { // Release version - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_RELEASE"] ); - vcProject.Configuration.compiler.PreprocessorDefinitions += "QT_NO_DEBUG"; - vcProject.Configuration.compiler.PreprocessorDefinitions += "NDEBUG"; + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_RELEASE"] ); + RConf.compiler.PreprocessorDefinitions += "QT_NO_DEBUG"; + RConf.compiler.PreprocessorDefinitions += "NDEBUG"; if ( project->isActiveConfig("thread") ) { if ( (projectTarget == Application) || (projectTarget == StaticLib) ) - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] ); else - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLL"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLL"] ); } else { - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_ST"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] ); } } @@ -492,44 +644,52 @@ void VcprojGenerator::initCompilerTool() // Common for both release and debug if ( project->isActiveConfig("warn_off") ) - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_OFF"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_OFF"] ); else if ( project->isActiveConfig("warn_on") ) - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_ON"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_ON"] ); if ( project->isActiveConfig("windows") ) - vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["MSVCPROJ_WINCONDEF"]; + RConf.compiler.PreprocessorDefinitions += project->variables()["MSVCPROJ_WINCONDEF"]; // Can this be set for ALL configs? // If so, use qmake.conf! if ( projectTarget == SharedLib ) - vcProject.Configuration.compiler.PreprocessorDefinitions += "_WINDOWS"; - - vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["DEFINES"]; - vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["PRL_EXPORT_DEFINES"]; - vcProject.Configuration.compiler.parseOptions( project->variables()["MSVCPROJ_INCPATH"] ); + RConf.compiler.PreprocessorDefinitions += "_WINDOWS"; + + RConf.compiler.PreprocessorDefinitions += project->variables()["DEFINES"]; + RConf.compiler.PreprocessorDefinitions += project->variables()["PRL_EXPORT_DEFINES"]; + QStringList::iterator it; + for(it=RConf.compiler.PreprocessorDefinitions.begin(); + it!=RConf.compiler.PreprocessorDefinitions.end(); + ++it) + (*it).replace('\"', """); + + RConf.compiler.parseOptions( project->variables()["MSVCPROJ_INCPATH"] ); } void VcprojGenerator::initLibrarianTool() { - vcProject.Configuration.librarian.OutputFile = project->first( "DESTDIR" ); - if( vcProject.Configuration.librarian.OutputFile.isEmpty() ) - vcProject.Configuration.librarian.OutputFile = ".\\"; + VCConfiguration &RConf = vcProject.Configuration[0]; + RConf.librarian.OutputFile = project->first( "DESTDIR" ); + if( RConf.librarian.OutputFile.isEmpty() ) + RConf.librarian.OutputFile = ".\\"; - if( !vcProject.Configuration.librarian.OutputFile.endsWith("\\") ) - vcProject.Configuration.librarian.OutputFile += '\\'; + if( !RConf.librarian.OutputFile.endsWith("\\") ) + RConf.librarian.OutputFile += '\\'; - vcProject.Configuration.librarian.OutputFile += project->first("MSVCPROJ_TARGET"); + RConf.librarian.OutputFile += project->first("MSVCPROJ_TARGET"); } void VcprojGenerator::initLinkerTool() { - vcProject.Configuration.linker.parseOptions( project->variables()["MSVCPROJ_LFLAGS"] ); - vcProject.Configuration.linker.AdditionalDependencies += project->variables()["MSVCPROJ_LIBS"]; + VCConfiguration &RConf = vcProject.Configuration[0]; + RConf.linker.parseOptions( project->variables()["MSVCPROJ_LFLAGS"] ); + RConf.linker.AdditionalDependencies += project->variables()["MSVCPROJ_LIBS"]; switch ( projectTarget ) { case Application: - vcProject.Configuration.linker.OutputFile = project->first( "DESTDIR" ); + RConf.linker.OutputFile = project->first( "DESTDIR" ); break; case SharedLib: - vcProject.Configuration.linker.parseOptions( project->variables()["MSVCPROJ_LIBOPTIONS"] ); - vcProject.Configuration.linker.OutputFile = project->first( "DLLDESTDIR" ); + RConf.linker.parseOptions( project->variables()["MSVCPROJ_LIBOPTIONS"] ); + RConf.linker.OutputFile = project->first( "DESTDIR" ); break; case StaticLib: //unhandled - added to remove warnings.. @@ -537,27 +697,26 @@ void VcprojGenerator::initLinkerTool() } - if( vcProject.Configuration.linker.OutputFile.isEmpty() ) - vcProject.Configuration.linker.OutputFile = ".\\"; + if( RConf.linker.OutputFile.isEmpty() ) + RConf.linker.OutputFile = ".\\"; - if( !vcProject.Configuration.linker.OutputFile.endsWith("\\") ) - vcProject.Configuration.linker.OutputFile += '\\'; + if( !RConf.linker.OutputFile.endsWith("\\") ) + RConf.linker.OutputFile += '\\'; - vcProject.Configuration.linker.OutputFile += project->first("MSVCPROJ_TARGET"); - vcProject.Configuration.linker.ProgramDatabaseFile = project->first("OBJECTS_DIR") + project->first("QMAKE_ORIG_TARGET") + ".pdb"; + RConf.linker.OutputFile += project->first("MSVCPROJ_TARGET"); if ( project->isActiveConfig("debug") ){ - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_DEBUG"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_DEBUG"] ); } else { - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_RELEASE"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_RELEASE"] ); } if ( project->isActiveConfig("dll") ){ - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_QT_DLL"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_QT_DLL"] ); } if ( project->isActiveConfig("console") ){ - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_CONSOLE"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_CONSOLE"] ); } else { - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_WINDOWS"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_WINDOWS"] ); } @@ -574,30 +733,20 @@ void VcprojGenerator::initCustomBuildTool() void VcprojGenerator::initPreBuildEventTools() { - QString collectionName = project->first("QMAKE_IMAGE_COLLECTION"); - if( !collectionName.isEmpty() ) { - QStringList& list = project->variables()["IMAGES"]; - vcProject.Configuration.preBuild.Description = "Generate imagecollection"; - //vcProject.Configuration.preBuild.AdditionalDependencies += list; - - QFile imgs( ".imgcol" ); - imgs.open( IO_WriteOnly ); - QTextStream s( &imgs ); - QStringList::ConstIterator it = list.begin(); - while( it!=list.end() ) { - s << *it << " "; - it++; - } - - vcProject.Configuration.preBuild.CommandLine = project->first("QMAKE_UIC") + " -embed " + project->first("QMAKE_ORIG_TARGET") + " -f .imgcol -o " + collectionName; - //vcProject.Configuration.preBuild.Outputs = collectionName; - - } } void VcprojGenerator::initPostBuildEventTools() { + VCConfiguration &RConf = vcProject.Configuration[0]; if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) { - vcProject.Configuration.postBuild.Description = var("QMAKE_POST_LINK"); - vcProject.Configuration.postBuild.CommandLine = var("QMAKE_POST_LINK"); + RConf.postBuild.Description = var("QMAKE_POST_LINK"); + RConf.postBuild.CommandLine = var("QMAKE_POST_LINK"); + RConf.postBuild.Description.replace(" && ", " && "); + RConf.postBuild.CommandLine.replace(" && ", " && "); + } + if ( !project->variables()["MSVCPROJ_COPY_DLL"].isEmpty() ) { + if ( !RConf.postBuild.CommandLine.isEmpty() ) + RConf.postBuild.CommandLine += " && "; + RConf.postBuild.Description += var("MSVCPROJ_COPY_DLL_DESC"); + RConf.postBuild.CommandLine += var("MSVCPROJ_COPY_DLL"); } if( project->isActiveConfig( "activeqt" ) ) { @@ -607,32 +756,28 @@ void VcprojGenerator::initPostBuildEventTools() QString idc = project->first( "QMAKE_IDC" ); - vcProject.Configuration.postBuild.Description = "Finalizing ActiveQt server..."; - if ( !vcProject.Configuration.postBuild.CommandLine.isEmpty() ) - vcProject.Configuration.postBuild.CommandLine += " && "; + RConf.postBuild.Description = "Finalizing ActiveQt server..."; + if ( !RConf.postBuild.CommandLine.isEmpty() ) + RConf.postBuild.CommandLine += " && "; if( project->isActiveConfig( "dll" ) ) { // In process - vcProject.Configuration.postBuild.CommandLine += + RConf.postBuild.CommandLine += // call idc to generate .idl file from .dll - idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " -idl " + objdir + name + ".idl -version 1.0 && " + + idc + " "$(TargetPath)" -idl " + objdir + name + ".idl -version 1.0 && " + // call midl to create implementations of the .idl file - project->first( "QMAKE_IDL" ) + " " + objdir + name + ".idl /nologo /o " + objdir + name + ".midl /tlb " + objdir + name + ".tlb /iid " + objdir + - "dump.midl /dlldata " + objdir + "dump.midl /cstub " + objdir + "dump.midl /header " + objdir + "dump.midl /proxy " + objdir + "dump.midl /sstub " + - objdir + "dump.midl && " + + project->first( "QMAKE_IDL" ) + " /nologo " + objdir + name + ".idl /tlb " + objdir + name + ".tlb && " + // call idc to replace tlb... - idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /tlb " + objdir + name + ".tlb && " + + idc + " "$(TargetPath)" /tlb " + objdir + name + ".tlb && " + // register server - idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /regserver"; + idc + " "$(TargetPath)" /regserver"; } else { // out of process - vcProject.Configuration.postBuild.CommandLine = + RConf.postBuild.CommandLine = // call application to dump idl - vcProject.Configuration.OutputDirectory + "\\" + nameext + " -dumpidl " + objdir + name + ".idl -version 1.0 && " + + ""$(TargetPath)" -dumpidl " + objdir + name + ".idl -version 1.0 && " + // call midl to create implementations of the .idl file - project->first( "QMAKE_IDL" ) + " " + objdir + name + ".idl /nologo /o " + objdir + name + ".midl /tlb " + objdir + name + ".tlb /iid " + objdir + - "dump.midl /dlldata " + objdir + "dump.midl /cstub " + objdir + "dump.midl /header " + objdir + "dump.midl /proxy " + objdir + "dump.midl /sstub " + - objdir + "dump.midl && " + + project->first( "QMAKE_IDL" ) + " /nologo " + objdir + name + ".idl /tlb " + objdir + name + ".tlb && " + // call idc to replace tlb... - idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /tlb " + objdir + name + ".tlb && " + + idc + " "$(TargetPath)" /tlb " + objdir + name + ".tlb && " + // call app to register - vcProject.Configuration.OutputDirectory + "\\" + nameext + " -regserver"; + ""$(TargetPath)" -regserver"; } } @@ -643,10 +788,86 @@ void VcprojGenerator::initPreLinkEventTools() } + +// ------------------------------------------------------------------ +// Helper functions to do proper sorting of the +// qstringlists, for both flat and non-flat modes. +inline bool XLessThanY( QString &x, QString &y, bool flat_mode ) +{ + if ( flat_mode ) { + QString subX = x.mid( x.findRev('\\')+1 ); + QString subY = y.mid( y.findRev('\\')+1 ); + return QString::compare(subX, subY) < 0; + } + + int xPos = 0; + int yPos = 0; + int xSlashPos; + int ySlashPos; + for (;;) { + xSlashPos = x.find('\\', xPos); + ySlashPos = y.find('\\', yPos); + + if (xSlashPos == -1 && ySlashPos != -1) { + return false; + } else if (xSlashPos != -1 && ySlashPos == -1) { + return true; + } else if (xSlashPos == -1 /* && yySlashPos == -1 */) { + QString subX = x.mid(xPos); + QString subY = y.mid(yPos); + return QString::compare(subX, subY) < 0; + } else { + QString subX = x.mid(xPos, xSlashPos - xPos); + QString subY = y.mid(yPos, ySlashPos - yPos); + int cmp = QString::compare(subX, subY); + if (cmp != 0) + return cmp < 0; + } + xPos = xSlashPos + 1; + yPos = ySlashPos + 1; + } + return false; +} +void nonflatDir_BubbleSort( QStringList& list, bool flat_mode ) +{ + QStringList::Iterator b = list.begin(); + QStringList::Iterator e = list.end(); + QStringList::Iterator last = e; + --last; // goto last + if ( last == b ) // shortcut + return; + while( b != last ) {// sort them + bool swapped = FALSE; + QStringList::Iterator swap_pos = b; + QStringList::Iterator x = e; + QStringList::Iterator y = x; + --y; + QString swap_str; + do { + --x; + --y; + if ( XLessThanY(*x,*y, flat_mode) ) { + swapped = TRUE; + swap_str = (*x); // Swap ------- + (*x) = (*y); + (*y) = swap_str; // ------------ + swap_pos = y; + } + } while( y != b ); + if ( !swapped ) + return; + b = swap_pos; + ++b; + } +} +// ------------------------------------------------------------------ + void VcprojGenerator::initSourceFiles() { + vcProject.SourceFiles.flat_files = project->isActiveConfig("flat"); vcProject.SourceFiles.Name = "Source Files"; vcProject.SourceFiles.Filter = "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"; vcProject.SourceFiles.Files += project->variables()["SOURCES"]; - vcProject.SourceFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.SourceFiles.Files, + vcProject.SourceFiles.flat_files ); vcProject.SourceFiles.Project = this; vcProject.SourceFiles.Config = &(vcProject.Configuration); @@ -656,8 +877,14 @@ void VcprojGenerator::initSourceFiles() void VcprojGenerator::initHeaderFiles() { + vcProject.HeaderFiles.flat_files = project->isActiveConfig("flat"); vcProject.HeaderFiles.Name = "Header Files"; vcProject.HeaderFiles.Filter = "h;hpp;hxx;hm;inl"; vcProject.HeaderFiles.Files += project->variables()["HEADERS"]; - vcProject.HeaderFiles.Files.sort(); + if (usePCH) { // Generated PCH cpp file + if (!vcProject.HeaderFiles.Files.contains(precompH)) + vcProject.HeaderFiles.Files += precompH; + } + nonflatDir_BubbleSort( vcProject.HeaderFiles.Files, + vcProject.HeaderFiles.flat_files ); vcProject.HeaderFiles.Project = this; vcProject.HeaderFiles.Config = &(vcProject.Configuration); @@ -667,8 +894,10 @@ void VcprojGenerator::initHeaderFiles() void VcprojGenerator::initMOCFiles() { + vcProject.MOCFiles.flat_files = project->isActiveConfig("flat"); vcProject.MOCFiles.Name = "Generated MOC Files"; vcProject.MOCFiles.Filter = "cpp;c;cxx;moc"; vcProject.MOCFiles.Files += project->variables()["SRCMOC"]; - vcProject.MOCFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.MOCFiles.Files, + vcProject.MOCFiles.flat_files ); vcProject.MOCFiles.Project = this; vcProject.MOCFiles.Config = &(vcProject.Configuration); @@ -678,10 +907,12 @@ void VcprojGenerator::initMOCFiles() void VcprojGenerator::initUICFiles() { - vcProject.UICFiles.Name = "Generated UI Files"; + vcProject.UICFiles.flat_files = project->isActiveConfig("flat"); + vcProject.UICFiles.Name = "Generated Form Files"; vcProject.UICFiles.Filter = "cpp;c;cxx;h;hpp;hxx;"; vcProject.UICFiles.Project = this; vcProject.UICFiles.Files += project->variables()["UICDECLS"]; vcProject.UICFiles.Files += project->variables()["UICIMPLS"]; - vcProject.UICFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.UICFiles.Files, + vcProject.UICFiles.flat_files ); vcProject.UICFiles.Config = &(vcProject.Configuration); vcProject.UICFiles.CustomBuild = none; @@ -690,9 +921,11 @@ void VcprojGenerator::initUICFiles() void VcprojGenerator::initFormsFiles() { + vcProject.FormFiles.flat_files = project->isActiveConfig("flat"); vcProject.FormFiles.Name = "Forms"; vcProject.FormFiles.ParseFiles = _False; vcProject.FormFiles.Filter = "ui"; vcProject.FormFiles.Files += project->variables()["FORMS"]; - vcProject.FormFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.FormFiles.Files, + vcProject.FormFiles.flat_files ); vcProject.FormFiles.Project = this; vcProject.FormFiles.Config = &(vcProject.Configuration); @@ -702,9 +935,11 @@ void VcprojGenerator::initFormsFiles() void VcprojGenerator::initTranslationFiles() { + vcProject.TranslationFiles.flat_files = project->isActiveConfig("flat"); vcProject.TranslationFiles.Name = "Translations Files"; vcProject.TranslationFiles.ParseFiles = _False; vcProject.TranslationFiles.Filter = "ts"; vcProject.TranslationFiles.Files += project->variables()["TRANSLATIONS"]; - vcProject.TranslationFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.TranslationFiles.Files, + vcProject.TranslationFiles.flat_files ); vcProject.TranslationFiles.Project = this; vcProject.TranslationFiles.Config = &(vcProject.Configuration); @@ -714,4 +949,5 @@ void VcprojGenerator::initTranslationFiles() void VcprojGenerator::initLexYaccFiles() { + vcProject.LexYaccFiles.flat_files = project->isActiveConfig("flat"); vcProject.LexYaccFiles.Name = "Lex / Yacc Files"; vcProject.LexYaccFiles.ParseFiles = _False; @@ -719,6 +955,8 @@ void VcprojGenerator::initLexYaccFiles() vcProject.LexYaccFiles.Files += project->variables()["LEXSOURCES"]; vcProject.LexYaccFiles.Files += project->variables()["YACCSOURCES"]; - vcProject.LexYaccFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.LexYaccFiles.Files, + vcProject.LexYaccFiles.flat_files ); vcProject.LexYaccFiles.Project = this; + vcProject.LexYaccFiles.Config = &(vcProject.Configuration); vcProject.LexYaccFiles.CustomBuild = lexyacc; } @@ -726,4 +964,5 @@ void VcprojGenerator::initLexYaccFiles() void VcprojGenerator::initResourceFiles() { + vcProject.ResourceFiles.flat_files = project->isActiveConfig("flat"); vcProject.ResourceFiles.Name = "Resources"; vcProject.ResourceFiles.ParseFiles = _False; @@ -733,7 +972,9 @@ void VcprojGenerator::initResourceFiles() vcProject.ResourceFiles.Files += project->variables()["IMAGES"]; vcProject.ResourceFiles.Files += project->variables()["IDLSOURCES"]; - vcProject.ResourceFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.ResourceFiles.Files, + vcProject.ResourceFiles.flat_files ); vcProject.ResourceFiles.Project = this; - vcProject.ResourceFiles.CustomBuild = none; + vcProject.ResourceFiles.Config = &(vcProject.Configuration); + vcProject.ResourceFiles.CustomBuild = resource; } @@ -866,5 +1107,4 @@ void VcprojGenerator::initOld() if ( project->isActiveConfig( "dll" ) ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"]; - project->variables()["MSVCPROJ_LFLAGS"].append("/DEF:"+project->first("DEF_FILE")); } } @@ -940,4 +1180,13 @@ void VcprojGenerator::initOld() setMocAware(TRUE); + // /VERSION:x.yz ------------------------------------------------- + if ( !project->variables()["VERSION"].isEmpty() ) { + QString version = project->variables()["VERSION"][0]; + int firstDot = version.find( "." ); + QString major = version.left( firstDot ); + QString minor = version.right( version.length() - firstDot - 1 ); + minor.replace( ".", "" ); + project->variables()["QMAKE_LFLAGS"].append( "/VERSION:" + major + "." + minor ); + } project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; @@ -950,4 +1199,5 @@ void VcprojGenerator::initOld() it = libList.insert( it, s.mid( 2 ) + ".lib" ); } else if( s.startsWith( "-L" ) ) { + project->variables()["QMAKE_LIBDIR"] += (*it).mid(2); it = libList.remove( it ); } else { @@ -1051,29 +1301,26 @@ void VcprojGenerator::initOld() dest.replace( QRegExp("\\$\\(QTDIR\\)"), getenv("QTDIR") ); project->variables()["MSVCPROJ_TARGET"] = dest; - if ( project->isActiveConfig("dll") ) { - QString imp = project->first( "DESTDIR" ); - if( !imp.isNull() && !imp.endsWith( "\\" ) ) - imp += "\\"; - imp += dest; - imp.replace(QRegExp("\\.dll"), ".lib"); - project->variables()["MSVCPROJ_LIBOPTIONS"] += QString("/IMPLIB:") + imp; - } // DLL COPY ------------------------------------------------------ if ( project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty() ) { QStringList dlldirs = project->variables()["DLLDESTDIR"]; - QString copydll = "# Begin Special Build Tool\n" - "TargetPath=" + dest + "\n" - "SOURCE=$(InputPath)\n" - "PostBuild_Desc=Copy DLL to " + project->first("DLLDESTDIR") + "\n" - "PostBuild_Cmds="; - - for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { - copydll += "copy \"" + dest + "\" \"" + *dlldir + "\"\t"; + QString copydll(""); + QStringList::Iterator dlldir; + for ( dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { + if ( !copydll.isEmpty() ) + copydll += " && "; + copydll += "copy "$(TargetPath)" "" + *dlldir + """; } - copydll += "\n# End Special Build Tool"; - project->variables()["MSVCPROJ_COPY_DLL_REL"].append( copydll ); - project->variables()["MSVCPROJ_COPY_DLL_DBG"].append( copydll ); + QString deststr( "Copy " + dest + " to " ); + for ( dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ) { + deststr += *dlldir; + ++dlldir; + if ( dlldir != dlldirs.end() ) + deststr += ", "; + } + + project->variables()["MSVCPROJ_COPY_DLL"].append( copydll ); + project->variables()["MSVCPROJ_COPY_DLL_DESC"].append( deststr ); } @@ -1086,7 +1333,6 @@ void VcprojGenerator::initOld() version = "1.0"; - project->variables()["MSVCPROJ_IDLSOURCES"].append( "tmp\\" + targetfilename + ".idl" ); - project->variables()["MSVCPROJ_IDLSOURCES"].append( "tmp\\" + targetfilename + ".tlb" ); - project->variables()["MSVCPROJ_IDLSOURCES"].append( "tmp\\" + targetfilename + ".midl" ); + QString objdir = project->first( "OBJECTS_DIR" ); + project->variables()["MSVCPROJ_IDLSOURCES"].append( objdir + targetfilename + ".idl" ); if ( project->isActiveConfig( "dll" ) ) { QString regcmd = "# Begin Special Build Tool\n" @@ -1095,7 +1341,7 @@ void VcprojGenerator::initOld() "PostBuild_Desc=Finalizing ActiveQt server...\n" "PostBuild_Cmds=" + - idc + " %1 -idl tmp\\" + targetfilename + ".idl -version " + version + - "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" - "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb" + idc + " %1 -idl " + objdir + targetfilename + ".idl -version " + version + + "\t" + idl + " /nologo " + objdir + targetfilename + ".idl /tlb " + objdir + targetfilename + ".tlb" + + "\t" + idc + " %1 /tlb " + objdir + targetfilename + ".tlb" "\tregsvr32 /s %1\n" "# End Special Build Tool"; @@ -1112,7 +1358,7 @@ void VcprojGenerator::initOld() "PostBuild_Desc=Finalizing ActiveQt server...\n" "PostBuild_Cmds=" - "%1 -dumpidl tmp\\" + targetfilename + ".idl -version " + version + - "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" - "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb" + "%1 -dumpidl " + objdir + targetfilename + ".idl -version " + version + + "\t" + idl + " /nologo " + objdir + targetfilename + ".idl /tlb " + objdir + targetfilename + ".tlb" + "\t" + idc + " %1 /tlb " + objdir + targetfilename + ".tlb" "\t%1 -regserver\n" "# End Special Build Tool"; @@ -1124,7 +1370,9 @@ void VcprojGenerator::initOld() project->variables()["MSVCPROJ_REGSVR_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) ); } - } + if ( !project->variables()["DEF_FILE"].isEmpty() ) + project->variables()["MSVCPROJ_LFLAGS"].append("/DEF:"+project->first("DEF_FILE")); + // FORMS --------------------------------------------------------- QStringList &list = project->variables()["FORMS"]; diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index 69e0c02..d1ca666 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -1,12 +1,11 @@ + /**************************************************************************** -** $Id$ +** ** ** Definition of VcprojGenerator class. ** -** Created : 970521 -** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -35,4 +34,5 @@ ** **********************************************************************/ + #ifndef __MSVC_VCPROJ_H__ #define __MSVC_VCPROJ_H__ @@ -64,4 +64,7 @@ public: QString defaultMakefile() const; virtual bool doDepends() const { return FALSE; } //never necesary + QString precompH, precompHFilename, + precompObj, precompPch; + bool usePCH; protected: @@ -96,4 +99,5 @@ protected: private: + QUuid getProjectUUID(const QString &filename=QString::null); QUuid increaseUUID(const QUuid &id); friend class VCFilter; diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index bc3fed9..cd733c6 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of Win32MakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -39,4 +37,5 @@ #include "option.h" #include "project.h" +#include "meta.h" #include <qtextstream.h> #include <qstring.h> @@ -98,6 +97,5 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) QPtrListIterator<SubDir> it(subdirs); - if(!project->isEmpty("MAKEFILE")) - t << "MAKEFILE= " << var("MAKEFILE") << endl; + t << "MAKEFILE = " << (project->isEmpty("MAKEFILE") ? QString("Makefile") : var("MAKEFILE")) << endl; t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; t << "SUBTARGETS = "; @@ -105,5 +103,5 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) t << " \\\n\t\t" << it.current()->target; t << endl << endl; - t << "all: qmake_all $(SUBTARGETS)" << endl << endl; + t << "all: $(MAKEFILE) $(SUBTARGETS)" << endl << endl; for( it.toFirst(); it.current(); ++it) { @@ -115,6 +113,4 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) mkfile.prepend((*it)->directory + Option::dir_sep); t << mkfile << ":"; - if(project->variables()["QMAKE_NOFORCE"].isEmpty()) - t << " FORCE"; if(have_dir) t << "\n\t" << "cd " << (*it)->directory; @@ -146,4 +142,14 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) } + if (project->isActiveConfig("ordered")) { // generate dependencies + for( it.toFirst(); it.current(); ) { + QString tar = it.current()->target; + ++it; + if (it.current()) + t << it.current()->target << ": " << tar << endl; + } + t << endl; + } + if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].findIndex("qmake_all") == -1) project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all"); @@ -176,9 +182,16 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) t << endl << endl; - QString targs[] = { QString("clean"), QString("install"), QString("mocclean"), QString::null }; - for(int x = 0; targs[x] != QString::null; x++) { - t << targs[x] << ": qmake_all"; - if(targs[x] == "clean") - t << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ", ""); + QStringList targs; + targs << "clean" << "install_subdirs" << "mocables" << "uicables" << "uiclean" << "mocclean"; + targs += project->values("SUBDIR_TARGETS"); + for(QStringList::Iterator targ_it = targs.begin(); targ_it != targs.end(); ++targ_it) { + t << (*targ_it) << ": qmake_all"; + QString targ = (*targ_it); + if(targ == "install_subdirs") + targ = "install"; + else if(targ == "uninstall_subdirs") + targ = "uninstall"; + if(targ == "clean") + t << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ", ""); if (!subdirs.isEmpty()) { for( it.toFirst(); it.current(); ++it) { @@ -188,5 +201,5 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) t << "\n\t" << "cd " << (*it)->directory; QString in_file = " -f " + (*it)->makefile; - t << "\n\t" << "$(MAKE) " << in_file << " " << targs[x]; + t << "\n\t" << "$(MAKE) " << in_file << " " << targ; if(have_dir) { t << "\n\t" << "@cd .."; @@ -203,4 +216,30 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) } + //installations + project->variables()["INSTALLDEPS"] += "install_subdirs"; + project->variables()["UNINSTALLDEPS"] += "uninstall_subdirs"; + writeInstalls(t, "INSTALLS"); + + // user defined targets + QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; + for(QStringList::Iterator sit = qut.begin(); sit != qut.end(); ++sit) { + QString targ = var((*sit) + ".target"), + cmd = var((*sit) + ".commands"), deps; + if(targ.isEmpty()) + targ = (*sit); + QStringList &deplist = project->variables()[(*sit) + ".depends"]; + for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) { + QString dep = var((*dep_it) + ".target"); + if(dep.isEmpty()) + dep = (*dep_it); + deps += " " + dep; + } + if(!project->variables()["QMAKE_NOFORCE"].isEmpty() && + project->variables()[(*sit) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; + t << "\n\n" << targ << ":" << deps << "\n\t" + << cmd; + } + if(project->variables()["QMAKE_NOFORCE"].isEmpty()) t << "FORCE:" << endl << endl; @@ -227,14 +266,48 @@ Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem regx.cap(2).isEmpty()) ? -1 : regx.cap(2).toInt()); } - if(dir.exists(dllStem + Option::prl_ext)) { - QMakeProject proj; - if(proj.read(bd + dllStem + Option::prl_ext, QDir::currentDirPath(), TRUE)) { - if(!proj.isEmpty("QMAKE_PRL_VERSION")) - biggest = QMAX(biggest, proj.first("QMAKE_PRL_VERSION").replace(".", "").toInt()); - } + QMakeMetaInfo libinfo; + if(libinfo.readLib(bd + dllStem)) { + if(!libinfo.isEmpty("QMAKE_PRL_VERSION")) + biggest = QMAX(biggest, libinfo.first("QMAKE_PRL_VERSION").replace(".", "").toInt()); } return biggest; } +QString +Win32MakefileGenerator::findDependency(const QString &dep) +{ + { + QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; + for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) { + QString targ = var((*it) + ".target"); + if(targ.isEmpty()) + targ = (*it); + if(targ.endsWith(dep)) + return targ; + } + } + { + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(QStringList::Iterator it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QString out = tmp_out; + QFileInfo fi(Option::fixPathToLocalOS((*input))); + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(out.endsWith(dep)) + return out; + } + } + } + } + return MakefileGenerator::findDependency(dep); +} bool @@ -279,5 +352,5 @@ Win32MakefileGenerator::findLibraries(const QString &where) extension += QString::number(ver); extension += ".lib"; - if(QFile::exists(mdd->local_dir + Option::dir_sep + lib + Option::prl_ext) || + if(QMakeMetaInfo::libExists(mdd->local_dir + Option::dir_sep + lib) || QFile::exists(mdd->local_dir + Option::dir_sep + lib + extension)) { out = mdd->real_dir + Option::dir_sep + lib + extension; @@ -304,24 +377,26 @@ Win32MakefileGenerator::findLibraries(const QString &where) lib_dirs = dirs; } - if(file.endsWith(".lib")) { - file = file.left(file.length() - 4); - if(!file.at(file.length()-1).isNumber()) { - for(MakefileDependDir *mdd = lib_dirs.first(); mdd; mdd = lib_dirs.next() ) { - QString lib_tmpl(file + "%1" + ".lib"); - int ver = findHighestVersion(mdd->local_dir, file); - if(ver != -1) { - if(ver) - lib_tmpl = lib_tmpl.arg(ver); - else - lib_tmpl = lib_tmpl.arg(""); - if(slsh != -1) { - QString dir = mdd->real_dir; - if(!dir.endsWith(Option::dir_sep)) - dir += Option::dir_sep; - lib_tmpl.prepend(dir); + if (!project->variables()["QMAKE_QT_DLL"].isEmpty()) { + if(file.endsWith(".lib")) { + file = file.left(file.length() - 4); + if(!file.at(file.length()-1).isNumber()) { + for(MakefileDependDir *mdd = lib_dirs.first(); mdd; mdd = lib_dirs.next() ) { + QString lib_tmpl(file + "%1" + ".lib"); + int ver = findHighestVersion(mdd->local_dir, file); + if(ver != -1) { + if(ver) + lib_tmpl = lib_tmpl.arg(ver); + else + lib_tmpl = lib_tmpl.arg(""); + if(slsh != -1) { + QString dir = mdd->real_dir; + if(!dir.endsWith(Option::dir_sep)) + dir += Option::dir_sep; + lib_tmpl.prepend(dir); + } + modified_opt = TRUE; + (*it) = lib_tmpl; + break; } - modified_opt = TRUE; - (*it) = lib_tmpl; - break; } } diff --git a/qmake/generators/win32/winmakefile.h b/qmake/generators/win32/winmakefile.h index 75ba0e0..dac4a99 100644 --- a/qmake/generators/win32/winmakefile.h +++ b/qmake/generators/win32/winmakefile.h @@ -1,12 +1,10 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of Win32MakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** ** This file may be distributed under the terms of the Q Public License @@ -35,4 +33,5 @@ ** **********************************************************************/ + #ifndef __WINMAKEFILE_H__ #define __WINMAKEFILE_H__ @@ -54,4 +53,5 @@ protected: int findHighestVersion(const QString &dir, const QString &stem); bool findLibraries(const QString &); + QString findDependency(const QString &); virtual bool findLibraries(); virtual void processPrlFiles(); |