Utils: FilePathify Environment::{ap,pre}pendOrSetPath etc

Change-Id: Idfa5ec247337570936b0236cab9d3a5669792ca0
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2021-11-09 18:20:14 +01:00
parent d14e68eac2
commit 652b9844e6
29 changed files with 88 additions and 89 deletions

View File

@@ -52,16 +52,22 @@ QProcessEnvironment Environment::toProcessEnvironment() const
return result;
}
void Environment::appendOrSetPath(const QString &value)
void Environment::appendOrSetPath(const FilePath &value)
{
appendOrSet("PATH", QDir::toNativeSeparators(value),
QTC_CHECK(value.osType() == m_osType);
if (value.isEmpty())
return;
appendOrSet("PATH", value.deviceLocalPath(),
QString(OsSpecificAspects::pathListSeparator(m_osType)));
}
void Environment::prependOrSetPath(const QString &value)
void Environment::prependOrSetPath(const FilePath &value)
{
prependOrSet("PATH", QDir::toNativeSeparators(value),
QString(OsSpecificAspects::pathListSeparator(m_osType)));
QTC_CHECK(value.osType() == m_osType);
if (value.isEmpty())
return;
prependOrSet("PATH", value.deviceLocalPath(),
QString(OsSpecificAspects::pathListSeparator(m_osType)));
}
void Environment::appendOrSet(const QString &key, const QString &value, const QString &sep)
@@ -92,17 +98,18 @@ void Environment::prependOrSet(const QString &key, const QString &value, const Q
}
}
void Environment::prependOrSetLibrarySearchPath(const QString &value)
void Environment::prependOrSetLibrarySearchPath(const FilePath &value)
{
QTC_CHECK(value.osType() == m_osType);
switch (m_osType) {
case OsTypeWindows: {
const QChar sep = ';';
prependOrSet("PATH", QDir::toNativeSeparators(value), QString(sep));
prependOrSet("PATH", value.deviceLocalPath(), QString(sep));
break;
}
case OsTypeMac: {
const QString sep = ":";
const QString nativeValue = QDir::toNativeSeparators(value);
const QString nativeValue = value.deviceLocalPath();
prependOrSet("DYLD_LIBRARY_PATH", nativeValue, sep);
prependOrSet("DYLD_FRAMEWORK_PATH", nativeValue, sep);
break;
@@ -110,7 +117,7 @@ void Environment::prependOrSetLibrarySearchPath(const QString &value)
case OsTypeLinux:
case OsTypeOtherUnix: {
const QChar sep = ':';
prependOrSet("LD_LIBRARY_PATH", QDir::toNativeSeparators(value), QString(sep));
prependOrSet("LD_LIBRARY_PATH", value.deviceLocalPath(), QString(sep));
break;
}
default:
@@ -118,9 +125,9 @@ void Environment::prependOrSetLibrarySearchPath(const QString &value)
}
}
void Environment::prependOrSetLibrarySearchPaths(const QStringList &values)
void Environment::prependOrSetLibrarySearchPaths(const FilePaths &values)
{
Utils::reverseForeach(values, [this](const QString &value) {
Utils::reverseForeach(values, [this](const FilePath &value) {
prependOrSetLibrarySearchPath(value);
});
}
@@ -431,17 +438,17 @@ void EnvironmentChange::addUnsetValue(const QString &key)
m_changeItems.append([key](Environment &env) { env.unset(key); });
}
void EnvironmentChange::addPrependToPath(const QStringList &values)
void EnvironmentChange::addPrependToPath(const FilePaths &values)
{
for (int i = values.size(); --i >= 0; ) {
const QString value = values.at(i);
const FilePath value = values.at(i);
m_changeItems.append([value](Environment &env) { env.prependOrSetPath(value); });
}
}
void EnvironmentChange::addAppendToPath(const QStringList &values)
void EnvironmentChange::addAppendToPath(const FilePaths &values)
{
for (const QString &value : values)
for (const FilePath &value : values)
m_changeItems.append([value](Environment &env) { env.appendOrSetPath(value); });
}

View File

@@ -51,11 +51,11 @@ public:
void appendOrSet(const QString &key, const QString &value, const QString &sep = QString());
void prependOrSet(const QString &key, const QString &value, const QString &sep = QString());
void appendOrSetPath(const QString &value);
void prependOrSetPath(const QString &value);
void appendOrSetPath(const Utils::FilePath &value);
void prependOrSetPath(const Utils::FilePath &value);
void prependOrSetLibrarySearchPath(const QString &value);
void prependOrSetLibrarySearchPaths(const QStringList &values);
void prependOrSetLibrarySearchPath(const Utils::FilePath &value);
void prependOrSetLibrarySearchPaths(const Utils::FilePaths &values);
void setupEnglishOutput();
@@ -97,8 +97,8 @@ public:
void addSetValue(const QString &key, const QString &value);
void addUnsetValue(const QString &key);
void addPrependToPath(const QStringList &values);
void addAppendToPath(const QStringList &values);
void addPrependToPath(const Utils::FilePaths &values);
void addAppendToPath(const Utils::FilePaths &values);
void addModify(const NameValueItems &items);
void addChange(const Item &item) { m_changeItems.append(item); }

View File

@@ -476,7 +476,7 @@ void FileUtils::setDeviceFileHooks(const DeviceFileHooks &hooks)
s_deviceHooks = hooks;
}
/// \returns a QString to display to the user
/// \returns a QString to display to the user, including the device prefix
/// Converts the separators to the native format of the system
/// this path belongs to.
QString FilePath::toUserOutput() const
@@ -487,6 +487,17 @@ QString FilePath::toUserOutput() const
return tmp.toString();
}
/// \returns a QString to pass to target system native commands, without the device prefix.
/// Converts the separators to the native format of the system
/// this path belongs to.
QString FilePath::deviceLocalPath() const
{
QString data = m_data;
if (osType() == OsTypeWindows)
data.replace('/', '\\');
return data;
}
QString FilePath::fileName() const
{
const QChar slash = QLatin1Char('/');

View File

@@ -66,6 +66,7 @@ public:
[[nodiscard]] static FilePath fromUrl(const QUrl &url);
QString toUserOutput() const;
QString deviceLocalPath() const;
QString toString() const;
QVariant toVariant() const;
QUrl toUrl() const;

View File

@@ -1414,7 +1414,7 @@ Environment AndroidConfigurations::toolsEnvironment(const AndroidConfig &config)
FilePath jdkLocation = config.openJDKLocation();
if (!jdkLocation.isEmpty()) {
env.set("JAVA_HOME", jdkLocation.toUserOutput());
env.prependOrSetPath(jdkLocation.pathAppended("bin").toUserOutput());
env.prependOrSetPath(jdkLocation.pathAppended("bin"));
}
return env;
}

