Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corefx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWes Haggard <Wes.Haggard@microsoft.com>2016-11-28 23:58:55 +0300
committerWes Haggard <Wes.Haggard@microsoft.com>2016-12-02 23:17:31 +0300
commitb7eda9d4a7d7414d693b7eca37fff5031f8d5a9e (patch)
tree28d4d745e902c2bc71dbf7f1702415870af0b1c1 /Documentation/coding-guidelines
parent81785e02ad372d61d70b03326dfdc41cc4de7556 (diff)
Update project-guidelines based on our current engineering plans
Diffstat (limited to 'Documentation/coding-guidelines')
-rw-r--r--Documentation/coding-guidelines/buildingvertical.md124
-rw-r--r--Documentation/coding-guidelines/project-guidelines.md315
2 files changed, 171 insertions, 268 deletions
diff --git a/Documentation/coding-guidelines/buildingvertical.md b/Documentation/coding-guidelines/buildingvertical.md
deleted file mode 100644
index b78cfbc993..0000000000
--- a/Documentation/coding-guidelines/buildingvertical.md
+++ /dev/null
@@ -1,124 +0,0 @@
-# Building a Vertical Implementation Details #
-
-**Definitions**
-
-*VerticalGroup*
-
-`VerticalGroup` - We need a property to define the vertical target group, but we don't want to set "TargetGroup" explicitly or we won't be able to build the "" TargetGroups for projects.
- If `VerticalGroup != ""`, we import buildvertical.targets which will contain our additional targets.
-
-*ProjectConfigurations*
-
-For each ref project and src project, we define `ProjectConfigurations`. `ProjectConfigurations` is a tuple for the supported `TargetGroup` and `OSGroup`.
-
-
-ie
-
-ref\System.Runtime.csproj
-```MSBuild
-<DefaultTargetGroup>netstandard1.7</DefaultTargetGroup>
-<PropertyGroup>
- <ProjectConfigurations>
- $(DefaultTargetGroup)|Windows_NT;
- $(DefaultTargetGroup)|OSX;
- $(DefaultTargetGroup)|Linux;
- netcoreapp1.1|Windows_NT;
- netcoreapp1.1|OSX;
- netcoreapp1.1|Linux
- </ProjectConfigurations>
-<PropertyGroup>
-```
-
-*DefaultTargetGroup*
-
-We define a `DefaultTargetGroup` in each csproj so that we can undefine the `TargetGroup` property if we are building targeting that `TargetGroup`.
-
-*Contract Layer*
-
-We have a contract layer (msbuild task).
-
-Inputs:
-
- ProjectConfigurations
- VerticalGroup (desired OSGroup and TargetGroup as OSGroup-TargetGroup-[Release|Debug])
-
-Output:
-
- VerticalTargets (ItemTask)
- metadata: TargetGroup
- OSGroup
-
-Given the supported target and OS groups, and the desired vertical target and OS groups, return the closest supported group or empty metadata items.
-
-How should we handle determining the target / os groups, fallback groups, etc...? The simplest solution is to use the NuGet api's for targets. We can use platforms\runtime.json for os groups, or try to use the already existent os group filtering instead of adding it to the contract layer.
-
-Options:
-
-1. Use NuGet API's
-
-2. Make use of information we already have and develop our own resolution algorithm.
-
-The current implementation uses our own resolution algorithm. We define the resolution graph for `TargetGroup` and `OSGroup` in targetgroup.props and osgroup.props files respectively.
-
-**Building a vertical implementation steps**
-
-1 - Include all projects, we don't need to build the .builds files for each library, because we only want to build each project at most once for a given vertical.
-
-```MSBuild
-<ItemGroup>
- <Project Include="**\ref\*proj" />
- <Project Include="**\src\*proj" />
-</ItemGroup>
-```
-
-2 - Iterate all projects through the contract layer, removing (and logging) any projects which return null metadata (not supported).
-
-3 - Build `OutputPath` is set to drop all binaries into a single folder
-
-Current standard `OutputPath`
-
-```MSBuild
-<OutputPath Condition="'$(OutputPath)'==''">$(BaseOutputPath)$(OSPlatformConfig)/$(MSBuildProjectName)/$(TargetOutputRelPath)$(OutputPathSubfolder)</OutputPath>
-```
-Example: E:\gh\chcosta\corefx\bin/AnyOS.AnyCPU.Debug/System.Buffers/netcoreapp1.1/
-
-Proposed vertical `OutputPath`
-
-```MSBuild
-<OutputPath Condition="'$(OutputPath)'==''">$(BinDir)/$(VerticalTargetGroup)/$(OSPlatformConfig)</OutputPath>
-```
-Example: E:\gh\chcosta\corefx\bin/netcoreapp1.7/AnyOS.AnyCPU.Debug
-
-Traditionally, the output path contains the `TargetGroup` as a part of the path. The flat structure means we don't have to play games with the `TargetPath` to figure out when, for example, "System.Buffers" ("netstandard1.1") is trying to find the "System.Runtime" reference ("netstandard1.7"), that there is no path for "System.Runtime.dll" containing the "netstandard1.1" target group.
-
-4 - Build all reference assemblies. The reference assembly projects, which were not trimmed in step 2, are all built. TBD, should we again use the contract layer during the build to determine the targets for the project, or should we capture that as metadata for the project in step 2?
-
-5 - Build all src assemblies into the "OutputPath". The src assembly projects, which were not trimmed in step 2. are all built.
-
-6 - build packages, TBD
-
-**Building a library**
-
-In addition to the ability to build an entire vertical, we require the ability to build a single library. This, single library build should utilize context to determine TargetGroup and OSGroup. ie, If a vertical build completes, and you want to build an individual library, it should use the group values from the vertical build unless you specify otherwise. If you specify otherwise, then those settings become the new settings. If no context is available, then the library should be built with a set of commond default values.
-
-When building an individual library, or project, its P2P references must be queried to determine supported configurations for building that refernce and then the best configuration must be chosen.
-
-**Additional issues**
-
-- building specific folders (filter by partition)?
-
-- building / running tests for a vertical
-
- - building tests against packages
-
-- Official builds?
-
-- CI testing?
-
-- Validation
-
- - Is it an error condition if any library does not contribute to the latest standard vertical?
-
- - Is it an error condition if a library does not contribute to any OS group? probably
-
-
diff --git a/Documentation/coding-guidelines/project-guidelines.md b/Documentation/coding-guidelines/project-guidelines.md
index 5dc6639a63..133f8bcbf8 100644
--- a/Documentation/coding-guidelines/project-guidelines.md
+++ b/Documentation/coding-guidelines/project-guidelines.md
@@ -1,49 +1,118 @@
-#Library Project guidelines
-Library projects should use the following directory layout.
+#Build Project Guidelines
+In order to work in corefx repo you must first run build.cmd/sh from the root of the repo at least
+once before you can iterate and work on a given library project.
+
+##Behind the scenes with build.cmd/sh
+
+- Setup tools (currently done in init-tools but will later be a boot-strap script in run.cmd/sh)
+- Restore external dependencies
+ - CoreCLR - Copy to `bin\runtime\$(BuildConfiguration)`
+ - Netstandard Library - Copy to `bin\ref\netstandard`
+ - UAP - Copy to `bin\runtime\$(BuildConfiguration)`
+ - NetFx targeting pack - Copy to `bin\ref\netfx`
+- Build targeting pack
+ - Build src\ref.builds which builds all references assembly projects. For reference assembly project information see [ref](#ref)
+- Build product
+ - Build src\src.builds which builds all the source library projects. For source library project information see [src](#src).
+- Sign product
+ - Build src\sign.builds
+//**CONSIDER**: We should make this as part of the src.builds file instead of a separate .builds file.
+
+##Behind the scenes with build-test.cmd/sh
+- build-test.cmd cannot be ran successfully until build.cmd has been ran at least once for a `BuildConfiguration`.
+- Build src\tests.builds which builds all applicable test projects. For test project information see [tests](#tests).
+- The build pass will happen twice. Once for the specific `$(BuildConfiguration)` and once for netstandard. That way we run both sets of applicable tests against for the given `$(BuildConfiguration)`.
+- TODO: Currently as part of src/post.builds we call CloudBuild.targets which sets up our test runs. This needs to be moved to be part of build-test.cmd now.
+
+##Behind the scenes with build-packages.cmd/sh
+- build-packages.cmd cannot be run successfully until build.cmd has been ran at least once for a BuildConfiguration.
+- Build src\packages.builds which will build only the packages it has the context to build which will generally be only the ones for the given `BuildConfiguration`. If a package requires assets from multiple `BuildConfigurations` it will require that all `BuildConfigurations` are built first.
+
+#Build Pivots
+Below is a list of all the various options we pivot the project builds on:
+
+- **Target Frameworks:** NetFx (aka Desktop), netstandard (aka dotnet/Portable), NETCoreApp (aka .NET Core), UAP (aka UWP/Store/netcore50)
+- **Platform Runtimes:** NetFx (aka CLR/Desktop), CoreCLR, CoreRT (aka NetNative/AOT/MRT)
+- **OS:** Windows_NT, Linux, OSX, FreeBSD, AnyOS
+- **Flavor:** Debug, Release
+- **Architecture:** x86, x64, ARM, ARM64, AnyCPU
+
+##Individual build properties
+The following are the properties associated with each build pivot
+
+- `$(TargetGroup) -> netstandard | netcoreapp | netcoreappcorert | netfx | uap | uapaot`
+//**CONSIDER**: naming netcoreappcorert something shorter maybe just corert.
+- `$(OSGroup) -> empty/AnyOS* | Windows | Linux | OSX | FreeBSD`
+- `$(ConfigurationGroup) -> empty/Debug* | Release`
+- `$(ArchGroup) - empty/AnyCPU* | x86 | x64 | ARM | ARM64`
+
+For more information on various targets see also [.NET Standard](https://github.com/dotnet/standard/blob/master/docs/versions.md)
+
+<BR/>`*` -> *default values*
+
+##Aggregate build properties
+Each project will define a set of supported build configurations
+
```
-src\<Library Name>\src - Contains the source code for the library.
-src\<Library Name>\ref - Contains any reference assembly projects for the library
-src\<Library Name>\pkg - Contains package projects for the library.
-src\<Library Name>\tests - Contains the test code for a library
+<PropertyGroup>
+ <BuildConfigurations>
+ [BuildConfiguration1];
+ [BuildConfiguration2];
+ ...
+ </BuildConfigurations>
+<PropertyGroup>
```
-In the src directory for a library there should be only **one** `.csproj` file that contains any information necessary to build the library in various configurations (see [Configurations](#project-configuration-conventions)). The src directory should also contain exactly **one** `.builds` file which contains all the valid configurations that a library should be built for (see [#.builds file](#project-builds-file)).
-In the ref directory for the library there should be at most **one** `.csproj` that contains the latest API for the reference assembly for the library. If a library cannot support all supported targets using the latest API it should use `.depproj` projects for each significant historical version in order to download and redistribute the historical reference assembly in the latest package. If a library is a pure portable library with a single implementation it need not use a reference assembly at all. (see [Reference assembly projects](#reference-assembly-projects)).
+- `$(BuildConfiguration) -> $(TargetGroup)[-$(OSGroup)][-$(ConfigurationGroup)][-$(ArchGroup)]`
+ - Note this property should be file path safe and thus can be used in file names or directories that need to a unique path for a project configuration.
+ - The only required configuration value is the `$(TargetGroup)` the others are optional.
-In the pkg directory for the library there should be only **one** `.pkgproj` for the primary package for the library. If the library has platform-specific implementations those should be split into platform specific projects in a subfolder for each platform. (see [Package projects](./package-projects.md))
+Example:
+Pure netstandard configuration:
+```
+<PropertyGroup>
+ <BuildConfigurations>
+ netstandard;
+ </BuildConfigurations>
+<PropertyGroup>
+```
-##Build Pivots
-Below is a list of all the various options we pivot the project builds on.
+All supported targets with unique windows/unix build for netcoreapp:
+```
+<PropertyGroup>
+ <BuildConfigurations>
+ netcoreapp-Windows_NT;
+ netcoreapp-Unix;
+ netfx-Windows_NT;
+ uap-Windows_NT;
+ </BuildConfigurations>
+<PropertyGroup>
+```
-- **Architecture:** x86, x64, ARM, ARM64
-- **Flavor:** Debug, Release
-- **OS:** Windows_NT, Linux, OSX, FreeBSD
-- **Platform Runtimes:** NetFx (aka CLR/Desktop), CoreCLR, CoreRT (aka NetNative/AOT/MRT)
-- **Target Frameworks:** NetFx (aka Desktop), netstandard (aka dotnet/Portable), NETCoreApp (aka .NET Core), UAP (aka UWP/Store/netcore50)
-- **Version:** Potentially multiple versions at the same time.
-- **TestTFM:** net46, netcoreapp1.1, netcore50. This is the TFM that will be used to run the tests in. (Used in test projects only)
+##Full build configuration
+The `BuildConfiguration` property can either be set directly via
+`/p:BuildConfiguration=[BuildConfiguration]` or will be defaulted based
+on where you are running the build. The default will look like `netcoreapp-[RunningOS]-Debug-[RunningProcessArch]`, example `netcoreapp-Windows_NT-Debug-x64`.
+
+##Selecting the correct build configuration
+When building an individual project the `BuildConfiguation` will be used to select the closest matching configuration listed in the projects `BuildConfigurations` property. The rules used to select the configuration will consider compatible target frameworks and OS fallbacks.
-##Full Repo build pass
-**Build Parameters:** *Flavor, Architecture*<BR/>
-For each combination of build parameters there should be a full build pass over the entire repo.
+TODO: Link to the target framework and OS fallbacks when they are available.
+Temporary versions are at https://github.com/dotnet/corefx/blob/dev/eng/src/Tools/GenerateProps/osgroups.props and https://github.com/dotnet/corefx/blob/dev/eng/src/Tools/GenerateProps/targetgroups.props
-##Project build pass
-**Optional Build Parameters:** *OS, Platform Runtime, Target Framework, Version*<BR/>
-These are optional build parameters for specific projects and don't require a full build pass but instead should be scoped to individual projects within the most appropriate full build pass.
+##Supported full build configurations
+- .NET Core latest on current OS (default) -> `netcoreapp-[RunningOS]`
+- .NET Core CoreRT -> `netcoreappcorert-[RunningOS]`
+- .NET Framework latest -> `netfx-Windows_NT`
+- UWP -> `uapaot-Windows_NT`
+- UAP F5 -> `uap-Windows_NT`
-#Project configuration conventions
+##Project configurations for VS
For each unique configuration needed for a given library project a configuration property group should be added to the project so it can be selected and built in VS and also clearly identify the various configurations.<BR/>
-`<PropertyGroup Condition="'$(Configuration)|$(Platform)' == '$(<OSGroup>_<TargetGroup>_<ConfigurationGroup>)|$(Platform)'">`
-
-- `$(Platform) -> AnyCPU* | x86 | x64 | ARM | ARM64`
-- `$(Configuration) -> $(OSGroup)_$(TargetGroup)_$(ConfigurationGroup)`
-- `$(OSGroup) -> [Empty]/AnyOS* | Windows | Linux | OSX | FreeBSD`
-- `$(TargetGroup) -> [Empty]* | <PackageTargetFramework> | <PackageTargetRuntime> | <Version> | <PackageTargetFramework><PackageTargetRuntime>`
- - `$(PackageTargetFramework) -> net46x | netstandard1.x | netcoreapp1.x | uap10.x | netcore50`
- - `$(PackageTargetRuntime) -> aot`
- - For more information on various targets see also [.NET Standard](https://github.com/dotnet/standard/blob/master/docs/versions.md)
-- `$(ConfigurationGroup) -> Debug* | Release`
-<BR/>`*` -> *default values*
+
+`<PropertyGroup Condition="'$(Configuration)|$(Platform)' == '$(OSGroup)-$(TargetGroup)-$(ConfigurationGroup)|$(Platform)'">`
+
+- Note that the majority of managed projects, currently all in corefx, $(Platform) is overridden to be AnyCPU.
####*Examples*
Project configurations for a pure IL library project which targets the defaults.
@@ -51,124 +120,87 @@ Project configurations for a pure IL library project which targets the defaults.
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'" />
```
-Project configurations with a unique implementation for each OS
+Project configurations with a unique implementation on Unix and Windows
```xml
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'FreeBSD_Debug|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'FreeBSD_Release|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Linux_Debug|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Linux_Release|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'OSX_Debug|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'OSX_Release|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Windows_Debug|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Windows_Release|AnyCPU'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Unix-Debug|AnyCPU'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Unix-Release|AnyCPU'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Windows_NT-Debug|AnyCPU'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Windows_NT-Release|AnyCPU'" />
```
Project configurations that are unique for a few different target frameworks and runtimes
```xml
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap101aot_Debug|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap101aot_Release|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap101_Debug|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap101_Release|AnyCPU'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap101aot-Debug|AnyCPU'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap101aot-Release|AnyCPU'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap101-Debug|AnyCPU'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap101-Release|AnyCPU'" />
```
-## Project .builds file
-To drive the Project build pass we have a `.builds` project file that will multiplex the various optional build parameters we have for all the various configurtions within a given build pass.
-
-####*Examples*
-
-Project configurations for pure IL library project
-```xml
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <ItemGroup>
- <Project Include="System.Reflection.Metadata.csproj" />
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
-</Project>
-```
-Project configurations with a unique implementation for each OS
-```xml
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <ItemGroup>
- <Project Include="System.IO.FileSystem.csproj">
- <OSGroup>FreeBSD</OSGroup>
- </Project>
- <Project Include="System.IO.FileSystem.csproj">
- <OSGroup>Linux</OSGroup>
- </Project>
- <Project Include="System.IO.FileSystem.csproj">
- <OSGroup>OSX</OSGroup>
- </Project>
- <Project Include="System.IO.FileSystem.csproj">
- <OSGroup>Windows_NT</OSGroup>
- </Project>
- <Project Include="System.IO.FileSystem.csproj">
- <OSGroup>Windows_NT</OSGroup>
- <TargetGroup>uap101</TargetGroup>
- </Project>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
-</Project>
+#Library project guidelines
+Library projects should use the following directory layout.
```
-Project configurations that are unique for a few different target frameworks and runtimes
-```xml
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <ItemGroup>
- <Project Include="System.Linq.Expressions.csproj" />
- <Project Include="System.Linq.Expressions.csproj">
- <OSGroup>Windows_NT</OSGroup>
- <TargetGroup>uap101</TargetGroup>
- </Project>
- <Project Include="System.Linq.Expressions.csproj">
- <OSGroup>Windows_NT</OSGroup>
- <TargetGroup>uap101aot</TargetGroup>
- </Project>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
-</Project>
+src\<Library Name>\src - Contains the source code for the library.
+src\<Library Name>\ref - Contains any reference assembly projects for the library
+src\<Library Name>\pkg - Contains package projects for the library.
+src\<Library Name>\tests - Contains the test code for a library
```
-###Tests project .builds files
+##ref
+Reference assemblies are required for any library that has more than one implementation or uses a facade. A reference assembly is a surface-area-only assembly that represents the public API of the library. To generate a reference assembly source file you can use the [GenAPI tool](https://www.nuget.org/packages/Microsoft.DotNet.BuildTools.GenAPI). If a library is a pure portable library with a single implementation it need not use a reference assembly at all.
-The tests .builds files are very similar to the regular ones, except that they usually tend to pass in one extra property as metadata: `TestTFMs`. The purpose for this extra metadata property, is to show which TFMs are supported by the test projects build configuration. When doing a full build, a TestTFM will be specified (if not specified netcoreapp1.1 will be used as default), and the build will look into all of these test .builds files to try and find which configurations support testing in that TestTFM, and then start running the tests for those configurations.
+In the ref directory for the library there should be at most **one** `.csproj` that contains the latest API for the reference assembly for the library. That project can contain multiple entries in its `BuildConfigurations` property.
-####How to know which TestTFMs does a project support
-`TargetGroup` and `TestTFM` are closely tied together, given that `TargetGroup` selects the TFM (the surface area) that the test assembly will use, and the `TestTFM` is where tests will actually run on. Here is a small cheat sheet of which `TestTFMs` you should add to the builds file given a `TargetGroup`:
+There are two types of reference assembly projects:
-TargetGroup | TestTFMs Supported
------------ | ------------------
-netstandard1.1 | netcoreapp1.0;net45
-netstandard1.2 | netcoreapp1.0;net451
-netstandard1.3 | netcoreapp1.0;net46
-netstandard1.4 | netcoreapp1.0;netcore50;net46
-netcoreapp1.0 | netcoreapp1.0
-netstandard1.6 | netcoreapp1.0;net462;netcore50
-netcoreapp1.1 | netcoreapp1.1
-netstandard1.7 | netcoreapp1.1;uap10.1;net463
+1. Libraries that are contain APIs in netstandard
+ - `BuildConfigurations` should contain non-netstandard configurations for the platforms they support.
+ - Should use a relative path `<ProjectReference>` to the dependencies it has. Those depedencies should only be libraries with similar build configurations and be part of netstandard.
+<BR/>//**CONSIDER**: just using Reference with a custom task to pull from TP or turn to ProjectReference
+2. Libraries that are built on top of netstandard
+ - `BuildConfigurations` should contain only netstandard configurations.
+ - Should contain `<Reference Include='netstandard'>`
+ - Anything outside of netstandard should use a relative path `<ProjectReference>` to its dependencies it has. Those depdencies should only be libraries that are built against netstandard as well.
-####*Example*
-```xml
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <ItemGroup>
- <Project Include="System.Linq.Expressions.Tests.csproj" />
- <Project Include="System.Linq.Expressions.Tests.csproj">
- <OSGroup>Windows_NT</OSGroup>
- <TestTFMs>net463</TestTFMs>
- </Project>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
-</Project>
-```
-In the example above, the first configuration does not pass in `TestTFMs`, which means that this configuration is supported only by [the default TestTFM](https://github.com/dotnet/corefx/blob/master/dir.props#L495)
+###ref output
+The output for the ref project build will be a flat targeting pack folder in the following directory:
+
+`bin\ref\$(TargetGroup)`
+
+<BR/>//**CONSIDER**: Do we need a specific BuildConfiguration version of TargetGroup for this output path to ensure all projects output to same targeting path?
+
+##src
+In the src directory for a library there should be only **one** `.csproj` file that contains any information necessary to build the library in various configurations. All supported configurations should be listed in the `BuildConfigurations` property.
+
+All libraries should use '<Reference Include="..." />' for all their project references. That will cause them to be resolved against a targeting pack (i.e. `bin\ref\netcoreapp` or `\bin\ref\netstanard`) based on the project configuration. There should not be any direct project references to other libraries. The only exception to that rule right now is for partial facades which directly reference System.Private.CoreLib and thus need to directly reference other partial facades to avoid type conflicts.
+<BR>//**CONSIDER**: just using Reference and use a reference to System.Private.CoreLib as a trigger to turn the other References into a ProjectReference automatically. That will allow us to have consistency where all projects just use Reference.
+
+###src output
+The output for the src product build will be a flat runtime folder into the following directory:
+
+`bin\runtime\$(BuildConfiguration)`
+
+Note: The `BuildConfiguration` is the global property and not the project configuration because we need all projects to output to the same runtime directory no matter which compatible configuration we select and build the project with.
+
+##pkg
+In the pkg directory for the library there should be only **one** `.pkgproj` for the primary package for the library. If the library has platform-specific implementations those should be split into platform specific projects in a subfolder for each platform. (see [Package projects](./package-projects.md))
+
+TODO: Outline changes needed for pkgprojs
+
+##tests
+Similar to the src projects tests projects will define a `BuildConfigurations` property so they can list out the set of build configurations they support.
+
+Tests should not have any `<Reference>` or `<ProjectReference>` items in their project because they will automatically reference everything in the targeting pack based on the configuration they are building in. The only exception to this is a `<ProjectReference>` can be used to reference other test helper libraries or assets.
+
+In order to build and run a test project in a given configuration a root level build.cmd/sh must have been completed for that configuration first. Tests will run on the live built runtime at `bin\runtime\$(BuildConfiguration)`.
+TODO: We need update our test host so that it can run from the shared runtime directory as well as resolve assemblies from the test output directory.
+
+###tests output
+All test outputs should be under
+
+`bin\tests\$(MSBuildProjectName)\$(BuildConfiguration)` or
+`bin\tests\$(MSBuildProjectName)\netstandard`
##Facades
Facade are unique in that they don't have any code and instead are generated by finding a contract reference assembly with the matching identity and generating type forwards for all the types to where they live in the implementation assemblies (aka facade seeds). There are also partial facades which contain some type forwards as well as some code definitions. All the various build configurations should be contained in the one csproj file per library.
@@ -203,9 +235,4 @@ Each source file should use the following guidelines
As mentioned in [Conventions for forked code](conventions-for-forked-code) `#ifdef`ing the code is the last resort as it makes code harder to maintain overtime. If we do need to use `#ifdef`'s we should use the following conventions:
- Defines based on conventions should be one of `$(OSGroup)`, `$(TargetGroup)`, `$(ConfigurationGroup)`, or `$(Platform)`, matching exactly by case to ensure consistency.
- Examples: `<DefineConstants>$(DefineConstants),net46</DefineContants>`
-- Defines based on convention should match the pattern `FEATURE_<feature name>`. These can unique to a given library project or potentially shared (via name) across multiple projects.
-
-# Reference assembly projects
-Reference assemblies are required for any library that has more than one implementation or uses a facade. A reference assembly is a surface-area-only assembly that represents the public API of the library. To generate a reference assembly source file you can use the [GenAPI tool](https://www.nuget.org/packages/Microsoft.DotNet.BuildTools.GenAPI).
-
-When adding API to a library it is sometimes impossible to support the new API on all the platforms where the library is supported today. We strive to support new APIs everywhere, but sometimes this is not possible. For example: string is part of the core library so a new property on string must exist on the core library type. We cannot ship a new copy of string to the desktop due to limitations in binding rules for the desktop. Instead of dropping support for desktop we include an older version of the reference assembly that represents the smaller surface area for that version of desktop. This is achieved by adding a deployment project (`.depproj`) to deploy the old reference assembly from the old package.
+- Defines based on convention should match the pattern `FEATURE_<feature name>`. These can unique to a given library project or potentially shared (via name) across multiple projects. \ No newline at end of file