Skip to content

Support for cross-compiling on Linux#465

Draft
universeindex wants to merge 25 commits intosmartcmd:mainfrom
universeindex:main
Draft

Support for cross-compiling on Linux#465
universeindex wants to merge 25 commits intosmartcmd:mainfrom
universeindex:main

Conversation

@universeindex
Copy link

Description

I've implemented support for cross-compiling a Windows build on a Linux host using clang-cl. I added a toolchain file at cmake/LinuxCrosscompile.cmake that achieves this. I also modified many source files to not use backslashes in include statements (which error with clang-cl) and use case-sensitive paths (many Linux filesystems are case-sensitive, unlike NTFS, which causes errors). I avoided changing actual functionality as much as possible, so I hope this isn't too intrusive. Additionally I apologize for the messy commit messages, I hope this isn't a big issue, I have detailed all of the changes I made here.

Changes

Include statements use forward slashes instead of backslashes
Include statements reference files with correct capitalization
Added a CMake toolchain file for using clang-cl on Linux
Minecraft.Client/Xbox/MinecraftWindows.rc is not compiled on Linux, this causes errors otherwise, as it can't find the windows SDK and I am unsure how to specify the location here.
I also added documentation for building on Linux.

Previous Behavior

Running CMake on Linux would throw a hardcoded error stating that Linux isn't supported. When removed, and clang-cl is set to be used, many errors occur due to include paths using backslashes and inconsistent capitalization. The only way to build and run on Linux before is to use a Windows VM, and there is no way to get proper code completion on a Linux IDE.

Root Cause

Backslashes in include paths are supported on Windows, but not other systems, and NTFS is case-insensitive, so include paths do not have to match capitalization, also not on other systems.

New Behavior

The game now compiles and outputs a Windows binary on Linux using clang-cl.

Fix Implementation

See changes section

@universeindex
Copy link
Author

P.S. I tested building on Windows, which still works fine, so hopefully there shouldn't be any issues

@universeindex
Copy link
Author

Most commits made to upstream will probably conflict with those by overwriting the includes I changed back with backslashes, but I'll be fixing those until this is merged

@void2012
Copy link
Collaborator

void2012 commented Mar 4, 2026

Yes, I will be very happy to have clang-cl support and cross compilation support. Actually, clang-cl will be a test site for /fp:fast because it optimizes better than MSVC. Let me review this one.

@void2012
Copy link
Collaborator

void2012 commented Mar 4, 2026

Have you tested it compiling with MSVC? Both msbuild and cmake. I hope this doesn't break the MSVC compilation.

@universeindex
Copy link
Author

universeindex commented Mar 4, 2026

I tested CMake w/ visual studio generator on Windows (with MSVC) which worked fine, but I haven't tried the normal .sln yet. I can do that now, but it might be a minute, i'm working on a really slow machine currently

@universeindex
Copy link
Author

works fine, compiles and runs w/ visual studio build ^

@void2012
Copy link
Collaborator

void2012 commented Mar 4, 2026

Could you please tell, aside from #includes, what did you change? Reviewing that much files is pain.

@universeindex
Copy link
Author

I did rewrite Minecraft.Client/iob_shim.asm in C++ as IobShim.cpp because I couldn't get MASM to work under Linux, but that's it aside from the includes I believe.

@DwifteJB
Copy link

DwifteJB commented Mar 4, 2026

can confirm does compile on linux w/ cmake

well done :)

@void2012
Copy link
Collaborator

void2012 commented Mar 4, 2026

That asm file wasn't really an asm thing rather a MSVC linker hack and it appears we don't actually need that at all.

set(CMAKE_C_COMPILER_FRONTEND_VARIANT MSVC)
set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT MSVC)

add_compile_options(/winsysroot /opt/msvc --target=x86_64-pc-windows-msvc -fms-compatibility -fms-extensions -fdelayed-template-parsing)
Copy link

Choose a reason for hiding this comment

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

the cmake file assumes /opt/msvc whereas https://github.com/mstorsjo/msvc-wine recommends ~/my_msvc/opt/msvc

just a simple issue as you can syslink or run the msvc-wine installer as root & install to /opt/msvc

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

oh, good catch, i think i might set it to CMAKE_BINARY_DIR/msvc so users can symlink one instead, or if theres a way to set options of a toolchain file that would be best
will change soon, not home atm

Copy link

@DwifteJB DwifteJB Mar 4, 2026

Choose a reason for hiding this comment

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

msvc-wine sets itself in the path directory (although the user has to set this up manually through something like .zshrc)

could do something like

whereis msbuild

to determine the directory?

if it isn't set as CMAKE_MSVC_DIR

Copy link

