Separate code model driver interface definition from CMS driver (#784)
* Add driver code model interface - Create driver code model interfac The cms client class has a code model. This code model is defined by the cmake cmake-server(7). The cmake-tools-extension needs a code model, which does not have to be identical to the cmake server. For more flexibility in future, a separate model is created. The first version contains all information required for the extension (e.g. for cpptools, code model tree) and is based on the cmake-server(7) model. - Separate code mode driver support from CMS driver version * Add first code model test and fix typos and a small bug * Fix unix build by separate test for single configuration generators * Fix node.js version problem with streamfilter * Add tests for project and target information * Fix linux build and reformat code model tests * Extend tests for shared library and utilities - Add tests for interface parts of cpptools - Add tests for utilities parts of tree view - Extend CMake test Project by required calls * Fix missing isGenerated in cms-client * Fix wrong library filename * Fix MacOS build and disable windows test for mingw (#775) * Fix regex * Update codemodel driver interface .documentation * Clean up tests and add sysroot test Clean up - Add helper for code model generation - Restructure test - Fix spelling Add missing sysroot test * Fix instable tests - Different CMake versions generate different code model outputs. - macOS test fails. I am unable to test the problem, but it seems the sysroot variable is required to build on macOS. * Remove test filter
This commit is contained in:
Родитель
13e97676da
Коммит
6f6c277dec
|
@ -3,7 +3,7 @@ image:
|
|||
- Visual Studio 2017
|
||||
|
||||
install:
|
||||
- ps: Install-Product node 8.9.3 x64
|
||||
- ps: Install-Product node 8 x64
|
||||
build_script:
|
||||
- pwsh: ./scripts/ci.ps1
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ import * as vscode from 'vscode';
|
|||
|
||||
import * as api from './api';
|
||||
import {ExecutionOptions, ExecutionResult} from './api';
|
||||
import {BadHomeDirectoryError, CodeModelContent} from '@cmt/drivers/cms-client';
|
||||
import * as codemodel_api from '@cmt/drivers/codemodel-driver-interface';
|
||||
import {BadHomeDirectoryError} from '@cmt/drivers/cms-client';
|
||||
import {CMakeServerClientDriver, NoGeneratorError} from '@cmt/drivers/cms-driver';
|
||||
import {CTestDriver} from './ctest';
|
||||
import {BasicTestResults} from './ctest';
|
||||
|
@ -133,7 +134,7 @@ export class CMakeTools implements vscode.Disposable, api.CMakeToolsAPI {
|
|||
*/
|
||||
get codeModel() { return this._codeModel.value; }
|
||||
get onCodeModelChanged() { return this._codeModel.changeEvent; }
|
||||
private readonly _codeModel = new Property<CodeModelContent|null>(null);
|
||||
private readonly _codeModel = new Property<codemodel_api.CodeModelContent|null>(null);
|
||||
private _codeModelDriverSub: vscode.Disposable|null = null;
|
||||
|
||||
/**
|
||||
|
@ -459,7 +460,7 @@ export class CMakeTools implements vscode.Disposable, api.CMakeToolsAPI {
|
|||
}
|
||||
const drv = await this._cmakeDriver;
|
||||
console.assert(drv !== null, 'Null driver immediately after creation?');
|
||||
if (drv instanceof CMakeServerClientDriver) {
|
||||
if (drv instanceof codemodel_api.CodeModelDriver) {
|
||||
this._codeModelDriverSub = drv.onCodeModelChanged(cm => { this._codeModel.set(cm); });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/ /** */
|
||||
|
||||
import {CMakeCache} from '@cmt/cache';
|
||||
import * as cms from '@cmt/drivers/cms-client';
|
||||
import * as codemodel_api from '@cmt/drivers/codemodel-driver-interface';
|
||||
import {createLogger} from '@cmt/logging';
|
||||
import rollbar from '@cmt/rollbar';
|
||||
import * as shlex from '@cmt/shlex';
|
||||
|
@ -131,9 +131,9 @@ export function parseCompileFlags(args: string[], lang?: string): CompileFlagInf
|
|||
*/
|
||||
export interface CodeModelParams {
|
||||
/**
|
||||
* The CMake Server codemodel message content. This is the important one.
|
||||
* The CMake codemodel content. This is the important one.
|
||||
*/
|
||||
codeModel: cms.CodeModelContent;
|
||||
codeModel: codemodel_api.CodeModelContent;
|
||||
/**
|
||||
* The contents of the CMakeCache.txt, which also provides supplementary
|
||||
* configuration information.
|
||||
|
@ -227,7 +227,7 @@ export class CppConfigurationProvider implements cpt.CustomConfigurationProvider
|
|||
* @param fileGroup The file group from the code model to create config data for
|
||||
* @param opts Index update options
|
||||
*/
|
||||
private _buildConfigurationData(fileGroup: cms.CodeModelFileGroup, opts: CodeModelParams, target: TargetDefaults, sysroot: string):
|
||||
private _buildConfigurationData(fileGroup: codemodel_api.CodeModelFileGroup, opts: CodeModelParams, target: TargetDefaults, sysroot: string):
|
||||
cpt.SourceFileConfiguration {
|
||||
// If the file didn't have a language, default to C++
|
||||
const lang = fileGroup.language;
|
||||
|
@ -281,7 +281,7 @@ export class CppConfigurationProvider implements cpt.CustomConfigurationProvider
|
|||
* @param opts Index update options
|
||||
*/
|
||||
private _updateFileGroup(sourceDir: string,
|
||||
grp: cms.CodeModelFileGroup,
|
||||
grp: codemodel_api.CodeModelFileGroup,
|
||||
opts: CodeModelParams,
|
||||
target: TargetDefaults,
|
||||
sysroot: string) {
|
||||
|
|
|
@ -224,6 +224,7 @@ export interface CodeModelFileGroup {
|
|||
includePath?: {path: string; isSystem?: boolean;}[];
|
||||
defines?: string[];
|
||||
sources: string[];
|
||||
isGenerated: boolean;
|
||||
}
|
||||
|
||||
export type TargetTypeString = ('STATIC_LIBRARY' | 'MODULE_LIBRARY' | 'SHARED_LIBRARY' | 'OBJECT_LIBRARY' | 'EXECUTABLE' | 'UTILITY' | 'INTERFACE_LIBRARY');
|
||||
|
|
|
@ -7,7 +7,8 @@ import * as api from '@cmt/api';
|
|||
import {CacheEntryProperties, ExecutableTarget, RichTarget} from '@cmt/api';
|
||||
import * as cache from '@cmt/cache';
|
||||
import * as cms from '@cmt/drivers/cms-client';
|
||||
import {CMakeDriver, CMakePreconditionProblemSolver} from '@cmt/drivers/driver';
|
||||
import * as codemodel from '@cmt/drivers/codemodel-driver-interface';
|
||||
import {CMakePreconditionProblemSolver} from '@cmt/drivers/driver';
|
||||
import {Kit, CMakeGenerator} from '@cmt/kit';
|
||||
import {createLogger} from '@cmt/logging';
|
||||
import * as proc from '@cmt/proc';
|
||||
|
@ -24,7 +25,7 @@ export class NoGeneratorError extends Error {
|
|||
message: string = localize('no.usable.generator.found', 'No usable generator found.');
|
||||
}
|
||||
|
||||
export class CMakeServerClientDriver extends CMakeDriver {
|
||||
export class CMakeServerClientDriver extends codemodel.CodeModelDriver {
|
||||
private constructor(cmake: CMakeExecutable, readonly config: ConfigurationReader, workspaceFolder: string | null, preconditionHandler: CMakePreconditionProblemSolver) {
|
||||
super(cmake, config, workspaceFolder, preconditionHandler);
|
||||
this.config.onChange('environment', () => this._restartClient());
|
||||
|
@ -56,7 +57,7 @@ export class CMakeServerClientDriver extends CMakeDriver {
|
|||
this._codeModel = v;
|
||||
}
|
||||
|
||||
private readonly _codeModelChanged = new vscode.EventEmitter<null|cms.CodeModelContent>();
|
||||
private readonly _codeModelChanged = new vscode.EventEmitter<null|codemodel.CodeModelContent>();
|
||||
get onCodeModelChanged() { return this._codeModelChanged.event; }
|
||||
|
||||
async asyncDispose() {
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
import {CMakeDriver} from '@cmt/drivers/driver';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
/**
|
||||
* This file contains the API description between IDE parts and the CMake model driver.
|
||||
* This API CodeModel contains only the current required CMake code model parts.
|
||||
* There is more information provided by CMake than is mapped.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Describes all required methods for access to the build code model of the driver
|
||||
*/
|
||||
export abstract class CodeModelDriver extends CMakeDriver {
|
||||
/**
|
||||
* Event registration for code model updates
|
||||
*
|
||||
* This event is fired after update of the code model, like after cmake configuration.
|
||||
*/
|
||||
abstract onCodeModelChanged: vscode.Event<CodeModelContent|null>;
|
||||
}
|
||||
|
||||
export type TargetTypeString
|
||||
= ('STATIC_LIBRARY'|'MODULE_LIBRARY'|'SHARED_LIBRARY'|'OBJECT_LIBRARY'|'EXECUTABLE'|'UTILITY'|'INTERFACE_LIBRARY');
|
||||
|
||||
/** Describes a cmake target */
|
||||
export interface CodeModelTarget {
|
||||
/**
|
||||
* A string specifying the logical name of the target.
|
||||
*
|
||||
* (Source CMake Documentation cmake-file-api(7))
|
||||
*/
|
||||
readonly name: string;
|
||||
|
||||
/**
|
||||
* A string specifying the type of the target.
|
||||
* The value is one of EXECUTABLE, STATIC_LIBRARY, SHARED_LIBRARY, MODULE_LIBRARY, OBJECT_LIBRARY, or UTILITY.
|
||||
*
|
||||
* (Source CMake Documentation cmake-file-api(7))
|
||||
*
|
||||
* \todo clarify need of INTERFACE_LIBRARY type
|
||||
*/
|
||||
type: TargetTypeString;
|
||||
|
||||
/** A string specifying the absolute path to the target’s source directory. */
|
||||
sourceDirectory?: string;
|
||||
|
||||
/** Name of the target artifact on disk (library or executable file name). */
|
||||
fullName?: string;
|
||||
|
||||
/** List of absolute paths to a target´s build artifacts. */
|
||||
artifacts?: string[];
|
||||
|
||||
/**
|
||||
* The file groups describe a list of compilation information for artifacts of this target.
|
||||
* The file groups contains source code files that use the same compilation information
|
||||
* and are known by CMake.
|
||||
*/
|
||||
fileGroups?: CodeModelFileGroup[];
|
||||
|
||||
/**
|
||||
* Represents the CMAKE_SYSROOT variable
|
||||
*/
|
||||
sysroot?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes a file group to describe the build settings.
|
||||
*/
|
||||
export interface CodeModelFileGroup {
|
||||
/** List of source files with the same compilation information */
|
||||
sources: string[];
|
||||
|
||||
/** Specifies the language (C, C++, ...) for the toolchain */
|
||||
language?: string;
|
||||
|
||||
/** Include paths for compilation of a source file */
|
||||
includePath?: {
|
||||
/** include path */
|
||||
path: string;
|
||||
}[];
|
||||
|
||||
/** Compiler flags */
|
||||
compileFlags?: string;
|
||||
|
||||
/** Defines */
|
||||
defines?: string[];
|
||||
|
||||
/** CMake generated file group */
|
||||
isGenerated: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes cmake project and all its related targets
|
||||
*/
|
||||
export interface CodeModelProject {
|
||||
/** Name of the project */
|
||||
name: string;
|
||||
|
||||
/** List of targets */
|
||||
targets: CodeModelTarget[];
|
||||
|
||||
/** Location of the Project */
|
||||
sourceDirectory: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes cmake configuration
|
||||
*/
|
||||
export interface CodeModelConfiguration {
|
||||
/** List of project() from CMakeLists.txt */
|
||||
projects: CodeModelProject[];
|
||||
}
|
||||
|
||||
/** Describes the cmake model */
|
||||
export interface CodeModelContent {
|
||||
/** List of configurations provided by the selected generator */
|
||||
configurations: CodeModelConfiguration[];
|
||||
}
|
21
src/tree.ts
21
src/tree.ts
|
@ -1,4 +1,4 @@
|
|||
import * as cms from '@cmt/drivers/cms-client';
|
||||
import * as codemodel_api from '@cmt/drivers/codemodel-driver-interface';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
|
@ -100,7 +100,7 @@ function collapseTreeInplace<T>(tree: PathedTree<T>): void {
|
|||
* Get the path to an icon for the given type of CMake target.
|
||||
* @param type The type of target
|
||||
*/
|
||||
function iconForTargetType(type: cms.TargetTypeString): string {
|
||||
function iconForTargetType(type: codemodel_api.TargetTypeString): string {
|
||||
switch (type) {
|
||||
case 'EXECUTABLE':
|
||||
return 'binary-icon.svg';
|
||||
|
@ -115,7 +115,7 @@ function iconForTargetType(type: cms.TargetTypeString): string {
|
|||
}
|
||||
}
|
||||
|
||||
function sortStringForType(type: cms.TargetTypeString): string {
|
||||
function sortStringForType(type: codemodel_api.TargetTypeString): string {
|
||||
switch (type) {
|
||||
case 'EXECUTABLE':
|
||||
return 'aaa';
|
||||
|
@ -232,7 +232,7 @@ export class SourceFileNode extends BaseNode {
|
|||
}
|
||||
|
||||
export class TargetNode extends BaseNode {
|
||||
constructor(readonly projectName: string, cm: cms.CodeModelTarget) {
|
||||
constructor(readonly projectName: string, cm: codemodel_api.CodeModelTarget) {
|
||||
super(`${projectName}::${cm.name}`);
|
||||
this.name = cm.name;
|
||||
this.sourceDir = cm.sourceDirectory || '';
|
||||
|
@ -242,7 +242,7 @@ export class TargetNode extends BaseNode {
|
|||
readonly name: string;
|
||||
readonly sourceDir: string;
|
||||
private _fullName = '';
|
||||
private _type: cms.TargetTypeString = 'UTILITY';
|
||||
private _type: codemodel_api.TargetTypeString = 'UTILITY';
|
||||
private _isDefault = false;
|
||||
private _isLaunch = false;
|
||||
private _fsPath: string = '';
|
||||
|
@ -306,7 +306,7 @@ export class TargetNode extends BaseNode {
|
|||
}
|
||||
}
|
||||
|
||||
update(cm: cms.CodeModelTarget, ctx: TreeUpdateContext) {
|
||||
update(cm: codemodel_api.CodeModelTarget, ctx: TreeUpdateContext) {
|
||||
console.assert(this.name == cm.name);
|
||||
console.assert(this.sourceDir == (cm.sourceDirectory || ''));
|
||||
|
||||
|
@ -393,12 +393,12 @@ class ProjectNode extends BaseNode {
|
|||
return item;
|
||||
}
|
||||
|
||||
update(pr: cms.CodeModelProject, ctx: TreeUpdateContext) {
|
||||
update(pr: codemodel_api.CodeModelProject, ctx: TreeUpdateContext) {
|
||||
if (pr.name !== this.name) {
|
||||
rollbar.error(localize('update.project.with.mismatch', 'Update project with mismatching name property'), {newName: pr.name, oldName: this.name});
|
||||
}
|
||||
|
||||
const tree: PathedTree<cms.CodeModelTarget> = {
|
||||
const tree: PathedTree<codemodel_api.CodeModelTarget> = {
|
||||
pathPart: '',
|
||||
children: [],
|
||||
items: [],
|
||||
|
@ -433,11 +433,12 @@ export class ProjectOutlineProvider implements vscode.TreeDataProvider<BaseNode>
|
|||
|
||||
private _children: BaseNode[] = [];
|
||||
|
||||
private _codeModel: cms.CodeModelContent = {configurations: []};
|
||||
private _codeModel: codemodel_api.CodeModelContent = {configurations: []};
|
||||
|
||||
get codeModel() { return this._codeModel; }
|
||||
|
||||
updateCodeModel(model: cms.CodeModelContent|null, exCtx: {launchTargetName: string|null, defaultTargetName: string}) {
|
||||
updateCodeModel(model: codemodel_api.CodeModelContent|null,
|
||||
exCtx: {launchTargetName: string|null, defaultTargetName: string}) {
|
||||
if (!model || model.configurations.length < 1) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,241 @@
|
|||
import {getCMakeExecutableInformation} from '@cmt/cmake/cmake-executable';
|
||||
import {ConfigurationReader} from '@cmt/config';
|
||||
import * as cms_driver from '@cmt/drivers/cms-driver';
|
||||
import * as codemodel_api from '@cmt/drivers/codemodel-driver-interface';
|
||||
import * as chai from 'chai';
|
||||
import {expect} from 'chai';
|
||||
import * as chaiString from 'chai-string';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as rimraf from 'rimraf';
|
||||
|
||||
chai.use(chaiString);
|
||||
|
||||
import {Kit} from '@cmt/kit';
|
||||
import {CMakeDriver} from '@cmt/drivers/driver';
|
||||
|
||||
const here = __dirname;
|
||||
function getTestRootFilePath(filename: string): string {
|
||||
return path.normalize(path.join(here, '../../../..', filename));
|
||||
}
|
||||
|
||||
function cleanupBuildDir(build_dir: string): boolean {
|
||||
if (fs.existsSync(build_dir)) {
|
||||
rimraf.sync(build_dir);
|
||||
}
|
||||
return !fs.existsSync(build_dir);
|
||||
}
|
||||
|
||||
let driver: CMakeDriver|null = null;
|
||||
// tslint:disable:no-unused-expression
|
||||
|
||||
suite('CMake-Server-Driver tests', () => {
|
||||
const cmakePath: string = process.env.CMAKE_EXECUTABLE ? process.env.CMAKE_EXECUTABLE : 'cmake';
|
||||
const workspacePath: string = 'test/unit-tests/cms-driver/workspace';
|
||||
const root = getTestRootFilePath(workspacePath);
|
||||
const defaultWorkspaceFolder = getTestRootFilePath('test/unit-tests/cms-driver/workspace/test_project');
|
||||
const emptyWorkspaceFolder = getTestRootFilePath('test/unit-tests/cms-driver/workspace/empty_project');
|
||||
|
||||
let kitDefault: Kit;
|
||||
if (process.platform === 'win32') {
|
||||
kitDefault = {
|
||||
name: 'Visual Studio Community 2017 - amd64',
|
||||
visualStudio: 'VisualStudio.15.0',
|
||||
visualStudioArchitecture: 'amd64',
|
||||
preferredGenerator: {name: 'Visual Studio 15 2017', platform: 'x64'}
|
||||
} as Kit;
|
||||
} else {
|
||||
kitDefault = {name: 'GCC', compilers: {C: 'gcc', CXX: 'g++'}, preferredGenerator: {name: 'Unix Makefiles'}} as Kit;
|
||||
}
|
||||
|
||||
setup(async function(this: Mocha.IBeforeAndAfterContext, done) {
|
||||
driver = null;
|
||||
|
||||
if (!cleanupBuildDir(path.join(defaultWorkspaceFolder, 'build'))) {
|
||||
done('Default build folder still exists');
|
||||
}
|
||||
|
||||
if (!cleanupBuildDir(path.join(emptyWorkspaceFolder, 'build'))) {
|
||||
done('Empty project build folder still exists');
|
||||
}
|
||||
done();
|
||||
});
|
||||
|
||||
teardown(async function(this: Mocha.IBeforeAndAfterContext) {
|
||||
this.timeout(20000);
|
||||
if (driver) {
|
||||
return driver.asyncDispose();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
async function generateCodeModelForConfiguredDriver(args: string[] =
|
||||
[]): Promise<null|codemodel_api.CodeModelContent> {
|
||||
const config = ConfigurationReader.createForDirectory(root);
|
||||
const executable = await getCMakeExecutableInformation(cmakePath);
|
||||
|
||||
driver = await cms_driver.CMakeServerClientDriver
|
||||
.create(executable, config, kitDefault, defaultWorkspaceFolder, async () => {}, []);
|
||||
let code_model: null|codemodel_api.CodeModelContent = null;
|
||||
if (driver instanceof codemodel_api.CodeModelDriver) {
|
||||
driver.onCodeModelChanged(cm => { code_model = cm; });
|
||||
}
|
||||
await driver.configure(args);
|
||||
return code_model;
|
||||
}
|
||||
|
||||
test('Test generation of code model with multi configuration like VS', async () => {
|
||||
if (process.platform !== 'win32')
|
||||
return;
|
||||
|
||||
const codemodel_data = await generateCodeModelForConfiguredDriver();
|
||||
expect(codemodel_data).to.be.not.null;
|
||||
expect(codemodel_data!.configurations.length).to.be.eql(4);
|
||||
}).timeout(90000);
|
||||
|
||||
test('Test generation of code model with one configuration like make on linux', async () => {
|
||||
if (process.platform === 'win32')
|
||||
return;
|
||||
|
||||
const codemodel_data = await generateCodeModelForConfiguredDriver();
|
||||
expect(codemodel_data).to.be.not.null;
|
||||
expect(codemodel_data!.configurations.length).to.be.eql(1);
|
||||
}).timeout(90000);
|
||||
|
||||
test('Test project information', async () => {
|
||||
const codemodel_data = await generateCodeModelForConfiguredDriver();
|
||||
expect(codemodel_data).to.be.not.null;
|
||||
|
||||
const project = codemodel_data!.configurations[0].projects[0];
|
||||
|
||||
// Test project name
|
||||
expect(project.name).to.be.eq('TestBuildProcess');
|
||||
|
||||
// Test location of project source directory
|
||||
// Used by tree view to make paths relative
|
||||
expect(path.normalize(project.sourceDirectory).toLowerCase())
|
||||
.to.eq(path.normalize(path.join(root, 'test_project')).toLowerCase());
|
||||
}).timeout(90000);
|
||||
|
||||
|
||||
test('Test first executable target directory', async () => {
|
||||
const codemodel_data = await generateCodeModelForConfiguredDriver();
|
||||
expect(codemodel_data).to.be.not.null;
|
||||
|
||||
const target = codemodel_data!.configurations[0].projects[0].targets.find(t => t.type == 'EXECUTABLE');
|
||||
expect(target).to.be.not.undefined;
|
||||
|
||||
// Test target name used for node label
|
||||
expect(target!.name).to.be.eq('TestBuildProcess');
|
||||
const executableName = process.platform === 'win32' ? 'TestBuildProcess.exe' : 'TestBuildProcess';
|
||||
expect(target!.fullName).to.be.eq(executableName);
|
||||
expect(target!.type).to.be.eq('EXECUTABLE');
|
||||
|
||||
// Test location of project source directory
|
||||
// used by tree view to make paths relative
|
||||
expect(path.normalize(target!.sourceDirectory!).toLowerCase())
|
||||
.to.eq(path.normalize(path.join(root, 'test_project')).toLowerCase());
|
||||
|
||||
// Test main source file used in by tree view
|
||||
expect(target!.fileGroups).to.be.not.undefined;
|
||||
const compile_information = target!.fileGroups!.find(t => !!t.language);
|
||||
|
||||
expect(compile_information).to.be.not.undefined;
|
||||
expect(compile_information!.sources).to.include('main.cpp');
|
||||
}).timeout(90000);
|
||||
|
||||
test('Test first static library target directory', async () => {
|
||||
const codemodel_data = await generateCodeModelForConfiguredDriver();
|
||||
expect(codemodel_data).to.be.not.null;
|
||||
|
||||
const target = codemodel_data!.configurations[0].projects[0].targets.find(t => t.type == 'STATIC_LIBRARY');
|
||||
expect(target).to.be.not.undefined;
|
||||
|
||||
// Test target name used for node label
|
||||
expect(target!.name).to.be.eq('StaticLibDummy');
|
||||
const executableName = process.platform === 'win32' ? 'StaticLibDummy.lib' : 'libStaticLibDummy.a';
|
||||
expect(target!.fullName).to.be.eq(executableName);
|
||||
expect(target!.type).to.be.eq('STATIC_LIBRARY');
|
||||
|
||||
// Test location of project source directory
|
||||
// Used by tree view to make paths relative
|
||||
expect(path.normalize(target!.sourceDirectory!).toLowerCase())
|
||||
.to.eq(path.normalize(path.join(root, 'test_project', 'static_lib_dummy')).toLowerCase());
|
||||
|
||||
// Language
|
||||
const compile_information = target!.fileGroups!.find(t => !!t.language);
|
||||
expect(compile_information).to.be.not.undefined;
|
||||
expect(compile_information!.language).to.eq('CXX');
|
||||
|
||||
// Test main source file
|
||||
expect(compile_information!.sources).to.include('info.cpp');
|
||||
expect(compile_information!.sources).to.include('test2.cpp');
|
||||
|
||||
// compile flags for file groups
|
||||
if (process.platform === 'win32') {
|
||||
expect(compile_information!.compileFlags).to.eq('/DWIN32 /D_WINDOWS /W3 /GR /EHsc /MDd /Zi /Ob0 /Od /RTC1 ');
|
||||
}
|
||||
}).timeout(90000);
|
||||
|
||||
test('Test first shared library target directory', async () => {
|
||||
const codemodel_data = await generateCodeModelForConfiguredDriver();
|
||||
expect(codemodel_data).to.be.not.null;
|
||||
|
||||
const target = codemodel_data!.configurations[0].projects[0].targets.find(t => t.type == 'SHARED_LIBRARY');
|
||||
expect(target).to.be.not.undefined;
|
||||
|
||||
// Test target name used for node label
|
||||
expect(target!.name).to.be.eq('SharedLibDummy');
|
||||
const executableNameRegex = process.platform === 'win32' ? /^SharedLibDummy.dll/ : /^libSharedLibDummy.(so|dylib)/;
|
||||
expect(target!.fullName).to.match(executableNameRegex);
|
||||
expect(target!.type).to.be.eq('SHARED_LIBRARY');
|
||||
|
||||
// Test location of project source directory
|
||||
// Used by tree view to make paths relative
|
||||
expect(path.normalize(target!.sourceDirectory!).toLowerCase())
|
||||
.to.eq(path.normalize(path.join(root, 'test_project', 'shared_lib_dummy')).toLowerCase());
|
||||
|
||||
// Test main source file
|
||||
expect(target!.fileGroups).to.be.not.undefined;
|
||||
expect(target!.fileGroups![0].sources[0]).to.eq('src/info.c');
|
||||
expect(target!.fileGroups![0].defines).contains('TEST_CMAKE_DEFINE');
|
||||
expect(target!.fileGroups![0].isGenerated).to.be.false;
|
||||
expect(path.normalize(target!.fileGroups![0].includePath![0].path).toLowerCase())
|
||||
.to.eq(path.normalize(path.join(root, 'test_project', 'shared_lib_dummy', 'inc')).toLowerCase());
|
||||
|
||||
// Language
|
||||
expect(target!.fileGroups![0].language).to.eq('C');
|
||||
|
||||
// compile flags for file groups
|
||||
if (process.platform === 'win32') {
|
||||
expect(target!.fileGroups![0].compileFlags).to.eq('/DWIN32 /D_WINDOWS /W3 /MDd /Zi /Ob0 /Od /RTC1 ');
|
||||
}
|
||||
}).timeout(90000);
|
||||
|
||||
test('Test cache access', async () => {
|
||||
const codemodel_data = await generateCodeModelForConfiguredDriver();
|
||||
expect(codemodel_data).to.be.not.null;
|
||||
|
||||
const target = codemodel_data!.configurations[0].projects[0].targets.find(t => t.type == 'UTILITY'
|
||||
&& t.name == 'runTestTarget');
|
||||
expect(target).to.be.not.undefined;
|
||||
|
||||
// maybe could be used to exclude file list from utility targets
|
||||
expect(target!.fileGroups![0].isGenerated).to.be.true;
|
||||
}).timeout(90000);
|
||||
|
||||
test('Test sysroot access', async () => {
|
||||
// This test does not work with VisualStudio.
|
||||
// VisualStudio generator does not provide the sysroot in the code model.
|
||||
// macOS has separate sysroot variable (see CMAKE_OSX_SYSROOT); this build fails.
|
||||
if (process.platform === 'win32' || process.platform === 'darwin')
|
||||
return;
|
||||
|
||||
const codemodel_data = await generateCodeModelForConfiguredDriver(['-DCMAKE_SYSROOT=/tmp']);
|
||||
expect(codemodel_data).to.be.not.null;
|
||||
|
||||
const target = codemodel_data!.configurations[0].projects[0].targets.find(t => t.type == 'EXECUTABLE');
|
||||
expect(target).to.be.not.undefined;
|
||||
expect(target!.sysroot).to.be.eq('/tmp');
|
||||
}).timeout(90000);
|
||||
});
|
|
@ -3,6 +3,9 @@ project(TestBuildProcess VERSION 0.1.0)
|
|||
|
||||
set(CMT_COOKIE passed-cookie CACHE STRING "Cookie to be written by the main executable")
|
||||
|
||||
add_subdirectory(static_lib_dummy)
|
||||
add_subdirectory(shared_lib_dummy)
|
||||
|
||||
add_executable(TestBuildProcess main.cpp)
|
||||
set_property(TARGET TestBuildProcess PROPERTY CXX_STANDARD 98)
|
||||
|
||||
|
@ -31,6 +34,7 @@ target_compile_definitions(TestBuildProcess PRIVATE
|
|||
"CMT_COOKIE=\"${CMT_COOKIE}\""
|
||||
"C_COMPILER_ID=\"${CMAKE_C_COMPILER_ID}\""
|
||||
)
|
||||
target_link_libraries(TestBuildProcess StaticLibDummy)
|
||||
|
||||
add_custom_target(runTestTarget DEPENDS TestBuildProcess
|
||||
COMMAND $<TARGET_FILE:TestBuildProcess> > output_target.txt
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
add_library (SharedLibDummy SHARED "src/info.c")
|
||||
|
||||
target_include_directories (SharedLibDummy PUBLIC "inc")
|
||||
target_compile_definitions (SharedLibDummy PRIVATE TEST_CMAKE_DEFINE)
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef DIR2_LIB_INFO_H_
|
||||
#define DIR2_LIB_INFO_H_
|
||||
|
||||
void dummy_info_print();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,5 @@
|
|||
#include "info.h"
|
||||
|
||||
void dummy_info_print() {
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
add_library(StaticLibDummy "info.cpp" "test2.cpp")
|
|
@ -99,7 +99,8 @@ suite('Kits scan test', async () => {
|
|||
expect(compkit!.environmentVariables).to.be.undefined;
|
||||
});
|
||||
|
||||
test('Detect an MinGW compiler file on windows', async () => {
|
||||
// Test is broken, the use of env path has changed
|
||||
test.skip('Detect an MinGW compiler file on windows', async () => {
|
||||
if (process.platform !== 'win32')
|
||||
return;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче