Пример #1
0
bool
SubdirsMetaMakefileGenerator::write(const QString &oldpwd)
{
    bool ret = true;
    const QString &pwd = qmake_getpwd();
    const QString &output_dir = Option::output_dir;
    const QString &output_name = Option::output.fileName();
    for(int i = 0; ret && i < subs.count(); i++) {
        const Subdir *sub = subs.at(i);
        qmake_setpwd(subs.at(i)->input_dir);
        Option::output_dir = QFileInfo(subs.at(i)->output_dir).absoluteFilePath();
        if(Option::output_dir.at(Option::output_dir.length()-1) != QLatin1Char('/'))
            Option::output_dir += QLatin1Char('/');
        Option::output.setFileName(subs.at(i)->output_file);
        if(i != subs.count()-1) {
            for (int ind = 0; ind < sub->indent; ++ind)
                printf(" ");
            printf("Writing %s\n", QDir::cleanPath(Option::output_dir+"/"+
                                                   Option::output.fileName()).toLatin1().constData());
        }
        QString writepwd = Option::fixPathToLocalOS(qmake_getpwd());
        if(!writepwd.startsWith(Option::fixPathToLocalOS(oldpwd)))
            writepwd = oldpwd;
        if(!(ret = subs.at(i)->makefile->write(writepwd)))
            break;
        //restore because I'm paranoid
        qmake_setpwd(pwd);
        Option::output.setFileName(output_name);
        Option::output_dir = output_dir;
    }
    return ret;
}
void MingwMakefileGenerator::writeIncPart(QTextStream &t)
{
    t << "INCPATH       = ";

    if (!project->isActiveConfig("no_include_pwd")) {
        QString pwd = escapeFilePath(fileFixify(qmake_getpwd()));
        if (pwd.isEmpty())
            pwd = ".";
        t << "-I" << pwd << " ";
    }

    QString isystem = var("QMAKE_CFLAGS_ISYSTEM");
    const ProStringList &incs = project->values("INCLUDEPATH");
    for (ProStringList::ConstIterator incit = incs.begin(); incit != incs.end(); ++incit) {
        QString inc = (*incit).toQString();
        inc.replace(QRegExp("\\\\$"), "");
        inc.replace(QRegExp("\""), "");

        if (!isystem.isEmpty() && isSystemInclude(inc))
            t << isystem << ' ';
        else
            t << "-I";
        t << quote << inc << quote << " ";
    }
    t << "-I" << quote << specdir() << quote
      << endl;
}
Пример #3
0
bool
ProjectGenerator::addFile(QString file)
{
    file = fileFixify(file, qmake_getpwd());
    QString dir;
    int s = file.lastIndexOf(Option::dir_sep);
    if(s != -1)
        dir = file.left(s+1);
    if(file.mid(dir.length(), Option::h_moc_mod.length()) == Option::h_moc_mod)
        return false;

    QString where;
    for(int cppit = 0; cppit < Option::cpp_ext.size(); ++cppit) {
        if(file.endsWith(Option::cpp_ext[cppit])) {
            where = "SOURCES";
            break;
        }
    }
    if(where.isEmpty()) {
        for(int hit = 0; hit < Option::h_ext.size(); ++hit)
            if(file.endsWith(Option::h_ext.at(hit))) {
                where = "HEADERS";
                break;
            }
    }
    if(where.isEmpty()) {
        for(int cit = 0; cit < Option::c_ext.size(); ++cit) {
            if(file.endsWith(Option::c_ext[cit])) {
                where = "SOURCES";
                break;
            }
        }
    }
    if(where.isEmpty()) {
        if(file.endsWith(Option::ui_ext))
            where = "FORMS";
        else if(file.endsWith(Option::lex_ext))
            where = "LEXSOURCES";
        else if(file.endsWith(Option::yacc_ext))
            where = "YACCSOURCES";
        else if(file.endsWith(".ts"))
            where = "TRANSLATIONS";
        else if(file.endsWith(".qrc"))
            where = "RESOURCES";
    }

    QString newfile = fixPathToQmake(fileFixify(file));

    QStringList &endList = project->variables()[where];
    if(!endList.contains(newfile, Qt::CaseInsensitive)) {
        endList += newfile;
        return true;
    }
    return false;
}
Пример #4
0
bool
ProjectGenerator::openOutput(QFile &file, const QString &build) const
{
    QString outdir;
    if(!file.fileName().isEmpty()) {
        QFileInfo fi(fileInfo(file.fileName()));
        if(fi.isDir())
            outdir = fi.path() + QDir::separator();
    }
    if(!outdir.isEmpty() || file.fileName().isEmpty()) {
        QString dir = qmake_getpwd();
        int s = dir.lastIndexOf('/');
        if(s != -1)
            dir = dir.right(dir.length() - (s + 1));
        file.setFileName(outdir + dir + Option::pro_ext);
    }
    return MakefileGenerator::openOutput(file, build);
}
Пример #5
0
bool
GBuildMakefileGenerator::openOutput(QFile &file, const QString &build) const
{
    Q_UNUSED(build)
    debug_msg(1, "file is %s", file.fileName().toLatin1().constData());
    QFileInfo fi(file);
    if (fi.filePath().isEmpty())
        file.setFileName(qmake_getpwd() + QDir::separator() + file.fileName());
    if (!file.fileName().endsWith(projectSuffix())) {
        QString outputName(file.fileName());
        outputName += QDir::separator();
        outputName += fileInfo(project->projectFile()).baseName();
        outputName += projectSuffix();
        file.setFileName(outputName);
    }
    debug_msg(1, "file is %s", file.fileName().toLatin1().constData());
    bool ret = MakefileGenerator::openOutput(file, QString());
    return ret;
}
Пример #6
0
int runQMake(int argc, char **argv)
{
    // parse command line
    int ret = Option::init(argc, argv);
    if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
        if ((ret & Option::QMAKE_CMDLINE_ERROR) != 0)
            return 1;
        return 0;
    }

    // report Qt usage for commercial customers with a "metered license" (currently experimental)
#if QT_EDITION != QT_EDITION_OPENSOURCE
    QString reporterPath = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator()
                           + "qtusagereporter";
#if defined(Q_OS_WIN)
    reporterPath += ".exe";
#endif
    if (QFile::exists(reporterPath))
        system(qPrintable(reporterPath + " qmake"));
#endif

    QString oldpwd = qmake_getpwd();
#ifdef Q_WS_WIN
    if(!(oldpwd.length() == 3 && oldpwd[0].isLetter() && oldpwd.endsWith(":/")))