Choose a reason for hiding this comment

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

opened pr on your fork that fixes this & a clang error universeindex#1

@void2012
Copy link
Collaborator

void2012 commented Mar 4, 2026

I think __iob_func should be implemented as __declspec(naked) + __asm.

@DwifteJB
Copy link

DwifteJB commented Mar 4, 2026

I think __iob_func should be implemented as __declspec(naked) + __asm.

_declspec(naked) seems to not be working since __asm seems to have been dropped for x64 (if you want to use it you have to use a .asm file, like how 4J seems to have done it)

__attribute__((naked)) & __asm__() works however

@DwifteJB
Copy link

DwifteJB commented Mar 4, 2026

will need someone to test compiling on windows however

@void2012
Copy link
Collaborator

void2012 commented Mar 4, 2026

I think __iob_func should be implemented as __declspec(naked) + __asm.

_declspec(naked) seems to not be working since __asm seems to have been dropped for x64 (if you want to use it you have to use a .asm file, like how 4J seems to have done it)

__attribute__((naked)) & __asm__() works however

Forgot about it that, as I am used to x86 development. Uncool, Microsoft. Anyway, maybe conditionally use the .asm file for MSVC assembler and .cpp with [[__gnu__::__naked__]] for Clang-cl?

@DRAGONTOS
Copy link

i dont seem to be able to compile this
image

@universeindex
Copy link
Author

i've been trying for ages and I genuinely have no clue how to add a clang build option to msbuild, really sorry. it works fine in cmake but visual studio just isn't playing along. if someone else can figure it out thats great, but I give up

@void2012
Copy link
Collaborator

void2012 commented Mar 5, 2026

Install Clang-cl with visual studio installer, add new configuration for a project, call it ClangRelease, set the toolchain from v145 to Clang-cl

@universeindex
Copy link
Author

I get that, but my issue is that it's just not creating a new configuration. I select new and click ok then nothing happens, doesn't add the config at all
https://files.catbox.moe/ds1lvy.mp4

@niansa
Copy link

niansa commented Mar 6, 2026

You can just use this: https://github.com/mstorsjo/msvc-wine
To install MSVC to /opt/msvc:

sudo mkdir /opt/msvc
sudo chown -R $USER /opt/msvc
./vsdownload.py --dest /opt/msvc
./install.sh /opt/msvc

Then add it to PATH:

export PATH="/opt/msvc/bin/x64:$PATH"

And then you can just use the Toolchain file and everything should work perfectly. This also adds a working rc executable to PATH, etc.

@void2012
Copy link
Collaborator

void2012 commented Mar 6, 2026

Folks say msvc-wine doesn't work for them.

@DwifteJB
Copy link

DwifteJB commented Mar 6, 2026

You can just use this: https://github.com/mstorsjo/msvc-wine

To install MSVC to /opt/msvc:


sudo mkdir /opt/msvc

sudo chown -R $USER /opt/msvc

./vsdownload.py --dest /opt/msvc

./install.sh /opt/msvc

Then add it to PATH:


export PATH="/opt/msvc/bin/x64:$PATH"

And then you can just use the Toolchain file and everything should work perfectly. This also adds a working rc executable to PATH, etc.

... this is what this pull request is doing... 😭😭😭

@niansa
Copy link

niansa commented Mar 6, 2026

Huh? It's working perfectly fine for me. This is exactly how I got this to work on my system.

@DwifteJB
Copy link

DwifteJB commented Mar 6, 2026

Folks say msvc-wine doesn't work for them.

they need lld installed which should probably be mentioned

@niansa
Copy link

niansa commented Mar 6, 2026

... this is what this pull request is doing... 😭😭😭

Is there a script included that already does this? If so then ignore me I guess lol
I just saw people discussing llvm-rc which isn't actually needed if done this way.

@DwifteJB
Copy link

DwifteJB commented Mar 6, 2026

that's the issue i had at the very least before it started working, an ambiguous error due to no lld linker

@niansa
Copy link

niansa commented Mar 6, 2026

they need lld installed which should probably be mentioned

Yes lld is needed.

Let me just create a fresh Debian Trixie Distrobox to figure out everything that is required.

@DwifteJB
Copy link

DwifteJB commented Mar 6, 2026

... this is what this pull request is doing... 😭😭😭

Is there a script included that already does this? If so then ignore me I guess lol

I just saw people discussing llvm-rc which isn't actually needed if done this way.

there's no script to install but it's mentioned in compile.md within the project, might be a good idea to use something like docker / nix so we can containerise the actual building so it works no matter what system (macos, linux, windows, etc)

@DwifteJB
Copy link

DwifteJB commented Mar 6, 2026