View File

@@ -124,7 +124,7 @@ void AndroidToolChain::addToEnvironment(Environment &env) const
const FilePath javaBin = javaHome.pathAppended("bin");
const FilePath currentJavaFilePath = env.searchInPath("java");
if (!currentJavaFilePath.isChildOf(javaBin))
env.prependOrSetPath(javaBin.toUserOutput());
env.prependOrSetPath(javaBin);
}
env.set(QLatin1String("ANDROID_HOME"), config.sdkLocation().toString());
env.set(QLatin1String("ANDROID_SDK_ROOT"), config.sdkLocation().toString());

View File

@@ -361,10 +361,8 @@ ToolChain::BuiltInHeaderPathsRunner IarToolChain::createBuiltInHeaderPathsRunner
void IarToolChain::addToEnvironment(Environment &env) const
{
if (!compilerCommand().isEmpty()) {
const FilePath path = compilerCommand().parentDir();
env.prependOrSetPath(path.toString());
}
if (!compilerCommand().isEmpty())
env.prependOrSetPath(compilerCommand().parentDir());
}
QList<Utils::OutputLineParser *> IarToolChain::createOutputParsers() const

View File

@@ -486,10 +486,8 @@ ToolChain::BuiltInHeaderPathsRunner KeilToolChain::createBuiltInHeaderPathsRunne
void KeilToolChain::addToEnvironment(Environment &env) const
{
if (!compilerCommand().isEmpty()) {
const FilePath path = compilerCommand().parentDir();
env.prependOrSetPath(path.toString());
}
if (!compilerCommand().isEmpty())
env.prependOrSetPath(compilerCommand().parentDir());
}
QList<OutputLineParser *> KeilToolChain::createOutputParsers() const

