diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5e0cf6..b75c0a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,10 +3,8 @@ name: CI on: push: branches: [main] - paths-ignore: ['LICENSE', 'README.rst'] pull_request: branches: [main] - paths-ignore: ['LICENSE', 'README.rst'] workflow_dispatch: env: @@ -16,34 +14,58 @@ env: jobs: # - # Test project on Ubuntu with Intel ifx compiler + # Test Fortuno in various system configurations # - ubuntu-ifx: - - runs-on: ubuntu-latest + fortuno-test: + + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + toolchain: [Intel, GNU] + exclude: + - os: macos-latest + toolchain: Intel steps: - name: Check-out code uses: actions/checkout@v3 - - name: Setup Intel oneAPI + - name: Setup Intel compiler + if: ${{ contains(matrix.toolchain, 'Intel') }} uses: rscohn2/setup-oneapi@v0 with: components: ifx - - name: Set compiler environment + - name: Setup Intel environment + if: ${{ contains(matrix.toolchain, 'Intel') }} run: | + source /opt/intel/oneapi/setvars.sh + printenv >> ${GITHUB_ENV} echo "FC=ifx" >> ${GITHUB_ENV} echo "FPM_FC=ifx" >> ${GITHUB_ENV} + - name: Setup GNU compiler + if: ${{ contains(matrix.toolchain, 'GNU') }} + uses: fortran-lang/setup-fortran@v1 + with: + compiler: gcc + version: 13 + + - name: Setup GNU environment + if: ${{ contains(matrix.toolchain, 'GNU') }} + run: | + echo "FC=${{ env.FC }}" >> ${GITHUB_ENV} + echo "FPM_FC=${{ env.FC }}" >> ${GITHUB_ENV} + - name: Setup build tools run: | pip install cmake fpm meson ninja - name: Build Fortuno run: | - source /opt/intel/oneapi/setvars.sh cmake -B ${BUILD_DIR} -G Ninja -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} cmake --build ${BUILD_DIR} cmake --install ${BUILD_DIR} @@ -51,35 +73,18 @@ jobs: - name: Test CMake export run: | - source /opt/intel/oneapi/setvars.sh CMAKE_PREFIX_PATH=${INSTALL_DIR} cmake -B ${BUILD_DIR} -G Ninja test/export cmake --build ${BUILD_DIR} ${BUILD_DIR}/testapp rm -rf ${BUILD_DIR} - - name: Test PkgConfig export - run: | - source /opt/intel/oneapi/setvars.sh - export LD_LIBRARY_PATH="${PWD}/${INSTALL_DIR}/lib:${LD_LIBRARY_PATH}" - export PKG_CONFIG_PATH="${PWD}/${INSTALL_DIR}/lib/pkgconfig:${PKG_CONFIG_PATH}" - cflags="$(pkg-config --cflags fortuno)" - lflags="$(pkg-config --libs fortuno)" - mkdir ${BUILD_DIR} - pushd ${BUILD_DIR} - ifx ${cflags} ${lflags} -o testapp ../test/export/app/testapp.f90 - ./testapp - popd - rm -rf ${BUILD_DIR} - - name: Test fpm export run: | - source /opt/intel/oneapi/setvars.sh cd test/export fpm run testapp - - name: Test meson PkgConfig export + - name: Test Meson pkgconfig export run: | - source /opt/intel/oneapi/setvars.sh export PKG_CONFIG_PATH="${PWD}/${INSTALL_DIR}/lib/pkgconfig:${PKG_CONFIG_PATH}" cd test/export meson setup -Dfortuno_subproject=false ${BUILD_DIR} @@ -87,9 +92,8 @@ jobs: ${BUILD_DIR}/testapp rm -rf ./${BUILD_DIR} - - name: Test meson subproject export + - name: Test Meson subproject export run: | - source /opt/intel/oneapi/setvars.sh FORTUNO_DIR=${PWD} GIT_REV=$(git rev-parse HEAD) cd test/export diff --git a/README.rst b/README.rst index dec7b1d..af8b98b 100644 --- a/README.rst +++ b/README.rst @@ -227,23 +227,24 @@ detailed explanations, further features and use cases. Known issues ============ -In order to offer a simple user interface, and to be modular, flexible and -extensible, Fortuno uses modern Fortran constructs extensively. Unfortunately, -this seems to be still challenging for some Fortran compilers. The following -table gives an overview over the compilers which were tested for building -Fortuno. +In order to offer a simple user interface and to allow for maximal reusability +and extensibility, Fortuno uses object-oriented Fortran constructs extensively. +Unfortunately, this is challenging for some older Fortran compilers. The +following table gives an overview over the compilers which were successfully +tested for building Fortuno. Make sure to use those compilers or any newer +versions of them. +------------------------+-----------------------------------------------------+ | Compiler | Status | +========================+=====================================================+ | Intel 2024.0 | * serial: OK | -| x86_64/Linux | * mpi (with Intel MPI): OK | +| | * mpi: OK | +------------------------+-----------------------------------------------------+ | NAG 7.1 (build 7145) | * serial: OK | -| x86_64/Linux | * mpi (MPICH 4.1): OK | +| | * mpi: OK | +------------------------+-----------------------------------------------------+ -| GNU 13.2 | * serial: Fails (Internal compiler error) | -| x86_64/Linux | | +| GNU 12.2 | * serial: OK | +| | * mpi: OK | +------------------------+-----------------------------------------------------+ If you are aware of other compilers being able to build Fortuno, open a pull diff --git a/src/fortuno/argumentparser.f90 b/src/fortuno/argumentparser.f90 index ce180f4..1c792a8 100644 --- a/src/fortuno/argumentparser.f90 +++ b/src/fortuno/argumentparser.f90 @@ -130,6 +130,8 @@ subroutine argument_parser_parse_args(this, argumentvalues, logger, exitcode) allocate(argumentvalues%argvals(0)) allocate(posargs(0)) optionsallowed = .true. + + ! Process all arguments iarg = 0 argloop: do while (iarg < nargs) iarg = iarg + 1 @@ -183,10 +185,20 @@ subroutine argument_parser_parse_args(this, argumentvalues, logger, exitcode) return end associate end do argloop + + ! Check collected positional arguments associate (argdef => this%argdefs(nargdefs)) + ! If the last argdef was not an option, store all position arguments under this name if (.not. allocated(argdef%longopt) .and. argdef%shortopt == "") then - argumentvalues%argvals = [argumentvalues%argvals,& - & argument_value(name=argdef%name, argval=string_list(posargs))] + ! argumentvalues%argvals = [argumentvalues%argvals,& + ! & argument_value(name=argdef%name, argval=string_list(posargs))] + ! Workaround:gfortran:13.2 + block + class(*), allocatable :: tmp + tmp = string_list(posargs) + argumentvalues%argvals = [argumentvalues%argvals,& + & argument_value(name=argdef%name, argval=tmp)] + end block else if (size(posargs) > 1) then call logger%log_error("Superfluous positional arguments found") exitcode = 1