twogood / unshield

Tool and library to extract CAB files from InstallShield installers
MIT License
332 stars 71 forks source link

Initial attempt at Windows build #141

Closed twogood closed 2 years ago

bwrsandman commented 2 years ago

If you're willing to add CMakePresets.json to the repo, you can make use of https://github.com/lukka/run-cmake to automatically run your config, build and tests for the different build types and platforms you want to support.

Presets also are supported by a lot of IDEs and make it easier to configure in an IDE, you just select the config, build and test presets and all cmake defines and configs are set.

An example CMakePresets.json for this test:

{
  "version": 3,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 20,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "ninja-multi",
      "displayName": "Ninja Multi-Config",
      "description": "Configure and generate Ninja project files for all configurations",
      "generator": "Ninja Multi-Config",
      "cacheVariables": {
        "FIRST_CACHE_VARIABLE": {
          "type": "BOOL",
          "value": "OFF"
        },
        "SECOND_CACHE_VARIABLE": "ON"
      }
    },
    {
      "name": "msys2",
      "displayName": "MSYS2",
      "description": "Configure and generate MinGW Makefiles for all configurations",
      "generator": "MSYS Makefiles"
    }
  ]
  "buildPresets": [
    {
      "name": "ninja-multi-debug",
      "configurePreset": "ninja-multi",
      "displayName": "Build ninja-multi-debug",
      "description": "Build ninja-multi Debug configuration",
      "configuration": "Debug"
    },
    {
      "name": "ninja-multi-release",
      "configurePreset": "ninja-multi",
      "displayName": "Build ninja-multi-release",
      "description": "Build ninja-multi Release configuration",
      "configuration": "Release"
    },
    {
      "name": "msys2-debug",
      "configurePreset": "msys2",
      "displayName": "Build msys2-debug",
      "description": "Build msys2 Debug configuration",
      "configuration": "Debug"
    },
    {
      "name": "msys2-release",
      "configurePreset": "msys2",
      "displayName": "Build msys2-release",
      "description": "Build msys2 Release configuration",
      "configuration": "Release"
    }
  ],
  "testPresets": [
    {
      "name": "ninja-multi-test",
      "configurePreset": "ninja-multi",
      "displayName": "Run CTest tests on Ninja Configuration",
      "output": {"outputOnFailure": true},
      "execution": {"noTestsAction": "error", "stopOnFailure": true}
    },
    {
      "name": "msys2-test",
      "configurePreset": "msys2",
      "displayName": "Run CTest tests on MSYS2 configuration",
      "output": {"outputOnFailure": true},
      "execution": {"noTestsAction": "error", "stopOnFailure": true}
    }
  ]
}

Then in the workflow you can make use of test matrices

jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        # This is the matrix. They form permutations.
        os: [ubuntu-latest, macos-latest, windows-latest]
        config: [ninja-multi]
        buildtype: [debug, release]
        # These are additional individual jobs. There are no permutations of these.
        include:
          - os: windows-latest
            config: msys2
            buildtype: debug
          - os: windows-latest
            config: msys2
            buildtype: release

    steps:
    - uses: actions/checkout@v2

    - name: Install zlib
      if: startsWith(matrix.os, 'windows')
      working-directory: ${{github.workspace}}
      run: powershell -Command "(Invoke-WebRequest -Uri https://git.io/JnHTY -OutFile install_zlib.bat)"; ./install_zlib.bat; del install_zlib.bat
      shell: cmd

    - name: Get latest CMake and ninja
      uses: lukka/get-cmake@latest

    - name: Run CMake consuming CMakePresets.json
      uses: lukka/run-cmake@v10
      with:
        configurePreset: '${{ matrix.config }}'
        buildPreset: '${{ matrix.config }}-${{ matrix.buildtype }}'
        testPreset: '${{ matrix.config }}-test'
twogood commented 2 years ago

@bwrsandman Very interesting! Does this CMakePresets.json work nicely with CLion?

twogood commented 2 years ago

Btw I hadn't heard of ninja until I googled up lukka/run-cmake and I still don't really know what it is ;)

bwrsandman commented 2 years ago

Ninja is an alternative to makefiles that work on all platforms and does parallel builds automatically. I've only ever used it with cmake preset because you can write the one preset and it works everywhere

bwrsandman commented 2 years ago

Newer versions of clion will automatically detect presets and will pop a dialog to enable them. I've been using clion and presets for a few months and it works great. Visual studio and vscode also support presets.

https://www.jetbrains.com/help/clion/cmake-presets.html

twogood commented 2 years ago

@kratz00 what do you think about this option?

kratz00 commented 2 years ago

Looks like a cool thing to have 😄 It also takes the matrix build approach (like https://github.com/twogood/unshield/pull/145) but leveraging existing features (CMakePresets.json) and tooling (https://github.com/lukka/run-cmake) which makes it better maintainable. I will have a seconds look and give it a shot.

The next big step would be to have the tests executable on all platforms too. The test data could be stored as Git LFS objects instead of downloading them all the time. We can use up to 1 GB of storage without purchasing a data pack (https://docs.github.com/en/repositories/working-with-files/managing-large-files/about-storage-and-bandwidth-usage). The tests can then be executed by ctest, I already have a PoC, which I will share soon (needs some more polishing).

twogood commented 2 years ago

@kratz00 Test data in LFS sounds like a great idea!

twogood commented 2 years ago

Going with #145 instead