From d1e358d412a2659318815d01725a45fbea0e6718 Mon Sep 17 00:00:00 2001 From: Doublecouponday Date: Sun, 21 Dec 2025 10:08:06 +1300 Subject: [PATCH 01/11] draft: stdlib artifact uploads for windows --- .github/workflows/windows.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index cc652de9fe9..9197dac472e 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -48,3 +48,12 @@ jobs: name: plc.exe path: target/release/plc.exe + - uses: actions/upload-artifact@master + with: + name: stdlib.dll + path: target/release/iec61131std.dll + + - uses: actions/upload-artifact@master + with: + name: stdlib.lib + path: target/release/iec61131std.lib From 4a2d85781c397e537daaf787081581d071315bdd Mon Sep 17 00:00:00 2001 From: Samuel Jenks Date: Mon, 22 Dec 2025 14:08:44 +1300 Subject: [PATCH 02/11] chore: spelling in docs --- book/src/arch/architecture.md | 2 +- libs/stdlib/build.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/arch/architecture.md b/book/src/arch/architecture.md index 225eebda1a6..a47e816f050 100644 --- a/book/src/arch/architecture.md +++ b/book/src/arch/architecture.md @@ -3,7 +3,7 @@ ## Overview RuSTy is a compiler for IEC61131-3 languages. At the moment, ST and CFC ("FBD") are supported. -It utilizes the LLVM compiler infrastructurue and contributes a [Structured Text](https://en.wikipedia.org/wiki/Structured_text) frontend that translates Structured Text into LLVM's language independent intermediate representation (IR). +It utilizes the LLVM compiler infrastructure and contributes a [Structured Text](https://en.wikipedia.org/wiki/Structured_text) frontend that translates Structured Text into LLVM's language independent intermediate representation (IR). [CFC](../cfc/cfc.md) uses a M2M-transformation and reuses most of the ST frontend for compilation. The further optimization and native code generation is performed by the existing LLVM infrastructure, namely LLVM's common optimizer and the platform specific backend (see [here](https://www.aosabook.org/en/llvm.html)). diff --git a/libs/stdlib/build.rs b/libs/stdlib/build.rs index 45ad1d9cefe..5f96c98f958 100644 --- a/libs/stdlib/build.rs +++ b/libs/stdlib/build.rs @@ -37,7 +37,7 @@ fn main() { println!("cargo:rustc-link-lib=static=st"); println!("cargo:rerun-if-changed=iec61131-st/"); - //We can link against the st lib gernerated, but this will only be reflected in static libs. + //We can link against the st lib generated, but this will only be reflected in static libs. // The shared lib still has to be generated later. // There is a planned feature in rust to allow whole-archive linking, but i could not get it to // work (should look something like this : `println!("cargo:rustc-flags=-l static:+whole-archive=st");`) From f5b37f64d45187f29729b1fb60afe129f3b2e01a Mon Sep 17 00:00:00 2001 From: Samuel Jenks Date: Tue, 23 Dec 2025 13:09:38 +1300 Subject: [PATCH 03/11] test: whole archive static lib output --- libs/stdlib/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/stdlib/build.rs b/libs/stdlib/build.rs index 5f96c98f958..edf9fb19e65 100644 --- a/libs/stdlib/build.rs +++ b/libs/stdlib/build.rs @@ -34,8 +34,8 @@ fn main() { //link the object file println!("cargo:rustc-link-search=native={out_dir}"); - println!("cargo:rustc-link-lib=static=st"); println!("cargo:rerun-if-changed=iec61131-st/"); + println!("cargo:rustc-link-lib=static:+whole-archive=st"); //create a whole archive without throwing away any object files (https://github.com/rust-lang/rust/pull/105601). //We can link against the st lib generated, but this will only be reflected in static libs. // The shared lib still has to be generated later. From 4f1ce71a6aae4b1d637be1467c945082469b622b Mon Sep 17 00:00:00 2001 From: Samuel Jenks Date: Tue, 23 Dec 2025 17:51:53 +1300 Subject: [PATCH 04/11] fix: formatting --- libs/stdlib/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/stdlib/build.rs b/libs/stdlib/build.rs index edf9fb19e65..ad47d277896 100644 --- a/libs/stdlib/build.rs +++ b/libs/stdlib/build.rs @@ -35,7 +35,7 @@ fn main() { //link the object file println!("cargo:rustc-link-search=native={out_dir}"); println!("cargo:rerun-if-changed=iec61131-st/"); - println!("cargo:rustc-link-lib=static:+whole-archive=st"); //create a whole archive without throwing away any object files (https://github.com/rust-lang/rust/pull/105601). + println!("cargo:rustc-link-lib=static:+whole-archive=st"); //create a whole archive without throwing away any object files (https://github.com/rust-lang/rust/pull/105601). //We can link against the st lib generated, but this will only be reflected in static libs. // The shared lib still has to be generated later. From cc4d997a80506c49e42dc44623fce5145a50a1a1 Mon Sep 17 00:00:00 2001 From: Samuel Jenks Date: Wed, 24 Dec 2025 19:51:12 +1300 Subject: [PATCH 05/11] chore: document windows usage example --- book/src/using_rusty.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/book/src/using_rusty.md b/book/src/using_rusty.md index 83fa8f68d19..213936049dc 100644 --- a/book/src/using_rusty.md +++ b/book/src/using_rusty.md @@ -161,4 +161,34 @@ int main() { return 0; } -``` \ No newline at end of file +``` + +## Native Windows Usage Example + +- Download `plc.zip` from the [Windows Build Pipeline](https://github.com/PLC-lang/rusty/actions/workflows/windows.yml). + + - Add it's location to the PATH environment variable. An AppData location is recommended. + +- Download `stdlib.lib` from the same pipeline and install it to the same folder. + +- Install the `Windows SDK` and `MSVC`. You can use the Visual Studio Installer to do this or install them as standalone packages. + +- Create a `LIB` environment variable containing paths to `iec61131std.lib`, `ws2_32.lib`, `ntdll.lib`, `userenv.lib`, `libcmt.lib`, `oldnames.lib` and `libucrt.lib`. + + - Your environment variable should look something like this: + + ``` + C:/Users//AppData/Local/rustycompiler; + C:\Program Files (x86)\Windows Kits\10\Lib\10.0.26100.0\um\x64; + C:\Program Files (x86)\Windows Kits\10\Lib\10.0.26100.0\ucrt\x64; + C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\lib\x64; + ``` + +- Restart your terminals to refresh the environment. + +- Proceed with compilation: + + ``` + plc ./examples/hello_world.st -c -l iec61131std -l ws2_32 -l ntdll -l userenv -o ./hello_world.o + clang ./hello_world.o --shared -l iec61131std -l ws2_32 -l ntdll -l userenv -fuse-ld=lld-link "-Wl,/DEF:exports.def" -o ./hello_world.dll + ``` From 06a3fb96c1e0caec9c1580cfaa0ef03fbc6e8858 Mon Sep 17 00:00:00 2001 From: Samuel Jenks Date: Wed, 24 Dec 2025 20:00:02 +1300 Subject: [PATCH 06/11] fix: missing documentation --- book/src/using_rusty.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/book/src/using_rusty.md b/book/src/using_rusty.md index 213936049dc..a69ec805561 100644 --- a/book/src/using_rusty.md +++ b/book/src/using_rusty.md @@ -165,6 +165,8 @@ int main() { ## Native Windows Usage Example +- Ensure [`LLVM 14.0.6`](https://github.com/PLC-lang/llvm-package-windows/releases/tag/v14.0.6) is installed and it's `bin` folder is added to your `PATH` environment variable. + - Download `plc.zip` from the [Windows Build Pipeline](https://github.com/PLC-lang/rusty/actions/workflows/windows.yml). - Add it's location to the PATH environment variable. An AppData location is recommended. @@ -186,6 +188,14 @@ int main() { - Restart your terminals to refresh the environment. +- Create an `exports.def` file in preparation `clang` usage. + +``` +EXPORTS + main + +``` + - Proceed with compilation: ``` From 8a83b5d50f751c0e037efa542162e4e5df79fa9c Mon Sep 17 00:00:00 2001 From: Samuel Jenks Date: Thu, 25 Dec 2025 07:46:16 +1300 Subject: [PATCH 07/11] chore: documentation --- book/src/using_rusty.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/book/src/using_rusty.md b/book/src/using_rusty.md index a69ec805561..5d1fbab95c1 100644 --- a/book/src/using_rusty.md +++ b/book/src/using_rusty.md @@ -167,11 +167,11 @@ int main() { - Ensure [`LLVM 14.0.6`](https://github.com/PLC-lang/llvm-package-windows/releases/tag/v14.0.6) is installed and it's `bin` folder is added to your `PATH` environment variable. -- Download `plc.zip` from the [Windows Build Pipeline](https://github.com/PLC-lang/rusty/actions/workflows/windows.yml). +- Install `plc.zip` from the [Windows Build Pipeline](https://github.com/PLC-lang/rusty/actions/workflows/windows.yml). - Add it's location to the PATH environment variable. An AppData location is recommended. -- Download `stdlib.lib` from the same pipeline and install it to the same folder. +- Install `stdlib.lib` from the same pipeline into the same folder. - Install the `Windows SDK` and `MSVC`. You can use the Visual Studio Installer to do this or install them as standalone packages. @@ -196,6 +196,8 @@ EXPORTS ``` +This example allows linking with Rusty's Standard Library. + - Proceed with compilation: ``` From 212108fb5b297e53f0c9e224ae096829c642aa7e Mon Sep 17 00:00:00 2001 From: Doublecouponday Date: Mon, 5 Jan 2026 09:32:11 +1300 Subject: [PATCH 08/11] step: allow linking with clang on windows --- src/linker.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/linker.rs b/src/linker.rs index 0d4bd065310..cca8cc4920c 100644 --- a/src/linker.rs +++ b/src/linker.rs @@ -46,12 +46,8 @@ impl Linker { return Err(LinkerError::Target(target.into())); }; match (platform, target_os) { - (_, "win32") | (_, "windows") | ("win32", _) | ("windows", _) => { - return Err(LinkerError::Target(target_os.into())) - } - + (_, "win32") | (_, "windows") | ("win32", _) | ("windows", _) => Box::new(CcLinker::new("clang")), //only clang from llvm is supported in windows (_, "darwin") => Box::new(CcLinker::new("clang")), - _ => Box::new(LdLinker::new()), } } From 30c78235c8218e92e3e24e178a560819da1bac76 Mon Sep 17 00:00:00 2001 From: Doublecouponday Date: Mon, 5 Jan 2026 14:29:21 +1300 Subject: [PATCH 09/11] fix: tests --- src/linker.rs | 4 ++-- ...ration__command_line_compile__ir_generation_full_pass.snap | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/linker.rs b/src/linker.rs index cca8cc4920c..0f465996565 100644 --- a/src/linker.rs +++ b/src/linker.rs @@ -286,7 +286,7 @@ mod test { use crate::linker::{Linker, LinkerType}; #[test] - fn windows_target_triple_should_result_in_error() { + fn windows_target_triple_should_result_in_ok() { for target in &[ "x86_64-pc-windows-gnu", "x86_64-pc-win32-gnu", @@ -301,7 +301,7 @@ mod test { "i686-windows-gnu", "i686-win32-gnu", ] { - assert!(Linker::new(target, LinkerType::Internal).is_err()); + assert!(Linker::new(target, LinkerType::Internal).is_ok()); } } diff --git a/tests/integration/snapshots/tests__integration__command_line_compile__ir_generation_full_pass.snap b/tests/integration/snapshots/tests__integration__command_line_compile__ir_generation_full_pass.snap index f151ac3254d..36fab44fb01 100644 --- a/tests/integration/snapshots/tests__integration__command_line_compile__ir_generation_full_pass.snap +++ b/tests/integration/snapshots/tests__integration__command_line_compile__ir_generation_full_pass.snap @@ -1,6 +1,6 @@ --- source: tests/integration/command_line_compile.rs +assertion_line: 26 expression: content -snapshot_kind: text --- -target datalayout = "[filtered]"@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* @__init___command_line_st, i8* null }]define void @__init___command_line_st() {entry: ret void}define i32 @myFunc(i32 %0, i32 %1, i32 %2) {entry: %myFunc = alloca i32, align 4 %a = alloca i32, align 4 store i32 %0, i32* %a, align 4 %b = alloca i32, align 4 store i32 %1, i32* %b, align 4 %c = alloca i32, align 4 store i32 %2, i32* %c, align 4 store i32 0, i32* %myFunc, align 4 %myFunc_ret = load i32, i32* %myFunc, align 4 ret i32 %myFunc_ret} +target datalayout = "[filtered]"@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* @__init___command_line_st, i8* null }]define i32 @myFunc(i32 %0, i32 %1, i32 %2) {entry: %myFunc = alloca i32, align 4 %a = alloca i32, align 4 store i32 %0, i32* %a, align 4 %b = alloca i32, align 4 store i32 %1, i32* %b, align 4 %c = alloca i32, align 4 store i32 %2, i32* %c, align 4 store i32 0, i32* %myFunc, align 4 %myFunc_ret = load i32, i32* %myFunc, align 4 ret i32 %myFunc_ret}define void @__init___command_line_st() {entry: ret void} From 75c5431f39dfbca94cad4ef2dc663783b4099c52 Mon Sep 17 00:00:00 2001 From: Samuel Jenks Date: Tue, 6 Jan 2026 06:18:28 +1300 Subject: [PATCH 10/11] revert: snapshot change (trying to fix pipelines) --- ...ration__command_line_compile__ir_generation_full_pass.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/snapshots/tests__integration__command_line_compile__ir_generation_full_pass.snap b/tests/integration/snapshots/tests__integration__command_line_compile__ir_generation_full_pass.snap index 36fab44fb01..f151ac3254d 100644 --- a/tests/integration/snapshots/tests__integration__command_line_compile__ir_generation_full_pass.snap +++ b/tests/integration/snapshots/tests__integration__command_line_compile__ir_generation_full_pass.snap @@ -1,6 +1,6 @@ --- source: tests/integration/command_line_compile.rs -assertion_line: 26 expression: content +snapshot_kind: text --- -target datalayout = "[filtered]"@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* @__init___command_line_st, i8* null }]define i32 @myFunc(i32 %0, i32 %1, i32 %2) {entry: %myFunc = alloca i32, align 4 %a = alloca i32, align 4 store i32 %0, i32* %a, align 4 %b = alloca i32, align 4 store i32 %1, i32* %b, align 4 %c = alloca i32, align 4 store i32 %2, i32* %c, align 4 store i32 0, i32* %myFunc, align 4 %myFunc_ret = load i32, i32* %myFunc, align 4 ret i32 %myFunc_ret}define void @__init___command_line_st() {entry: ret void} +target datalayout = "[filtered]"@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* @__init___command_line_st, i8* null }]define void @__init___command_line_st() {entry: ret void}define i32 @myFunc(i32 %0, i32 %1, i32 %2) {entry: %myFunc = alloca i32, align 4 %a = alloca i32, align 4 store i32 %0, i32* %a, align 4 %b = alloca i32, align 4 store i32 %1, i32* %b, align 4 %c = alloca i32, align 4 store i32 %2, i32* %c, align 4 store i32 0, i32* %myFunc, align 4 %myFunc_ret = load i32, i32* %myFunc, align 4 ret i32 %myFunc_ret} From ae0e1afa9c1df92b38f55c6bdedc4ad9840b57a0 Mon Sep 17 00:00:00 2001 From: Samuel Jenks Date: Tue, 6 Jan 2026 19:47:35 +1300 Subject: [PATCH 11/11] fix: formatting --- src/linker.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/linker.rs b/src/linker.rs index 0f465996565..a0906c1b742 100644 --- a/src/linker.rs +++ b/src/linker.rs @@ -46,7 +46,9 @@ impl Linker { return Err(LinkerError::Target(target.into())); }; match (platform, target_os) { - (_, "win32") | (_, "windows") | ("win32", _) | ("windows", _) => Box::new(CcLinker::new("clang")), //only clang from llvm is supported in windows + (_, "win32") | (_, "windows") | ("win32", _) | ("windows", _) => { + Box::new(CcLinker::new("clang")) + } //only clang from llvm is supported in windows (_, "darwin") => Box::new(CcLinker::new("clang")), _ => Box::new(LdLinker::new()), }