#!/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 --qtdir=*) EX_QTDIR=$optarg shift ;; --static) QC_STATIC="Y" shift ;; --release) QC_RELEASE="Y" shift ;; --debug) QC_DEBUG="Y" shift ;; --debug-and-release) QC_DEBUG_AND_RELEASE="Y" shift ;; --no-separate-debug-info) QC_NO_SEPARATE_DEBUG_INFO="Y" shift ;; --separate-debug-info) QC_SEPARATE_DEBUG_INFO="Y" shift ;; --no-framework) QC_NO_FRAMEWORK="Y" shift ;; --framework) QC_FRAMEWORK="Y" shift ;; --universal) QC_UNIVERSAL="Y" shift ;; --mac-sdk=*) QC_MAC_SDK=$optarg shift ;; --disable-tests) QC_DISABLE_TESTS="Y" shift ;; --with-qca=*) QC_WITH_QCA=$optarg shift ;; --with-zlib-inc=*) QC_WITH_ZLIB_INC=$optarg shift ;; --with-zlib-lib=*) QC_WITH_ZLIB_LIB=$optarg shift ;; --verbose) QC_VERBOSE="Y" shift ;; --help) show_usage; exit ;; *) show_usage; exit ;; esac done echo "Configuring Iris ..." if [ "$QC_VERBOSE" = "Y" ]; then echo echo EX_QTDIR=$EX_QTDIR echo QC_STATIC=$QC_STATIC echo QC_RELEASE=$QC_RELEASE echo QC_DEBUG=$QC_DEBUG echo QC_DEBUG_AND_RELEASE=$QC_DEBUG_AND_RELEASE echo QC_NO_SEPARATE_DEBUG_INFO=$QC_NO_SEPARATE_DEBUG_INFO echo QC_SEPARATE_DEBUG_INFO=$QC_SEPARATE_DEBUG_INFO echo QC_NO_FRAMEWORK=$QC_NO_FRAMEWORK echo QC_FRAMEWORK=$QC_FRAMEWORK echo QC_UNIVERSAL=$QC_UNIVERSAL echo QC_MAC_SDK=$QC_MAC_SDK echo QC_DISABLE_TESTS=$QC_DISABLE_TESTS echo QC_WITH_QCA=$QC_WITH_QCA echo QC_WITH_ZLIB_INC=$QC_WITH_ZLIB_INC echo QC_WITH_ZLIB_LIB=$QC_WITH_ZLIB_LIB echo fi printf "Verifying Qt 4 build environment ... " # run qmake -v and check version qmake_check_v4() { if [ -x "$1" ]; then if echo `$1 -v 2>&1` | grep "Qt version 4\." >/dev/null 2>&1; then return 0 elif [ "$QC_VERBOSE" = "Y" ]; then echo "Warning: $1 not for Qt 4" 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 <= 4.2 -----END QCMOD----- */ class qc_qt42 : public ConfObj { public: qc_qt42(Conf *c) : ConfObj(c) {} QString name() const { return "Qt >= 4.2"; } QString shortname() const { return "qt42"; } bool exec() { conf->debug(QString("QT_VERSION = 0x%1").arg(QString::number(QT_VERSION, 16))); if(QT_VERSION >= 0x040200) return true; else return false; } }; #line 1 "buildmode.qcm" /* -----BEGIN QCMOD----- name: buildmode section: project arg: release,Build with debugging turned off (default). arg: debug,Build with debugging turned on. arg: debug-and-release,Build two versions, with and without debugging turned on (mac only). arg: no-separate-debug-info,Do not store debug information in a separate file (default for mac). arg: separate-debug-info,Strip debug information into a separate .debug file (default for non-mac). arg: no-framework,Do not build as a Mac framework. arg: framework,Build as a Mac framework (default). -----END QCMOD----- */ #define QC_BUILDMODE bool qc_buildmode_release = false; bool qc_buildmode_debug = false; bool qc_buildmode_framework = false; bool qc_buildmode_separate_debug_info = false; class qc_buildmode : public ConfObj { public: qc_buildmode(Conf *c) : ConfObj(c) {} QString name() const { return "buildmode"; } QString shortname() const { return "buildmode"; } // no output QString checkString() const { return QString(); } bool exec() { // first, parse out the options bool opt_release = false; bool opt_debug = false; bool opt_debug_and_release = false; bool opt_no_framework = false; bool opt_framework = false; bool opt_no_separate_debug_info = false; bool opt_separate_debug_info = false; if(conf->getenv("QC_RELEASE") == "Y") opt_release = true; if(conf->getenv("QC_DEBUG") == "Y") opt_debug = true; if(conf->getenv("QC_DEBUG_AND_RELEASE") == "Y") opt_debug_and_release = true; if(conf->getenv("QC_NO_FRAMEWORK") == "Y") opt_no_framework = true; if(conf->getenv("QC_FRAMEWORK") == "Y") opt_framework = true; if(conf->getenv("QC_NO_SEPARATE_DEBUG_INFO") == "Y") opt_no_separate_debug_info = true; if(conf->getenv("QC_SEPARATE_DEBUG_INFO") == "Y") opt_separate_debug_info = true; bool staticmode = false; if(conf->getenv("QC_STATIC") == "Y") staticmode = true; #ifndef Q_OS_MAC if(opt_debug_and_release) { printf("\nError: The --debug-and-release option is for mac only.\n"); exit(1); } if(opt_framework) { printf("\nError: The --framework option is for mac only.\n"); exit(1); } #endif if(opt_framework && opt_debug) { printf("\nError: Cannot use both --framework and --debug.\n"); exit(1); } // sanity check exclusive options int x; // build mode x = 0; if(opt_release) ++x; if(opt_debug) ++x; if(opt_debug_and_release) ++x; if(x > 1) { printf("\nError: Use only one of --release, --debug, or --debug-and-release.\n"); exit(1); } // framework if(opt_framework && staticmode) { printf("\nError: Cannot use both --framework and --static.\n"); exit(1); } x = 0; if(opt_no_framework) ++x; if(opt_framework) ++x; if(x > 1) { printf("\nError: Use only one of --framework or --no-framework.\n"); exit(1); } // debug info x = 0; if(opt_no_separate_debug_info) ++x; if(opt_separate_debug_info) ++x; if(x > 1) { printf("\nError: Use only one of --separate-debug-info or --no-separate-debug-info\n"); exit(1); } // now process the options if(opt_release) qc_buildmode_release = true; else if(opt_debug) qc_buildmode_debug = true; else if(opt_debug_and_release) { qc_buildmode_release = true; qc_buildmode_debug = true; } else // default qc_buildmode_release = true; if(opt_framework) qc_buildmode_framework = true; else if(opt_no_framework) { // nothing to do } else // default { if(!staticmode && !opt_debug) qc_buildmode_framework = true; } if(opt_separate_debug_info) qc_buildmode_separate_debug_info = true; else if(opt_no_separate_debug_info) { // nothing to do } else // default { #ifndef Q_OS_MAC qc_buildmode_separate_debug_info = true; #endif } // make the string QStringList opts; QString other; if(qc_buildmode_release && qc_buildmode_debug) { opts += "debug_and_release"; opts += "build_all"; } else if(qc_buildmode_release) opts += "release"; else // qc_buildmode_debug opts += "debug"; #ifdef Q_OS_MAC if(qc_buildmode_framework) opts += "lib_bundle"; #endif if(qc_buildmode_separate_debug_info) { opts += "separate_debug_info"; other += "QMAKE_CFLAGS += -g\n"; other += "QMAKE_CXXFLAGS += -g\n"; } QString str = QString("CONFIG += ") + opts.join(" ") + '\n'; conf->addExtra(str); if(!other.isEmpty()) conf->addExtra(other); return true; } }; #line 1 "universal.qcm" /* -----BEGIN QCMOD----- name: Mac universal binary support section: project arg: universal,Build with Mac universal binary support. arg: mac-sdk=[path],Path to Mac universal SDK (PPC host only). -----END QCMOD----- */ #define QC_UNIVERSAL bool qc_universal_enabled = false; QString qc_universal_sdk; //---------------------------------------------------------------------------- // qc_universal //---------------------------------------------------------------------------- class qc_universal : public ConfObj { public: qc_universal(Conf *c) : ConfObj(c) {} QString name() const { return "Mac universal binary support"; } QString shortname() const { return "universal"; } QString checkString() const { return QString(); } bool exec() { #ifdef Q_OS_MAC if(qc_getenv("QC_UNIVERSAL") == "Y") { qc_universal_enabled = true; QString str = "contains(QT_CONFIG,x86):contains(QT_CONFIG,ppc) {\n" " CONFIG += x86 ppc\n" "}\n"; QString sdk = qc_getenv("QC_MAC_SDK"); if(!sdk.isEmpty()) { str += QString("QMAKE_MAC_SDK = %1\n").arg(sdk); qc_universal_sdk = sdk; } conf->addExtra(str); } #endif return true; } }; #line 1 "qca.qcm" /* -----BEGIN QCMOD----- name: QCA >= 2.0 arg: with-qca=[path],Specify path to QCA tree, mainly for building against an uninstalled QCA. -----END QCMOD----- */ // based on crypto.prf. any changes made to that file need to be tracked here. static QString internal_crypto_prf(const QString &incdir, const QString &libdir) { QString out = QString( "QCA_INCDIR = %1\n" "QCA_LIBDIR = %2\n" "\n" "CONFIG *= qt\n" "\n" "LINKAGE =\n" "\n" "# on mac, if qca was built as a framework, link against it\n" "mac: {\n" " framework_dir = \$\$QCA_LIBDIR\n" " exists(\$\$framework_dir/qca.framework) {\n" " #QMAKE_FRAMEWORKPATH *= \$\$framework_dir\n" " LIBS += -F\$\$framework_dir\n" " INCLUDEPATH += \$\$framework_dir/qca.framework/Headers\n" " LINKAGE = -framework qca\n" " }\n" "}\n" "\n" "# else, link normally\n" "isEmpty(LINKAGE) {\n" " INCLUDEPATH += \$\$QCA_INCDIR/QtCrypto\n" " LIBS += -L\$\$QCA_LIBDIR\n" " LINKAGE = -lqca\n" " CONFIG(debug, debug|release) {\n" " windows:LINKAGE = -lqcad\n" " mac:LINKAGE = -lqca_debug\n" " }\n" "}\n" "\n" "LIBS += \$\$LINKAGE\n" ).arg(incdir, libdir); return out; } #define QC_QCA QString qc_qca_procode; //---------------------------------------------------------------------------- // qc_qca //---------------------------------------------------------------------------- class qc_qca : public ConfObj { public: qc_qca(Conf *c) : ConfObj(c) {} QString name() const { return "QCA >= 2.0"; } QString shortname() const { return "qca"; } bool exec() { // get the build mode #ifdef QC_BUILDMODE bool release = qc_buildmode_release; bool debug = qc_buildmode_debug; #else // else, default to just release mode bool release = true; bool debug = false; #endif // test for "crypto" feature and check qca version number QString qca_prefix, qca_incdir, qca_libdir, qca_crypto_prf; qca_prefix = conf->getenv("QC_WITH_QCA"); QString proextra; if(!qca_prefix.isEmpty()) { qca_incdir = qca_prefix + "/include"; qca_libdir = qca_prefix + "/lib"; qca_crypto_prf = internal_crypto_prf(qca_incdir, qca_libdir); proextra = "CONFIG += qt\n" "QT -= gui\n"; proextra += qca_crypto_prf; } else { proextra = "CONFIG += qt crypto\n" "QT -= gui\n"; } QString str = "#include \n" "\n" "int main()\n" "{\n" " unsigned long x = QCA_VERSION;\n" " if(x >= 0x020000 && x < 0x030000) return 0; else return 1;\n" "}\n"; if(release) { int ret; if(!conf->doCompileAndLink(str, QStringList(), QString(), proextra + "CONFIG += release\n", &ret)) return false; if(ret != 0) return false; } if(debug) { int ret; if(!conf->doCompileAndLink(str, QStringList(), QString(), proextra + "CONFIG += debug\n", &ret)) return false; if(ret != 0) return false; } if(!qca_prefix.isEmpty()) str = qca_crypto_prf; else str = "CONFIG += crypto\n"; qc_qca_procode = str; conf->addExtra(str); return true; } }; #line 1 "zlib.qcm" /* -----BEGIN QCMOD----- name: zlib arg: with-zlib-inc=[path],Path to zlib include files arg: with-zlib-lib=[path],Path to zlib library files -----END QCMOD----- */ //---------------------------------------------------------------------------- // qc_zlib //---------------------------------------------------------------------------- class qc_zlib : public ConfObj { public: qc_zlib(Conf *c) : ConfObj(c) {} QString name() const { return "zlib"; } QString shortname() const { return "zlib"; } bool exec() { QString inc, lib; QString s; s = conf->getenv("QC_WITH_ZLIB_INC"); if(!s.isEmpty()) { if(!conf->checkHeader(s, "zlib.h")) return false; inc = s; } else { if(!conf->findHeader("zlib.h", QStringList(), &s)) return false; inc = s; } s = conf->getenv("QC_WITH_ZLIB_LIB"); if(!s.isEmpty()) { if(!conf->checkLibrary(s, "z")) return false; lib = s; } else { if(!conf->findLibrary("z", &s)) return false; lib = s; } if(!inc.isEmpty()) conf->addIncludePath(inc); if(!lib.isEmpty()) conf->addLib(QString("-L") + s); conf->addLib("-lz"); return true; } }; #line 1 "extra.qcm" /* -----BEGIN QCMOD----- name: extra section: project arg: disable-tests,Don't build examples and unittests. -----END QCMOD----- */ class qc_extra : public ConfObj { public: qc_extra(Conf *c) : ConfObj(c) {} QString name() const { return "extra"; } QString shortname() const { return "extra"; } // no output QString checkString() const { return QString(); } bool exec() { QString str; QFile f; if(conf->getenv("QC_DISABLE_TESTS") == "Y") str += "CONFIG += no_tests\n"; conf->addExtra(str); bool release = true; bool debug = false; bool debug_info = false; bool universal = false; QString sdk; #ifdef QC_BUILDMODE release = qc_buildmode_release; debug = qc_buildmode_debug; debug_info = qc_buildmode_separate_debug_info; #endif #ifdef QC_UNIVERSAL universal = qc_universal_enabled; sdk = qc_universal_sdk; #endif // write confapp_unix.pri str = QString(); QString var = conf->getenv("BINDIR"); if(!var.isEmpty()) str += QString("BINDIR = %1\n").arg(var); if(debug) // debug or debug-and-release str += QString("CONFIG += debug\n"); else // release str += QString("CONFIG += release\n"); if(debug_info) { str += QString("CONFIG += separate_debug_info\n"); str += "QMAKE_CFLAGS += -g\n"; str += "QMAKE_CXXFLAGS += -g\n"; } if(universal) { str += "contains(QT_CONFIG,x86):contains(QT_CONFIG,ppc) {\n" " CONFIG += x86 ppc\n" "}\n"; if(!sdk.isEmpty()) str += QString("QMAKE_MAC_SDK = %1\n").arg(sdk); } #ifdef QC_QCA if(!qc_qca_procode.isEmpty()) str += qc_qca_procode; #endif f.setFileName("confapp_unix.pri"); if(f.open(QFile::WriteOnly | QFile::Truncate)) f.write(str.toLatin1()); f.close(); return true; } QString makeEscapedDefine(const QString &var, const QString &val) { QString str = QString( "DEFINES += %1=\\\\\\\\\\\\\\"%2\\\\\\\\\\\\\\"\n" ).arg(var).arg(val); return str; } }; EOT cat >$1/modules_new.cpp <required = true; o->disabled = false; o = new qc_buildmode(conf); o->required = true; o->disabled = false; o = new qc_universal(conf); o->required = true; o->disabled = false; o = new qc_qca(conf); o->required = true; o->disabled = false; o = new qc_zlib(conf); o->required = true; o->disabled = false; o = new qc_extra(conf); o->required = true; o->disabled = false; EOT cat >$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()) list = path.split(':', QString::SkipEmptyParts); 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; } } return out; } QString qc_findself(const QString &argv0) { if(argv0.contains('/')) return argv0; else return qc_findprogram(argv0); } int qc_runcommand(const QString &command, QByteArray *out, bool showOutput) { QString fullcmd = command; if(!showOutput) fullcmd += " 2>/dev/null"; FILE *f = popen(fullcmd.toLatin1().data(), "r"); if(!f) return -1; if(out) out->clear(); while(1) { char c = (char)fgetc(f); if(feof(f)) break; if(out) out->append(c); if(showOutput) fputc(c, stdout); } int ret = pclose(f); if(ret == -1) return -1; return ret; } int qc_runprogram(const QString &prog, const QStringList &args, QByteArray *out, bool showOutput) { QString fullcmd = prog; QString argstr = args.join(" "); if(!argstr.isEmpty()) fullcmd += QString(" ") + argstr; return qc_runcommand(fullcmd, out, showOutput); // TODO: use QProcess once it is fixed /* QProcess process; if(showOutput) process.setReadChannelMode(ForwardedChannels); process.start(prog, args); process.waitForFinished(-1); return process.exitCode(); */ } 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) { QDir tmp(".qconftemp"); 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" "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) *retcode = doCommand(QString("./") + out, 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; o = 0; #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=iris.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