diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index 3115943e885..0ab7ff8e62c 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -538,6 +538,14 @@ CMakeBuildConfiguration *CMakeBuildSystem::cmakeBuildConfiguration() const return m_buildConfiguration; } +static Utils::FilePaths librarySearchPaths(const CMakeBuildSystem *bs, const QString &buildKey) +{ + const CMakeBuildTarget cmakeBuildTarget + = Utils::findOrDefault(bs->buildTargets(), Utils::equal(&CMakeBuildTarget::title, buildKey)); + + return cmakeBuildTarget.libraryDirectories; +} + const QList CMakeBuildSystem::appTargets() const { QList appTargetList; @@ -548,20 +556,21 @@ const QList CMakeBuildSystem::appTargets() const continue; if (ct.targetType == ExecutableType || (forAndroid && ct.targetType == DynamicLibraryType)) { + const QString buildKey = ct.title; + BuildTargetInfo bti; bti.displayName = ct.title; bti.targetFilePath = ct.executable; bti.projectFilePath = ct.sourceDirectory.stringAppended("/"); bti.workingDirectory = ct.workingDirectory; - bti.buildKey = ct.title; + bti.buildKey = buildKey; bti.usesTerminal = !ct.linksToQtGui; // Workaround for QTCREATORBUG-19354: - bti.runEnvModifier = [this](Environment &env, bool) { - if (HostOsInfo::isWindowsHost()) { - const Kit *k = target()->kit(); - if (const QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(k)) - env.prependOrSetPath(qt->binPath().toString()); + bti.runEnvModifier = [this, buildKey](Environment &env, bool enabled) { + if (enabled) { + const Utils::FilePaths paths = librarySearchPaths(this, buildKey); + env.prependOrSetLibrarySearchPaths(Utils::transform(paths, &FilePath::toString)); } }; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildtarget.h b/src/plugins/cmakeprojectmanager/cmakebuildtarget.h index 54ce6957390..c2a51c67fc4 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildtarget.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildtarget.h @@ -57,6 +57,7 @@ public: Utils::FilePath workingDirectory; Utils::FilePath sourceDirectory; Utils::FilePath makeCommand; + Utils::FilePaths libraryDirectories; Backtrace backtrace; diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp index 6498ea0a8ce..e389ca4765d 100644 --- a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp +++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp @@ -147,6 +147,7 @@ PreprocessedData preprocess(FileApiData &data, // Simplify to only one configuration: result.codemodel = extractConfiguration(data.codemodel, errorMessage); + if (!errorMessage.isEmpty()) { return result; } @@ -208,6 +209,8 @@ QList generateBuildTargets(const PreprocessedData &input, const QList result = transform( input.targetDetails, [&sourceDir, &buildDir](const TargetDetails &t) -> CMakeBuildTarget { + const auto currentBuildDir = QDir(buildDir.absoluteFilePath(t.buildDir.toString())); + CMakeBuildTarget ct; ct.title = t.name; ct.executable = t.artifacts.isEmpty() @@ -226,9 +229,9 @@ QList generateBuildTargets(const PreprocessedData &input, else type = UtilityType; ct.targetType = type; - ct.workingDirectory = ct.executable.isEmpty() ? FilePath::fromString( - buildDir.absoluteFilePath(t.buildDir.toString())) - : ct.executable.parentDir(); + ct.workingDirectory = ct.executable.isEmpty() + ? FilePath::fromString(currentBuildDir.absolutePath()) + : ct.executable.parentDir(); ct.sourceDirectory = FilePath::fromString( QDir::cleanPath(sourceDir.absoluteFilePath(t.sourceDir.toString()))); @@ -258,15 +261,38 @@ QList generateBuildTargets(const PreprocessedData &input, } // Is this a terminal application? + Utils::FilePaths librarySeachPaths; if (ct.targetType == ExecutableType && t.link && t.link.value().language == "CXX") { for (const FragmentInfo &f : t.link.value().fragments) { - if (f.role != "libraries") - continue; - if (f.fragment.contains("QtGui") || f.fragment.contains("Qt5Gui") - || f.fragment.contains("Qt6Gui")) - ct.linksToQtGui = true; + FilePath tmp; + // Some projects abuse linking to libraries to pass random flags to the linker! + if (f.role != "flags" + && !(f.fragment.startsWith("-") || f.fragment.contains(" -"))) { + tmp = FilePath::fromString(currentBuildDir.absoluteFilePath( + QDir::fromNativeSeparators(f.fragment))); + } + + if (f.role == "libraries") { + tmp = tmp.parentDir(); + + if (f.fragment.contains("QtGui") || f.fragment.contains("Qt5Gui") + || f.fragment.contains("Qt6Gui")) + ct.linksToQtGui = true; + } + + if (!tmp.isEmpty()) { + librarySeachPaths.append(tmp); + // Libraries often have their import libs in ../lib and the + // actual dll files in ../bin on windows. Qt is one example of that. + if (tmp.fileName() == "lib" && HostOsInfo::isWindowsHost()) { + const FilePath path = tmp.parentDir().pathAppended("bin"); + + librarySeachPaths.append(path); + } + } } } + ct.libraryDirectories = filteredUnique(librarySeachPaths); return ct; }); diff --git a/src/plugins/projectexplorer/desktoprunconfiguration.cpp b/src/plugins/projectexplorer/desktoprunconfiguration.cpp index 838c99f289d..d534c297315 100644 --- a/src/plugins/projectexplorer/desktoprunconfiguration.cpp +++ b/src/plugins/projectexplorer/desktoprunconfiguration.cpp @@ -80,9 +80,6 @@ DesktopRunConfiguration::DesktopRunConfiguration(Target *target, Core::Id id, Ki setUpdater([this] { updateTargetInformation(); }); - if (m_kind == CMake) - libAspect->setVisible(false); - connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); }