async configure()

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;
        }
    }