Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pythonqt_generator modified argument handling, make generate #124

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 76 additions & 76 deletions generator/abstractmetalang.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion generator/abstractmetalang.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ class AbstractMetaFunction : public AbstractMetaAttributes
// true if one or more of the arguments are of QtJambiObject subclasses
bool argumentsHaveNativeId() const
{
foreach (const AbstractMetaArgument *arg, m_arguments) {
for (const AbstractMetaArgument *arg : m_arguments) {
if (arg->type()->hasNativeId())
return true;
}
Expand Down
8 changes: 4 additions & 4 deletions generator/generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void Generator::generate()

std::stable_sort(m_classes.begin(), m_classes.end());

foreach (AbstractMetaClass *cls, m_classes) {
for (AbstractMetaClass *cls : m_classes) {
if (!shouldGenerate(cls))
continue;

Expand All @@ -88,7 +88,7 @@ void Generator::printClasses()
AbstractMetaClassList classes = m_classes;
std::sort(classes.begin(), classes.end());

foreach (AbstractMetaClass *cls, classes) {
for (AbstractMetaClass *cls : classes) {
if (!shouldGenerate(cls))
continue;
write(s, cls);
Expand Down Expand Up @@ -128,10 +128,10 @@ bool Generator::hasDefaultConstructor(const AbstractMetaType *type)
QString full_name = type->typeEntry()->qualifiedTargetLangName();
QString class_name = type->typeEntry()->targetLangName();

foreach (const AbstractMetaClass *java_class, m_classes) {
for (const AbstractMetaClass *java_class : m_classes) {
if (java_class->typeEntry()->qualifiedTargetLangName() == full_name) {
AbstractMetaFunctionList functions = java_class->functions();
foreach (const AbstractMetaFunction *function, functions) {
for (const AbstractMetaFunction *function : functions) {
if (function->arguments().size() == 0 && function->name() == class_name)
return true;
}
Expand Down
8 changes: 7 additions & 1 deletion generator/generator.pro
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ HEADERS += \
shellimplgenerator.h \
shellheadergenerator.h \
setupgenerator.h

SOURCES += \
generatorsetqtscript.cpp \
metaqtscriptbuilder.cpp \
Expand All @@ -22,3 +22,9 @@ SOURCES += \
shellimplgenerator.cpp \
shellheadergenerator.cpp \
setupgenerator.cpp

#The generate target is NOT built automatically!
QMAKE_EXTRA_TARGETS += generate

generate.depends = $$TARGET
generate.commands = ./$$TARGET --qt-headers="$$[QT_INSTALL_HEADERS]" --core-error --output-directory="."
1 change: 1 addition & 0 deletions generator/generatorsetqtscript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ void GeneratorSetQtScript::buildModel(const QString pp_file) {
ReportHandler::setContext("MetaJavaBuilder");
builder.setFileName(pp_file);
builder.build();
ReportHandler::setContext("After MetaJavaBuilder");
}

void GeneratorSetQtScript::dumpObjectTree() {
Expand Down
238 changes: 212 additions & 26 deletions generator/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,21 @@
void displayHelp(GeneratorSet *generatorSet);

#include <QDebug>

/* List of core modules to add to the build in order. */
static const char coreModuleListDefault[]{"Xml,Network,Core,Gui,OpenGL"};

int main(int argc, char *argv[])
{
ReportHandler::setContext("Parameters");
QScopedPointer<GeneratorSet> gs(GeneratorSet::getInstance());

QString default_file = ":/trolltech/generator/qtscript_masterinclude.h";
QString default_system = ":/trolltech/generator/build_all.txt";

QString fileName;
QString typesystemFileName;
QString pp_file = ".preprocessed.tmp";
const QString pp_file = "qtheaders.preprocessed.tmp";
QStringList rebuild_classes;

QMap<QString, QString> args;
Expand Down Expand Up @@ -132,57 +137,238 @@ int main(int argc, char *argv[])
if (!gs->readParameters(args))
displayHelp(&*gs);

ReportHandler::setContext("Files");

/* This used to be in main.h::preprocess however this makes it difficult to
* update the command line argument handling (because, unusually, it was
* split into two different places, one a header file!). This is the
* code form main.h:
*/
const bool minimal(args.contains("minimal"));
QStringList includes;
if (!minimal)
includes << QString(".");

// Environment INCLUDE
const QString includePath(getenv("INCLUDE"));
if (!includePath.isEmpty())
includes += includePath.split(QDir::listSeparator());

// Includes from the command line
const QString commandLineIncludes(args.value("include-paths"));
if (!commandLineIncludes.isEmpty())
includes += commandLineIncludes.split(QDir::listSeparator());

/* Allow coreModules to be specified on the command line (e.g. to add or
* remove modules for an application specific build).
*/
QString moduleList(args.value("core-modules"));
if (moduleList.isEmpty())
moduleList = coreModuleListDefault;
const QStringList coreModules(moduleList.split(","));
jbowler marked this conversation as resolved.
Show resolved Hide resolved

// Include Qt
QString qtHeaders(args.value("qt-headers"));

if (qtHeaders.isEmpty()) {
/* This is the legacy QTDIR approach. It requires Qt to be installed
* in a single directory which contains a subdirectory /include with
* all the expected header files (in module-specific sub-directories).
* There is a work-round for MacOS (recent versions) which understands
* the MacOS file system layout.
*
* TODO: remove this, require the directories to be specified on the
* command line.
*/
QString qtdir = getenv ("QTDIR");

if (qtdir.isEmpty()) {
#if defined(Q_OS_MAC)
qWarning(
"QTDIR environment variable not set. Assuming standard binary install using\n"
"frameworks.");
for (const QString &mod : coreModules)
includes << ("/Library/Frameworks/Qt" + mod + ".framework/Headers");
includes << "/Library/Frameworks"; // this seems wrong
#else
qWarning(
"QTDIR environment variable not set. This may cause problems with finding the\n"
"necessary include files. You can find the correct directory with the\n"
"command:\n\n"
" qmake -query QT_INSTALL_HEADERS\n\n"
"This directory can be supplied using the command line argument --qt-headers\n"
);
#endif
} else {
/* Legacy handling: Qt install into a single directory on its own,
* basically /opt/qt or something like that:
*/
qtHeaders = qtdir + "/include";
}
}

if (!qtHeaders.isEmpty()) {
/* Look for the 'standard' directories, favouring the first found
* in the qt-headers list.
*
* NOTE: use of a list here is intended for the project build workflows
* which apparently have to assemble the headers from different
* installation directories. This could be avoided by using
* --include-paths instead!
*
*/
QStringList dirList;
QStringList requiredModules(coreModules);

for (const QString &dir : qtHeaders.split(QDir::listSeparator()))
if (QDir(dir).exists()) {
QStringList remaining(requiredModules);

for (const QString &mod : requiredModules) {
const QString modpath(dir + "/Qt" + mod);
if (QDir(modpath).exists()) {
includes << modpath;
remaining.removeAll(mod);
}
}

requiredModules = remaining;
dirList << dir;
} else
qWarning((dir + " Qt header directory not found")
.toLocal8Bit().constData());

/* Add the top level directories at the end; this simulates the legacy
* behaviour.
*/
if (!minimal)
includes += dirList;

/* Warn if standard directories are not found: */
if (!requiredModules.isEmpty()) {
const QString errMsg("WARNING: missing core Qt modules: Qt" +
requiredModules.join(",Qt"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking: If you want it as before (with the space) you need join(", Qt")).


if (args.contains("core-error"))
qFatal(errMsg.toLocal8Bit().constData());
else
qWarning(errMsg.toLocal8Bit().constData());
}
} else if (includes.isEmpty()) {
/* This is never true unless --minimal is given because "." is always
* added to includes first.
*/
qWarning("No directories to scan: use --include-paths or --qt-headers");
displayHelp(&*gs);
mrbean-bremen marked this conversation as resolved.
Show resolved Hide resolved
}

std::cout << "-------------------------------------------------------------" << std::endl;
std::cout << "Scanning Qt headers from (in this order):" << std::endl;
for (const QString &dir : includes) {
std::cout << " " << dir.toUtf8().constData();
if (!QDir(dir).exists())
std::cout << " [DIRECTORY DOES NOT EXIST]";
std::cout << std::endl;
}
std::cout << "-------------------------------------------------------------" << std::endl;

printf("Please wait while source files are being generated...\n");

printf("Parsing typesystem file [%s]\n", qPrintable(typesystemFileName));
fflush(stdout);
jbowler marked this conversation as resolved.
Show resolved Hide resolved
ReportHandler::setContext(QString("Parse[%1]").arg(typesystemFileName));

if (!TypeDatabase::instance()->parseFile(typesystemFileName))
qFatal("Cannot parse file: '%s'", qPrintable(typesystemFileName));

printf("PreProcessing - Generate [%s] using [%s] and include-paths [%s]\n",
qPrintable(pp_file), qPrintable(fileName), qPrintable(args.value("include-paths")));
if (!Preprocess::preprocess(fileName, pp_file, args.value("include-paths"))) {
fprintf(stderr, "Preprocessor failed on file: '%s'\n", qPrintable(fileName));
qPrintable(pp_file), qPrintable(fileName),
qPrintable(args.value("include-paths")));
fflush(stdout);
ReportHandler::setContext(QString("Preprocess[%1]->[%2]")
.arg(fileName).arg(pp_file));

if (!Preprocess::preprocess(fileName, pp_file, includes)) {
fprintf(stderr, "Preprocessor failed on file: '%s'\n",
qPrintable(fileName));
return 1;
}

if (args.contains("ast-to-xml")) {
printf("Running ast-to-xml on file [%s] using pp_file [%s] and include-paths [%s]\n",
qPrintable(fileName), qPrintable(pp_file), qPrintable(args.value("include-paths")));
astToXML(pp_file);
return 0;
printf("Running ast-to-xml on file [%s] using pp_file [%s] and include-paths [%s]+[%s]\n",
qPrintable(fileName), qPrintable(pp_file),
qPrintable(includePath), qPrintable(commandLineIncludes));
fflush(stdout);
ReportHandler::setContext(QString("ast-to-xml[%1]([%2]+[%3])")
.arg(pp_file).arg(includePath).arg(commandLineIncludes));
astToXML(pp_file);
return 0;
}

printf("Building model using [%s]\n", qPrintable(pp_file));
fflush(stdout);
ReportHandler::setContext(QString("Model[%1]").arg(pp_file));
gs->buildModel(pp_file);
if (args.contains("dump-object-tree")) {
ReportHandler::setContext("dump-object-tree");
gs->dumpObjectTree();
return 0;
}

printf("Generate\n");
fflush(stdout);
ReportHandler::setContext("Generate");
printf("%s\n", qPrintable(gs->generate()));

printf("Done, %d warnings (%d known issues)\n", ReportHandler::warningCount(),
ReportHandler::suppressedCount());
ReportHandler::setContext("Finished");
printf("Done, %d warnings (%d known issues)\n",
ReportHandler::warningCount(),
ReportHandler::suppressedCount());
fflush(stdout);
}


void displayHelp(GeneratorSet* generatorSet) {
#if defined(Q_OS_WIN32)
char path_splitter = ';';
#else
char path_splitter = ':';
#endif
const QByteArray sep(QString(QDir::listSeparator()).toLocal8Bit());

printf("Usage:\n generator [options] header-file typesystem-file\n\n");
printf("Available options:\n\n");
printf("General:\n");
printf(" --debug-level=[sparse|medium|full] \n"
" --dump-object-tree \n"
" --help, -h or -? \n"
" --no-suppress-warnings \n"
" --output-directory=[dir] \n"
" --include-paths=<path>[%c<path>%c...] \n"
" --print-stdout \n",
path_splitter, path_splitter);

printf("%s", qPrintable( generatorSet->usage()));
exit(0);
printf(" --debug-level=[sparse|medium|full]\n"
" --dump-object-tree\n"
" --help, -h or -?\n"
" --no-suppress-warnings\n"
" --output-directory=[dir]\n"
" --include-paths=<path>[%s<path>%s...]\n"
" --qt-headers=<path>[%s<path>%s...]\n"
" --core-modules=module,...\n"
" --core-error\n"
" --minimal\n"
" --print-stdout\n\n",
sep.constData(), sep.constData(), sep.constData(), sep.constData());

printf("%s\n", qPrintable( generatorSet->usage()));

printf("Notes:\n"
" The location of the Qt header files to be used must be specified either by\n"
" a directory in --qt-headers or by the location of the Qt installation in\n"
" the environment variable QTDIR. The latter is equivalent to passing\n"
" $QT_DIR/include to --qt-headers.\n\n"
" --core-modules is a comma-separated list of Qt modules names without the\n"
" leading 'Qt'. Do not put spaces in the list. The headers directory is\n"
" used to locate these modules and they are added, in turn, to the end of\n"
" the list of directories to scan. The header directory itself is added at\n"
" the end unless --minimal is given. By default:\n\n"
" --core-modules=\"%s\"\n\n"
" If core modules fail to be found a warning is issued unless --core-error\n"
" is given in which case the generator exits with an error.\n\n"
" Additional directories to be scanned are passed in the environment\n"
" variable INCLUDE and the --include-paths argument. Both are '%s'\n"
" separated lists of directories which are scanned before the core module\n"
" directories in the order given.\n\n"
" The current working directory is also scanned (first) unless --minimal is\n"
" given.\n",
coreModuleListDefault, sep.constData());

exit(1);
}
Loading
Loading