Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Visual Studio IDE support #9

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ trim_trailing_whitespace = true
# Set file behavior to:
# 2 space indentation
###############################################################################
[*.{cmd,config,csproj,cproj,cxxproj,json,nuspec,pkgproj,props,ps1,resx,sh,tasks,targets,yml}]
[*.{cmd,config,csproj,cproj,cxxproj,xml,xaml,json,nuspec,pkgproj,props,ps1,resx,sh,tasks,targets,yml}]
indent_size = 2

###############################################################################
Expand Down
3 changes: 3 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
<PackageReference Update="Microsoft.Net.Compilers.Toolset" Version="3.9.0-4.final" />
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="16.9.0-preview-20210127-04" />
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.1.0-beta-20204-02" />
<PackageReference Update="Microsoft.VisualStudio.Sdk" Version="16.0.206" />
<PackageReference Update="Microsoft.VisualStudio.ProjectSystem" Version="15.8.243" />
<PackageReference Update="Microsoft.VSSDK.BuildTools" Version="16.11.16" />
</ItemGroup>

</Project>
33 changes: 27 additions & 6 deletions Finite.Cpp.Sdk.sln
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
# Visual Studio Version 16
VisualStudioVersion = 16.0.31624.102
MinimumVisualStudioVersion = 15.0.26124.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D63BE145-0B9A-4A0C-834D-EF9E8F007B2D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Finite.Cpp.Sdk", "src\Core\Finite.Cpp.Sdk.csproj", "{012461A5-B00E-41AD-8EA1-7866A8B1F8A5}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Finite.Cpp.Sdk", "src\Core\Finite.Cpp.Sdk.csproj", "{012461A5-B00E-41AD-8EA1-7866A8B1F8A5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Finite.Cpp.Sdk.VisualStudio", "src\VisualStudio\Finite.Cpp.Sdk.VisualStudio.csproj", "{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}"
ProjectSection(ProjectDependencies) = postProject
{012461A5-B00E-41AD-8EA1-7866A8B1F8A5} = {012461A5-B00E-41AD-8EA1-7866A8B1F8A5}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -16,9 +21,6 @@ Global
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{012461A5-B00E-41AD-8EA1-7866A8B1F8A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{012461A5-B00E-41AD-8EA1-7866A8B1F8A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
Expand All @@ -32,8 +34,27 @@ Global
{012461A5-B00E-41AD-8EA1-7866A8B1F8A5}.Release|x64.Build.0 = Release|Any CPU
{012461A5-B00E-41AD-8EA1-7866A8B1F8A5}.Release|x86.ActiveCfg = Release|Any CPU
{012461A5-B00E-41AD-8EA1-7866A8B1F8A5}.Release|x86.Build.0 = Release|Any CPU
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}.Debug|x64.ActiveCfg = Debug|Any CPU
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}.Debug|x64.Build.0 = Debug|Any CPU
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}.Debug|x86.ActiveCfg = Debug|Any CPU
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}.Debug|x86.Build.0 = Debug|Any CPU
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}.Release|Any CPU.Build.0 = Release|Any CPU
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}.Release|x64.ActiveCfg = Release|Any CPU
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}.Release|x64.Build.0 = Release|Any CPU
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}.Release|x86.ActiveCfg = Release|Any CPU
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{012461A5-B00E-41AD-8EA1-7866A8B1F8A5} = {D63BE145-0B9A-4A0C-834D-EF9E8F007B2D}
{DF68DB18-A68D-4641-8B58-9961D0FE4DF9} = {D63BE145-0B9A-4A0C-834D-EF9E8F007B2D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {089CD4E0-CE16-4B84-A2CD-65A12FC98CB2}
EndGlobalSection
EndGlobal
6 changes: 6 additions & 0 deletions samples/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,10 @@

<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.props" />

<!-- Default settings that are used for Visual Studio design-time builds -->
<PropertyGroup>
<VisualStudioDesignTimeFiles>$(BaseArtifactsPath)bin\src\Finite.Cpp.Sdk.VisualStudio\Debug\net472\DesignTime\</VisualStudioDesignTimeFiles>
<CPlusPlusDesignTimeTargetsPath>$(VisualStudioDesignTimeFiles)Finite.Cpp.Sdk.CPlusPlus.DesignTime.targets</CPlusPlusDesignTimeTargetsPath>
</PropertyGroup>

</Project>
3 changes: 3 additions & 0 deletions src/Core/ClangCompile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ protected override string GenerateFullPathToTool()
if (File.Exists(fullPath))
return fullPath;
}

Log.LogError($"Could not find {ToolName} executable");
return null!;
}


Expand Down
10 changes: 8 additions & 2 deletions src/Core/ClangLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,11 @@ to the system linker which has different behaviour on

if (Language == "C++")
{
builder.AppendSwitch("-lstdc++");
builder.AppendSwitch("-lm");
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
builder.AppendSwitch("-lstdc++");
builder.AppendSwitch("-lm");
}
}

