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

Fix the mono runtime test config #958

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ markdown = ['dep:wit-bindgen-markdown']
teavm-java = ['dep:wit-bindgen-teavm-java']
go = ['dep:wit-bindgen-go']
csharp = ['dep:wit-bindgen-csharp']
csharp-mono = ['csharp']
csharp-mono = ['dep:wit-bindgen-csharp']
moonbit = ['dep:wit-bindgen-moonbit']

[dev-dependencies]
Expand Down
21 changes: 12 additions & 9 deletions crates/csharp/src/csproj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ impl CSProjectLLVMBuilder {
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
<add key="dotnet9" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v3/index.json" />
<add key="dotnet-experimental" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json" />
<!--<add key="dotnet-experimental" value="C:\github\runtimelab\artifacts\packages\Debug\Shipping" />-->
</packageSources>
Expand Down Expand Up @@ -161,23 +162,20 @@ impl CSProjectMonoBuilder {
let camel = format!("{}World", world.to_upper_camel_case());

let aot = self.aot;

let maybe_aot = match aot {
true => format!("<WasmBuildNative>{aot}</WasmBuildNative>"),
false => String::new(),
};
let tfm = "net9.0";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move to Net10 ?
Because we are not going to backport fixes to Net9, right ?
One more below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there won't be a working net10 sdk for a while unfortunately


let mut csproj = format!(
"<Project Sdk=\"Microsoft.NET.Sdk\">
"<Project Sdk=\"Microsoft.NET.Sdk.WebAssembly\">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>{tfm}</TargetFramework>
<RuntimeIdentifier>wasi-wasm</RuntimeIdentifier>
<OutputType>Library</OutputType>
{maybe_aot}
<RunAOTCompilation>{aot}</RunAOTCompilation>
<WasmNativeStrip>false</WasmNativeStrip>
<WasmSingleFileBundle>true</WasmSingleFileBundle>
<WasmGenerateAppBundle>true</WasmGenerateAppBundle>
<WasmBuildNative>true</WasmBuildNative>
<RootNamespace>{name}</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand All @@ -190,9 +188,14 @@ impl CSProjectMonoBuilder {
</PropertyGroup>

<ItemGroup>
<NativeFileReference Include=\"{camel}_component_type.o\" Condition=\"Exists('{camel}_component_type.o')\"/>
<_WasiLinkStepArgs Include=\"-Wl,--component-type,{camel}_component_type.wit\" />
</ItemGroup>

<Target Name=\"_FixRootAssembly\" AfterTargets=\"PrepareForILLink\">
<ItemGroup>
<TrimmerRootAssembly Update=\"@(TrimmerRootAssembly)\" Condition=\" '%(RootMode)' == 'EntryPoint' \" RootMode=\"Library\" />
</ItemGroup>
</Target>
"
);

Expand Down
16 changes: 0 additions & 16 deletions crates/csharp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,22 +690,6 @@ impl WorldGenerator for CSharp {
}

if !self.opts.skip_support_files {
//TODO: This is currently needed for mono even if it's built as a library.
if self.opts.runtime == CSharpRuntime::Mono {
files.push(
&format!("MonoEntrypoint.cs",),
indent(&format!(
r#"
{access} class MonoEntrypoint() {{
{access} static void Main() {{
}}
}}
"#
))
.as_bytes(),
);
}

// For the time being, we generate both a .wit file and a .o file to
// represent the component type. Newer releases of the .NET runtime
// will be able to use the former, but older ones will need the
Expand Down
82 changes: 12 additions & 70 deletions tests/runtime/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ fn tests(name: &str, dir_name: &str) -> Result<Vec<PathBuf>> {
let (resolve, world) = resolve_wit_dir(&dir);
for path in c_sharp.iter() {
let world_name = &resolve.worlds[world].name;
let out_dir = out_dir.join(format!("csharp-{}", world_name));
let out_dir = out_dir.join(format!("csharp-mono-{}", world_name));
drop(fs::remove_dir_all(&out_dir));
fs::create_dir_all(&out_dir).unwrap();

Expand Down Expand Up @@ -540,7 +540,7 @@ fn tests(name: &str, dir_name: &str) -> Result<Vec<PathBuf>> {
fs::write(dst, contents).unwrap();
}

let mut csproj = wit_bindgen_csharp::CSProject::new_mono(
let csproj = wit_bindgen_csharp::CSProject::new_mono(
out_dir.clone(),
&assembly_name,
world_name,
Expand All @@ -553,6 +553,7 @@ fn tests(name: &str, dir_name: &str) -> Result<Vec<PathBuf>> {
csproj.generate()?;

let dotnet_root_env = "DOTNET_ROOT";
let configuration = "Debug";
let dotnet_cmd: PathBuf;
match env::var(dotnet_root_env) {
Ok(val) => dotnet_cmd = Path::new(&val).join("dotnet"),
Expand All @@ -563,10 +564,10 @@ fn tests(name: &str, dir_name: &str) -> Result<Vec<PathBuf>> {

cmd.current_dir(&out_dir);

cmd.arg("build")
cmd.arg("publish")
.arg(out_dir.join(format!("{camel}.csproj")))
.arg("-c")
.arg("Debug")
.arg(configuration)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.arg(configuration)
.arg(configuration)
.arg("-bl:publish-mono.binlog")

.arg("/p:PlatformTarget=AnyCPU")
.arg("--self-contained")
Copy link

@pavelsavara pavelsavara Sep 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for me --self-contained doesn't' work with 9.0.100-preview.6.24328.19 without workload. The publish doesn't fail but the file is located elsewhere and it's not single file.

After I install workload Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk version 9.0.0-preview.6.24327.7 I get

FooWorld failed with 4 error(s) (11.4s) → xxx\
    wasm-ld : error : unknown argument: --component-type
    wasm-ld : error : unknown file type: FooWorld_component_type.wit

Which makes sense for preview6.

With preview7 I get

    1: error while executing at wasm backtrace:
           0: 0x296a7b - .tmpJCkP17!fseek
           1: 0x8efe - .tmpJCkP17!load_icu_data
           2: 0x8ff4 - .tmpJCkP17!mono_wasm_load_runtime
           3: 0x9299 - .tmpJCkP17!initialize_runtime
           4: 0x92b8 - .tmpJCkP17!main
           5: 0x28bc5c - .tmpJCkP17!__main_void
           6: 0x7e78 - .tmpJCkP17!_start
           7: 0xb40aff - wit-component:adapter:wasi_snapshot_preview1!wasi:cli/run@0.2.0#run

Which means <WasmSingleFileBundle>true</WasmSingleFileBundle> didn't work.

Copy link
Contributor Author

@lewing lewing Sep 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nothing about this will work without the workload, I'm testing against daily builds of 9

using https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script
and dotnet-install -c 9.0 -q daily

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to add <WasmBuildNative>true</WasmBuildNative> to get it to produce a single file

.arg("-o")
Expand All @@ -586,75 +587,16 @@ fn tests(name: &str, dir_name: &str) -> Result<Vec<PathBuf>> {
panic!("failed to compile");
}

let out_wasm = out_wasm.join("AppBundle").join(assembly_name);
let out_wasm = out_dir
.join("bin")
.join(configuration)
.join("net9.0")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tmf

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is only one of the issues here, build doesn't respect the project name, and the publish doesn't respect the output directory. @maraf we should discuss what options we have here

.join("AppBundle")
.join(assembly_name);
let mut wasm_filename = out_wasm.clone();
wasm_filename.set_extension("wasm");

let module = fs::read(&wasm_filename).with_context(|| {
format!("failed to read wasm file: {}", wasm_filename.display())
})?;

// Translate the canonical ABI module into a component.
let component_type_filename = out_dir.join(format!("{camel}_component_type.o"));
let component_type = fs::read(&component_type_filename).with_context(|| {
format!(
"failed to read component type file: {}",
component_type_filename.display()
)
})?;

let mut new_module = wasm_encoder::Module::new();

for payload in wasmparser::Parser::new(0).parse_all(&module) {
let payload = payload.unwrap();
match payload {
_ => {
if let Some((id, range)) = payload.as_section() {
new_module.section(&wasm_encoder::RawSection {
id,
data: &module[range],
});
}
}
}
}

for payload in wasmparser::Parser::new(0).parse_all(&component_type) {
let payload = payload.unwrap();
match payload {
wasmparser::Payload::CustomSection(_) => {
if let Some((id, range)) = payload.as_section() {
new_module.section(&wasm_encoder::RawSection {
id,
data: &component_type[range],
});
}
}
_ => {
continue;
}
}
}

let module = new_module.finish();

let component = ComponentEncoder::default()
.module(&module)
.expect("pull custom sections from module")
.validate(true)
.adapter("wasi_snapshot_preview1", &wasi_adapter)
.expect("adapter failed to get loaded")
.realloc_via_memory_grow(true)
.encode()
.expect(&format!(
"module {:?} can be translated to a component",
out_wasm
));
let component_path = out_wasm.with_extension("component.wasm");
println!("COMPONENT WASM File name: {}", component_path.display());
fs::write(&component_path, component).expect("write component to disk");

result.push(component_path);
result.push(wasm_filename);
}
}

Expand Down
Loading