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

sln-add: Support for slnx #44570

Merged
merged 64 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
1d1c4b0
[IMP] sln-list: Support for slnx
edvilme Oct 30, 2024
bdff950
sln-add: Support for slnx
edvilme Oct 31, 2024
01b3031
Handle solution folders
edvilme Nov 1, 2024
277a1d7
Fix tests
edvilme Nov 1, 2024
5e6e3ff
Fix UTF8 BOM tests
edvilme Nov 1, 2024
b4ac6a4
Catch errors
edvilme Nov 1, 2024
3f967f7
Fix additional tests
edvilme Nov 4, 2024
3d52972
Fix additional tests
edvilme Nov 4, 2024
de95e6d
Fix additional issues
edvilme Nov 5, 2024
a090ad4
Remove sdk.slnx file
edvilme Nov 5, 2024
c03cad7
Fix additional tests
edvilme Nov 6, 2024
90f4248
Fix additional tests
edvilme Nov 6, 2024
4929979
Fix additional tests
edvilme Nov 6, 2024
f88c3eb
Fix duplicate project tests
edvilme Nov 6, 2024
a900dc3
Fix tests
edvilme Nov 7, 2024
c394d75
108/133 tests passing
edvilme Nov 7, 2024
c8e5996
Work on tests
edvilme Nov 8, 2024
039e694
Nit
edvilme Nov 8, 2024
cef4d22
Refactored code to fix guid tests
edvilme Nov 8, 2024
51294e9
Fix tests
edvilme Nov 8, 2024
6aee575
Fix some config tests
edvilme Nov 8, 2024
e168158
Revert guid detection
edvilme Nov 8, 2024
07343f9
Update tests guids and translations
edvilme Nov 11, 2024
af2917a
Update translations (build)
edvilme Nov 11, 2024
6d8c3fe
Fix additional tests
edvilme Nov 11, 2024
b195880
Fix issues from pr
edvilme Nov 12, 2024
93775e8
Solve solution folder tests
edvilme Nov 12, 2024
3195e02
Fix additional tests
edvilme Nov 12, 2024
8975dbc
Refactor code
edvilme Nov 13, 2024
2e9b5ea
Update tests
edvilme Nov 13, 2024
76a2f1d
Fix tests
edvilme Nov 13, 2024
60d434c
Fix WhenProjectWithAdditionalConfigurationsIsAddedSolutionDoesNotMapThem
edvilme Nov 19, 2024
f79ddf3
Revert changed project guids
edvilme Nov 19, 2024
d90d9df
Revert changed project guids
edvilme Nov 20, 2024
63c1fda
Fix project config tests
edvilme Nov 21, 2024
6f0cc41
Fix tests
edvilme Nov 21, 2024
7cf1a37
Fix all tests + Update vs-solutionpersistence
edvilme Nov 21, 2024
0c83e51
Nit
edvilme Nov 21, 2024
32cae25
Nit
edvilme Nov 21, 2024
0b3b696
Nit
edvilme Nov 21, 2024
a4a9f74
Fix whitespaces
edvilme Nov 21, 2024
14bac00
[TEST] sln-add: Add example slnx files, and parameters
edvilme Nov 22, 2024
96274cf
[TEST] sln-add: Use vs-solutionpersistence on templates
edvilme Nov 22, 2024
68f8de2
[TEST] sln-add: Add SolutionFilesTemplates
edvilme Nov 22, 2024
f1a735f
[TEST] sln-add: Compare slnx templates
edvilme Nov 23, 2024
9492a03
[TEST] sln-add: Fix sln-templates tests
edvilme Nov 25, 2024
6f8c166
[TEST] sln-add: Migrate all tests
edvilme Nov 26, 2024
13c8cd1
Fix typo
edvilme Nov 26, 2024
2dd69b0
[TEST] sln-list: Update testAsset identifiers
edvilme Nov 26, 2024
6e62402
[TEST] restore: Add App.sln to argument list
edvilme Nov 26, 2024
8992fce
Merge branch 'main' into edvilme-slnx-add
edvilme Nov 26, 2024
12533a5
Merge branch 'main' into edvilme-slnx-add
edvilme Nov 27, 2024
d8fbc8e
sln-add: When working and solution directories are different, resolve…
edvilme Nov 27, 2024
c3bac1d
Merge branch 'edvilme-slnx-add' of https://github.com/edvilme/sdk int…
edvilme Nov 27, 2024
f7a4fb7
Nit
edvilme Nov 27, 2024
5b5190e
Nit
edvilme Dec 2, 2024
931d2df
Nit
edvilme Dec 2, 2024
41c7c38
Nit
edvilme Dec 2, 2024
b0bff17
Nit: Update comments for readability
edvilme Dec 3, 2024
96cb8a0
Remove unused code
edvilme Dec 3, 2024
0f118ef
NIT: Make default solution configuration constant
edvilme Dec 4, 2024
bf80cbd
Merge branch 'main' into edvilme-slnx-add
edvilme Dec 4, 2024
74193d2
[FIX] sln-add: Default solution folders for nested projects
edvilme Dec 5, 2024
5205f1b
Nit: Remove comment
edvilme Dec 5, 2024
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
222 changes: 129 additions & 93 deletions src/Cli/dotnet/commands/dotnet-sln/add/Program.cs
Original file line number Diff line number Diff line change
@@ -1,144 +1,180 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.CommandLine;
using Microsoft.Build.Construction;
using Microsoft.Build.Exceptions;
using Microsoft.Build.Execution;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.Sln.Internal;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Common;
using Microsoft.VisualStudio.SolutionPersistence;
using Microsoft.VisualStudio.SolutionPersistence.Model;
using Microsoft.VisualStudio.SolutionPersistence.Serializer.SlnV12;

