Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# What's New?

## 1.22

Features:

- Pass mandatory compiler arguments from `CMAKE_<LANG>_COMPILER` to cpptools so it can properly determine system include paths and built-in preprocessor macro definitions. Requires CMake 4.3 or newer. [#4627](https://github.com/microsoft/vscode-cmake-tools/pull/4627) [@cwalther](https://github.com/cwalther)

## 1.21

Features:
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3949,6 +3949,7 @@
"translations-import": "gulp translations-import",
"package": "vsce package --yarn -o cmake-tools.vsix",
"pretest": "tsc -p test.tsconfig.json",
"pretest-buildfakebin": "cmake -DCMAKE_INSTALL_PREFIX=test/fakebin -DCMAKE_BUILD_TYPE=Release -S test/fakeOutputGenerator -B test/fakeOutputGenerator/build && cmake --build test/fakeOutputGenerator/build && cmake --install test/fakeOutputGenerator/build && cmake -E rm -rf test/fakeOutputGenerator/build",
"lint": "gulp lint",
"smokeTests": "yarn run pretest && node ./out/test/smoke/badProject/runTest.js && node ./out/test/smoke/goodProject/runTest.js && node ./out/test/smoke/noCtest/runTest.js",
"unitTests": "yarn run pretest && node ./out/test/unit-tests/runTest.js",
Expand Down Expand Up @@ -4010,7 +4011,7 @@
"tsconfig-paths": "^3.11.0",
"tslint": "^6.1.3",
"typescript": "^4.1.5",
"vscode-cmake-tools": "^1.5.0",
"vscode-cmake-tools": "^1.6.0",
"vscode-nls-dev": "^3.3.2",
"webpack": "^5.94.0",
"webpack-cli": "^4.5.0"
Expand Down
13 changes: 8 additions & 5 deletions src/cmakeExecutable.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as proc from '@cmt/proc';
import * as util from '@cmt/util';
import {setContextAndStore} from '@cmt/extension';
import { setContextAndStore } from '@cmt/extension';
import * as logging from '@cmt/logging';
import * as nls from 'vscode-nls';
import { ConfigurationReader } from './config';
Expand Down Expand Up @@ -69,10 +69,13 @@ export async function getCMakeExecutableInformation(path: string, config?: Confi
// Support for CMake using an internal default generator when one isn't provided
cmake.isDefaultGeneratorSupported = util.versionGreaterOrEquals(cmake.version, cmake.minimalDefaultGeneratorVersion);
}
const debuggerPresent = await proc.execute(path, ['-E', 'capabilities'], null, execOpt).result;
if (debuggerPresent.retc === 0 && debuggerPresent.stdout) {
console.assert(debuggerPresent.stdout);
const stdoutJson = JSON.parse(debuggerPresent.stdout);
const capabilities = await proc.execute(path, ['-E', 'capabilities'], null, execOpt).result;
if (capabilities.retc === 0 && capabilities.stdout) {
console.assert(capabilities.stdout);
const stdoutJson = JSON.parse(capabilities.stdout);
if (cmake.isServerModeSupported && !stdoutJson["serverMode"]) {
cmake.isServerModeSupported = false;
}
cmake.isDebuggerSupported = stdoutJson["debugger"];
await setCMakeDebuggerAvailableContext(
cmake.isDebuggerSupported?.valueOf() ?? false
Expand Down
25 changes: 18 additions & 7 deletions src/cpptools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,8 @@ export class CppConfigurationProvider implements cpptools.CustomConfigurationPro
let compilerToolchains: CodeModelToolchain | undefined;
if ("toolchains" in opts.codeModelContent) {
compilerToolchains = opts.codeModelContent.toolchains?.get(lang ?? "")
|| opts.codeModelContent.toolchains?.get('CXX')
|| opts.codeModelContent.toolchains?.get('C');
|| opts.codeModelContent.toolchains?.get('CXX')
|| opts.codeModelContent.toolchains?.get('C');
}
// If none of those work, fall back to the same order, but in the cache.
const compilerCache = opts.cache.get(`CMAKE_${lang}_COMPILER`)
Expand All @@ -449,22 +449,34 @@ export class CppConfigurationProvider implements cpptools.CustomConfigurationPro
const targetArchFromToolchains = targetFromToolchains ? parseTargetArch(targetFromToolchains) : undefined;

const normalizedCompilerPath = util.platformNormalizePath(compilerPath);
let compileCommandFragments = useFragments ? (fileGroup.compileCommandFragments || target.compileCommandFragments) : [];
const compileCommandFragments = useFragments ? (fileGroup.compileCommandFragments || target.compileCommandFragments).slice(0) : [];
const getAsFlags = (fragments?: string[]) => {
if (!fragments) {
return [];
}
return [...util.flatMap(fragments, fragment => shlex.split(fragment))];
};
let flags: string[] = [];
const flags: string[] = [];
let extraDefinitions: string[] = [];
let standard: StandardVersion;
let targetArch: Architecture;
let intelliSenseMode: IntelliSenseMode;
let defines = (fileGroup.defines || target.defines || []);
if (!useFragments) {
if (useFragments) {
if (compilerToolchains?.commandFragment) {
compileCommandFragments.unshift(compilerToolchains.commandFragment);
}
} else {
if (compilerToolchains?.commandFragment) {
// This is incorrect: shlex.split() does not do what one would
// expect, it treats quotes and backslashes differently than a
// shell would. But maybe it's good enough for a legacy codepath,
// what are the chances that anyone has old CppTools but new
// CMake Tools and new CMake?
flags.push(...shlex.split(compilerToolchains.commandFragment));
}
// Send the intelliSenseMode and standard only for CppTools API v5 and below.
flags = getAsFlags(fileGroup.compileCommandFragments || target.compileCommandFragments);
flags.push(...getAsFlags(fileGroup.compileCommandFragments || target.compileCommandFragments));
({ extraDefinitions, standard, targetArch } = parseCompileFlags(this.cpptoolsVersion, flags, lang));
defines = defines.concat(extraDefinitions);
intelliSenseMode = getIntelliSenseMode(this.cpptoolsVersion, compilerPath, targetArchFromToolchains ?? targetArch);
Expand All @@ -491,7 +503,6 @@ export class CppConfigurationProvider implements cpptools.CustomConfigurationPro
}
if (targetFromToolchains) {
if (useFragments) {
compileCommandFragments = compileCommandFragments.slice(0);
compileCommandFragments.push(`--target=${targetFromToolchains}`);
} else {
flags.push(`--target=${targetFromToolchains}`);
Expand Down
11 changes: 8 additions & 3 deletions src/drivers/cmakeFileApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ export namespace Toolchains {

export interface Compiler {
path?: string;
commandFragment?: string;
id?: string;
version?: string;
target?: string;
Expand Down Expand Up @@ -594,11 +595,15 @@ export async function loadToolchains(filename: string): Promise<Map<string, Code

return toolchains.toolchains.reduce((acc, el) => {
if (el.compiler.path) {
const tc: CodeModelToolchain = { path: el.compiler.path };
if (el.compiler.target) {
acc.set(el.language, { path: el.compiler.path, target: el.compiler.target });
} else {
acc.set(el.language, { path: el.compiler.path });
tc.target = el.compiler.target;
}
if (el.compiler.commandFragment) {
// available (optional) since toolchains object version 1.1 (CMake 4.3)
tc.commandFragment = el.compiler.commandFragment;
}
acc.set(el.language, tc);
}
return acc;
}, new Map<string, CodeModelToolchain>());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0)
cmake_minimum_required(VERSION 3.5.0)
project(TestBuildProcess VERSION 0.1.0)

set(CMT_COOKIE passed-cookie CACHE STRING "Cookie to be written by the main executable")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0)
cmake_minimum_required(VERSION 3.5.0)
project(TestBuildProcess VERSION 0.1.0)

set(CMT_COOKIE passed-cookie CACHE STRING "Cookie to be written by the main executable")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0)
cmake_minimum_required(VERSION 3.5.0)
project(TestBuildProcess VERSION 0.1.0)

set(CMT_COOKIE passed-cookie CACHE STRING "Cookie to be written by the main executable")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0)
cmake_minimum_required(VERSION 3.5.0)
project(TestBuildProcess VERSION 0.1.0)

set(CMT_COOKIE passed-cookie CACHE STRING "Cookie to be written by the main executable")
Expand Down
2 changes: 1 addition & 1 deletion test/smoke/badProject/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.2)
cmake_minimum_required(VERSION 3.5)
project(TestProject VERSION 0.1)

bad_command()
2 changes: 1 addition & 1 deletion test/smoke/goodProject/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.2)
cmake_minimum_required(VERSION 3.5)
project(TestProject VERSION 0.1)

add_executable(test-exe main.cpp)
2 changes: 1 addition & 1 deletion test/smoke/noCtest/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.2)
cmake_minimum_required(VERSION 3.5)
project(TestProject VERSION 0.1)

add_executable(test-exe main.cpp)
16 changes: 14 additions & 2 deletions test/unit-tests/cpptools.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,20 @@ suite('CppTools tests', () => {
}]
}]
}],
toolchains: new Map<string, codeModel.CodeModelToolchain>([['CXX', { path: 'path_from_toolchain_object' }]])
toolchains: new Map<string, codeModel.CodeModelToolchain>([['CXX', {
path: 'path_from_toolchain_object',
commandFragment: '--fragment from -toolchain=object'
}]])
};

