Skip to content

Commit 7e162b7

Browse files
Add documentation related to msvcurt-c1xx (and a few other items)
1 parent b7dc835 commit 7e162b7

6 files changed

+685
-0
lines changed

Documentation/C++-notes.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# C++ Notes
2+
3+
- `$(RepoRoot)eng\WpfArcadeSdk\tools\` contains `Wpf.Cpp.Props`,`Wpf.Cpp.targets`, `Wpf.Cpp.PrivateTools.props` and `Wpf.Cpp.PrivateTools.targets`, which contain all the important C++ related properties
4+
- We need to undefine the `TargetFramework` property when `ProjectReference`-ing a C++/CLI project from a C# project
5+
- When a C++/CLI project is built directly from the solution, `TargetFramework=netcoreapp3.0` etc. property is NOT passed to it.
6+
- When the same project is built via a C# project, it receives a global property `TargetFramework=netcoreapp3.0`.
7+
- This results in msbuild treating those two instances as _sufficiently different_ and builds them independently.
8+
- In turn, the same project is built twice (often simultaneously), and results in simultaneous writes to the PDB etc.
9+
- This leads to build failures.
10+
- The solution is to delete `TargetFramework` property when specifying `ProjectReference` to a C++/CLI project from a C# project, like this:
11+
`<ProjectReference Include="$(WpfSourceDir)PresentationCore\CPP\PresentationCoreCpp.vcxproj">
12+
<UndefineProperties>TargetFramework;TargetFrameworks</UndefineProperties>
13+
</ProjectReference>`
14+
15+
### Deprecated Compiler Features
16+
17+
- /nowarn:D9035 is now being passed to build.ps1 in order to suppress the following C++ compiler warnings:
18+
- cl : Command line error D9035: option 'clr:pure' has been deprecated and will be removed in a future release
19+
- cl : Command line error D9035: option 'Zc:forScope-' has been deprecated and will be removed in a future release
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
### Local Markup Compilation
2+
3+
This repo builds PresentationBuildTasks.dll and the WindowsDesktop SDK itself, which are needed for markup-compilation.
4+
5+
Some of the projects in this repo require Markup Compilation themselves - for e.g., theme assemblies.
6+
7+
Here, we outline the scheme used by this repo to bootstrap markup compilation before a full-fledged WindowsDesktop SDK is available. All projects in this repo are base .NET Core SDK projects that utilize additional props/targets outlined below to enable markup compilation.
8+
9+
Local Markup Compilation is implemented in the following files:
10+
11+
- eng\WpfArcadeSdk\tools\Pbt.props
12+
- eng\WpfArcadeSdk\tools\Pbt.targets
13+
- eng\WpfArcadeSdk\tools\NoInternalTypeHelper.targets
14+
15+
16+
See comments in these targets for further details. Some additional work is needed to make this work completely.
17+
It can be enabled for a project by setting this:
18+
19+
```
20+
<PropertyGroup>
21+
<InternalMarkupCompilation>true</InternalMarkupCompilation>
22+
</PropertyGroup>
23+
```
24+
25+
Also, it's a good idea to use the following properties:
26+
27+
```
28+
<PropertyGroup>
29+
<NoInternalTypeHelper>true</NoInternalTypeHelper>
30+
<GenerateDependencyFile>false<GenerateDependencyFile>
31+
</PropertyGroup>
32+
```
33+
34+
Please take a look at `src\Microsoft.DotNet.Wpf\src\PresentationUI\PresentationUI.csproj` to see how this is utilized.
35+
36+
37+
In addition to these, care must be taken for the following:
38+
39+
- Use `<EmbeddedResource>` instead of `<Resource>`
40+
- `PresentationBuildTask` will strip out `<Resource>` items during `_CompileTemporaryAssembly` phase. Using `EmbeddedResource` is equivalent (esp. in for `Xlf` based string resource generation with `Arcade.Sdk`) and will not be adversely affected by `PresentationBuildTasks` transformations.
41+
- Always use `<NetCoreReference>` instead of implicitly acquiring the full set of `Microsoft.NetCore.App` references.
42+
- `Microsoft.NetCore.App` contains a version `WindowsBase` that clashes with WPF's `WindowsBase` during markup compilation.
43+
- To avoid this clash, we must always specify the references we need explicitly.
44+
- Also, our code-base requires that all references be specified explicitly anyway to avoid inadvertent reference-creep to bug-fixes.

Documentation/c++-private-tools.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# C++ Private Tools
2+
3+
### What is msvcurt-c1xx in global.json?
4+
5+
In late Feb 2019, we discovered a bug in the C++/CLI compiler for .NET Core that requried the front-end (`c1xx.dll`) and the libraries (`msvcurt(d)_netcore.lib`) to be rebuilt.
6+
7+
A fix was available in mid Mar, 2019, but this change could not make it into Dev16.0, and Dev16.1 Preview1 build weren't coming out until later in Apr, 2019.
8+
9+
In collaboration with the C++ team, we decided to build our repo using private (but signed) copies of `c1xx.dll` and `msvcurt(d)_netcore.dll`.
10+
11+
We have uploaded these private DLL's to an Azure blob at this location using Arcade's [_Native Toolset Bootstrapping_](https://github.com/dotnet/arcade/blob/master/Documentation/NativeToolBootstrapping.md) process.
12+
13+
This results in the the packages being uploaded to locations like these:
14+
15+
```
16+
- https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/msvcurt-c1xx/msvcurt-c1xx-0.0.0.3-win32-x86.zip
17+
- https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/msvcurt-c1xx/msvcurt-c1xx-0.0.0.3-win64-x64.zip
18+
```
19+
20+
PS: The version at the time this note was written is `0.0.0.3`. The version might be updated in the future and `global.json` would contain the correct version.
21+
22+
The version (`0.0.0.3`) is arbitrary, and simply refers to the the number of different versions we have uploaded as part of a trial-and-error approach to making our build work with these private compiler-bits.
23+
24+
In Azure Storage Explorer, the blobs can be found at this location:
25+
26+
```
27+
- Dotnet Engineering Services
28+
- Storage Accounts
29+
- netcorenativeassets
30+
- Blob Containers
31+
- resource-packages
32+
- external
33+
- windows
34+
- msvcurt-c1xx
35+
- msvcurt-c1xx-0.0.0.3-win64-x64.zip
36+
- msvcurt-c1xx-0.0.0.3-win32-x86.zip
37+
```
38+
39+
Writing to this storage account requires special permissions and is only available to Microsoft Employees - please work with DncEng if you need to do this. Also refer to [Native Toolset Bootstrapping documentation](https://github.com/dotnet/arcade/blob/master/Documentation/NativeToolBootstrapping.md).
40+
41+
42+
#### How does msvcurt-c1xx work?
43+
44+
- global.json + Arcade's toolset restore-phase will download the blobs and lay it out under `$(RepoRoot).tools\native\bin\msvcurt-c1xx\0.0.0.3\`
45+
- This will happen before build starts.
46+
- WPF's `Wpf.Cpp.props` + `Wpf.Cpp.targets` identifies the right copy of `c1xx.dll` and `msvcurt(d)_netcore.lib` and passes it to `cl.exe` and `link.exe` - thus overriding the copies that shipeed with Visual Studio.
47+
- For testing, you can prepare appropriate zip-bundles as described in the _Native Toolset Bootstrapping_ documentation and place them under `$env:USERPROFILE\.netcoreeng\native\temp` folder.
48+
- This is the _cache_ location used by the Arcade scripts for downloading the zip bundles from Azure Blob storage to local disk.
49+
- When the build-scripts observe that the zip file is already present in this location, they will not attempt to download the zip file from the blob.

Documentation/cycle-breakers.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Cycle Breakers
2+
3+
Certain assemblies in WPF contain cycles - they use types from other assemblies which, in turn, use types from them, effectively creating a cycle.
4+
5+
To allow assemblies to compile, we introduced cycle-breaking assemblies which re-define the problematic types (without an implementation and/or closure) and allow projects to referene them instead of referencing themselves, and break the cycle.
6+
7+
There are 2 types of cycle breaking assemblies:
8+
9+
* **Implementation cycle breakers**
10+
11+
An implementation cycle breaker assembly is referenced directly from a project that uses types from another "cycled" assembly in its implementation. An implemention cycle breaking assembly is likely to include types *and* their closures, because the closure may be used from the calling assembly.
12+
13+
* **API cycle breakers**
14+
15+
An API cycle breaking assembly is an assembly is likely referenced from a ref-assembly, or an implementation cycle breaking assembly. It is likely to not contain type closures, as much as possible, and generally minimal - way smaller in footprint than an implementation cycle breaker.
16+
17+
Examples of such assemblies are under *src\Microsoft.DotNet.Wpf\cycle-breakers*:
18+
19+
> Ex: PresentationFramework\PresentationFramework-PresentationUI-api-cycle.csproj
20+
21+
In the previous example, this assembly contains types from PresentationFramework and is exposing them to PresentationUI as an api-cycle-breaker. You will likely see minimal types here.
22+
23+
24+
> Ex: PresentationFramework\PresentationFramework-ReachFramework-impl-cycle.csproj
25+
26+
In the previous example, this assembly contains types from PresentationFramework and is exposing them to the ReachFramework's implementation. This is what we call an implementation cycle-breaker and you will likely see types with full closures here.

0 commit comments

Comments
 (0)