View File

@@ -265,10 +265,8 @@ ToolChain::BuiltInHeaderPathsRunner SdccToolChain::createBuiltInHeaderPathsRunne
void SdccToolChain::addToEnvironment(Environment &env) const
{
if (!compilerCommand().isEmpty()) {
const FilePath path = compilerCommand().parentDir();
env.prependOrSetPath(path.toString());
}
if (!compilerCommand().isEmpty())
env.prependOrSetPath(compilerCommand().parentDir());
}
QList<Utils::OutputLineParser *> SdccToolChain::createOutputParsers() const

View File

@@ -87,8 +87,7 @@ BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc)
CMakeSpecificSettings *settings = CMakeProjectPlugin::projectTypeSpecificSettings();
if (!settings->ninjaPath.filePath().isEmpty()) {
const Utils::FilePath ninja = settings->ninjaPath.filePath();
const Utils::FilePath ninjaDir = ninja.isFile() ? ninja.parentDir() : ninja;
environment.appendOrSetPath(ninjaDir.path());
environment.appendOrSetPath(ninja.isFile() ? ninja.parentDir() : ninja);
}
cmakeToolId = CMakeKitAspect::cmakeToolId(k);

View File

@@ -1022,10 +1022,8 @@ const QList<BuildTargetInfo> CMakeBuildSystem::appTargets() const
// Workaround for QTCREATORBUG-19354:
bti.runEnvModifier = [this, buildKey](Environment &env, bool enabled) {
if (enabled) {
const Utils::FilePaths paths = librarySearchPaths(this, buildKey);
env.prependOrSetLibrarySearchPaths(Utils::transform(paths, &FilePath::toString));
}
if (enabled)
env.prependOrSetLibrarySearchPaths(librarySearchPaths(this, buildKey));
};
appTargetList.append(bti);

View File

@@ -848,8 +848,8 @@ void CMakeGeneratorKitAspect::addToBuildEnvironment(const Kit *k, Environment &e
if (info.generator == "NMake Makefiles JOM") {
if (env.searchInPath("jom.exe").exists())
return;
env.appendOrSetPath(Core::ICore::libexecPath().toUserOutput());
env.appendOrSetPath(Core::ICore::libexecPath("jom").toUserOutput());
env.appendOrSetPath(Core::ICore::libexecPath());
env.appendOrSetPath(Core::ICore::libexecPath("jom"));
}
}

View File

@@ -36,6 +36,8 @@
#include "vcsmanager.h"
#include <app/app_version.h>
#include <utils/algorithm.h>
#include <utils/checkablemessagebox.h>
#include <utils/consoleprocess.h>
#include <utils/environment.h>
@@ -324,7 +326,7 @@ void SystemSettingsWidget::resetFileBrowser()
void SystemSettingsWidget::updatePath()
{
EnvironmentChange change;
change.addAppendToPath(VcsManager::additionalToolsPath());
change.addAppendToPath(Utils::transform(VcsManager::additionalToolsPath(), &FilePath::fromString));
m_ui.patchChooser->setEnvironmentChange(change);
}

View File