they need lld installed which should probably be mentioned

Yes lld is needed.

Let me just create a fresh Debian Trixie Distrobox to figure out everything that is required.

i tested with arch, all that's required is base-devel, cmake, gcc, ninja & lld from my knowledge (and obviously msvc-wine & wine)

@niansa
Copy link

niansa commented Mar 6, 2026

Alright I'll put together a Dockerfile real quick then.

@niansa
Copy link

niansa commented Mar 6, 2026

There are Dockerfiles already in the repo lol

Either way in case anyone can use it, here's a script I wrote for testing purposes:

# Fresh Debian Trixie install

dpkg --add-architecture i386
apt update
apt install wine wine32 wine64 msitools git python3 cmake ninja-build lld-19 llvm-19 clang-19

DISPLAY= wineboot

# MSVC install
(
    git clone https://github.com/mstorsjo/msvc-wine.git
    cd msvc-wine
    git checkout 32b504c63b869681cda6824a20e30b74cb718432

    mkdir /opt/msvc
    ./vsdownload.py --dest /opt/msvc --accept-license
    ./install.sh /opt/msvc

    ln -s /usr/bin/clang-cl{-19,}
    ln -s /usr/bin/lld-link{-19,}
)

# MSVC setup
export PATH="/opt/msvc/bin/x64:$PATH"

# Project build
(
    git clone https://github.com/universeindex/MinecraftConsoles.git --depth 1 --recursive
    cd MinecraftConsoles
    mkdir build
    cd build
    cmake .. -GNinja -DCMAKE_TOOLCHAIN_FILE=../cmake/LinuxCrosscompile.cmake
    ninja
)

@niansa
Copy link

niansa commented Mar 6, 2026

I might try to get this to build using clang-cl with mingw 🤔
That would avoid a LOT of complications but probably introduces other complications on the way

@universeindex
Copy link
Author

tried this, but i started to get many more strange errors, i think lce depends on msvc specific stdlib stuff
i think this system works fine, we just need to add clang-cl into the visual studio build and then this pr is done (hopefully)
later i could add scripts to automatically download the msvc toolchain, but due to the eula it would have to download the official packages and extract those, which requires the msitools package

@niansa
Copy link

niansa commented Mar 6, 2026

Yeah, fuck this codebase lol... using backslashes in include paths is already insane enough
Depending on MSVC sucks, but the quality... who the HECK thought it'd be a good idea to using namespace std; in every single header file??

@universeindex
Copy link
Author

God only knows

@BlueishSapphire
Copy link

Would it be reasonable to split this into multiple PRs? Converting backslashes to forward slashes and fixing the casing issues in #includes would be easy to split off into a new PR and merge it right now. It would also make developing on HEAD on linux a lot easier in the meantime while the rest of this PR is still being developed.

@universeindex
Copy link
Author

good idea actually, didnt think of that
not sure how i would go about that now that all my changes are mangled together though.. probably I'll make a new branch on my fork and start from scratch, i used scripts to do the conversion anyways so it shouldn't be that hard
I'm not home now but i can gladly do that over the weekend, thanks for the idea

@void2012
Copy link
Collaborator

void2012 commented Mar 6, 2026

Okay, screw the Visual Studio solution file, I can't add new configuration either. Let's add clang-cl as cmake only for now. Resolve the branch conflicts and imma merge this one.

@universeindex
Copy link
Author

We love microslop <3
I'll see if i can fix merge conflicts soon but I am still a little busy at school right now, so sorry if it takes a few hours

@BlueishSapphire
Copy link

I can make a new branch and PR with the #include changes, I'll just have to run a couple sed scripts

@universeindex
Copy link
Author

looks like void is ready to merge this existing one once i fix up merge conflicts though, so maybe not, sorry

@DRAGONTOS
Copy link

    ninja

this script made me possible to also compile this :3

@AE70
Copy link

AE70 commented Mar 6, 2026

Since there's no updates, I fixed the conflicts and got this to work in one of the latest commit of upstream and can merge automatically as of speaking, PR the PR? https://github.com/AE70/MinecraftConsoles/tree/pr465 .

@DRAGONTOS
Copy link

Since there's no updates, I fixed the conflicts and got this to work in one of the latest commit of upstream and can merge automatically as of speaking, PR the PR? https://github.com/AE70/MinecraftConsoles/tree/pr465 .

it doesnt seem to have audio but that could be a upstream issue

@AE70
Copy link

AE70 commented Mar 6, 2026

it doesnt seem to have audio but that could be a upstream issue

not upstream issue, need to fix that.

@universeindex
Copy link
Author

was it one of my commits that broke audio? i never touched that, last i checked it was working, weird

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.

7 participants