provider.updateConfigurationData({ cache, codeModelContent: codeModel3, activeTarget: 'target3', activeBuildTypeVariant: 'Release', folder: smokeFolder });
let configurations = await provider.provideConfigurations([vscode.Uri.file(sourceFile3)]);
expect(configurations.length).to.eq(1);
expect(configurations[0].configuration.compilerPath).to.eq('path_from_toolchain_object');
expect(configurations[0].configuration.compilerFragments).to.be.undefined;
expect(configurations[0].configuration.compilerArgs?.[0]).to.eq('--fragment');
expect(configurations[0].configuration.compilerArgs?.[1]).to.eq('from');
expect(configurations[0].configuration.compilerArgs?.[2]).to.eq('-toolchain=object');

configurations = await provider.provideConfigurations([uri1]);
expect(configurations.length).to.eq(1);
Expand Down Expand Up @@ -333,13 +340,18 @@ suite('CppTools tests', () => {
}]
}]
}],
toolchains: new Map<string, codeModel.CodeModelToolchain>([['CXX', { path: 'path_from_toolchain_object' }]])
toolchains: new Map<string, codeModel.CodeModelToolchain>([['CXX', {
path: 'path_from_toolchain_object',
commandFragment: '--fragment "from" -toolchain=object'
}]])
};

