Skip to the content.

.Subsln files

.Subsln files are used by SubSolution tools to describe the content of Visual Studio solutions in a user-friendly syntax. You can generate a Visual Studio solution from it or update an existing one.

You can find the XML schema here.

<Subsln xmlns="http://subsln.github.io/">
    <Root>
        <Folder Name="Tools">
            <Files Path="tools/*.bat" />
        </Folder>
        <Folder Name="Tests">
            <Projects Path="**/*.Tests.csproj" />
        </Folder>
        <Projects Path="src/">
    </Root>
</Subsln>

Why use a .subsln file ?

Subsln

By default, a .subsln file will generate a .sln file in the same folder and use the same filename. But paths and names can be configured through optional attributes:

<Subsln xmlns="http://subsln.github.io/"
        SolutionName="MySolution"
        OutputDirectory="sources/solutions"
        WorkspaceDirectory="sources/projects">
    ...
</Subsln>

Items sources

You can add items sources to a <Root> element in <Subsln> to define your solution items and hierarchy.

There are multiple item sources:

Projects

<Projects />
<Projects Path="sources/projects/MyProject.csproj" />
<Projects Path="sources/projects/" />
<Projects Path="sources/projects/**/*.csproj" />

Files

<Files Path="tools/deploy.bat" />
<Files Path="tools/" />
<Files Path="tools/**/*.bat" />

Folder

<Folder Name="Projects">
    <Folder Name="Test Projects">
        <Projects Path="**/*.Test.csproj" />
    </Folder>
    <Projects />
</Folder>

Dependencies

<Dependencies />
<Dependencies Target="ProjectSetID" />

Example: Add an application project and all its dependencies.

<Projects Path="sources/projects/MyApplication.csproj" />
<Dependencies />

Dependents

<Dependents />
<Dependencies Target="ProjectSetID" Scope="ScopeProjectSetID"
    KeepOnlyDirect="true" KeepOnlySatisfied="true" />

Solutions

<Solutions />
<Solutions Path="solutions/MySolution.sln" />
<Solutions Path="solutions/" />
<Solutions Path="solutions/**/*.sln" />

SubSolutions

<SubSolutions />
<SubSolutions Path="solutions/MySolution.subsln" />
<SubSolutions Path="solutions/" />
<SubSolutions Path="solutions/**/*.subsln" />

Advanced options

Build order & Overwrite

During solution, all the items sources will be applied to solution, in the order. If an item has already been added to solution by a previous item source, it will not be modified.

To force an items source to redefine an item already added to solution by a previous source, you can set the attribute Overwrite to true.

It can be necessary to move some projects in the wanted folder.

Example: Create a copy an existing solution but move the tests projects in a specific solution folder.

<Solutions Path="MySolution.sln" />
<Folder Name="Tests">
    <Projects Path="**/*.Tests.csproj" Overwrite="true" />
<Folder />

Folders mirroring

Use attribute CreateFolders on any project or file source to recreate the file system hierarchy inside the solution.

If you have too many intermediary folder in result, you can use CollapseFoldersWithUniqueSubFolder and CollapseFoldersWithUniqueItem on your root or folder to clean unnecessary folders.

Example: Get all projects and recreate their folder organization, but remove all folder with a unique project or sub-folder.

<Root CollapseFoldersWithUniqueSubFolder="true" CollapseFoldersWithUniqueItem="true">
    <Projects CreateFolders="true" />
</Root>

Note: Collapse attributes are applied recursively in all sub-folders. You can stop the propagation of the collapsing behaviour by setting it back to false in the wanted sub-folder.

Project sets & Virtual

To declare a project set, you can give an Id to a project source. All the projects resolved by that source will be stored under that name.

You can then use them as Target or Scope of <Dependencies> and <Dependents> item sources.

If you want to define a set of projects without adding them to the current solution, you can put project sources in the Virtual element instead of Root. Virtual item sources are resolved at build start to prepare the project sets you will need during build.

Example: Get only dependents projects that can be found in another solution.

<Virtual>
    <Solutions Path="MySolution.sln" Id="SolutionContent" />
</Virtual>
<Root>
    <Projects Path="MyFramework*.csproj" Id="Framework" />
    <Dependents Target="Framework" Scope="SolutionContent" />
</Root>

Where

You can use advanced filters with the element <Where> inside the item sources when the file glob pattern is not enough:

Project filters

File filters

Example: Get only test projects from solutions not in “external” folder.

<Solutions />
    <Where>
        <FileNot>
            <FilePath Match="external/">
        </FileNot>
    </Where>
    <WhereProjects>
        <ProjectMatchAnyOf>
            <ProjectPath Match="**/*Test.csproj">
            <ProjectPath Match="**/*Tests.csproj">
        </ProjectMatchAnyOf>
    </WhereProjects>
    <WhereFiles IgnoreAll="true" />
</Solutions>

KeepOnly

On <Solutions> and <SubSolutions>, you can also use item sources in the <KeepOnly> element to filter items.

In that case, only the items found by both the original item source and by any of <KeepOnly> item sources will be kept. It’s useful to filter items of an existing solution by dependency relationship or solution content, without breaking the original solution structure.

Example: Get projects (and their folders) from another solution only if they are dependent of a given project.

<Projects Path="**/MyFramework.csproj" Id="Framework" />
<SubSolutions Path="MySolution.sln" />
    <KeepOnly>
        <Dependents Target="Framework" />
    </KeepOnly>
</Solutions>

Configurations & Platforms

By default, the configurations and platforms of the resulting solution are automatically defined and filled by the projects contained in the solution.

But it is possible to define your own solution configurations and platforms, and decide how they match the projects configurations and platforms.

Note: Like in Visual Studio, the popular project platform “AnyCPU” is renamed as “Any CPU” in solutions.

Example: Solution with 3 manually-defined solution configurations and 3 solution platforms.

<Subsln xmlns="http://subsln.github.io/">
    <Root>
        <Projects />
    </Root>
    <Configurations>
        <!-- 3 configurations: Debug, Release, Final -->
        <!-- Final build projects in Final, or fallback on Release. -->
        <Configuration Name="Debug" />
        <Configuration Name="Release" />
        <Configuration Name="Final">
            <ProjectConfiguration Match="Final" />
            <ProjectConfiguration Match="Release" />
        </Configuration>
    </Configurations>
    <Platforms>
        <!-- 3 configurations: Any CPU, x86, x64 -->
        <!-- x86/x64 build projects in x86/x64, or fallback on Any CPU. -->
        <Platform Name="Any CPU" />
        <Platform Name="x86">
            <ProjectPlatform Match="x86" />
            <ProjectPlatform Match="Any CPU" />
        </Platform>
        <Platform Name="x64">
            <ProjectPlatform Match="x64" />
            <ProjectPlatform Match="Any CPU" />
        </Platform>
    </Platforms>
</Subsln>