namespace Microsoft.DotNet.Tools.Sln.Add
{
internal class AddProjectToSolutionCommand : CommandBase
{
private static string[] _defaultPlatforms = new[] { "Any CPU", "x64", "x86" };
private static string[] _defaultBuildTypes = new[] { "Debug", "Release" };
private readonly string _fileOrDirectory;
private readonly bool _inRoot;
private readonly IList<string> _relativeRootSolutionFolders;
private readonly IReadOnlyCollection<string> _arguments;
private readonly IReadOnlyCollection<string> _projects;
private readonly string? _solutionFolderPath;

private static string GetSolutionFolderPathWithForwardSlashes(string path)
{
// SolutionModel::AddFolder expects paths to have leading, trailing and inner forward slashes
nagilson marked this conversation as resolved.
Show resolved Hide resolved
// https://github.com/microsoft/vs-solutionpersistence/blob/87ee8ea069662d55c336a9bd68fe4851d0384fa5/src/Microsoft.VisualStudio.SolutionPersistence/Model/SolutionModel.cs#L171C1-L172C1
return "/" + string.Join("/", PathUtility.GetPathWithDirectorySeparator(path).Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries)) + "/";
edvilme marked this conversation as resolved.
Show resolved Hide resolved
}

public AddProjectToSolutionCommand(ParseResult parseResult) : base(parseResult)
{
_fileOrDirectory = parseResult.GetValue(SlnCommandParser.SlnArgument);

_arguments = parseResult.GetValue(SlnAddParser.ProjectPathArgument)?.ToArray() ?? (IReadOnlyCollection<string>)Array.Empty<string>();

_projects = (IReadOnlyCollection<string>)(parseResult.GetValue(SlnAddParser.ProjectPathArgument) ?? []);
_inRoot = parseResult.GetValue(SlnAddParser.InRootOption);
string relativeRoot = parseResult.GetValue(SlnAddParser.SolutionFolderOption);

SlnArgumentValidator.ParseAndValidateArguments(_fileOrDirectory, _arguments, SlnArgumentValidator.CommandType.Add, _inRoot, relativeRoot);

bool hasRelativeRoot = !string.IsNullOrEmpty(relativeRoot);

if (hasRelativeRoot)
{
relativeRoot = PathUtility.GetPathWithDirectorySeparator(relativeRoot);
_relativeRootSolutionFolders = relativeRoot.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries);
}
else
{
_relativeRootSolutionFolders = null;
}
_solutionFolderPath = parseResult.GetValue(SlnAddParser.SolutionFolderOption);
SlnArgumentValidator.ParseAndValidateArguments(_fileOrDirectory, _projects, SlnArgumentValidator.CommandType.Add, _inRoot, _solutionFolderPath);
edvilme marked this conversation as resolved.
Show resolved Hide resolved
}