#endif
    {
        if(oldpwd.right(1) != QString(QChar(QDir::separator())))
            oldpwd += QDir::separator();
    }
    Option::output_dir = oldpwd; //for now this is the output dir

    if(Option::output.fileName() != "-") {
        QFileInfo fi(Option::output);
        QString dir;
        if(fi.isDir()) {
            dir = fi.filePath();
        } else {
            QString tmp_dir = fi.path();
            if(!tmp_dir.isEmpty() && QFile::exists(tmp_dir))
                dir = tmp_dir;
        }
        if(!dir.isNull() && dir != ".")
            Option::output_dir = dir;
        if(QDir::isRelativePath(Option::output_dir))
            Option::output_dir.prepend(oldpwd);
        Option::output_dir = QDir::cleanPath(Option::output_dir);
    }

    QMakeProperty prop;
    if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY || Option::qmake_mode == Option::QMAKE_SET_PROPERTY)
        return prop.exec() ? 0 : 101;

    QMakeProject project(&prop);
    int exit_val = 0;
    QStringList files;
    if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
        files << "(*hack*)"; //we don't even use files, but we do the for() body once
    else
        files = Option::mkfile::project_files;
    for(QStringList::Iterator pfile = files.begin(); pfile != files.end(); pfile++) {
        if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
           Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
            QString fn = Option::fixPathToLocalOS((*pfile));
            if(!QFile::exists(fn)) {
                fprintf(stderr, "Cannot find file: %s.\n", fn.toLatin1().constData());
                exit_val = 2;
                continue;
            }

            //setup pwd properly
            debug_msg(1, "Resetting dir to: %s", oldpwd.toLatin1().constData());
            qmake_setpwd(oldpwd); //reset the old pwd
            int di = fn.lastIndexOf(Option::dir_sep);
            if(di != -1) {
                debug_msg(1, "Changing dir to: %s", fn.left(di).toLatin1().constData());
                if(!qmake_setpwd(fn.left(di)))
                    fprintf(stderr, "Cannot find directory: %s\n", fn.left(di).toLatin1().constData());
                fn = fn.right(fn.length() - di - 1);
            }

            // read project..
            if(!project.read(fn)) {
                fprintf(stderr, "Error processing project file: %s\n",
                        fn == "-" ? "(stdin)" : (*pfile).toLatin1().constData());
                exit_val = 3;
                continue;
            }
            if(Option::mkfile::do_preprocess) //no need to create makefile
                continue;
        }

        MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false);
        if(mkfile && !mkfile->write(oldpwd)) {
            if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
                fprintf(stderr, "Unable to generate project file.\n");
            else
                fprintf(stderr, "Unable to generate makefile for: %s\n", (*pfile).toLatin1().constData());
            exit_val = 5;
        }
        delete mkfile;
        mkfile = NULL;
    }
    qmakeClearCaches();
    return exit_val;
}
Пример #7
0
bool
SubdirsMetaMakefileGenerator::init()
{
    if(init_flag)
        return false;
    init_flag = true;

    if(Option::recursive) {
        QString old_output_dir = QDir::cleanPath(Option::output_dir);
        if(!old_output_dir.endsWith('/'))
            old_output_dir += '/';
        QString old_output = Option::output.fileName();
        QString oldpwd = QDir::cleanPath(qmake_getpwd());
        if(!oldpwd.endsWith('/'))
            oldpwd += '/';
        const QStringList &subdirs = project->values("SUBDIRS");
        static int recurseDepth = -1;
        ++recurseDepth;
        for(int i = 0; i < subdirs.size(); ++i) {
            Subdir *sub = new Subdir;
            sub->indent = recurseDepth;

            QFileInfo subdir(subdirs.at(i));
            if(!project->isEmpty(subdirs.at(i) + ".file"))
                subdir = project->first(subdirs.at(i) + ".file");
            else if(!project->isEmpty(subdirs.at(i) + ".subdir"))
                subdir = project->first(subdirs.at(i) + ".subdir");
            QString sub_name;
            if(subdir.isDir())
                subdir = QFileInfo(subdir.filePath() + "/" + subdir.fileName() + Option::pro_ext);
            else
                sub_name = subdir.baseName();
            if(!subdir.isRelative()) { //we can try to make it relative
                QString subdir_path = subdir.filePath();
                if(subdir_path.startsWith(oldpwd))
                    subdir = QFileInfo(subdir_path.mid(oldpwd.length()));
            }

            //handle sub project
            QMakeProject *sub_proj = new QMakeProject(project->properties());
            for (int ind = 0; ind < sub->indent; ++ind)
                printf(" ");
            sub->input_dir = subdir.absolutePath();
            if(subdir.isRelative() && old_output_dir != oldpwd) {
                sub->output_dir = old_output_dir + "/" + subdir.path();
                printf("Reading %s [%s]\n", subdir.absoluteFilePath().toLatin1().constData(), sub->output_dir.toLatin1().constData());
            } else { //what about shadow builds?
                sub->output_dir = sub->input_dir;
                printf("Reading %s\n", subdir.absoluteFilePath().toLatin1().constData());
            }
            qmake_setpwd(sub->input_dir);
            Option::output_dir = sub->output_dir;
            if(Option::output_dir.at(Option::output_dir.length()-1) != QLatin1Char('/'))
                Option::output_dir += QLatin1Char('/');
            sub_proj->read(subdir.fileName());
            if(!sub_proj->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
                fprintf(stderr, "Project file(%s) not recursed because all requirements not met:\n\t%s\n",
                        subdir.fileName().toLatin1().constData(),
                        sub_proj->values("QMAKE_FAILED_REQUIREMENTS").join(" ").toLatin1().constData());
                delete sub;
                delete sub_proj;
                continue;
            }
            sub->makefile = MetaMakefileGenerator::createMetaGenerator(sub_proj, sub_name);
            if(0 && sub->makefile->type() == SUBDIRSMETATYPE) {
                subs.append(sub);
            } else {
                const QString output_name = Option::output.fileName();
                Option::output.setFileName(sub->output_file);
                sub->makefile->write(sub->output_dir);
                delete sub;
                qmakeClearCaches();
                sub = 0;
                Option::output.setFileName(output_name);
            }
            Option::output_dir = old_output_dir;
            qmake_setpwd(oldpwd);

        }
        --recurseDepth;
        Option::output.setFileName(old_output);
        Option::output_dir = old_output_dir;
        qmake_setpwd(oldpwd);
    }

    Subdir *self = new Subdir;
    self->input_dir = qmake_getpwd();
    self->output_dir = Option::output_dir;
    if(!Option::recursive || (!Option::output.fileName().endsWith(Option::dir_sep) && !QFileInfo(Option::output).isDir()))
        self->output_file = Option::output.fileName();
    self->makefile = new BuildsMetaMakefileGenerator(project, name, false);
    self->makefile->init();
    subs.append(self);
    return true;
}
Пример #8
0
bool
BuildsMetaMakefileGenerator::write(const QString &oldpwd)
{
    Build *glue = 0;
    if(!makefiles.isEmpty() && !makefiles.first()->build.isNull()) {
        glue = new Build;
        glue->name = name;
        glue->makefile = createMakefileGenerator(project, true);
        makefiles += glue;
    }

    bool ret = true;
    const QString &output_name = Option::output.fileName();
    for(int i = 0; ret && i < makefiles.count(); i++) {
        Option::output.setFileName(output_name);
        Build *build = makefiles[i];

        bool using_stdout = false;
        if(build->makefile && (Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
                               Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
                && (!build->makefile->supportsMergedBuilds()
                    || (build->makefile->supportsMergedBuilds() && (!glue || build == glue)))) {
            //open output
            if(!(Option::output.isOpen())) {
                if(Option::output.fileName() == "-") {
                    Option::output.setFileName("");
                    Option::output_dir = qmake_getpwd();
                    Option::output.open(stdout, QIODevice::WriteOnly | QIODevice::Text);
                    using_stdout = true;
                } else {
                    if(Option::output.fileName().isEmpty() &&
                            Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE)
                        Option::output.setFileName(project->first("QMAKE_MAKEFILE"));
                    Option::output_dir = oldpwd;
                    QString build_name = build->name;
                    if(!build->build.isEmpty()) {
                        if(!build_name.isEmpty())
                            build_name += ".";
                        build_name += build->build;
                    }
                    if(!build->makefile->openOutput(Option::output, build_name)) {
                        fprintf(stderr, "Failure to open file: %s\n",
                                Option::output.fileName().isEmpty() ? "(stdout)" :
                                Option::output.fileName().toLatin1().constData());
                        return false;
                    }
                }
            }
        } else {
            using_stdout = true; //kind of..
        }

        if(!build->makefile) {
            ret = false;
        } else if(build == glue) {
            ret = build->makefile->writeProjectMakefile();
        } else {
            ret = build->makefile->write();
            if (glue && glue->makefile->supportsMergedBuilds())
                ret = glue->makefile->mergeBuildProject(build->makefile);
        }
        if(!using_stdout) {
            Option::output.close();
            if(!ret)
                Option::output.remove();
        }

        // debugging
        if(Option::debug_level) {
            QMap<QString, QStringList> &vars = project->variables();
            for(QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) {
                if(!it.key().startsWith(".") && !it.value().isEmpty())
                    debug_msg(1, "%s === %s", it.key().toLatin1().constData(),
                              it.value().join(" :: ").toLatin1().constData());
            }
        }
    }
    return ret;
}
Пример #9
0
bool
QMakeMetaInfo::readLibtoolFile(const QString &f)
{
    /* I can just run the .la through the .pro parser since they are compatible.. */
    QMakeProject proj;
    if(!proj.read(Option::fixPathToLocalOS(f), QMakeProject::ReadProFile))
        return false;
    QString dirf = Option::fixPathToTargetOS(f).section(Option::dir_sep, 0, -2);
    if(dirf == f)
        dirf = "";
    else if(!dirf.isEmpty() && !dirf.endsWith(Option::output_dir))
        dirf += Option::dir_sep;
    QMap<QString, QStringList> &v = proj.variables();
    for(QMap<QString, QStringList>::Iterator it = v.begin(); it != v.end(); ++it) {
        QStringList lst = it.value();
        if(lst.count() == 1 && (lst.first().startsWith("'") || lst.first().startsWith("\"")) &&
           lst.first().endsWith(QString(lst.first()[0])))
            lst = QStringList(lst.first().mid(1, lst.first().length() - 2));
        if(!vars.contains("QMAKE_PRL_TARGET") &&
           (it.key() == "dlname" || it.key() == "library_names" || it.key() == "old_library")) {
            QString dir = v["libdir"].first();
            if((dir.startsWith("'") || dir.startsWith("\"")) && dir.endsWith(QString(dir[0])))
                dir = dir.mid(1, dir.length() - 2);
            dir = dir.trimmed();
            if(!dir.isEmpty() && !dir.endsWith(Option::dir_sep))
                dir += Option::dir_sep;
            if(lst.count() == 1)
                lst = lst.first().split(" ");
            for(QStringList::Iterator lst_it = lst.begin(); lst_it != lst.end(); ++lst_it) {
                bool found = false;
                QString dirs[] = { "", dir, dirf, dirf + ".libs" + QDir::separator(), "(term)" };
                for(int i = 0; !found && dirs[i] != "(term)"; i++) {
                    if(QFile::exists(dirs[i] + (*lst_it))) {
                        QString targ = dirs[i] + (*lst_it);
                        if(QDir::isRelativePath(targ))
                            targ.prepend(qmake_getpwd() + QDir::separator());
                        vars["QMAKE_PRL_TARGET"] << targ;
                        found = true;
                    }
                }
                if(found)
                    break;
            }
        } else if(it.key() == "dependency_libs") {
            if(lst.count() == 1) {
                QString dep = lst.first();
                if((dep.startsWith("'") || dep.startsWith("\"")) && dep.endsWith(QString(dep[0])))
                    dep = dep.mid(1, dep.length() - 2);
                lst = dep.trimmed().split(" ");
            }
            QMakeProject *conf = NULL;
            for(QStringList::Iterator lit = lst.begin(); lit != lst.end(); ++lit) {
                if((*lit).startsWith("-R")) {
                    if(!conf) {
                        conf = new QMakeProject;
                        conf->read(QMakeProject::ReadAll ^ QMakeProject::ReadProFile);
                    }
                    if(!conf->isEmpty("QMAKE_LFLAGS_RPATH"))
                        (*lit) = conf->first("QMAKE_LFLAGS_RPATH") + (*lit).mid(2);
                }
            }
            if(conf)
                delete conf;
            vars["QMAKE_PRL_LIBS"] += lst;
        }
    }
    return true;
}
Пример #10
0
int
Option::init(int argc, char **argv)
{
    Option::prf_ext = ".prf";
    Option::pro_ext = ".pro";
    Option::field_sep = ' ';

    if(argc && argv) {
        QString argv0 = argv[0];
        if(Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING)
            Option::qmake_mode = default_mode(argv0);
        if(!argv0.isEmpty() && !QFileInfo(argv0).isRelative()) {
            globals->qmake_abslocation = argv0;
        } else if (argv0.contains(QLatin1Char('/'))
#ifdef Q_OS_WIN
                   || argv0.contains(QLatin1Char('\\'))
#endif
            ) { //relative PWD
            globals->qmake_abslocation = QDir::current().absoluteFilePath(argv0);
        } else { //in the PATH
            QByteArray pEnv = qgetenv("PATH");
            QDir currentDir = QDir::current();
#ifdef Q_OS_WIN
            QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(";"));
            paths.prepend(QLatin1String("."));
#else
            QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(":"));
#endif
            for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
                if ((*p).isEmpty())
                    continue;
                QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
#ifdef Q_OS_WIN
                if (!candidate.endsWith(QLatin1String(".exe")))
                    candidate += QLatin1String(".exe");
#endif
                if (QFile::exists(candidate)) {
                    globals->qmake_abslocation = candidate;
                    break;
                }
            }
        }
        if (!globals->qmake_abslocation.isNull())
            globals->qmake_abslocation = QDir::cleanPath(globals->qmake_abslocation);
        else // This is rather unlikely to ever happen on a modern system ...
            globals->qmake_abslocation = QLibraryInfo::rawLocation(QLibraryInfo::HostBinariesPath,
                                                                   QLibraryInfo::EffectivePaths) +
#ifdef Q_OS_WIN
                    "/qmake.exe";
#else
                    "/qmake";