@@ -217,8 +217,7 @@ void LldbEngine::setupEngine()
FilePath androidPythonDir = lldbCmd.parentDir().parentDir().pathAppended("python3");
if (HostOsInfo::isAnyUnixHost())
androidPythonDir = androidPythonDir.pathAppended("bin");
if (androidPythonDir.exists())
environment.prependOrSetPath(androidPythonDir.path());
environment.prependOrSetPath(androidPythonDir);
}
m_lldbProc.setEnvironment(environment);

View File

@@ -2217,7 +2217,7 @@ Environment GitClient::processEnvironment() const
{
Environment environment = VcsBaseClientImpl::processEnvironment();
QString gitPath = settings().path.value();
environment.prependOrSetPath(gitPath);
environment.prependOrSetPath(FilePath::fromUserInput(gitPath));
if (HostOsInfo::isWindowsHost() && settings().winSetHomeEnvironment.value())
environment.set("HOME", QDir::toNativeSeparators(QDir::homePath()));
environment.set("GIT_EDITOR", m_disableEditor ? "true" : m_gitQtcEditor);

View File

@@ -143,8 +143,7 @@ FilePath GitSettings::gitExecutable(bool *ok, QString *errorMessage) const
FilePath binPath = binaryPath.filePath();
if (!binPath.isAbsolutePath()) {
Environment env = Environment::systemEnvironment();
if (!path.filePath().isEmpty())
env.prependOrSetPath(path.filePath().toString());
env.prependOrSetPath(path.filePath());
binPath = env.searchInPath(binPath.toString());
}
if (binPath.isEmpty()) {

View File

@@ -66,7 +66,7 @@ NimbleBuildStep::NimbleBuildStep(BuildStepList *parentList, Id id)
});
setWorkingDirectoryProvider([this] { return project()->projectDirectory(); });
setEnvironmentModifier([this](Environment &env) {
env.appendOrSetPath(Nim::nimPathFromKit(kit()).toUserOutput());
env.appendOrSetPath(Nim::nimPathFromKit(kit()));
});
setSummaryUpdater([this] {

View File

@@ -77,7 +77,7 @@ ToolChain::BuiltInHeaderPathsRunner NimToolChain::createBuiltInHeaderPathsRunner
void NimToolChain::addToEnvironment(Environment &env) const
{
if (isValid())
env.prependOrSetPath(compilerCommand().parentDir().toString());
env.prependOrSetPath(compilerCommand().parentDir());
}
FilePath NimToolChain::makeCommand(const Environment &env) const

View File

@@ -153,11 +153,11 @@ ToolChain::BuiltInHeaderPathsRunner CustomToolChain::createBuiltInHeaderPathsRun
void CustomToolChain::addToEnvironment(Environment &env) const
{
if (!m_compilerCommand.isEmpty()) {
FilePath path = m_compilerCommand.parentDir();
env.prependOrSetPath(path.toString());
FilePath makePath = m_makeCommand.parentDir();
const FilePath path = m_compilerCommand.parentDir();
env.prependOrSetPath(path);
const FilePath makePath = m_makeCommand.parentDir();
if (makePath != path)
env.prependOrSetPath(makePath.toString());
env.prependOrSetPath(makePath);
}
}

View File

@@ -633,9 +633,7 @@ ToolChain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner
void GccToolChain::addCommandPathToEnvironment(const FilePath &command, Environment &env)
{
const Utils::FilePath compilerDir = command.parentDir();
if (!compilerDir.isEmpty())
env.prependOrSetPath(compilerDir.toString());
env.prependOrSetPath(command.parentDir());
}
void GccToolChain::addToEnvironment(Environment &env) const
@@ -1526,7 +1524,7 @@ void ClangToolChain::addToEnvironment(Environment &env) const
const QString sysroot = sysRoot();
if (!sysroot.isEmpty())
env.prependOrSetPath(sysroot + "/bin");
env.prependOrSetPath(FilePath::fromString(sysroot) / "bin");
// Clang takes PWD as basis for debug info, if set.
// When running Qt Creator from a shell, PWD is initially set to an "arbitrary" value.

View File

@@ -1701,8 +1701,7 @@ bool ClangClToolChain::isValid() const
void ClangClToolChain::addToEnvironment(Utils::Environment &env) const
{
MsvcToolChain::addToEnvironment(env);
QDir path = QFileInfo(m_clangPath).absoluteDir(); // bin folder
env.prependOrSetPath(path.canonicalPath());
env.prependOrSetPath(FilePath::fromString(m_clangPath).parentDir()); // bin folder
}
Utils::FilePath ClangClToolChain::compilerCommand() const

View File

@@ -1187,7 +1187,7 @@ void QmakeBuildSystem::updateBuildSystemData()
bti.usesTerminal = !qt.contains("testlib") && !qt.contains("qmltest");
}
QStringList libraryPaths;
FilePaths libraryPaths;
// The user could be linking to a library found via a -L/some/dir switch
// to find those libraries while actually running we explicitly prepend those
@@ -1202,12 +1202,12 @@ void QmakeBuildSystem::updateBuildSystemData()
const QFileInfo fi(dir);
if (!fi.isAbsolute())
dir = QDir::cleanPath(proDirectory + '/' + dir);
libraryPaths.append(dir);
libraryPaths.append(FilePath::fromUserInput(dir));
}
}
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(kit());
if (qtVersion)
libraryPaths.append(qtVersion->librarySearchPath().toString());
libraryPaths.append(qtVersion->librarySearchPath());
bti.runEnvModifierHash = qHash(libraryPaths);
bti.runEnvModifier = [libraryPaths](Environment &env, bool useLibrarySearchPath) {

View File

@@ -485,8 +485,7 @@ QProcessEnvironment PuppetCreator::processEnvironment() const
const QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(m_target->kit());
if (QTC_GUARD(qt)) { // Kits without a Qt version should not have a puppet!
// Update PATH to include QT_HOST_BINS
const Utils::FilePath qtBinPath = qt->hostBinPath();
environment.prependOrSetPath(qtBinPath.toString());
environment.prependOrSetPath(qt->hostBinPath());
}
}
}

