CMakePM: Detect C/C++ object extension for single source build

When using CMake package manager auto-setup the CMAKE_C|
XX_OUTPUT_EXTENSION is stored in the CMake cache.

This way CMake project manager can know about the correct extension when
building a single source file.

If CMAKE_C|XX_OUTPUT_EXTENSION is not found in cache it will only use
".obj" for Clang-Cl/MSVC/MinGW toolchains.

Task-number: QTCREATORBUG-27471
Change-Id: Ib9b75608d5a6834014150c57f3098f79284d8276
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Cristian Adam
2023-11-03 14:25:34 +01:00
parent 18817c4088
commit 42cc29902b
2 changed files with 34 additions and 3 deletions

View File

@@ -26,6 +26,7 @@
#include <debugger/analyzer/analyzermanager.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/kitaspects.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorericons.h>
@@ -42,6 +43,7 @@
#include <QFileDialog>
#include <QMessageBox>
using namespace CppEditor;
using namespace ProjectExplorer;
using namespace Utils;
@@ -402,7 +404,6 @@ void CMakeManager::buildFile(Node *node)
QTC_ASSERT(target, return);
const QString generator = CMakeGeneratorKitAspect::generator(target->kit());
const QString relativeSource = filePath.relativeChildPath(targetNode->filePath()).toString();
const QString objExtension = Utils::HostOsInfo::isWindowsHost() ? QString(".obj") : QString(".o");
Utils::FilePath targetBase;
BuildConfiguration *bc = target->activeBuildConfiguration();
QTC_ASSERT(bc, return);
@@ -416,8 +417,32 @@ void CMakeManager::buildFile(Node *node)
return;
}
static_cast<CMakeBuildSystem *>(bc->buildSystem())
->buildCMakeTarget(targetBase.pathAppended(relativeSource).toString() + objExtension);
auto cbc = static_cast<CMakeBuildSystem *>(bc->buildSystem());
const QString sourceFile = targetBase.pathAppended(relativeSource).toString();
const QString objExtension = [&]() -> QString {
const auto sourceKind = ProjectFile::classify(relativeSource);
const QByteArray cmakeLangExtension = ProjectFile::isCxx(sourceKind)
? "CMAKE_CXX_OUTPUT_EXTENSION"
: "CMAKE_C_OUTPUT_EXTENSION";
const QString extension = cbc->configurationFromCMake().stringValueOf(cmakeLangExtension);
if (!extension.isEmpty())
return extension;
const auto toolchain = ProjectFile::isCxx(sourceKind)
? ToolChainKitAspect::cxxToolChain(target->kit())
: ToolChainKitAspect::cToolChain(target->kit());
using namespace ProjectExplorer::Constants;
static QSet<Id> objIds{
CLANG_CL_TOOLCHAIN_TYPEID,
MSVC_TOOLCHAIN_TYPEID,
MINGW_TOOLCHAIN_TYPEID,
};
if (objIds.contains(toolchain->typeId()))
return ".obj";
return ".o";
}();
cbc->buildCMakeTarget(sourceFile + objExtension);
}
void CMakeManager::buildFileContextMenu()

View File

@@ -16,6 +16,12 @@ if (QT_CREATOR_SKIP_PACKAGE_MANAGER_SETUP)
endif()
option(QT_CREATOR_SKIP_PACKAGE_MANAGER_SETUP "Skip Qt Creator's package manager auto-setup" OFF)
# Store the C/C++ object output extension
if (CMAKE_VERSION GREATER_EQUAL "3.19")
cmake_language(DEFER CALL set CMAKE_C_OUTPUT_EXTENSION "${CMAKE_C_OUTPUT_EXTENSION}" CACHE STRING "" FORCE)
cmake_language(DEFER CALL set CMAKE_CXX_OUTPUT_EXTENSION "${CMAKE_CXX_OUTPUT_EXTENSION}" CACHE STRING "" FORCE)
endif()
macro(qtc_auto_setup_compiler_standard toolchainFile)
foreach(lang_var C CXX CUDA OBJC OBJCXX)
foreach(prop_var STANDARD STANDARD_REQUIRED EXTENSIONS)