pmq20/ruby-packer

Cannot pack ruby sinatra app on Windows using GH actions (Linux and MacOS work fine)

piotr-iohk opened this issue ยท 9 comments

Hello! I'm trying to pack a light-weight Sinatra app. I'm using GH actions (inspired by how the ruby-packer is built itself ๐Ÿ˜… ). Both Linux and MacOS workflows work great for me, however on Windows I'm getting failure and rather cryptic error message:

-> CI=true ENCLOSE_IO_USE_ORIGINAL_RUBY=true MAKE=nmake CL=/MP nmake /f win32\Makefile.msc
Failed running [{"CI"=>"true", "ENCLOSE_IO_USE_ORIGINAL_RUBY"=>"true", "MAKE"=>"nmake", "CL"=>"/MP"}, "nmake /f win32\\Makefile.msc"]

Running rubyc.exe with --debug switch doesn't show more that that. Anyway, it seems that nmake is there:

>where nmake 
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\bin\Hostx64\x64\nmake.exe

Also I think I have all the prerequisites installed on Windows box. My workflow is:

name: Windows
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]
    tags: [ "*" ]
jobs:
  make:
    strategy:
      matrix:
        include:
          - os: windows-2019
            vs: 2019
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - uses: ilammy/setup-nasm@v1
      - uses: actions/checkout@v2

      - name: "Install libraries"
        run: |
          choco install --no-progress squashfs
          choco install wget

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.7.1

      - name: "Install dependencies"
        run: bundle install

      - name: "Set up Perl"
        run: |
          choco install strawberryperl
          echo "##[add-path]C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin"

      - name: "Inspect Windows Environment"
        run: |
          call "C:\Program Files (x86)\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
          echo on
          wmic OS get OSArchitecture
          echo %PROCESSOR_ARCHITECTURE%
          set
          systeminfo
          where perl
          perl -V
          where nmake
          where mksquashfs
          mksquashfs -version
          where ruby
          ruby -v
          where bundle
          bundle -v
        shell: cmd

      - name: Get ruby-packer
        run: |
          wget https://github.com/pmq20/ruby-packer/releases/download/windows-x64/rubyc.exe
          dir
          copy rubyc.exe C:\strawberry\c\bin\rubyc.exe
          del rubyc.exe
          rubyc.exe -v

      - name: Build executable
        run: |
          dir
          mkdir bin
          rubyc.exe app.rb -o bin\ikar.exe --tmpdir=C:\rubyc_tmp

      - name: ๐Ÿ“Ž Upload Artifact
        uses: actions/upload-artifact@v1
        with:
          name: ${{ matrix.os }}-exe
          path: bin

Not sure if I missed anything or would it be a bug of some sort?
Many thanks! Ruby-packer is awesome! โค๏ธ

Got the same thing when trying to compile my app by directly using ruby-packer code from the repo (workflow).

I've also made a small PR #134 fixing small typo in compiler.rb that was causing another error.

pmq20 commented

@piotr-iohk Hi Piotr, thanks for reporting the issue! I'll spawn a CI runner now to try if I can reproduce it.

Thanks @pmq20! It turns out I missed call "C:\Program Files (x86)\Microsoft Visual Studio\${{ matrix.vs }\Enterprise\VC\Auxiliary\Build\vcvars64.bat" in the Build executables step ๐Ÿคฆ . After adding it packing works! ๐ŸŽ‰

I have encountered another problem though... It seems to be failing on getting nokogiri gem which has native extensions. The gem itself is dep of capybara which actually I don't need to include, cause it is not my runtime dependency. (see: Gemfile)

I was wondering, is there any way to exclude developement/test dependencies? I was trying with adding this -> piotr-iohk@0d763d4, but still got the same result -> https://github.com/piotr-iohk/ikar/runs/1311970099?check_suite_focus=true#step:10:3108

pmq20 commented

@piotr-iohk I think you might want to change the line below piotr-iohk@0d763d4 to @utils.run(local_toolchain_env, @bundle, 'install', '--without', 'development', 'test').

@pmq20 awesome, your suggestion works!

Unfortunately another gem -> sys-proctable failed due to it's native-extensions dependency:
https://github.com/piotr-iohk/ikar/runs/1313443677?check_suite_focus=true

Installing ffi 1.13.1 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

...

In Gemfile:
  sys-proctable was resolved to 1.2.6, which depends on
    ffi

This one I cannot get rid off I'm afraid, it's a runtime dep... ๐Ÿ˜…
๐Ÿค”

@pmq20 If I'm not mistaken the reason is -> https://github.com/pmq20/ruby-packer/blob/master/lib/compiler.rb#L606, cause ffi depends on libffi...

pmq20 commented

@piotr-iohk Oh right. I think you are right. Those vendored libraries just need to be compiled and referenced when compiling corresponding extensions/gems. This is probably exactly the thing to do to solve the problem.

My attepmt so far -> piotr-iohk#1.

Unfortunately cannot get libffi to compile (fails at configure).
https://github.com/piotr-iohk/ruby-packer/runs/1329140090?check_suite_focus=true

configure: error: in `/c/rubyc_tmp/libffi/x86_64-pc-msys':
configure: error: C compiler cannot create executables
See `config.log' for more details

In the /libffi/x86_64-pc-msys/config.log there is. (also attached as GH action job artifact):

configure:3823: msvcc.sh --version >&5
.././configure: line 3825: msvcc.sh: command not found
configure:3834: $? = 127
configure:3823: msvcc.sh -v >&5
.././configure: line 3825: msvcc.sh: command not found
configure:3834: $? = 127
configure:3823: msvcc.sh -V >&5
.././configure: line 3825: msvcc.sh: command not found
configure:3834: $? = 127
configure:3823: msvcc.sh -qversion >&5
.././configure: line 3825: msvcc.sh: command not found
configure:3834: $? = 127
configure:3854: checking whether the C compiler works
configure:3876: msvcc.sh  "-DFFI_BUILDING_DLL"  conftest.c  >&5
.././configure: line 3878: msvcc.sh: command not found
configure:3880: $? = 127
configure:3918: result: no
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "libffi"
| #define PACKAGE_TARNAME "libffi"
| #define PACKAGE_VERSION "3.2.1"
| #define PACKAGE_STRING "libffi 3.2.1"
| #define PACKAGE_BUGREPORT "http://github.com/atgreen/libffi/issues"
| #define PACKAGE_URL ""
| #define PACKAGE "libffi"
| #define VERSION "3.2.1"
| /* end confdefs.h.  */
| 
| int
| main ()
| {
| 
|   ;
|   return 0;
| }
configure:3923: error: in `/c/rubyc_tmp/libffi/x86_64-pc-msys':
configure:3925: error: C compiler cannot create executables

๐Ÿคทโ€โ™‚๏ธ

Ok, I managed to build libffi for Windows in the stuff_libffi method. I currently have issue with building ruby in the build_pass1_windows. The build fails on nmake:

C:\rubyc_tmp\libffi\x86_64-w64-mingw32\.libs\libffi-6.dll : fatal error LNK1107: invalid or corrupt file: cannot read at 0x430
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\bin\HostX64\x64\cl.EXE"' : return code '0x2'
Stop.

Here is work-in-progress pr on my fork: piotr-iohk#2
Corresponding CI failure: https://github.com/piotr-iohk/ruby-packer/runs/1346149673?check_suite_focus=true

@pmq20 if you have any suggestions, please let me know.