View File

@@ -156,8 +156,7 @@ void QnxQtVersion::addToEnvironment(const Kit *k, Environment &env) const
QtSupport::BaseQtVersion::addToEnvironment(k, env);
updateEnvironment();
env.modify(m_qnxEnv);
env.prependOrSetLibrarySearchPath(libraryPath().toString());
env.prependOrSetLibrarySearchPath(libraryPath());
}
void QnxQtVersion::setupQmakeRunEnvironment(Environment &env) const

View File

@@ -381,17 +381,11 @@ void QtKitAspect::setQtVersion(Kit *k, const BaseQtVersion *v)
void QtKitAspect::addHostBinariesToPath(const Kit *k, Environment &env)
{
if (const ToolChain *tc = ToolChainKitAspect::cxxToolChain(k)) {
const FilePath compilerDir = tc->compilerCommand().parentDir();
if (!compilerDir.isEmpty())
env.prependOrSetPath(compilerDir.toString());
}
if (const ToolChain *tc = ToolChainKitAspect::cxxToolChain(k))
env.prependOrSetPath(tc->compilerCommand().parentDir());
if (const BaseQtVersion *qt = qtVersion(k)) {
const FilePath hostBinPath = qt->hostBinPath();
if (!hostBinPath.isEmpty())
env.prependOrSetPath(hostBinPath.toString());
}
if (const BaseQtVersion *qt = qtVersion(k))
env.prependOrSetPath(qt->hostBinPath());
}
void QtKitAspect::qtVersionsChanged(const QList<int> &addedIds,

View File

@@ -31,6 +31,7 @@
#include <coreplugin/iversioncontrol.h>
#include <coreplugin/vcsmanager.h>
#include <utils/algorithm.h>
#include <utils/environment.h>
#include <utils/hostosinfo.h>
#include <utils/layoutbuilder.h>
@@ -156,7 +157,8 @@ CommonSettingsWidget::CommonSettingsWidget(CommonOptionsPage *page)
void CommonSettingsWidget::updatePath()
{
EnvironmentChange change;
change.addAppendToPath(Core::VcsManager::additionalToolsPath());
change.addAppendToPath(Utils::transform(Core::VcsManager::additionalToolsPath(),
&FilePath::fromString));
m_page->settings().sshPasswordPrompt.setEnvironmentChange(change);
}

View File

@@ -76,7 +76,7 @@ static void parseEmSdkEnvOutputAndAddToEnv(const QString &output, Environment &e
for (const QString &line : lines) {
const QStringList prependParts = line.trimmed().split(" += ");
if (prependParts.count() == 2)
env.prependOrSetPath(prependParts.last());
env.prependOrSetPath(FilePath::fromUserInput(prependParts.last()));
const QStringList setParts = line.trimmed().split(" = ");
if (setParts.count() == 2) {
@@ -89,7 +89,7 @@ static void parseEmSdkEnvOutputAndAddToEnv(const QString &output, Environment &e
// QTCREATORBUG-26199: Wrapper scripts (e.g. emcc.bat) of older emsdks might not find python
const QString emsdkPython = env.value("EMSDK_PYTHON");
if (!emsdkPython.isEmpty())
env.appendOrSetPath(FilePath::fromUserInput(emsdkPython).parentDir().toUserOutput());
env.appendOrSetPath(FilePath::fromUserInput(emsdkPython).parentDir());
}
bool WebAssemblyEmSdk::isValid(const FilePath &sdkRoot)

View File

@@ -64,10 +64,8 @@ static void addRegisteredMinGWToEnvironment(Environment &env)
const ToolChain *toolChain = ToolChainManager::toolChain([](const ToolChain *t){
return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID;
});
if (toolChain) {
const QString mingwPath = toolChain->compilerCommand().parentDir().toUserOutput();
env.appendOrSetPath(mingwPath);
}
if (toolChain)
env.appendOrSetPath(toolChain->compilerCommand().parentDir());
}
void WebAssemblyToolChain::addToEnvironment(Environment &env) const

View File

@@ -1224,10 +1224,10 @@ void tst_Dumpers::initTestCase()
if (m_makeBinary.isEmpty())
m_makeBinary = "mingw32-make";
if (m_makeBinary != "mingw32-make")
env.prependOrSetPath(QDir::toNativeSeparators(QFileInfo(m_makeBinary).absolutePath()));
env.prependOrSetPath(Utils::FilePath::fromString(m_makeBinary));
// if qmake is not in PATH make sure the correct libs for inferior are prepended to PATH
if (m_qmakeBinary != "qmake")
env.prependOrSetPath(QDir::toNativeSeparators(QFileInfo(m_qmakeBinary).absolutePath()));
env.prependOrSetPath(Utils::FilePath::fromString(m_qmakeBinary));
m_env = env.toProcessEnvironment();
#else
m_env = QProcessEnvironment::systemEnvironment();
@@ -1248,7 +1248,7 @@ void tst_Dumpers::initTestCase()
cdbextPath = QString(CDBEXT_PATH "\\qtcreatorcdbext64");
QVERIFY(QFile::exists(cdbextPath + "\\qtcreatorcdbext.dll"));
env.set("_NT_DEBUGGER_EXTENSION_PATH", cdbextPath);
env.prependOrSetPath(QDir::toNativeSeparators(QFileInfo(m_qmakeBinary).absolutePath()));
env.prependOrSetPath(Utils::FilePath::fromString(m_qmakeBinary));
m_makeBinary = env.searchInPath("nmake.exe").toString();
m_env = env.toProcessEnvironment();