diff --git a/src/app/main.cpp b/src/app/main.cpp index 6e632917532..8bfb8bb6093 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -552,6 +552,33 @@ int main(int argc, char **argv) Options options = parseCommandLine(argc, argv); applicationDirPath(argv[0]); + // Remove entries from environment variables that were set up by Qt Creator to run + // the application (in this case, us). + // TODO: We should be able to merge at least some of the stuff below with similar intent + // into a more generalized version of this. + EnvironmentItems specialItems; + EnvironmentItems diff; + Environment::systemEnvironment().forEachEntry( + [&specialItems](const QString &name, const QString &value, bool enabled) { + if (enabled && name.startsWith("_QTC_")) + specialItems.emplaceBack(name, value, EnvironmentItem::SetEnabled); + }); + for (const EnvironmentItem &item : std::as_const(specialItems)) { + const QString varName = item.name.mid(5); + const FilePaths addedPaths + = Environment::pathListFromValue(item.value, HostOsInfo::hostOs()); + FilePaths allPaths = Environment::systemEnvironment().pathListValue(varName); + Utils::eraseOne(allPaths, [&addedPaths](const FilePath &p) { + return addedPaths.contains(p); + }); + diff.emplaceBack( + varName, + Environment::valueFromPathList(allPaths, HostOsInfo::hostOs()), + EnvironmentItem::SetEnabled); + diff.emplaceBack(item.name, "", EnvironmentItem::Unset); + } + Environment::modifySystemEnvironment(diff); + if (qEnvironmentVariableIsSet("QTC_DO_NOT_PROPAGATE_LD_PRELOAD")) Environment::modifySystemEnvironment({{"LD_PRELOAD", "", EnvironmentItem::Unset}}); diff --git a/src/libs/utils/buildablehelperlibrary.cpp b/src/libs/utils/buildablehelperlibrary.cpp index 6530113bb3e..3a678ffcda2 100644 --- a/src/libs/utils/buildablehelperlibrary.cpp +++ b/src/libs/utils/buildablehelperlibrary.cpp @@ -26,6 +26,7 @@ FilePath BuildableHelperLibrary::qtChooserToQmakePath(const FilePath &qtChooser) { const QString toolDir = QLatin1String("QTTOOLDIR=\""); Process proc; + proc.setEnvironment(qtChooser.deviceEnvironment()); proc.setCommand({qtChooser, {"-print-env"}}); proc.runBlocking(1s); if (proc.result() != ProcessResult::FinishedWithSuccess) @@ -107,6 +108,7 @@ QString BuildableHelperLibrary::qtVersionForQMake(const FilePath &qmakePath) return QString(); Process qmake; + qmake.setEnvironment(qmakePath.deviceEnvironment()); qmake.setCommand({qmakePath, {"--version"}}); qmake.runBlocking(5s); if (qmake.result() != ProcessResult::FinishedWithSuccess) { diff --git a/src/libs/utils/environment.cpp b/src/libs/utils/environment.cpp index 76906b5d599..f9324634a12 100644 --- a/src/libs/utils/environment.cpp +++ b/src/libs/utils/environment.cpp @@ -208,6 +208,12 @@ Environment Environment::systemEnvironment() return *staticSystemEnvironment(); } +const Environment &Environment::originalSystemEnvironment() +{ + static const Environment env(QProcessEnvironment::systemEnvironment().toStringList()); + return env; +} + void Environment::setupEnglishOutput() { addItem(Item{std::in_place_index_t()}); @@ -238,8 +244,24 @@ FilePaths Environment::path() const FilePaths Environment::pathListValue(const QString &varName) const { - const QStringList pathComponents = expandedValueForKey(varName).split( - OsSpecificAspects::pathListSeparator(osType()), Qt::SkipEmptyParts); + return pathListFromValue(expandedValueForKey(varName), osType()); +} + +void Environment::setPathListValue(const QString &varName, const FilePaths &paths) +{ + set(varName, valueFromPathList(paths, osType())); +} + +QString Environment::valueFromPathList(const FilePaths &paths, OsType osType) +{ + return transform(paths, &FilePath::toUserOutput) + .join(OsSpecificAspects::pathListSeparator(osType)); +} + +FilePaths Environment::pathListFromValue(const QString &value, OsType osType) +{ + const QStringList pathComponents + = value.split(OsSpecificAspects::pathListSeparator(osType), Qt::SkipEmptyParts); return transform(pathComponents, &FilePath::fromUserInput); } diff --git a/src/libs/utils/environment.h b/src/libs/utils/environment.h index 1b6b7d2c0e0..341facfab5b 100644 --- a/src/libs/utils/environment.h +++ b/src/libs/utils/environment.h @@ -72,6 +72,9 @@ public: FilePaths path() const; FilePaths pathListValue(const QString &varName) const; + void setPathListValue(const QString &varName, const FilePaths &paths); + static QString valueFromPathList(const FilePaths &paths, OsType osType); + static FilePaths pathListFromValue(const QString &value, OsType osType); QString expandedValueForKey(const QString &key) const; QString expandVariables(const QString &input) const; @@ -91,6 +94,7 @@ public: bool operator==(const Environment &other) const; static Environment systemEnvironment(); + static const Environment &originalSystemEnvironment(); static void modifySystemEnvironment(const EnvironmentItems &list); // use with care!!! static void setSystemEnvironment(const Environment &environment); // don't use at all!!! diff --git a/src/plugins/projectexplorer/desktoprunconfiguration.cpp b/src/plugins/projectexplorer/desktoprunconfiguration.cpp index 7842e501fd4..3cbe11125b9 100644 --- a/src/plugins/projectexplorer/desktoprunconfiguration.cpp +++ b/src/plugins/projectexplorer/desktoprunconfiguration.cpp @@ -52,8 +52,22 @@ protected: environment.addModifier([this](Environment &env) { BuildTargetInfo bti = buildTargetInfo(); - if (bti.runEnvModifier) + if (bti.runEnvModifier) { + Environment old = env; bti.runEnvModifier(env, useLibraryPaths()); + const EnvironmentItems diff = old.diff(env, true); + for (const EnvironmentItem &i : diff) { + switch (i.operation) { + case EnvironmentItem::SetEnabled: + case EnvironmentItem::Prepend: + case EnvironmentItem::Append: + env.addItem(std::make_tuple("_QTC_" + i.name, i.value)); + break; + default: + break; + } + } + } }); setUpdater([this] { updateTargetInformation(); }); diff --git a/src/plugins/projectexplorer/devicesupport/sshparameters.cpp b/src/plugins/projectexplorer/devicesupport/sshparameters.cpp index c266055003c..70e6cf9e91f 100644 --- a/src/plugins/projectexplorer/devicesupport/sshparameters.cpp +++ b/src/plugins/projectexplorer/devicesupport/sshparameters.cpp @@ -80,8 +80,11 @@ void SshParameters::setupSshEnvironment(Process *process) Environment env = process->controlEnvironment(); if (!env.hasChanges()) env = Environment::systemEnvironment(); - if (SshSettings::askpassFilePath().exists()) { - env.set("SSH_ASKPASS", SshSettings::askpassFilePath().toUserOutput()); + const FilePath askPass = SshSettings::askpassFilePath(); + if (askPass.exists()) { + if (askPass.fileName().contains("qtc")) + env = Environment::originalSystemEnvironment(); + env.set("SSH_ASKPASS", askPass.toUserOutput()); env.set("SSH_ASKPASS_REQUIRE", "force"); // OpenSSH only uses the askpass program if DISPLAY is set, regardless of the platform. diff --git a/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp b/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp index 4968d3d2163..b7f831b8dee 100644 --- a/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp +++ b/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -224,6 +225,7 @@ QString QbsProfileManager::runQbsConfig(QbsConfigOp op, const QString &key, cons if (qbsConfigExe.isEmpty() || !qbsConfigExe.exists()) return {}; Utils::Process qbsConfig; + qbsConfig.setEnvironment(QbsSettings::qbsProcessEnvironment()); qbsConfig.setCommand({qbsConfigExe, args}); qbsConfig.start(); using namespace std::chrono_literals; diff --git a/src/plugins/qbsprojectmanager/qbssession.cpp b/src/plugins/qbsprojectmanager/qbssession.cpp index 5920487bce8..ac3ed5724ec 100644 --- a/src/plugins/qbsprojectmanager/qbssession.cpp +++ b/src/plugins/qbsprojectmanager/qbssession.cpp @@ -201,6 +201,7 @@ void QbsSession::initialize() QTimer::singleShot(0, this, [this] { setError(Error::InvalidQbsExecutable); }); return; } + d->qbsProcess->setEnvironment(QbsSettings::qbsProcessEnvironment()); d->qbsProcess->setCommand({qbsExe, {"session"}}); d->qbsProcess->start(); } diff --git a/src/plugins/qbsprojectmanager/qbssettings.cpp b/src/plugins/qbsprojectmanager/qbssettings.cpp index ea89d659855..00426e001fd 100644 --- a/src/plugins/qbsprojectmanager/qbssettings.cpp +++ b/src/plugins/qbsprojectmanager/qbssettings.cpp @@ -28,12 +28,20 @@ const char QBS_EXE_KEY[] = "QbsProjectManager/QbsExecutable"; const char QBS_DEFAULT_INSTALL_DIR_KEY[] = "QbsProjectManager/DefaultInstallDir"; const char USE_CREATOR_SETTINGS_KEY[] = "QbsProjectManager/useCreatorDir"; +static Environment getQbsProcessEnvironment(const FilePath &qbsExe) +{ + if (qbsExe == QbsSettings::defaultQbsExecutableFilePath()) + return Environment::originalSystemEnvironment(); + return qbsExe.deviceEnvironment(); +} + static QString getQbsVersion(const FilePath &qbsExe) { if (qbsExe.isEmpty() || !qbsExe.exists()) return {}; Process qbsProc; qbsProc.setCommand({qbsExe, {"--version"}}); + qbsProc.setEnvironment(getQbsProcessEnvironment(qbsExe)); qbsProc.start(); using namespace std::chrono_literals; if (!qbsProc.waitForFinished(5s) || qbsProc.exitCode() != 0) @@ -82,6 +90,11 @@ FilePath QbsSettings::qbsConfigFilePath() return qbsConfig; } +Environment QbsSettings::qbsProcessEnvironment() +{ + return getQbsProcessEnvironment(qbsExecutableFilePath()); +} + QString QbsSettings::defaultInstallDirTemplate() { return instance().m_settings.defaultInstallDirTemplate; diff --git a/src/plugins/qbsprojectmanager/qbssettings.h b/src/plugins/qbsprojectmanager/qbssettings.h index 434a9af34f3..f996eb2e9a7 100644 --- a/src/plugins/qbsprojectmanager/qbssettings.h +++ b/src/plugins/qbsprojectmanager/qbssettings.h @@ -9,6 +9,8 @@ #include +namespace Utils { class Environment; } + namespace QbsProjectManager::Internal { class QbsSettingsData @@ -29,6 +31,7 @@ public: static Utils::FilePath qbsExecutableFilePath(); static Utils::FilePath defaultQbsExecutableFilePath(); static Utils::FilePath qbsConfigFilePath(); + static Utils::Environment qbsProcessEnvironment(); static bool hasQbsExecutable(); static QString defaultInstallDirTemplate(); static bool useCreatorSettingsDirForQbs(); diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index e686e448b30..2528912b757 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -1337,8 +1337,6 @@ void QtVersionPrivate::updateVersionInfo() m_qmakeIsExecutable = false; qWarning("Cannot update Qt version information from %s: %s.", qPrintable(m_qmakeCommand.displayName()), qPrintable(error)); - qWarning("If this appears when running Qt Creator in Qt Creator make " - "sure to disable \"Add build library search path to LD_LIBRARY_PATH\""); return; } m_qmakeIsExecutable = true;