From de95e6998d3c2a0d03bba047d4fbe71d2ec2e9d3 Mon Sep 17 00:00:00 2001 From: Jacob Williams Date: Sun, 22 Feb 2026 22:32:30 -0600 Subject: [PATCH 1/8] experiment to add -ftrampoline-impl=heap for gfortran See #599 --- CMakeLists.txt | 6 ++++++ fpm.toml | 4 ++++ json-fortran.fobis | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 68574a236..64cb8183a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,6 +235,12 @@ set_target_properties ( ${LIB_NAME} LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR} ) +# Add trampoline heap implementation flag for gfortran on Linux +if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + target_link_options(${LIB_NAME} PRIVATE -ftrampoline-impl=heap) + target_link_options(${LIB_NAME}-static PRIVATE -ftrampoline-impl=heap) +endif() + #------------------------------------- # Build the documentation with FORD #------------------------------------- diff --git a/fpm.toml b/fpm.toml index d8270b49b..db8b93ce9 100644 --- a/fpm.toml +++ b/fpm.toml @@ -7,6 +7,10 @@ homepage = "https://github.com/jacobwilliams/json-fortran" categories = ["io"] keywords = ["JSON"] +[features] +debug.gfortran.linux.link-time-flags = "-ftrampoline-impl=heap" +release.gfortran.linux.link-time-flags = "-ftrampoline-impl=heap" + [build] external-modules = "ifcore" auto-executables = true diff --git a/json-fortran.fobis b/json-fortran.fobis index 0a9ef618e..127b39563 100644 --- a/json-fortran.fobis +++ b/json-fortran.fobis @@ -12,6 +12,7 @@ $FORD_FILE = ford.md $STATIC_LIB = libjsonfortran.a $SHARED_LIB = libjsonfortran.so $OPTIMIZE = -O2 +$LFLAGS_GNU = -ftrampoline-impl=heap $CSTATIC_GNU = -c -fbacktrace -Wall -Wextra -Wno-maybe-uninitialized -Wno-unused-function -pedantic $DEBUG_GNU = -O0 -g3 -Warray-bounds -Wcharacter-truncation -Wline-truncation -Wimplicit-interface -Wimplicit-procedure -Wunderflow -fcheck=all -fmodule-private -ffree-line-length-132 -fimplicit-none -fbacktrace -fdump-core -finit-real=nan -fall-intrinsics $CSTATIC_INT = -c -std18 @@ -69,12 +70,14 @@ exclude_dirs = $EXCLUDE_DIRS description = Build library with GNU gfortran by optimized-static flags compiler = gnu cflags = $CSTATIC_GNU $OPTIMIZE +lflags = $LFLAGS_GNU template = template-static [static-gnu-debug] description = Build library with GNU gfortran by debug-static flags compiler = gnu cflags = $CSTATIC_GNU $DEBUG_GNU +lflags = $LFLAGS_GNU template = template-static [static-intel] @@ -93,12 +96,14 @@ template = template-static description = Build library with GNU gfortran by optimized-shared flags compiler = gnu cflags = $CSTATIC_GNU $OPTIMIZE +lflags = $LFLAGS_GNU template = template-shared [shared-gnu-debug] description = Build library with GNU gfortran by debug-shared flags compiler = gnu cflags = $CSTATIC_GNU $DEBUG_GNU +lflags = $LFLAGS_GNU template = template-shared [shared-intel] @@ -118,12 +123,14 @@ template = template-shared description = Build all tests with GNU gfortran by optimized-static flags compiler = gnu cflags = $CSTATIC_GNU $OPTIMIZE +lflags = $LFLAGS_GNU template = template-tests [tests-gnu-debug] description = Build all tests with GNU gfortran by debug-static flags compiler = gnu cflags = $CSTATIC_GNU $DEBUG_GNU +lflags = $LFLAGS_GNU template = template-tests [tests-intel] From be2657b0a8e40ca6a3ca686d1a201bb6d2918750 Mon Sep 17 00:00:00 2001 From: Jacob Williams Date: Mon, 23 Feb 2026 21:26:23 -0600 Subject: [PATCH 2/8] updates --- .github/workflows/CI.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a346217c6..f5241df46 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -60,11 +60,11 @@ jobs: run: | python -m pip install --upgrade pip #pip install ford FoBiS.py pygooglechart fpm - pip install ford pygooglechart fpm + pip install ford pygooglechart fpm>=0.13 # just get the latest FoBiS from git: - # git clone https://github.com/szaghi/FoBiS.git + git clone https://github.com/szaghi/FoBiS.git # use a fork until there is a new release: - git clone https://github.com/jacobwilliams/FoBiS.git + # git clone https://github.com/jacobwilliams/FoBiS.git if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Install GFortran Linux @@ -94,7 +94,7 @@ jobs: sudo apt update && sudo apt install -y valgrind fpm --version gfortran --version - fpm test "*" --runner "valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1" + fpm test "*" --link-flag "-ftrampoline-impl=heap" --runner "valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1" - name: Compile_with_cmake # CMake build with unit tests, no documentation, with coverage analysis From b76de24bb135705f04725be65d5e0b875bfb399b Mon Sep 17 00:00:00 2001 From: Jacob Williams Date: Mon, 23 Feb 2026 21:52:08 -0600 Subject: [PATCH 3/8] try fortran-lang/setup-fpm@v7 added -ftrampoline-impl=heap to build.sh --- .github/workflows/CI.yml | 7 ++++++- build.sh | 13 +++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f5241df46..e099bdba1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -55,12 +55,17 @@ jobs: echo "PYTHONPATH=$MYDIR/FoBiS/src/main/python:$PYTHONPATH" >> $GITHUB_ENV echo "PATH=$MYDIR/FoBiS/src/main/python:$PATH" >> $GITHUB_ENV + - name: Setup Fortran Package Manager + uses: fortran-lang/setup-fpm@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Install Python dependencies if: contains( matrix.os, 'ubuntu') run: | python -m pip install --upgrade pip #pip install ford FoBiS.py pygooglechart fpm - pip install ford pygooglechart fpm>=0.13 + pip install ford pygooglechart # just get the latest FoBiS from git: git clone https://github.com/szaghi/FoBiS.git # use a fork until there is a new release: diff --git a/build.sh b/build.sh index 384717fbc..b4c2d01b0 100755 --- a/build.sh +++ b/build.sh @@ -116,7 +116,6 @@ argument is passed. Additionally, A custom compiler may be passed to the 'compil flag, but appropriate 'cflags' should also be passed to the script.\n\n" } - while [ "$#" -ge "1" ]; do # Get command line arguments while there are more left to process key="$1" # Command line args are key-value pairs or value-less keys @@ -257,6 +256,12 @@ while [ "$#" -ge "1" ]; do # Get command line arguments while there are more lef shift # look at next argument done # with argument parsing loop +# linker flags for gfortran: +COMPILERLFLAGS="" +if [ $FCOMPILER = gnu ]; then + COMPILERLFLAGS='-lflags "-ftrampoline-impl=heap"' +fi + # if no compiler selected, then we're defaulting to gnu, and need to check that the cflags are set if [ "$FCOMPILER" = 'gnu' ] && [ -z "$FCOMPILERFLAGS" ]; then FCOMPILERFLAGS="$GNUCOMPILERFLAGS" @@ -279,7 +284,7 @@ fi if [[ $TRY_UNICODE == [yY]* ]]; then echo "Trying to compile library with Unicode/UCS4 support" - FoBiS.py build -ch -compiler "${FCOMPILER}" "${CUSTOM[@]}" -cflags "${FCOMPILERFLAGS}" -dbld "${BINDIR}" -s "${INTROSPECDIR}" -dmod ./ -dobj ./ -t "${UCS4TESTCODE}" -o "${UCS4TESTCODE%.f90}" -colors + FoBiS.py build -ch -compiler "${FCOMPILER}" "${CUSTOM[@]}" "${COMPILERLFLAGS}" -cflags "${FCOMPILERFLAGS}" -dbld "${BINDIR}" -s "${INTROSPECDIR}" -dmod ./ -dobj ./ -t "${UCS4TESTCODE}" -o "${UCS4TESTCODE%.f90}" -colors if "${BINDIR}/${UCS4TESTCODE%.f90}"; then DEFINES="-DUSE_UCS4 -Wunused-function" fi @@ -289,7 +294,7 @@ fi echo "" echo "Building library..." -FoBiS.py build -ch -compiler ${FCOMPILER} "${CUSTOM[@]}" -cflags "${FCOMPILERFLAGS} ${DEFINES} ${REAL_KIND} ${INT_KIND}" ${COVERAGE} ${PROFILING} -dbld ${LIBDIR} -s ${SRCDIR} -dmod ./ -dobj ./ -t ${MODCODE} -o ${LIBOUT} -mklib static -colors +FoBiS.py build -ch -compiler ${FCOMPILER} "${CUSTOM[@]}" $COMPILERLFLAGS -cflags "${FCOMPILERFLAGS} ${DEFINES} ${REAL_KIND} ${INT_KIND}" ${COVERAGE} ${PROFILING} -dbld ${LIBDIR} -s ${SRCDIR} -dmod ./ -dobj ./ -t ${MODCODE} -o ${LIBOUT} -mklib static -colors #build the unit tests (uses the above library): if [[ $JF_SKIP_TESTS != [yY]* ]]; then @@ -302,7 +307,7 @@ if [[ $JF_SKIP_TESTS != [yY]* ]]; then for TEST in "${TESTDIR%/}"/jf_test_*.[fF]90; do THIS_TEST=${TEST##*/} echo "Build ${THIS_TEST%.[fF]90}" - FoBiS.py build -ch -compiler ${FCOMPILER} "${CUSTOM[@]}" -cflags "${FCOMPILERFLAGS} ${DEFINES}" ${COVERAGE} ${PROFILING} -dbld "${BINDIR}" -s "${TESTDIR}" -i "${LIBDIR}" -libs "${LIBDIR}/${LIBOUT}" -dmod ./ -dobj ./ -t "${THIS_TEST}" -o "${THIS_TEST%.[fF]90}" -colors + FoBiS.py build -ch -compiler ${FCOMPILER} "${CUSTOM[@]}" "${COMPILERLFLAGS}" -cflags "${FCOMPILERFLAGS} ${DEFINES}" ${COVERAGE} ${PROFILING} -dbld "${BINDIR}" -s "${TESTDIR}" -i "${LIBDIR}" -libs "${LIBDIR}/${LIBOUT}" -dmod ./ -dobj ./ -t "${THIS_TEST}" -o "${THIS_TEST%.[fF]90}" -colors done else echo "Skip building the unit tests since \$JF_SKIP_TESTS has been set to 'true'." From b5418e96e966ba6ec1706b4982fe86d19b8a51e7 Mon Sep 17 00:00:00 2001 From: Jacob Williams Date: Mon, 23 Feb 2026 21:57:35 -0600 Subject: [PATCH 4/8] fix --- build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index b4c2d01b0..314f61a7c 100755 --- a/build.sh +++ b/build.sh @@ -284,7 +284,7 @@ fi if [[ $TRY_UNICODE == [yY]* ]]; then echo "Trying to compile library with Unicode/UCS4 support" - FoBiS.py build -ch -compiler "${FCOMPILER}" "${CUSTOM[@]}" "${COMPILERLFLAGS}" -cflags "${FCOMPILERFLAGS}" -dbld "${BINDIR}" -s "${INTROSPECDIR}" -dmod ./ -dobj ./ -t "${UCS4TESTCODE}" -o "${UCS4TESTCODE%.f90}" -colors + FoBiS.py build -ch -compiler "${FCOMPILER}" "${CUSTOM[@]}" $COMPILERLFLAGS -cflags "${FCOMPILERFLAGS}" -dbld "${BINDIR}" -s "${INTROSPECDIR}" -dmod ./ -dobj ./ -t "${UCS4TESTCODE}" -o "${UCS4TESTCODE%.f90}" -colors if "${BINDIR}/${UCS4TESTCODE%.f90}"; then DEFINES="-DUSE_UCS4 -Wunused-function" fi @@ -307,7 +307,7 @@ if [[ $JF_SKIP_TESTS != [yY]* ]]; then for TEST in "${TESTDIR%/}"/jf_test_*.[fF]90; do THIS_TEST=${TEST##*/} echo "Build ${THIS_TEST%.[fF]90}" - FoBiS.py build -ch -compiler ${FCOMPILER} "${CUSTOM[@]}" "${COMPILERLFLAGS}" -cflags "${FCOMPILERFLAGS} ${DEFINES}" ${COVERAGE} ${PROFILING} -dbld "${BINDIR}" -s "${TESTDIR}" -i "${LIBDIR}" -libs "${LIBDIR}/${LIBOUT}" -dmod ./ -dobj ./ -t "${THIS_TEST}" -o "${THIS_TEST%.[fF]90}" -colors + FoBiS.py build -ch -compiler ${FCOMPILER} "${CUSTOM[@]}" $COMPILERLFLAGS -cflags "${FCOMPILERFLAGS} ${DEFINES}" ${COVERAGE} ${PROFILING} -dbld "${BINDIR}" -s "${TESTDIR}" -i "${LIBDIR}" -libs "${LIBDIR}/${LIBOUT}" -dmod ./ -dobj ./ -t "${THIS_TEST}" -o "${THIS_TEST%.[fF]90}" -colors done else echo "Skip building the unit tests since \$JF_SKIP_TESTS has been set to 'true'." From 39bda83c5b6aa4e05f2e92f8b20590369118f68e Mon Sep 17 00:00:00 2001 From: Jacob Williams Date: Tue, 24 Feb 2026 21:27:30 -0600 Subject: [PATCH 5/8] get fobis from pypi again now that it is updated --- .github/workflows/CI.yml | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e099bdba1..e14582340 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -47,14 +47,6 @@ jobs: - name: Setup Graphviz uses: ts-graphviz/setup-graphviz@v2.0.2 - - name: Set current directory in env variable - run: echo "MYDIR=$(pwd)" >> $GITHUB_ENV - - - name: Set PYTHONPATH and PATH for later steps - run: | - echo "PYTHONPATH=$MYDIR/FoBiS/src/main/python:$PYTHONPATH" >> $GITHUB_ENV - echo "PATH=$MYDIR/FoBiS/src/main/python:$PATH" >> $GITHUB_ENV - - name: Setup Fortran Package Manager uses: fortran-lang/setup-fpm@v7 with: @@ -65,11 +57,7 @@ jobs: run: | python -m pip install --upgrade pip #pip install ford FoBiS.py pygooglechart fpm - pip install ford pygooglechart - # just get the latest FoBiS from git: - git clone https://github.com/szaghi/FoBiS.git - # use a fork until there is a new release: - # git clone https://github.com/jacobwilliams/FoBiS.git + pip install ford FoBiS.py pygooglechart if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Install GFortran Linux From 07161cf76b258dffeea7141375f651518d51cb0e Mon Sep 17 00:00:00 2001 From: Jacob Williams Date: Tue, 24 Feb 2026 21:36:28 -0600 Subject: [PATCH 6/8] try gfortran 15 --- .github/workflows/CI.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e14582340..a7de4003c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -10,7 +10,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - gcc_v: [12,10,11,9] # Version of GFortran we want to use. + gcc_v: [15,10,11,9] # Version of GFortran we want to use. python-version: [3.11] env: FC: gfortran-${{matrix.gcc_v}} @@ -22,7 +22,7 @@ jobs: # 9 - build.sh with documentation, unit tests and coverage analysis. doc deployment # 10 - build.sh - no documentation, with and without unicode. # 11 - FPM - # 12 - CMake build with unit tests, no documentation, with coverage analysis. no unicode + # 15 - CMake build with unit tests, no documentation, with coverage analysis. no unicode # # NOTE: coverage disabled for now @@ -34,7 +34,7 @@ jobs: submodules: recursive - name: Setup cmake - if: contains( matrix.gcc_v, 12 ) + if: contains( matrix.gcc_v, 15 ) uses: jwlawson/actions-setup-cmake@v2.0.2 with: cmake-version: '3.28.x' @@ -93,7 +93,7 @@ jobs: # CMake build with unit tests, no documentation, with coverage analysis # No unicode so that coverage combined with the build script will cover unicode # and non-unicode code paths - if: matrix.gcc_v == 12 + if: matrix.gcc_v == 15 run: | GFORTRAN=gfortran-${{matrix.gcc_v}} GCOV=gcov-${{matrix.gcc_v}} From e8353fb52654124fc1ab69e9d2907437b189b0bd Mon Sep 17 00:00:00 2001 From: Jacob Williams Date: Tue, 24 Feb 2026 21:43:54 -0600 Subject: [PATCH 7/8] CI: try gcc 14 --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a7de4003c..0dd1cf5e9 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -10,7 +10,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - gcc_v: [15,10,11,9] # Version of GFortran we want to use. + gcc_v: [14,10,11,9] # Version of GFortran we want to use. python-version: [3.11] env: FC: gfortran-${{matrix.gcc_v}} From 8b89f11c0f6a6deff08aaa10ce2d5bf5d234d867 Mon Sep 17 00:00:00 2001 From: Jacob Williams Date: Tue, 24 Feb 2026 21:49:16 -0600 Subject: [PATCH 8/8] CI fixes --- .github/workflows/CI.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 0dd1cf5e9..182dfdadd 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -22,7 +22,7 @@ jobs: # 9 - build.sh with documentation, unit tests and coverage analysis. doc deployment # 10 - build.sh - no documentation, with and without unicode. # 11 - FPM - # 15 - CMake build with unit tests, no documentation, with coverage analysis. no unicode + # 14 - CMake build with unit tests, no documentation, with coverage analysis. no unicode # # NOTE: coverage disabled for now @@ -34,13 +34,12 @@ jobs: submodules: recursive - name: Setup cmake - if: contains( matrix.gcc_v, 15 ) uses: jwlawson/actions-setup-cmake@v2.0.2 with: cmake-version: '3.28.x' - name: Install Python - uses: actions/setup-python@v5.1.0 # Use pip to install latest CMake, & FORD/Jin2For, etc. + uses: actions/setup-python@v5.1.0 with: python-version: ${{ matrix.python-version }} @@ -53,15 +52,11 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Install Python dependencies - if: contains( matrix.os, 'ubuntu') run: | python -m pip install --upgrade pip - #pip install ford FoBiS.py pygooglechart fpm pip install ford FoBiS.py pygooglechart - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Install GFortran Linux - if: contains( matrix.os, 'ubuntu') run: | sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update @@ -93,7 +88,7 @@ jobs: # CMake build with unit tests, no documentation, with coverage analysis # No unicode so that coverage combined with the build script will cover unicode # and non-unicode code paths - if: matrix.gcc_v == 15 + if: matrix.gcc_v == 14 run: | GFORTRAN=gfortran-${{matrix.gcc_v}} GCOV=gcov-${{matrix.gcc_v}}