provider.updateConfigurationData({ cache, codeModelContent: codeModel3, activeTarget: 'target3', activeBuildTypeVariant: 'Release', folder: smokeFolder });
let configurations = await provider.provideConfigurations([vscode.Uri.file(sourceFile3)]);
expect(configurations.length).to.eq(1);
expect(configurations[0].configuration.compilerPath).to.eq('path_from_toolchain_object');
expect(configurations[0].configuration.compilerFragments?.[0]).to.eq('--fragment "from" -toolchain=object');
expect(configurations[0].configuration.compilerArgs).to.be.empty;

configurations = await provider.provideConfigurations([uri1]);
expect(configurations.length).to.eq(1);
Expand Down
8 changes: 6 additions & 2 deletions test/unit-tests/driver/cmakeFileApiDriver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@ async function cmakeFileApiDriverFactory(cmake: CMakeExecutable, config: Configu
return d;
}

makeDriverTestsuite('FileAPI', cmakeFileApiDriverFactory);
makeCodeModelDriverTestsuite('FileAPI', cmakeFileApiDriverFactory);
function driverSupportsCMake(cmake: CMakeExecutable) {
return cmake.isFileApiModeSupported ?? false;
}

makeDriverTestsuite('FileAPI', cmakeFileApiDriverFactory, driverSupportsCMake);
makeCodeModelDriverTestsuite('FileAPI', cmakeFileApiDriverFactory, driverSupportsCMake);
8 changes: 6 additions & 2 deletions test/unit-tests/driver/cmakeServerDriver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ async function cmakeServerDriverFactory(cmake: CMakeExecutable, config: Configur
return d;
}

function driverSupportsCMake(cmake: CMakeExecutable) {
return cmake.isServerModeSupported ?? false;
}

// CMake 3.18.3 has problems on macOS, but we don't have an action to install 3.18.2 right now.
// CMake Server is deprecated and unavailable after 3.20 so we will just skip the tests on macOS.
// We still have coverage on other platforms.
// Also removing support for CMake Server on Windows as we switch to windows-2022 and beyond. CMake version 3.20 and below
// don't have VS 2022 support, and CMake 3.20 and beyond don't have server support, so we will disable the tests on Windows as well.
if (process.platform !== 'darwin' && process.platform !== 'win32') {
makeDriverTestsuite('Server', cmakeServerDriverFactory);
makeCodeModelDriverTestsuite('Server', cmakeServerDriverFactory);
makeDriverTestsuite('Server', cmakeServerDriverFactory, driverSupportsCMake);
makeCodeModelDriverTestsuite('Server', cmakeServerDriverFactory, driverSupportsCMake);
}
Loading