Skip to content

Commit be0034a

Browse files
committed
make gfortran linking a separate action
1 parent 15b5d50 commit be0034a

File tree

3 files changed

+90
-146
lines changed

3 files changed

+90
-146
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: 'Patch macOS libgfortran'
2+
description: 'Backport gfortran shared libraries to paths expected by bootstrap fpm binary'
3+
inputs:
4+
gcc-version:
5+
description: 'GCC version to use for patching'
6+
required: true
7+
runs:
8+
using: 'composite'
9+
steps:
10+
- name: MacOS patch libgfortran
11+
shell: bash
12+
run: |
13+
which gfortran-${{ inputs.gcc-version }}
14+
which gfortran || true
15+
BREW_PREFIX=$(brew --prefix)
16+
17+
# Query the actual library paths that fpm expects
18+
echo "Checking library dependencies of fpm bootstrap binary..."
19+
otool -L $(which fpm)
20+
21+
# Extract the gcc version from the bootstrap binary's library paths
22+
BOOTSTRAP_GCC_VERSION=$(otool -L $(which fpm) | grep -o 'gcc@[0-9]\+' | head -n 1 | cut -d@ -f2)
23+
if [ -z "$BOOTSTRAP_GCC_VERSION" ]; then
24+
# Try alternative pattern: /lib/gcc/13/ -> extract 13
25+
BOOTSTRAP_GCC_VERSION=$(otool -L $(which fpm) | grep libgfortran | grep -o '/lib/gcc/[0-9]\+/' | grep -o '[0-9]\+' | head -n 1)
26+
fi
27+
28+
echo "Bootstrap fpm built with gcc@$BOOTSTRAP_GCC_VERSION"
29+
echo "Current toolchain: gcc@${{ inputs.gcc-version }}"
30+
31+
if [ "$BOOTSTRAP_GCC_VERSION" == "${{ inputs.gcc-version }}" ]; then
32+
echo "✓ Bootstrap gcc version matches current toolchain - no patching needed"
33+
exit 0
34+
fi
35+
36+
echo "⚠ Version mismatch detected - creating compatibility symlinks..."
37+
38+
# Find the actual Cellar path by following the symlink
39+
if [ -L "${BREW_PREFIX}/opt/gcc@${{ inputs.gcc-version }}" ]; then
40+
GCC_CELLAR_PATH=$(cd -P "${BREW_PREFIX}/opt/gcc@${{ inputs.gcc-version }}" && pwd)
41+
else
42+
GCC_CELLAR_PATH="${BREW_PREFIX}/Cellar/gcc@${{ inputs.gcc-version }}"/*
43+
fi
44+
echo "GCC Cellar path: $GCC_CELLAR_PATH"
45+
46+
# Find the actual library files
47+
CURRENT_GFORTRAN=$(find "$GCC_CELLAR_PATH"/lib/gcc/${{ inputs.gcc-version }} -name "libgfortran.*.dylib" 2>/dev/null | head -n 1)
48+
CURRENT_QUADMATH=$(find "$GCC_CELLAR_PATH"/lib/gcc/${{ inputs.gcc-version }} -name "libquadmath.*.dylib" 2>/dev/null | head -n 1)
49+
CURRENT_GCC_S=$(find "$GCC_CELLAR_PATH"/lib/gcc/${{ inputs.gcc-version }} -name "libgcc_s.*.dylib" 2>/dev/null | head -n 1)
50+
51+
echo "Current gcc@${{ inputs.gcc-version }} libraries:"
52+
echo " libgfortran: $CURRENT_GFORTRAN"
53+
echo " libquadmath: $CURRENT_QUADMATH"
54+
echo " libgcc_s: $CURRENT_GCC_S"
55+
56+
# Extract the expected libgfortran path and create symlink
57+
LIBGFORTRAN_PATH=$(otool -L $(which fpm) | grep libgfortran | awk '{print $1}' | head -n 1)
58+
if [ -n "$LIBGFORTRAN_PATH" ] && [ -n "$CURRENT_GFORTRAN" ]; then
59+
TARGET_DIR=$(dirname "$LIBGFORTRAN_PATH")
60+
echo "Creating directory: $TARGET_DIR"
61+
sudo mkdir -p "$TARGET_DIR"
62+
echo "Linking $CURRENT_GFORTRAN to $LIBGFORTRAN_PATH"
63+
sudo ln -fs "$CURRENT_GFORTRAN" "$LIBGFORTRAN_PATH"
64+
fi
65+
66+
# Extract the expected libquadmath path and create symlink
67+
LIBQUADMATH_PATH=$(otool -L $(which fpm) | grep libquadmath | awk '{print $1}' | head -n 1)
68+
if [ -n "$LIBQUADMATH_PATH" ] && [ -n "$CURRENT_QUADMATH" ]; then
69+
TARGET_DIR=$(dirname "$LIBQUADMATH_PATH")
70+
echo "Creating directory: $TARGET_DIR"
71+
sudo mkdir -p "$TARGET_DIR"
72+
echo "Linking $CURRENT_QUADMATH to $LIBQUADMATH_PATH"
73+
sudo ln -fs "$CURRENT_QUADMATH" "$LIBQUADMATH_PATH"
74+
fi
75+
76+
# Extract the expected libgcc_s path and create symlink
77+
LIBGCC_PATH=$(otool -L $(which fpm) | grep libgcc_s | awk '{print $1}' | head -n 1)
78+
if [ -n "$LIBGCC_PATH" ] && [ -n "$CURRENT_GCC_S" ]; then
79+
TARGET_DIR=$(dirname "$LIBGCC_PATH")
80+
echo "Creating directory: $TARGET_DIR"
81+
sudo mkdir -p "$TARGET_DIR"
82+
echo "Linking $CURRENT_GCC_S to $LIBGCC_PATH"
83+
sudo ln -fs "$CURRENT_GCC_S" "$LIBGCC_PATH"
84+
fi

.github/workflows/CI.yml

Lines changed: 3 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -81,79 +81,9 @@ jobs:
8181
# On ARM64 it runs under Rosetta 2 and needs /usr/local paths.
8282
- name: MacOS patch libgfortran
8383
if: contains(matrix.os, 'macos')
84-
run: |
85-
which gfortran-${{ matrix.toolchain.version }}
86-
which gfortran
87-
BREW_PREFIX=$(brew --prefix)
88-
89-
# Query the actual library paths that fpm expects
90-
echo "Checking library dependencies of fpm bootstrap binary..."
91-
otool -L $(which fpm)
92-
93-
# Extract the gcc version from the bootstrap binary's library paths
94-
BOOTSTRAP_GCC_VERSION=$(otool -L $(which fpm) | grep -o 'gcc@[0-9]\+' | head -n 1 | cut -d@ -f2)
95-
if [ -z "$BOOTSTRAP_GCC_VERSION" ]; then
96-
# Try alternative pattern: /lib/gcc/13/ -> extract 13
97-
BOOTSTRAP_GCC_VERSION=$(otool -L $(which fpm) | grep libgfortran | grep -o '/lib/gcc/[0-9]\+/' | grep -o '[0-9]\+' | head -n 1)
98-
fi
99-
100-
echo "Bootstrap fpm built with gcc@$BOOTSTRAP_GCC_VERSION"
101-
echo "Current toolchain: gcc@${{ matrix.toolchain.version }}"
102-
103-
if [ "$BOOTSTRAP_GCC_VERSION" == "${{ matrix.toolchain.version }}" ]; then
104-
echo "✓ Bootstrap gcc version matches current toolchain - no patching needed"
105-
exit 0
106-
fi
107-
108-
echo "⚠ Version mismatch detected - creating compatibility symlinks..."
109-
110-
# Find the actual Cellar path by following the symlink
111-
if [ -L "${BREW_PREFIX}/opt/gcc@${{ matrix.toolchain.version }}" ]; then
112-
GCC_CELLAR_PATH=$(cd -P "${BREW_PREFIX}/opt/gcc@${{ matrix.toolchain.version }}" && pwd)
113-
else
114-
GCC_CELLAR_PATH="${BREW_PREFIX}/Cellar/gcc@${{ matrix.toolchain.version }}"/*
115-
fi
116-
echo "GCC Cellar path: $GCC_CELLAR_PATH"
117-
118-
# Find the actual library files
119-
CURRENT_GFORTRAN=$(find "$GCC_CELLAR_PATH"/lib/gcc/${{ matrix.toolchain.version }} -name "libgfortran.*.dylib" 2>/dev/null | head -n 1)
120-
CURRENT_QUADMATH=$(find "$GCC_CELLAR_PATH"/lib/gcc/${{ matrix.toolchain.version }} -name "libquadmath.*.dylib" 2>/dev/null | head -n 1)
121-
CURRENT_GCC_S=$(find "$GCC_CELLAR_PATH"/lib/gcc/${{ matrix.toolchain.version }} -name "libgcc_s.*.dylib" 2>/dev/null | head -n 1)
122-
123-
echo "Current gcc@${{ matrix.toolchain.version }} libraries:"
124-
echo " libgfortran: $CURRENT_GFORTRAN"
125-
echo " libquadmath: $CURRENT_QUADMATH"
126-
echo " libgcc_s: $CURRENT_GCC_S"
127-
128-
# Extract the expected libgfortran path and create symlink
129-
LIBGFORTRAN_PATH=$(otool -L $(which fpm) | grep libgfortran | awk '{print $1}' | head -n 1)
130-
if [ -n "$LIBGFORTRAN_PATH" ] && [ -n "$CURRENT_GFORTRAN" ]; then
131-
TARGET_DIR=$(dirname "$LIBGFORTRAN_PATH")
132-
echo "Creating directory: $TARGET_DIR"
133-
sudo mkdir -p "$TARGET_DIR"
134-
echo "Linking $CURRENT_GFORTRAN to $LIBGFORTRAN_PATH"
135-
sudo ln -fs "$CURRENT_GFORTRAN" "$LIBGFORTRAN_PATH"
136-
fi
137-
138-
# Extract the expected libquadmath path and create symlink
139-
LIBQUADMATH_PATH=$(otool -L $(which fpm) | grep libquadmath | awk '{print $1}' | head -n 1)
140-
if [ -n "$LIBQUADMATH_PATH" ] && [ -n "$CURRENT_QUADMATH" ]; then
141-
TARGET_DIR=$(dirname "$LIBQUADMATH_PATH")
142-
echo "Creating directory: $TARGET_DIR"
143-
sudo mkdir -p "$TARGET_DIR"
144-
echo "Linking $CURRENT_QUADMATH to $LIBQUADMATH_PATH"
145-
sudo ln -fs "$CURRENT_QUADMATH" "$LIBQUADMATH_PATH"
146-
fi
147-
148-
# Extract the expected libgcc_s path and create symlink
149-
LIBGCC_PATH=$(otool -L $(which fpm) | grep libgcc_s | awk '{print $1}' | head -n 1)
150-
if [ -n "$LIBGCC_PATH" ] && [ -n "$CURRENT_GCC_S" ]; then
151-
TARGET_DIR=$(dirname "$LIBGCC_PATH")
152-
echo "Creating directory: $TARGET_DIR"
153-
sudo mkdir -p "$TARGET_DIR"
154-
echo "Linking $CURRENT_GCC_S to $LIBGCC_PATH"
155-
sudo ln -fs "$CURRENT_GCC_S" "$LIBGCC_PATH"
156-
fi
84+
uses: ./.github/actions/patch-macos-libgfortran
85+
with:
86+
gcc-version: ${{ matrix.toolchain.version }}
15787

15888
# gcc and g++ will point to clang/clang++: use versioned alias for fpm
15989
- name: MacOS patch C and C++ compilers

.github/workflows/meta.yml

Lines changed: 3 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -244,79 +244,9 @@ jobs:
244244
# On ARM64 it runs under Rosetta 2 and needs /usr/local paths.
245245
- name: MacOS patch libgfortran
246246
if: contains(matrix.os, 'macos')
247-
run: |
248-
which gfortran-${{ env.GCC_V }}
249-
which gfortran || true
250-
BREW_PREFIX=$(brew --prefix)
251-
252-
# Query the actual library paths that fpm expects
253-
echo "Checking library dependencies of fpm bootstrap binary..."
254-
otool -L $(which fpm)
255-
256-
# Extract the gcc version from the bootstrap binary's library paths
257-
BOOTSTRAP_GCC_VERSION=$(otool -L $(which fpm) | grep -o 'gcc@[0-9]\+' | head -n 1 | cut -d@ -f2)
258-
if [ -z "$BOOTSTRAP_GCC_VERSION" ]; then
259-
# Try alternative pattern: /lib/gcc/13/ -> extract 13
260-
BOOTSTRAP_GCC_VERSION=$(otool -L $(which fpm) | grep libgfortran | grep -o '/lib/gcc/[0-9]\+/' | grep -o '[0-9]\+' | head -n 1)
261-
fi
262-
263-
echo "Bootstrap fpm built with gcc@$BOOTSTRAP_GCC_VERSION"
264-
echo "Current toolchain: gcc@${{ env.GCC_V }}"
265-
266-
if [ "$BOOTSTRAP_GCC_VERSION" == "${{ env.GCC_V }}" ]; then
267-
echo "✓ Bootstrap gcc version matches current toolchain - no patching needed"
268-
exit 0
269-
fi
270-
271-
echo "⚠ Version mismatch detected - creating compatibility symlinks..."
272-
273-
# Find the actual Cellar path by following the symlink
274-
if [ -L "${BREW_PREFIX}/opt/gcc@${{ env.GCC_V }}" ]; then
275-
GCC_CELLAR_PATH=$(cd -P "${BREW_PREFIX}/opt/gcc@${{ env.GCC_V }}" && pwd)
276-
else
277-
GCC_CELLAR_PATH="${BREW_PREFIX}/Cellar/gcc@${{ env.GCC_V }}"/*
278-
fi
279-
echo "GCC Cellar path: $GCC_CELLAR_PATH"
280-
281-
# Find the actual library files
282-
CURRENT_GFORTRAN=$(find "$GCC_CELLAR_PATH"/lib/gcc/${{ env.GCC_V }} -name "libgfortran.*.dylib" 2>/dev/null | head -n 1)
283-
CURRENT_QUADMATH=$(find "$GCC_CELLAR_PATH"/lib/gcc/${{ env.GCC_V }} -name "libquadmath.*.dylib" 2>/dev/null | head -n 1)
284-
CURRENT_GCC_S=$(find "$GCC_CELLAR_PATH"/lib/gcc/${{ env.GCC_V }} -name "libgcc_s.*.dylib" 2>/dev/null | head -n 1)
285-
286-
echo "Current gcc@${{ env.GCC_V }} libraries:"
287-
echo " libgfortran: $CURRENT_GFORTRAN"
288-
echo " libquadmath: $CURRENT_QUADMATH"
289-
echo " libgcc_s: $CURRENT_GCC_S"
290-
291-
# Extract the expected libgfortran path and create symlink
292-
LIBGFORTRAN_PATH=$(otool -L $(which fpm) | grep libgfortran | awk '{print $1}' | head -n 1)
293-
if [ -n "$LIBGFORTRAN_PATH" ] && [ -n "$CURRENT_GFORTRAN" ]; then
294-
TARGET_DIR=$(dirname "$LIBGFORTRAN_PATH")
295-
echo "Creating directory: $TARGET_DIR"
296-
sudo mkdir -p "$TARGET_DIR"
297-
echo "Linking $CURRENT_GFORTRAN to $LIBGFORTRAN_PATH"
298-
sudo ln -fs "$CURRENT_GFORTRAN" "$LIBGFORTRAN_PATH"
299-
fi
300-
301-
# Extract the expected libquadmath path and create symlink
302-
LIBQUADMATH_PATH=$(otool -L $(which fpm) | grep libquadmath | awk '{print $1}' | head -n 1)
303-
if [ -n "$LIBQUADMATH_PATH" ] && [ -n "$CURRENT_QUADMATH" ]; then
304-
TARGET_DIR=$(dirname "$LIBQUADMATH_PATH")
305-
echo "Creating directory: $TARGET_DIR"
306-
sudo mkdir -p "$TARGET_DIR"
307-
echo "Linking $CURRENT_QUADMATH to $LIBQUADMATH_PATH"
308-
sudo ln -fs "$CURRENT_QUADMATH" "$LIBQUADMATH_PATH"
309-
fi
310-
311-
# Extract the expected libgcc_s path and create symlink
312-
LIBGCC_PATH=$(otool -L $(which fpm) | grep libgcc_s | awk '{print $1}' | head -n 1)
313-
if [ -n "$LIBGCC_PATH" ] && [ -n "$CURRENT_GCC_S" ]; then
314-
TARGET_DIR=$(dirname "$LIBGCC_PATH")
315-
echo "Creating directory: $TARGET_DIR"
316-
sudo mkdir -p "$TARGET_DIR"
317-
echo "Linking $CURRENT_GCC_S to $LIBGCC_PATH"
318-
sudo ln -fs "$CURRENT_GCC_S" "$LIBGCC_PATH"
319-
fi
247+
uses: ./.github/actions/patch-macos-libgfortran
248+
with:
249+
gcc-version: ${{ env.GCC_V }}
320250

321251
- name: Remove fpm from path
322252
shell: bash

0 commit comments

Comments
 (0)