#endif
    } else {
        Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
    }

    QMakeCmdLineParserState cmdstate(QDir::currentPath());
    const QByteArray envflags = qgetenv("QMAKEFLAGS");
    if (!envflags.isNull()) {
        QStringList args;
        QByteArray buf = "";
        char quote = 0;
        bool hasWord = false;
        for (int i = 0; i < envflags.size(); ++i) {
            char c = envflags.at(i);
            if (!quote && (c == '\'' || c == '"')) {
                quote = c;
            } else if (c == quote) {
                quote = 0;
            } else if (!quote && c == ' ') {
                if (hasWord) {
                    args << QString::fromLocal8Bit(buf);
                    hasWord = false;
                    buf = "";
                }
            } else {
                buf += c;
                hasWord = true;
            }
        }
        if (hasWord)
            args << QString::fromLocal8Bit(buf);
        parseCommandLine(args, cmdstate);
        cmdstate.flush();
    }
    if(argc && argv) {
        QStringList args;
        for (int i = 1; i < argc; i++)
            args << QString::fromLocal8Bit(argv[i]);

        while (!args.isEmpty()) {
            QString opt = args.at(0);
            if (opt == "-project") {
                Option::recursive = true;
                Option::qmake_mode = Option::QMAKE_GENERATE_PROJECT;
            } else if (opt == "-prl") {
                Option::mkfile::do_deps = false;
                Option::mkfile::do_mocs = false;
                Option::qmake_mode = Option::QMAKE_GENERATE_PRL;
            } else if (opt == "-set") {
                Option::qmake_mode = Option::QMAKE_SET_PROPERTY;
            } else if (opt == "-unset") {
                Option::qmake_mode = Option::QMAKE_UNSET_PROPERTY;
            } else if (opt == "-query") {
                Option::qmake_mode = Option::QMAKE_QUERY_PROPERTY;
            } else if (opt == "-makefile") {
                Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
            } else {
                break;
            }
            args.takeFirst();
            break;
        }

        int ret = parseCommandLine(args, cmdstate);
        if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
            if ((ret & Option::QMAKE_CMDLINE_SHOW_USAGE) != 0)
                usage(argv[0]);
            return ret;
            //return ret == QMAKE_CMDLINE_SHOW_USAGE ? usage(argv[0]) : false;
        }
        globals->qmake_args = args;
    }
    globals->commitCommandLineArguments(cmdstate);
    globals->debugLevel = Option::debug_level;

    //last chance for defaults
    if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
        Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
        globals->useEnvironment();

        //try REALLY hard to do it for them, lazy..
        if(Option::mkfile::project_files.isEmpty()) {
            QString proj = detectProjectFile(qmake_getpwd());
            if(!proj.isNull())
                Option::mkfile::project_files.append(proj);
#ifndef QT_BUILD_QMAKE_LIBRARY
            if(Option::mkfile::project_files.isEmpty()) {
                usage(argv[0]);
                return Option::QMAKE_CMDLINE_ERROR;
            }
#endif
        }
    }

    return QMAKE_CMDLINE_SUCCESS;
}
Пример #11
0
int runQMake(int argc, char **argv)
{
    // stderr is unbuffered by default, but stdout buffering depends on whether
    // there is a terminal attached. Buffering can make output from stderr and stdout
    // appear out of sync, so force stdout to be unbuffered as well.
    // This is particularly important for things like QtCreator and scripted builds.
    setvbuf(stdout, (char *)NULL, _IONBF, 0);

    // parse command line
    int ret = Option::init(argc, argv);
    if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
        if ((ret & Option::QMAKE_CMDLINE_ERROR) != 0)
            return 1;
        return 0;
    }

    QString oldpwd = qmake_getpwd();
#ifdef Q_WS_WIN
    if(!(oldpwd.length() == 3 && oldpwd[0].isLetter() && oldpwd.endsWith(":/")))
#endif
    {
        if(oldpwd.right(1) != QString(QChar(QDir::separator())))
            oldpwd += QDir::separator();
    }
    Option::output_dir = oldpwd; //for now this is the output dir

    if(Option::output.fileName() != "-") {
        QFileInfo fi(Option::output);
        QString dir;
        if(fi.isDir()) {
            dir = fi.filePath();
        } else {
            QString tmp_dir = fi.path();
            if(!tmp_dir.isEmpty() && QFile::exists(tmp_dir))
                dir = tmp_dir;
        }
        if(!dir.isNull() && dir != ".")
            Option::output_dir = dir;
        if(QDir::isRelativePath(Option::output_dir))
            Option::output_dir.prepend(oldpwd);
        Option::output_dir = QDir::cleanPath(Option::output_dir);
    }

    QMakeProperty prop;
    if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY ||
       Option::qmake_mode == Option::QMAKE_SET_PROPERTY ||
       Option::qmake_mode == Option::QMAKE_UNSET_PROPERTY)
        return prop.exec() ? 0 : 101;

    QMakeProject project(&prop);
    int exit_val = 0;
    QStringList files;
    if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
        files << "(*hack*)"; //we don't even use files, but we do the for() body once
    else
        files = Option::mkfile::project_files;
    for(QStringList::Iterator pfile = files.begin(); pfile != files.end(); pfile++) {
        if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
           Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
            QString fn = Option::fixPathToLocalOS((*pfile));
            if(!QFile::exists(fn)) {
                fprintf(stderr, "Cannot find file: %s.\n", fn.toLatin1().constData());
                exit_val = 2;
                continue;
            }

            //setup pwd properly
            debug_msg(1, "Resetting dir to: %s", oldpwd.toLatin1().constData());
            qmake_setpwd(oldpwd); //reset the old pwd
            int di = fn.lastIndexOf(QDir::separator());
            if(di != -1) {
                debug_msg(1, "Changing dir to: %s", fn.left(di).toLatin1().constData());
                if(!qmake_setpwd(fn.left(di)))
                    fprintf(stderr, "Cannot find directory: %s\n", fn.left(di).toLatin1().constData());
                fn = fn.right(fn.length() - di - 1);
            }

            // read project..
            if(!project.read(fn)) {
                fprintf(stderr, "Error processing project file: %s\n",
                        fn == "-" ? "(stdin)" : (*pfile).toLatin1().constData());
                exit_val = 3;
                continue;
            }
            if(Option::mkfile::do_preprocess) //no need to create makefile
                continue;
        }

        bool success = true;
        MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false, &success);
        if (!success)
            exit_val = 3;

        if(mkfile && !mkfile->write(oldpwd)) {
            if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
                fprintf(stderr, "Unable to generate project file.\n");
            else
                fprintf(stderr, "Unable to generate makefile for: %s\n", (*pfile).toLatin1().constData());
            exit_val = 5;
        }
        delete mkfile;
        mkfile = NULL;
    }
    qmakeClearCaches();
    return exit_val;
}
Пример #12
0
void
ProjectGenerator::init()
{
    if(init_flag)
        return;
    int file_count = 0;
    init_flag = true;
    verifyCompilers();

    project->read(QMakeProject::ReadFeatures);
    project->variables()["CONFIG"].clear();

    QMap<QString, QStringList> &v = project->variables();
    QString templ = Option::user_template.isEmpty() ? QString("app") : Option::user_template;
    if(!Option::user_template_prefix.isEmpty())
        templ.prepend(Option::user_template_prefix);
    v["TEMPLATE_ASSIGN"] += templ;

    //figure out target
    if(Option::output.fileName() == "-")
        v["TARGET_ASSIGN"] = QStringList("unknown");
    else
        v["TARGET_ASSIGN"] = QStringList(QFileInfo(Option::output).baseName());

    //the scary stuff
    if(project->first("TEMPLATE_ASSIGN") != "subdirs") {
        QString builtin_regex = project_builtin_regx();
        QStringList dirs = Option::projfile::project_dirs;
        if(Option::projfile::do_pwd) {
            if(!v["INCLUDEPATH"].contains("."))
                v["INCLUDEPATH"] += ".";
            dirs.prepend(qmake_getpwd());
        }

        for(int i = 0; i < dirs.count(); ++i) {
            QString dir, regex, pd = dirs.at(i);
            bool add_depend = false;
            if(exists(pd)) {
                QFileInfo fi(fileInfo(pd));
                if(fi.isDir()) {
                    dir = pd;
                    add_depend = true;
                    if(dir.right(1) != Option::dir_sep)
                        dir += Option::dir_sep;
                    if(Option::recursive) {
                        QStringList files = QDir(dir).entryList(QDir::Files);
                        for(int i = 0; i < (int)files.count(); i++) {
                            if(files[i] != "." && files[i] != "..")
                                dirs.append(dir + files[i] + QDir::separator() + builtin_regex);
                        }
                    }
                    regex = builtin_regex;
                } else {
                    QString file = pd;
                    int s = file.lastIndexOf(Option::dir_sep);
                    if(s != -1)
                        dir = file.left(s+1);
                    if(addFile(file)) {
                        add_depend = true;
                        file_count++;
                    }
                }
            } else { //regexp
                regex = pd;
            }
            if(!regex.isEmpty()) {
                int s = regex.lastIndexOf(Option::dir_sep);
                if(s != -1) {
                    dir = regex.left(s+1);
                    regex = regex.right(regex.length() - (s+1));
                }
                if(Option::recursive) {
                    QStringList entries = QDir(dir).entryList(QDir::Dirs);
                    for(int i = 0; i < (int)entries.count(); i++) {
                        if(entries[i] != "." && entries[i] != "..") {
                            dirs.append(dir + entries[i] + QDir::separator() + regex);
                        }
                    }
                }
                QStringList files = QDir(dir).entryList(QDir::nameFiltersFromString(regex));
                for(int i = 0; i < (int)files.count(); i++) {
                    QString file = dir + files[i];
                    if (addFile(file)) {
                        add_depend = true;
                        file_count++;
                    }
                }
            }
            if(add_depend && !dir.isEmpty() && !v["DEPENDPATH"].contains(dir, Qt::CaseInsensitive)) {
                QFileInfo fi(fileInfo(dir));
                if(fi.absoluteFilePath() != qmake_getpwd())
                    v["DEPENDPATH"] += fileFixify(dir);
            }
        }
    }
    if(!file_count) { //shall we try a subdir?
        QStringList knownDirs = Option::projfile::project_dirs;
        if(Option::projfile::do_pwd)
            knownDirs.prepend(".");
        const QString out_file = fileFixify(Option::output.fileName());
        for(int i = 0; i < knownDirs.count(); ++i) {
            QString pd = knownDirs.at(i);
            if(exists(pd)) {
                QString newdir = pd;
                QFileInfo fi(fileInfo(newdir));
                if(fi.isDir()) {
                    newdir = fileFixify(newdir);
                    QStringList &subdirs = v["SUBDIRS"];
                    if(exists(fi.filePath() + QDir::separator() + fi.fileName() + Option::pro_ext) &&
                       !subdirs.contains(newdir, Qt::CaseInsensitive)) {
                        subdirs.append(newdir);
                    } else {
                        QStringList profiles = QDir(newdir).entryList(QStringList("*" + Option::pro_ext), QDir::Files);
                        for(int i = 0; i < (int)profiles.count(); i++) {
                            QString nd = newdir;
                            if(nd == ".")
                                nd = "";
                            else if(!nd.isEmpty() && !nd.endsWith(QString(QChar(QDir::separator()))))
                                nd += QDir::separator();
                            nd += profiles[i];
                            fileFixify(nd);
                            if(profiles[i] != "." && profiles[i] != ".." &&
                               !subdirs.contains(nd, Qt::CaseInsensitive) && !out_file.endsWith(nd))
                                subdirs.append(nd);
                        }
                    }
                    if(Option::recursive) {
                        QStringList dirs = QDir(newdir).entryList(QDir::Dirs);
                        for(int i = 0; i < (int)dirs.count(); i++) {
                            QString nd = fileFixify(newdir + QDir::separator() + dirs[i]);
                            if(dirs[i] != "." && dirs[i] != ".." && !knownDirs.contains(nd, Qt::CaseInsensitive))
                                knownDirs.append(nd);
                        }
                    }
                }
            } else { //regexp
                QString regx = pd, dir;
                int s = regx.lastIndexOf(Option::dir_sep);
                if(s != -1) {
                    dir = regx.left(s+1);
                    regx = regx.right(regx.length() - (s+1));
                }
                QStringList files = QDir(dir).entryList(QDir::nameFiltersFromString(regx), QDir::Dirs);
                QStringList &subdirs = v["SUBDIRS"];
                for(int i = 0; i < (int)files.count(); i++) {
                    QString newdir(dir + files[i]);
                    QFileInfo fi(fileInfo(newdir));
                    if(fi.fileName() != "." && fi.fileName() != "..") {
                        newdir = fileFixify(newdir);
                        if(exists(fi.filePath() + QDir::separator() + fi.fileName() + Option::pro_ext) &&
                           !subdirs.contains(newdir)) {
                           subdirs.append(newdir);
                        } else {
                            QStringList profiles = QDir(newdir).entryList(QStringList("*" + Option::pro_ext), QDir::Files);
                            for(int i = 0; i < (int)profiles.count(); i++) {
                                QString nd = newdir + QDir::separator() + files[i];
                                fileFixify(nd);
                                if(files[i] != "." && files[i] != ".." && !subdirs.contains(nd, Qt::CaseInsensitive)) {
                                    if(newdir + files[i] != Option::output_dir + Option::output.fileName())
                                        subdirs.append(nd);
                                }
                            }
                        }
                        if(Option::recursive && !knownDirs.contains(newdir, Qt::CaseInsensitive))
                            knownDirs.append(newdir);
                    }
                }
            }
        }
        v["TEMPLATE_ASSIGN"] = QStringList("subdirs");
        return;
    }

    //setup deplist
    QList<QMakeLocalFileName> deplist;
    {
        const QStringList &d = v["DEPENDPATH"];
        for(int i = 0; i < d.size(); ++i)
            deplist.append(QMakeLocalFileName(d[i]));
    }
    setDependencyPaths(deplist);

    QStringList &h = v["HEADERS"];
    bool no_qt_files = true;
    QString srcs[] = { "SOURCES", "YACCSOURCES", "LEXSOURCES", "FORMS", QString() };
    for(int i = 0; !srcs[i].isNull(); i++) {
        const QStringList &l = v[srcs[i]];
        QMakeSourceFileInfo::SourceFileType type = QMakeSourceFileInfo::TYPE_C;
        QMakeSourceFileInfo::addSourceFiles(l, QMakeSourceFileInfo::SEEK_DEPS, type);
        for(int i = 0; i < l.size(); ++i) {
            QStringList tmp = QMakeSourceFileInfo::dependencies(l[i]);
            if(!tmp.isEmpty()) {
                for(int dep_it = 0; dep_it < tmp.size(); ++dep_it) {
                    QString dep = tmp[dep_it];
                    dep = fixPathToQmake(dep);
                    QString file_dir = dep.section(Option::dir_sep, 0, -2),
                        file_no_path = dep.section(Option::dir_sep, -1);
                    if(!file_dir.isEmpty()) {
                        for(int inc_it = 0; inc_it < deplist.size(); ++inc_it) {
                            QMakeLocalFileName inc = deplist[inc_it];
                            if(inc.local() == file_dir && !v["INCLUDEPATH"].contains(inc.real(), Qt::CaseInsensitive))
                                v["INCLUDEPATH"] += inc.real();
                        }
                    }
                    if(no_qt_files && file_no_path.indexOf(QRegExp("^q[a-z_0-9].h$")) != -1)
                        no_qt_files = false;
                    QString h_ext;
                    for(int hit = 0; hit < Option::h_ext.size(); ++hit) {
                        if(dep.endsWith(Option::h_ext.at(hit))) {
                            h_ext = Option::h_ext.at(hit);
                            break;
                        }
                    }
                    if(!h_ext.isEmpty()) {
                        for(int cppit = 0; cppit < Option::cpp_ext.size(); ++cppit) {
                            QString src(dep.left(dep.length() - h_ext.length()) +
                                        Option::cpp_ext.at(cppit));
                            if(exists(src)) {
                                QStringList &srcl = v["SOURCES"];
                                if(!srcl.contains(src, Qt::CaseInsensitive))
                                    srcl.append(src);
                            }
                        }
                    } else if(dep.endsWith(Option::lex_ext) &&
                              file_no_path.startsWith(Option::lex_mod)) {
                        addConfig("lex_included");
                    }
                    if(!h.contains(dep, Qt::CaseInsensitive))
                        h += dep;
                }
            }
        }
    }

    //strip out files that are actually output from internal compilers (ie temporary files)
    const QStringList &quc = project->variables()["QMAKE_EXTRA_COMPILERS"];
    for(QStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) {
        QString tmp_out = project->variables()[(*it) + ".output"].first();
        if(tmp_out.isEmpty())
            continue;

        QStringList var_out = project->variables()[(*it) + ".variable_out"];
        bool defaults = var_out.isEmpty();
        for(int i = 0; i < var_out.size(); ++i) {
            QString v = var_out.at(i);
            if(v.startsWith("GENERATED_")) {
                defaults = true;
                break;
            }
        }
        if(defaults) {
            var_out << "SOURCES";
            var_out << "HEADERS";
            var_out << "FORMS";
        }
        const QStringList &tmp = project->variables()[(*it) + ".input"];
        for(QStringList::ConstIterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) {
            QStringList &inputs = project->variables()[(*it2)];
            for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) {
                QString path = replaceExtraCompilerVariables(tmp_out, (*input), QString());
                path = fixPathToQmake(path).section('/', -1);
                for(int i = 0; i < var_out.size(); ++i) {
                    QString v = var_out.at(i);
                    QStringList &list = project->variables()[v];
                    for(int src = 0; src < list.size(); ) {
                        if(list[src] == path || list[src].endsWith("/" + path))
                            list.removeAt(src);
                        else
                            ++src;
                    }
                }
            }
        }
    }
}
Пример #13
0
int
Option::init(int argc, char **argv)
{
    Option::application_argv0 = 0;
    Option::cpp_moc_mod = "";
    Option::h_moc_mod = "moc_";
    Option::lex_mod = "_lex";
    Option::yacc_mod = "_yacc";
    Option::prl_ext = ".prl";
    Option::libtool_ext = ".la";
    Option::pkgcfg_ext = ".pc";
    Option::prf_ext = ".prf";
    Option::js_ext = ".js";
    Option::ui_ext = ".ui";
    Option::h_ext << ".h" << ".hpp" << ".hh" << ".hxx";
    Option::c_ext << ".c";
#ifndef Q_OS_WIN
    Option::h_ext << ".H";
#endif
    Option::cpp_moc_ext = ".moc";
    Option::h_moc_ext = ".cpp";
    Option::cpp_ext << ".cpp" << ".cc" << ".cxx";
#ifndef Q_OS_WIN
    Option::cpp_ext << ".C";
#endif
    Option::lex_ext = ".l";
    Option::yacc_ext = ".y";
    Option::pro_ext = ".pro";
#ifdef Q_OS_WIN
    Option::dirlist_sep = ";";
    Option::shellPath = detectShellPath();
#else
    Option::dirlist_sep = ":";
#endif
    Option::sysenv_mod = "QMAKE_ENV_";
    Option::field_sep = ' ';

    if(argc && argv) {
        Option::application_argv0 = argv[0];
        QString argv0 = argv[0];
        if(Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING)
            Option::qmake_mode = default_mode(argv0);
        if(!argv0.isEmpty() && !QFileInfo(argv0).isRelative()) {
            Option::qmake_abslocation = argv0;
        } else if (argv0.contains(QLatin1Char('/'))
#ifdef Q_OS_WIN
                   || argv0.contains(QLatin1Char('\\'))
#endif
                  ) { //relative PWD
            Option::qmake_abslocation = QDir::current().absoluteFilePath(argv0);
        } else { //in the PATH
            QByteArray pEnv = qgetenv("PATH");
            QDir currentDir = QDir::current();
#ifdef Q_OS_WIN
            QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(";"));
#else
            QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(":"));
#endif
            for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
                if ((*p).isEmpty())
                    continue;
                QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
#ifdef Q_OS_WIN
                candidate += ".exe";
#endif
                if (QFile::exists(candidate)) {
                    Option::qmake_abslocation = candidate;
                    break;
                }
            }
        }
        if(!Option::qmake_abslocation.isNull())
            Option::qmake_abslocation = QDir::cleanPath(Option::qmake_abslocation);
    } else {
        Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
    }

    const QByteArray envflags = qgetenv("QMAKEFLAGS");
    if (!envflags.isNull()) {
        int env_argc = 0, env_size = 0, currlen=0;
        char quote = 0, **env_argv = NULL;
        for (int i = 0; i < envflags.size(); ++i) {
            if (!quote && (envflags.at(i) == '\'' || envflags.at(i) == '"')) {
                quote = envflags.at(i);
            } else if (envflags.at(i) == quote) {
                quote = 0;
            } else if (!quote && envflags.at(i) == ' ') {
                if (currlen && env_argv && env_argv[env_argc]) {
                    env_argv[env_argc][currlen] = '\0';
                    currlen = 0;
                    env_argc++;
                }
            } else {
                if(!env_argv || env_argc > env_size) {
                    env_argv = (char **)realloc(env_argv, sizeof(char *)*(env_size+=10));
                    for(int i2 = env_argc; i2 < env_size; i2++)
                        env_argv[i2] = NULL;
                }
                if(!env_argv[env_argc]) {
                    currlen = 0;
                    env_argv[env_argc] = (char*)malloc(255);
                }
                if(currlen < 255)
                    env_argv[env_argc][currlen++] = envflags.at(i);
            }
        }
        if(env_argv) {
            if(env_argv[env_argc]) {
                env_argv[env_argc][currlen] = '\0';
                currlen = 0;
                env_argc++;
            }
            parseCommandLine(env_argc, env_argv);
            for(int i2 = 0; i2 < env_size; i2++) {
                if(env_argv[i2])
                    free(env_argv[i2]);
            }
            free(env_argv);
        }
    }
    if(argc && argv) {
        int ret = parseCommandLine(argc, argv, 1);
        if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
            if ((ret & Option::QMAKE_CMDLINE_SHOW_USAGE) != 0)
                usage(argv[0]);
            return ret;
            //return ret == QMAKE_CMDLINE_SHOW_USAGE ? usage(argv[0]) : false;
        }
    }

    //last chance for defaults
    if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
            Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
        if(Option::mkfile::qmakespec.isNull() || Option::mkfile::qmakespec.isEmpty())
            Option::mkfile::qmakespec = QString::fromLocal8Bit(qgetenv("QMAKESPEC").constData());

        //try REALLY hard to do it for them, lazy..
        if(Option::mkfile::project_files.isEmpty()) {
            QString pwd = qmake_getpwd(),
                    proj = pwd + "/" + pwd.right(pwd.length() - (pwd.lastIndexOf('/') + 1)) + Option::pro_ext;
            if(QFile::exists(proj)) {
                Option::mkfile::project_files.append(proj);
            } else { //last try..
                QStringList profiles = QDir(pwd).entryList(QStringList("*" + Option::pro_ext));
                if(profiles.count() == 1)
                    Option::mkfile::project_files.append(pwd + "/" + profiles[0]);
            }
#ifndef QT_BUILD_QMAKE_LIBRARY
            if(Option::mkfile::project_files.isEmpty()) {
                usage(argv[0]);
                return Option::QMAKE_CMDLINE_ERROR;
            }
#endif
        }
    }

    //defaults for globals
    if(Option::target_mode == Option::TARG_WIN_MODE) {
        Option::dir_sep = "\\";
        Option::obj_ext = ".obj";
        Option::res_ext = ".res";
    } else {
        if(Option::target_mode == Option::TARG_MAC9_MODE)
            Option::dir_sep = ":";
        else
            Option::dir_sep = "/";
        Option::obj_ext = ".o";
    }
    Option::qmake_abslocation = Option::fixPathToTargetOS(Option::qmake_abslocation);
    return QMAKE_CMDLINE_SUCCESS;
}
Пример #14
0
bool QMakeSourceFileInfo::findDeps(SourceFile *file)
{
    if(file->dep_checked || file->type == TYPE_UNKNOWN)
        return true;
    files_changed = true;
    file->dep_checked = true;

    struct stat fst;
    char *buffer = 0;
    int buffer_len = 0;
    {
        int fd;
#if defined(_MSC_VER) && _MSC_VER >= 1400
        if (_sopen_s(&fd, fixPathForFile(file->file, true).local().toLatin1().constData(),
            _O_RDONLY, _SH_DENYNO, _S_IREAD) != 0)
            fd = -1;
#else
        fd = open(fixPathForFile(file->file, true).local().toLatin1().constData(), O_RDONLY);
#endif
        if(fd == -1 || fstat(fd, &fst) || S_ISDIR(fst.st_mode))
            return false;
        buffer = getBuffer(fst.st_size);
        for(int have_read = 0;
            (have_read = QT_READ(fd, buffer + buffer_len, fst.st_size - buffer_len));
            buffer_len += have_read);
        QT_CLOSE(fd);
    }
    if(!buffer)
        return false;
    if(!file->deps)
        file->deps = new SourceDependChildren;

    int line_count = 1;

    for(int x = 0; x < buffer_len; ++x) {
        bool try_local = true;
        char *inc = 0;
        if(file->type == QMakeSourceFileInfo::TYPE_UI) {
            // skip whitespaces
            while(x < buffer_len && (*(buffer+x) == ' ' || *(buffer+x) == '\t'))
                ++x;
            if(*(buffer + x) == '<') {
                ++x;
                if(buffer_len >= x + 12 && !strncmp(buffer + x, "includehint", 11) &&
                   (*(buffer + x + 11) == ' ' || *(buffer + x + 11) == '>')) {
                    for(x += 11; *(buffer + x) != '>'; ++x);
                    int inc_len = 0;
                    for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len);
                    *(buffer + x + inc_len) = '\0';
                    inc = buffer + x;
                } else if(buffer_len >= x + 13 && !strncmp(buffer + x, "customwidget", 12) &&
                          (*(buffer + x + 12) == ' ' || *(buffer + x + 12) == '>')) {
                    for(x += 13; *(buffer + x) != '>'; ++x); //skip up to >
                    while(x < buffer_len) {
                        for(x++; *(buffer + x) != '<'; ++x); //skip up to <
                        x++;
                        if(buffer_len >= x + 7 && !strncmp(buffer+x, "header", 6) &&
                           (*(buffer + x + 6) == ' ' || *(buffer + x + 6) == '>')) {
                            for(x += 7; *(buffer + x) != '>'; ++x); //skip up to >
                            int inc_len = 0;
                            for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len);
                            *(buffer + x + inc_len) = '\0';
                            inc = buffer + x;
                            break;
                        } else if(buffer_len >= x + 14 && !strncmp(buffer+x, "/customwidget", 13) &&
                                  (*(buffer + x + 13) == ' ' || *(buffer + x + 13) == '>')) {
                            x += 14;
                            break;
                        }
                    }
                } else if(buffer_len >= x + 8 && !strncmp(buffer + x, "include", 7) &&
                          (*(buffer + x + 7) == ' ' || *(buffer + x + 7) == '>')) {
                    for(x += 8; *(buffer + x) != '>'; ++x) {
                        if(buffer_len >= x + 9 && *(buffer + x) == 'i' &&
                           !strncmp(buffer + x, "impldecl", 8)) {
                            for(x += 8; *(buffer + x) != '='; ++x);
                            if(*(buffer + x) != '=')
                                continue;
                            for(++x; *(buffer+x) == '\t' || *(buffer+x) == ' '; ++x);
                            char quote = 0;
                            if(*(buffer+x) == '\'' || *(buffer+x) == '"') {
                                quote = *(buffer + x);
                                ++x;
                            }
                            int val_len;
                            for(val_len = 0; true; ++val_len) {
                                if(quote) {
                                    if(*(buffer+x+val_len) == quote)
                                        break;
                                } else if(*(buffer + x + val_len) == '>' ||
                                          *(buffer + x + val_len) == ' ') {
                                    break;
                                }
                            }
//?                            char saved = *(buffer + x + val_len);
                            *(buffer + x + val_len) = '\0';
                            if(!strcmp(buffer+x, "in implementation")) {
                                //### do this
                            }
                        }
                    }
                    int inc_len = 0;
                    for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len);
                    *(buffer + x + inc_len) = '\0';
                    inc = buffer + x;
                }
            }
            //read past new line now..
            for(; x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x);
            ++line_count;
        } else if(file->type == QMakeSourceFileInfo::TYPE_QRC) {
        } else if(file->type == QMakeSourceFileInfo::TYPE_C) {
            for(int beginning=1; x < buffer_len; ++x) {
                // whitespace comments and line-endings
                for(; x < buffer_len; ++x) {
                    if(*(buffer+x) == ' ' || *(buffer+x) == '\t') {
                        // keep going
                    } else if(*(buffer+x) == '/') {
                        ++x;
                        if(buffer_len >= x) {
                            if(*(buffer+x) == '/') { //c++ style comment
                                for(; x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x);
                                beginning = 1;
                            } else if(*(buffer+x) == '*') { //c style comment
                                for(++x; x < buffer_len; ++x) {
                                    if(*(buffer+x) == '*') {
                                        if(x < buffer_len-1 && *(buffer + (x+1)) == '/') {
                                            ++x;
                                            break;
                                        }
                                    } else if(qmake_endOfLine(*(buffer+x))) {
                                        ++line_count;
                                    }
                                }
                            }
                        }
                    } else if(qmake_endOfLine(*(buffer+x))) {
                        ++line_count;
                        beginning = 1;
                    } else {
                        break;
                    }
                }

                if(x >= buffer_len)
                    break;

                // preprocessor directive
                if(beginning && *(buffer+x) == '#')
                    break;

                // quoted strings
                if(*(buffer+x) == '\'' || *(buffer+x) == '"') {
                    const char term = *(buffer+(x++));
                    for(; x < buffer_len; ++x) {
                        if(*(buffer+x) == term) {
                            ++x;
                            break;
                        } else if(*(buffer+x) == '\\') {
                            ++x;
                        } else if(qmake_endOfLine(*(buffer+x))) {
                            ++line_count;
                        }
                    }
                }
                beginning = 0;
            }
            if(x >= buffer_len)
                break;

            //got a preprocessor symbol
            ++x;
            while(x < buffer_len) {
                if(*(buffer+x) != ' ' && *(buffer+x) != '\t')
                    break;
                ++x;
            }

            int keyword_len = 0;
            const char *keyword = buffer+x;
            while(x+keyword_len < buffer_len) {
                if(((*(buffer+x+keyword_len) < 'a' || *(buffer+x+keyword_len) > 'z')) &&
                   *(buffer+x+keyword_len) != '_') {
                    for(x+=keyword_len; //skip spaces after keyword
                        x < buffer_len && (*(buffer+x) == ' ' || *(buffer+x) == '\t');
                        x++);
                    break;
                } else if(qmake_endOfLine(*(buffer+x+keyword_len))) {
                    x += keyword_len-1;
                    keyword_len = 0;
                    break;
                }
                keyword_len++;
            }

            if(keyword_len == 7 && !strncmp(keyword, "include", keyword_len)) {
                char term = *(buffer + x);
                if(term == '<') {
                    try_local = false;
                    term = '>';
                } else if(term != '"') { //wtf?
                    continue;
                }
                x++;

                int inc_len;
                for(inc_len = 0; *(buffer + x + inc_len) != term && !qmake_endOfLine(*(buffer + x + inc_len)); ++inc_len);
                *(buffer + x + inc_len) = '\0';
                inc = buffer + x;
                x += inc_len;
            } else if(keyword_len == 13 && !strncmp(keyword, "qmake_warning", keyword_len)) {
                char term = 0;
                if(*(buffer + x) == '"')
                    term = '"';
                if(*(buffer + x) == '\'')
                    term = '\'';
                if(term)
                    x++;

                int msg_len;
                for(msg_len = 0; (term && *(buffer + x + msg_len) != term) &&
                              !qmake_endOfLine(*(buffer + x + msg_len)); ++msg_len);
                *(buffer + x + msg_len) = '\0';
                debug_msg(0, "%s:%d %s -- %s", file->file.local().toLatin1().constData(), line_count, keyword, buffer+x);
                x += msg_len;
            } else if(*(buffer+x) == '\'' || *(buffer+x) == '"') {
                const char term = *(buffer+(x++));
                while(x < buffer_len) {
                    if(*(buffer+x) == term)
                        break;
                    if(*(buffer+x) == '\\') {
                        x+=2;
                    } else {
                        if(qmake_endOfLine(*(buffer+x)))
                            ++line_count;
                        ++x;
                    }
                }
            } else {
                --x;
            }
        }

        if(inc) {
            if(!includes)
                includes = new SourceFiles;
            SourceFile *dep = includes->lookupFile(inc);
            if(!dep) {
                bool exists = false;
                QMakeLocalFileName lfn(inc);
                if(QDir::isRelativePath(lfn.real())) {
                    if(try_local) {
                        QString dir = findFileInfo(file->file).path();
                        if(QDir::isRelativePath(dir))
                            dir.prepend(qmake_getpwd() + "/");
                        if(!dir.endsWith("/"))
                            dir += "/";
                        QMakeLocalFileName f(dir + lfn.local());
                        if(findFileInfo(f).exists()) {
                            lfn = fixPathForFile(f);
                            exists = true;
                        }
                    }
                    if(!exists) { //path lookup
                        for(QList<QMakeLocalFileName>::Iterator it = depdirs.begin(); it != depdirs.end(); ++it) {
                            QMakeLocalFileName f((*it).real() + Option::dir_sep + lfn.real());
                            QFileInfo fi(findFileInfo(f));
                            if(fi.exists() && !fi.isDir()) {
                                lfn = fixPathForFile(f);
                                exists = true;
                                break;
                            }
                        }
                    }
                    if(!exists) { //heuristic lookup
                        lfn = findFileForDep(QMakeLocalFileName(inc), file->file);
                        if((exists = !lfn.isNull()))
                            lfn = fixPathForFile(lfn);
                    }
                } else {
                    exists = QFile::exists(lfn.real());
                }
                if(!lfn.isNull()) {
                    dep = files->lookupFile(lfn);
                    if(!dep) {
                        dep = new SourceFile;
                        dep->file = lfn;
                        dep->type = QMakeSourceFileInfo::TYPE_C;
                        files->addFile(dep);
                        includes->addFile(dep, inc, false);
                    }
                    dep->exists = exists;
                }
            }
            if(dep && dep->file != file->file) {
                dep->included_count++;
                if(dep->exists) {
                    debug_msg(5, "%s:%d Found dependency to %s", file->file.real().toLatin1().constData(),
                              line_count, dep->file.local().toLatin1().constData());
                    file->deps->addChild(dep);
                }
            }
        }
    }
    if(dependencyMode() == Recursive) { //done last because buffer is shared
        for(int i = 0; i < file->deps->used_nodes; i++) {
            if(!file->deps->children[i]->deps)
                findDeps(file->deps->children[i]);
        }
    }
    return true;
}
Пример #15
0
bool
QMakeMetaInfo::readLibtoolFile(const QString &f)
{
    /* I can just run the .la through the .pro parser since they are compatible.. */
    QMakeProject proj;
    QString nf = Option::normalizePath(f);
    if (!proj.read(nf, QMakeEvaluator::LoadProOnly))
        return false;
    QString dirf = nf.section(QLatin1Char('/'), 0, -2);
    if(dirf == nf)
        dirf = "";
    else if(!dirf.isEmpty() && !dirf.endsWith(Option::output_dir))
        dirf += QLatin1Char('/');
    const ProValueMap &v = proj.variables();
    for (ProValueMap::ConstIterator it = v.begin(); it != v.end(); ++it) {
        ProStringList lst = it.value();
        if(lst.count() == 1 && (lst.first().startsWith("'") || lst.first().startsWith("\"")) &&
           lst.first().endsWith(QString(lst.first().at(0))))
            lst = ProStringList(lst.first().mid(1, lst.first().length() - 2));
        if(!vars.contains("QMAKE_PRL_TARGET") &&
           (it.key() == "dlname" || it.key() == "library_names" || it.key() == "old_library")) {
            ProString dir = v["libdir"].first();
            if ((dir.startsWith('\'') || dir.startsWith('"')) && dir.endsWith(dir.at(0)))
                dir = dir.mid(1, dir.length() - 2);
            dir = dir.trimmed();
            if(!dir.isEmpty() && !dir.endsWith(QLatin1Char('/')))
                dir += QLatin1Char('/');
            if(lst.count() == 1)
                lst = ProStringList(lst.first().toQString().split(" "));
            for (ProStringList::Iterator lst_it = lst.begin(); lst_it != lst.end(); ++lst_it) {
                bool found = false;
                QString dirs[] = { "", dir.toQString(), dirf, dirf + ".libs/", "(term)" };
                for(int i = 0; !found && dirs[i] != "(term)"; i++) {
                    if(QFile::exists(dirs[i] + (*lst_it))) {
                        QString targ = dirs[i] + (*lst_it);
                        if(QDir::isRelativePath(targ))
                            targ.prepend(qmake_getpwd() + QLatin1Char('/'));
                        vars["QMAKE_PRL_TARGET"] << targ;
                        found = true;
                    }
                }
                if(found)
                    break;
            }
        } else if(it.key() == "dependency_libs") {
            if(lst.count() == 1) {
                ProString dep = lst.first();
                if ((dep.startsWith('\'') || dep.startsWith('"')) && dep.endsWith(dep.at(0)))
                    dep = dep.mid(1, dep.length() - 2);
                lst = ProStringList(dep.trimmed().toQString().split(" "));
            }
            for (ProStringList::Iterator lit = lst.begin(); lit != lst.end(); ++lit) {
                if((*lit).startsWith("-R")) {
                    if(!conf->isEmpty("QMAKE_LFLAGS_RPATH"))
                        (*lit) = conf->first("QMAKE_LFLAGS_RPATH") + (*lit).mid(2);
                }
            }
            vars["QMAKE_PRL_LIBS"] += lst;
        }
    }
    return true;
}
Пример #16
0
bool
GBuildMakefileGenerator::write()
{
    QStringList tmp;
    QString filename(Option::output.fileName());
    QString pathtoremove(qmake_getpwd());
    QString relpath(pathtoremove);
    QString strtarget(project->first("TARGET").toQString());
    bool isnativebin = nativebins.contains(strtarget);
    relpath.replace(Option::output_dir, "");

    /* correct output for non-prl, non-recursive case */
    QString outname(qmake_getpwd());
    outname += QDir::separator();
    outname += fileInfo(Option::output.fileName()).baseName();
    outname += projectSuffix();
    Option::output.close();
    Option::output.setFileName(outname);
    MakefileGenerator::openOutput(Option::output, QString());

    if (strtarget != fileInfo(project->projectFile()).baseName()) {
        QString gpjname(strtarget);
        QString outputName(qmake_getpwd());
        outputName += QDir::separator();
        outputName += fileInfo(project->projectFile()).baseName();
        outputName += projectSuffix();
        QFile f(outputName);
        f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
        QTextStream t(&f);
        t << "#!gbuild\n";
        t << "[Project]\n";
        t << gpjname << projectSuffix() << "\n";
        if ((project->first("TEMPLATE") == "lib")
                && project->isActiveConfig("shared"))
            t << gpjname << "_shared" << projectSuffix() << "\n";
        t.flush();
        gpjname += projectSuffix();
        Option::output.close();
        Option::output.setFileName(gpjname);
        MakefileGenerator::openOutput(Option::output, QString());
    }

    if ((project->first("TEMPLATE") == "app")
            && (!isnativebin)) {
        QTextStream t(&Option::output);
        QString intname(strtarget);
        intname += ".int";
        /* this is for bulding an INTEGRITY application.
         * generate the .int integrate file and the .gpj INTEGRITY Application
         * project file, then go on with regular files */
        t << "#!gbuild\n";
        t << "[INTEGRITY Application]\n";
        t << "\t:binDirRelative=.\n";
        t << "\t-o " << strtarget << "\n";
        t << intname << "\n";
        t << strtarget << "_app" << projectSuffix() << "\n";
        t.flush();

        /* generate integrate file */
        QFile f(intname);
        f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
        QTextStream ti(&f);
        ti << "# This is a file automatically generated by qmake\n";
        ti << "# Modifications will be lost next time you run qmake\n";
        ti << "Kernel\n";
        ti << "\tFilename\tDynamicDownload\n";
        ti << "EndKernel\n\n";
        ti << "AddressSpace\n";
        ti << "\tName\t" << strtarget << "\n";
        ti << "\tFilename\t" << strtarget << "_app\n";
        ti << "\tMemoryPoolSize\t0x100000\n";
        ti << "\tLanguage\tC++\n";
        /* FIXME : heap size is huge to be big enough for every example
         * it should probably be tailored for each example, btu there is no
         * good way to guess that */
        ti << "\tHeapSize\t0x00D00000\n";
        ti << "\tTask\tInitial\n";
        ti << "\t\tStackSize\t0x30000\n";
        ti << "\tEndTask\n";
        ti << "EndAddressSpace\n";
        ti.flush();

        /* change current project file to <projectname>_app.gpj and continue
         * generation */
        filename.insert(filename.lastIndexOf("."), "_app");
        Option::output.close();
        Option::output.setFileName(filename);
        MakefileGenerator::openOutput(Option::output, QString());
    } else if ((project->first("TEMPLATE") == "lib")
            && project->isActiveConfig("shared")) {
        QString gpjname(strtarget);
        gpjname += "_shared";
        gpjname += projectSuffix();
        QFile f(gpjname);
        f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
        QTextStream t(&f);
        t << "#!gbuild\n"
            "[Program]\n"
            "\t-A libINTEGRITY.so\n"
            "\t-A libc.so\n"
            "\t-A libscxx.so\n"
            "\t-A libQtCore.so\n"
            "\t-e __ghsbegin_text\n"
            "\t-startfile=-\n"
            "\t:syslibraries=-\n"
            "\t-Onolink\n";
        t << "\t-o lib" << strtarget << ".so\n";
        t << "\t-l" << strtarget << "\n";
        t << "\t-extractall=-l" << strtarget << "\n";
        t << "\t:outputDir=work/" << filename.section(QDir::separator(), 0, -1).remove(".gpj") << "\n";
        t << strtarget << "_shared.ld\n";
        t << "$(__OS_DIR)/intlib/sharedobjbssinit.c\n";
        t.flush();

        QFile fl(strtarget + "_shared.ld");
        fl.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
        QTextStream tl(&fl);
        tl << "CONSTANTS {\n"
             "    __INTEGRITY_MinPageAlign          = 16K\n"
             "    __INTEGRITY_MaxPageAlign          = 16K\n"
             "    __INTEGRITY_LibCBaseAddress       = \n";
        tl << dllbase << "\n";
        tl << "}\n"
             "-sec\n"
             "{\n"
             "  .picbase __INTEGRITY_LibCBaseAddress :\n"
             "        .text :\n"
             "  .syscall :\n"
             "        .intercall :\n"
             "        .interfunc :\n"
             "  .secinfo :\n"
             "  .rodata align(16) :\n"
             "  .fixaddr :\n"
             "  .fixtype :\n"
             "        .rombeg :\n"
             "        .textchecksum :\n"
             "        // The above sections may be large. Leave a bigger gap for large pages.\n"
             "  .pidbase align(__INTEGRITY_MaxPageAlign) :\n"
             "        .sdabase :\n"
             "        .data :\n"
             "        .toc :\n"
             "        .opd :\n"
             "        .datachecksum :\n"
             "  .bss align(__INTEGRITY_MinPageAlign) :\n"
             "        .heap :\n"
             "}\n";
        tl.flush();
        dllbase += DLLOFFSET;
    }

    QTextStream t(&Option::output);
    QString primaryTarget(project->values("QMAKE_CXX").at(0).toQString());

    pathtoremove += QDir::separator();
    filename.remove(qmake_getpwd());

    //HEADER
    t << "#!gbuild\n";

    /* find the architecture out of the compiler name */
    if (filename.endsWith("projects.gpj")) {
        primaryTarget.remove(0, 5);
        t << "macro QT_BUILD_DIR=%expand_path(.)\n";
        t << "macro __OS_DIR=" << project->values("INTEGRITY_DIR").first() << "\n";
        t << "primaryTarget=" << primaryTarget << "_integrity.tgt\n";
        t << "customization=util/integrity/qt.bod\n";
    }
    /* project type */
    if (project->first("TEMPLATE") == "app") {
        t << "[Program]\n";
        if (isnativebin) {
            t << "\t:binDir=bin\n";
            t << "\t-o " << strtarget << "\n";
        } else {
            t << "\t:binDirRelative=.\n";
            t << "\t-o " << strtarget << "_app\n";
        }
    } else if (project->first("TEMPLATE") == "lib") {
        t << "[Library]\n";
        t << "\t:binDir=lib\n";
        t << "\t-o lib" << strtarget << ".a\n";
    } else if (project->first("TEMPLATE") == "subdirs")
        t << "[Project]\n";
    else
        t << project->first("TEMPLATE") << "\n";

    /* compilations options */
    t << "\t:sourceDir=.\n";

    t << "\t:outputDir=work" << relpath << "\n";
    if (filename.endsWith("projects.gpj")) {
        t << "\t:sourceDir=work\n";
        t << "\t-Iwork\n";
        t << "\t-Llib\n";
        t << "\t";
        const ProStringList &l = project->values("QMAKE_CXXFLAGS");
        for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
            if ((*it).startsWith("-"))
                t << "\n\t" << (*it);
            else
                t << " " << (*it);
        }
        t << "\n";
    }
    t << "\n";

    t << varGlue("DEFINES", "\t-D", "\n\t-D", "\n");

    t << "\t-I.\n\t-I" << specdir() << "\n";
    t << varGlue("INCLUDEPATH", "\t-I", "\n\t-I", "\n");
    t << "\t--cxx_include_directory .\n\t--cxx_include_directory " << specdir() << "\n";
    t << varGlue("INCLUDEPATH", "\t--cxx_include_directory ", "\n\t--cxx_include_directory ", "\n");

    if (project->first("TEMPLATE") == "app") {
        /* include linker flags if it's an application */
        static const char * const src[] = { "QMAKE_LFLAGS", "QMAKE_LIBS", "LIBS", 0 };
        for (int i = 0; src[i]; i++) {
            /* skip target libraries for native tools */
            if (isnativebin && (i == 0))
                continue;
            t << "\t";
            const ProStringList &l = project->values(src[i]);
            for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
                if ((*it).startsWith("-"))
                    t << "\n\t" << (*it);
                else
                    t << " " << (*it);
            }
            t << "\n";
        }
    }

    /* first subdirectories/subprojects */
    {
        const ProStringList &l = project->values("SUBDIRS");
        for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
            QString gpjname((*it).toQString());
            /* avoid native tools */
            if (nativebins.contains(gpjname.section("_", -1)))
                continue;
            const ProKey skey(*it + ".subdir");
            if (!project->first(skey).isEmpty())
                gpjname = project->first(skey).toQString();
            else
                gpjname.replace("_", QDir::separator());
            gpjname += QDir::separator() + gpjname.section(QDir::separator(), -1);
            gpjname += projectSuffix();
            /* make relative */
            if (!project->values("QT_SOURCE_TREE").isEmpty()) {
                gpjname.replace(project->values("QT_SOURCE_TREE").first() + QDir::separator(), "");
            }
            t << gpjname << "\n";
        }
    }

    {
        const ProStringList &l = project->values("RESOURCES");
        for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
            QString tmpstr((*it).toQString());
            tmpstr.remove(pathtoremove);
            t << tmpstr << "\t[Qt Resource]\n";
            tmpstr = tmpstr.section(".", -2, -1).section(QDir::separator(), -1);
            tmpstr.remove(".qrc");
            t << "\t-name " << tmpstr << "\n";
            tmpstr.insert(tmpstr.lastIndexOf(QDir::separator()) + 1, "qrc_");
            tmpstr.append(".cpp");
            t << "\t-o work/" << tmpstr << "\n";
        }
    }
    {
        const ProStringList &l = project->values("FORMS");
        for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
            QString tmpstr((*it).toQString());
            tmpstr.remove(pathtoremove);
            t << tmpstr << "\t[Qt Dialog]\n";
            tmpstr = tmpstr.section(".", 0, 0).section(QDir::separator(), -1);
            tmpstr.insert(tmpstr.lastIndexOf(QDir::separator()) + 1, "ui_");
            tmpstr.remove(".ui");
            tmpstr.append(".h");
            t << "\t-o work/" << tmpstr << "\n";
        }
    }

    /* source files for this project */
    static const char * const src[] = { "HEADERS", "SOURCES", 0 };
    for (int i = 0; src[i]; i++) {
        const ProStringList &l = project->values(src[i]);
        for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
            if ((*it).isEmpty())
                continue;
            /* native tools aren't preprocessed */
            if (!isnativebin)
                t << writeOne((*it).toQString(), pathtoremove);
            else
                t << (*it).toQString().remove(pathtoremove) << "\n";
        }
    }
    t << "\n";

    {
        const ProStringList &l = project->values("GENERATED_SOURCES");
        for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
            t << "work/" << (*it).toQString().section(QDir::separator(), -1) << "\n";
        }
    }

    return true;
}
Пример #17
0
bool
BuildsMetaMakefileGenerator::write()
{
    Build *glue = 0;
    if(!makefiles.isEmpty() && !makefiles.first()->build.isNull()) {
        glue = new Build;
        glue->name = name;
        glue->makefile = createMakefileGenerator(project, true);
        makefiles += glue;
    }

    bool ret = true;
    const QString &output_name = Option::output.fileName();
    for(int i = 0; ret && i < makefiles.count(); i++) {
        Option::output.setFileName(output_name);
        Build *build = makefiles[i];

        bool using_stdout = false;
        if(build->makefile && (Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
                               Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
           && (!build->makefile->supportsMergedBuilds()
            || (build->makefile->supportsMergedBuilds() && (!glue || build == glue)))) {
            //open output
            if(!(Option::output.isOpen())) {
                if(Option::output.fileName() == "-") {
                    Option::output.setFileName("");
                    Option::output_dir = qmake_getpwd();
                    Option::output.open(stdout, QIODevice::WriteOnly | QIODevice::Text);
                    using_stdout = true;
                } else {
                    if(Option::output.fileName().isEmpty() &&
                       Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE)
                        Option::output.setFileName(project->first("QMAKE_MAKEFILE").toQString());
                    QString build_name = build->name;
                    if(!build->build.isEmpty()) {
                        if(!build_name.isEmpty())
                            build_name += ".";
                        build_name += build->build;
                    }
                    if(!build->makefile->openOutput(Option::output, build_name)) {
                        fprintf(stderr, "Failure to open file: %s\n",
                                Option::output.fileName().isEmpty() ? "(stdout)" :
                                Option::output.fileName().toLatin1().constData());
                        return false;
                    }
                }
            }
        } else {
           using_stdout = true; //kind of..
        }

        if(!build->makefile) {
            ret = false;
        } else if(build == glue) {
            ret = build->makefile->writeProjectMakefile();
        } else {
            ret = build->makefile->write();
            if (glue && glue->makefile->supportsMergedBuilds())
                ret = glue->makefile->mergeBuildProject(build->makefile);
        }
        if(!using_stdout) {
            Option::output.close();
            if(!ret)
                Option::output.remove();
        }
    }
    return ret;
}
Пример #18
0
void Win32MakefileGenerator::processRcFileVar()
{
    if (Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING)
        return;

    if (((!project->values("VERSION").isEmpty())
        && project->values("RC_FILE").isEmpty()
        && project->values("RES_FILE").isEmpty()
        && !project->isActiveConfig("no_generated_target_info")
        && (project->isActiveConfig("shared") || !project->values("QMAKE_APP_FLAG").isEmpty()))
        || !project->values("QMAKE_WRITE_DEFAULT_RC").isEmpty()){

        QByteArray rcString;
        QTextStream ts(&rcString, QFile::WriteOnly);

        QStringList vers = project->values("VERSION").first().split(".");
        for (int i = vers.size(); i < 4; i++)
            vers += "0";
        QString versionString = vers.join(".");

        QString companyName;
        if (!project->values("QMAKE_TARGET_COMPANY").isEmpty())
            companyName = project->values("QMAKE_TARGET_COMPANY").join(" ");

        QString description;
        if (!project->values("QMAKE_TARGET_DESCRIPTION").isEmpty())
            description = project->values("QMAKE_TARGET_DESCRIPTION").join(" ");

        QString copyright;
        if (!project->values("QMAKE_TARGET_COPYRIGHT").isEmpty())
            copyright = project->values("QMAKE_TARGET_COPYRIGHT").join(" ");

        QString productName;
        if (!project->values("QMAKE_TARGET_PRODUCT").isEmpty())
            productName = project->values("QMAKE_TARGET_PRODUCT").join(" ");
        else
            productName = project->values("TARGET").first();

        QString originalName = project->values("TARGET").first() + project->values("TARGET_EXT").first();
        int rcLang = project->intValue("RC_LANG", 1033);            // default: English(USA)
        int rcCodePage = project->intValue("RC_CODEPAGE", 1200);    // default: Unicode

        ts << "# if defined(UNDER_CE)" << endl;
        ts << "#  include <winbase.h>" << endl;
        ts << "# else" << endl;
        ts << "#  include <winver.h>" << endl;
        ts << "# endif" << endl;
        ts << endl;
        ts << "VS_VERSION_INFO VERSIONINFO" << endl;
        ts << "\tFILEVERSION " << QString(versionString).replace(".", ",") << endl;
        ts << "\tPRODUCTVERSION " << QString(versionString).replace(".", ",") << endl;
        ts << "\tFILEFLAGSMASK 0x3fL" << endl;
        ts << "#ifdef _DEBUG" << endl;
        ts << "\tFILEFLAGS VS_FF_DEBUG" << endl;
        ts << "#else" << endl;
        ts << "\tFILEFLAGS 0x0L" << endl;
        ts << "#endif" << endl;
        ts << "\tFILEOS VOS__WINDOWS32" << endl;
        if (project->isActiveConfig("shared"))
            ts << "\tFILETYPE VFT_DLL" << endl;
        else
            ts << "\tFILETYPE VFT_APP" << endl;
        ts << "\tFILESUBTYPE 0x0L" << endl;
        ts << "\tBEGIN" << endl;
        ts << "\t\tBLOCK \"StringFileInfo\"" << endl;
        ts << "\t\tBEGIN" << endl;
        ts << "\t\t\tBLOCK \""
           << QString("%1%2").arg(rcLang, 4, 16, QLatin1Char('0')).arg(rcCodePage, 4, 16, QLatin1Char('0'))
           << "\"" << endl;
        ts << "\t\t\tBEGIN" << endl;
        ts << "\t\t\t\tVALUE \"CompanyName\", \"" << companyName << "\\0\"" << endl;
        ts << "\t\t\t\tVALUE \"FileDescription\", \"" <<  description << "\\0\"" << endl;
        ts << "\t\t\t\tVALUE \"FileVersion\", \"" << versionString << "\\0\"" << endl;
        ts << "\t\t\t\tVALUE \"LegalCopyright\", \"" << copyright << "\\0\"" << endl;
        ts << "\t\t\t\tVALUE \"OriginalFilename\", \"" << originalName << "\\0\"" << endl;
        ts << "\t\t\t\tVALUE \"ProductName\", \"" << productName << "\\0\"" << endl;
        ts << "\t\t\tEND" << endl;
        ts << "\t\tEND" << endl;
        ts << "\t\tBLOCK \"VarFileInfo\"" << endl;
        ts << "\t\tBEGIN" << endl;
        ts << "\t\t\tVALUE \"Translation\", "
           << QString("0x%1").arg(rcLang, 4, 16, QLatin1Char('0'))
           << ", " << QString("%1").arg(rcCodePage, 4) << endl;
        ts << "\t\tEND" << endl;
        ts << "\tEND" << endl;
        ts << "/* End of Version info */" << endl;
        ts << endl;

        ts.flush();


        QString rcFilename = project->values("OUT_PWD").first()
                           + "/"
                           + project->values("TARGET").first()
                           + "_resource"
                           + ".rc";
        QFile rcFile(QDir::cleanPath(rcFilename));

        bool writeRcFile = true;
        if (rcFile.exists() && rcFile.open(QFile::ReadOnly)) {
            writeRcFile = rcFile.readAll() != rcString;
            rcFile.close();
        }
        if (writeRcFile) {
	    bool ok;
	    ok = rcFile.open(QFile::WriteOnly);
	    if (!ok) {
		// The file can't be opened... try creating the containing
		// directory first (needed for clean shadow builds)
		QDir().mkpath(QFileInfo(rcFile).path());
		ok = rcFile.open(QFile::WriteOnly);
	    }
	    if (!ok) {
		::fprintf(stderr, "Cannot open for writing: %s", rcFile.fileName().toLatin1().constData());
		::exit(1);
	    }
	    rcFile.write(rcString);
	    rcFile.close();
        }
        if (project->values("QMAKE_WRITE_DEFAULT_RC").isEmpty())
            project->values("RC_FILE").insert(0, rcFile.fileName());
    }
    if (!project->values("RC_FILE").isEmpty()) {
        if (!project->values("RES_FILE").isEmpty()) {
            fprintf(stderr, "Both rc and res file specified.\n");
            fprintf(stderr, "Please specify one of them, not both.");
            exit(1);
        }
        QString resFile = project->values("RC_FILE").first();

        // if this is a shadow build then use the absolute path of the rc file
        if (Option::output_dir != qmake_getpwd()) {
            QFileInfo fi(resFile);
            project->values("RC_FILE").first() = fi.absoluteFilePath();
        }

        resFile.replace(".rc", Option::res_ext);
        project->values("RES_FILE").prepend(fileInfo(resFile).fileName());
        if (!project->values("OBJECTS_DIR").isEmpty()) {
            QString resDestDir;
            if (project->isActiveConfig("staticlib"))
                resDestDir = fileInfo(project->first("DESTDIR")).absoluteFilePath();
            else
                resDestDir = project->first("OBJECTS_DIR");
            resDestDir.append(Option::dir_sep);
            project->values("RES_FILE").first().prepend(resDestDir);
        }
        project->values("RES_FILE").first() = Option::fixPathToTargetOS(project->values("RES_FILE").first(), false, false);
	project->values("POST_TARGETDEPS") += project->values("RES_FILE");
        project->values("CLEAN_FILES") += project->values("RES_FILE");
    }
}
Пример #19
0
bool
SubdirsMetaMakefileGenerator::init()
{
    if(init_flag)
        return false;
    init_flag = true;
    bool hasError = false;

    // It might make sense to bequeath the CONFIG option to the recursed
    // projects. OTOH, one would most likely have it in all projects anyway -
    // either through a qmakespec, a .qmake.cache or explicitly - as otherwise
    // running qmake in a subdirectory would have a different auto-recurse
    // setting than in parent directories.
    bool recurse = Option::recursive == Option::QMAKE_RECURSIVE_YES
                   || (Option::recursive == Option::QMAKE_RECURSIVE_DEFAULT
                       && project->isRecursive());
    if(recurse) {
        QString old_output_dir = Option::output_dir;
        QString old_output = Option::output.fileName();
        QString oldpwd = qmake_getpwd();
        QString thispwd = oldpwd;
        if(!thispwd.endsWith('/'))
           thispwd += '/';
        const QStringList &subdirs = project->values("SUBDIRS");
        static int recurseDepth = -1;
        ++recurseDepth;
        for(int i = 0; i < subdirs.size(); ++i) {
            Subdir *sub = new Subdir;
            sub->indent = recurseDepth;

            QFileInfo subdir(subdirs.at(i));
            if(!project->isEmpty(subdirs.at(i) + ".file"))
                subdir = project->first(subdirs.at(i) + ".file");
            else if(!project->isEmpty(subdirs.at(i) + ".subdir"))
                subdir = project->first(subdirs.at(i) + ".subdir");
            QString sub_name;
            if(subdir.isDir())
                subdir = QFileInfo(subdir.filePath() + "/" + subdir.fileName() + Option::pro_ext);
            else
                sub_name = subdir.baseName();
            if(!subdir.isRelative()) { //we can try to make it relative
                QString subdir_path = subdir.filePath();
                if(subdir_path.startsWith(thispwd))
                    subdir = QFileInfo(subdir_path.mid(thispwd.length()));
            }

            //handle sub project
            QMakeProject *sub_proj = new QMakeProject(project->properties());
            for (int ind = 0; ind < sub->indent; ++ind)
                printf(" ");
            sub->input_dir = subdir.absolutePath();
            if(subdir.isRelative() && old_output_dir != oldpwd) {
                sub->output_dir = old_output_dir + "/" + subdir.path();
                printf("Reading %s [%s]\n", subdir.absoluteFilePath().toLatin1().constData(), sub->output_dir.toLatin1().constData());
            } else { //what about shadow builds?
                sub->output_dir = sub->input_dir;
                printf("Reading %s\n", subdir.absoluteFilePath().toLatin1().constData());
            }
            qmake_setpwd(sub->input_dir);
            Option::output_dir = sub->output_dir;
            bool tmpError = !sub_proj->read(subdir.fileName());
            if(!sub_proj->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
                fprintf(stderr, "Project file(%s) not recursed because all requirements not met:\n\t%s\n",
                        subdir.fileName().toLatin1().constData(),
                        sub_proj->values("QMAKE_FAILED_REQUIREMENTS").join(" ").toLatin1().constData());
                delete sub;
                delete sub_proj;
                Option::output_dir = old_output_dir;
                qmake_setpwd(oldpwd);
                continue;
            } else {
                hasError |= tmpError;
            }
            sub->makefile = MetaMakefileGenerator::createMetaGenerator(sub_proj, sub_name);
            if(0 && sub->makefile->type() == SUBDIRSMETATYPE) {
                subs.append(sub);
            } else {
                const QString output_name = Option::output.fileName();
                Option::output.setFileName(sub->output_file);
                hasError |= !sub->makefile->write(sub->output_dir);
                delete sub;
                qmakeClearCaches();
                sub = 0;
                Option::output.setFileName(output_name);
            }
            Option::output_dir = old_output_dir;
            qmake_setpwd(oldpwd);

        }
        --recurseDepth;
        Option::output.setFileName(old_output);
        Option::output_dir = old_output_dir;
        qmake_setpwd(oldpwd);
    }

    Subdir *self = new Subdir;
    self->input_dir = qmake_getpwd();
    self->output_dir = Option::output_dir;
    if(!recurse || (!Option::output.fileName().endsWith(Option::dir_sep) && !QFileInfo(Option::output).isDir()))
        self->output_file = Option::output.fileName();
    self->makefile = new BuildsMetaMakefileGenerator(project, name, false);
    self->makefile->init();
    subs.append(self);

    return !hasError;
}