public override int Execute()
{
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(_fileOrDirectory);

var arguments = (_parseResult.GetValue<IEnumerable<string>>(SlnAddParser.ProjectPathArgument) ?? Array.Empty<string>()).ToList().AsReadOnly();
if (arguments.Count == 0)
if (_projects.Count == 0)
edvilme marked this conversation as resolved.
Show resolved Hide resolved
{
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd);
}
string solutionFileFullPath = SlnCommandParser.GetSlnFileFullPath(_fileOrDirectory);

PathUtility.EnsureAllPathsExist(arguments, CommonLocalizableStrings.CouldNotFindProjectOrDirectory, true);

var fullProjectPaths = _arguments.Select(p =>
{
var fullPath = Path.GetFullPath(p);
return Directory.Exists(fullPath) ?
MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName :
fullPath;
}).ToList();

var preAddProjectCount = slnFile.Projects.Count;

foreach (var fullProjectPath in fullProjectPaths)
try
edvilme marked this conversation as resolved.
Show resolved Hide resolved
{
// Identify the intended solution folders
var solutionFolders = DetermineSolutionFolder(slnFile, fullProjectPath);

slnFile.AddProject(fullProjectPath, solutionFolders);
PathUtility.EnsureAllPathsExist(_projects, CommonLocalizableStrings.CouldNotFindProjectOrDirectory, true);
IEnumerable<string> fullProjectPaths = _projects.Select(project =>
{
var fullPath = Path.GetFullPath(project);
return Directory.Exists(fullPath) ? MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName : fullPath;
});
AddProjectsToSolutionAsync(solutionFileFullPath, fullProjectPaths, CancellationToken.None).GetAwaiter().GetResult();
return 0;
}

if (slnFile.Projects.Count > preAddProjectCount)
catch (Exception ex) when (ex is not GracefulException)
{
slnFile.Write();
{
if (ex is SolutionException || ex.InnerException is SolutionException)
{
throw new GracefulException(CommonLocalizableStrings.InvalidSolutionFormatString, solutionFileFullPath, ex.Message);
}
throw new GracefulException(ex.Message, ex);
}
}

return 0;
}

private static IList<string> GetSolutionFoldersFromProjectPath(string projectFilePath)
private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnumerable<string> projectPaths, CancellationToken cancellationToken)
{
var solutionFolders = new List<string>();

if (!IsPathInTreeRootedAtSolutionDirectory(projectFilePath))
return solutionFolders;

var currentDirString = $".{Path.DirectorySeparatorChar}";
if (projectFilePath.StartsWith(currentDirString))
ISolutionSerializer serializer = SlnCommandParser.GetSolutionSerializer(solutionFileFullPath);
nagilson marked this conversation as resolved.
Show resolved Hide resolved
SolutionModel solution = await serializer.OpenAsync(solutionFileFullPath, cancellationToken);
// set UTF8 BOM encoding for .sln
if (serializer is ISolutionSerializer<SlnV12SerializerSettings> v12Serializer)
nagilson marked this conversation as resolved.
Show resolved Hide resolved
{
projectFilePath = projectFilePath.Substring(currentDirString.Length);
solution.SerializerExtension = v12Serializer.CreateModelExtension(new()
{
Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true)
});
}
edvilme marked this conversation as resolved.
Show resolved Hide resolved
// Set default configurations and platforms for sln file
foreach (var platform in _defaultPlatforms)
{
solution.AddPlatform(platform);
}
foreach (var buildType in _defaultBuildTypes)
{
solution.AddBuildType(buildType);
edvilme marked this conversation as resolved.
Show resolved Hide resolved
}

var projectDirectoryPath = TrimProject(projectFilePath);
if (string.IsNullOrEmpty(projectDirectoryPath))
return solutionFolders;

var solutionFoldersPath = TrimProjectDirectory(projectDirectoryPath);
if (string.IsNullOrEmpty(solutionFoldersPath))
return solutionFolders;

solutionFolders.AddRange(solutionFoldersPath.Split(Path.DirectorySeparatorChar));
SolutionFolderModel? solutionFolder = (!_inRoot && !string.IsNullOrEmpty(_solutionFolderPath))
? solution.AddFolder(GetSolutionFolderPathWithForwardSlashes(_solutionFolderPath))
edvilme marked this conversation as resolved.
Show resolved Hide resolved
: null;