if (EnableDebugSymbols)
Expand Down Expand Up @@ -245,6 +248,9 @@ protected override string GenerateFullPathToTool()
if (File.Exists(fullPath))
return fullPath;
}

Log.LogError($"Could not find {ToolName} executable");
return null!;
}


Expand Down
6 changes: 6 additions & 0 deletions src/Core/targets/Finite.Cpp.Sdk.CXX.targets
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,10 @@
<TargetRuntime>Unmanaged</TargetRuntime>
</PropertyGroup>

<PropertyGroup>
<CPlusPlusDesignTimeTargetsPath Condition="'$(CPlusPlusDesignTimeTargetsPath)' == ''">$(MSBuildExtensionsPath)\FiniteCppSdk\Finite.Cpp.Sdk.CPlusPlus.DesignTime.targets</CPlusPlusDesignTimeTargetsPath>
</PropertyGroup>

<Import Project="$(CPlusPlusDesignTimeTargetsPath)" Condition="'$(CPlusPlusDesignTimeTargetsPath)' != '' and Exists('$(CPlusPlusDesignTimeTargetsPath)')" />

</Project>
8 changes: 0 additions & 8 deletions src/Core/targets/Finite.Cpp.Sdk.targets
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,4 @@
</ItemGroup>
</Target>

<ItemGroup>
<ProjectCapability Remove="AssemblyReferences" />
<ProjectCapability Remove="ReferenceManagerAssemblies" />
<ProjectCapability Include="VisualC" Condition="'$(OS)' == 'Windows_NT'" />
<ProjectCapability Include="CrossPlatformExecutable" />
<ProjectCapability Include="ReferencesFolder" />
</ItemGroup>

</Project>
32 changes: 32 additions & 0 deletions src/VisualStudio/Capabilities/ProjectTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.ProjectSystem;

