Skip to content

Conversation

@luau-project
Copy link
Collaborator

@luau-project luau-project commented Sep 21, 2025

Description

fix: trim MSVCRT caught as output of pe-parser

Reason

Without trimming the output, the msvcrt variable always contains trailing new lines (due Lua's print). Thus, lines

if (msvcrt === "nil") {
and
else if (msvcrt === "MSVCRT") {
will never get a hit.

Reproduction

Through GitHub Actions (https://github.com/luau-project/ci-tests/actions/runs/17896638550), using the workflow at the end, employing several C toolchains (MinGW-w64 provided by MSYS2) that link to the legacy MSVCRT and the newer UCRT C runtimes, the runs are split in the following manner:

Workflow

Expand to see the reproduction workflow
name: Test

on: push

jobs:
  test:
    runs-on: windows-latest

    defaults:
      run:
        shell: cmd

    strategy:

      fail-fast: false

      matrix:
        use-fix:
          - false
          - true

        lua-version:
          - 5.1.5
          - 5.2.4
          - 5.3.6
          - 5.4.8

        MSYS2-CONFIG:
          # MinGW-w64 with MSVCRT
          - sys: mingw64
            env: x86_64

          # MinGW-w64 with UCRT
          - sys: ucrt64
            env: ucrt-x86_64

          # LLVM-MinGW-w64
          - sys: clang64
            env: clang-x86_64

    env:
      MSYS2_SED: C:\msys64\usr\bin\sed.exe
      MSYS2_BASH: C:\msys64\usr\bin\bash.exe
      MSYS2_MINGW_W64_DIR: C:\msys64\${{ matrix.MSYS2-CONFIG.sys }}
      MSYS2_PACKAGES: mingw-w64-${{ matrix.MSYS2-CONFIG.env }}-cc mingw-w64-${{ matrix.MSYS2-CONFIG.env }}-make

    steps:

      # When running many concurrent jobs,
      # pacman might fail to download packages
      # from MSYS2 servers due a high load.
      # So, retry the installation a few times
      - name: Install C compiler, GNU Make
        run: |
          SET "TRIES=0"
          SET "MAX_TRIES=5"
          SET "SECS_TO_WAIT=1"

          GOTO :INSTALL_FROM_MSYS2

          :INSTALL_FROM_MSYS2
          ${{ env.MSYS2_BASH }} -lc "pacman -S ${{ env.MSYS2_PACKAGES }} --noconfirm"

          IF %ERRORLEVEL% EQU 0 (
            ECHO ${{ env.MSYS2_MINGW_W64_DIR }}\bin>>${{ github.path }}
          ) ELSE (
            SET /A "TRIES=TRIES+1"
            IF %TRIES% LSS %MAX_TRIES% (
              ECHO Attempt %TRIES% out of %MAX_TRIES% to install packages failed
              SET /A "SECS_TO_WAIT*=2"
              ECHO Waiting %SECS_TO_WAIT% seconds to retry
              SLEEP %SECS_TO_WAIT%
              GOTO :INSTALL_FROM_MSYS2
            ) ELSE (
              ECHO Failed to install MinGW-w64 and dependencies from MSYS2
              EXIT /B 1
            )
          )

      - name: Test C compiler and GNU Make
        run: |
          cc --version
          mingw32-make --version

      - name: Download Lua ${{ matrix.lua-version }}
        run: curl -kLO "https://lua.org/ftp/lua-${{ matrix.lua-version }}.tar.gz"

      - name: Extract Lua ${{ matrix.lua-version }}
        run: tar -xf "lua-${{ matrix.lua-version }}.tar.gz"

      - name: Patch Lua 5.1 Makefile to remove shell comment
        if: ${{ startsWith(matrix.lua-version, '5.1.') }}
        run: |
          CD "lua-${{ matrix.lua-version }}"
          CD "src"
          ${{ env.MSYS2_SED }} -e "s|# DLL needs all object files||" -i Makefile

      - name: Build Lua ${{ matrix.lua-version }}
        run: mingw32-make -C "lua-${{ matrix.lua-version }}" "SHELL=%COMSPEC%" mingw

      - name: Install Lua ${{ matrix.lua-version }}
        run: |
          CD "lua-${{ matrix.lua-version }}"
          CD "src"
          SET "LUA_DIR=${{ github.workspace }}\.lua"
          SET "LUA_BINDIR=%LUA_DIR%\bin"
          SET "LUA_INCDIR=%LUA_DIR%\include"
          SET "LUA_LIBDIR=%LUA_DIR%\lib"
          SET "LUA_VERSION=${{ matrix.lua-version}}"
          SET "LUA_SHORT=%LUA_VERSION:~0,4%"
          IF EXIST "%LUA_DIR%\" RMDIR /S /Q "%LUA_DIR%"
          MKDIR "%LUA_DIR%"
          MKDIR "%LUA_BINDIR%"
          MKDIR "%LUA_INCDIR%"
          MKDIR "%LUA_LIBDIR%"
          @COPY lua.exe "%LUA_BINDIR%"
          @COPY luac.exe "%LUA_BINDIR%"
          @COPY *.dll "%LUA_BINDIR%"
          @COPY *.dll "%LUA_LIBDIR%"
          IF "%LUA_SHORT%" EQU "5.1." (
            FOR %%F IN (lua.h luaconf.h lualib.h lauxlib.h ..\etc\lua.hpp) DO @COPY %%F "%LUA_INCDIR%"
          ) ELSE (
            FOR %%F IN (lua.h luaconf.h lualib.h lauxlib.h lua.hpp) DO @COPY %%F "%LUA_INCDIR%"
          )
          ECHO %LUA_BINDIR%>> ${{ github.path }}

      - uses: luarocks/gh-actions-luarocks@v6
        if: ${{ ! matrix.use-fix }}
        with:
          luaRocksVersion: 3.12.2

      - uses: luau-project/gh-actions-luarocks@trim-msvcrt
        if: ${{ matrix.use-fix }}
        with:
          luaRocksVersion: 3.12.2

      - name: Configure LuaRocks for MinGW-w64
        run: |
          luarocks config "variables.CC" "cc"
          luarocks config "variables.LD" "cc"
          luarocks config "external_deps_dirs[1]" "${{ env.MSYS2_MINGW_W64_DIR }}"

      - name: Show LuaRocks config
        run: luarocks config

      - name: Install LuaSocket
        run: luarocks install luasocket

@luau-project
Copy link
Collaborator Author

I am closing this PR, because I found the proper solution. Moreover, my findings invalidate the changes proposed on this PR, so it is pointless to keep it open.

Warning

Long post ahead

Reason

Earlier, due to false positives, I thought that MSVCRT was needed to be set in order to link LuaSocket correctly on Windows with GCC. However, recently, (2 days ago), during the development of my setup-lua GitHub Actions to setup Lua + LuaRocks, I found the correct manner to solve the problem.

Root cause of LuaSocket linking issue on Windows with GCC

The root cause is a misconfiguration of LuaRocks for the many different GCC providers on Windows.

The misconfiguration is about finding the correct location for Windows headers (directory holding windows.h) and WINAPI libraries (libkernel32.a, libuser32.a, etc), which is often different depending on the provider.

For example, for GCC provided by MSYS2, the directory layout is more or less the following:

root
  |
  | - bin
  |    |- gcc.exe
  |    |- .
  |    |- .
  |    |- .
  | - include
  |    |- windows.h
  |    |- .
  |    |- .
  |    |- .
  | - lib
  |    |- libkernel32.a
  |    |- .
  |    |- .
  |    |- .

For the first GCC on GitHub PATH environment variable, which comes from https://github.com/niXman/mingw-builds-binaries, the directory layout is the following:

root
  |
  | - bin
  |    |- gcc.exe
  |    |- .
  |    |- .
  |    |- .
  | - include
  |    |- .
  |    |- .
  |    |- .
  | - x86_64-w64-mingw32
  |    |- bin
  |    |   |- .
  |    |   |- .
  |    |   |- .
  |    |- include
  |    |   |- windows.h
  |    |   |- .
  |    |   |- .
  |    |   |- .
  |    |- lib
  |    |   |- libkernel32.a
  |    |   |- .
  |    |   |- .
  |    |   |- .

On the other hand, regardless of the GCC provider, LuaRocks assumes (external_deps_dirs config variable) that headers and libraries can be found at C:\external, C:\MinGW or C:\Windows\system32, causing the LuaSocket linking issue.

Solution

So, in a simplified process to solve the problem, the solution that I provided on my action was:

  1. At LuaRocks configuration step, if the toolchain is not MSVC, use gcc -dumpmachine to grab that value x86_64-w64-mingw32 as a sysroot variable.

    If you are interested, see https://github.com/luau-project/setup-lua/blob/48961279fba711f39fa539a4903b1ac66153b694/src/Projects/LuaRocks/Installation/LuaRocksPreparePostInstallTarget.ts#L127-L219

  2. Then add the directories {root} and {root}\{sysroot} to LuaRocks config external_deps_dirs:

Conclusion

@luau-project luau-project deleted the trim-msvcrt branch November 12, 2025 15:28
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.

1 participant