return solutionFolders;
foreach (var projectPath in projectPaths)
{
string relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath);
// Add fallback solution folder
string relativeSolutionFolder = Path.GetDirectoryName(relativePath);
if (!_inRoot && solutionFolder is null && !string.IsNullOrEmpty(relativeSolutionFolder))
{
if (relativeSolutionFolder.Split(Path.DirectorySeparatorChar).LastOrDefault() == Path.GetFileNameWithoutExtension(relativePath))
{
relativeSolutionFolder = Path.Combine(relativeSolutionFolder.Split(Path.DirectorySeparatorChar).SkipLast(1).ToArray());
}
if (!string.IsNullOrEmpty(relativeSolutionFolder))
edvilme marked this conversation as resolved.
Show resolved Hide resolved
{
solutionFolder = solution.AddFolder(GetSolutionFolderPathWithForwardSlashes(relativeSolutionFolder));
}
}

try
edvilme marked this conversation as resolved.
Show resolved Hide resolved
{
AddProject(solution, relativePath, projectPath, solutionFolder);
}
catch (InvalidProjectFileException ex)
{
Reporter.Error.WriteLine(string.Format(CommonLocalizableStrings.InvalidProjectWithExceptionMessage, projectPath, ex.Message));
Forgind marked this conversation as resolved.
Show resolved Hide resolved
}
catch (SolutionArgumentException ex) when (solution.FindProject(relativePath) != null || ex.Type == SolutionErrorType.DuplicateProjectName)
{
Reporter.Output.WriteLine(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath);
}
}
await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken);
}

private IList<string> DetermineSolutionFolder(SlnFile slnFile, string fullProjectPath)
private void AddProject(SolutionModel solution, string solutionRelativeProjectPath, string fullPath, SolutionFolderModel? solutionFolder)
{
if (_inRoot)
// Open project instance to see if it is a valid project
ProjectRootElement projectRootElement = ProjectRootElement.Open(fullPath);
SolutionProjectModel project;
try
{
// The user requested all projects go to the root folder
return null;
project = solution.AddProject(solutionRelativeProjectPath, null, solutionFolder);
}

if (_relativeRootSolutionFolders != null)
catch (SolutionArgumentException ex) when (ex.ParamName == "projectTypeName")
{
// The user has specified an explicit root
return _relativeRootSolutionFolders;
// If guid is not identified by vs-solutionpersistence, check in project element itself
var guid = projectRootElement.GetProjectTypeGuid();
if (string.IsNullOrEmpty(guid))
{
Reporter.Error.WriteLine(CommonLocalizableStrings.UnsupportedProjectType, fullPath);
return;
}
project = solution.AddProject(solutionRelativeProjectPath, guid, solutionFolder);
}
// Add settings based on existing project instance
nagilson marked this conversation as resolved.
Show resolved Hide resolved
ProjectInstance projectInstance = new ProjectInstance(projectRootElement);
string projectInstanceId = projectInstance.GetProjectId();
if (!string.IsNullOrEmpty(projectInstanceId))
{
project.Id = new Guid(projectInstanceId);
}

// We determine the root for each individual project
var relativeProjectPath = Path.GetRelativePath(
PathUtility.EnsureTrailingSlash(slnFile.BaseDirectory),
fullProjectPath);

return GetSolutionFoldersFromProjectPath(relativeProjectPath);
}

private static bool IsPathInTreeRootedAtSolutionDirectory(string path)
{
return !path.StartsWith("..");
}
var projectInstanceBuildTypes = projectInstance.GetConfigurations();
var projectInstancePlatforms = projectInstance.GetPlatforms();

private static string TrimProject(string path)
{
return Path.GetDirectoryName(path);
}
foreach (var solutionPlatform in solution.Platforms)
{
var projectPlatform = projectInstancePlatforms.FirstOrDefault(
edvilme marked this conversation as resolved.
Show resolved Hide resolved
platform => platform.Replace(" ", string.Empty) == solutionPlatform.Replace(" ", string.Empty), projectInstancePlatforms.FirstOrDefault());
project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.Platform, "*", solutionPlatform, projectPlatform));
}

