-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Support Windows as a first class platform (note: not WSL or emulation) #26
Comments
Hi, Thank you for your interest in Crystal! Yes, it would be awesome to have Crystal running on Windows. I don't think there is much to do on LLVM side to make it work, except having the necessary libraries to link to. I read this the other day, it might be useful: http://www.phoronix.com/scan.php?page=news_item&px=MTQ1NjI If you want to contribute, I think the path is the following:
Any doubts you have about how the compiler works, we can answer and help you :-) Regards, |
Thanks, Ary! I will give it a shot.
|
I forgot to mention there are thousands of specs, so if you manage to pass Lexer, parser, normalization and type inference specs, except those
|
I apologize for forgetting to follow up on this. I was able to compile LLVM on Windows (that was a "fun" task in itself) but failed to get ruby-llvm working with it and eventually gave up (for now). The website says that the Crystal compiler is now written in Crystal itself. Does that carry any implications as to how one might get it running on Windows? Do you think a better pursuit would be to make Crystal cross-compile (compile on Linux, run on Windows)? |
Well, if you get cross-compilation to work that would indeed be awesome and very, very useful. If you are on Mac or Linux you can download a preocmpiled compiler that will let you compile new versions of the compiler. Since such compiler doesn't exist for Windows, you will need to create one, but I'm not sure how. There are the options:
Maybe you can tell us what problem you had with ruby-llvm on Windows. If you make that work, point 1 would be the easiest, I think. Thanks! |
ruby-llvm says it requires LLVM built with shared library enabled. However, the LLVM CMake doc says "Shared libraries are not supported on Windows and not recommended in the other OSes." I don't know whether "not supported" means it's not possible, so I'll try rebuilding LLVM and find out. |
Here is what happens when I try to install ruby-llvm:
Any ideas? Windows 7 64-bit |
Hello, I've been watching the development of Crystal for a while now, and I've become interested in possibly contributing to the ecosystem. I'm posting in this issue because Windows support is integral to my adoption of the language. I work on both Windows and Linux and need all of my tools to work on both. I'll be busy for the next couple of weeks, but I should have some free time toward the end of the month. I'd like to try and get Crystal compiling on Windows if possible. Is this information up to date? Judging by some of the recent blog posts, it seems out of date. |
Hi @Kelet, First, thanks for wanting to help in the development of Crystal! My last comment is still up-to-date, I think. But now I think the best thing to do is to cross-compile from mac/linux to Windows. We can start by making a very simple "Hello World" and try to run it on Windows. This will be the program: # file: hello.cr
lib C
fun puts(str : UInt8*) : Int32
end
class String
def cstr
pointerof(@c)
end
end
C.puts "Hello World!" We will compile it like this:
The "--prelude=empty" tells the compiler to not include the file prelude.cr and instead use empty.cr. This just defines the main function, which will contain whatever is in your program. The "--single-module" just makes it generate a single LLVM module, otherwise it generates one per class/module. So this way is simpler. Then we bind to the C function puts, which I don't know if it exists in Windows. If not, it should be replaced by another one provided by Windows that does that (I don't know much about Windows, it seems it does exist) Then the String#cstr method just gets a pointer to the first character in the String. This method is used to implicitly convert a String to UInt8* by the compiler (I guess that method should be built-in so we don't have to do this...). But it's not a big deal anyway. Then if you run it like this:
you will see the generated LLVM code: ; ModuleID = 'main_module'
%String = type { i32, i32, i8 }
@symbol_table = global [0 x %String*] zeroinitializer
@str = private constant { i32, i32, [13 x i8] } { i32 1, i32 12, [13 x i8] c"Hello World!\00" }
define i32 @__crystal_main(i32 %argc, i8** %argv) {
alloca:
br label %const
const: ; preds = %alloca
br label %entry
entry: ; preds = %const
%0 = call i8* @"*String#cstr<String>:UInt8*"(%String* bitcast ({ i32, i32, [13 x i8] }* @str to %String*))
%1 = call i32 @puts(i8* %0)
ret i32 %1
}
define i32 @main(i32 %argc, i8** %argv) {
alloca:
%argc1 = alloca i32
%argv2 = alloca i8**
br label %entry
entry: ; preds = %alloca
store i32 %argc, i32* %argc1
store i8** %argv, i8*** %argv2
%0 = load i32* %argc1
%1 = load i8*** %argv2
%2 = call i32 @__crystal_main(i32 %0, i8** %1)
ret i32 0
}
define internal i8* @"*String#cstr<String>:UInt8*"(%String* %self) {
alloca:
br label %entry
entry: ; preds = %alloca
%0 = getelementptr %String* %self, i32 0, i32 2
ret i8* %0
}
declare i32 @puts(i8*) We can get that LLVM code, put it in a file "hello.ll" in Windows and try to compile it:
Of course these last commands are in linux/mac, for Windows it will be similar. We are using LLVM 3.3 so the commands might be named like llc-3.3, clang-3.3 and so on. I don't know if in Windows the main function is just "int main(int argc, char** argv)" or you always need to use WinMain (I think that's for graphical stuff). There's a simple way to do all of the above: we use the --cross-compile flag:
This will genreate a hello.bc file (similar to ll file, but binary). The last command will also print this:
So you copy the "hello.bc" file to Windows and executing that command should generate an executable. The "windows" part passed to the --cross-compile flag just passes "windows" as a flag to the compiler so when you use If you manage to compile a Crystal program in linux/mac, copy the ll/bc file to Windows, compile it in Windows, execute it and get "Hello World!" in the conosle, we'll be a bit closer to having a compiler in Windows :-) The next steps would be trying to compile bigger programs until we reach the program that is the compiler itself :-P If you make some progress with the above, please let us know and we can continue trying to make it work. Again, thanks for your help! |
Excellent, I'll try this process when I find some time and report back to you! |
I tried it out real quick:
hello.s .def @feat.00;
.scl 3;
.type 0;
.endef
.globl @feat.00
@feat.00 = 1
.def ___crystal_main;
.scl 2;
.type 32;
.endef
.text
.globl ___crystal_main
.align 16, 0x90
___crystal_main: # @__crystal_main
# BB#0: # %entry
pushl %eax
movl $L_str, (%esp)
calll "_*String#cstr<String>:UInt8*"
movl %eax, (%esp)
calll _puts
popl %edx
ret
.def _main;
.scl 2;
.type 32;
.endef
.globl _main
.align 16, 0x90
_main: # @main
# BB#0: # %alloca
subl $16, %esp
movl 24(%esp), %eax
movl 20(%esp), %ecx
movl %ecx, 12(%esp)
movl %eax, 8(%esp)
movl 12(%esp), %ecx
movl %eax, 4(%esp)
movl %ecx, (%esp)
calll ___crystal_main
xorl %eax, %eax
addl $16, %esp
ret
.def "_*String#cstr<String>:UInt8*";
.scl 3;
.type 32;
.endef
.align 16, 0x90
"_*String#cstr<String>:UInt8*": # @"*String#cstr<String>:UInt8*"
# BB#0: # %alloca
movl 4(%esp), %eax
addl $8, %eax
ret
.bss
.globl _symbol_table # @symbol_table
.align 4
_symbol_table:
.section .rdata,"r"
.align 16 # @str
L_str:
.long 1 # 0x1
.long 12 # 0xc
.asciz "Hello World!"
.zero 3 |
Cool! That's progress. It seems clang for windows doesn't like names like "_String#cstr:UInt8" for labels. What happens if you change:
to this:
in the hello.s file and try to execute |
Or maybe to:
(I see all .def in the file start with |
Both |
Awesome!! :-) So our first step is to have a different mangling for functions, at least for Windows. I'll think of something. I don't think replacing all non-alphanumeric characters to underscore will work, but it need to be thought a bit to avoid conflicts between definitions. I'll let you know when I do this. In the meantime you can try to do it. The method that mangles a name is here, just in case you wonder or want to try to change it too. |
@Kelet, can I ask you to try something else? What happens if you use |
Yep, it works. Dollar signs, periods, and underscores should work according to the manual. |
Any progress on this issue? Crystal looks like exactly the kind of language I'd like to begin using for new projects but the lack of Windows support is a dealbreaker for me - Windows is where you find paying customers and I can't be investing myself in something that locks me out of having an audience. |
@Flaise yeah I agree, I'd love to try this on windows. |
So, Trying to build the Windows branch using the instructions in: https://github.com/manastech/crystal/blob/windows/README_win32.md Step 1 produces:
|
Using @XWanderer fork from https://github.com/xwanderer/crystal/tree/win32
|
Just wanted to add my support to this. I really want to try out Crystal but not at the cost of my favored platform and environment. |
And I'm going to support on this, too. |
@david50407 Well, the compiler is written in Crystal, so you kind of need to do both at the same time...maybe Cygwin could help there? |
@kirbyfan64 I tried this way #26 (comment) , and run Then I'm going to make Crystal compiler can be cross-compiled to Windows, for this, I will make a part of std-lib (core libs?) works that compiler needs. EDIT: Or use Crystal to build LLVM code, use LLC to generate object file, but link with MSVC link works well, too. |
So glad to see progress and interest on this front! |
Please stop flooding about WSL! This issue is about *adding support for Windows not about running crystal in whatever VM/emulation system. We gradually had support, but Windows is still UNSUPPORTED. |
Thank you @ysbaddaden, no windows users care about VM's we want native support. |
Yo, just wanted to pop in and pipe up. As a game developer, despite the fact that I like to work on Linux and Crystal's looking pretty great, most gamers are on Windows. So, Windows support would be needed for a supported target platform for me to be able to use Crystal for development. |
Please, can we keep the comments to constructive comments with discussion about actually implementing this feature. We know how much the community wants this, we don't need any more comments which essentially translate to 👍. |
I do agree with you, but considering that it's not an insignificant portion of people that believe that running Crystal on a bash VM is OK for now, it can't hurt to bring up another use case in which a fully compatible version of Crystal is absolutely necessary. |
I second @ysbaddaden and @RX14. Please, stop asking for something that was already accepted and is one of the top project goals. If it hasn't happened just yet, it is because of lack of resources and time. It is slowly progressing though. Verbalizing more requests for it to happen will only make this thread harder to follow and confusing for by-passers. Learn to take "yes" for an answer! :) |
One more thing to consider: the second we get native windows support, there are a lot of people who are going to be interested in doing something like Electron but with crystal -- I have several friends working on desktop apps in Electron who would switch to crystal in a second if the cross platform support was there. Not only that, but crystal is perfect for doing little one-off command line utility programs, and windows support would just make that sweeter. Right now the best I can find as a cross platform solution for that is Node.js with |
#5339 has just been merged, which brings the ability to compile |
I'm not against implementing concurrency on Windows, however I may not have the time or knowledge of current Crystal to do so. When is this expected to be fully complete via development like this? |
@TsundereBug that's hard to say, we'll never get "fully complete" since we can't implement |
@RX14 that is actually super exciting 🕺 |
Just FYI, windows coordination is now happening in #5430. Not sure when this issue should be closed, I guess most people would want to at least see a self-hosted compiler before closing this issue. |
The Windows package is now self-hosting and rather portable. We are targetting MSVC and the Win32 APIs directly, instead of Cygwin or MinGW(-x64) (#6170). I don't think there are any immediate plans to be able to build DLLs on Windows, nor build libraries on Unix-like systems, for that matter. DLL support as a whole has many details yet to be decided (#11575). |
It's been nearly a year and a half later... Any news? |
See #5430 for latest updates, as I understand it. |
By now all the main platform features for Windows (#5430) are finished! 🚀 But there are still some smaller stories pending to complete Windows support. If you want to financially support the ongoing efforts, check out the Windows suppport project on Open Collective. It's a dedicated contribution to boost the development of Windows support, not a subscription. Thank you very much 🙇 |
The Windows project board and the other open issues are sufficient to track the progress of Windows support. #921 is a more appropriate place to discuss building DLLs as mentioned in OP. |
Hi,
Crystal is an exciting project with lots of potential. I am interested in the possibility of a Crystal compiler for Windows. How feasible is that idea, and how much work would it be?
Specifically, I would like to be able to compile a Crystal program into a Windows .DLL file with exported C functions. I don't care if I run the actual Crystal compiler on a Linux or Windows machine, I just want to end up with a DLL library that will run on Windows.
I have knowledge of Ruby and some C, and I'm willing to dive into learning about LLVM if it means I can contribute here. I would be pleased if you could point me in the right direction.
Regards,
Justin
The text was updated successfully, but these errors were encountered: