source: trunk/src/corelib/global/qlibraryinfo.cpp@ 600

Last change on this file since 600 was 596, checked in by Dmitry A. Kuminov, 15 years ago

lrelease: Fixed the build.

File size: 19.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qdir.h"
43#include "qfile.h"
44#include "qconfig.h"
45#include "qsettings.h"
46#include "qlibraryinfo.h"
47#include "qscopedpointer.h"
48
49#if defined(QT_BUILD_QMAKE) || defined(QT_BOOTSTRAPPED)
50# define BOOTSTRAPPING
51#endif
52
53#ifdef BOOTSTRAPPING
54QT_BEGIN_NAMESPACE
55extern QString qmake_libraryInfoFile();
56QT_END_NAMESPACE
57#else
58# include "qcoreapplication.h"
59#endif
60
61#ifdef Q_OS_MAC
62# include "private/qcore_mac_p.h"
63#endif
64
65#ifdef Q_OS_OS2
66
67#include "qt_os2.h"
68
69static const char *qt_module_path()
70{
71 static char path[CCHMAXPATH] = {'\0'};
72 if (!path[0]) {
73 HMODULE hmod;
74 ULONG objNum, offset;
75 DosQueryModFromEIP(&hmod, &objNum, sizeof(path), path, &offset,
76 (ULONG)qt_module_path);
77 DosQueryModuleName(hmod, sizeof(path), path);
78 char *slash = strrchr(path, '\\');
79 if (slash)
80 *slash = '\0';
81 }
82 return path;
83}
84
85#endif // Q_OS_OS2
86
87#include "qconfig.cpp"
88
89QT_BEGIN_NAMESPACE
90
91#ifndef QT_NO_SETTINGS
92
93struct QLibrarySettings
94{
95 QLibrarySettings();
96 QScopedPointer<QSettings> settings;
97};
98Q_GLOBAL_STATIC(QLibrarySettings, qt_library_settings)
99
100class QLibraryInfoPrivate
101{
102public:
103 static QSettings *findConfiguration();
104 static void cleanup()
105 {
106 QLibrarySettings *ls = qt_library_settings();
107 if (ls)
108 ls->settings.reset(0);
109 }
110 static QSettings *configuration()
111 {
112 QLibrarySettings *ls = qt_library_settings();
113 return ls ? ls->settings.data() : 0;
114 }
115};
116
117QLibrarySettings::QLibrarySettings()
118 : settings(QLibraryInfoPrivate::findConfiguration())
119{
120#ifndef BOOTSTRAPPING
121 qAddPostRoutine(QLibraryInfoPrivate::cleanup);
122#endif
123}
124
125QSettings *QLibraryInfoPrivate::findConfiguration()
126{
127 QString qtconfig = QLatin1String(":/qt/etc/qt.conf");
128#ifdef BOOTSTRAPPING
129 if(!QFile::exists(qtconfig))
130 qtconfig = qmake_libraryInfoFile();
131#else
132 if (!QFile::exists(qtconfig) && QCoreApplication::instance()) {
133#ifdef Q_OS_MAC
134 CFBundleRef bundleRef = CFBundleGetMainBundle();
135 if (bundleRef) {
136 QCFType<CFURLRef> urlRef = CFBundleCopyResourceURL(bundleRef,
137 QCFString(QLatin1String("qt.conf")),
138 0,
139 0);
140 if (urlRef) {
141 QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
142 qtconfig = QDir::cleanPath(path);
143 }
144 }
145 if (qtconfig.isEmpty())
146#endif
147 {
148 QDir pwd(QCoreApplication::applicationDirPath());
149 qtconfig = pwd.filePath(QLatin1String("qt.conf"));
150 }
151 }
152#ifdef Q_OS_OS2
153 if (!QFile::exists(qtconfig)) {
154 // search in the directory that contains the DLL or EXE where this
155 // code is located (e.g. QtCore.dll or app.exe if Qt is a static lib)
156 qtconfig = QString::fromLocal8Bit(qt_module_path());
157 qtconfig = QDir::fromNativeSeparators(qtconfig) +
158 QLatin1String("/qt.conf");
159 qtconfig = QDir::cleanPath(qtconfig);
160
161 if (!QFile::exists(qtconfig)) {
162 // search in the system-wide location
163 qtconfig = QString::fromLocal8Bit(qgetenv("ETC"));
164 if (qtconfig.isEmpty())
165 qtconfig = QDir::rootPath();
166 qtconfig = QDir::fromNativeSeparators(qtconfig) +
167 QLatin1String("/qtsys.conf");
168 qtconfig = QDir::cleanPath(qtconfig);
169 }
170 }
171#endif
172#endif
173 if (QFile::exists(qtconfig))
174 return new QSettings(qtconfig, QSettings::IniFormat);
175 return 0; //no luck
176}
177
178/*!
179 \class QLibraryInfo
180 \brief The QLibraryInfo class provides information about the Qt library.
181
182 Many pieces of information are established when Qt is configured.
183 Installation paths, license information, and even a unique build
184 key. This class provides an abstraction for accessing this
185 information.
186
187 \table
188 \header \o Function \o Return value
189 \row \o buildKey() \o A string that identifies the Qt version and
190 the configuration. This key is used to ensure
191 that \l{plugins} link against the same version
192 of Qt as the application.
193 \row \o location() \o The path to a certain Qt
194 component (e.g., documentation, header files).
195 \row \o licensee(),
196 licensedProducts() \o Licensing information.
197 \endtable
198
199 You can also use a \c qt.conf file to override the hard-coded paths
200 that are compiled into the Qt library. For more information, see
201 the \l {Using qt.conf} documentation.
202
203 \sa QSysInfo, {Using qt.conf}
204*/
205
206/*! \internal
207
208 You cannot create a QLibraryInfo, instead only the static functions are available to query
209 information.
210*/
211
212QLibraryInfo::QLibraryInfo()
213{ }
214
215/*!
216 Returns the person to whom this build of Qt is licensed.
217
218 \sa licensedProducts()
219*/
220
221QString
222QLibraryInfo::licensee()
223{
224 const char *str = QT_CONFIGURE_LICENSEE;
225 return QString::fromLocal8Bit(str);
226}
227
228/*!
229 Returns the products that the license for this build of Qt has access to.
230
231 \sa licensee()
232*/
233
234QString
235QLibraryInfo::licensedProducts()
236{
237 const char *str = QT_CONFIGURE_LICENSED_PRODUCTS;
238 return QString::fromLatin1(str);
239}
240
241/*!
242 Returns a unique key identifying this build of Qt and its
243 configurations. This key is not globally unique, rather only useful
244 for establishing of two configurations are compatible. This can be
245 used to compare with the \c QT_BUILD_KEY preprocessor symbol.
246
247 \sa location()
248*/
249
250QString
251QLibraryInfo::buildKey()
252{
253 return QString::fromLatin1(QT_BUILD_KEY);
254}
255
256/*!
257 \since 4.6
258 Returns the installation date for this build of Qt. The install date will
259 usually be the last time that Qt sources were configured.
260*/
261#ifndef QT_NO_DATESTRING
262QDate
263QLibraryInfo::buildDate()
264{
265 return QDate::fromString(QString::fromLatin1(qt_configure_installation + 12), Qt::ISODate);
266}
267#endif //QT_NO_DATESTRING
268
269/*!
270 Returns the location specified by \a loc.
271
272*/
273
274QString
275QLibraryInfo::location(LibraryLocation loc)
276{
277 QString ret;
278 if(!QLibraryInfoPrivate::configuration()) {
279 const char *path = 0;
280 switch (loc) {
281#ifdef QT_CONFIGURE_PREFIX_PATH
282 case PrefixPath:
283 path = QT_CONFIGURE_PREFIX_PATH;
284 break;
285#endif
286#ifdef QT_CONFIGURE_DOCUMENTATION_PATH
287 case DocumentationPath:
288 path = QT_CONFIGURE_DOCUMENTATION_PATH;
289 break;
290#endif
291#ifdef QT_CONFIGURE_HEADERS_PATH
292 case HeadersPath:
293 path = QT_CONFIGURE_HEADERS_PATH;
294 break;
295#endif
296#ifdef QT_CONFIGURE_LIBRARIES_PATH
297 case LibrariesPath:
298 path = QT_CONFIGURE_LIBRARIES_PATH;
299 break;
300#endif
301#ifdef QT_CONFIGURE_BINARIES_PATH
302 case BinariesPath:
303 path = QT_CONFIGURE_BINARIES_PATH;
304 break;
305#endif
306#ifdef QT_CONFIGURE_PLUGINS_PATH
307 case PluginsPath:
308 path = QT_CONFIGURE_PLUGINS_PATH;
309 break;
310#endif
311#ifdef QT_CONFIGURE_DATA_PATH
312 case DataPath:
313 path = QT_CONFIGURE_DATA_PATH;
314 break;
315#endif
316#ifdef QT_CONFIGURE_TRANSLATIONS_PATH
317 case TranslationsPath:
318 path = QT_CONFIGURE_TRANSLATIONS_PATH;
319 break;
320#endif
321#ifdef QT_CONFIGURE_SETTINGS_PATH
322 case SettingsPath:
323 path = QT_CONFIGURE_SETTINGS_PATH;
324 break;
325#endif
326#ifdef QT_CONFIGURE_EXAMPLES_PATH
327 case ExamplesPath:
328 path = QT_CONFIGURE_EXAMPLES_PATH;
329 break;
330#endif
331#ifdef QT_CONFIGURE_DEMOS_PATH
332 case DemosPath:
333 path = QT_CONFIGURE_DEMOS_PATH;
334 break;
335#endif
336 default:
337 break;
338 }
339
340 if (path) {
341 ret = QString::fromLocal8Bit(path);
342#ifdef Q_OS_OS2
343 // expand environment variables in the form $(ENVVAR)
344 int rep;
345 QRegExp reg_var(QLatin1String("\\$\\(.*\\)"));
346 reg_var.setMinimal(true);
347 while((rep = reg_var.indexIn(ret)) != -1) {
348 ret.replace(rep, reg_var.matchedLength(),
349 QFile::decodeName(qgetenv(ret.mid(rep + 2,
350 reg_var.matchedLength() - 3).toLatin1().constData()).constData()));
351 }
352#endif
353 }
354 } else {
355 QString key;
356 QString defaultValue;
357 switch(loc) {
358 case PrefixPath:
359 key = QLatin1String("Prefix");
360 break;
361 case DocumentationPath:
362 key = QLatin1String("Documentation");
363 defaultValue = QLatin1String("doc");
364 break;
365 case HeadersPath:
366 key = QLatin1String("Headers");
367 defaultValue = QLatin1String("include");
368 break;
369 case LibrariesPath:
370 key = QLatin1String("Libraries");
371 defaultValue = QLatin1String("lib");
372 break;
373 case BinariesPath:
374 key = QLatin1String("Binaries");
375 defaultValue = QLatin1String("bin");
376 break;
377 case PluginsPath:
378 key = QLatin1String("Plugins");
379 defaultValue = QLatin1String("plugins");
380 break;
381 case DataPath:
382 key = QLatin1String("Data");
383 break;
384 case TranslationsPath:
385 key = QLatin1String("Translations");
386 defaultValue = QLatin1String("translations");
387 break;
388 case SettingsPath:
389 key = QLatin1String("Settings");
390 break;
391 case ExamplesPath:
392 key = QLatin1String("Examples");
393 break;
394 case DemosPath:
395 key = QLatin1String("Demos");
396 break;
397 default:
398 break;
399 }
400
401 if(!key.isNull()) {
402 QSettings *config = QLibraryInfoPrivate::configuration();
403 config->beginGroup(QLatin1String("Paths"));
404
405 QString subKey;
406 {
407 /*
408 find the child group whose version number is closest
409 to the library version. for example and we have the
410 following groups:
411
412 Paths
413 Paths/4.0
414 Paths/4.1.2
415 Paths/4.2.5
416 Paths/5
417
418 if QT_VERSION is 4.0.1, then we use 'Paths/4.0'
419 if QT_VERSION is 4.1.5, then we use 'Paths/4.1.2'
420 if QT_VERSION is 4.6.3, then we use 'Paths/4.2.5'
421 if QT_VERSION is 6.0.2, then we use 'Paths/5'
422
423 note: any of the trailing version numbers may be
424 omitted (in which case, they default to zero),
425 i.e. 4 == 4.0.0, 4.1 == 4.1.0, and so on
426 */
427 enum {
428 QT_MAJOR = ((QT_VERSION >> 16) & 0xFF),
429 QT_MINOR = ((QT_VERSION >> 8) & 0xFF),
430 QT_PATCH = (QT_VERSION & 0xFF)
431 };
432 int maj = 0, min = 0, pat = 0;
433 QStringList children = config->childGroups();
434 for(int child = 0; child < children.size(); ++child) {
435 QString cver = children.at(child);
436 QStringList cver_list = cver.split(QLatin1Char('.'));
437 if(cver_list.size() > 0 && cver_list.size() < 4) {
438 bool ok;
439 int cmaj = -1, cmin = -1, cpat = -1;
440 cmaj = cver_list[0].toInt(&ok);
441 if(!ok || cmaj < 0)
442 continue;
443 if(cver_list.size() >= 2) {
444 cmin = cver_list[1].toInt(&ok);
445 if(!ok)
446 continue;
447 if(cmin < 0)
448 cmin = -1;
449 }
450 if(cver_list.size() >= 3) {
451 cpat = cver_list[2].toInt(&ok);
452 if(!ok)
453 continue;
454 if(cpat < 0)
455 cpat = -1;
456 }
457 if((cmaj >= maj && cmaj <= QT_MAJOR) &&
458 (cmin == -1 || (cmin >= min && cmin <= QT_MINOR)) &&
459 (cpat == -1 || (cpat >= pat && cpat <= QT_PATCH)) &&
460 config->contains(cver + QLatin1Char('/') + key)) {
461 subKey = cver + QLatin1Char('/');
462 maj = cmaj;
463 min = cmin;
464 pat = cpat;
465 }
466 }
467 }
468 }
469 ret = config->value(subKey + key, defaultValue).toString();
470 // expand environment variables in the form $(ENVVAR)
471 int rep;
472 QRegExp reg_var(QLatin1String("\\$\\(.*\\)"));
473 reg_var.setMinimal(true);
474 while((rep = reg_var.indexIn(ret)) != -1) {
475 ret.replace(rep, reg_var.matchedLength(),
476 QFile::decodeName(qgetenv(ret.mid(rep + 2,
477 reg_var.matchedLength() - 3).toLatin1().constData()).constData()));
478 }
479 config->endGroup();
480 }
481 }
482
483#ifdef Q_OS_OS2
484
485 // QDir::isRelativePath() isn't precise on OS/2 (see
486 // QDir::absoluteFilePath()) therefore we don't rely on it
487 if (loc == PrefixPath) {
488#ifdef BOOTSTRAPPING
489 QFileInfo fi(qmake_libraryInfoFile());
490 return QDir::cleanPath(QDir(fi.absolutePath()).absoluteFilePath(ret));
491#else
492 QSettings *config = QLibraryInfoPrivate::configuration();
493 if (config) {
494 // if we read paths from qt[sys].conf, the Prefix is relative to
495 // the directory we load qt[sys].conf from
496 QFileInfo fi(config->fileName());
497 return QDir::cleanPath(QDir(fi.absolutePath()).absoluteFilePath(ret));
498 } else {
499 // we make the prefix path absolute to the executable's directory
500 if (QCoreApplication::instance()) {
501 return QDir::cleanPath(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(ret));
502 }
503 return QDir::current().absoluteFilePath(ret);
504 }
505#endif
506 }
507
508 // we make any other path absolute to the prefix directory
509 return QDir::cleanPath(QDir(location(PrefixPath)).absoluteFilePath(ret));
510
511#else // #ifdef Q_OS_OS2
512
513 if (QDir::isRelativePath(ret)) {
514 if (loc == PrefixPath) {
515 // we make the prefix path absolute to the executable's directory
516#ifdef BOOTSTRAPPING
517 QFileInfo fi(qmake_libraryInfoFile());
518 return QDir::cleanPath(QDir(fi.absolutePath()).absoluteFilePath(ret));
519#else
520 if (QCoreApplication::instance()) {
521#ifdef Q_OS_MAC
522 CFBundleRef bundleRef = CFBundleGetMainBundle();
523 if (bundleRef) {
524 QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef);
525 if (urlRef) {
526 QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
527 return QDir::cleanPath(path + QLatin1String("/Contents/") + ret);
528 }
529 }
530#endif
531 return QDir::cleanPath(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(ret));
532 } else {
533 return QDir::current().absoluteFilePath(ret);
534 }
535#endif
536 } else {
537 // we make any other path absolute to the prefix directory
538 return QDir::cleanPath(QDir(location(PrefixPath)).absoluteFilePath(ret));
539 }
540 }
541 return QDir::cleanPath(ret);
542
543#endif // #ifdef Q_OS_OS2
544}
545
546/*!
547 \enum QLibraryInfo::LibraryLocation
548
549 \keyword library location
550
551 This enum type is used to specify a specific location
552 specifier:
553
554 \value PrefixPath The default prefix for all paths.
555 \value DocumentationPath The location for documentation upon install.
556 \value HeadersPath The location for all headers.
557 \value LibrariesPath The location of installed librarires.
558 \value BinariesPath The location of installed Qt binaries (tools and applications).
559 \value PluginsPath The location of installed Qt plugins.
560 \value DataPath The location of general Qt data.
561 \value TranslationsPath The location of translation information for Qt strings.
562 \value SettingsPath The location for Qt settings.
563 \value ExamplesPath The location for examples upon install.
564 \value DemosPath The location for demos upon install.
565
566 \sa location()
567*/
568
569#endif // QT_NO_SETTINGS
570
571QT_END_NAMESPACE
572
573#if defined(Q_CC_GNU) && defined(ELF_INTERPRETER)
574# include <stdio.h>
575# include <stdlib.h>
576
577extern const char qt_core_interpreter[] __attribute__((section(".interp")))
578 = ELF_INTERPRETER;
579
580extern "C" void qt_core_boilerplate();
581void qt_core_boilerplate()
582{
583 printf("This is the QtCore library version " QT_VERSION_STR "\n"
584 "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).\n"
585 "Contact: Nokia Corporation ([email protected])\n"
586 "\n"
587 "Build key: " QT_BUILD_KEY "\n"
588 "Build date: %s\n"
589 "Installation prefix: %s\n"
590 "Library path: %s\n"
591 "Include path: %s\n",
592 qt_configure_installation + 12,
593 qt_configure_prefix_path_str + 12,
594 qt_configure_libraries_path_str + 12,
595 qt_configure_headers_path_str + 12);
596
597#ifdef QT_EVAL
598 extern void qt_core_eval_init(uint);
599 qt_core_eval_init(1);
600#endif
601
602 exit(0);
603}
604
605#endif
Note: See TracBrowser for help on using the repository browser.