1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the qmake application of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include "property.h" |
30 | #include "option.h" |
31 | |
32 | #include <qdir.h> |
33 | #include <qsettings.h> |
34 | #include <qlibraryinfo.h> |
35 | #include <qstringlist.h> |
36 | #include <stdio.h> |
37 | |
38 | QT_BEGIN_NAMESPACE |
39 | |
40 | static const struct { |
41 | const char *name; |
42 | QLibraryInfo::LibraryPath loc; |
43 | bool raw; |
44 | bool singular; |
45 | } propList[] = { |
46 | { "QT_SYSROOT" , QLibraryInfo::SysrootPath, true, true }, |
47 | { "QT_INSTALL_PREFIX" , QLibraryInfo::PrefixPath, false, false }, |
48 | { "QT_INSTALL_ARCHDATA" , QLibraryInfo::ArchDataPath, false, false }, |
49 | { "QT_INSTALL_DATA" , QLibraryInfo::DataPath, false, false }, |
50 | { "QT_INSTALL_DOCS" , QLibraryInfo::DocumentationPath, false, false }, |
51 | { "QT_INSTALL_HEADERS" , QLibraryInfo::HeadersPath, false, false }, |
52 | { "QT_INSTALL_LIBS" , QLibraryInfo::LibrariesPath, false, false }, |
53 | { "QT_INSTALL_LIBEXECS" , QLibraryInfo::LibraryExecutablesPath, false, false }, |
54 | { "QT_INSTALL_BINS" , QLibraryInfo::BinariesPath, false, false }, |
55 | { "QT_INSTALL_TESTS" , QLibraryInfo::TestsPath, false, false }, |
56 | { "QT_INSTALL_PLUGINS" , QLibraryInfo::PluginsPath, false, false }, |
57 | { "QT_INSTALL_QML" , QLibraryInfo::Qml2ImportsPath, false, false }, |
58 | { "QT_INSTALL_TRANSLATIONS" , QLibraryInfo::TranslationsPath, false, false }, |
59 | { "QT_INSTALL_CONFIGURATION" , QLibraryInfo::SettingsPath, false, false }, |
60 | { "QT_INSTALL_EXAMPLES" , QLibraryInfo::ExamplesPath, false, false }, |
61 | { "QT_INSTALL_DEMOS" , QLibraryInfo::ExamplesPath, false, false }, // Just backwards compat |
62 | { "QT_HOST_PREFIX" , QLibraryInfo::HostPrefixPath, true, false }, |
63 | { "QT_HOST_DATA" , QLibraryInfo::HostDataPath, true, false }, |
64 | { "QT_HOST_BINS" , QLibraryInfo::HostBinariesPath, true, false }, |
65 | { "QT_HOST_LIBS" , QLibraryInfo::HostLibrariesPath, true, false }, |
66 | { "QMAKE_SPEC" , QLibraryInfo::HostSpecPath, true, true }, |
67 | { "QMAKE_XSPEC" , QLibraryInfo::TargetSpecPath, true, true }, |
68 | }; |
69 | |
70 | QMakeProperty::QMakeProperty() : settings(nullptr) |
71 | { |
72 | reload(); |
73 | } |
74 | |
75 | void QMakeProperty::reload() |
76 | { |
77 | QLibraryInfo::reload(); |
78 | for (unsigned i = 0; i < sizeof(propList)/sizeof(propList[0]); i++) { |
79 | QString name = QString::fromLatin1(propList[i].name); |
80 | if (!propList[i].singular) { |
81 | m_values[ProKey(name + "/src" )] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectiveSourcePaths); |
82 | m_values[ProKey(name + "/get" )] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectivePaths); |
83 | } |
84 | QString val = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::FinalPaths); |
85 | if (!propList[i].raw) { |
86 | m_values[ProKey(name + "/dev" )] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::DevicePaths); |
87 | m_values[ProKey(name)] = QLibraryInfo::path(propList[i].loc); |
88 | name += "/raw" ; |
89 | } |
90 | m_values[ProKey(name)] = val; |
91 | } |
92 | m_values["QMAKE_VERSION" ] = ProString(QMAKE_VERSION_STR); |
93 | #ifdef QT_VERSION_STR |
94 | m_values["QT_VERSION" ] = ProString(QT_VERSION_STR); |
95 | #endif |
96 | } |
97 | |
98 | QMakeProperty::~QMakeProperty() |
99 | { |
100 | delete settings; |
101 | settings = nullptr; |
102 | } |
103 | |
104 | void QMakeProperty::initSettings() |
105 | { |
106 | if(!settings) { |
107 | settings = new QSettings(QSettings::UserScope, "QtProject" , "QMake" ); |
108 | settings->setFallbacksEnabled(false); |
109 | } |
110 | } |
111 | |
112 | ProString |
113 | QMakeProperty::value(const ProKey &vk) |
114 | { |
115 | ProString val = m_values.value(vk); |
116 | if (!val.isNull()) |
117 | return val; |
118 | |
119 | initSettings(); |
120 | return settings->value(vk.toQString()).toString(); |
121 | } |
122 | |
123 | bool |
124 | QMakeProperty::hasValue(const ProKey &v) |
125 | { |
126 | return !value(v).isNull(); |
127 | } |
128 | |
129 | void |
130 | QMakeProperty::setValue(QString var, const QString &val) |
131 | { |
132 | initSettings(); |
133 | settings->setValue(var, val); |
134 | } |
135 | |
136 | void |
137 | QMakeProperty::remove(const QString &var) |
138 | { |
139 | initSettings(); |
140 | settings->remove(var); |
141 | } |
142 | |
143 | bool |
144 | QMakeProperty::exec() |
145 | { |
146 | bool ret = true; |
147 | if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY) { |
148 | if(Option::prop::properties.isEmpty()) { |
149 | initSettings(); |
150 | const auto keys = settings->childKeys(); |
151 | for (const QString &key : keys) { |
152 | QString val = settings->value(key).toString(); |
153 | fprintf(stdout, "%s:%s\n" , qPrintable(key), qPrintable(val)); |
154 | } |
155 | QStringList specialProps; |
156 | for (unsigned i = 0; i < sizeof(propList)/sizeof(propList[0]); i++) |
157 | specialProps.append(QString::fromLatin1(propList[i].name)); |
158 | specialProps.append("QMAKE_VERSION" ); |
159 | #ifdef QT_VERSION_STR |
160 | specialProps.append("QT_VERSION" ); |
161 | #endif |
162 | for (const QString &prop : qAsConst(specialProps)) { |
163 | ProString val = value(ProKey(prop)); |
164 | ProString pval = value(ProKey(prop + "/raw" )); |
165 | ProString gval = value(ProKey(prop + "/get" )); |
166 | ProString sval = value(ProKey(prop + "/src" )); |
167 | ProString dval = value(ProKey(prop + "/dev" )); |
168 | fprintf(stdout, "%s:%s\n" , prop.toLatin1().constData(), val.toLatin1().constData()); |
169 | if (!pval.isEmpty() && pval != val) |
170 | fprintf(stdout, "%s/raw:%s\n" , prop.toLatin1().constData(), pval.toLatin1().constData()); |
171 | if (!gval.isEmpty() && gval != (pval.isEmpty() ? val : pval)) |
172 | fprintf(stdout, "%s/get:%s\n" , prop.toLatin1().constData(), gval.toLatin1().constData()); |
173 | if (!sval.isEmpty() && sval != gval) |
174 | fprintf(stdout, "%s/src:%s\n" , prop.toLatin1().constData(), sval.toLatin1().constData()); |
175 | if (!dval.isEmpty() && dval != pval) |
176 | fprintf(stdout, "%s/dev:%s\n" , prop.toLatin1().constData(), dval.toLatin1().constData()); |
177 | } |
178 | return true; |
179 | } |
180 | for (QStringList::ConstIterator it = Option::prop::properties.cbegin(); |
181 | it != Option::prop::properties.cend(); it++) { |
182 | if(Option::prop::properties.count() > 1) |
183 | fprintf(stdout, "%s:" , (*it).toLatin1().constData()); |
184 | const ProKey pkey(*it); |
185 | if (!hasValue(pkey)) { |
186 | ret = false; |
187 | fprintf(stdout, "**Unknown**\n" ); |
188 | } else { |
189 | fprintf(stdout, "%s\n" , value(pkey).toLatin1().constData()); |
190 | } |
191 | } |
192 | } else if(Option::qmake_mode == Option::QMAKE_SET_PROPERTY) { |
193 | for (QStringList::ConstIterator it = Option::prop::properties.cbegin(); |
194 | it != Option::prop::properties.cend(); it++) { |
195 | QString var = (*it); |
196 | it++; |
197 | if (it == Option::prop::properties.cend()) { |
198 | ret = false; |
199 | break; |
200 | } |
201 | if(!var.startsWith("." )) |
202 | setValue(var, (*it)); |
203 | } |
204 | } else if(Option::qmake_mode == Option::QMAKE_UNSET_PROPERTY) { |
205 | for (QStringList::ConstIterator it = Option::prop::properties.cbegin(); |
206 | it != Option::prop::properties.cend(); it++) { |
207 | QString var = (*it); |
208 | if(!var.startsWith("." )) |
209 | remove(var); |
210 | } |
211 | } |
212 | return ret; |
213 | } |
214 | |
215 | QT_END_NAMESPACE |
216 | |