Raven Project System
Raven supports compiling either individual .rvn files (with legacy .rav compatibility) or a project file (.rvnproj).
You can scaffold a project in the current directory with:
rvn init
Project file format
*.rvnproj is now a real MSBuild project file. The primary format matches SDK-style .csproj structure and relies on evaluated MSBuild properties/items rather than Raven-specific XML attributes.
Primary MSBuild properties Raven currently consumes:
TargetFrameworkTargetFrameworks(first TFM is used for now)AssemblyNameOutputType(ExeorLibrary)AllowUnsafeBlocksorAllowUnsafeAllowGlobalStatementsorRavenAllowGlobalStatementsDefineConstants(conditional-compilation symbols separated by semicolons, commas, or whitespace)FrameworkProjectionsorRavenFrameworkProjections(Standardby default, orNonefor the ordinary .NET API surface)IntermediateOutputPathConfigurationRavenGenerateDocumentation(trueby default for libraries)GenerateDocumentationFileGenerateMarkdownDocumentationFileGenerateXmlDocumentationFromMarkdownCommentsDocumentationFileMarkdownDocumentationOutputPath
Library projects emit both Raven Markdown sidecars and compatible .NET XML
documentation by default. Raven-authored comments are Markdown unless the XML
format is explicitly selected. Set RavenGenerateDocumentation to false to
disable the default bundle, or override the individual properties to select one
projection. When consuming metadata, Raven prefers the Markdown sidecar and
falls back to adjacent XML documentation.
Implementation details are available in the repository's Raven Documentation Model and External Documentation Sidecars design notes.
Primary MSBuild items Raven currently consumes:
<RavenCompile Include="..."/><ProjectReference Include="..."/><Reference Include="...">withHintPath<PackageReference Include="Package.Id" Version="x.y.z"/><FrameworkReference Include="Framework.Name"/>
.editorconfig diagnostic severity support
Raven reads .editorconfig files when compiling project and source files and applies
diagnostic severity overrides from:
dotnet_diagnostic.<ID>.severitydotnet_diagnostic.*.severitydotnet_analyzer_diagnostic.severity
Supported severity values:
none/suppress-> suppressedsilent/hidden-> hiddensuggestion/info-> infowarning/warn-> warningerror-> errordefault-> default severity
Example:
root = true
[*.rvn]
dotnet_diagnostic.RAV9012.severity = none
dotnet_diagnostic.RAV9013.severity = none
dotnet_diagnostic.RAV9014.severity = none
Raven source inclusion
Raven source files should be declared with RavenCompile items, just like C# uses Compile items.
Minimal example:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<AssemblyName>App</AssemblyName>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<RavenCompile Include="src/**/*.rvn" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>
Conditional-compilation symbols use the standard MSBuild property:
<PropertyGroup>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
The evaluated value is passed into every syntax tree in the project, including trees used by the language server. Changing the value causes affected documents to be reparsed so editor diagnostics and inactive-code highlighting remain consistent with builds.
Legacy .ravenproj files and legacy Raven-specific XML are deprecated. They remain loadable for compatibility, but new projects should use .rvnproj and the MSBuild-backed project shape.
Generated prelude imports
Raven projects generate a <ProjectName>.Prelude.g.rvn source file by default.
It globally imports the common System namespaces plus System.Result.* and
System.Option.*.
Global imports are hoisted across the compilation, but they still use ordinary
import binding rules. Namespace imports are the most robust project-file import
shape because the namespace only has to exist after references and project
declarations are known. Type-scope imports such as System.Result.* and direct
nested-case imports such as System.Result.Ok require the imported type or
nested type to be available to the compilation. They are supported, but they are
less flexible than namespace imports and should normally be reserved for stable
library/prelude cases; user-defined union cases are usually clearer as qualified
or target-typed .Case references.
Set GeneratePreludeImports to false to disable the generated standard
imports:
<PropertyGroup>
<GeneratePreludeImports>false</GeneratePreludeImports>
</PropertyGroup>
Projects can add prelude imports with Import items:
<ItemGroup>
<Import Include="SuperheroApp.Models" />
<Import Include="System.Console" Static="True" />
<Import Include="System.DateTime" Alias="DT" />
</ItemGroup>
Non-aliased items generate global wildcard imports. Static="True" is intended
for type-scope imports such as System.Console.*. Alias generates a
project-wide alias in the prelude. If a source file repeats an import that is
already supplied by a global import, the compiler reports a hidden redundant
import diagnostic and editors can offer a remove-import fix.
NuGet package references
When a .rvnproj includes <PackageReference>:
- Raven first resolves package assemblies from the global NuGet cache:
$NUGET_PACKAGESwhen set- otherwise
~/.nuget/packages
- If required assets are missing, Raven runs
dotnet restorefor a temporary SDK project. - Raven reads resolved compile assets and adds those assemblies as metadata references.
When a .rvnproj includes <FrameworkReference>:
- Raven restores a temporary SDK project that contains those framework references.
- Raven resolves the corresponding framework reference packs from installed .NET SDK
packs/. - Pack reference assemblies are added as metadata references for compilation.
Project extensions
A Raven project can load compiled extension assemblies:
<ItemGroup>
<Analyzer Include="extensions/MyProjectRules.dll" />
<SourceGenerator Include="extensions/MyProjectGenerators.dll" />
</ItemGroup>
Analyzerassemblies contribute custom diagnostics after generators and normal compiler binding.SourceGeneratorassemblies contribute additional Raven syntax trees before binding and analyzer execution.
Both paths are resolved relative to the project file. An extension assembly may contain multiple public, non-abstract extension types with parameterless constructors.
When the extension is built alongside the Raven project, use a
ProjectReference to establish build ordering without adding the extension as
an application metadata reference:
<ItemGroup>
<ProjectReference
Include="extension/MyExtensions.csproj"
ReferenceOutputAssembly="false" />
<Analyzer
Include="extension/bin/$(Configuration)/$(TargetFramework)/MyExtensions.dll" />
</ItemGroup>
See Extend a Raven project for authoring guidance and runnable analyzer and generator samples.
Build vs publish outputs
Raven project builds use the standard .NET output layout:
- Normal build (
dotnet build App.rvnproj)- default output directory:
<project-dir>/bin/<Configuration> - emits apphost +
.dll+.runtimeconfig.jsonfor console apps - does not copy package/runtime dependency sets
- default output directory:
- Publish (
dotnet publish App.rvnproj)- default output directory:
<project-dir>/bin/<Configuration>/publish - copies runtime dependencies (NuGet/framework/local assemblies) to output
- emits runtime artifacts (
.runtimeconfig.json, apphost)
- default output directory:
Dependency copy details:
- Only
.dllpackage dependencies are copied. - If a compile reference comes from
ref/, Raven prefers the runtime assembly underlib/.
Generated intermediate sources
For project builds, Raven can generate intermediate Raven source files under:
<project-dir>/obj/<Configuration>/raven/generated/
Current generated source:
<ProjectName>.TargetFrameworkAttribute.g.rvncontaining:
import System.Runtime.Versioning.*
[assembly: TargetFramework(".NETCoreApp,Version=vX.Y")]
Generation rules:
- Emitted when
TargetFrameworkis set on.rvnproj. - Skipped if user source already declares assembly-level
TargetFrameworkAttribute.
CLI usage
Compile a project file:
dotnet run --project src/Raven.Compiler --property WarningLevel=0 -- path/to/App.rvnproj
Use dotnet build and dotnet run --project for normal application build and
run workflows.
Use -o with rvnc to override the output directory:
dotnet run --project src/Raven.Compiler --property WarningLevel=0 -- path/to/App.rvnproj -o path/to/out
Sample:
samples/projects/nuget-demo/README.mdsamples/projects/raven-msbuild-integration/README.mdsamples/projects/runtime-async-net11/README.md
Runtime async for net11.0
If a .rvnproj sets <TargetFramework>net11.0</TargetFramework> (or newer), Raven enables runtime-async mode by default.
- Async methods emit with runtime async metadata.
- Await expressions emit
System.Runtime.CompilerServices.AsyncHelpers.Await(...)calls when available. - State-machine type synthesis is skipped.
When invoking the compiler driver through dotnet run, make sure the compiler host itself runs as net11.0:
dotnet run -f net11.0 --project src/Raven.Compiler --property WarningLevel=0 -- path/to/App.rvnproj
When invoking a net11.0 .rvnproj through dotnet build or
dotnet run --project, the selected .NET SDK must also support net11.0. Use a
project-local global.json to pin SDK 11 when a machine has multiple SDK bands
installed.
You can still override behavior explicitly:
--runtime-asyncto force on.--no-runtime-asyncto force off.
MSBuild build integration
.rvnproj files can build through the normal .NET SDK pipeline when MSBuild is
wired to Raven's language targets:
build/Raven.MSBuild.propssets.rvnprojLanguageTargetsto Raven's target file.build/Raven.Language.targetsimports the common managed build targets and implements Raven'sCoreCompile.- The Raven compile writes the SDK intermediate assembly, copies it to the SDK
reference-assembly slot when requested, and lets the normal SDK output pipeline
copy files to
bin/<Configuration>/<TargetFramework>/. - MSBuild-resolved
ReferencePathitems are passed torvnc; package restore and framework-reference resolution remain owned by the .NET SDK rather than the Raven compiler core.
Inside this repository, Directory.Build.props wires .rvnproj files
automatically, so sample projects build directly:
dotnet build samples/projects/hello-world/HelloWorld.rvnproj --property WarningLevel=0
For standalone projects before Raven is packaged as an SDK/NuGet build asset,
set LanguageTargets and, when needed, RavenCompilerHost explicitly:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<LanguageTargets>/path/to/Raven/build/Raven.Language.targets</LanguageTargets>
<RavenCompilerHost>/path/to/Raven/src/Raven.Compiler/bin/Debug/net10.0/rvnc.dll</RavenCompilerHost>
<TargetFramework>net10.0</TargetFramework>
<AssemblyName>RavenGreeter</AssemblyName>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
<RavenCompile Include="src/**/*.rvn" />
</ItemGroup>
</Project>
C# and other SDK projects can reference a Raven project with normal
ProjectReference once the referenced .rvnproj has Raven language targets:
<ItemGroup>
<ProjectReference Include="..\raven\RavenGreeter.rvnproj" />
</ItemGroup>
The old build/Raven.MSBuild.targets bridge remains for compatibility with
host projects that set RavenProjectFile, but new projects should prefer
building the .rvnproj itself and using ProjectReference.
Workspace and project-system services
RavenWorkspace now consumes project loading/saving through host services rather than hardcoding project-file persistence logic in workspace APIs.
PersistenceServicedelegates project open/save toIProjectSystemService.RavenProjectSystemServiceis the deprecated compatibility implementation for legacy.ravenproj.MsBuildProjectSystemServiceopens Raven projects authored as MSBuild-backed.rvnprojfiles.CompositeProjectSystemServicelets the workspace route between legacy.ravenprojfiles and primary.rvnprojprojects.RavenWorkspace.Create(..., projectSystemService: ...)still allows overriding the project-system implementation explicitly.
MSBuild-backed Raven projects
The workspace can now load Raven projects from ordinary MSBuild project files when they declare Raven sources through RavenCompile.
Example:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
<RavenCompile Include="src/**/*.rvn" />
<ProjectReference Include="..\Lib\Lib.csproj" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
Current behavior:
RavenWorkspace.OpenProject(...)can open that project throughMsBuildProjectSystemService.TargetFramework,AssemblyName,OutputType,AllowUnsafe/AllowUnsafeBlocks, andAllowGlobalStatementsare mapped into Raven project state.ProjectReferencepaths are surfaced through the project-system abstraction so callers such as the language server can recurse without knowing the concrete project-file format.- Referenced Raven MSBuild projects become workspace project references when they are loaded.
- Referenced non-Raven MSBuild projects are consumed as metadata references when their evaluated
TargetPathalready exists on disk.
Current behavior also includes save support for Raven-owned MSBuild state (RavenCompile, mapped Raven properties, and on-disk Raven source files) while preserving unrelated MSBuild items.
Scaffolding with rvn init
rvn init creates a starter layout in the current directory:
<ProjectName>.rvnprojsrc/main.rvnbin/.gitkeep
Options:
--name <project-name>: set explicit project/assembly name.--framework <tfm>: setTargetFrameworkin the generated.rvnproj.console|classlib: select the scaffold type (consoledefault).--type <console|classlib>: compatibility alias for selecting the scaffold type.--force: overwrite scaffold files when they already exist.