namespace Finite.Cpp.Sdk.VisualStudio
{
internal static class Capabilities
{
internal static class ProjectType
{
public const string FiniteCppSdk = nameof(FiniteCppSdk);
public const string CPlusPlus = nameof(CPlusPlus);
}

internal static class ProjectTypes
{
public const string FiniteCppSdk =
$"{ProjectCapabilities.HandlesOwnReload}; " +
$"{ProjectCapabilities.OpenProjectFile}; " +
$"{ProjectCapabilities.PreserveFormatting}; " +
$"{ProjectCapabilities.ProjectConfigurationsDeclaredDimensions}; " +
$"{ProjectType.FiniteCppSdk}";

public const string CPlusPlus =
$"{FiniteCppSdk}; " +
$"{ProjectType.CPlusPlus}";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Finite.Cpp.Sdk.VisualStudio.Configuration
{
internal sealed partial class ProjectConfigurationDimensionProvider
{
private record Dimension(string Name, string MSBuildProperty, string[] Value);

private static readonly Dimension ConfigurationDimension
= new("Configuration", "Configurations", new[] { "Debug" });
private static readonly Dimension PlatformDimension
= new("Platform", "Platforms", new[] { "Native" });
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Build.Evaluation;
using Microsoft.VisualStudio.ProjectSystem;

namespace Finite.Cpp.Sdk.VisualStudio.Configuration
{
//[Export(typeof(IProjectConfigurationDimensionsProvider))]
//[AppliesTo(ProjectCapabilities.ProjectConfigurationsDeclaredDimensions)]
internal sealed partial class ProjectConfigurationDimensionProvider
: IProjectConfigurationDimensionsProvider3
{
private readonly IProjectLockService _lockService;

public ProjectConfigurationDimensionProvider(IProjectLockService lockService)
{
_lockService = lockService;
}

private async Task<Dimension> FindDimensionFromProjectOrDefaultAsync(UnconfiguredProject project, Dimension defaultValue)
{
using var lck = await _lockService.ReadLockAsync();
var xml = await lck.GetProjectXmlAsync(project.FullPath);

var property = xml.PropertyGroups
.SelectMany(x => x.Properties)
.FirstOrDefault(x => x.Name.Equals(defaultValue.MSBuildProperty, StringComparison.OrdinalIgnoreCase));

return property switch
{
{ } => new(property.Name, defaultValue.MSBuildProperty, ProjectCollection.Unescape(property.Value).Split(';')),
_ => defaultValue
};
}

public async Task<IEnumerable<KeyValuePair<string, string>>> GetBestGuessDefaultValuesForDimensionsAsync(UnconfiguredProject project)
{
return AsEnumerable(
await FindDimensionFromProjectOrDefaultAsync(project, ConfigurationDimension),
await FindDimensionFromProjectOrDefaultAsync(project, PlatformDimension)
);

static IEnumerable<KeyValuePair<string, string>> AsEnumerable(params Dimension[] values)
=> values.Select(x => new KeyValuePair<string, string>(x.Name, string.Join(";", x.Value)));
}

public async Task<IEnumerable<KeyValuePair<string, string>>> GetDefaultValuesForDimensionsAsync(UnconfiguredProject project)
{
return AsEnumerable(
await FindDimensionFromProjectOrDefaultAsync(project, ConfigurationDimension),
await FindDimensionFromProjectOrDefaultAsync(project, PlatformDimension)
);

static IEnumerable<KeyValuePair<string, string>> AsEnumerable(params Dimension[] values)
=> values.Select(x => new KeyValuePair<string, string>(x.Name, x.Value[0]));
}

public async Task<IEnumerable<KeyValuePair<string, IEnumerable<string>>>> GetProjectConfigurationDimensionsAsync(UnconfiguredProject project)
{
return AsEnumerable(
await FindDimensionFromProjectOrDefaultAsync(project, ConfigurationDimension),
await FindDimensionFromProjectOrDefaultAsync(project, PlatformDimension)
);

static IEnumerable<KeyValuePair<string, IEnumerable<string>>> AsEnumerable(params Dimension[] values)
=> values.Select(x => new KeyValuePair<string, IEnumerable<string>>(x.Name, x.Value));
}

public Task OnDimensionValueChangedAsync(ProjectConfigurationDimensionValueChangedEventArgs args)
{
return Task.CompletedTask;
}
}
}
20 changes: 20 additions & 0 deletions src/VisualStudio/CppSdkPackage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.VisualStudio.Shell;

namespace Finite.Cpp.Sdk.VisualStudio
{
[PackageRegistration(AllowsBackgroundLoading = true, UseManagedResourcesOnly = true)]
[InstalledProductRegistration("Finite.Cpp.Sdk", "Cross-platform C/C++ SDK", productId: "memes")]
[Guid(PackageGuid)]
public sealed class CppSdkPackage : AsyncPackage
{
public const string PackageGuid = "780D1924-1B9B-4C3C-82AF-704A61F855D4";

protected override async System.Threading.Tasks.Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<Import Project="Finite.Cpp.Sdk.DesignTime.targets" />

<ItemGroup>
<PropertyPageSchema Include="$(FiniteCppSdkXamlResourcesDirectory)ProjectItemsSchema.CPlusPlus.xaml" Context="Project" />

<ProjectCapability Include="CPlusPlus" />
</ItemGroup>

</Project>
50 changes: 50 additions & 0 deletions src/VisualStudio/DesignTime/Finite.Cpp.Sdk.DesignTime.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>
<DefineCommonItemSchemas>false</DefineCommonItemSchemas>
<DefineCommonCapabilities>false</DefineCommonCapabilities>
<DefineCommonReferenceSchemas>false</DefineCommonReferenceSchemas>

<SupportedOutputTypes Condition="'$(SupportedOutputTypes)' == ''">exe;library</SupportedOutputTypes>
<SuppressOutOfDateMessageOnBuild Condition="'$(SuppressOutOfDateMessageOnBuild)' == ''">true</SuppressOutOfDateMessageOnBuild>

<PackageAction Condition="'$(PackageAction)' == ''">Pack</PackageAction>
</PropertyGroup>

<PropertyGroup Condition="'$(FiniteCppSdkXamlResourcesDirectory)' == ''">
<FiniteCppSdkXamlResourcesDirectory>$(MSBuildThisFileDirectory)</FiniteCppSdkXamlResourcesDirectory>
</PropertyGroup>

<PropertyGroup>
<FiniteCppSdkXamlResourcesDirectory Condition="!HasTrailingSlash('$(FiniteCppSdkXamlResourcesDirectory)')">$(FiniteCppSdkXamlResourcesDirectory)\</FiniteCppSdkXamlResourcesDirectory>
</PropertyGroup>

<ItemGroup>
<ProjectCapability Include="FiniteCppSdk" />

<ProjectCapability Include="UseFileGlobs" />
<ProjectCapability Include="DynamicDependentFile" />
<ProjectCapability Include="ConfigurableFileNesting" />

<ProjectCapability Include="
ProjectReferences;
OutputGroups;
AllTargetOutputGroups;
VisualStudioWellKnownOutputGroups;
SingleFileGenerators;
DeclaredSourceItems;
UserSourceItems;
SupportAvailableItemName;
IntegratedConsoleDebugging;
DisableBuiltInDebuggerServices;
PersistDesignTimeDataOutOfProject;" />
</ItemGroup>


<ItemGroup>
<PropertyPageSchema Include="$(FiniteCppSdkXamlResourcesDirectory)Compile.xaml" Context="Project" />
<PropertyPageSchema Include="$(FiniteCppSdkXamlResourcesDirectory)Compile.BrowseObject.xaml" Context="BrowseObject" />
</ItemGroup>

</Project>
Loading