in src/drivers/driver.ts [1187:1384]
async configure(trigger: ConfigureTrigger, extra_args: string[], consumer?: proc.OutputConsumer, withoutCmakeSettings: boolean = false, showCommandOnly?: boolean): Promise<number> {
// Check if the configuration is using cache in the first configuration and adjust the logging messages based on that.
const shouldUseCachedConfiguration: boolean = this.shouldUseCachedConfiguration(trigger);
if (trigger === ConfigureTrigger.configureWithCache && !shouldUseCachedConfiguration) {
log.debug(localize('no.cached.config', "No cached config could be used for IntelliSense"));
return -2;
}
if (this.configRunning) {
await this.preconditionHandler(CMakePreconditionProblems.ConfigureIsAlreadyRunning);
return -1;
}
if (this.buildRunning) {
await this.preconditionHandler(CMakePreconditionProblems.BuildIsAlreadyRunning);
return -1;
}
this.configRunning = true;
try {
// _beforeConfigureOrBuild needs to refresh expansions early because it reads various settings
// (example: cmake.sourceDirectory).
await this._refreshExpansions();
if (!showCommandOnly) {
if (!shouldUseCachedConfiguration) {
log.debug(localize('start.configure', 'Start configure'), extra_args);
} else {
log.debug(localize('use.cached.configuration', 'Use cached configuration'), extra_args);
}
}
const pre_check_ok = await this._beforeConfigureOrBuild(showCommandOnly);
if (!pre_check_ok) {
return -2;
}
// Cache flags will construct the command line for cmake.
const init_cache_flags = this.generateInitCacheFlags();
let expanded_flags: string[];
if (this.useCMakePresets) {
if (!this._configurePreset) {
log.debug(localize('no.config.Preset', 'No configure preset selected'));
return -3;
}
// For now, fields in presets are expanded when the preset is selected
expanded_flags = init_cache_flags.concat(preset.configureArgs(this._configurePreset));
} else {
const common_flags = ['--no-warn-unused-cli'].concat(extra_args, this.config.configureArgs);
const define_flags = withoutCmakeSettings ? [] : this.generateCMakeSettingsFlags();
const final_flags = common_flags.concat(define_flags, init_cache_flags);
// Get expanded configure environment
const expanded_configure_env = await this.getConfigureEnvironment();
// Expand all flags
const opts = this.expansionOptions;
const expanded_flags_promises = final_flags.map(
async (value: string) => expand.expandString(value, { ...opts, envOverride: expanded_configure_env }));
expanded_flags = await Promise.all(expanded_flags_promises);
}
if (!shouldUseCachedConfiguration) {
log.trace(localize('cmake.flags.are', 'CMake flags are {0}', JSON.stringify(expanded_flags)));
}
// A more complete round of expansions
await this._refreshExpansions();
const timeStart: number = new Date().getTime();
let retc: number;
if (shouldUseCachedConfiguration) {
retc = await this.doCacheConfigure();
this._isConfiguredAtLeastOnce = true;
return retc;
} else {
retc = await this.doConfigure(expanded_flags, consumer, showCommandOnly);
this._isConfiguredAtLeastOnce = true;
}
const timeEnd: number = new Date().getTime();
const cmakeVersion = this.cmake.version;
let telemetryProperties: telemetry.Properties;
if (this.useCMakePresets) {
telemetryProperties = {
CMakeExecutableVersion: cmakeVersion ? util.versionToString(cmakeVersion) : '',
CMakeGenerator: this.getGeneratorNameForTelemetry(),
Preset: this.useCMakePresets ? 'true' : 'false',
Trigger: trigger,
ShowCommandOnly: showCommandOnly ? 'true' : 'false'
};
} else {
telemetryProperties = {
CMakeExecutableVersion: cmakeVersion ? util.versionToString(cmakeVersion) : '',
CMakeGenerator: this.getGeneratorNameForTelemetry(),
ConfigType: this.isMultiConfFast ? 'MultiConf' : this.currentBuildType || '',
Toolchain: this._kit?.toolchainFile ? 'true' : 'false', // UseToolchain?
Trigger: trigger,
ShowCommandOnly: showCommandOnly ? 'true' : 'false'
};
}
if (this._kit?.compilers) {
let cCompilerVersion;
let cppCompilerVersion;
if (this._kit.compilers["C"]) {
cCompilerVersion = await this.getCompilerVersion(this._kit.compilers["C"]);
}
if (this._kit.compilers["CXX"]) {
cppCompilerVersion = await this.getCompilerVersion(this._kit.compilers["CXX"]);
}
if (cCompilerVersion) {
telemetryProperties.CCompilerName = cCompilerVersion.name;
telemetryProperties.CCompilerVersion = cCompilerVersion.version;
}
if (cppCompilerVersion) {
telemetryProperties.CppCompilerName = cppCompilerVersion.name;
telemetryProperties.CppCompilerVersion = cppCompilerVersion.version;
}
} else if (this._kit?.visualStudio && this._kit.visualStudioArchitecture) {
const env = await getVSKitEnvironment(this._kit);
const dirs = env?.['Path']?.split(';') ?? [];
let compilerPath = '';
for (const dir of dirs) {
if (dir.indexOf('MSVC') > 0) {
compilerPath = path.join(dir, 'cl.exe');
break;
}
}
if (compilerPath) {
const compiler = await this.getCompilerVersion(compilerPath);
telemetryProperties.CCompilerVersion = compiler.version;
telemetryProperties.CppCompilerVersion = compiler.version;
} else {
telemetryProperties.CCompilerVersion = 'unknown';
telemetryProperties.CppCompilerVersion = 'unknown';
}
telemetryProperties.CCompilerName = 'cl';
telemetryProperties.CppCompilerName = 'cl';
}
if (this._kit?.visualStudioArchitecture) {
telemetryProperties.VisualStudioArchitecture = this._kit?.visualStudioArchitecture;
}
const telemetryMeasures: telemetry.Measures = {
Duration: timeEnd - timeStart
};
if (this.useCMakePresets && this.workspaceFolder) {
const configurePresets = preset.configurePresets(this.workspaceFolder);
const userConfigurePresets = preset.userConfigurePresets(this.workspaceFolder);
const buildPresets = preset.buildPresets(this.workspaceFolder);
const userBuildPresets = preset.userBuildPresets(this.workspaceFolder);
const testPresets = preset.testPresets(this.workspaceFolder);
const userTestPresets = preset.userTestPresets(this.workspaceFolder);
telemetryMeasures['ConfigurePresets'] = configurePresets.length;
telemetryMeasures['HiddenConfigurePresets'] = this.countHiddenPresets(configurePresets);
telemetryMeasures['UserConfigurePresets'] = userConfigurePresets.length;
telemetryMeasures['HiddenUserConfigurePresets'] = this.countHiddenPresets(userConfigurePresets);
telemetryMeasures['BuildPresets'] = buildPresets.length;
telemetryMeasures['HiddenBuildPresets'] = this.countHiddenPresets(buildPresets);
telemetryMeasures['UserBuildPresets'] = userBuildPresets.length;
telemetryMeasures['HiddenUserBuildPresets'] = this.countHiddenPresets(userBuildPresets);
telemetryMeasures['TestPresets'] = testPresets.length;
telemetryMeasures['HiddenTestPresets'] = this.countHiddenPresets(testPresets);
telemetryMeasures['UserTestPresets'] = userTestPresets.length;
telemetryMeasures['HiddenUserTestPresets'] = this.countHiddenPresets(userTestPresets);
}
if (consumer) {
if (consumer instanceof CMakeOutputConsumer) {
let errorCount: number = 0;
let warningCount: number = 0;
consumer.diagnostics.forEach(v => {
if (v.diag.severity === 0) {
errorCount++;
} else if (v.diag.severity === 1) {
warningCount++;
}
});
telemetryMeasures['ErrorCount'] = errorCount;
telemetryMeasures['WarningCount'] = warningCount;
} else {
// Wrong type: shouldn't get here, just in case
rollbar.error('Wrong build result type.');
telemetryMeasures['ErrorCount'] = retc ? 1 : 0;
}
}
telemetry.logEvent('configure', telemetryProperties, telemetryMeasures);
return retc;
} catch {
log.info(localize('configure.failed', 'Failed to configure project'));
return -1;
} finally {
this.configRunning = false;
}
}