Skip to content

Conversation

@DoubleCouponDay
Copy link

@DoubleCouponDay DoubleCouponDay commented Dec 20, 2025

Based on a previous discussion regarding Windows development, I was able to compile the Rusty project natively on windows by using mingw as the implementation of the CC linker.

To progress the experience of our Windows users further, I've exposed stdlib as an artifact in the Windows build pipeline. This will allow them to quickly link with the Standard Library, in feature parity with the Linux Pipeline.

@ghaith Hello. How do I request a review?

@DoubleCouponDay DoubleCouponDay changed the title stdlib artifact uploads for Windows stdlib Artifact Uploads for Windows Dec 21, 2025
@ghaith ghaith self-requested a review December 21, 2025 19:57
@ghaith
Copy link
Collaborator

ghaith commented Dec 21, 2025

Looks like this would work, i started the workflow but i currently don't have access to a windows pc to check the artifact on, so this will have to wait until after new year unless @mhasel , @volsa or @Angus-Bethke-Bachmann are available to test it this week.

Copy link
Collaborator

@ghaith ghaith left a comment

Choose a reason for hiding this comment

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

I just realized the artifact might be missing some parts of the standard lib because of hwo it gets compiled, you probably need to test this.

run: cargo test integration -- --nocapture --test-threads=1

- name: Release Build
run: cargo build --release --workspace
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm suspecting the build might not work because part of the std lib is written in ST, which means you will also need to compile the st part of the lib and link the dlls together. Check the package command in scripts/build.sh to see how we do this on linux

Copy link
Author

@DoubleCouponDay DoubleCouponDay Dec 22, 2025

Choose a reason for hiding this comment

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

I compiled the library from source and simple symbols such as SQRT can be found but not complex ones, such as REAL_TO_DINT.

The lib/stdlib/build.rs script appears to compile the structured text and link it to the rust part. Why does this require build.sh? From what I understand from the source code, the shell script will copy all the structured text files into the output directory's include folder, before invoking clang.

PS C:\Users\sjsui\Desktop\workshop\stickle> plc ./examples/stdlib_usage.st --linker=cc --target=x86_64-windows-msvc -L C:\Users\sjsui\AppData\Local\rustycompiler -l iec61131std  --shared -o ./compiled/libstdlib_usage.dll
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\sjsui\AppData\Local\Temp\.tmpaK5vlz\x86_64-windows-msvc\x86_64-windows-msvc\Users\sjsui\Desktop\workshop\stickle\examples\stdlib_usage.st.o:stdlib_usage.st:(.text+0x17): undefined reference to `REAL_TO_DINT'
collect2.exe: error: ld returned 1 exit status
An error occurred during linking: An error occured during linking.
Hint: You can use `plc explain <ErrorCode>` for more information

Copy link
Collaborator

Choose a reason for hiding this comment

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

for some reason the build script does not end up linking in the ST code as expected.
This only is a problem on the shared library.
Which is why we call the package std which calls the linker again here :

create_shared_library "$cc" "$lib_dir" "$val"

The function called simply converts the static library with the correct symbols into a shared library, the key command here is -Wl,whole-archive for the standard lib. https://github.com/PLC-lang/rusty/blob/50825be581ec3457208582ab95e8b932a0a66c45/scripts/build.sh#L212C10-L212C23

This comment has more context

//We can link against the st lib gernerated, but this will only be reflected in static libs.

it might be working by now it might be worth a try

Copy link
Collaborator

Choose a reason for hiding this comment

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

rust-lang/rust#99429 it would seem support for this has been added. I'll try to see if the linux build behaves as expected in the comming days and we then we probably won't need the script for that anymore

@DoubleCouponDay
Copy link
Author

DoubleCouponDay commented Dec 22, 2025

With DLL generation put to the side for a moment, I've found that static linking with the generated LIB displays a number of errors on Windows. I used the linker=cc.exe argument to bypass windows blocking and I used the --target=x86_64-pc-windows-gnu argument in hopes of utilising all of mingw's functionality. I think it's missing a few DLL libraries as references, so tomorrow I'll try adding another -L argument with the required symbols.

log.txt

@DoubleCouponDay DoubleCouponDay marked this pull request as draft December 22, 2025 18:48
@DoubleCouponDay
Copy link
Author

DoubleCouponDay commented Dec 23, 2025

@ghaith I compiled stdlib using the build script line println!("cargo:rustc-link-lib=static:+whole-archive=st"); but it didn't modify the DLL artifact correctly. Instead, I continued progressing by static linking with the LIB artifact. Setting clang as the linker when using plc.exe helped me progress linking with stdlib, on native Windows, while using the REAL_TO_DINT function. There were quite a few win32 apis that needed to be linked though:

plc ./examples/clampandsaw.st --linker=clang --target=x86_64-windows-msvc --shared -L C:/Users/sjsui/AppData/local/rustycompiler -l iec61131std -l ws2_32 -l ntdll -l userenv -o ./compiled/libclampandsaw.dll

My next problem is that usage of clang isn't exporting an entrypoint symbol into the header of the DLL. When I use mingw it succeeds but mingw is incompatible with stdlib. The linker used when compiling stdlib and compiling user code must be clang.

PS C:\Users\sjsui\Desktop\workshop\stickle> plc ./examples/hello_world.st --linker=cc --target=x86_64-windows-msvc --shared -o ./compiled/mingw-hello_world.dll                                                                                               
PS C:\Users\sjsui\Desktop\workshop\stickle> dumpbin /exports ./compiled/mingw-hello_world.dll
Microsoft (R) COFF/PE Dumper Version 14.43.34810.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file .\compiled\mingw-hello_world.dll

File Type: DLL

  Section contains the following exports for mingw-hello_world.dll

    00000000 characteristics
    6949DAD9 time date stamp Tue Dec 23 12:57:13 2025
        0.00 version
           1 ordinal base
           2 number of functions
           2 number of names

    ordinal hint RVA      name

          1    0 00001370 __init___hello_world_st
          2    1 00001380 main

  Summary

        1000 .CRT
        1000 .bss
        1000 .data
        2000 .debug_abbrev
        1000 .debug_aranges
        1000 .debug_frame
        8000 .debug_info
        2000 .debug_line
        2000 .debug_line_str
        2000 .debug_loclists
        1000 .debug_rnglists
        1000 .debug_str
        1000 .edata
        1000 .idata
        1000 .pdata
        1000 .rdata
        1000 .reloc
        2000 .text
        1000 .tls
        1000 .xdata
PS C:\Users\sjsui\Desktop\workshop\stickle> plc ./examples/hello_world.st --linker=clang --target=x86_64-windows-msvc --shared -o ./compiled/clang-hello_world.dll
PS C:\Users\sjsui\Desktop\workshop\stickle> dumpbin /exports ./compiled/clang-hello_world.dll
Microsoft (R) COFF/PE Dumper Version 14.43.34810.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file .\compiled\clang-hello_world.dll

File Type: DLL

  Summary

        2000 .data
        1000 .fptable
        1000 .pdata
        A000 .rdata
        1000 .reloc
        E000 .text

@DoubleCouponDay
Copy link
Author

I got exported functions with clang by attaching an exports.def file to the compilation. I also split the .o generation from the .dll generation to have better control of the llvm compilation step. Simple and Complex stdlib functions are now linking with a C# unit test natively on windows! ✅

Here's the working example if anyone wants to try windows development.

plc ./examples/clampandsaw.st -c -l iec61131std -l ws2_32 -l ntdll -l userenv -o ./compiled/libclampandsaw.o

clang ./compiled/libclampandsaw.o --shared -l iec61131std -l ws2_32 -l ntdll -l userenv -fuse-ld=lld-link "-Wl,/DEF:exports.def" -o ./compiled/libclampandsaw.dll
image

@DoubleCouponDay DoubleCouponDay marked this pull request as ready for review December 24, 2025 06:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants