diff --git a/.github/actions/test-cc/action.yml b/.github/actions/test-cc/action.yml new file mode 100644 index 00000000..cede4847 --- /dev/null +++ b/.github/actions/test-cc/action.yml @@ -0,0 +1,36 @@ +name: Test CC +description: Test C compiler compatibility +inputs: + compiler: + description: "Toolchain or compiler to install" + required: true + version: + description: "Version of toolchain or compiler" + required: true +runs: + using: "composite" + steps: + + - name: Check compiler version + shell: bash + run: | + if ([ "$RUNNER_OS" == "Windows" ] && [[ "${{ inputs.compiler }}" =~ "intel" ]]); then + # only last line of output captured by command substitution, write to temp file instead + ${{ env.CC }} //QV > "$RUNNER_TEMP/${{ env.CC }}.ver" 2>&1 + ccv=$(cat "$RUNNER_TEMP/${{ env.CC }}.ver" | head -n 1) + ccv=${ccv#*Version } + ccv=${ccv%% Build*} + else + ccv=$(${{ env.CC }} --version | head -n 1) + ccv=$(echo "$ccv" | grep -woE '[0123456789.]+' | head -n 1) + fi + [[ "$ccv" == ${{ inputs.version }}* ]] && (echo "found ${{ env.CC }} version: $ccv") || (echo "unexpected ${{ env.CC }} version: $ccv"; exit 1) + + - name: Test compile (bash) + shell: bash + run: | + ${{ env.CC }} -o hw hw.c + output=$(./hw '2>&1') + [[ "$output" == *"hello world"* ]] && echo "$output" || (echo "Unexpected C program output: $output"; exit 1) + rm hw + \ No newline at end of file diff --git a/.github/actions/test-cxx/action.yml b/.github/actions/test-cxx/action.yml new file mode 100644 index 00000000..8fb84ec5 --- /dev/null +++ b/.github/actions/test-cxx/action.yml @@ -0,0 +1,36 @@ +name: Test CXX +description: Test CXX compiler compatibility +inputs: + compiler: + description: "Toolchain or compiler to install" + required: true + version: + description: "Version of toolchain or compiler" + required: true +runs: + using: "composite" + steps: + + - name: Check compiler version + shell: bash + run: | + if ([ "$RUNNER_OS" == "Windows" ] && [[ "${{ matrix.toolchain.compiler }}" =~ "intel" ]]); then + # only last line of output captured by command substitution, write to temp file instead + ${{ env.CXX }} //QV > "$RUNNER_TEMP/${{ env.CXX }}.ver" 2>&1 + cxxv=$(cat "$RUNNER_TEMP/${{ env.CXX }}.ver" | head -n 1) + cxxv=${cxxv#*Version } + cxxv=${cxxv%% Build*} + else + cxxv=$(${{ env.CXX }} --version | head -n 1) + cxxv=$(echo "$cxxv" | grep -woE '[0123456789.]+' | head -n 1) + fi + [[ "$cxxv" == ${{ matrix.toolchain.version }}* ]] && (echo "found ${{ env.CXX }} version: $cxxv") || (echo "unexpected ${{ env.CXX }} version: $cxxv"; exit 1) + + - name: Test compile (bash) + shell: bash + run: | + ${{ env.CXX }} -o hw hw.cpp + output=$(./hw '2>&1') + [[ "$output" == *"hello world"* ]] && echo "$output" || (echo "Unexpected C++ program output: $output"; exit 1) + rm hw + \ No newline at end of file diff --git a/.github/actions/test-fc/action.yml b/.github/actions/test-fc/action.yml new file mode 100644 index 00000000..39b21a16 --- /dev/null +++ b/.github/actions/test-fc/action.yml @@ -0,0 +1,89 @@ +name: Test FC +description: Test Fortran compiler compatibility +inputs: + compiler: + description: "Toolchain or compiler to install" + required: true + version: + description: "Version of toolchain or compiler" + required: true +runs: + using: "composite" + steps: + + - name: Check compiler version + shell: bash + run: | + if ([ "$RUNNER_OS" == "Windows" ] && [[ "${{ inputs.compiler }}" =~ "intel" ]]); then + # only last line of output captured by command substitution, write to temp file instead + ${{ env.FC }} //QV > "$RUNNER_TEMP/${{ env.FC }}.ver" 2>&1 + fcv=$(cat "$RUNNER_TEMP/${{ env.FC }}.ver" | head -n 1) + fcv=${fcv#*Version } + fcv=${fcv%% Build*} + else + fcv=$(${{ env.FC }} --version | head -n 1) + fcv=$(echo "$fcv" | grep -woE '[0123456789.]+' | head -n 1) + fi + [[ "$fcv" == ${{ inputs.version }}* ]] && (echo "found ${{ env.FC }} version: $fcv") || (echo "unexpected ${{ env.FC }} version: $fcv"; exit 1) + + - name: Test compile (bash) + shell: bash + run: | + # macos-13/gfortran 7-9 compatibility workaround + args="" + if [ "$RUNNER_OS" == "macOS" ]; then + if [[ $(sw_vers -productVersion) == 13* ]] && \ + [[ ${{ inputs.compiler }} == "gcc" ]] && \ + [[ ${{ inputs.version }} =~ ^(7|8|9)$ ]] + then + args="-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib" + fi + fi + + ${{ env.FC }} $args -o hw hw.f90 + output=$(./hw '2>&1') + [[ "$output" == *"hello world"* ]] && echo "$output" || (echo "Unexpected Fortran program output: $output"; exit 1) + rm hw + + - name: Test compile Fortran (pwsh) + if: ${{ (success() || failure()) && runner.os == 'Windows' }} + shell: pwsh + run: | + ${{ env.FC }} -o hw.exe hw.f90 + $output=$(& ".\hw.exe") + if ($output -match "hello world") { + write-output $output + } else { + write-output "unexpected output: $output" + exit 1 + } + rm hw.exe + + - name: Test compile Fortran (powershell) + if: ${{ (success() || failure()) && runner.os == 'Windows' }} + shell: powershell + run: | + ${{ env.FC }} -o hw.exe hw.f90 + $output=$(& ".\hw.exe") + if ($output -match "hello world") { + write-output $output + } else { + write-output "unexpected output: $output" + exit 1 + } + rm hw.exe + + - name: Test compile Fortran (cmd) + if: ${{ (success() || failure()) && runner.os == 'Windows' }} + shell: cmd + run: | + ${{ env.FC }} -o hw.exe hw.f90 + for /f "tokens=* usebackq" %%f in (`.\hw.exe`) do @set "OUTPUT=%%f" + if "%OUTPUT%"=="hello world" ( + echo %OUTPUT% + ) else ( + echo unexpected output: %OUTPUT% + exit 1 + ) + del hw.exe + \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5e9f5d70..2c677b01 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,9 +2,6 @@ name: Test on: push: - branches: - - main - - develop* paths-ignore: - '**.md' pull_request: @@ -17,8 +14,8 @@ on: - cron: '0 0 1 * *' jobs: - test: - name: Test latest compiler versions + test_latest: + name: Test latest versions if: github.event_name != 'schedule' runs-on: ${{ matrix.os }} strategy: @@ -44,149 +41,42 @@ jobs: toolchain: {compiler: intel} - os: macos-11 toolchain: {compiler: intel} - steps: - - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Fortran id: setup-fortran + continue-on-error: true uses: ./ with: compiler: ${{ matrix.toolchain.compiler }} version: ${{ matrix.toolchain.version }} - - name: Check compiler version + - name: Test Fortran compiler if: steps.setup-fortran.outcome == 'success' - shell: bash - env: - FC: ${{ steps.setup-fortran.outputs.fc }} - CC: ${{ steps.setup-fortran.outputs.cc }} - CXX: ${{ steps.setup-fortran.outputs.cxx }} - run: | - if ([ "$RUNNER_OS" == "Windows" ] && [[ "${{ matrix.toolchain.compiler }}" =~ "intel" ]]); then - # only last line of output captured by command substitution, write to temp file instead - ${{ env.FC }} //QV > "$RUNNER_TEMP/${{ env.FC }}.ver" 2>&1 - ${{ env.CC }} //QV > "$RUNNER_TEMP/${{ env.CC }}.ver" 2>&1 - ${{ env.CXX }} //QV > "$RUNNER_TEMP/${{ env.CXX }}.ver" 2>&1 - - fcv=$(cat "$RUNNER_TEMP/${{ env.FC }}.ver" | head -n 1) - ccv=$(cat "$RUNNER_TEMP/${{ env.CC }}.ver" | head -n 1) - cxxv=$(cat "$RUNNER_TEMP/${{ env.CXX }}.ver" | head -n 1) - - fcv=${fcv#*Version } - fcv=${fcv%% Build*} - ccv=${ccv#*Version } - ccv=${ccv%% Build*} - cxxv=${cxxv#*Version } - cxxv=${cxxv%% Build*} - else - fcv=$(${{ env.FC }} --version | head -n 1) - ccv=$(${{ env.CC }} --version | head -n 1) - cxxv=$(${{ env.CXX }} --version | head -n 1) - - fcv=$(echo "$fcv" | grep -woE '[0123456789.]+' | head -n 1) - ccv=$(echo "$ccv" | grep -woE '[0123456789.]+' | head -n 1) - cxxv=$(echo "$cxxv" | grep -woE '[0123456789.]+' | head -n 1) - fi - - [[ "$fcv" == ${{ matrix.toolchain.version }}* ]] && (echo "found ${{ env.FC }} version: $fcv") || (echo "unexpected ${{ env.FC }} version: $fcv"; exit 1) - [[ "$ccv" == ${{ matrix.toolchain.version }}* ]] && (echo "found ${{ env.CC }} version: $ccv") || (echo "unexpected ${{ env.CC }} version: $ccv"; exit 1) - [[ "$cxxv" == ${{ matrix.toolchain.version }}* ]] && (echo "found ${{ env.CXX }} version: $cxxv") || (echo "unexpected ${{ env.CXX }} version: $cxxv"; exit 1) - - - name: Test compile (bash) + uses: ./.github/actions/test-fc + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} + + - name: Test C compiler + continue-on-error: true if: steps.setup-fortran.outcome == 'success' - shell: bash - env: - FC: ${{ steps.setup-fortran.outputs.fc }} - CC: ${{ steps.setup-fortran.outputs.cc }} - CXX: ${{ steps.setup-fortran.outputs.cxx }} - run: | - # macos-13/gfortran 7-9 compatibility workaround - args="" - if [ "$RUNNER_OS" == "macOS" ]; then - if [[ $(sw_vers -productVersion) == 13* ]] && \ - [[ ${{ matrix.toolchain.compiler }} == "gcc" ]] && \ - [[ ${{ matrix.toolchain.version }} =~ ^(7|8|9)$ ]] - then - args="-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib" - fi - fi - - ${{ env.FC }} $args -o hw hw.f90 - output=$(./hw '2>&1') - [[ "$output" == *"hello world"* ]] && echo "$output" || (echo "Unexpected Fortran program output: $output"; exit 1) - rm hw - - # gcc/g++ 7-9 broken on macos-13, skip tests - if [[ $args == "" ]]; then - ${{ env.CC }} -o hw hw.c - output=$(./hw '2>&1') - [[ "$output" == *"hello world"* ]] && echo "$output" || (echo "Unexpected C program output: $output"; exit 1) - rm hw - - ${{ env.CXX }} -o hw hw.cpp - output=$(./hw '2>&1') - [[ "$output" == *"hello world"* ]] && echo "$output" || (echo "Unexpected C++ program output: $output"; exit 1) - rm hw - fi - - - name: Test compile Fortran (pwsh) - if: ${{ steps.setup-fortran.outcome == 'success' && runner.os == 'Windows' }} - shell: pwsh - env: - FC: ${{ steps.setup-fortran.outputs.fc }} - CC: ${{ steps.setup-fortran.outputs.cc }} - CXX: ${{ steps.setup-fortran.outputs.cxx }} - run: | - ${{ env.FC }} -o hw.exe hw.f90 - $output=$(& ".\hw.exe") - if ($output -match "hello world") { - write-output $output - } else { - write-output "unexpected output: $output" - exit 1 - } - rm hw.exe - - - name: Test compile (powershell) - if: ${{ steps.setup-fortran.outcome == 'success' && runner.os == 'Windows' }} - shell: powershell - env: - FC: ${{ steps.setup-fortran.outputs.fc }} - CC: ${{ steps.setup-fortran.outputs.cc }} - CXX: ${{ steps.setup-fortran.outputs.cxx }} - run: | - ${{ env.FC }} -o hw.exe hw.f90 - $output=$(& ".\hw.exe") - if ($output -match "hello world") { - write-output $output - } else { - write-output "unexpected output: $output" - exit 1 - } - rm hw.exe - - - name: Test compile (cmd) - if: ${{ steps.setup-fortran.outcome == 'success' && runner.os == 'Windows' }} - shell: cmd - env: - FC: ${{ steps.setup-fortran.outputs.fc }} - CC: ${{ steps.setup-fortran.outputs.cc }} - CXX: ${{ steps.setup-fortran.outputs.cxx }} - run: | - ${{ env.FC }} -o hw.exe hw.f90 - for /f "tokens=* usebackq" %%f in (`.\hw.exe`) do @set "OUTPUT=%%f" - if "%OUTPUT%"=="hello world" ( - echo %OUTPUT% - ) else ( - echo unexpected output: %OUTPUT% - exit 1 - ) - del hw.exe - - full_test: + uses: ./.github/actions/test-cc + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} + + - name: Test C++ compiler + continue-on-error: true + if: steps.setup-fortran.outcome == 'success' + uses: ./.github/actions/test-cxx + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} + + test_full: name: Full compatibility test if: github.event_name == 'schedule' runs-on: ${{ matrix.os }} @@ -241,161 +131,50 @@ jobs: toolchain: {compiler: intel} - os: macos-11 toolchain: {compiler: intel} - steps: - - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Fortran - continue-on-error: true id: setup-fortran + continue-on-error: true uses: ./ with: compiler: ${{ matrix.toolchain.compiler }} version: ${{ matrix.toolchain.version }} - - name: Check compiler version + - name: Test Fortran compiler if: steps.setup-fortran.outcome == 'success' - shell: bash - env: - FC: ${{ steps.setup-fortran.outputs.fc }} - CC: ${{ steps.setup-fortran.outputs.cc }} - CXX: ${{ steps.setup-fortran.outputs.cxx }} - run: | - if ([ "$RUNNER_OS" == "Windows" ] && [[ "${{ matrix.toolchain.compiler }}" =~ "intel" ]]); then - # only last line of output captured by command substitution, write to temp file instead - ${{ env.FC }} //QV > "$RUNNER_TEMP/${{ env.FC }}.ver" 2>&1 - ${{ env.CC }} //QV > "$RUNNER_TEMP/${{ env.CC }}.ver" 2>&1 - ${{ env.CXX }} //QV > "$RUNNER_TEMP/${{ env.CXX }}.ver" 2>&1 - - fcv=$(cat "$RUNNER_TEMP/${{ env.FC }}.ver" | head -n 1) - ccv=$(cat "$RUNNER_TEMP/${{ env.CC }}.ver" | head -n 1) - cxxv=$(cat "$RUNNER_TEMP/${{ env.CXX }}.ver" | head -n 1) - - fcv=${fcv#*Version } - fcv=${fcv%% Build*} - ccv=${ccv#*Version } - ccv=${ccv%% Build*} - cxxv=${cxxv#*Version } - cxxv=${cxxv%% Build*} - else - fcv=$(${{ env.FC }} --version | head -n 1) - ccv=$(${{ env.CC }} --version | head -n 1) - cxxv=$(${{ env.CXX }} --version | head -n 1) - - fcv=$(echo "$fcv" | grep -woE '[0123456789.]+' | head -n 1) - ccv=$(echo "$ccv" | grep -woE '[0123456789.]+' | head -n 1) - cxxv=$(echo "$cxxv" | grep -woE '[0123456789.]+' | head -n 1) - fi - - [[ "$fcv" == ${{ matrix.toolchain.version }}* ]] && (echo "found ${{ env.FC }} version: $fcv") || (echo "unexpected ${{ env.FC }} version: $fcv"; exit 1) - [[ "$ccv" == ${{ matrix.toolchain.version }}* ]] && (echo "found ${{ env.CC }} version: $ccv") || (echo "unexpected ${{ env.CC }} version: $ccv"; exit 1) - [[ "$cxxv" == ${{ matrix.toolchain.version }}* ]] && (echo "found ${{ env.CXX }} version: $cxxv") || (echo "unexpected ${{ env.CXX }} version: $cxxv"; exit 1) - - - name: Test compile (bash) + uses: ./.github/actions/test-fc + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} + + - name: Test C compiler + continue-on-error: true if: steps.setup-fortran.outcome == 'success' - shell: bash - env: - FC: ${{ steps.setup-fortran.outputs.fc }} - CC: ${{ steps.setup-fortran.outputs.cc }} - CXX: ${{ steps.setup-fortran.outputs.cxx }} - run: | - # macos-13/gfortran 7-9 compatibility workaround - args="" - if [ "$RUNNER_OS" == "macOS" ]; then - if [[ $(sw_vers -productVersion) == 13* ]] && \ - [[ ${{ matrix.toolchain.compiler }} == "gcc" ]] && \ - [[ ${{ matrix.toolchain.version }} =~ ^(7|8|9)$ ]] - then - args="-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib" - fi - fi - - ${{ env.FC }} $args -o hw hw.f90 - output=$(./hw '2>&1') - [[ "$output" == *"hello world"* ]] && echo "$output" || (echo "Unexpected Fortran program output: $output"; exit 1) - rm hw - - # gcc/g++ 7-9 broken on macos-13, skip tests - if [[ $args == "" ]]; then - ${{ env.CC }} -o hw hw.c - output=$(./hw '2>&1') - [[ "$output" == *"hello world"* ]] && echo "$output" || (echo "Unexpected C program output: $output"; exit 1) - rm hw - - ${{ env.CXX }} -o hw hw.cpp - output=$(./hw '2>&1') - [[ "$output" == *"hello world"* ]] && echo "$output" || (echo "Unexpected C++ program output: $output"; exit 1) - rm hw - fi - - - name: Test compile Fortran (pwsh) - if: ${{ steps.setup-fortran.outcome == 'success' && runner.os == 'Windows' }} - shell: pwsh - env: - FC: ${{ steps.setup-fortran.outputs.fc }} - CC: ${{ steps.setup-fortran.outputs.cc }} - CXX: ${{ steps.setup-fortran.outputs.cxx }} - run: | - ${{ env.FC }} -o hw.exe hw.f90 - $output=$(& ".\hw.exe") - if ($output -match "hello world") { - write-output $output - } else { - write-output "unexpected output: $output" - exit 1 - } - rm hw.exe - - - name: Test compile (powershell) - if: ${{ steps.setup-fortran.outcome == 'success' && runner.os == 'Windows' }} - shell: powershell - env: - FC: ${{ steps.setup-fortran.outputs.fc }} - CC: ${{ steps.setup-fortran.outputs.cc }} - CXX: ${{ steps.setup-fortran.outputs.cxx }} - run: | - ${{ env.FC }} -o hw.exe hw.f90 - $output=$(& ".\hw.exe") - if ($output -match "hello world") { - write-output $output - } else { - write-output "unexpected output: $output" - exit 1 - } - rm hw.exe - - - name: Test compile (cmd) - if: ${{ steps.setup-fortran.outcome == 'success' && runner.os == 'Windows' }} - shell: cmd - env: - FC: ${{ steps.setup-fortran.outputs.fc }} - CC: ${{ steps.setup-fortran.outputs.cc }} - CXX: ${{ steps.setup-fortran.outputs.cxx }} - run: | - ${{ env.FC }} -o hw.exe hw.f90 - for /f "tokens=* usebackq" %%f in (`.\hw.exe`) do @set "OUTPUT=%%f" - if "%OUTPUT%"=="hello world" ( - echo %OUTPUT% - ) else ( - echo unexpected output: %OUTPUT% - exit 1 - ) - del hw.exe + uses: ./.github/actions/test-cc + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} + + - name: Test C++ compiler + continue-on-error: true + if: steps.setup-fortran.outcome == 'success' + uses: ./.github/actions/test-cxx + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} - name: Create compatibility report shell: bash run: | - if [[ "${{ steps.setup-fortran.outcome }}" == "success" ]]; then - support="✓" - else - support="" - fi - mkdir compat + support=$([ "${{ steps.setup-fortran.outcome }}" == "success" ] && echo "✓" || echo "") prefix="${{ matrix.os }},${{ matrix.toolchain.compiler }},${{ matrix.toolchain.version }}" - echo "$prefix,$support" >> "compat/${prefix//,/_}.csv" + report="compat/${prefix//,/_}.csv" + echo "$prefix,$support" >> "$report" + cat "$report" - name: Upload compatibility report uses: actions/upload-artifact@v3 @@ -406,7 +185,7 @@ jobs: compat: name: Report compatibility if: github.event_name == 'schedule' - needs: full_test + needs: test_full runs-on: ubuntu-latest permissions: contents: write @@ -414,7 +193,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v4 diff --git a/README.md b/README.md index 3a3fb4de..629b1aa7 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![GitHub tag](https://img.shields.io/github/tag/fortran-lang/setup-fortran.svg)](https://github.com/fortran-lang/setup-fortran/tags/latest) -Action to setup a Fortran compiler. +Set up a Fortran compiler on Ubuntu, macOS and Windows runners. @@ -23,10 +23,6 @@ Action to setup a Fortran compiler. ## Usage -This action sets up a Fortran compiler on Ubuntu, MacOS and Windows runners. - -C/C++ compilers of the same toolchain/version are provided where possible, otherwise (if a standalone Fortran compiler is selected) defaulting to the preinstalled GCC. - ```yaml jobs: test: @@ -75,6 +71,8 @@ The action sets the following outputs: - `cc`: C compiler executable, e.g. `gcc` - `cxx`: C++ compiler executable, e.g. `g++` +C/C++ compilers of the same toolchain/version are provided where possible, otherwise (if a standalone Fortran compiler is selected) defaulting to the preinstalled GCC. While this action attempts to guarantee Fortran compiler compatibility with all supported platform/toolchain/version combinations, no corresponding guarantee is made with regard to C/C++ compilers — use at your own risk. + ## Environment variables diff --git a/setup-fortran.sh b/setup-fortran.sh index 5fc4ff85..33a087e2 100755 --- a/setup-fortran.sh +++ b/setup-fortran.sh @@ -14,10 +14,19 @@ require_fetch() fi } - install_gcc_brew() { - brew install gcc@${version} + # check if gcc preinstalled via brew + cur=$(brew list --versions gcc | cut -d' ' -f2) + maj=$(echo $cur | cut -d'.' -f1) + # if already installed, nothing to do + if [ "$maj" == "$version" ]; then + echo "GCC $version already installed" + else + # otherwise install selected version + brew install gcc@${version} + fi + ln -fs /usr/local/bin/gfortran-${version} /usr/local/bin/gfortran ln -fs /usr/local/bin/gcc-${version} /usr/local/bin/gcc ln -fs /usr/local/bin/g++-${version} /usr/local/bin/g++ @@ -43,9 +52,17 @@ install_gcc_brew() install_gcc_apt() { - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test - sudo apt-get update - sudo apt-get install -y gcc-${version} gfortran-${version} g++-${version} + # check if gcc preinstalled via apt + cur=$(apt show gcc | grep "Version" | cut -d':' -f3 | cut -d'-' -f1) + maj=$(echo $cur | cut -d'.' -f1) + if [ "$maj" == "$version" ]; then + echo "GCC $version already installed" + else + sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test + sudo apt-get update + sudo apt-get install -y gcc-${version} gfortran-${version} g++-${version} + fi + sudo update-alternatives \ --install /usr/bin/gcc gcc /usr/bin/gcc-${version} 100 \ --slave /usr/bin/gfortran gfortran /usr/bin/gfortran-${version} \ @@ -59,47 +76,65 @@ install_gcc_apt() install_gcc_choco() { - case $version in - 13) - choco install mingw --version 13.2.0 --force - # mingw 13 on Windows doesn't create shims (http://disq.us/p/2w5c5tj) - # so hide Strawberry compilers and manually add mingw bin dir to PATH - mv /c/Strawberry/c/bin/gfortran "$RUNNER_TEMP/gfortran" - mv /c/Strawberry/c/bin/gcc "$RUNNER_TEMP/gcc" - mv /c/Strawberry/c/bin/g++ "$RUNNER_TEMP/g++" - echo "C:\ProgramData\mingw64\mingw64\bin" >> $GITHUB_PATH - ;; - 12) - choco install mingw --version 12.2.0 --force - ;; - 11) - choco install mingw --version 11.2.0 --force - ;; - 10) - choco install mingw --version 10.3.0 --force - ;; - 9) - choco install mingw --version 9.4.0 --force - ;; - 8) - choco install mingw --version 8.5.0 --force - ;; - *) - echo "Unsupported version: $version (choose 8-13)" - exit 1 - ;; - esac - - export FC="gfortran" - export CC="gcc" - export CXX="g++" + # check if mingw preinstalled via choco, falling back to check directly for gfortran + cur=$(choco list -e mingw -r | cut -d'|' -f2) + if [[ "$cur" == "" ]] && [[ "$(which gfortran)" != "" ]]; then + cur=$(gfortran --version | grep -woE '[0123456789.]+' | head -n 1) + fi + maj=$(echo $cur | cut -d'.' -f1) + # if already installed, nothing to do + if [ "$maj" == "$version" ]; then + echo "GCC $version already installed" + else + # otherwise hide preinstalled mingw compilers + mkdir "$RUNNER_TEMP/mingw64" + mv /c/mingw64/bin/gfortran "$RUNNER_TEMP/mingw64/gfortran" + mv /c/mingw64/bin/gcc "$RUNNER_TEMP/mingw64/gcc" + mv /c/mingw64/bin/g++ "$RUNNER_TEMP/mingw64/g++" + # ...and install selected version + case $version in + 13) + choco install mingw --version 13.2.0 --force + # mingw 13 on Windows doesn't create shims (http://disq.us/p/2w5c5tj) + # so hide Strawberry compilers and manually add mingw bin dir to PATH + mkdir "$RUNNER_TEMP/strawberry" + mv /c/Strawberry/c/bin/gfortran "$RUNNER_TEMP/strawberry/gfortran" + mv /c/Strawberry/c/bin/gcc "$RUNNER_TEMP/strawberry/gcc" + mv /c/Strawberry/c/bin/g++ "$RUNNER_TEMP/strawberry/g++" + echo "C:\ProgramData\mingw64\mingw64\bin" >> $GITHUB_PATH + ;; + 12) + choco install mingw --version 12.2.0 --force + ;; + 11) + choco install mingw --version 11.2.0 --force + ;; + 10) + choco install mingw --version 10.3.0 --force + ;; + 9) + choco install mingw --version 9.4.0 --force + ;; + 8) + choco install mingw --version 8.5.0 --force + ;; + *) + echo "Unsupported version: $version (choose 8-13)" + exit 1 + ;; + esac + fi - # missing DLL can cause successfully compiled executables to fail at runtime + # missing DLL workaround FCDIR=/c/ProgramData/Chocolatey/bin LNDIR=/c/ProgramData/Chocolatey/lib/mingw/tools/install/mingw64/bin if [ -d "$FCDIR" ] && [ -f "$LNDIR/libgfortran-5.dll" ] && [ ! -f "$FCDIR/libgfortran-5.dll" ]; then ln -s "$LNDIR/libgfortran-5.dll" "$FCDIR/libgfortran-5.dll" fi + + export FC="gfortran" + export CC="gcc" + export CXX="g++" } install_gcc() diff --git a/wide_compat_reports.py b/wide_compat_reports.py index 1715fac9..fb663f40 100644 --- a/wide_compat_reports.py +++ b/wide_compat_reports.py @@ -22,7 +22,8 @@ index="runner", columns=["compiler", "version"], values="support", - sort=False + sort=False, + aggfunc="first" ).sort_values(by=["runner"]) # write wide CSV