private static string TrimProjectDirectory(string path)
{
return Path.GetDirectoryName(path);
foreach (var solutionBuildType in solution.BuildTypes)
{
var projectBuildType = projectInstanceBuildTypes.FirstOrDefault(
edvilme marked this conversation as resolved.
Show resolved Hide resolved
buildType => buildType.Replace(" ", string.Empty) == solutionBuildType.Replace(" ", string.Empty), projectInstanceBuildTypes.FirstOrDefault());
project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.BuildType, solutionBuildType, "*", projectBuildType));
}
Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, solutionRelativeProjectPath);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<invalid>
</invalid>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a test of an invalid solution.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<invalid>
</invalid>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Solution>
<Configurations>
<Platform Name="Any CPU" />
<Platform Name="x64" />
<Platform Name="x86" />
</Configurations>
</Solution>
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26006.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "App\App.csproj", "{7072A694-548F-4CAE-A58F-12D257D5F486}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lib", "Lib\Lib.csproj", "__LIB_PROJECT_GUID__"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x64.ActiveCfg = Debug|x64
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x64.Build.0 = Debug|x64
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x86.ActiveCfg = Debug|x86
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x86.Build.0 = Debug|x86
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|Any CPU.Build.0 = Release|Any CPU
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x64.ActiveCfg = Release|x64
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x64.Build.0 = Release|x64
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x86.ActiveCfg = Release|x86
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x86.Build.0 = Release|x86
__LIB_PROJECT_GUID__.Debug|Any CPU.ActiveCfg = Debug|Any CPU
__LIB_PROJECT_GUID__.Debug|Any CPU.Build.0 = Debug|Any CPU
__LIB_PROJECT_GUID__.Debug|x64.ActiveCfg = Debug|Any CPU
__LIB_PROJECT_GUID__.Debug|x64.Build.0 = Debug|Any CPU
__LIB_PROJECT_GUID__.Debug|x86.ActiveCfg = Debug|Any CPU
__LIB_PROJECT_GUID__.Debug|x86.Build.0 = Debug|Any CPU
__LIB_PROJECT_GUID__.Release|Any CPU.ActiveCfg = Release|Any CPU
__LIB_PROJECT_GUID__.Release|Any CPU.Build.0 = Release|Any CPU
__LIB_PROJECT_GUID__.Release|x64.ActiveCfg = Release|Any CPU
__LIB_PROJECT_GUID__.Release|x64.Build.0 = Release|Any CPU
__LIB_PROJECT_GUID__.Release|x86.ActiveCfg = Release|Any CPU
__LIB_PROJECT_GUID__.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Solution>
<Configurations>
<Platform Name="Any CPU" />
<Platform Name="x64" />
<Platform Name="x86" />
</Configurations>
<Project Path="App/App.csproj">
<Platform Solution="*|x64" Project="x64" />
<Platform Solution="*|x86" Project="x86" />
</Project>
<Project Path="Lib/Lib.csproj" Id="__LIB_PROJECT_GUID__"/>
</Solution>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26006.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lib", "Lib\Lib.csproj", "__LIB_PROJECT_GUID__"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
__LIB_PROJECT_GUID__.Debug|Any CPU.ActiveCfg = Debug|Any CPU
__LIB_PROJECT_GUID__.Debug|Any CPU.Build.0 = Debug|Any CPU
__LIB_PROJECT_GUID__.Debug|x64.ActiveCfg = Debug|Any CPU
__LIB_PROJECT_GUID__.Debug|x64.Build.0 = Debug|Any CPU
__LIB_PROJECT_GUID__.Debug|x86.ActiveCfg = Debug|Any CPU
__LIB_PROJECT_GUID__.Debug|x86.Build.0 = Debug|Any CPU
__LIB_PROJECT_GUID__.Release|Any CPU.ActiveCfg = Release|Any CPU
__LIB_PROJECT_GUID__.Release|Any CPU.Build.0 = Release|Any CPU
__LIB_PROJECT_GUID__.Release|x64.ActiveCfg = Release|Any CPU
__LIB_PROJECT_GUID__.Release|x64.Build.0 = Release|Any CPU
__LIB_PROJECT_GUID__.Release|x86.ActiveCfg = Release|Any CPU
__LIB_PROJECT_GUID__.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Solution>
<Configurations>
<Platform Name="Any CPU" />
<Platform Name="x64" />
<Platform Name="x86" />
</Configurations>
<Project Path="Lib/Lib.csproj" Id="__LIB_PROJECT_GUID__" />
</Solution>
Loading
Loading