Skip to content

Commit

Permalink
Merge branch 'master' into feature/win32-long-import-libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
HertzDevil committed Oct 24, 2024
2 parents 52f0fa2 + 24fc1a9 commit 661986b
Show file tree
Hide file tree
Showing 33 changed files with 662 additions and 223 deletions.
91 changes: 91 additions & 0 deletions .github/workflows/mingw-w64.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: MinGW-w64 CI

on: [push, pull_request]

permissions: {}

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}

jobs:
x86_64-mingw-w64-cross-compile:
runs-on: ubuntu-24.04
steps:
- name: Download Crystal source
uses: actions/checkout@v4

- name: Install LLVM 18
run: |
sudo apt remove 'llvm-*' 'libllvm*'
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
sudo apt-add-repository -y deb http://apt.llvm.org/noble/ llvm-toolchain-noble-18 main
sudo apt install -y llvm-18-dev
- name: Install Crystal
uses: crystal-lang/install-crystal@v1
with:
crystal: "1.14.0"

- name: Cross-compile Crystal
run: make && make -B target=x86_64-windows-gnu release=1

- name: Upload crystal.obj
uses: actions/upload-artifact@v4
with:
name: x86_64-mingw-w64-crystal-obj
path: .build/crystal.obj

- name: Upload standard library
uses: actions/upload-artifact@v4
with:
name: x86_64-mingw-w64-crystal-stdlib
path: src

x86_64-mingw-w64-link:
runs-on: windows-2022
needs: [x86_64-mingw-w64-cross-compile]
steps:
- name: Setup MSYS2
id: msys2
uses: msys2/setup-msys2@ddf331adaebd714795f1042345e6ca57bd66cea8 # v2.24.1
with:
msystem: UCRT64
update: true
install: >-
mingw-w64-ucrt-x86_64-pkgconf
mingw-w64-ucrt-x86_64-cc
mingw-w64-ucrt-x86_64-gc
mingw-w64-ucrt-x86_64-pcre2
mingw-w64-ucrt-x86_64-libiconv
mingw-w64-ucrt-x86_64-zlib
mingw-w64-ucrt-x86_64-llvm
- name: Download crystal.obj
uses: actions/download-artifact@v4
with:
name: x86_64-mingw-w64-crystal-obj

- name: Download standard library
uses: actions/download-artifact@v4
with:
name: x86_64-mingw-w64-crystal-stdlib
path: share/crystal/src

- name: Link Crystal executable
shell: msys2 {0}
run: |
mkdir bin
cc crystal.obj -o bin/crystal.exe \
$(pkg-config bdw-gc libpcre2-8 iconv zlib --libs) \
$(llvm-config --libs --system-libs --ldflags) \
-lDbgHelp -lole32 -lWS2_32 -Wl,--stack,0x800000
ldd bin/crystal.exe | grep -iv /c/windows/system32 | sed 's/.* => //; s/ (.*//' | xargs -t -i cp '{}' bin/
- name: Upload Crystal
uses: actions/upload-artifact@v4
with:
name: x86_64-mingw-w64-crystal
path: |
bin/
share/
53 changes: 29 additions & 24 deletions spec/compiler/codegen/pointer_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -492,28 +492,33 @@ describe "Code gen: pointer" do
)).to_b.should be_true
end

it "takes pointerof lib external var" do
test_c(
%(
int external_var = 0;
),
%(
lib LibFoo
$external_var : Int32
end
LibFoo.external_var = 1
ptr = pointerof(LibFoo.external_var)
x = ptr.value
ptr.value = 10
y = ptr.value
ptr.value = 100
z = LibFoo.external_var
x + y + z
), &.to_i.should eq(111))
end
# FIXME: `$external_var` implies __declspec(dllimport), but we only have an
# object file, so MinGW-w64 fails linking (actually MSVC also emits an
# LNK4217 linker warning)
{% unless flag?(:win32) && flag?(:gnu) %}
it "takes pointerof lib external var" do
test_c(
%(
int external_var = 0;
),
%(
lib LibFoo
$external_var : Int32
end
LibFoo.external_var = 1
ptr = pointerof(LibFoo.external_var)
x = ptr.value
ptr.value = 10
y = ptr.value
ptr.value = 100
z = LibFoo.external_var
x + y + z
), &.to_i.should eq(111))
end
{% end %}
end
2 changes: 1 addition & 1 deletion spec/compiler/codegen/thread_local_spec.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% skip_file if flag?(:openbsd) %}
{% skip_file if flag?(:openbsd) || (flag?(:win32) && flag?(:gnu)) %}

require "../../spec_helper"

Expand Down
6 changes: 3 additions & 3 deletions spec/std/exception/call_stack_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ describe "Backtrace" do

_, output, _ = compile_and_run_file(source_file)

