Diffstat (limited to 'qmake/generators/unix/unixmake2.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | qmake/generators/unix/unixmake2.cpp | 596 |
1 files changed, 537 insertions, 59 deletions
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,11 +1,9 @@ /**************************************************************************** -** $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. ** @@ -39,2 +37,3 @@ #include "option.h" +#include "meta.h" #include <qregexp.h> @@ -44,2 +43,3 @@ +QString mkdir_p_asstring(const QString &dir); @@ -50,2 +50,19 @@ 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 @@ -53,5 +70,12 @@ 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 (" @@ -75,5 +99,27 @@ 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") && @@ -137,2 +183,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "GZIP = " << var("QMAKE_GZIP") << endl; + if(project->isActiveConfig("compile_libtool")) + t << "LIBTOOL = " << var("QMAKE_LIBTOOL") << endl; t << "COPY = " << var("QMAKE_COPY") << endl; @@ -140,2 +188,5 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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; @@ -222,2 +273,16 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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; @@ -225,2 +290,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "DESTDIR = " << var("DESTDIR") << endl; + if(project->isActiveConfig("compile_libtool")) + t << "TARGETL = " << var("TARGET_la") << endl; t << "TARGET = " << var("TARGET") << endl; @@ -240,5 +307,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } + writeExtraVariables(t); t << endl; - // blasted incldues + // blasted includes QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"]; @@ -251,3 +319,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "####### Implicit rules" << endl << endl; - t << ".SUFFIXES: .c"; + t << ".SUFFIXES: .c " << Option::obj_ext; QStringList::Iterator cppit; @@ -257,4 +325,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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; @@ -280,3 +348,2 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) - QString src[] = { "SOURCES", "UICIMPLS", "SRCMOC", QString::null }; @@ -300,6 +367,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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; } @@ -325,4 +392,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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; @@ -331,3 +398,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) dir = (*it).left(slsh + 1); - QString targ = dir + proj.first("QMAKE_PRL_TARGET"); + QString targ = dir + libinfo.first("QMAKE_PRL_TARGET"); deps += " " + targ; @@ -335,3 +402,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << "@echo \"Creating '" << targ << "'\"" << "\n\t" - << "(cd " << proj.first("QMAKE_PRL_BUILD_DIR") << ";" + << "(cd " << libinfo.first("QMAKE_PRL_BUILD_DIR") << ";" << "$(MAKE) )" << endl; @@ -394,3 +461,3 @@ 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"; @@ -400,3 +467,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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")) @@ -409,3 +476,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " - << var("POST_TARGETDEPS") << "\n\t"; + << target_deps << " " << var("POST_TARGETDEPS") << "\n\t"; if(!destdir.isEmpty()) @@ -414,3 +481,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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")) @@ -471,3 +538,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") << " " - << incr_deps << " $(SUBLIBS) " << var("POST_TARGETDEPS"); + << incr_deps << " $(SUBLIBS) " << target_deps << " " << var("POST_TARGETDEPS"); } else { @@ -476,3 +543,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") - << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) " << var("POST_TARGETDEPS"); + << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) $(OBJCOMP) " << target_deps + << " " << var("POST_TARGETDEPS"); } @@ -483,3 +551,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) - 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" @@ -528,3 +599,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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) @@ -546,3 +617,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") - << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("POST_TARGETDEPS") << "\n\t"; + << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(OBJCOMP) " << var("POST_TARGETDEPS") << "\n\t"; if(!project->isEmpty("DESTDIR")) { @@ -562,3 +633,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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"]; @@ -599,3 +671,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) - t << "mocables: $(SRCMOC)" << endl << endl; + t << "mocables: $(SRCMOC)" << endl + << "uicables: $(UICDECLS) $(UICIMPLS)" << endl << endl; @@ -605,3 +678,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) //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); @@ -610,3 +686,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "$(MOC): \n\t" - << "( cd $(QTDIR)/src/moc ; $(MAKE) )" << endl << endl; + << "( cd " << moc_dir << " && $(MAKE) )" << endl << endl; } @@ -614,2 +690,21 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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; + } + } @@ -632,8 +727,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &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; } @@ -650,2 +747,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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")) { @@ -668,4 +767,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) QString clean_targets; - if(mocAware()) { t << "mocclean:" << "\n"; + if(mocAware()) { if(!objMoc.isEmpty() || !srcMoc.isEmpty() || moc_incremental) { @@ -699,4 +798,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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() ); } @@ -719,3 +818,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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() ); } @@ -737,4 +836,14 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "clean:" << clean_targets << "\n\t"; - if(!project->isEmpty("OBJECTS")) + 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")) @@ -764,2 +873,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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 @@ -767,3 +878,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) 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) " @@ -772,10 +883,32 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) - 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 " @@ -784,3 +917,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &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; @@ -788,3 +921,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) - // blasted user defined targets + // user defined targets QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"]; @@ -802,2 +935,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } + if(project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; t << targ << ":" << deps << "\n\t" @@ -805,2 +940,50 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } + // 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; @@ -816,2 +999,8 @@ 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; @@ -834,2 +1023,4 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) } else { + if(!file.isEmpty()) + sd->profile = file.section(Option::dir_sep, -1) + ".pro"; sd->directory = file; @@ -859,2 +1050,6 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) 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 @@ -876,4 +1071,6 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) 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 @@ -898,3 +1095,4 @@ 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 { @@ -916,3 +1114,4 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) 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) { @@ -924,2 +1123,18 @@ 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"; @@ -933,2 +1148,27 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) } + + //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; @@ -969,2 +1209,5 @@ void UnixMakefileGenerator::init2() 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() ) @@ -973,5 +1216,8 @@ void UnixMakefileGenerator::init2() 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")) @@ -979,6 +1225,6 @@ void UnixMakefileGenerator::init2() project->first("VER_MAJ") + "." + - project->first("QMAKE_EXTENSION_SHLIB")); + 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")); @@ -1077,3 +1323,3 @@ void UnixMakefileGenerator::init2() project->variables()["QMAKE_LINK_SHLIB_CMD"].append( - "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)"); + "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) $(OBJCOMP)"); } @@ -1082,9 +1328,15 @@ void UnixMakefileGenerator::init2() 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") ) { + 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"]; @@ -1092,2 +1344,18 @@ void UnixMakefileGenerator::init2() project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SHLIB"]; + 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"]; @@ -1109,2 +1377,212 @@ 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}"; } |