pax_global_header00006660000000000000000000000064120661354520014516gustar00rootroot0000000000000052 comment=a00d71a09ddf960cf668211044dcf228a72d1883 qconf-1.5/000077500000000000000000000000001206613545200124715ustar00rootroot00000000000000qconf-1.5/AUTHORS000066400000000000000000000000451206613545200135400ustar00rootroot00000000000000Justin Karneges qconf-1.5/COPYING000066400000000000000000000365551206613545200135420ustar00rootroot00000000000000 As a special exception, Justin Karneges gives permission to link this program with the Qt Library (commercial or non-commercial edition), and distribute the resulting executable, without including the source code for the Qt library in the source distribution. Files generated by qconf (such as 'configure') are not considered to be a derived work of any of the input files used to create them, even though the input files might be included verbatim in the generated files. These generated files can be freely used and distributed and are not bound by the license terms below. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS qconf-1.5/README000066400000000000000000000103151206613545200133510ustar00rootroot00000000000000QConf v1.5 ---------- Date: May 30th, 2008 Website: http://delta.affinix.com/qconf/ Mailing List: Delta Project Author: Justin Karneges Description: QConf allows you to have a nice configure script for your qmake-based project. It is intended for developers who don't need (or want) to use the more complex GNU autotools. Scripts generated by QConf are meant for unix. This means it should only be used with projects based on Qt/X11, Qt/Mac, or Qt/Embedded. No effort has been made in supporting Qt/Windows based projects (yet). NOTE: QConf is a Qt 4 program as of version 1.2. However, it can still generate configure scripts for Qt 3 apps. See below for information. Using QConf is easy: 1) First, install qconf: $ ./configure $ make # make install 2) Now, create a project.qc file. It is in an XML format: MyProject <-- a friendly string project.pro <-- your qmake profile 3) Then run qconf on your file: $ qconf project.qc Assuming all goes well, this will output a 'configure' script. Simply copy this into your application package. Make sure to include(conf.pri) in your project.pro file. Tip: If qconf is launched with no arguments, it will use the first .qc file it can find in the current directory. If there is no .qc file, then it will look for a .pro file, and create a .qc for you based on it. Running 'configure': Once the configure script has been created, it is immediately usable. The script simply performs the following tasks: 1) Check for a proper Qt build environment. This is done by compiling the 'conf' program, which ensures that the Qt library, qmake, and necessary compiler tools are present and functioning. 2) 'conf' is launched, which does any needed dependency checking and creates a suitable conf.pri. This operation also ensures that not only can we successfully build Qt-based programs, but launch them as well. 3) qmake is invoked on the project's .pro file. Assuming configuration was a success, the Makefile should be generated and the user can now type 'make'. The script does not touch any of your project files. It is up to you to actually include conf.pri in your .pro file. Tip: Passing the '--verbose' option to configure can aid in diagnosing configuration problems. Q & A ----- Q: How do I specify dependencies? A: List them in your .qc file using the element. Follow sampledeps.qc for a hint. Q: My dependency is not supported! A: You will need to make it. Look in the 'modules' folder to see how it is done. If you find that you need to make a lot of these, perhaps you should consider GNU autotools. ;-) Q: How does qconf find modules? A: Modules are found in the 'modules' subdirectory within the configured libdir (default is /usr/local/share/qconf). Additional directories can be specified using the element. For instance: qcm would cause qconf to look for modules in the relative directory 'qcm'. This is useful if you want to bundle modules within your application distribution. Q: How do I perform custom processing or add project-specific arguments? A: The recommended way of doing this is to create an extra.qcm file that does the processing you need, and then just add it to your .qc file like any normal dependency. Implement checkString() in your module to return an empty QString if you want to suppress output. Q: How can I install more than just the binary with 'make install'? A: You need to specify the extra files using the qmake INSTALLS variable (see qmake docs for details). Q: What environment variables are available? A: Main variables: PREFIX, BINDIR, LIBDIR, QTDIR. All other variables are written as QC_FOO, where FOO is the option name in all caps. Boolean variables are set to 'Y' when flagged. Q: How do I generate scripts for Qt 3 projects? A: Include the element in the project's .qc file. Modules will not be able to take advantage of most new qconf features, and everything should work as they did with qconf 1.1. qconf-1.5/TODO000066400000000000000000000024531206613545200131650ustar00rootroot00000000000000Store last-used configure arguments in a config.status file. Don't generate conf.log, put that information in --verbose. make it possible to use relative paths as input? QConf can be considered complete. There are some todo items in this file, but they are not vital. I've added some rationale text for each one to explain why. - cross-compile? (set host / target arches) I haven't needed to cross-compile yet, so I haven't looked into this. Probably one can do it anyway by setting a bunch of environment variables, like CC, QMAKESPEC, etc. Maybe when we start seeing active Qt4/Embedded usage, this can be revisited, but even still it may not need to be explicitly supported. - turn .qc file into qmake-style format instead of xml? XML is human-readable and nice for application data interchange, but it isn't very nice to have to write by yourself. I'm using it only because I didn't want to write a parser. I generally hate it when applications require manual XML editing (I'm looking at you jabberd), and here I am committing the same offense. Fortunately, the XML files are usually only a handful of lines, and they work well enough ("if it ain't broke..."). Even so, I think it is worth looking into supporting an easy-to-write, flat-text format like what is used for qmake. qconf-1.5/conf/000077500000000000000000000000001206613545200134165ustar00rootroot00000000000000qconf-1.5/conf/conf.cpp000066400000000000000000000163451206613545200150600ustar00rootroot00000000000000/* Copyright (C) 2003-2008 Justin Karneges This file is free software; unlimited permission is given to copy and/or distribute it, with or without modifications, as long as this notice is preserved. */ #include #include #include #include #include #include #include #include #include #include class MocTestObject : public QObject { Q_OBJECT public: MocTestObject() {} }; class Conf; class ConfObj { public: ConfObj(Conf *c); virtual ~ConfObj(); virtual QString name() const=0; virtual QString shortname() const=0; virtual QString checkString() const; virtual QString resultString() const; virtual bool exec()=0; Conf *conf; bool required; bool disabled; }; typedef QPtrList ConfObjList; typedef QPtrListIterator ConfObjListIt; class Conf { public: Conf() : vars(17) { list.setAutoDelete(true); vars.setAutoDelete(true); vars.insert("QMAKE_INCDIR_X11", new QString(X11_INC)); vars.insert("QMAKE_LIBDIR_X11", new QString(X11_LIBDIR)); vars.insert("QMAKE_LIBS_X11", new QString(X11_LIB)); vars.insert("QMAKE_CC", new QString(CC)); vars.insert("QMAKE_CXX", new QString(CXX)); do_debug = false; done_debug = false; } ~Conf() { } void added(ConfObj *o) { list.append(o); } QString getenv(const QString &var) { char *p = ::getenv(var.latin1()); if(!p) return QString::null; return QString(p); } void debug(const QString &s) { if(do_debug) { if(!done_debug) printf("\n"); done_debug = true; printf(" * %s\n", s.latin1()); } } bool exec() { if(getenv("QC_VERBOSE") == "Y") do_debug = true; ConfObjListIt it(list); for(ConfObj *o; (o = it.current()); ++it) { // if this was a disabled-by-default option, check if it was enabled if(o->disabled) { QString v = QString("QC_ENABLE_") + o->shortname(); if(getenv(v) != "Y") continue; } // and the opposite? else { QString v = QString("QC_DISABLE_") + o->shortname(); if(getenv(v) == "Y") continue; } QString check = o->checkString(); if(check.isEmpty()) check = QString("Checking for %1 ...").arg(o->name()); printf("%s", check.latin1()); fflush(stdout); done_debug = false; bool ok = o->exec(); QString result = o->resultString(); if(result.isEmpty()) { if(ok) result = "yes"; else result = "no"; } if(done_debug) printf(" -> %s\n", result.latin1()); else printf(" %s\n", result.latin1()); if(!ok && o->required) { printf("\nError: need %s!\n", o->name().latin1()); return false; } } return true; } const QString & qvar(const QString &s) { QString *p = vars.find(s); if(p) return *p; else return blank; } QString expandIncludes(const QString &inc) { return QString("-I") + inc; } QString expandLibs(const QString &lib) { return QString("-L") + lib; } int doCommand(const QString &s) { debug(QString("[%1]").arg(s)); QString fullcmd; if(do_debug) fullcmd = s; else fullcmd = s + " 1>/dev/null 2>/dev/null"; int r = system(fullcmd.latin1()); debug(QString("returned: %1").arg(r)); return r; } bool doCompileAndLink(const QString &filedata, const QString &flags, int *retcode=0) { QDir dir("."); QString fname = "atest.c"; QString out = "atest"; QFile f(fname); QCString cs = filedata.latin1(); if(!f.open(IO_WriteOnly | IO_Truncate)) { debug("unable to open atest.c for writing"); return false; } if(f.writeBlock(cs.data(), cs.length()) == -1) { debug("error writing to atest.c"); return false; } f.close(); debug(QString("Wrote atest.c:\n%1").arg(filedata)); QString str = qvar("QMAKE_CXX") + ' ' + fname + " -o " + out; if(!flags.isEmpty()) { str += ' '; str += flags; } int r = doCommand(str); if(r == 0 && retcode) *retcode = doCommand(QString("./") + out); dir.remove(fname); dir.remove(out); if(r != 0) return false; return true; } bool checkHeader(const QString &path, const QString &h) { QFileInfo fi(path + '/' + h); if(fi.exists()) return true; return false; } bool findHeader(const QString &h, const QStringList &ext, QString *inc) { if(checkHeader("/usr/include", h)) { *inc = ""; return true; } QStringList dirs; dirs += "/usr/local/include"; dirs += ext; for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) { if(checkHeader(*it, h)) { *inc = *it; return true; } } return false; } bool checkLibrary(const QString &path, const QString &name) { QString str = "int main()\n" "{\n" " return 0;\n" "}\n"; QString extra; if(!path.isEmpty()) extra += QString("-L") + path + ' '; extra += QString("-l") + name; if(!doCompileAndLink(str, extra)) return false; return true; } bool findLibrary(const QString &name, QString *lib) { if(checkLibrary("", name)) { *lib = ""; return true; } if(checkLibrary("/usr/local/lib", name)) { *lib = "/usr/local/lib"; return true; } return false; } void addDefine(const QString &str) { if(DEFINES.isEmpty()) DEFINES = str; else DEFINES += QString(" ") + str; debug(QString("DEFINES += %1").arg(str)); } void addLib(const QString &str) { if(LIBS.isEmpty()) LIBS = str; else LIBS += QString(" ") + str; debug(QString("LIBS += %1").arg(str)); } void addIncludePath(const QString &str) { if(INCLUDEPATH.isEmpty()) INCLUDEPATH = str; else INCLUDEPATH += QString(" ") + str; debug(QString("INCLUDEPATH += %1").arg(str)); } void addExtra(const QString &str) { extra += str + '\n'; debug(QString("extra += %1").arg(str)); } QString DEFINES; QString INCLUDEPATH; QString LIBS; QString extra; private: ConfObjList list; QDict vars; QString blank; bool do_debug, done_debug; }; ConfObj::ConfObj(Conf *c) { conf = c; conf->added(this); required = false; disabled = false; } ConfObj::~ConfObj() { } QString ConfObj::checkString() const { return QString(); } QString ConfObj::resultString() const { return QString(); } #include"modules.cpp" //---------------------------------------------------------------------------- // main //---------------------------------------------------------------------------- int main() { Conf *conf = new Conf; ConfObj *o; o = 0; #include"modules_new.cpp" printf("ok\n"); bool success = false; if(conf->exec()) { QFile f("conf.pri"); if(!f.open(IO_WriteOnly | IO_Truncate)) { printf("Error writing %s\n", f.name().latin1()); return 1; } QString str; str += "# qconf\n"; str += "QT_PATH_PLUGINS = " + QString(qInstallPathPlugins()) + '\n'; if(!conf->DEFINES.isEmpty()) str += "DEFINES += " + conf->DEFINES + '\n'; if(!conf->INCLUDEPATH.isEmpty()) str += "INCLUDEPATH += " + conf->INCLUDEPATH + '\n'; if(!conf->LIBS.isEmpty()) str += "LIBS += " + conf->LIBS + '\n'; if(!conf->extra.isEmpty()) str += conf->extra; str += '\n'; char *p = getenv("BINDIR"); if(p) { str += QString("target.path = ") + p + '\n'; str += "INSTALLS += target\n"; } QCString cs = str.latin1(); f.writeBlock(cs.data(), cs.length()); f.close(); success = true; } delete conf; if(success) return 0; else return 1; } #include"conf.moc" qconf-1.5/conf/conf.pro000066400000000000000000000004161206613545200150660ustar00rootroot00000000000000TEMPLATE = app CONFIG += qt x11 thread console TARGET = conf DEFINES += X11_INC='"$$QMAKE_INCDIR_X11"' DEFINES += X11_LIBDIR='"$$QMAKE_LIBDIR_X11"' DEFINES += X11_LIB='"$$QMAKE_LIBS_X11"' DEFINES += CC='"$$QMAKE_CC"' DEFINES += CXX='"$$QMAKE_CXX"' SOURCES += conf.cpp qconf-1.5/conf/conf4.cpp000066400000000000000000000443001206613545200151340ustar00rootroot00000000000000/* Copyright (C) 2004-2008 Justin Karneges This file is free software; unlimited permission is given to copy and/or distribute it, with or without modifications, as long as this notice is preserved. */ #include "conf4.h" #include #include class MocTestObject : public QObject { Q_OBJECT public: MocTestObject() {} }; QString qc_getenv(const QString &var) { char *p = ::getenv(var.toLatin1().data()); if(!p) return QString(); return QString(p); } QStringList qc_pathlist() { QStringList list; QString path = qc_getenv("PATH"); if(!path.isEmpty()) { #ifdef Q_OS_WIN list = path.split(';', QString::SkipEmptyParts); #else list = path.split(':', QString::SkipEmptyParts); #endif } #ifdef Q_OS_WIN list.prepend("."); #endif return list; } QString qc_findprogram(const QString &prog) { QString out; QStringList list = qc_pathlist(); for(int n = 0; n < list.count(); ++n) { QFileInfo fi(list[n] + '/' + prog); if(fi.exists() && fi.isExecutable()) { out = fi.filePath(); break; } #ifdef Q_OS_WIN // on windows, be sure to look for .exe if(prog.right(4).toLower() != ".exe") { fi = QFileInfo(list[n] + '/' + prog + ".exe"); if(fi.exists() && fi.isExecutable()) { out = fi.filePath(); break; } } #endif } return out; } QString qc_findself(const QString &argv0) { #ifdef Q_OS_WIN if(argv0.contains('\\\\')) #else if(argv0.contains('/')) #endif return argv0; else return qc_findprogram(argv0); } int qc_run_program_or_command(const QString &prog, const QStringList &args, const QString &command, QByteArray *out, bool showOutput) { if(out) out->clear(); QProcess process; process.setReadChannel(QProcess::StandardOutput); if(!prog.isEmpty()) process.start(prog, args); else if(!command.isEmpty()) process.start(command); else return -1; if(!process.waitForStarted(-1)) return -1; QByteArray buf; while(process.waitForReadyRead(-1)) { buf = process.readAllStandardOutput(); if(out) out->append(buf); if(showOutput) fprintf(stdout, "%s", buf.data()); buf = process.readAllStandardError(); if(showOutput) fprintf(stderr, "%s", buf.data()); } buf = process.readAllStandardError(); if(showOutput) fprintf(stderr, "%s", buf.data()); // calling waitForReadyRead will cause the process to eventually be // marked as finished, so we should not need to separately call // waitForFinished. however, we will do it anyway just to be safe. // we won't check the return value since false could still mean // success (if the process had already been marked as finished). process.waitForFinished(-1); if(process.exitStatus() != QProcess::NormalExit) return -1; return process.exitCode(); } int qc_runcommand(const QString &command, QByteArray *out, bool showOutput) { return qc_run_program_or_command(QString(), QStringList(), command, out, showOutput); } int qc_runprogram(const QString &prog, const QStringList &args, QByteArray *out, bool showOutput) { return qc_run_program_or_command(prog, args, QString(), out, showOutput); } bool qc_removedir(const QString &dirPath) { QDir dir(dirPath); if(!dir.exists()) return false; QStringList list = dir.entryList(); foreach(QString s, list) { if(s == "." || s == "..") continue; QFileInfo fi(dir.filePath(s)); if(fi.isDir()) { if(!qc_removedir(fi.filePath())) return false; } else { if(!dir.remove(s)) return false; } } QString dirName = dir.dirName(); if(!dir.cdUp()) return false; if(!dir.rmdir(dirName)) return false; return true; } void qc_splitcflags(const QString &cflags, QStringList *incs, QStringList *otherflags) { incs->clear(); otherflags->clear(); QStringList cflagsList = cflags.split(" "); for(int n = 0; n < cflagsList.count(); ++n) { QString str = cflagsList[n]; if(str.startsWith("-I")) { // we want everything except the leading "-I" incs->append(str.remove(0, 2)); } else { // we want whatever is left otherflags->append(str); } } } QString qc_escapeArg(const QString &str) { QString out; for(int n = 0; n < (int)str.length(); ++n) { if(str[n] == '-') out += '_'; else out += str[n]; } return out; } //---------------------------------------------------------------------------- // ConfObj //---------------------------------------------------------------------------- ConfObj::ConfObj(Conf *c) { conf = c; conf->added(this); required = false; disabled = false; success = false; } ConfObj::~ConfObj() { } QString ConfObj::checkString() const { return QString("Checking for %1 ...").arg(name()); } QString ConfObj::resultString() const { if(success) return "yes"; else return "no"; } //---------------------------------------------------------------------------- // qc_internal_pkgconfig //---------------------------------------------------------------------------- class qc_internal_pkgconfig : public ConfObj { public: QString pkgname, desc; VersionMode mode; QString req_ver; qc_internal_pkgconfig(Conf *c, const QString &_name, const QString &_desc, VersionMode _mode, const QString &_req_ver) : ConfObj(c) { pkgname = _name; desc = _desc; mode = _mode; req_ver = _req_ver; } QString name() const { return desc; } QString shortname() const { return pkgname; } bool exec() { QStringList incs; QString version, libs, other; if(!conf->findPkgConfig(pkgname, mode, req_ver, &version, &incs, &libs, &other)) return false; for(int n = 0; n < incs.count(); ++n) conf->addIncludePath(incs[n]); if(!libs.isEmpty()) conf->addLib(libs); //if(!other.isEmpty()) // conf->addExtra(QString("QMAKE_CFLAGS += %1\n").arg(other)); return true; } }; //---------------------------------------------------------------------------- // Conf //---------------------------------------------------------------------------- Conf::Conf() { // TODO: no more vars? //vars.insert("QMAKE_INCDIR_X11", new QString(X11_INC)); //vars.insert("QMAKE_LIBDIR_X11", new QString(X11_LIBDIR)); //vars.insert("QMAKE_LIBS_X11", new QString(X11_LIB)); //vars.insert("QMAKE_CC", CC); debug_enabled = false; } Conf::~Conf() { qDeleteAll(list); } void Conf::added(ConfObj *o) { list.append(o); } QString Conf::getenv(const QString &var) { return qc_getenv(var); } void Conf::debug(const QString &s) { if(debug_enabled) { if(first_debug) printf("\n"); first_debug = false; printf(" * %s\n", qPrintable(s)); } } bool Conf::exec() { for(int n = 0; n < list.count(); ++n) { ConfObj *o = list[n]; // if this was a disabled-by-default option, check if it was enabled if(o->disabled) { QString v = QString("QC_ENABLE_") + qc_escapeArg(o->shortname()); if(getenv(v) != "Y") continue; } // and the opposite? else { QString v = QString("QC_DISABLE_") + qc_escapeArg(o->shortname()); if(getenv(v) == "Y") continue; } bool output = true; QString check = o->checkString(); if(check.isEmpty()) output = false; if(output) { printf("%s", check.toLatin1().data()); fflush(stdout); } first_debug = true; bool ok = o->exec(); o->success = ok; if(output) { QString result = o->resultString(); if(!first_debug) printf(" -> %s\n", result.toLatin1().data()); else printf(" %s\n", result.toLatin1().data()); } if(!ok && o->required) { printf("\nError: need %s!\n", o->name().toLatin1().data()); return false; } } return true; } QString Conf::qvar(const QString &s) { return vars.value(s); } QString Conf::expandIncludes(const QString &inc) { return QString("-I") + inc; } QString Conf::expandLibs(const QString &lib) { return QString("-L") + lib; } int Conf::doCommand(const QString &s, QByteArray *out) { debug(QString("[%1]").arg(s)); int r = qc_runcommand(s, out, debug_enabled); debug(QString("returned: %1").arg(r)); return r; } int Conf::doCommand(const QString &prog, const QStringList &args, QByteArray *out) { QString fullcmd = prog; QString argstr = args.join(" "); if(!argstr.isEmpty()) fullcmd += QString(" ") + argstr; debug(QString("[%1]").arg(fullcmd)); int r = qc_runprogram(prog, args, out, debug_enabled); debug(QString("returned: %1").arg(r)); return r; } bool Conf::doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode) { #ifdef Q_OS_WIN QDir tmp("qconftemp"); #else QDir tmp(".qconftemp"); #endif if(!tmp.mkdir("atest")) { debug("unable to create atest dir"); return false; } QDir dir(tmp.filePath("atest")); if(!dir.exists()) { debug("atest dir does not exist"); return false; } QString fname = dir.filePath("atest.cpp"); QString out = "atest"; QFile f(fname); if(!f.open(QFile::WriteOnly | QFile::Truncate)) { debug("unable to open atest.cpp for writing"); return false; } if(f.write(filedata.toLatin1()) == -1) { debug("error writing to atest.cpp"); return false; } f.close(); debug(QString("Wrote atest.cpp:\n%1").arg(filedata)); QString pro = QString( "CONFIG += console\n" "CONFIG -= qt app_bundle\n" "DESTDIR = $$PWD\n" "SOURCES += atest.cpp\n"); QString inc = incs.join(" "); if(!inc.isEmpty()) pro += "INCLUDEPATH += " + inc + '\n'; if(!libs.isEmpty()) pro += "LIBS += " + libs + '\n'; pro += proextra; fname = dir.filePath("atest.pro"); f.setFileName(fname); if(!f.open(QFile::WriteOnly | QFile::Truncate)) { debug("unable to open atest.pro for writing"); return false; } if(f.write(pro.toLatin1()) == -1) { debug("error writing to atest.pro"); return false; } f.close(); debug(QString("Wrote atest.pro:\n%1").arg(pro)); QString oldpath = QDir::currentPath(); QDir::setCurrent(dir.path()); bool ok = false; int r = doCommand(qmake_path, QStringList() << "atest.pro"); if(r == 0) { r = doCommand(maketool, QStringList()); if(r == 0) { ok = true; if(retcode) { QString runatest = out; #ifdef Q_OS_UNIX runatest.prepend("./"); #endif *retcode = doCommand(runatest, QStringList()); } } r = doCommand(maketool, QStringList() << "distclean"); if(r != 0) debug("error during atest distclean"); } QDir::setCurrent(oldpath); // cleanup //dir.remove("atest.pro"); //dir.remove("atest.cpp"); //tmp.rmdir("atest"); // remove whole dir since distclean doesn't always work qc_removedir(tmp.filePath("atest")); if(!ok) return false; return true; } bool Conf::checkHeader(const QString &path, const QString &h) { QFileInfo fi(path + '/' + h); if(fi.exists()) return true; return false; } bool Conf::findHeader(const QString &h, const QStringList &ext, QString *inc) { if(checkHeader("/usr/include", h)) { *inc = ""; return true; } QStringList dirs; dirs += "/usr/local/include"; dirs += ext; for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) { if(checkHeader(*it, h)) { *inc = *it; return true; } } return false; } bool Conf::checkLibrary(const QString &path, const QString &name) { QString str = //"#include \n" "int main()\n" "{\n" //" printf(\"library checker running\\\\n\");\n" " return 0;\n" "}\n"; QString libs; if(!path.isEmpty()) libs += QString("-L") + path + ' '; libs += QString("-l") + name; if(!doCompileAndLink(str, QStringList(), libs, QString())) return false; return true; } bool Conf::findLibrary(const QString &name, QString *lib) { if(checkLibrary("", name)) { *lib = ""; return true; } if(checkLibrary("/usr/local/lib", name)) { *lib = "/usr/local/lib"; return true; } return false; } QString Conf::findProgram(const QString &prog) { return qc_findprogram(prog); } bool Conf::findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs) { QString inc, lib; QString s; s = getenv(incvar); if(!s.isEmpty()) { if(!checkHeader(s, incname)) return false; inc = s; } else { if(!findHeader(incname, QStringList(), &s)) return false; inc = s; } s = getenv(libvar); if(!s.isEmpty()) { if(!checkLibrary(s, libname)) return false; lib = s; } else { if(!findLibrary(libname, &s)) return false; lib = s; } QString lib_out; if(!lib.isEmpty()) lib_out += QString("-L") + s; lib_out += QString("-l") + libname; *incpath = inc; *libs = lib_out; return true; } bool Conf::findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags) { QStringList args; QByteArray out; int ret; args += "--version"; ret = doCommand(path, args, &out); if(ret != 0) return false; QString version_out = QString::fromLatin1(out).trimmed(); args.clear(); args += "--libs"; ret = doCommand(path, args, &out); if(ret != 0) return false; QString libs_out = QString::fromLatin1(out).trimmed(); args.clear(); args += "--cflags"; ret = doCommand(path, args, &out); if(ret != 0) return false; QString cflags = QString::fromLatin1(out).trimmed(); QStringList incs_out, otherflags_out; qc_splitcflags(cflags, &incs_out, &otherflags_out); *version = version_out; *incs = incs_out; *libs = libs_out; *otherflags = otherflags_out.join(" "); return true; } bool Conf::findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags) { QStringList args; QByteArray out; int ret; args += name; args += "--exists"; ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; if(mode != VersionAny) { args.clear(); args += name; if(mode == VersionMin) args += QString("--atleast-version=%1").arg(req_version); else if(mode == VersionMax) args += QString("--max-version=%1").arg(req_version); else args += QString("--exact-version=%1").arg(req_version); ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; } args.clear(); args += name; args += "--modversion"; ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; QString version_out = QString::fromLatin1(out).trimmed(); args.clear(); args += name; args += "--libs"; ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; QString libs_out = QString::fromLatin1(out).trimmed(); args.clear(); args += name; args += "--cflags"; ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; QString cflags = QString::fromLatin1(out).trimmed(); QStringList incs_out, otherflags_out; qc_splitcflags(cflags, &incs_out, &otherflags_out); *version = version_out; *incs = incs_out; *libs = libs_out; *otherflags = otherflags_out.join(" "); return true; } void Conf::addDefine(const QString &str) { if(DEFINES.isEmpty()) DEFINES = str; else DEFINES += QString(" ") + str; debug(QString("DEFINES += %1").arg(str)); } void Conf::addLib(const QString &str) { if(LIBS.isEmpty()) LIBS = str; else LIBS += QString(" ") + str; debug(QString("LIBS += %1").arg(str)); } void Conf::addIncludePath(const QString &str) { if(INCLUDEPATH.isEmpty()) INCLUDEPATH = str; else INCLUDEPATH += QString(" ") + str; debug(QString("INCLUDEPATH += %1").arg(str)); } void Conf::addExtra(const QString &str) { extra += str + '\n'; debug(QString("extra += %1").arg(str)); } //---------------------------------------------------------------------------- // main //---------------------------------------------------------------------------- #include "conf4.moc" #ifdef HAVE_MODULES # include"modules.cpp" #endif int main() { Conf *conf = new Conf; ConfObj *o = 0; Q_UNUSED(o); #ifdef HAVE_MODULES # include"modules_new.cpp" #endif conf->debug_enabled = (qc_getenv("QC_VERBOSE") == "Y") ? true: false; if(conf->debug_enabled) printf(" -> ok\n"); else printf("ok\n"); QString confCommand = qc_getenv("QC_COMMAND"); QString proName = qc_getenv("QC_PROFILE"); conf->qmake_path = qc_getenv("QC_QMAKE"); conf->qmakespec = qc_getenv("QC_QMAKESPEC"); conf->maketool = qc_getenv("QC_MAKETOOL"); if(conf->debug_enabled) printf("conf command: [%s]\n", qPrintable(confCommand)); QString confPath = qc_findself(confCommand); if(confPath.isEmpty()) { printf("Error: cannot find myself; rerun with an absolute path\n"); return 1; } QString srcdir = QFileInfo(confPath).absolutePath(); QString builddir = QDir::current().absolutePath(); QString proPath = QDir(srcdir).filePath(proName); if(conf->debug_enabled) { printf("conf path: [%s]\n", qPrintable(confPath)); printf("srcdir: [%s]\n", qPrintable(srcdir)); printf("builddir: [%s]\n", qPrintable(builddir)); printf("profile: [%s]\n", qPrintable(proPath)); printf("qmake path: [%s]\n", qPrintable(conf->qmake_path)); printf("qmakespec: [%s]\n", qPrintable(conf->qmakespec)); printf("make tool: [%s]\n", qPrintable(conf->maketool)); printf("\n"); } bool success = false; if(conf->exec()) { QFile f("conf.pri"); if(!f.open(QFile::WriteOnly | QFile::Truncate)) { printf("Error writing %s\n", qPrintable(f.fileName())); return 1; } QString str; str += "# qconf\n\n"; QString var; var = qc_getenv("PREFIX"); if(!var.isEmpty()) str += QString("PREFIX = %1\n").arg(var); var = qc_getenv("BINDIR"); if(!var.isEmpty()) str += QString("BINDIR = %1\n").arg(var); var = qc_getenv("INCDIR"); if(!var.isEmpty()) str += QString("INCDIR = %1\n").arg(var); var = qc_getenv("LIBDIR"); if(!var.isEmpty()) str += QString("LIBDIR = %1\n").arg(var); var = qc_getenv("DATADIR"); if(!var.isEmpty()) str += QString("DATADIR = %1\n").arg(var); str += '\n'; if(qc_getenv("QC_STATIC") == "Y") str += "CONFIG += staticlib\n"; // TODO: don't need this? //str += "QT_PATH_PLUGINS = " + QString(qInstallPathPlugins()) + '\n'; if(!conf->DEFINES.isEmpty()) str += "DEFINES += " + conf->DEFINES + '\n'; if(!conf->INCLUDEPATH.isEmpty()) str += "INCLUDEPATH += " + conf->INCLUDEPATH + '\n'; if(!conf->LIBS.isEmpty()) str += "LIBS += " + conf->LIBS + '\n'; if(!conf->extra.isEmpty()) str += conf->extra; str += '\n'; QByteArray cs = str.toLatin1(); f.write(cs); f.close(); success = true; } QString qmake_path = conf->qmake_path; QString qmakespec = conf->qmakespec; delete conf; if(!success) return 1; // run qmake on the project file QStringList args; if(!qmakespec.isEmpty()) { args += "-spec"; args += qmakespec; } args += proPath; int ret = qc_runprogram(qmake_path, args, 0, true); if(ret != 0) return 1; return 0; } qconf-1.5/conf/conf4.h000066400000000000000000000054771206613545200146150ustar00rootroot00000000000000/* Copyright (C) 2004-2008 Justin Karneges This file is free software; unlimited permission is given to copy and/or distribute it, with or without modifications, as long as this notice is preserved. */ #ifndef QC_CONF4_H #define QC_CONF4_H #include class Conf; enum VersionMode { VersionMin, VersionExact, VersionMax, VersionAny }; // ConfObj // // Subclass ConfObj to create a new configuration module. class ConfObj { public: Conf *conf; bool required; bool disabled; bool success; ConfObj(Conf *c); virtual ~ConfObj(); // long or descriptive name of what is being checked/performed // example: "KDE >= 3.3" virtual QString name() const = 0; // short name // example: "kde" virtual QString shortname() const = 0; // string to display during check // default: "Checking for [name] ..." virtual QString checkString() const; // string to display after check // default: "yes" or "no", based on result of exec() virtual QString resultString() const; // this is where the checking code goes virtual bool exec() = 0; }; // Conf // // Interact with this class from your ConfObj to perform detection // operations and to output configuration parameters. class Conf { public: bool debug_enabled; QString qmake_path; QString qmakespec; QString maketool; QString DEFINES; QString INCLUDEPATH; QString LIBS; QString extra; QList list; QMap vars; Conf(); ~Conf(); QString getenv(const QString &var); QString qvar(const QString &s); bool exec(); void debug(const QString &s); QString expandIncludes(const QString &inc); QString expandLibs(const QString &lib); int doCommand(const QString &s, QByteArray *out = 0); int doCommand(const QString &prog, const QStringList &args, QByteArray *out = 0); bool doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode = 0); bool checkHeader(const QString &path, const QString &h); bool findHeader(const QString &h, const QStringList &ext, QString *inc); bool checkLibrary(const QString &path, const QString &name); bool findLibrary(const QString &name, QString *lib); QString findProgram(const QString &prog); bool findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs); bool findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags); bool findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags); void addDefine(const QString &str); void addLib(const QString &str); void addIncludePath(const QString &str); void addExtra(const QString &str); private: bool first_debug; friend class ConfObj; void added(ConfObj *o); }; #endif qconf-1.5/conf/conf4.pro000066400000000000000000000002031206613545200151440ustar00rootroot00000000000000CONFIG += console CONFIG -= app_bundle QT -= gui TARGET = conf DESTDIR = $$PWD HEADERS += conf4.h SOURCES += conf4.cpp qconf-1.5/configure000077500000000000000000000705771206613545200144200ustar00rootroot00000000000000#!/bin/sh # # Generated by qconf 1.5 ( http://delta.affinix.com/qconf/ ) # show_usage() { cat </dev/null` if echo $WHICH | grep 'shell built-in command' >/dev/null 2>&1; then WHICH=which elif [ -z "$WHICH" ]; then if which which >/dev/null 2>&1; then WHICH=which else for a in /usr/ucb /usr/bin /bin /usr/local/bin; do if [ -x $a/which ]; then WHICH=$a/which break; fi done fi fi if [ -z "$WHICH" ]; then OLD_IFS=$IFS IFS=: for a in $PATH; do if [ -x $a/$1 ]; then echo "$a/$1" IFS=$OLD_IFS export IFS HOME=$OLD_HOME export HOME return 0 fi done IFS=$OLD_IFS export IFS else a=`"$WHICH" "$1" 2>/dev/null` if [ ! -z "$a" -a -x "$a" ]; then echo "$a" HOME=$OLD_HOME export HOME return 0 fi fi HOME=$OLD_HOME export HOME return 1 } WHICH=which_command # find a make command if [ -z "$MAKE" ]; then MAKE= for mk in gmake make; do if $WHICH $mk >/dev/null 2>&1; then MAKE=`$WHICH $mk` break fi done if [ -z "$MAKE" ]; then echo "You don't seem to have 'make' or 'gmake' in your PATH." echo "Cannot proceed." exit 1 fi fi show_qt_info() { printf "Be sure you have a proper Qt 4.0 build environment set up. This means not\n" printf "just Qt, but also a C++ compiler, a make tool, and any other packages\n" printf "necessary for compiling C++ programs.\n" printf "\n" printf "If you are certain everything is installed, then it could be that Qt 4 is not\n" printf "being recognized or that a different version of Qt is being detected by\n" printf "mistake (for example, this could happen if \$QTDIR is pointing to a Qt 3\n" printf "installation). At least one of the following conditions must be satisfied:\n" printf "\n" printf " 1) --qtdir is set to the location of Qt\n" printf " 2) \$QTDIR is set to the location of Qt\n" printf " 3) QtCore is in the pkg-config database\n" printf " 4) qmake is in the \$PATH\n" printf "\n" printf "This script will use the first one it finds to be true, checked in the above\n" printf "order. #3 and #4 are the recommended options. #1 and #2 are mainly for\n" printf "overriding the system configuration.\n" printf "\n" } while [ $# -gt 0 ]; do optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` case "$1" in --prefix=*) PREFIX=$optarg shift ;; --bindir=*) BINDIR=$optarg shift ;; --datadir=*) DATADIR=$optarg shift ;; --qtdir=*) EX_QTDIR=$optarg shift ;; --verbose) QC_VERBOSE="Y" shift ;; --help) show_usage; exit ;; *) show_usage; exit ;; esac done PREFIX=${PREFIX:-/usr/local} BINDIR=${BINDIR:-$PREFIX/bin} DATADIR=${DATADIR:-$PREFIX/share} echo "Configuring QConf ..." if [ "$QC_VERBOSE" = "Y" ]; then echo echo PREFIX=$PREFIX echo BINDIR=$BINDIR echo DATADIR=$DATADIR echo EX_QTDIR=$EX_QTDIR echo fi printf "Verifying Qt 4 build environment ... " # run qmake -v and check version qmake_check_v4() { if [ -x "$1" ]; then local v=`$1 -query QT_VERSION 2>&1` vmaj="${v%%.*}" case "${v}" in ?.?.?) [ "$vmaj" = 4 -o "$vmaj" = 5 ] && return 0 ;; esac if [ "$QC_VERBOSE" = "Y" ]; then echo "Warning: $1 not for Qt 4 or 5" fi fi return 1 } if [ "$QC_VERBOSE" = "Y" ]; then echo fi qm="" names="qmake-qt4 qmake4 qmake" # qt4 check: --qtdir if [ -z "$qm" ] && [ ! -z "$EX_QTDIR" ]; then for n in $names; do qstr=$EX_QTDIR/bin/$n if qmake_check_v4 "$qstr"; then qm=$qstr break; fi done fi if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then echo "Warning: qmake not found via --qtdir" fi # qt4 check: QTDIR if [ -z "$qm" ] && [ ! -z "$QTDIR" ]; then for n in $names; do qstr=$QTDIR/bin/$n if qmake_check_v4 "$qstr"; then qm=$qstr break; fi done fi if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then echo "Warning: qmake not found via \$QTDIR" fi # qt4 check: pkg-config if [ -z "$qm" ]; then str=`pkg-config QtCore --variable=exec_prefix 2>/dev/null` if [ ! -z "$str" ]; then for n in $names; do qstr=$str/bin/$n if qmake_check_v4 "$qstr"; then qm=$qstr break; fi done fi fi if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then echo "Warning: qmake not found via pkg-config" fi # qt4 check: PATH if [ -z "$qm" ]; then for n in $names; do qstr=`$WHICH $n 2>/dev/null` if qmake_check_v4 "$qstr"; then qm=$qstr break; fi done fi if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then echo "Warning: qmake not found via \$PATH" fi if [ -z "$qm" ]; then if [ "$QC_VERBOSE" = "Y" ]; then echo " -> fail" else echo "fail" fi printf "\n" printf "Reason: Unable to find the 'qmake' tool for Qt 4.\n" printf "\n" show_qt_info exit 1; fi if [ "$QC_VERBOSE" = "Y" ]; then echo qmake found in $qm fi # try to determine the active makespec defmakespec=$QMAKESPEC if [ -z "$defmakespec" ]; then if $WHICH readlink >/dev/null 2>&1; then READLINK=`$WHICH readlink` fi if [ ! -z "$READLINK" ]; then qt_mkspecsdir=`$qm -query QT_INSTALL_DATA`/mkspecs if [ -d "$qt_mkspecsdir" ] && [ -h "$qt_mkspecsdir/default" ]; then defmakespec=`$READLINK $qt_mkspecsdir/default` fi fi fi if [ "$QC_VERBOSE" = "Y" ]; then echo makespec is $defmakespec fi qm_spec="" # if the makespec is macx-xcode, force macx-g++ if [ "$defmakespec" = "macx-xcode" ]; then qm_spec=macx-g++ QMAKESPEC=$qm_spec export QMAKESPEC if [ "$QC_VERBOSE" = "Y" ]; then echo overriding makespec to $qm_spec fi fi gen_files() { cat >$1/modules.cpp <$1/modules_new.cpp <$1/conf4.h < class Conf; enum VersionMode { VersionMin, VersionExact, VersionMax, VersionAny }; // ConfObj // // Subclass ConfObj to create a new configuration module. class ConfObj { public: Conf *conf; bool required; bool disabled; bool success; ConfObj(Conf *c); virtual ~ConfObj(); // long or descriptive name of what is being checked/performed // example: "KDE >= 3.3" virtual QString name() const = 0; // short name // example: "kde" virtual QString shortname() const = 0; // string to display during check // default: "Checking for [name] ..." virtual QString checkString() const; // string to display after check // default: "yes" or "no", based on result of exec() virtual QString resultString() const; // this is where the checking code goes virtual bool exec() = 0; }; // Conf // // Interact with this class from your ConfObj to perform detection // operations and to output configuration parameters. class Conf { public: bool debug_enabled; QString qmake_path; QString qmakespec; QString maketool; QString DEFINES; QString INCLUDEPATH; QString LIBS; QString extra; QList list; QMap vars; Conf(); ~Conf(); QString getenv(const QString &var); QString qvar(const QString &s); bool exec(); void debug(const QString &s); QString expandIncludes(const QString &inc); QString expandLibs(const QString &lib); int doCommand(const QString &s, QByteArray *out = 0); int doCommand(const QString &prog, const QStringList &args, QByteArray *out = 0); bool doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode = 0); bool checkHeader(const QString &path, const QString &h); bool findHeader(const QString &h, const QStringList &ext, QString *inc); bool checkLibrary(const QString &path, const QString &name); bool findLibrary(const QString &name, QString *lib); QString findProgram(const QString &prog); bool findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs); bool findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags); bool findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags); void addDefine(const QString &str); void addLib(const QString &str); void addIncludePath(const QString &str); void addExtra(const QString &str); private: bool first_debug; friend class ConfObj; void added(ConfObj *o); }; #endif EOT cat >$1/conf4.cpp < #include class MocTestObject : public QObject { Q_OBJECT public: MocTestObject() {} }; QString qc_getenv(const QString &var) { char *p = ::getenv(var.toLatin1().data()); if(!p) return QString(); return QString(p); } QStringList qc_pathlist() { QStringList list; QString path = qc_getenv("PATH"); if(!path.isEmpty()) { #ifdef Q_OS_WIN list = path.split(';', QString::SkipEmptyParts); #else list = path.split(':', QString::SkipEmptyParts); #endif } #ifdef Q_OS_WIN list.prepend("."); #endif return list; } QString qc_findprogram(const QString &prog) { QString out; QStringList list = qc_pathlist(); for(int n = 0; n < list.count(); ++n) { QFileInfo fi(list[n] + '/' + prog); if(fi.exists() && fi.isExecutable()) { out = fi.filePath(); break; } #ifdef Q_OS_WIN // on windows, be sure to look for .exe if(prog.right(4).toLower() != ".exe") { fi = QFileInfo(list[n] + '/' + prog + ".exe"); if(fi.exists() && fi.isExecutable()) { out = fi.filePath(); break; } } #endif } return out; } QString qc_findself(const QString &argv0) { #ifdef Q_OS_WIN if(argv0.contains('\\\\')) #else if(argv0.contains('/')) #endif return argv0; else return qc_findprogram(argv0); } int qc_run_program_or_command(const QString &prog, const QStringList &args, const QString &command, QByteArray *out, bool showOutput) { if(out) out->clear(); QProcess process; process.setReadChannel(QProcess::StandardOutput); if(!prog.isEmpty()) process.start(prog, args); else if(!command.isEmpty()) process.start(command); else return -1; if(!process.waitForStarted(-1)) return -1; QByteArray buf; while(process.waitForReadyRead(-1)) { buf = process.readAllStandardOutput(); if(out) out->append(buf); if(showOutput) fprintf(stdout, "%s", buf.data()); buf = process.readAllStandardError(); if(showOutput) fprintf(stderr, "%s", buf.data()); } buf = process.readAllStandardError(); if(showOutput) fprintf(stderr, "%s", buf.data()); // calling waitForReadyRead will cause the process to eventually be // marked as finished, so we should not need to separately call // waitForFinished. however, we will do it anyway just to be safe. // we won't check the return value since false could still mean // success (if the process had already been marked as finished). process.waitForFinished(-1); if(process.exitStatus() != QProcess::NormalExit) return -1; return process.exitCode(); } int qc_runcommand(const QString &command, QByteArray *out, bool showOutput) { return qc_run_program_or_command(QString(), QStringList(), command, out, showOutput); } int qc_runprogram(const QString &prog, const QStringList &args, QByteArray *out, bool showOutput) { return qc_run_program_or_command(prog, args, QString(), out, showOutput); } bool qc_removedir(const QString &dirPath) { QDir dir(dirPath); if(!dir.exists()) return false; QStringList list = dir.entryList(); foreach(QString s, list) { if(s == "." || s == "..") continue; QFileInfo fi(dir.filePath(s)); if(fi.isDir()) { if(!qc_removedir(fi.filePath())) return false; } else { if(!dir.remove(s)) return false; } } QString dirName = dir.dirName(); if(!dir.cdUp()) return false; if(!dir.rmdir(dirName)) return false; return true; } void qc_splitcflags(const QString &cflags, QStringList *incs, QStringList *otherflags) { incs->clear(); otherflags->clear(); QStringList cflagsList = cflags.split(" "); for(int n = 0; n < cflagsList.count(); ++n) { QString str = cflagsList[n]; if(str.startsWith("-I")) { // we want everything except the leading "-I" incs->append(str.remove(0, 2)); } else { // we want whatever is left otherflags->append(str); } } } QString qc_escapeArg(const QString &str) { QString out; for(int n = 0; n < (int)str.length(); ++n) { if(str[n] == '-') out += '_'; else out += str[n]; } return out; } //---------------------------------------------------------------------------- // ConfObj //---------------------------------------------------------------------------- ConfObj::ConfObj(Conf *c) { conf = c; conf->added(this); required = false; disabled = false; success = false; } ConfObj::~ConfObj() { } QString ConfObj::checkString() const { return QString("Checking for %1 ...").arg(name()); } QString ConfObj::resultString() const { if(success) return "yes"; else return "no"; } //---------------------------------------------------------------------------- // qc_internal_pkgconfig //---------------------------------------------------------------------------- class qc_internal_pkgconfig : public ConfObj { public: QString pkgname, desc; VersionMode mode; QString req_ver; qc_internal_pkgconfig(Conf *c, const QString &_name, const QString &_desc, VersionMode _mode, const QString &_req_ver) : ConfObj(c) { pkgname = _name; desc = _desc; mode = _mode; req_ver = _req_ver; } QString name() const { return desc; } QString shortname() const { return pkgname; } bool exec() { QStringList incs; QString version, libs, other; if(!conf->findPkgConfig(pkgname, mode, req_ver, &version, &incs, &libs, &other)) return false; for(int n = 0; n < incs.count(); ++n) conf->addIncludePath(incs[n]); if(!libs.isEmpty()) conf->addLib(libs); //if(!other.isEmpty()) // conf->addExtra(QString("QMAKE_CFLAGS += %1\n").arg(other)); return true; } }; //---------------------------------------------------------------------------- // Conf //---------------------------------------------------------------------------- Conf::Conf() { // TODO: no more vars? //vars.insert("QMAKE_INCDIR_X11", new QString(X11_INC)); //vars.insert("QMAKE_LIBDIR_X11", new QString(X11_LIBDIR)); //vars.insert("QMAKE_LIBS_X11", new QString(X11_LIB)); //vars.insert("QMAKE_CC", CC); debug_enabled = false; } Conf::~Conf() { qDeleteAll(list); } void Conf::added(ConfObj *o) { list.append(o); } QString Conf::getenv(const QString &var) { return qc_getenv(var); } void Conf::debug(const QString &s) { if(debug_enabled) { if(first_debug) printf("\n"); first_debug = false; printf(" * %s\n", qPrintable(s)); } } bool Conf::exec() { for(int n = 0; n < list.count(); ++n) { ConfObj *o = list[n]; // if this was a disabled-by-default option, check if it was enabled if(o->disabled) { QString v = QString("QC_ENABLE_") + qc_escapeArg(o->shortname()); if(getenv(v) != "Y") continue; } // and the opposite? else { QString v = QString("QC_DISABLE_") + qc_escapeArg(o->shortname()); if(getenv(v) == "Y") continue; } bool output = true; QString check = o->checkString(); if(check.isEmpty()) output = false; if(output) { printf("%s", check.toLatin1().data()); fflush(stdout); } first_debug = true; bool ok = o->exec(); o->success = ok; if(output) { QString result = o->resultString(); if(!first_debug) printf(" -> %s\n", result.toLatin1().data()); else printf(" %s\n", result.toLatin1().data()); } if(!ok && o->required) { printf("\nError: need %s!\n", o->name().toLatin1().data()); return false; } } return true; } QString Conf::qvar(const QString &s) { return vars.value(s); } QString Conf::expandIncludes(const QString &inc) { return QString("-I") + inc; } QString Conf::expandLibs(const QString &lib) { return QString("-L") + lib; } int Conf::doCommand(const QString &s, QByteArray *out) { debug(QString("[%1]").arg(s)); int r = qc_runcommand(s, out, debug_enabled); debug(QString("returned: %1").arg(r)); return r; } int Conf::doCommand(const QString &prog, const QStringList &args, QByteArray *out) { QString fullcmd = prog; QString argstr = args.join(" "); if(!argstr.isEmpty()) fullcmd += QString(" ") + argstr; debug(QString("[%1]").arg(fullcmd)); int r = qc_runprogram(prog, args, out, debug_enabled); debug(QString("returned: %1").arg(r)); return r; } bool Conf::doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode) { #ifdef Q_OS_WIN QDir tmp("qconftemp"); #else QDir tmp(".qconftemp"); #endif if(!tmp.mkdir("atest")) { debug("unable to create atest dir"); return false; } QDir dir(tmp.filePath("atest")); if(!dir.exists()) { debug("atest dir does not exist"); return false; } QString fname = dir.filePath("atest.cpp"); QString out = "atest"; QFile f(fname); if(!f.open(QFile::WriteOnly | QFile::Truncate)) { debug("unable to open atest.cpp for writing"); return false; } if(f.write(filedata.toLatin1()) == -1) { debug("error writing to atest.cpp"); return false; } f.close(); debug(QString("Wrote atest.cpp:\n%1").arg(filedata)); QString pro = QString( "CONFIG += console\n" "CONFIG -= qt app_bundle\n" "DESTDIR = \$\$PWD\n" "SOURCES += atest.cpp\n"); QString inc = incs.join(" "); if(!inc.isEmpty()) pro += "INCLUDEPATH += " + inc + '\n'; if(!libs.isEmpty()) pro += "LIBS += " + libs + '\n'; pro += proextra; fname = dir.filePath("atest.pro"); f.setFileName(fname); if(!f.open(QFile::WriteOnly | QFile::Truncate)) { debug("unable to open atest.pro for writing"); return false; } if(f.write(pro.toLatin1()) == -1) { debug("error writing to atest.pro"); return false; } f.close(); debug(QString("Wrote atest.pro:\n%1").arg(pro)); QString oldpath = QDir::currentPath(); QDir::setCurrent(dir.path()); bool ok = false; int r = doCommand(qmake_path, QStringList() << "atest.pro"); if(r == 0) { r = doCommand(maketool, QStringList()); if(r == 0) { ok = true; if(retcode) { QString runatest = out; #ifdef Q_OS_UNIX runatest.prepend("./"); #endif *retcode = doCommand(runatest, QStringList()); } } r = doCommand(maketool, QStringList() << "distclean"); if(r != 0) debug("error during atest distclean"); } QDir::setCurrent(oldpath); // cleanup //dir.remove("atest.pro"); //dir.remove("atest.cpp"); //tmp.rmdir("atest"); // remove whole dir since distclean doesn't always work qc_removedir(tmp.filePath("atest")); if(!ok) return false; return true; } bool Conf::checkHeader(const QString &path, const QString &h) { QFileInfo fi(path + '/' + h); if(fi.exists()) return true; return false; } bool Conf::findHeader(const QString &h, const QStringList &ext, QString *inc) { if(checkHeader("/usr/include", h)) { *inc = ""; return true; } QStringList dirs; dirs += "/usr/local/include"; dirs += ext; for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) { if(checkHeader(*it, h)) { *inc = *it; return true; } } return false; } bool Conf::checkLibrary(const QString &path, const QString &name) { QString str = //"#include \n" "int main()\n" "{\n" //" printf(\"library checker running\\\\n\");\n" " return 0;\n" "}\n"; QString libs; if(!path.isEmpty()) libs += QString("-L") + path + ' '; libs += QString("-l") + name; if(!doCompileAndLink(str, QStringList(), libs, QString())) return false; return true; } bool Conf::findLibrary(const QString &name, QString *lib) { if(checkLibrary("", name)) { *lib = ""; return true; } if(checkLibrary("/usr/local/lib", name)) { *lib = "/usr/local/lib"; return true; } return false; } QString Conf::findProgram(const QString &prog) { return qc_findprogram(prog); } bool Conf::findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs) { QString inc, lib; QString s; s = getenv(incvar); if(!s.isEmpty()) { if(!checkHeader(s, incname)) return false; inc = s; } else { if(!findHeader(incname, QStringList(), &s)) return false; inc = s; } s = getenv(libvar); if(!s.isEmpty()) { if(!checkLibrary(s, libname)) return false; lib = s; } else { if(!findLibrary(libname, &s)) return false; lib = s; } QString lib_out; if(!lib.isEmpty()) lib_out += QString("-L") + s; lib_out += QString("-l") + libname; *incpath = inc; *libs = lib_out; return true; } bool Conf::findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags) { QStringList args; QByteArray out; int ret; args += "--version"; ret = doCommand(path, args, &out); if(ret != 0) return false; QString version_out = QString::fromLatin1(out).trimmed(); args.clear(); args += "--libs"; ret = doCommand(path, args, &out); if(ret != 0) return false; QString libs_out = QString::fromLatin1(out).trimmed(); args.clear(); args += "--cflags"; ret = doCommand(path, args, &out); if(ret != 0) return false; QString cflags = QString::fromLatin1(out).trimmed(); QStringList incs_out, otherflags_out; qc_splitcflags(cflags, &incs_out, &otherflags_out); *version = version_out; *incs = incs_out; *libs = libs_out; *otherflags = otherflags_out.join(" "); return true; } bool Conf::findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags) { QStringList args; QByteArray out; int ret; args += name; args += "--exists"; ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; if(mode != VersionAny) { args.clear(); args += name; if(mode == VersionMin) args += QString("--atleast-version=%1").arg(req_version); else if(mode == VersionMax) args += QString("--max-version=%1").arg(req_version); else args += QString("--exact-version=%1").arg(req_version); ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; } args.clear(); args += name; args += "--modversion"; ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; QString version_out = QString::fromLatin1(out).trimmed(); args.clear(); args += name; args += "--libs"; ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; QString libs_out = QString::fromLatin1(out).trimmed(); args.clear(); args += name; args += "--cflags"; ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; QString cflags = QString::fromLatin1(out).trimmed(); QStringList incs_out, otherflags_out; qc_splitcflags(cflags, &incs_out, &otherflags_out); *version = version_out; *incs = incs_out; *libs = libs_out; *otherflags = otherflags_out.join(" "); return true; } void Conf::addDefine(const QString &str) { if(DEFINES.isEmpty()) DEFINES = str; else DEFINES += QString(" ") + str; debug(QString("DEFINES += %1").arg(str)); } void Conf::addLib(const QString &str) { if(LIBS.isEmpty()) LIBS = str; else LIBS += QString(" ") + str; debug(QString("LIBS += %1").arg(str)); } void Conf::addIncludePath(const QString &str) { if(INCLUDEPATH.isEmpty()) INCLUDEPATH = str; else INCLUDEPATH += QString(" ") + str; debug(QString("INCLUDEPATH += %1").arg(str)); } void Conf::addExtra(const QString &str) { extra += str + '\n'; debug(QString("extra += %1").arg(str)); } //---------------------------------------------------------------------------- // main //---------------------------------------------------------------------------- #include "conf4.moc" #ifdef HAVE_MODULES # include"modules.cpp" #endif int main() { Conf *conf = new Conf; ConfObj *o = 0; Q_UNUSED(o); #ifdef HAVE_MODULES # include"modules_new.cpp" #endif conf->debug_enabled = (qc_getenv("QC_VERBOSE") == "Y") ? true: false; if(conf->debug_enabled) printf(" -> ok\n"); else printf("ok\n"); QString confCommand = qc_getenv("QC_COMMAND"); QString proName = qc_getenv("QC_PROFILE"); conf->qmake_path = qc_getenv("QC_QMAKE"); conf->qmakespec = qc_getenv("QC_QMAKESPEC"); conf->maketool = qc_getenv("QC_MAKETOOL"); if(conf->debug_enabled) printf("conf command: [%s]\n", qPrintable(confCommand)); QString confPath = qc_findself(confCommand); if(confPath.isEmpty()) { printf("Error: cannot find myself; rerun with an absolute path\n"); return 1; } QString srcdir = QFileInfo(confPath).absolutePath(); QString builddir = QDir::current().absolutePath(); QString proPath = QDir(srcdir).filePath(proName); if(conf->debug_enabled) { printf("conf path: [%s]\n", qPrintable(confPath)); printf("srcdir: [%s]\n", qPrintable(srcdir)); printf("builddir: [%s]\n", qPrintable(builddir)); printf("profile: [%s]\n", qPrintable(proPath)); printf("qmake path: [%s]\n", qPrintable(conf->qmake_path)); printf("qmakespec: [%s]\n", qPrintable(conf->qmakespec)); printf("make tool: [%s]\n", qPrintable(conf->maketool)); printf("\n"); } bool success = false; if(conf->exec()) { QFile f("conf.pri"); if(!f.open(QFile::WriteOnly | QFile::Truncate)) { printf("Error writing %s\n", qPrintable(f.fileName())); return 1; } QString str; str += "# qconf\n\n"; QString var; var = qc_getenv("PREFIX"); if(!var.isEmpty()) str += QString("PREFIX = %1\n").arg(var); var = qc_getenv("BINDIR"); if(!var.isEmpty()) str += QString("BINDIR = %1\n").arg(var); var = qc_getenv("INCDIR"); if(!var.isEmpty()) str += QString("INCDIR = %1\n").arg(var); var = qc_getenv("LIBDIR"); if(!var.isEmpty()) str += QString("LIBDIR = %1\n").arg(var); var = qc_getenv("DATADIR"); if(!var.isEmpty()) str += QString("DATADIR = %1\n").arg(var); str += '\n'; if(qc_getenv("QC_STATIC") == "Y") str += "CONFIG += staticlib\n"; // TODO: don't need this? //str += "QT_PATH_PLUGINS = " + QString(qInstallPathPlugins()) + '\n'; if(!conf->DEFINES.isEmpty()) str += "DEFINES += " + conf->DEFINES + '\n'; if(!conf->INCLUDEPATH.isEmpty()) str += "INCLUDEPATH += " + conf->INCLUDEPATH + '\n'; if(!conf->LIBS.isEmpty()) str += "LIBS += " + conf->LIBS + '\n'; if(!conf->extra.isEmpty()) str += conf->extra; str += '\n'; QByteArray cs = str.toLatin1(); f.write(cs); f.close(); success = true; } QString qmake_path = conf->qmake_path; QString qmakespec = conf->qmakespec; delete conf; if(!success) return 1; // run qmake on the project file QStringList args; if(!qmakespec.isEmpty()) { args += "-spec"; args += qmakespec; } args += proPath; int ret = qc_runprogram(qmake_path, args, 0, true); if(ret != 0) return 1; return 0; } EOT cat >$1/conf4.pro </dev/null else $qm conf4.pro >/dev/null fi $MAKE clean >/dev/null 2>&1 $MAKE >../conf.log 2>&1 ) if [ "$?" != "0" ]; then rm -rf .qconftemp if [ "$QC_VERBOSE" = "Y" ]; then echo " -> fail" else echo "fail" fi printf "\n" printf "Reason: There was an error compiling 'conf'. See conf.log for details.\n" printf "\n" show_qt_info if [ "$QC_VERBOSE" = "Y" ]; then echo "conf.log:" cat conf.log fi exit 1; fi QC_COMMAND=$0 export QC_COMMAND QC_PROFILE=qconf.pro export QC_PROFILE QC_QMAKE=$qm export QC_QMAKE QC_QMAKESPEC=$qm_spec export QC_QMAKESPEC QC_MAKETOOL=$MAKE export QC_MAKETOOL .qconftemp/conf ret="$?" if [ "$ret" = "1" ]; then rm -rf .qconftemp echo exit 1; else if [ "$ret" != "0" ]; then rm -rf .qconftemp if [ "$QC_VERBOSE" = "Y" ]; then echo " -> fail" else echo "fail" fi echo echo "Reason: Unexpected error launching 'conf'" echo exit 1; fi fi rm -rf .qconftemp echo echo "Good, your configure finished. Now run $MAKE." echo qconf-1.5/configure.exe000066400000000000000000001043251206613545200151620ustar00rootroot00000000000000MZ@ !L!This program cannot be run in DOS mode. $PEL3J 8 ,0@`w P.textL `P`.dataX0$@0.bss@@.idataP*@0U]E1ۉu1=wC=r[$1҉T$tzt$л؋u]]=twJ=t؋u]]=t[=u$1t$ptjt$=$D$@vl$ 1D$t0R$ ?$L$%$ D$ 'US$$@% EED$0@$@@D$ ED$@@D$0@@td(0@tQ@t0@@D$tQ@@0$CtQ@t(0@@D$tQ@@P$ (0@>D$@@D$@@$u $D$tQ@@$tQ@@U$`Q@&U$`Q@&U Q@]t&U |Q@]ᐐU]gUM]QQQÍv'Ul!WVS=0@1ۉ<$019 :B19|F $0@t$D$$E_\$0@\$$1ɍTD)AB~D2 L$\$$8E $1!$0@T$f$B1$@  D$T$ |$$)1ۉ;}:t&)9ȋ94t?C;|̋@ @1ۋ$e[^_]Ãtŋ);}륋1|$؋)؉D$$uL$1ۉ4$T$ T$}O4$$3|$4$D$ D$:~"$ E 0E84$U}ǍB]u։$$Ét$|$؋u]}]Í'U($U]u}EËE $MƉ)E@$NjUE<$T$D$gt$EU T$$OU>Mu)ӋU)uʉUM\$ʉT$$E]u8}]Í&U$]Éut$‰$$]u]Í&'UWVS F1PG9~~JF$OFD$@FD t͉$G,9~ ^1~-1ېt&F G$F D $9~ڋFu$Fu,4$ [^_]É$D$Ftԉ$4$ [^_]Ð&U$]uƉ}<$D$$Ét$$yf=|$$$]u}]Ív'UVSÉ$$$19}&'<2/tB9|[^]2\B쐍t&UX]u}$Y0@ÍED$$$uu ]u}]É<$Z]1u}]ÍvU$]u0@R$$]u]fU$bɅÐ&UWV1SE@ UUEz9}01ۍ'EUD$$StF 9|1[^_]ÃtE$30@UZ4$X$0@D$$=1tt$ D$EH TT$D$j4$cU]u$0@0@4$u ]u]$0@b0@P4$]u]Í&'UWVSb ED$ED$U $'u7tQ@\$L$@D$ $0@qe[^_]Ëu$ %Eԉ4$‰ƉM<$uԉF$FVEv'<$EƋEԋUЋ@UȉẺMȋỦ<$MԉƉ‰Y_UȋMԋuȉDQGEЉD1D E9A<$UԉB@$/EMԉA A1x&<$ƋEԉ@ EĉxMĉ <$XƋEԋ@ E4$xMD UԋxB Dt$|$$EЋUԋxB tuЃ 9rx^<$Ɖ‰8UB<$‰ƉMA<$‰uԅFEԋt_U :$1@$Ƹ1@D$c)؃ |$‰؉4$E؋Mԋ$xE؋uԉEU9UEs&'Mu ;-{-K1ҍCt&=B u$ EEuܿ1@tduܿ 1@U1ۋEԋr@9|}6M܉L$|$;XC9|֋Uԋ$1@D$ EM܉ $W E؅t u؉4$E EE9E1҃}…Et>E@@$ 1@1@ @@]끋U MԋAUD$$!1@M @@$81@4 tQ@ $ @@@@Dž @@)HaE0@$ 0@^1@$E?P" @@$j1@I $ E $t1@1 $ - uԋF$1@D$O @@H<$ 1ۋE @@1e[^_]á @@$1@ t = @@$1@ $ $1@x $ t uԋF$1@D$ W$1@$ U$ 4 P$ 1! Eԋ@ UԋBL\ $1@L$( t\$$1@ $ F M9q$1@ $2@ <$AZE܍D3$ E7]Cuܿ2@u)@@4E؉$ @@UԋR|]|D |TuZU؉$m |D EԋHET D +$= Uԋ$1@D$ E$1@ |D3 $2@ @@$j1@ 8|$$D2@ tQ@$X2@@D$ "D$D$7 E${2@E$2@E$2@Eh$2@EP0@]><$ E2@pE$2@[E$EE$utRU$2@$2@4h$uԋv|$M $E0@EtwE @@t u$2@t$E0@EU$2@E EM $GM EM 0@Mu2@}U2@EԋP3@o 3@cU3@V<$0@$ 3@E<$U$"MÉ $ @@$j1@$ $(3@$ E$7u4$R3@EE$EE$U4$EUU$1@l$ E$h3@D$6$ E$:U80@8t80@BR80@uÍ&US8.@t)t'8.@Ku$'@Y[]1=<.@ @<.@u뾍'U@@@t]f]@@@냐U@@Q@@@r]ÐUSX5 PX1ة 1%ft P@@t P@@t P@@t P@@t P@@ t P@@@ t P@@=v,P@@@t P@@[]à P@@M[ P@@]ÐU]ÐU@@]HUBSdT$U1ۉT$$0Q@ u=Jx|*Au Jy;Tu؋]$3@3@T$D$$ 4@3@\$L$'UWVS=@@te[^_]EAAAA3@}EAAAAEAAAAE3@EAAAAEAAAAE3@EAAAAEAAAAE3@EAAAAEġ3@Eȡ3@E̡3@EС3@E3@fE؉<$,Q@q$TQ$1ɾTL$t$C.@C)@p@@Tt@@C(CH0@SL0@C@@C,S C0P0@T0@C4@@S8@@C<@@CDS@CH\0@X0@SPCL!ȃ$ A*HJy硘3@h3@l3@p3@t3@x3@|3@E3@E3@fEH$$Q@uB1҅u$<$,Q@/É@@C@@C@@e[^_]É9؉uKQ=r -) ̋@%HQ@%DQ@%hQ@%XQ@%Q@%\Q@%Q@%TQ@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%lQ@%pQ@%xQ@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%dQ@%Q@%Q@%(Q@%8Q@%4Q@U](.@h0@0@0@0@0@@H.@QCONF_CONFIGWIN_BLOCKSIG%08xrbmakemingw32-makenmakeqconftemp/bin/qmake.exe >NUL 2>&1/wbdeltree /y rmdir /s /q Error: Can't import data. $0helpverbose%sYQC_VERBOSEConfiguring %s ... Verifying Qt 4 build environment ... modules.cpp -> failReason: There was an error compiling 'conf'. See conf.log for details.QTDIRfailReason: Unable to find the 'qmake' tool for Qt 4.%s=conf.log:type conf.logqtdirWarning: qmake not found via %%QTDIR%% qmake found in %s Error: Can't parse internal data. modules_new.cppconf4.hconf4.cppconf4.pro conf4.pro >NUL..Warning: qmake not found via --qtdirTrying "%s" cleanQC_COMMANDQC_PROFILEQC_QMAKEQC_MAKETOOL/confReason: Unexpected error launching 'conf' >..\conf.log 2>&1Good, your configure finished. Now run %s. -LIBGCCW32-EH-3-SJLJ-GTHR-MINGW32w32_sharedptr->size == sizeof(W32_EH_SHARED)../../gcc-3.4.5/gcc/config/i386/w32-shared-ptr.cGetAtomNameA (atom, s, sizeof(s)) != 0TP T$QtP$TDQPTTQQQ RR&R_putenvQ_strdup'__getmainargs<__p__environ>__p__fmodeP__set_app_typeo_asserty_cexit{_chdir_errno_iobY_mkdir^_onexit_setmode_statabortatexit-fclose0fflush8fopen>fread?freeCfseekEftellGfwriteKgetenvrmallocxmemcpyzmemsetprintfputcharputssignalsprintfstrcatstrcmpstrcpystrlenstrstrsystemPPPPPPKERNEL32.dllPPmsvcrt.dll(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(Pmsvcrt.dllQCONF_CONFIGWIN_BLOCKSIG_68b7e7d7XUsage: $0 [OPTION]... This script creates necessary configuration files to build/install. Main options: --qtdir=[path] Directory where Qt is installed. --verbose Show extra configure output. --help This help text. qtdirEX_QTDIR modules.cppmodules_new.cppconf4.h ?/* Copyright (C) 2004-2008 Justin Karneges This file is free software; unlimited permission is given to copy and/or distribute it, with or without modifications, as long as this notice is preserved. */ #ifndef QC_CONF4_H #define QC_CONF4_H #include class Conf; enum VersionMode { VersionMin, VersionExact, VersionMax, VersionAny }; // ConfObj // // Subclass ConfObj to create a new configuration module. class ConfObj { public: Conf *conf; bool required; bool disabled; bool success; ConfObj(Conf *c); virtual ~ConfObj(); // long or descriptive name of what is being checked/performed // example: "KDE >= 3.3" virtual QString name() const = 0; // short name // example: "kde" virtual QString shortname() const = 0; // string to display during check // default: "Checking for [name] ..." virtual QString checkString() const; // string to display after check // default: "yes" or "no", based on result of exec() virtual QString resultString() const; // this is where the checking code goes virtual bool exec() = 0; }; // Conf // // Interact with this class from your ConfObj to perform detection // operations and to output configuration parameters. class Conf { public: bool debug_enabled; QString qmake_path; QString qmakespec; QString maketool; QString DEFINES; QString INCLUDEPATH; QString LIBS; QString extra; QList list; QMap vars; Conf(); ~Conf(); QString getenv(const QString &var); QString qvar(const QString &s); bool exec(); void debug(const QString &s); QString expandIncludes(const QString &inc); QString expandLibs(const QString &lib); int doCommand(const QString &s, QByteArray *out = 0); int doCommand(const QString &prog, const QStringList &args, QByteArray *out = 0); bool doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode = 0); bool checkHeader(const QString &path, const QString &h); bool findHeader(const QString &h, const QStringList &ext, QString *inc); bool checkLibrary(const QString &path, const QString &name); bool findLibrary(const QString &name, QString *lib); QString findProgram(const QString &prog); bool findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs); bool findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags); bool findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags); void addDefine(const QString &str); void addLib(const QString &str); void addIncludePath(const QString &str); void addExtra(const QString &str); private: bool first_debug; friend class ConfObj; void added(ConfObj *o); }; #endif conf4.cppH/* Copyright (C) 2004-2008 Justin Karneges This file is free software; unlimited permission is given to copy and/or distribute it, with or without modifications, as long as this notice is preserved. */ #include "conf4.h" #include #include class MocTestObject : public QObject { Q_OBJECT public: MocTestObject() {} }; QString qc_getenv(const QString &var) { char *p = ::getenv(var.toLatin1().data()); if(!p) return QString(); return QString(p); } QStringList qc_pathlist() { QStringList list; QString path = qc_getenv("PATH"); if(!path.isEmpty()) { #ifdef Q_OS_WIN list = path.split(';', QString::SkipEmptyParts); #else list = path.split(':', QString::SkipEmptyParts); #endif } #ifdef Q_OS_WIN list.prepend("."); #endif return list; } QString qc_findprogram(const QString &prog) { QString out; QStringList list = qc_pathlist(); for(int n = 0; n < list.count(); ++n) { QFileInfo fi(list[n] + '/' + prog); if(fi.exists() && fi.isExecutable()) { out = fi.filePath(); break; } #ifdef Q_OS_WIN // on windows, be sure to look for .exe if(prog.right(4).toLower() != ".exe") { fi = QFileInfo(list[n] + '/' + prog + ".exe"); if(fi.exists() && fi.isExecutable()) { out = fi.filePath(); break; } } #endif } return out; } QString qc_findself(const QString &argv0) { #ifdef Q_OS_WIN if(argv0.contains('\\')) #else if(argv0.contains('/')) #endif return argv0; else return qc_findprogram(argv0); } int qc_run_program_or_command(const QString &prog, const QStringList &args, const QString &command, QByteArray *out, bool showOutput) { if(out) out->clear(); QProcess process; process.setReadChannel(QProcess::StandardOutput); if(!prog.isEmpty()) process.start(prog, args); else if(!command.isEmpty()) process.start(command); else return -1; if(!process.waitForStarted(-1)) return -1; QByteArray buf; while(process.waitForReadyRead(-1)) { buf = process.readAllStandardOutput(); if(out) out->append(buf); if(showOutput) fprintf(stdout, "%s", buf.data()); buf = process.readAllStandardError(); if(showOutput) fprintf(stderr, "%s", buf.data()); } buf = process.readAllStandardError(); if(showOutput) fprintf(stderr, "%s", buf.data()); // calling waitForReadyRead will cause the process to eventually be // marked as finished, so we should not need to separately call // waitForFinished. however, we will do it anyway just to be safe. // we won't check the return value since false could still mean // success (if the process had already been marked as finished). process.waitForFinished(-1); if(process.exitStatus() != QProcess::NormalExit) return -1; return process.exitCode(); } int qc_runcommand(const QString &command, QByteArray *out, bool showOutput) { return qc_run_program_or_command(QString(), QStringList(), command, out, showOutput); } int qc_runprogram(const QString &prog, const QStringList &args, QByteArray *out, bool showOutput) { return qc_run_program_or_command(prog, args, QString(), out, showOutput); } bool qc_removedir(const QString &dirPath) { QDir dir(dirPath); if(!dir.exists()) return false; QStringList list = dir.entryList(); foreach(QString s, list) { if(s == "." || s == "..") continue; QFileInfo fi(dir.filePath(s)); if(fi.isDir()) { if(!qc_removedir(fi.filePath())) return false; } else { if(!dir.remove(s)) return false; } } QString dirName = dir.dirName(); if(!dir.cdUp()) return false; if(!dir.rmdir(dirName)) return false; return true; } void qc_splitcflags(const QString &cflags, QStringList *incs, QStringList *otherflags) { incs->clear(); otherflags->clear(); QStringList cflagsList = cflags.split(" "); for(int n = 0; n < cflagsList.count(); ++n) { QString str = cflagsList[n]; if(str.startsWith("-I")) { // we want everything except the leading "-I" incs->append(str.remove(0, 2)); } else { // we want whatever is left otherflags->append(str); } } } QString qc_escapeArg(const QString &str) { QString out; for(int n = 0; n < (int)str.length(); ++n) { if(str[n] == '-') out += '_'; else out += str[n]; } return out; } //---------------------------------------------------------------------------- // ConfObj //---------------------------------------------------------------------------- ConfObj::ConfObj(Conf *c) { conf = c; conf->added(this); required = false; disabled = false; success = false; } ConfObj::~ConfObj() { } QString ConfObj::checkString() const { return QString("Checking for %1 ...").arg(name()); } QString ConfObj::resultString() const { if(success) return "yes"; else return "no"; } //---------------------------------------------------------------------------- // qc_internal_pkgconfig //---------------------------------------------------------------------------- class qc_internal_pkgconfig : public ConfObj { public: QString pkgname, desc; VersionMode mode; QString req_ver; qc_internal_pkgconfig(Conf *c, const QString &_name, const QString &_desc, VersionMode _mode, const QString &_req_ver) : ConfObj(c) { pkgname = _name; desc = _desc; mode = _mode; req_ver = _req_ver; } QString name() const { return desc; } QString shortname() const { return pkgname; } bool exec() { QStringList incs; QString version, libs, other; if(!conf->findPkgConfig(pkgname, mode, req_ver, &version, &incs, &libs, &other)) return false; for(int n = 0; n < incs.count(); ++n) conf->addIncludePath(incs[n]); if(!libs.isEmpty()) conf->addLib(libs); //if(!other.isEmpty()) // conf->addExtra(QString("QMAKE_CFLAGS += %1\n").arg(other)); return true; } }; //---------------------------------------------------------------------------- // Conf //---------------------------------------------------------------------------- Conf::Conf() { // TODO: no more vars? //vars.insert("QMAKE_INCDIR_X11", new QString(X11_INC)); //vars.insert("QMAKE_LIBDIR_X11", new QString(X11_LIBDIR)); //vars.insert("QMAKE_LIBS_X11", new QString(X11_LIB)); //vars.insert("QMAKE_CC", CC); debug_enabled = false; } Conf::~Conf() { qDeleteAll(list); } void Conf::added(ConfObj *o) { list.append(o); } QString Conf::getenv(const QString &var) { return qc_getenv(var); } void Conf::debug(const QString &s) { if(debug_enabled) { if(first_debug) printf("\n"); first_debug = false; printf(" * %s\n", qPrintable(s)); } } bool Conf::exec() { for(int n = 0; n < list.count(); ++n) { ConfObj *o = list[n]; // if this was a disabled-by-default option, check if it was enabled if(o->disabled) { QString v = QString("QC_ENABLE_") + qc_escapeArg(o->shortname()); if(getenv(v) != "Y") continue; } // and the opposite? else { QString v = QString("QC_DISABLE_") + qc_escapeArg(o->shortname()); if(getenv(v) == "Y") continue; } bool output = true; QString check = o->checkString(); if(check.isEmpty()) output = false; if(output) { printf("%s", check.toLatin1().data()); fflush(stdout); } first_debug = true; bool ok = o->exec(); o->success = ok; if(output) { QString result = o->resultString(); if(!first_debug) printf(" -> %s\n", result.toLatin1().data()); else printf(" %s\n", result.toLatin1().data()); } if(!ok && o->required) { printf("\nError: need %s!\n", o->name().toLatin1().data()); return false; } } return true; } QString Conf::qvar(const QString &s) { return vars.value(s); } QString Conf::expandIncludes(const QString &inc) { return QString("-I") + inc; } QString Conf::expandLibs(const QString &lib) { return QString("-L") + lib; } int Conf::doCommand(const QString &s, QByteArray *out) { debug(QString("[%1]").arg(s)); int r = qc_runcommand(s, out, debug_enabled); debug(QString("returned: %1").arg(r)); return r; } int Conf::doCommand(const QString &prog, const QStringList &args, QByteArray *out) { QString fullcmd = prog; QString argstr = args.join(" "); if(!argstr.isEmpty()) fullcmd += QString(" ") + argstr; debug(QString("[%1]").arg(fullcmd)); int r = qc_runprogram(prog, args, out, debug_enabled); debug(QString("returned: %1").arg(r)); return r; } bool Conf::doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode) { #ifdef Q_OS_WIN QDir tmp("qconftemp"); #else QDir tmp(".qconftemp"); #endif if(!tmp.mkdir("atest")) { debug("unable to create atest dir"); return false; } QDir dir(tmp.filePath("atest")); if(!dir.exists()) { debug("atest dir does not exist"); return false; } QString fname = dir.filePath("atest.cpp"); QString out = "atest"; QFile f(fname); if(!f.open(QFile::WriteOnly | QFile::Truncate)) { debug("unable to open atest.cpp for writing"); return false; } if(f.write(filedata.toLatin1()) == -1) { debug("error writing to atest.cpp"); return false; } f.close(); debug(QString("Wrote atest.cpp:\n%1").arg(filedata)); QString pro = QString( "CONFIG += console\n" "CONFIG -= qt app_bundle\n" "DESTDIR = $$PWD\n" "SOURCES += atest.cpp\n"); QString inc = incs.join(" "); if(!inc.isEmpty()) pro += "INCLUDEPATH += " + inc + '\n'; if(!libs.isEmpty()) pro += "LIBS += " + libs + '\n'; pro += proextra; fname = dir.filePath("atest.pro"); f.setFileName(fname); if(!f.open(QFile::WriteOnly | QFile::Truncate)) { debug("unable to open atest.pro for writing"); return false; } if(f.write(pro.toLatin1()) == -1) { debug("error writing to atest.pro"); return false; } f.close(); debug(QString("Wrote atest.pro:\n%1").arg(pro)); QString oldpath = QDir::currentPath(); QDir::setCurrent(dir.path()); bool ok = false; int r = doCommand(qmake_path, QStringList() << "atest.pro"); if(r == 0) { r = doCommand(maketool, QStringList()); if(r == 0) { ok = true; if(retcode) { QString runatest = out; #ifdef Q_OS_UNIX runatest.prepend("./"); #endif *retcode = doCommand(runatest, QStringList()); } } r = doCommand(maketool, QStringList() << "distclean"); if(r != 0) debug("error during atest distclean"); } QDir::setCurrent(oldpath); // cleanup //dir.remove("atest.pro"); //dir.remove("atest.cpp"); //tmp.rmdir("atest"); // remove whole dir since distclean doesn't always work qc_removedir(tmp.filePath("atest")); if(!ok) return false; return true; } bool Conf::checkHeader(const QString &path, const QString &h) { QFileInfo fi(path + '/' + h); if(fi.exists()) return true; return false; } bool Conf::findHeader(const QString &h, const QStringList &ext, QString *inc) { if(checkHeader("/usr/include", h)) { *inc = ""; return true; } QStringList dirs; dirs += "/usr/local/include"; dirs += ext; for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) { if(checkHeader(*it, h)) { *inc = *it; return true; } } return false; } bool Conf::checkLibrary(const QString &path, const QString &name) { QString str = //"#include \n" "int main()\n" "{\n" //" printf(\"library checker running\\n\");\n" " return 0;\n" "}\n"; QString libs; if(!path.isEmpty()) libs += QString("-L") + path + ' '; libs += QString("-l") + name; if(!doCompileAndLink(str, QStringList(), libs, QString())) return false; return true; } bool Conf::findLibrary(const QString &name, QString *lib) { if(checkLibrary("", name)) { *lib = ""; return true; } if(checkLibrary("/usr/local/lib", name)) { *lib = "/usr/local/lib"; return true; } return false; } QString Conf::findProgram(const QString &prog) { return qc_findprogram(prog); } bool Conf::findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs) { QString inc, lib; QString s; s = getenv(incvar); if(!s.isEmpty()) { if(!checkHeader(s, incname)) return false; inc = s; } else { if(!findHeader(incname, QStringList(), &s)) return false; inc = s; } s = getenv(libvar); if(!s.isEmpty()) { if(!checkLibrary(s, libname)) return false; lib = s; } else { if(!findLibrary(libname, &s)) return false; lib = s; } QString lib_out; if(!lib.isEmpty()) lib_out += QString("-L") + s; lib_out += QString("-l") + libname; *incpath = inc; *libs = lib_out; return true; } bool Conf::findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags) { QStringList args; QByteArray out; int ret; args += "--version"; ret = doCommand(path, args, &out); if(ret != 0) return false; QString version_out = QString::fromLatin1(out).trimmed(); args.clear(); args += "--libs"; ret = doCommand(path, args, &out); if(ret != 0) return false; QString libs_out = QString::fromLatin1(out).trimmed(); args.clear(); args += "--cflags"; ret = doCommand(path, args, &out); if(ret != 0) return false; QString cflags = QString::fromLatin1(out).trimmed(); QStringList incs_out, otherflags_out; qc_splitcflags(cflags, &incs_out, &otherflags_out); *version = version_out; *incs = incs_out; *libs = libs_out; *otherflags = otherflags_out.join(" "); return true; } bool Conf::findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags) { QStringList args; QByteArray out; int ret; args += name; args += "--exists"; ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; if(mode != VersionAny) { args.clear(); args += name; if(mode == VersionMin) args += QString("--atleast-version=%1").arg(req_version); else if(mode == VersionMax) args += QString("--max-version=%1").arg(req_version); else args += QString("--exact-version=%1").arg(req_version); ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; } args.clear(); args += name; args += "--modversion"; ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; QString version_out = QString::fromLatin1(out).trimmed(); args.clear(); args += name; args += "--libs"; ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; QString libs_out = QString::fromLatin1(out).trimmed(); args.clear(); args += name; args += "--cflags"; ret = doCommand("pkg-config", args, &out); if(ret != 0) return false; QString cflags = QString::fromLatin1(out).trimmed(); QStringList incs_out, otherflags_out; qc_splitcflags(cflags, &incs_out, &otherflags_out); *version = version_out; *incs = incs_out; *libs = libs_out; *otherflags = otherflags_out.join(" "); return true; } void Conf::addDefine(const QString &str) { if(DEFINES.isEmpty()) DEFINES = str; else DEFINES += QString(" ") + str; debug(QString("DEFINES += %1").arg(str)); } void Conf::addLib(const QString &str) { if(LIBS.isEmpty()) LIBS = str; else LIBS += QString(" ") + str; debug(QString("LIBS += %1").arg(str)); } void Conf::addIncludePath(const QString &str) { if(INCLUDEPATH.isEmpty()) INCLUDEPATH = str; else INCLUDEPATH += QString(" ") + str; debug(QString("INCLUDEPATH += %1").arg(str)); } void Conf::addExtra(const QString &str) { extra += str + '\n'; debug(QString("extra += %1").arg(str)); } //---------------------------------------------------------------------------- // main //---------------------------------------------------------------------------- #include "conf4.moc" #ifdef HAVE_MODULES # include"modules.cpp" #endif int main() { Conf *conf = new Conf; ConfObj *o = 0; Q_UNUSED(o); #ifdef HAVE_MODULES # include"modules_new.cpp" #endif conf->debug_enabled = (qc_getenv("QC_VERBOSE") == "Y") ? true: false; if(conf->debug_enabled) printf(" -> ok\n"); else printf("ok\n"); QString confCommand = qc_getenv("QC_COMMAND"); QString proName = qc_getenv("QC_PROFILE"); conf->qmake_path = qc_getenv("QC_QMAKE"); conf->qmakespec = qc_getenv("QC_QMAKESPEC"); conf->maketool = qc_getenv("QC_MAKETOOL"); if(conf->debug_enabled) printf("conf command: [%s]\n", qPrintable(confCommand)); QString confPath = qc_findself(confCommand); if(confPath.isEmpty()) { printf("Error: cannot find myself; rerun with an absolute path\n"); return 1; } QString srcdir = QFileInfo(confPath).absolutePath(); QString builddir = QDir::current().absolutePath(); QString proPath = QDir(srcdir).filePath(proName); if(conf->debug_enabled) { printf("conf path: [%s]\n", qPrintable(confPath)); printf("srcdir: [%s]\n", qPrintable(srcdir)); printf("builddir: [%s]\n", qPrintable(builddir)); printf("profile: [%s]\n", qPrintable(proPath)); printf("qmake path: [%s]\n", qPrintable(conf->qmake_path)); printf("qmakespec: [%s]\n", qPrintable(conf->qmakespec)); printf("make tool: [%s]\n", qPrintable(conf->maketool)); printf("\n"); } bool success = false; if(conf->exec()) { QFile f("conf.pri"); if(!f.open(QFile::WriteOnly | QFile::Truncate)) { printf("Error writing %s\n", qPrintable(f.fileName())); return 1; } QString str; str += "# qconf\n\n"; QString var; var = qc_getenv("PREFIX"); if(!var.isEmpty()) str += QString("PREFIX = %1\n").arg(var); var = qc_getenv("BINDIR"); if(!var.isEmpty()) str += QString("BINDIR = %1\n").arg(var); var = qc_getenv("INCDIR"); if(!var.isEmpty()) str += QString("INCDIR = %1\n").arg(var); var = qc_getenv("LIBDIR"); if(!var.isEmpty()) str += QString("LIBDIR = %1\n").arg(var); var = qc_getenv("DATADIR"); if(!var.isEmpty()) str += QString("DATADIR = %1\n").arg(var); str += '\n'; if(qc_getenv("QC_STATIC") == "Y") str += "CONFIG += staticlib\n"; // TODO: don't need this? //str += "QT_PATH_PLUGINS = " + QString(qInstallPathPlugins()) + '\n'; if(!conf->DEFINES.isEmpty()) str += "DEFINES += " + conf->DEFINES + '\n'; if(!conf->INCLUDEPATH.isEmpty()) str += "INCLUDEPATH += " + conf->INCLUDEPATH + '\n'; if(!conf->LIBS.isEmpty()) str += "LIBS += " + conf->LIBS + '\n'; if(!conf->extra.isEmpty()) str += conf->extra; str += '\n'; QByteArray cs = str.toLatin1(); f.write(cs); f.close(); success = true; } QString qmake_path = conf->qmake_path; QString qmakespec = conf->qmakespec; delete conf; if(!success) return 1; // run qmake on the project file QStringList args; if(!qmakespec.isEmpty()) { args += "-spec"; args += qmakespec; } args += proPath; int ret = qc_runprogram(qmake_path, args, 0, true); if(ret != 0) return 1; return 0; } conf4.proCONFIG += console CONFIG -= app_bundle QT -= gui TARGET = conf DESTDIR = $$PWD HEADERS += conf4.h SOURCES += conf4.cpp DEFINES += HAVE_MODULES QConf qconf.proBe sure you have a proper Qt 4.0 build environment set up. This means not just Qt, but also a C++ compiler, a make tool, and any other packages necessary for compiling C++ programs. If you are certain everything is installed, then it could be that Qt 4 is not being recognized or that a different version of Qt is being detected by mistake (for example, this could happen if %QTDIR% is pointing to a Qt 3 installation). At least one of the following conditions must be satisfied: 1) --qtdir is set to the location of Qt 2) %QTDIR% is set to the location of Qt This program will use the first one it finds to be true, checked in the above order. qconf-1.5/examples/000077500000000000000000000000001206613545200143075ustar00rootroot00000000000000qconf-1.5/examples/sample.qc000066400000000000000000000001231206613545200161110ustar00rootroot00000000000000 Sample Application sample.pro qconf-1.5/examples/samplecustom.qc000066400000000000000000000001441206613545200173470ustar00rootroot00000000000000 Totally Custom Sample sample.pro qconf-1.5/examples/sampledeps.qc000066400000000000000000000002001206613545200167610ustar00rootroot00000000000000 Sample Application sample.pro qconf-1.5/examples/samplelib.qc000066400000000000000000000001621206613545200166030ustar00rootroot00000000000000 Sample Library sample.pro qconf-1.5/modules/000077500000000000000000000000001206613545200141415ustar00rootroot00000000000000qconf-1.5/modules/qt31.qcm000066400000000000000000000037341206613545200154420ustar00rootroot00000000000000/* Copyright (C) 2003-2008 Justin Karneges This file is free software; unlimited permission is given to copy and/or distribute it, with or without modifications, as long as this notice is preserved. QCM (QConf Module) Howto: - Modules are Qt/C++ files that are compiled and run during configure time. - Name your file "feature.qcm". - Create a "BEGIN QCMOD" block like the one below, and specify a friendly name for the feature. This block should be placed in a C comment, so that it does not disrupt the compiler. - If you want arguments for this feature, then add extra lines to the QCMOD block in the format: "arg: {name}(=[{value}]),description". For example: arg: enable-foo,Enable the Foo feature arg: with-foo-inc=[path],Path to Foo include files These are set as environment variables, which your module can use conf->getenv() to examine. - Create a class like the one below, named qc_feature (yes, the same word used in the filename), that inherits ConfObj. - Derive name() to produce a friendly string. This should probably be identical to the string used in the QCMOD block. It is this text that is used when configure outputs "Checking for {name} ..." - Derive shortname() to return "feature". - You may also derive checkString() and resultString() if you want to use different text than the usual "Checking for" and "yes/no" response. For resultString(), you'll want to maintain the result of the last call to exec(), so that you can output an appropriate string based on the result. Below you will find a sample module that simply checks for Qt >= 3.1 -----BEGIN QCMOD----- name: Qt >= 3.1 -----END QCMOD----- */ class qc_qt31 : public ConfObj { public: qc_qt31(Conf *c) : ConfObj(c) {} QString name() const { return "Qt >= 3.1"; } QString shortname() const { return "qt31"; } bool exec() { conf->debug(QString("QT_VERSION = %1").arg(QT_VERSION)); if(QT_VERSION >= 0x030100) return true; else return false; } }; qconf-1.5/modules/qt41.qcm000066400000000000000000000007461206613545200154430ustar00rootroot00000000000000/* Copyright (C) 2004-2008 Justin Karneges This file is free software; unlimited permission is given to copy and/or distribute it, with or without modifications, as long as this notice is preserved. -----BEGIN QCMOD----- name: Qt >= 4.1 -----END QCMOD----- */ class qc_qt41 : public ConfObj { public: qc_qt41(Conf *c) : ConfObj(c) {} QString name() const { return "Qt >= 4.1"; } QString shortname() const { return "qt41"; } bool exec() { return(QT_VERSION >= 0x040100); } }; qconf-1.5/qconf.pro000066400000000000000000000012311206613545200143160ustar00rootroot00000000000000QT -= gui QT += xml CONFIG += console CONFIG -= app_bundle DESTDIR = $$PWD HEADERS += src/stringhelp.h SOURCES += src/stringhelp.cpp src/qconf.cpp include($$OUT_PWD/conf.pri) !isEmpty(DATADIR) { contains($$list($$[QT_VERSION]), 4.0.*|4.1.*) { DEFINES += DATADIR=\"$$DATADIR\" } else { DEFINES += DATADIR=\\\"$$DATADIR\\\" } } RESOURCES += src/qconf.qrc # install # we check for empty BINDIR here in case we're debugging with configexe on unix unix:!isEmpty(BINDIR) { #CONFIG += no_fixpath target.path = $$BINDIR INSTALLS += target libfiles.path = $$DATADIR/qconf libfiles.files = $$IN_PWD/conf $$IN_PWD/modules INSTALLS += libfiles } qconf-1.5/qconf.qc000066400000000000000000000001221206613545200141170ustar00rootroot00000000000000 QConf qconf.pro qconf-1.5/src/000077500000000000000000000000001206613545200132605ustar00rootroot00000000000000qconf-1.5/src/configexe/000077500000000000000000000000001206613545200152275ustar00rootroot00000000000000qconf-1.5/src/configexe/configexe.c000066400000000000000000000335731206613545200173550ustar00rootroot00000000000000/* Copyright (C) 2009 Justin Karneges This file is free software; unlimited permission is given to copy and/or distribute it, with or without modifications, as long as this notice is preserved. */ #include #include #include #include #include #include #include #include "embed.h" #if defined(WIN32) || defined(_WIN32) # define QC_OS_WIN #endif #ifdef QC_OS_WIN #include #endif #ifdef QC_OS_WIN static char *qconftemp_path = "qconftemp"; #else static char *qconftemp_path = ".qconftemp"; #endif static int qc_verbose = 0; static char *ex_qtdir = 0; enum ArgType { ArgValue, ArgFlag }; typedef struct qcarg { char *name; char *envvar; int type; char *val; // we populate this later based on actual passed args } qcarg_t; typedef struct qcfile { char *name; unsigned char *data; unsigned int size; } qcfile_t; typedef struct qcdata { char *usage; qcarg_t *args; int args_count; qcfile_t *files; int files_count; char *pro_name; char *pro_file; char *qtinfo; } qcdata_t; static char *alloc_str(const unsigned char *src, int len) { char *out; out = (char *)malloc(len + 1); memcpy(out, src, len); out[len] = 0; return out; } static int index_of(const char *in, char sub) { int n; for(n = 0; in[n]; ++n) { if(in[n] == sub) return n; } return -1; } static int index_of_str(const char *in, const char *sub) { char *p; p = strstr(in, sub); if(p) return p - in; else return -1; } static char *selection_insert(const char *in, int at, int len, const char *sub) { int ilen; int slen; int newsize; char *out; ilen = strlen(in); slen = strlen(sub); newsize = ilen - len + slen; out = (char *)malloc(newsize + 1); memcpy(out, in, at); memcpy(out + at, sub, slen); memcpy(out + at + slen, in + at + len, ilen - at - len); out[newsize] = 0; return out; } static char *find_replace(const char *in, const char *old, const char *newv) { int at; int olen; olen = strlen(old); at = index_of_str(in, old); if(at != -1) return selection_insert(in, at, olen, newv); else return strdup(in); } static char *append_str(const char *in, const char *add) { return selection_insert(in, strlen(in), 0, add); } // creates new string and frees old static char *append_free(char *in, const char *add) { char *out; out = append_str(in, add); free(in); return out; } // FIXME: handle bad data, don't malloc 0, etc static qcdata_t *parse_data(unsigned char *data, unsigned int size) { unsigned char *p; qcdata_t *q; unsigned int len; int n; (void)size; q = (qcdata_t *)malloc(sizeof(qcdata_t)); p = data; len = read32(p); p += 4; q->usage = alloc_str(p, len); p += len; q->args_count = read32(p); p += 4; q->args = (qcarg_t *)malloc(sizeof(qcarg_t) * q->args_count); for(n = 0; n < q->args_count; ++n) { len = read32(p); p += 4; q->args[n].name = alloc_str(p, len); p += len; len = read32(p); p += 4; q->args[n].envvar = alloc_str(p, len); p += len; q->args[n].type = *(p++); q->args[n].val = NULL; } q->files_count = read32(p); p += 4; q->files = (qcfile_t *)malloc(sizeof(qcfile_t) * q->files_count); for(n = 0; n < q->files_count; ++n) { len = read32(p); p += 4; q->files[n].name = alloc_str(p, len); p += len; len = read32(p); p += 4; q->files[n].data = (unsigned char *)malloc(len); memcpy(q->files[n].data, p, len); q->files[n].size = len; p += len; } len = read32(p); p += 4; q->pro_name = alloc_str(p, len); p += len; len = read32(p); p += 4; q->pro_file = alloc_str(p, len); p += len; len = read32(p); p += 4; q->qtinfo = alloc_str(p, len); p += len; return q; } static void qcdata_delete(qcdata_t *q) { int n; if(q->usage) free(q->usage); for(n = 0; n < q->args_count; ++n) { free(q->args[n].name); free(q->args[n].envvar); if(q->args[n].val) free(q->args[n].val); } for(n = 0; n < q->files_count; ++n) { free(q->files[n].name); free(q->files[n].data); } if(q->pro_name) free(q->pro_name); if(q->pro_file) free(q->pro_file); free(q); } static int find_arg(const qcarg_t *args, int count, const char *name) { int n; for(n = 0; n < count; ++n) { if(strcmp(args[n].name, name) == 0) return n; } return -1; } static int find_file(const qcfile_t *files, int count, const char *name) { int n; for(n = 0; n < count; ++n) { if(strcmp(files[n].name, name) == 0) return n; } return -1; } // adapted from qt static int set_envvar(const char *var, const char *val) { #if defined(_MSC_VER) && _MSC_VER >= 1400 return (_putenv_s(var, val) == 0 ? 1 : 0); #else char *str; str = malloc(strlen(var) + 1 + strlen(val) + 1); strcpy(str, var); strcat(str, "="); strcat(str, val); return (putenv(str) == 0 ? 1 : 0); #endif } static char *get_envvar(const char *var) { return getenv(var); } static char *separators_to_native(const char *in) { char *out; #ifdef QC_OS_WIN int len; int n; out = strdup(in); len = strlen(in); for(n = 0; n < len; ++n) { if(out[n] == '/') out[n] = '\\'; } #else out = strdup(in); #endif return out; } static int file_exists(const char *path) { char *npath; int ret; #ifdef QC_OS_WIN struct _stat buf; #else struct stat buf; #endif npath = separators_to_native(path); #ifdef QC_OS_WIN ret = _stat(npath, &buf); #else ret = stat(npath, &buf); #endif free(npath); if(ret == 0) return 1; else return 0; } static char *check_qmake_path(const char *qtdir) { char *str; str = strdup(qtdir); #ifdef QC_OS_WIN str = append_free(str, "/bin/qmake.exe"); #else str = append_free(str, "/bin/qmake"); #endif if(file_exists(str)) { return str; } else { free(str); return NULL; } } static char *find_qmake() { char *qtdir; char *path; qtdir = ex_qtdir; if(qtdir) { path = check_qmake_path(qtdir); if(path) return path; } if(qc_verbose) printf("Warning: qmake not found via --qtdir\n"); qtdir = get_envvar("QTDIR"); if(qtdir) { path = check_qmake_path(qtdir); if(path) return path; } if(qc_verbose) printf("Warning: qmake not found via %%QTDIR%%\n"); return NULL; } static int run_silent_stdout(const char *cmd) { char *str; int ret; str = strdup(cmd); #ifdef QC_OS_WIN str = append_free(str, " >NUL"); #else str = append_free(str, " >/dev/null"); #endif ret = system(str); free(str); return ret; } static int run_silent_all(const char *cmd) { char *str; int ret; str = strdup(cmd); #ifdef QC_OS_WIN str = append_free(str, " >NUL 2>&1"); #else str = append_free(str, " >/dev/null 2>&1"); #endif ret = system(str); free(str); return ret; } static int run_conflog_all(const char *cmd) { char *str; int ret; str = strdup(cmd); #ifdef QC_OS_WIN str = append_free(str, " >..\\conf.log 2>&1"); #else str = append_free(str, " >../conf.log 2>&1"); #endif ret = system(str); free(str); return ret; } static int qc_ensuredir(const char *path) { #ifdef QC_OS_WIN if(_mkdir(path) == 0) return 1; else if(errno == EEXIST) return 1; else return 0; #else if(mkdir(path, S_IRWXU | S_IRWXG) == 0) return 1; else if(errno == EEXIST) return 1; else return 0; #endif } static int qc_chdir(const char *path) { int ret; #ifdef QC_OS_WIN ret = _chdir(path); #else ret = chdir(path); #endif if(ret == 0) return 1; else return 0; } static int qc_removedir(const char *path) { char *str; int ret; #ifdef QC_OS_WIN str = strdup("deltree /y "); str = append_free(str, qconftemp_path); ret = run_silent_all(str); free(str); if(ret != 0) { str = strdup("rmdir /s /q "); str = append_free(str, qconftemp_path); ret = run_silent_all(str); free(str); } #else str = strdup("rm -rf "); str = append_free(str, path); ret = system(str); free(str); #endif if(ret == 0) return 1; else return 0; } static int gen_file(qcdata_t *q, const char *name, const char *dest) { int at; char *str, *npath; FILE *fp; at = find_file(q->files, q->files_count, name); if(at == -1) return 0; str = strdup(dest); str = append_free(str, "/"); str = append_free(str, name); npath = separators_to_native(str); free(str); fp = fopen(npath, "wb"); free(npath); if(!fp) return 0; /*if(*/fwrite(q->files[at].data, q->files[at].size, 1, fp);/* < 1) { fclose(fp); return 0; }*/ fclose(fp); return 1; } static int gen_files(qcdata_t *q, const char *dest) { if(!gen_file(q, "modules.cpp", dest)) return 0; if(!gen_file(q, "modules_new.cpp", dest)) return 0; if(!gen_file(q, "conf4.h", dest)) return 0; if(!gen_file(q, "conf4.cpp", dest)) return 0; if(!gen_file(q, "conf4.pro", dest)) return 0; return 1; } static int try_make(const char *makecmd, char **maketool) { char *str; int ret; str = strdup(makecmd); str = append_free(str, " clean"); ret = run_silent_all(str); free(str); if(ret != 0) return 0; if(run_conflog_all(makecmd) != 0) return 0; *maketool = strdup(makecmd); return 1; } static char *maketool_list[] = { "make", "mingw32-make", "nmake", NULL }; static int do_conf_create(qcdata_t *q, const char *qmake_path, char **maketool) { char *str; int n; int at; if(!qc_ensuredir(qconftemp_path)) return 0; if(!gen_files(q, qconftemp_path)) return 0; if(!qc_chdir(qconftemp_path)) return 0; // TODO: support -spec once QC_MAKESPEC matters str = strdup(qmake_path); str = append_free(str, " conf4.pro"); if(run_silent_stdout(str) != 0) { free(str); qc_chdir(".."); return 0; } free(str); at = -1; for(n = 0; maketool_list[n]; ++n) { if(qc_verbose) printf("Trying \"%s\"\n", maketool_list[n]); if(try_make(maketool_list[n], maketool)) { at = n; break; } } qc_chdir(".."); if(at == -1) return 0; return 1; } static int do_conf_run() { char *str, *npath; int ret; str = strdup(qconftemp_path); str = append_free(str, "/conf"); npath = separators_to_native(str); free(str); ret = system(npath); free(npath); return ret; } static void cleanup_qconftemp() { qc_removedir(qconftemp_path); } static void try_print_var(const char *var, const char *val) { printf("%s=", var); if(val) printf("%s", val); printf("\n"); } static int do_conf(qcdata_t *q, const char *argv0) { char *qmake_path; char *maketool; int n; int ret; printf("Configuring %s ...\n", q->pro_name); if(qc_verbose) { printf("\n"); for(n = 0; n < q->args_count; ++n) try_print_var(q->args[n].envvar, q->args[n].val); } printf("Verifying Qt 4 build environment ... "); fflush(stdout); if(qc_verbose) printf("\n"); qmake_path = find_qmake(); if(!qmake_path) { if(qc_verbose) printf(" -> fail\n"); else printf("fail\n"); printf("\n"); printf("Reason: Unable to find the 'qmake' tool for Qt 4.\n"); printf("\n"); printf("%s", q->qtinfo); return 0; } if(qc_verbose) printf("qmake found in %s\n", qmake_path); // TODO: in verbose mode, print out default makespec and what we're // overriding the makespec to (if any). since at this time we don't // ever override the makespec on windows, we don't need this yet. cleanup_qconftemp(); maketool = NULL; if(!do_conf_create(q, qmake_path, &maketool)) { cleanup_qconftemp(); if(qc_verbose) printf(" -> fail\n"); else printf("fail\n"); printf("\n"); printf("Reason: There was an error compiling 'conf'. See conf.log for details.\n"); printf("\n"); printf("%s", q->qtinfo); if(qc_verbose) { printf("conf.log:\n"); system("type conf.log"); } free(qmake_path); return 0; } set_envvar("QC_COMMAND", argv0); set_envvar("QC_PROFILE", q->pro_file); set_envvar("QC_QMAKE", qmake_path); // TODO: unix configure will set QC_MAKESPEC here if it needs to // override the mkspec. currently, it only does this for macx-xcode // so the behavior doesn't apply to windows yet. set_envvar("QC_MAKETOOL", maketool); free(qmake_path); ret = do_conf_run(); if(ret == 1) { cleanup_qconftemp(); printf("\n"); free(maketool); return 0; } else if(ret != 0) { cleanup_qconftemp(); if(qc_verbose) printf(" -> fail\n"); else printf("fail\n"); printf("\n"); printf("Reason: Unexpected error launching 'conf'\n"); printf("\n"); free(maketool); return 0; } cleanup_qconftemp(); printf("\n"); printf("Good, your configure finished. Now run %s.\n", maketool); printf("\n"); free(maketool); return 1; } int main(int argc, char **argv) { unsigned char *data; unsigned int size; qcdata_t *q; int n; int at; int quit; char *arg, *var, *val; if(!embed_get_data(argv[0], &data, &size)) { fprintf(stderr, "Error: Can't import data.\n"); return 1; } q = parse_data(data, size); if(!q) { fprintf(stderr, "Error: Can't parse internal data.\n"); free(data); return 1; } if(q->usage) { val = find_replace(q->usage, "$0", argv[0]); free(q->usage); q->usage = val; } quit = 0; for(n = 1; n < argc && !quit; ++n) { arg = argv[n]; if(arg[0] != '-' || arg[1] != '-') { printf("%s", q->usage); quit = 1; break; } at = index_of(arg + 2, '='); if(at != -1) { var = alloc_str((unsigned char *)arg + 2, at); val = strdup(arg + 2 + at + 1); } else { var = strdup(arg + 2); val = 0; } if(strcmp(var, "help") == 0) { printf("%s", q->usage); quit = 1; } else if(strcmp(var, "verbose") == 0) { qc_verbose = 1; set_envvar("QC_VERBOSE", "Y"); } else { at = find_arg(q->args, q->args_count, var); if(at != -1) { // keep a stash of ex_qtdir if(strcmp(var, "qtdir") == 0) { if(ex_qtdir) free(ex_qtdir); ex_qtdir = strdup(val); } if(q->args[at].val) free(q->args[at].val); if(q->args[at].type == ArgValue) q->args[at].val = strdup(val); else // ArgFlag q->args[at].val = strdup("Y"); set_envvar(q->args[at].envvar, q->args[at].val); } else { printf("%s", q->usage); quit = 1; } } free(var); if(val) free(val); } if(quit) { qcdata_delete(q); if(ex_qtdir) free(ex_qtdir); return 1; } n = do_conf(q, argv[0]); qcdata_delete(q); if(ex_qtdir) free(ex_qtdir); if(n) return 0; else return 1; } qconf-1.5/src/configexe/configexe.pro000066400000000000000000000002221206613545200177140ustar00rootroot00000000000000CONFIG += console CONFIG -= qt app_bundle TARGET = configexe_stub CONFIG += release HEADERS += \ embed.h SOURCES += \ embed.c \ configexe.c qconf-1.5/src/configexe/configexe_stub.exe000077500000000000000000000300001206613545200207320ustar00rootroot00000000000000MZ@ !L!This program cannot be run in DOS mode. $PEL3J 8 ,0@`w P.textL `P`.dataX0$@0.bss@@.idataP*@0U]E1ۉu1=wC=r[$1҉T$tzt$л؋u]]=twJ=t؋u]]=t[=u$1t$ptjt$=$D$@vl$ 1D$t0R$ ?$L$%$ D$ 'US$$@% EED$0@$@@D$ ED$@@D$0@@td(0@tQ@t0@@D$tQ@@0$CtQ@t(0@@D$tQ@@P$ (0@>D$@@D$@@$u $D$tQ@@$tQ@@U$`Q@&U$`Q@&U Q@]t&U |Q@]ᐐU]gUM]QQQÍv'Ul!WVS=0@1ۉ<$019 :B19|F $0@t$D$$E_\$0@\$$1ɍTD)AB~D2 L$\$$8E $1!$0@T$f$B1$@  D$T$ |$$)1ۉ;}:t&)9ȋ94t?C;|̋@ @1ۋ$e[^_]Ãtŋ);}륋1|$؋)؉D$$uL$1ۉ4$T$ T$}O4$$3|$4$D$ D$:~"$ E 0E84$U}ǍB]u։$$Ét$|$؋u]}]Í'U($U]u}EËE $MƉ)E@$NjUE<$T$D$gt$EU T$$OU>Mu)ӋU)uʉUM\$ʉT$$E]u8}]Í&U$]Éut$‰$$]u]Í&'UWVS F1PG9~~JF$OFD$@FD t͉$G,9~ ^1~-1ېt&F G$F D $9~ڋFu$Fu,4$ [^_]É$D$Ftԉ$4$ [^_]Ð&U$]uƉ}<$D$$Ét$$yf=|$$$]u}]Ív'UVSÉ$$$19}&'<2/tB9|[^]2\B쐍t&UX]u}$Y0@ÍED$$$uu ]u}]É<$Z]1u}]ÍvU$]u0@R$$]u]fU$bɅÐ&UWV1SE@ UUEz9}01ۍ'EUD$$StF 9|1[^_]ÃtE$30@UZ4$X$0@D$$=1tt$ D$EH TT$D$j4$cU]u$0@0@4$u ]u]$0@b0@P4$]u]Í&'UWVSb ED$ED$U $'u7tQ@\$L$@D$ $0@qe[^_]Ëu$ %Eԉ4$‰ƉM<$uԉF$FVEv'<$EƋEԋUЋ@UȉẺMȋỦ<$MԉƉ‰Y_UȋMԋuȉDQGEЉD1D E9A<$UԉB@$/EMԉA A1x&<$ƋEԉ@ EĉxMĉ <$XƋEԋ@ E4$xMD UԋxB Dt$|$$EЋUԋxB tuЃ 9rx^<$Ɖ‰8UB<$‰ƉMA<$‰uԅFEԋt_U :$1@$Ƹ1@D$c)؃ |$‰؉4$E؋Mԋ$xE؋uԉEU9UEs&'Mu ;-{-K1ҍCt&=B u$ EEuܿ1@tduܿ 1@U1ۋEԋr@9|}6M܉L$|$;XC9|֋Uԋ$1@D$ EM܉ $W E؅t u؉4$E EE9E1҃}…Et>E@@$ 1@1@ @@]끋U MԋAUD$$!1@M @@$81@4 tQ@ $ @@@@Dž @@)HaE0@$ 0@^1@$E?P" @@$j1@I $ E $t1@1 $ - uԋF$1@D$O @@H<$ 1ۋE @@1e[^_]á @@$1@ t = @@$1@ $ $1@x $ t uԋF$1@D$ W$1@$ U$ 4 P$ 1! Eԋ@ UԋBL\ $1@L$( t\$$1@ $ F M9q$1@ $2@ <$AZE܍D3$ E7]Cuܿ2@u)@@4E؉$ @@UԋR|]|D |TuZU؉$m |D EԋHET D +$= Uԋ$1@D$ E$1@ |D3 $2@ @@$j1@ 8|$$D2@ tQ@$X2@@D$ "D$D$7 E${2@E$2@E$2@Eh$2@EP0@]><$ E2@pE$2@[E$EE$utRU$2@$2@4h$uԋv|$M $E0@EtwE @@t u$2@t$E0@EU$2@E EM $GM EM 0@Mu2@}U2@EԋP3@o 3@cU3@V<$0@$ 3@E<$U$"MÉ $ @@$j1@$ $(3@$ E$7u4$R3@EE$EE$U4$EUU$1@l$ E$h3@D$6$ E$:U80@8t80@BR80@uÍ&US8.@t)t'8.@Ku$'@Y[]1=<.@ @<.@u뾍'U@@@t]f]@@@냐U@@Q@@@r]ÐUSX5 PX1ة 1%ft P@@t P@@t P@@t P@@t P@@ t P@@@ t P@@=v,P@@@t P@@[]à P@@M[ P@@]ÐU]ÐU@@]HUBSdT$U1ۉT$$0Q@ u=Jx|*Au Jy;Tu؋]$3@3@T$D$$ 4@3@\$L$'UWVS=@@te[^_]EAAAA3@}EAAAAEAAAAE3@EAAAAEAAAAE3@EAAAAEAAAAE3@EAAAAEġ3@Eȡ3@E̡3@EС3@E3@fE؉<$,Q@q$TQ$1ɾTL$t$C.@C)@p@@Tt@@C(CH0@SL0@C@@C,S C0P0@T0@C4@@S8@@C<@@CDS@CH\0@X0@SPCL!ȃ$ A*HJy硘3@h3@l3@p3@t3@x3@|3@E3@E3@fEH$$Q@uB1҅u$<$,Q@/É@@C@@C@@e[^_]É9؉uKQ=r -) ̋@%HQ@%DQ@%hQ@%XQ@%Q@%\Q@%Q@%TQ@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%lQ@%pQ@%xQ@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%Q@%dQ@%Q@%Q@%(Q@%8Q@%4Q@U](.@h0@0@0@0@0@@H.@QCONF_CONFIGWIN_BLOCKSIG%08xrbmakemingw32-makenmakeqconftemp/bin/qmake.exe >NUL 2>&1/wbdeltree /y rmdir /s /q Error: Can't import data. $0helpverbose%sYQC_VERBOSEConfiguring %s ... Verifying Qt 4 build environment ... modules.cpp -> failReason: There was an error compiling 'conf'. See conf.log for details.QTDIRfailReason: Unable to find the 'qmake' tool for Qt 4.%s=conf.log:type conf.logqtdirWarning: qmake not found via %%QTDIR%% qmake found in %s Error: Can't parse internal data. modules_new.cppconf4.hconf4.cppconf4.pro conf4.pro >NUL..Warning: qmake not found via --qtdirTrying "%s" cleanQC_COMMANDQC_PROFILEQC_QMAKEQC_MAKETOOL/confReason: Unexpected error launching 'conf' >..\conf.log 2>&1Good, your configure finished. Now run %s. -LIBGCCW32-EH-3-SJLJ-GTHR-MINGW32w32_sharedptr->size == sizeof(W32_EH_SHARED)../../gcc-3.4.5/gcc/config/i386/w32-shared-ptr.cGetAtomNameA (atom, s, sizeof(s)) != 0TP T$QtP$TDQPTTQQQ RR&R_putenvQ_strdup'__getmainargs<__p__environ>__p__fmodeP__set_app_typeo_asserty_cexit{_chdir_errno_iobY_mkdir^_onexit_setmode_statabortatexit-fclose0fflush8fopen>fread?freeCfseekEftellGfwriteKgetenvrmallocxmemcpyzmemsetprintfputcharputssignalsprintfstrcatstrcmpstrcpystrlenstrstrsystemPPPPPPKERNEL32.dllPPmsvcrt.dll(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(Pmsvcrt.dllqconf-1.5/src/configexe/embed.c000066400000000000000000000070351206613545200164540ustar00rootroot00000000000000/* Copyright (C) 2009 Justin Karneges This file is free software; unlimited permission is given to copy and/or distribute it, with or without modifications, as long as this notice is preserved. */ #include "embed.h" #include #include #include #if defined(WIN32) || defined(_WIN32) # define QC_OS_WIN # include #endif // this hash stuff is total overkill but i was bored static const char *BLOCKSIG_ID = "QCONF_CONFIGWIN_BLOCKSIG"; static unsigned int calc_hash(const char *in, int len) { unsigned int x; int n; x = 0; for(n = 0; n < len; ++n) { x <<= 4; x ^= (unsigned int)in[n]; } return x; } // result should be "QCONF_CONFIGWIN_BLOCKSIG_68b7e7d7" // // the basic idea here is that we use this string as a marker for our // appended data section, but we don't want to include this actual // string in our code otherwise it could be misinterpretted as the // marker static char *blocksig() { char *blocksig_data; int idlen; unsigned int hash; char hashstr[9]; int n; idlen = strlen(BLOCKSIG_ID); hash = calc_hash(BLOCKSIG_ID, idlen); blocksig_data = (char *)malloc(idlen + 1 + 8 + 1); memcpy(blocksig_data, BLOCKSIG_ID, idlen); blocksig_data[idlen] = '_'; sprintf(hashstr, "%08x", hash); for(n = 0; n < 8; ++n) blocksig_data[idlen + 1 + n] = hashstr[n]; blocksig_data[idlen + 1 + 8] = 0; return blocksig_data; } static char *app_file_path(const char *argv0) { #ifdef QC_OS_WIN char module_name[MAX_PATH+1]; (void)argv0; GetModuleFileNameA(0, module_name, MAX_PATH); module_name[MAX_PATH] = 0; return strdup(module_name); #else return strdup(argv0); #endif } static int find_partial(const char *in, int in_size, const char *sub, int sub_size) { int n; int size; for(n = 0; n < in_size; ++n) { if(sub_size < in_size - n) size = sub_size; else size = in_size - n; if(memcmp(in + n, sub, size) == 0) return n; } return -1; } static int seek_string(FILE *fp, const char *str) { char block[8192]; int str_at; int str_len; int size; int ret; int pos; str_len = strlen(str); str_at = 0; pos = ftell(fp); while(!feof(fp)) { size = fread(block, 1, 8192, fp); if(size < 1) break; ret = find_partial(block, size, str + str_at, str_len - str_at); if(ret != -1) { if(str_at + (size - ret) >= str_len) { if(fseek(fp, pos + ret - str_at + str_len, SEEK_SET) != 0) return 0; return 1; } else str_at += (size - ret); } pos += size; } return 0; } unsigned int read32(const unsigned char *in) { unsigned int out = in[0]; out <<= 8; out += in[1]; out <<= 8; out += in[2]; out <<= 8; out += in[3]; return out; } // format is: // static int import_data(const char *argv0, const char *sig, unsigned char **ret_data, unsigned int *ret_size) { char *fname; FILE *fp; int ret; unsigned char buf[4]; unsigned int size; unsigned char *data; fname = app_file_path(argv0); if(!fname) return 0; fp = fopen(fname, "rb"); if(!fp) return 0; if(!seek_string(fp, sig)) return 0; ret = fread(buf, 4, 1, fp); if(ret < 1) return 0; size = read32(buf); data = (unsigned char *)malloc(size); if(!data) return 0; ret = fread(data, size, 1, fp); if(ret < 1) { free(data); return 0; } fclose(fp); *ret_data = data; *ret_size = size; return 1; } int embed_get_data(const char *argv0, unsigned char **ret_data, unsigned int *ret_size) { char *sig; int ret; sig = blocksig(); //printf("%s\n", sig); ret = import_data(argv0, sig, ret_data, ret_size); free(sig); return ret; } qconf-1.5/src/configexe/embed.h000066400000000000000000000005711206613545200164570ustar00rootroot00000000000000/* Copyright (C) 2009 Justin Karneges This file is free software; unlimited permission is given to copy and/or distribute it, with or without modifications, as long as this notice is preserved. */ #ifndef EMBED_H #define EMBED_H unsigned int read32(const unsigned char *in); int embed_get_data(const char *argv0, unsigned char **ret_data, unsigned int *ret_size); #endif qconf-1.5/src/qconf.cpp000066400000000000000000001257221206613545200151030ustar00rootroot00000000000000/* * qconf.cpp - main qconf source * Copyright (C) 2003-2009 Justin Karneges * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include // for chmod #include #include #include "stringhelp.h" #define VERSION "1.5" #define CONF_USAGE_SPACE 4 #define CONF_WRAP 78 bool looksLikeInPlace(const QString &path) { QFileInfo confinfo(path + "/conf"); QFileInfo modulesinfo(path + "/modules"); if(confinfo.exists() && confinfo.isDir() && modulesinfo.exists() && modulesinfo.isDir()) return true; return false; } QString escapeFile(const QString &str) { QString out; for(int n = 0; n < (int)str.length(); ++n) { if(str[n] == '$' || str[n] == '`') out += '\\'; out += str[n]; } return out; } QString escapeArg(const QString &str) { QString out; for(int n = 0; n < (int)str.length(); ++n) { if(str[n] == '-') out += '_'; else out += str[n]; } return out; } QString c_escape(const QString &in) { QString out; for(int n = 0; n < in.length(); ++n) { /*if(in[n] == '\\') out += "\\\\"; else*/ if(in[n] == '\"') out += "\\\""; else if(in[n] == '\n') out += "\\n"; else out += in[n]; } return out; } QString echoBlock(int tabs, const QString &in) { QStringList pars = in.split('\n', QString::KeepEmptyParts); if(!pars.isEmpty() && pars.last().isEmpty()) pars.removeLast(); QStringList lines; int n; for(n = 0; n < pars.count(); ++n) { QStringList list = wrapString(pars[n], CONF_WRAP); for(int n2 = 0; n2 < list.count(); ++n2) lines.append(list[n2]); } QString str; for(n = 0; n < lines.count(); ++n) { QString out; out.fill(9, tabs); // 9 == tab character if(lines[n].isEmpty()) out += QString("printf \"\\n\"\n"); else out += QString("printf \"%1\\n\"\n").arg(c_escape(lines[n])); str += out; } return str; } QString formatBlock(const QString &in) { QStringList pars = in.split('\n', QString::KeepEmptyParts); if(!pars.isEmpty() && pars.last().isEmpty()) pars.removeLast(); QStringList lines; int n; for(n = 0; n < pars.count(); ++n) { QStringList list = wrapString(pars[n], CONF_WRAP); for(int n2 = 0; n2 < list.count(); ++n2) lines.append(list[n2]); } QString str; for(n = 0; n < lines.count(); ++n) str += lines[n] + '\n'; return str; } static void write32(quint8 *out, quint32 i) { out[0] = (i >> 24) & 0xff; out[1] = (i >> 16) & 0xff; out[2] = (i >> 8) & 0xff; out[3] = i & 0xff; } static QByteArray lenval(const QByteArray &in) { QByteArray out; out.resize(4); write32((quint8 *)out.data(), in.size()); out += in; return out; } static QByteArray embed_file(const QString &name, const QByteArray &data) { QByteArray out; out += lenval(name.toLatin1()); out += lenval(data); return out; } // eat double-backslashes on windows, as we don't need the extra escaping to // satisfy the unix shell script static QByteArray filter_backslashes(const QByteArray &in) { QByteArray out; bool inbs = false; for(int n = 0; n < in.size(); ++n) { if(in[n] == '\\') { if(inbs) { inbs = false; continue; } inbs = true; } else inbs = false; out += in[n]; } return out; } static QByteArray get_configexe_stub() { QFile f; f.setFileName(":/configexe/configexe_stub.exe"); if(!f.open(QIODevice::ReadOnly)) { // for debugging purposes, if .exe stub isn't found, use // possible unix stub f.setFileName(":/configexe/configexe_stub"); if(!f.open(QIODevice::ReadOnly)) return QByteArray(); } return f.readAll(); } const char *qt4_info_str = "Be sure you have a proper Qt 4.0 build environment set up. This means not just Qt, " "but also a C++ compiler, a make tool, and any other packages necessary " "for compiling C++ programs.\n" "\n" "If you are certain everything is installed, then it could be that Qt 4 is not being " "recognized or that a different version of Qt is being detected by mistake (for example, " "this could happen if \\$QTDIR is pointing to a Qt 3 installation). At least one of " "the following conditions must be satisfied:\n" "\n" " 1) --qtdir is set to the location of Qt\n" " 2) \\$QTDIR is set to the location of Qt\n" " 3) QtCore is in the pkg-config database\n" " 4) qmake is in the \\$PATH\n" "\n" "This script will use the first one it finds to be true, checked in the above order. #3 and #4 are the " "recommended options. #1 and #2 are mainly for overriding the system configuration.\n" "\n"; const char *qt4_info_str_win = "Be sure you have a proper Qt 4.0 build environment set up. This means not just Qt, " "but also a C++ compiler, a make tool, and any other packages necessary " "for compiling C++ programs.\n" "\n" "If you are certain everything is installed, then it could be that Qt 4 is not being " "recognized or that a different version of Qt is being detected by mistake (for example, " "this could happen if %QTDIR% is pointing to a Qt 3 installation). At least one of " "the following conditions must be satisfied:\n" "\n" " 1) --qtdir is set to the location of Qt\n" " 2) %QTDIR% is set to the location of Qt\n" "\n" "This program will use the first one it finds to be true, checked in the above order.\n" "\n"; class ConfUsageOpt { public: ConfUsageOpt(const QString &_name="", const QString &_arg="", const QString &_desc="") { name = _name; arg = _arg; desc = _desc; } QString generateFirst() const { QString line = QString(" --%1").arg(name); if(!arg.isEmpty()) line += QString("=[%1]").arg(arg); return line; } QString generate(int indent, int width) const { QString str; QStringList descLines = wrapString(desc, width); bool first = true; //printf("lines:%d,indent:%d\n", descLines.count(), indent); for(QStringList::ConstIterator it = descLines.begin(); it != descLines.end(); ++it) { QString line; if(first) { line = generateFirst(); first = false; } while((int)line.length() < indent) line += ' '; line += *it; str += line + '\n'; } return str; } QString name, arg, desc; }; class ConfOpt { public: ConfOpt(const QString &_name="", const QString &_arg="", const QString &_var="", const QString &_desc="") { name = _name; arg = _arg; var = _var; desc = _desc; } QString name, arg, var, desc; }; class ConfGen { public: QList mainopts; QList appopts; QList depopts; QList all; QString name; QString profile; QByteArray filemodulescpp, filemodulesnewcpp, fileconfh, fileconfcpp, fileconfpro; bool libmode, usePrefix, useBindir, useIncdir, useLibdir, useDatadir; bool qt4, byoq; ConfGen() { libmode = false; usePrefix = true; useBindir = true; useIncdir = false; useLibdir = false; useDatadir = false; qt4 = false; byoq = false; // extra //extraopts += ConfOpt("zlib-inc", "path", "QC_ZLIB_INC", "Specify path to zlib include files."); //extraopts += ConfOpt("zlib-lib", "path", "QC_ZLIB_LIB", "Specify path to zlib library files."); //extraopts += ConfOpt("disable-dnotify", "", "QC_DISABLE_DNOTIFY", "Disable Linux DNOTIFY."); } void addDepOption(const QString &name, const QString &arg, const QString &var, const QString &desc) { ConfOpt opt; opt.name = name; opt.arg = arg; opt.var = var; opt.desc = desc; depopts += opt; } void addAppOption(const QString &name, const QString &arg, const QString &var, const QString &desc) { ConfOpt opt; opt.name = name; opt.arg = arg; opt.var = var; opt.desc = desc; appopts += opt; } void addOption(const QString §ion, const QString &name, const QString &arg, const QString &var, const QString &desc) { if(section == "project") addAppOption(name, arg, var, desc); else addDepOption(name, arg, var, desc); } QByteArray generate() { // main options mainopts.clear(); if(usePrefix) { mainopts += ConfOpt("prefix", "path", "PREFIX", "Base path for build/install. Default: /usr/local"); if(useBindir) mainopts += ConfOpt("bindir", "path", "BINDIR", "Directory for binaries. Default: PREFIX/bin"); if(useIncdir) mainopts += ConfOpt("includedir", "path", "INCDIR", "Directory for headers. Default: PREFIX/include"); if(useLibdir) mainopts += ConfOpt("libdir", "path", "LIBDIR", "Directory for libraries. Default: PREFIX/lib"); if(useDatadir) mainopts += ConfOpt("datadir", "path", "DATADIR", "Directory for data. Default: PREFIX/share"); } if(!byoq) mainopts += ConfOpt("qtdir", "path", "EX_QTDIR", "Directory where Qt is installed."); if(libmode) mainopts += ConfOpt("static", QString(), "QC_STATIC", "Create a static library instead of shared."); QString str; str += genHeader(); str += genUsage(); str += genFindStuff(); str += genQtInfo(); // combine main and extra opts together all = mainopts + appopts + depopts; /*str += "# save environment variable\n" "ORIG_QTDIR=$QTDIR\n\n";*/ // argument parsing str += createConfArgsSection(); // set the builtin defaults if(usePrefix) { str += "PREFIX=${PREFIX:-/usr/local}\n"; if(useBindir) str += "BINDIR=${BINDIR:-$PREFIX/bin}\n"; if(useIncdir) str += "INCDIR=${INCDIR:-$PREFIX/include}\n"; if(useLibdir) str += "LIBDIR=${LIBDIR:-$PREFIX/lib}\n"; if(useDatadir) str += "DATADIR=${DATADIR:-$PREFIX/share}\n"; } str += '\n'; str += QString("echo \"Configuring %1 ...\"\n\n").arg(name); // display values str += "if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n"; str += "echo\n"; for(QList::ConstIterator it = all.begin(); it != all.end(); ++it) { const ConfOpt &i = *it; str += QString("echo %1=$%2\n").arg(i.var).arg(i.var); } str += "echo\n"; str += "fi\n\n"; if(qt4) { if(byoq) { str += "printf \"Preparing internal Qt 4 build environment ... \"\n\n"; str += "cd byoq\n"; str += "./byoq build\n"; str += "ret=\"$?\"\n"; str += "cd ..\n"; str += "if [ \"$ret\" != \"0\" ]; then\n"; str += " exit 1\n"; str += "fi\n"; str += "unset QTDIR\n"; str += "unset QMAKESPEC\n"; // NOTE: if this is ever uncommented, remember // that exporting with a set is a bashism //str += "if [ \"$QMAKESPEC\" == \"\" ]; then\n"; //str += " export QMAKESPEC=linux-g++\n"; //str += "fi\n"; str += "qm=$PWD/byoq/qt/bin/qmake\n\n"; } str += "printf \"Verifying Qt 4 build environment ... \"\n\n"; if(!byoq) str += genQt4Checks(); } else { str += "printf \"Verifying Qt 3.x Multithreaded (MT) build environment ... \"\n\n"; str += genQt3Checks(); } str += genEmbeddedFiles(); // export all values for(QList::ConstIterator it = all.begin(); it != all.end(); ++it) { const ConfOpt &i = *it; str += QString("export %1\n").arg(i.var); } str += "export QC_VERBOSE\n"; // export verbose flag also str += genDoQConf(); // newer versions have this stuff in the conf program if(!qt4) { str += genRunExtra(); str += genRunQMake(); } str += genFooter(); return str.toLatin1(); } QByteArray generateExe() { // main options mainopts.clear(); mainopts += ConfOpt("qtdir", "path", "EX_QTDIR", "Directory where Qt is installed."); if(libmode) mainopts += ConfOpt("static", QString(), "QC_STATIC", "Create a static library instead of shared."); // combine main and extra opts together all = mainopts + appopts + depopts; QByteArray out = get_configexe_stub(); QByteArray sig = "QCONF_CONFIGWIN_BLOCKSIG_68b7e7d7"; QByteArray datasec = makeDatasec(); out += sig; out += lenval(datasec); return out; } QByteArray makeDatasec() const { QByteArray out; QByteArray buf(4, 0); out += lenval(genUsageOutput().toLatin1()); write32((quint8 *)buf.data(), all.count()); out += buf; for(int n = 0; n < all.count(); ++n) { const ConfOpt &i = all[n]; out += lenval(i.name.toLatin1()); out += lenval(i.var.toLatin1()); if(!i.arg.isEmpty()) out += (char)0; else out += (char)1; } write32((quint8 *)buf.data(), 5); out += buf; out += embed_file("modules.cpp", filter_backslashes(filemodulescpp)); out += embed_file("modules_new.cpp", filter_backslashes(filemodulesnewcpp)); out += embed_file("conf4.h", filter_backslashes(fileconfh)); out += embed_file("conf4.cpp", filter_backslashes(fileconfcpp)); out += embed_file("conf4.pro", filter_backslashes(fileconfpro)); out += lenval(name.toLatin1()); out += lenval(profile.toLatin1()); out += lenval(formatBlock(qt4_info_str_win).toLatin1()); return out; } private: QString genHeader() { QString str = QString( "#!/bin/sh\n" "#\n" "# Generated by qconf %1 ( http://delta.affinix.com/qconf/ )\n" "#\n" "\n" ).arg(VERSION); return str; } QString genFooter() { QString str = "echo\n"; //"if [ \"$QTDIR\" != \"$ORIG_QTDIR\" ]; then\n" //" echo Good, your configure finished. Now run \\'QTDIR=$QTDIR make\\'.\n" //"else\n" if(qt4) str += "echo \"Good, your configure finished. Now run $MAKE.\"\n"; else str += "echo \"Good, your configure finished. Now run 'make'.\"\n"; //"fi\n" str += "echo\n"; return str; } int getUsageIndent(const QList list) const { int largest = 0; for(QList::ConstIterator it = list.begin(); it != list.end(); ++it) { const ConfUsageOpt &opt = *it; QString tmp = opt.generateFirst(); if((int)tmp.length() > largest) largest = tmp.length(); } return largest; } QList optsToUsage(const QList &list) const { QList out; for(QList::ConstIterator it = list.begin(); it != list.end(); ++it) { const ConfOpt &i = *it; out += ConfUsageOpt(i.name, i.arg, i.desc); } return out; } QString genUsageSection(const QString &title, const QList &list) const { QString str; str += title; str += '\n'; int indent = getUsageIndent(list) + CONF_USAGE_SPACE; for(QList::ConstIterator it = list.begin(); it != list.end(); ++it) { const ConfUsageOpt &opt = *it; str += opt.generate(indent, CONF_WRAP - indent); } str += "\n"; return str; } QString genUsage() { QString str = "show_usage() {\ncat < list = optsToUsage(mainopts); list += ConfUsageOpt("verbose", "", "Show extra configure output."); list += ConfUsageOpt("help", "", "This help text."); str += genUsageSection("Main options:", list); if(!appopts.isEmpty()) { list = optsToUsage(appopts); str += genUsageSection("Project options:", list); } if(!depopts.isEmpty()) { list = optsToUsage(depopts); str += genUsageSection("Dependency options:", list); } str += "EOT\n}\n\n"; return str; } QString genUsageOutput() const { QString str = "Usage: $0 [OPTION]...\n\n" "This script creates necessary configuration files to build/install.\n\n"; QList list = optsToUsage(mainopts); list += ConfUsageOpt("verbose", "", "Show extra configure output."); list += ConfUsageOpt("help", "", "This help text."); str += genUsageSection("Main options:", list); if(!appopts.isEmpty()) { list = optsToUsage(appopts); str += genUsageSection("Project options:", list); } if(!depopts.isEmpty()) { list = optsToUsage(depopts); str += genUsageSection("Dependency options:", list); } return str; } QString genFindStuff() { QString str; // which str += "# which/make detection adapted from Qt\n" "which_command() {\n" " OLD_HOME=$HOME\n" " HOME=/dev/null\n" " export HOME\n" "\n" " WHICH=`which which 2>/dev/null`\n" " if echo $WHICH | grep 'shell built-in command' >/dev/null 2>&1; then\n" " WHICH=which\n" " elif [ -z \"$WHICH\" ]; then\n" " if which which >/dev/null 2>&1; then\n" " WHICH=which\n" " else\n" " for a in /usr/ucb /usr/bin /bin /usr/local/bin; do\n" " if [ -x $a/which ]; then\n" " WHICH=$a/which\n" " break;\n" " fi\n" " done\n" " fi\n" " fi\n" "\n" " if [ -z \"$WHICH\" ]; then\n" " OLD_IFS=$IFS\n" " IFS=:\n" " for a in $PATH; do\n" " if [ -x $a/$1 ]; then\n" " echo \"$a/$1\"\n" " IFS=$OLD_IFS\n" " export IFS\n" " HOME=$OLD_HOME\n" " export HOME\n" " return 0\n" " fi\n" " done\n" " IFS=$OLD_IFS\n" " export IFS\n" " else\n" " a=`\"$WHICH\" \"$1\" 2>/dev/null`\n" " if [ ! -z \"$a\" -a -x \"$a\" ]; then\n" " echo \"$a\"\n" " HOME=$OLD_HOME\n" " export HOME\n" " return 0\n" " fi\n" " fi\n" " HOME=$OLD_HOME\n" " export HOME\n" " return 1\n" "}\n" "WHICH=which_command\n" "\n"; // make str += "# find a make command\n" "if [ -z \"$MAKE\" ]; then\n" " MAKE=\n" " for mk in gmake make; do\n" " if $WHICH $mk >/dev/null 2>&1; then\n" " MAKE=`$WHICH $mk`\n" " break\n" " fi\n" " done\n" " if [ -z \"$MAKE\" ]; then\n" " echo \"You don't seem to have 'make' or 'gmake' in your PATH.\"\n" " echo \"Cannot proceed.\"\n" " exit 1\n" " fi\n" "fi\n" "\n"; return str; } QString genQtInfo() { QString str = "show_qt_info() {\n"; str += echoBlock(1, qt4_info_str); str += "}\n\n"; return str; } QString genConfArg(const QString &name, const QString &var, bool arg=true) { QString str; if(arg) { str = QString( " --%1=*)\n" //" %2=`expr \"${1}\" : \"--%3=\\(.*\\)\"`\n" //" %2=\"${1#--%3=}\"\n" " %2=$optarg\n" " shift\n" " ;;\n" "\n").arg(name).arg(var); //.arg(name); } else { str = QString( " --%1)\n" " %2=\"Y\"\n" " shift\n" " ;;\n" "\n").arg(name).arg(var); } return str; } QString createConfArgsSection() { char argsheader[] = "while [ $# -gt 0 ]; do\n" " optarg=`expr \"x$1\" : 'x[^=]*=\\(.*\\)'`\n" " case \"$1\" in\n"; char argsfooter[] = " --verbose)\n" " QC_VERBOSE=\"Y\"\n" " shift\n" " ;;\n" " --help) show_usage; exit ;;\n" " *) show_usage; exit ;;\n" " esac\n" "done\n\n"; QString str; str += argsheader; for(QList::ConstIterator it = mainopts.begin(); it != mainopts.end(); ++it) str += genConfArg((*it).name, (*it).var, !(*it).arg.isEmpty()); for(QList::ConstIterator it = appopts.begin(); it != appopts.end(); ++it) str += genConfArg((*it).name, (*it).var, !(*it).arg.isEmpty()); for(QList::ConstIterator it = depopts.begin(); it != depopts.end(); ++it) str += genConfArg((*it).name, (*it).var, !(*it).arg.isEmpty()); str += argsfooter; return str; } QString genQt3Checks() { QStringList qtloc; qtloc += "/usr/lib/qt"; qtloc += "/usr/share/qt"; qtloc += "/usr/share/qt3"; qtloc += "/usr/local/lib/qt"; qtloc += "/usr/local/share/qt"; qtloc += "/usr/lib/qt3"; qtloc += "/usr/local/lib/qt3"; qtloc += "/usr/X11R6/share/qt"; qtloc += "/usr/qt/3"; QString for_items; for(QStringList::ConstIterator it = qtloc.begin(); it != qtloc.end(); ++it) { for_items += (*it) + ' '; } QString str = "if [ -z \"$QTDIR\" ]; then\n" " if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo \\$QTDIR not set... trying to find Qt manually\n" " fi\n"; str += QString( " for p in %1; do\n" ).arg(for_items); str += " if [ -d \"$p/mkspecs\" ]; then\n" " QTDIR=$p\n" " break;\n" " fi;\n" " done\n" " if [ -z \"$QTDIR\" ]; then\n" " echo fail\n" " echo\n" " echo \"Unable to find Qt 'mkspecs'. Perhaps you need to\"\n" " echo \"install the Qt 3 development utilities. You may download\"\n" " echo \"them either from the vendor of your operating system\"\n" " echo \"or from http://www.trolltech.com/\"\n" " echo\n" " echo \"If you're sure you have the Qt development utilities\"\n" " echo \"installed, you might try using the --qtdir option.\"\n" " echo\n" " exit 1;\n" " fi\n" " if [ ! -x \"$QTDIR/bin/moc\" ]; then\n" " m=`which moc 2>/dev/null`\n" " if [ ! -x \"$m\" ]; then\n" " echo fail\n" " echo\n" " echo \"We found Qt in $QTDIR, but we were unable to locate\"\n" " echo \"the moc utility. It was not found in $QTDIR/bin\"\n" " echo \"nor in PATH. This seems to be a very unusual setup.\"\n" " echo \"You might try using the --qtdir option.\"\n" " echo\n" " exit 1;\n" " fi\n" " qtpre=`echo $m | awk '{ n = index($0, \"/bin/moc\"); if (!n) { exit 1; } print substr($0, 0, n-1); exit 0; }' 2>/dev/null`\n" " ret=\"$?\"\n" " if [ \"$ret\" != \"0\" ]; then\n" " echo fail\n" " echo\n" " echo \"We found Qt in $QTDIR, but the location of moc\"\n" " echo \"($m) is not suitable for use with this build system.\"\n" " echo \"This is a VERY unusual and likely-broken setup. You\"\n" " echo \"should contact the maintainer of your Qt package.\"\n" " echo\n" " exit 1;\n" " fi\n" " QTDIR=$qtpre\n" " fi\n" "fi\n" "\n" "if [ ! -x \"$QTDIR/bin/qmake\" ]; then\n" " if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo Warning: qmake not in \\$QTDIR/bin/qmake\n" " echo trying to find it in \\$PATH\n" " fi\n" " qm=`which qmake 2>/dev/null`\n" " if [ -x \"$qm\" ]; then\n" " if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo qmake found in $qm\n" " fi\n" " else\n" " echo fail\n" " echo\n" " echo Sorry, you seem to have a very unusual setup,\n" " echo or I missdetected \\$QTDIR=$QTDIR\n" " echo\n" " echo Please set \\$QTDIR manually and make sure that\n" " echo \\$QTDIR/bin/qmake exists.\n" " echo\n" " exit 1;\n" " fi\n" "else\n" " qm=$QTDIR/bin/qmake\n" "fi\n\n"; return str; } QString genQt4Checks() { QString str = "# run qmake -v and check version\n" "qmake_check_v4() {\n" " if [ -x \"$1\" ]; then\n" " local v=`$1 -query QT_VERSION 2>&1`\n" " vmaj=\"${v%%.*}\"\n" " case \"${v}\" in ?.?.?) [ \"$vmaj\" = 4 -o \"$vmaj\" = 5 ] && return 0 ;; esac\n" " if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo \"Warning: $1 not for Qt 4 or 5\"\n" " fi\n" " fi\n" " return 1\n" "}\n" "\n"; str += "if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo\n" "fi\n" "\n" "qm=\"\"\n" "names=\"qmake-qt5 qmake5 qmake-qt4 qmake4 qmake\"\n" "\n" "# qt4 check: --qtdir\n" "if [ -z \"$qm\" ] && [ ! -z \"$EX_QTDIR\" ]; then\n" " for n in $names; do\n" " qstr=$EX_QTDIR/bin/$n\n" " if qmake_check_v4 \"$qstr\"; then\n" " qm=$qstr\n" " break;\n" " fi\n" " done\n" "fi\n" "if [ -z \"$qm\" ] && [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo \"Warning: qmake not found via --qtdir\"\n" "fi\n" "\n" "# qt4 check: QTDIR\n" "if [ -z \"$qm\" ] && [ ! -z \"$QTDIR\" ]; then\n" " for n in $names; do\n" " qstr=$QTDIR/bin/$n\n" " if qmake_check_v4 \"$qstr\"; then\n" " qm=$qstr\n" " break;\n" " fi\n" " done\n" "fi\n" "if [ -z \"$qm\" ] && [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo \"Warning: qmake not found via \\$QTDIR\"\n" "fi\n" "\n" "# qt4 check: pkg-config\n" "if [ -z \"$qm\" ]; then\n" " str=`pkg-config QtCore --variable=exec_prefix 2>/dev/null`\n" " if [ ! -z \"$str\" ]; then\n" " for n in $names; do\n" " qstr=$str/bin/$n\n" " if qmake_check_v4 \"$qstr\"; then\n" " qm=$qstr\n" " break;\n" " fi\n" " done\n" " fi\n" "fi\n" "if [ -z \"$qm\" ] && [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo \"Warning: qmake not found via pkg-config\"\n" "fi\n" "\n" "# qt4 check: PATH\n" "if [ -z \"$qm\" ]; then\n" " for n in $names; do\n" " qstr=`$WHICH $n 2>/dev/null`\n" " if qmake_check_v4 \"$qstr\"; then\n" " qm=$qstr\n" " break;\n" " fi\n" " done\n" "fi\n" "if [ -z \"$qm\" ] && [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo \"Warning: qmake not found via \\$PATH\"\n" "fi\n" "\n" "if [ -z \"$qm\" ]; then\n" " if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo \" -> fail\"\n" " else\n" " echo \"fail\"\n" " fi\n"; str += echoBlock(1, "\n" "Reason: Unable to find the 'qmake' tool for Qt 4.\n" "\n"); str += " show_qt_info\n"; str += " exit 1;\n" "fi\n" "if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo qmake found in $qm\n" "fi\n\n"; str += "# try to determine the active makespec\n" "defmakespec=$QMAKESPEC\n" "if [ -z \"$defmakespec\" ]; then\n" " if $WHICH readlink >/dev/null 2>&1; then\n" " READLINK=`$WHICH readlink`\n" " fi\n" " if [ ! -z \"$READLINK\" ]; then\n" " qt_mkspecsdir=`$qm -query QT_INSTALL_DATA`/mkspecs\n" " if [ -d \"$qt_mkspecsdir\" ] && [ -h \"$qt_mkspecsdir/default\" ]; then\n" " defmakespec=`$READLINK $qt_mkspecsdir/default`\n" " fi\n" " fi\n" "fi\n" "\n" "if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo makespec is $defmakespec\n" "fi\n" "\n" "qm_spec=\"\"\n" "# if the makespec is macx-xcode, force macx-g++\n" "if [ \"$defmakespec\" = \"macx-xcode\" ]; then\n" " qm_spec=macx-g++\n" " QMAKESPEC=$qm_spec\n" " export QMAKESPEC\n" " if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo overriding makespec to $qm_spec\n" " fi\n" "fi\n\n"; return str; } QString genDoQConf() { QString outdir = ".qconftemp"; QString cleanup = QString("rm -rf %1").arg(outdir); QString str; str += QString("%1\n").arg(cleanup); str += QString( "(\n" " mkdir %1\n" " gen_files %2\n" " cd %3\n" ).arg(outdir).arg(outdir).arg(outdir); if(qt4) { str += " if [ ! -z \"$qm_spec\" ]; then\n" " $qm -spec $qm_spec conf4.pro >/dev/null\n" " else\n" " $qm conf4.pro >/dev/null\n" " fi\n" " $MAKE clean >/dev/null 2>&1\n" " $MAKE >../conf.log 2>&1\n"; } else { str += " $qm conf.pro >/dev/null\n" " QTDIR=$QTDIR make clean >/dev/null 2>&1\n" " QTDIR=$QTDIR make >../conf.log 2>&1\n"; } str += ")\n\n"; if(qt4) { str += QString( "if [ \"$?\" != \"0\" ]; then\n" " %1\n" " if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo \" -> fail\"\n" " else\n" " echo \"fail\"\n" " fi\n").arg(cleanup); str += echoBlock(1, "\n" "Reason: There was an error compiling 'conf'. See conf.log for details.\n" "\n"); if(!byoq) { str += " show_qt_info\n"; } str += " if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo \"conf.log:\"\n" " cat conf.log\n" " fi\n"; str += " exit 1;\n" "fi\n\n"; } else { str += QString( "if [ \"$?\" != \"0\" ]; then\n" " %1\n" " echo fail\n" " echo\n" " echo \"There was an error compiling 'conf'. Be sure you have a proper\"\n" " echo \"Qt 3.x Multithreaded (MT) build environment set up. This\"\n" " echo \"means not just Qt, but also a C++ compiler, the 'make' command,\"\n" " echo \"and any other packages necessary to compile C++ programs.\"\n" " echo \"See conf.log for details.\"\n" " if [ ! -f \"$QTDIR/lib/libqt-mt.so.3\" ]; then\n" " echo\n" " echo \"One possible reason is that you don't have\"\n" " echo \"libqt-mt.so.3 installed in $QTDIR/lib/.\"\n" " fi\n" " echo\n" " exit 1;\n" "fi\n\n").arg(cleanup); } if(qt4) { str += QString("QC_COMMAND=$0\n"); str += QString("export QC_COMMAND\n"); str += QString("QC_PROFILE=%1\n").arg(profile); str += QString("export QC_PROFILE\n"); str += QString("QC_QMAKE=$qm\n"); str += QString("export QC_QMAKE\n"); str += QString("QC_QMAKESPEC=$qm_spec\n"); str += QString("export QC_QMAKESPEC\n"); str += QString("QC_MAKETOOL=$MAKE\n"); str += QString("export QC_MAKETOOL\n"); } str += QString("%1/conf\n").arg(outdir); str += "ret=\"$?\"\n"; str += "if [ \"$ret\" = \"1\" ]; then\n"; str += QString(" %1\n").arg(cleanup); str += " echo\n"; str += " exit 1;\n"; str += "else\n"; str += " if [ \"$ret\" != \"0\" ]; then\n"; str += QString(" %1\n").arg(cleanup); if(qt4) { str += " if [ \"$QC_VERBOSE\" = \"Y\" ]; then\n" " echo \" -> fail\"\n" " else\n" " echo \"fail\"\n" " fi\n"; } else str += " echo fail\n"; str += " echo\n"; if(qt4) str += " echo \"Reason: Unexpected error launching 'conf'\"\n"; else str += " echo \"Unexpected error launching 'conf'\"\n"; str += " echo\n"; str += " exit 1;\n"; str += " fi\n"; str += "fi\n"; str += QString("%1\n\n").arg(cleanup); return str; } QString genRunExtra() { QString str = "if [ -x \"./qcextra\" ]; then\n" " ./qcextra\n" "fi\n"; return str; } QString genRunQMake() { QString str; str += "# run qmake\n"; str += QString("$qm %1\n").arg(profile); str += "if [ \"$?\" != \"0\" ]; then\n" " echo\n" " exit 1;\n" "fi\n"; if(!qt4) { str += "cat >Makefile.tmp <> Makefile.tmp\n" "rm -f Makefile\n" "cp -f Makefile.tmp Makefile\n" "rm -f Makefile.tmp\n"; } str += "\n"; return str; } QString genEmbeddedFile(const QString &name, const QByteArray &a) { QString str; str += QString("cat >%1 < args; static QCModInfo getModInfo(const QByteArray &buf) { QCModInfo info; QStringList lines = getQCMODLines(buf); for(QStringList::ConstIterator it = lines.begin(); it != lines.end(); ++it) { const QString &line = *it; int n = line.indexOf(':'); if(n == -1) continue; QString type = line.mid(0, n).toLower(); // find next non-whitespace ++n; for(; n < (int)line.length(); ++n) { if(!line[n].isSpace()) break; } QString rest = line.mid(n); if(type == "name") { info.longname = rest; } else if(type == "section") { info.section = rest; } else if(type == "arg") { QString name, arg, desc; if(!parseArg(rest, &name, &arg, &desc)) continue; QCModArg a; a.name = name; a.arg = arg; a.desc = desc; info.args += a; } } return info; } }; enum VersionMode { VersionMin, VersionExact, VersionMax, VersionAny }; class Dep { public: Dep() { required = false; disabled = false; pkgconfig = false; } QString name, longname, section; bool required; bool disabled; QList args; bool pkgconfig; QString pkgname; VersionMode pkgvermode; QString pkgver; }; class Conf { public: Conf() { libmode = false; noprefix = false; nobindir = false; useincdir = false; uselibdir = false; usedatadir = false; qt4 = false; byoq = false; } QString name, profile; QList deps; QList args; bool libmode, noprefix, nobindir, useincdir, uselibdir, usedatadir; QStringList moddirs; bool qt4, byoq; }; Conf xmlToConf(const QDomElement &e) { Conf conf; conf.name = e.elementsByTagName("name").item(0).toElement().text(); conf.profile = e.elementsByTagName("profile").item(0).toElement().text(); QDomNodeList nl = e.elementsByTagName("dep"); for(int n = 0; n < (int)nl.count(); ++n) { QDomElement i = nl.item(n).toElement(); Dep dep; dep.name = i.attribute("type"); if(dep.name == "pkg") { dep.name = i.attribute("name"); dep.longname = dep.name; dep.pkgconfig = true; dep.pkgname = i.attribute("pkgname"); QString str = i.attribute("version"); VersionMode mode = VersionAny; QString ver; if(str.startsWith(">=")) { mode = VersionMin; ver = str.mid(2); } else if(str.startsWith("<=")) { mode = VersionMax; ver = str.mid(2); } else if(!str.isEmpty()) { mode = VersionExact; ver = str; } dep.pkgvermode = mode; dep.pkgver = ver; } if(i.elementsByTagName("required").count() > 0) dep.required = true; if(i.elementsByTagName("disabled").count() > 0) dep.disabled = true; conf.deps += dep; } nl = e.elementsByTagName("arg"); for(int n = 0; n < (int)nl.count(); ++n) { QDomElement i = nl.item(n).toElement(); QCModArg a; a.name = i.attribute("name"); a.arg = i.attribute("arg"); a.desc = i.text(); conf.args += a; } if(e.elementsByTagName("lib").count() > 0) conf.libmode = true; if(e.elementsByTagName("noprefix").count() > 0) conf.noprefix = true; if(e.elementsByTagName("nobindir").count() > 0) conf.nobindir = true; if(e.elementsByTagName("incdir").count() > 0) conf.useincdir = true; if(e.elementsByTagName("libdir").count() > 0) conf.uselibdir = true; if(e.elementsByTagName("datadir").count() > 0) conf.usedatadir = true; nl = e.elementsByTagName("moddir"); for(int n = 0; n < (int)nl.count(); ++n) { QDomElement i = nl.item(n).toElement(); conf.moddirs += i.text(); } conf.qt4 = true; if(e.elementsByTagName("qt3").count() > 0) conf.qt4 = false; if(conf.qt4 && e.elementsByTagName("byoq").count() > 0) conf.byoq = true; return conf; } int main(int argc, char **argv) { QCoreApplication app(argc, argv); Conf conf; QString fname; bool skipLoad = false; if(argc < 2) { // try to find a .qc file QDir cur; QStringList list = cur.entryList(QStringList() << "*.qc"); if(list.isEmpty()) { // try to find a .pro file to work from list = cur.entryList(QStringList() << "*.pro"); if(list.isEmpty()) { printf("qconf: no .qc or .pro file found.\n"); return 1; } QFileInfo fi(cur.filePath(list[0])); conf.name = fi.baseName(); conf.profile = fi.fileName(); // save to .qc fname = conf.name + ".qc"; QFile f(fname); if(!f.open(QFile::WriteOnly | QFile::Truncate)) { printf("qconf: unable to write %s\n", qPrintable(fname)); return 1; } QDomDocument doc; QDomElement e = doc.createElement("qconf"); QDomElement i; i = doc.createElement("name"); i.appendChild(doc.createTextNode(conf.name)); e.appendChild(i); i = doc.createElement("profile"); i.appendChild(doc.createTextNode(conf.profile)); e.appendChild(i); doc.appendChild(e); QByteArray cs = doc.toString().toUtf8(); f.write(cs); f.close(); skipLoad = true; } else { fname = list[0]; } } else { QString cs = argv[1]; if(cs.left(2) == "--") { if(cs == "--help") { printf("Usage: qconf [.qc file]\n\n"); printf("Options:\n"); printf(" --version Show version number\n"); printf(" --help This help\n"); printf("\n"); return 0; } else if(cs == "--version") { printf("qconf version: %s by Justin Karneges \n", VERSION); return 0; } else { printf("Unknown option: %s\n", qPrintable(cs)); return 0; } } fname = QFile::decodeName(QByteArray(argv[1])); } if(!skipLoad) { QFile f(fname); if(!f.open(QFile::ReadOnly)) { printf("qconf: error reading %s\n", qPrintable(f.fileName())); return 1; } QDomDocument doc; if(!doc.setContent(&f)) { printf("qconf: error parsing %s\n", qPrintable(f.fileName())); return 1; } f.close(); QDomElement base = doc.documentElement(); if(base.tagName() != "qconf") { printf("qconf: bad format of %s\n", qPrintable(f.fileName())); return 1; } conf = xmlToConf(base); } // see if the appdir looks like an in-place qconf build QString appdir = QCoreApplication::applicationDirPath(); QString localDataPath; if(looksLikeInPlace(appdir)) localDataPath = appdir; QStringList moddirs; if(!conf.moddirs.isEmpty()) moddirs += conf.moddirs; QString confdirpath; if(!localDataPath.isEmpty()) { moddirs += localDataPath + "/modules"; confdirpath = localDataPath + "/conf"; } else { #ifdef DATADIR moddirs += QString(DATADIR) + "/qconf/modules"; confdirpath = QString(DATADIR) + "/qconf/conf"; #else moddirs += "./modules"; confdirpath = "./conf"; #endif } QDir confdir(confdirpath); if(!confdir.exists()) { printf("qconf: %s does not exist.\n", qPrintable(confdir.path())); return 1; } QFile f; QByteArray confh; if(conf.qt4) { f.setFileName(confdir.filePath("conf4.h")); if(!f.open(QFile::ReadOnly)) { printf("qconf: cannot read %s\n", qPrintable(f.fileName())); return 1; } confh = f.readAll(); f.close(); } f.setFileName(confdir.filePath(conf.qt4 ? "conf4.cpp" : "conf.cpp")); if(!f.open(QFile::ReadOnly)) { printf("qconf: cannot read %s\n", qPrintable(f.fileName())); return 1; } QByteArray confcpp = f.readAll(); f.close(); f.setFileName(confdir.filePath(conf.qt4 ? "conf4.pro" : "conf.pro")); if(!f.open(QFile::ReadOnly)) { printf("qconf: cannot read %s\n", qPrintable(f.fileName())); return 1; } QByteArray confpro = f.readAll(); f.close(); confpro += "\nDEFINES += HAVE_MODULES\n"; printf("Project name: %s\n", qPrintable(conf.name)); printf("Profile: %s\n", qPrintable(conf.profile)); printf("Deps: "); if(conf.deps.isEmpty()) printf("none\n"); else { bool first = true; for(QList::ConstIterator it = conf.deps.begin(); it != conf.deps.end(); ++it) { const Dep &dep = *it; printf("%s%s%s", first ? "": " ", qPrintable(dep.name), dep.required ? "*": ""); first = false; } printf("\n"); } printf("\n"); // look up dep module information QByteArray allmods; QString modscreate; for(QList::Iterator it = conf.deps.begin(); it != conf.deps.end(); ++it) { Dep &dep = *it; if(dep.pkgconfig) { QString desc = dep.longname; QString modestr = "VersionAny"; if(dep.pkgvermode != VersionAny) { if(dep.pkgvermode == VersionMin) { desc += " >= "; modestr = "VersionMin"; } else if(dep.pkgvermode == VersionMax) { desc += " <= "; modestr = "VersionMax"; } else { desc += " "; modestr = "VersionExact"; } desc += dep.pkgver; } modscreate += QString(" o = new qc_internal_pkgconfig(conf, \"%1\", \"%2\", %3, \"%4\");\n o->required = %5;\n o->disabled = %6;\n" ).arg(dep.pkgname).arg(desc).arg(modestr).arg(dep.pkgver).arg(dep.required ? "true": "false").arg(dep.disabled ? "true": "false"); continue; } // look for module QString modfname = QString("%1.qcm").arg(dep.name); QFileInfo fi; bool found = false; for(QStringList::ConstIterator mit = moddirs.begin(); mit != moddirs.end(); ++mit) { QDir moddir(*mit); fi.setFile(moddir.filePath(modfname)); //printf("checking for: [%s]\n", fi.filePath().latin1()); if(fi.exists()) { found = true; break; } } if(!found) { printf("qconf: no such module '%s'!\n", qPrintable(dep.name)); return 1; } QFile mod(fi.filePath()); if(!mod.open(QFile::ReadOnly | QFile::Text)) { printf("qconf: error opening '%s'!\n", qPrintable(mod.fileName())); return 1; } QByteArray buf = mod.readAll(); mod.close(); QCModInfo info = QCModInfo::getModInfo(buf); dep.longname = info.longname; dep.section = info.section; dep.args = info.args; // prepend #line int oldsize = buf.size(); QString str = QString("#line 1 \"%1\"\n").arg(modfname); QByteArray cs = str.toLocal8Bit(); int len = cs.length(); buf.resize(oldsize + len); memmove(buf.data() + len, buf.data(), oldsize); memcpy(buf.data(), cs.data(), len); // append to the module buffer oldsize = allmods.size(); allmods.resize(oldsize + buf.size()); memcpy(allmods.data() + oldsize, buf.data(), buf.size()); modscreate += QString(" o = new qc_%1(conf);\n o->required = %2;\n o->disabled = %3;\n" ).arg(escapeArg(dep.name)).arg(dep.required ? "true": "false").arg(dep.disabled ? "true": "false"); } QByteArray modsnew = modscreate.toLatin1(); // write configure QFile out; out.setFileName("configure"); if(!out.open(QFile::WriteOnly | QFile::Truncate)) { printf("qconf: error writing configure\n"); return 1; } ConfGen cg; cg.name = conf.name; cg.profile = conf.profile; if(conf.libmode) cg.libmode = true; if(conf.noprefix) cg.usePrefix = false; if(conf.nobindir) cg.useBindir = false; if(conf.useincdir) cg.useIncdir = true; if(conf.uselibdir) cg.useLibdir = true; if(conf.usedatadir) cg.useDatadir = true; if(conf.qt4) cg.qt4 = true; if(conf.byoq) cg.byoq = true; cg.filemodulescpp = allmods; cg.filemodulesnewcpp = modsnew; cg.fileconfh = confh; cg.fileconfcpp = confcpp; cg.fileconfpro = confpro; for(QList::Iterator it = conf.deps.begin(); it != conf.deps.end(); ++it) { Dep &dep = *it; QString longname; if(!dep.longname.isEmpty()) longname = dep.longname; else longname = dep.name; if(!dep.required && !dep.disabled) cg.addOption(dep.section, QString("disable-") + dep.name, "", QString("QC_DISABLE_") + escapeArg(dep.name), QString("Disable use of ") + longname); else if(dep.disabled) cg.addOption(dep.section, QString("enable-") + dep.name, "", QString("QC_ENABLE_") + escapeArg(dep.name), QString("Enable use of ") + longname); // extra dep args? for(QList::ConstIterator ait = dep.args.begin(); ait != dep.args.end(); ++ait) { const QCModArg &a = *ait; cg.addOption(dep.section, a.name, a.arg, QString("QC_") + escapeArg(a.name.toUpper()), a.desc); } } // extra .qc args? for(QList::ConstIterator it = conf.args.begin(); it != conf.args.end(); ++it) { const QCModArg &a = *it; cg.addAppOption(a.name, a.arg, QString("QC_") + escapeArg(a.name.toUpper()), a.desc); } QByteArray cs = cg.generate(); out.write(cs); out.close(); #ifdef Q_OS_UNIX chmod("configure", 0755); #endif printf("'configure' written.\n"); if(conf.qt4) { // write configexe out.setFileName("configure.exe"); if(!out.open(QFile::WriteOnly | QFile::Truncate)) { printf("qconf: error writing configure.exe\n"); return 1; } cs = cg.generateExe(); out.write(cs); out.close(); printf("'configure.exe' written.\n"); } return 0; } qconf-1.5/src/qconf.qrc000066400000000000000000000001611206613545200150730ustar00rootroot00000000000000 configexe/configexe_stub.exe qconf-1.5/src/stringhelp.cpp000066400000000000000000000040021206613545200161370ustar00rootroot00000000000000/* * stringhelp.cpp - string wrapping * Copyright (C) 2003-2005 Justin Karneges * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "stringhelp.h" static QString getNext(QString *str) { if(str->isEmpty()) return QString(); // are we in space? int n = 0; if(str->at(n).isSpace()) { // get out of it while(n < (int)str->length() && str->at(n).isSpace()) ++n; if(n == (int)str->length()) return QString(); } // find end or next space while(n < (int)str->length() && !str->at(n).isSpace()) ++n; QString result = str->mid(0, n); *str = str->mid(n); return result; } // wraps a string against a fixed width QStringList wrapString(const QString &str, int wid) { QStringList lines; QString cur; QString tmp = str; bool firstword = true; //printf("parsing: [%s]\n", qPrintable(tmp)); while(1) { QString word = getNext(&tmp); if(word.isNull()) { lines += cur; break; } //printf("word:[%s]\n", qPrintable(word)); if(!cur.isEmpty()) { if((int)cur.length() + (int)word.length() > wid) { lines += cur; cur = ""; } } if(cur.isEmpty() && !firstword) { // trim the whitespace in front for(int n = 0; n < (int)word.length(); ++n) { if(!word.at(n).isSpace()) { if(n > 0) word = word.mid(n); break; } } } cur += word; firstword = false; } return lines; } qconf-1.5/src/stringhelp.h000066400000000000000000000016401206613545200156110ustar00rootroot00000000000000/* * stringhelp.h - string wrapping * Copyright (C) 2003-2005 Justin Karneges * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef STRINGHELP_H #define STRINGHELP_H #include QStringList wrapString(const QString &str, int wid); #endif