# resolved file:line:column (no column for windows PDB because of poor
# support in general)
{% if flag?(:win32) %}
# resolved file:line:column (no column for MSVC PDB because of poor support
# by external tooling in general)
{% if flag?(:msvc) %}
output.should match(/^#{Regex.escape(source_file)}:3 in 'callee1'/m)
output.should match(/^#{Regex.escape(source_file)}:13 in 'callee3'/m)
{% else %}
Expand Down
2 changes: 1 addition & 1 deletion spec/std/io/io_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ describe IO do
it "says invalid byte sequence" do
io = SimpleIOMemory.new(Slice.new(1, 255_u8))
io.set_encoding("EUC-JP")
expect_raises ArgumentError, {% if flag?(:musl) || flag?(:freebsd) %}"Incomplete multibyte sequence"{% else %}"Invalid multibyte sequence"{% end %} do
expect_raises ArgumentError, {% if flag?(:musl) || flag?(:freebsd) || flag?(:netbsd) %}"Incomplete multibyte sequence"{% else %}"Invalid multibyte sequence"{% end %} do
io.read_char
end
end
Expand Down
70 changes: 42 additions & 28 deletions spec/std/kernel_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ describe "PROGRAM_NAME" do
pending! "Example is broken in Nix shell (#12332)"
end

# MSYS2: gcc/ld doesn't support unicode paths
# https://github.com/msys2/MINGW-packages/issues/17812
{% if flag?(:windows) %}
if ENV["MSYSTEM"]?
pending! "Example is broken in MSYS2 shell"
end
{% end %}

File.write(source_file, "File.basename(PROGRAM_NAME).inspect(STDOUT)")

compile_file(source_file, bin_name: "×‽😂") do |executable_file|
Expand Down Expand Up @@ -254,38 +262,44 @@ describe "hardware exception" do
error.should_not contain("Stack overflow")
end

it "detects stack overflow on the main stack", tags: %w[slow] do
# This spec can take some time under FreeBSD where
# the default stack size is 0.5G. Setting a
# smaller stack size with `ulimit -s 8192`
# will address this.
status, _, error = compile_and_run_source <<-'CRYSTAL'
def foo
y = StaticArray(Int8, 512).new(0)
{% if flag?(:netbsd) %}
# FIXME: on netbsd the process crashes with SIGILL after receiving SIGSEGV
pending "detects stack overflow on the main stack"
pending "detects stack overflow on a fiber stack"
{% else %}
it "detects stack overflow on the main stack", tags: %w[slow] do
# This spec can take some time under FreeBSD where
# the default stack size is 0.5G. Setting a
# smaller stack size with `ulimit -s 8192`
# will address this.
status, _, error = compile_and_run_source <<-'CRYSTAL'
def foo
y = StaticArray(Int8, 512).new(0)
foo
end
foo
end
foo
CRYSTAL
CRYSTAL

status.success?.should be_false
error.should contain("Stack overflow")
end
status.success?.should be_false
error.should contain("Stack overflow")
end

it "detects stack overflow on a fiber stack", tags: %w[slow] do
status, _, error = compile_and_run_source <<-'CRYSTAL'
def foo
y = StaticArray(Int8, 512).new(0)
foo
end
it "detects stack overflow on a fiber stack", tags: %w[slow] do
status, _, error = compile_and_run_source <<-'CRYSTAL'
def foo
y = StaticArray(Int8, 512).new(0)
foo
end

spawn do
foo
end
spawn do
foo
end

sleep 60.seconds
CRYSTAL
sleep 60.seconds
CRYSTAL

status.success?.should be_false
error.should contain("Stack overflow")
end
status.success?.should be_false
error.should contain("Stack overflow")
end
{% end %}
end
4 changes: 2 additions & 2 deletions spec/std/socket/tcp_server_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ describe TCPServer, tags: "network" do
# FIXME: Resolve special handling for win32. The error code handling should be identical.
{% if flag?(:win32) %}
[WinError::WSAHOST_NOT_FOUND, WinError::WSATRY_AGAIN].should contain err.os_error
{% elsif flag?(:android) %}
{% elsif flag?(:android) || flag?(:netbsd) %}
err.os_error.should eq(Errno.new(LibC::EAI_NODATA))
{% else %}
[Errno.new(LibC::EAI_NONAME), Errno.new(LibC::EAI_AGAIN)].should contain err.os_error
Expand All @@ -110,7 +110,7 @@ describe TCPServer, tags: "network" do
# FIXME: Resolve special handling for win32. The error code handling should be identical.
{% if flag?(:win32) %}
[WinError::WSAHOST_NOT_FOUND, WinError::WSATRY_AGAIN].should contain err.os_error
{% elsif flag?(:android) %}
{% elsif flag?(:android) || flag?(:netbsd) %}
err.os_error.should eq(Errno.new(LibC::EAI_NODATA))
{% else %}
[Errno.new(LibC::EAI_NONAME), Errno.new(LibC::EAI_AGAIN)].should contain err.os_error
Expand Down
6 changes: 3 additions & 3 deletions spec/std/socket/tcp_socket_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ describe TCPSocket, tags: "network" do
# FIXME: Resolve special handling for win32. The error code handling should be identical.
{% if flag?(:win32) %}
[WinError::WSAHOST_NOT_FOUND, WinError::WSATRY_AGAIN].should contain err.os_error
{% elsif flag?(:android) %}
{% elsif flag?(:android) || flag?(:netbsd) %}
err.os_error.should eq(Errno.new(LibC::EAI_NODATA))
{% else %}
[Errno.new(LibC::EAI_NONAME), Errno.new(LibC::EAI_AGAIN)].should contain err.os_error
Expand All @@ -93,7 +93,7 @@ describe TCPSocket, tags: "network" do
# FIXME: Resolve special handling for win32. The error code handling should be identical.
{% if flag?(:win32) %}
[WinError::WSAHOST_NOT_FOUND, WinError::WSATRY_AGAIN].should contain err.os_error
{% elsif flag?(:android) %}
{% elsif flag?(:android) || flag?(:netbsd) %}
err.os_error.should eq(Errno.new(LibC::EAI_NODATA))
{% else %}
[Errno.new(LibC::EAI_NONAME), Errno.new(LibC::EAI_AGAIN)].should contain err.os_error
Expand Down Expand Up @@ -142,7 +142,7 @@ describe TCPSocket, tags: "network" do
(client.tcp_nodelay = false).should be_false
client.tcp_nodelay?.should be_false

{% unless flag?(:openbsd) %}
{% unless flag?(:openbsd) || flag?(:netbsd) %}
(client.tcp_keepalive_idle = 42).should eq 42
client.tcp_keepalive_idle.should eq 42
(client.tcp_keepalive_interval = 42).should eq 42
Expand Down
3 changes: 3 additions & 0 deletions spec/std/socket/udp_socket_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ describe UDPSocket, tags: "network" do
elsif {{ flag?(:freebsd) }} && family == Socket::Family::INET6
# FIXME: fails with "Error sending datagram to [ipv6]:port: Network is unreachable"
pending "joins and transmits to multicast groups"
elsif {{ flag?(:netbsd) }} && family == Socket::Family::INET6
# FIXME: fails with "setsockopt: EADDRNOTAVAIL"
pending "joins and transmits to multicast groups"
else
it "joins and transmits to multicast groups" do
udp = UDPSocket.new(family)
Expand Down
8 changes: 4 additions & 4 deletions spec/std/string_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2830,7 +2830,7 @@ describe "String" do
bytes.to_a.should eq([72, 0, 101, 0, 108, 0, 108, 0, 111, 0])
end

{% unless flag?(:musl) || flag?(:solaris) || flag?(:freebsd) || flag?(:dragonfly) %}
{% unless flag?(:musl) || flag?(:solaris) || flag?(:freebsd) || flag?(:dragonfly) || flag?(:netbsd) %}
it "flushes the shift state (#11992)" do
"\u{00CA}".encode("BIG5-HKSCS").should eq(Bytes[0x88, 0x66])
"\u{00CA}\u{0304}".encode("BIG5-HKSCS").should eq(Bytes[0x88, 0x62])
Expand All @@ -2839,7 +2839,7 @@ describe "String" do

# FreeBSD iconv encoder expects ISO/IEC 10646 compatibility code points,
# see https://www.ccli.gov.hk/doc/e_hkscs_2008.pdf for details.
{% if flag?(:freebsd) || flag?(:dragonfly) %}
{% if flag?(:freebsd) || flag?(:dragonfly) || flag?(:netbsd) %}
it "flushes the shift state (#11992)" do
"\u{F329}".encode("BIG5-HKSCS").should eq(Bytes[0x88, 0x66])
"\u{F325}".encode("BIG5-HKSCS").should eq(Bytes[0x88, 0x62])
Expand Down Expand Up @@ -2883,7 +2883,7 @@ describe "String" do
String.new(bytes, "UTF-16LE").should eq("Hello")
end

{% unless flag?(:solaris) || flag?(:freebsd) || flag?(:dragonfly) %}
{% unless flag?(:solaris) || flag?(:freebsd) || flag?(:dragonfly) || flag?(:netbsd) %}
it "decodes with shift state" do
String.new(Bytes[0x88, 0x66], "BIG5-HKSCS").should eq("\u{00CA}")
String.new(Bytes[0x88, 0x62], "BIG5-HKSCS").should eq("\u{00CA}\u{0304}")
Expand All @@ -2892,7 +2892,7 @@ describe "String" do

# FreeBSD iconv decoder returns ISO/IEC 10646-1:2000 code points,
# see https://www.ccli.gov.hk/doc/e_hkscs_2008.pdf for details.
{% if flag?(:freebsd) || flag?(:dragonfly) %}
{% if flag?(:freebsd) || flag?(:dragonfly) || flag?(:netbsd) %}
it "decodes with shift state" do
String.new(Bytes[0x88, 0x66], "BIG5-HKSCS").should eq("\u{00CA}")
String.new(Bytes[0x88, 0x62], "BIG5-HKSCS").should eq("\u{F325}")
Expand Down
Loading

0 comments on commit 661986b

Please sign in to comment.