diff --git a/.github/workflows/mingw-w64.yml b/.github/workflows/mingw-w64.yml index 10841a325bf5..d1af67f49682 100644 --- a/.github/workflows/mingw-w64.yml +++ b/.github/workflows/mingw-w64.yml @@ -80,7 +80,7 @@ jobs: shell: msys2 {0} run: | mkdir bin - cc crystal.obj -o bin/crystal.exe \ + cc crystal.obj -o bin/crystal.exe -mcrtdll=ucrt -municode \ $(pkg-config bdw-gc libpcre2-8 iconv zlib libffi --libs) \ $(llvm-config --libs --system-libs --ldflags) \ -lDbgHelp -lole32 -lWS2_32 -Wl,--stack,0x800000 diff --git a/src/compiler/crystal/loader/mingw.cr b/src/compiler/crystal/loader/mingw.cr index 677f564cec16..0e0d86ef64c6 100644 --- a/src/compiler/crystal/loader/mingw.cr +++ b/src/compiler/crystal/loader/mingw.cr @@ -27,6 +27,7 @@ class Crystal::Loader libnames = [] of String file_paths = [] of String extra_search_paths = [] of String + crt_dll = "msvcrt" OptionParser.parse(args.dup) do |parser| parser.on("-L DIRECTORY", "--library-path DIRECTORY", "Add DIRECTORY to library search path") do |directory| @@ -39,17 +40,21 @@ class Crystal::Loader raise LoadError.new "static libraries are not supported by Crystal's runtime loader" end parser.unknown_args do |args, after_dash| - file_paths.concat args + file_paths.concat args.reject(&.starts_with?("-mcrtdll=")) end parser.invalid_option do |arg| - unless arg.starts_with?("-Wl,") + if crt_dll_arg = arg.lchop?("-mcrtdll=") + # the GCC spec is `%{!mcrtdll=*:-lmsvcrt} %{mcrtdll=*:-l%*}` + crt_dll = crt_dll_arg + elsif !arg.starts_with?("-Wl,") raise LoadError.new "Not a recognized linker flag: #{arg}" end end end search_paths = extra_search_paths + search_paths + libnames << crt_dll begin loader = new(search_paths) diff --git a/src/crystal/system/win32/wmain.cr b/src/crystal/system/win32/wmain.cr index caad6748229f..2120bfc06bfc 100644 --- a/src/crystal/system/win32/wmain.cr +++ b/src/crystal/system/win32/wmain.cr @@ -2,14 +2,12 @@ require "c/stringapiset" require "c/winnls" require "c/stdlib" -{% begin %} - # we have both `main` and `wmain`, so we must choose an unambiguous entry point +# we have both `main` and `wmain`, so we must choose an unambiguous entry point +{% if flag?(:msvc) %} @[Link({{ flag?(:static) ? "libcmt" : "msvcrt" }})] - {% if flag?(:msvc) %} - @[Link(ldflags: "/ENTRY:wmainCRTStartup")] - {% elsif flag?(:gnu) && !flag?(:interpreted) %} - @[Link(ldflags: "-municode")] - {% end %} + @[Link(ldflags: "/ENTRY:wmainCRTStartup")] +{% elsif flag?(:gnu) && !flag?(:interpreted) %} + @[Link(ldflags: "-municode")] {% end %} lib LibCrystalMain end diff --git a/src/empty.cr b/src/empty.cr index 204e30da48c0..cb79610a5be3 100644 --- a/src/empty.cr +++ b/src/empty.cr @@ -1,6 +1,6 @@ require "primitives" -{% if flag?(:win32) %} +{% if flag?(:msvc) %} @[Link({{ flag?(:static) ? "libcmt" : "msvcrt" }})] # For `mainCRTStartup` {% end %} lib LibCrystalMain diff --git a/src/lib_c.cr b/src/lib_c.cr index 0bd8d2c2cc35..98ffa2163b59 100644 --- a/src/lib_c.cr +++ b/src/lib_c.cr @@ -1,5 +1,7 @@ -{% if flag?(:win32) %} +{% if flag?(:msvc) %} @[Link({{ flag?(:static) ? "libucrt" : "ucrt" }})] +{% elsif flag?(:win32) && flag?(:gnu) %} + @[Link(ldflags: "-mcrtdll=ucrt")] {% end %} lib LibC alias Char = UInt8