@@ -80,80 +80,86 @@ def install
8080 # Create wrapper script in buildpath first, then install it
8181 wrapper_script = buildpath /"mfc_wrapper"
8282 wrapper_script . write <<~EOS
83- #!/bin/bash
84- set -euo pipefail
85-
86- # Unset VIRTUAL_ENV to ensure mfc.sh uses the copied venv, not the Cellar one
87- unset VIRTUAL_ENV || true
88-
89- # Save original working directory
90- ORIGINAL_PWD="${PWD}"
91-
92- # Convert relative file paths to absolute paths before changing directories
93- # This handles cases where users run: mfc run case.py
94- ARGS=("$@")
95- for i in "${!ARGS[@]}"; do
96- arg="${ARGS[$i]}"
97- # If argument looks like a file path (ends with .py or .json) and is relative
98- if [[ "$arg" =~ \. (py|json)$ ]] && [[ "$arg" != /* ]]; then
99- # Convert to absolute path using original working directory
100- ARGS[$i]="${ORIGINAL_PWD}/${arg}"
101- fi
102- done
103-
104- # Create a temporary working directory (Cellar is read-only)
105- TMPDIR="$(mktemp -d)"
106- trap 'rm -rf "${TMPDIR}"' EXIT
107-
108- # Copy mfc.sh to temp dir (it may try to write build artifacts)
109- cp "#{ libexec } /mfc.sh" "${TMPDIR}/"
110- chmod +x "${TMPDIR}/mfc.sh"
111-
112- # Copy CMakeLists.txt (needed by toolchain/bootstrap/cmake.sh)
113- cp "#{ prefix } /CMakeLists.txt" "${TMPDIR}/CMakeLists.txt"
114-
115- cd "${TMPDIR}"
116-
117- # Copy toolchain directory (not symlink) so Python paths resolve correctly
118- # This prevents paths from resolving back to read-only Cellar
119- cp -R "#{ prefix } /toolchain" "toolchain"
120-
121- # Patch toolchain in place to use Homebrew-installed binaries
122- # Write patch directly to file to avoid heredoc temp file issues
123- {
124- echo ""
125- echo " # Homebrew patch: Override get_install_binpath to use pre-installed binaries"
126- echo " _original_get_install_binpath = MFCTarget.get_install_binpath"
127- echo " def _homebrew_get_install_binpath(self, case):"
128- echo " return \" #{ bin } /\" + self.name"
129- echo " MFCTarget.get_install_binpath = _homebrew_get_install_binpath"
130- echo ""
131- echo " # Override is_buildable to skip building main targets and syscheck"
132- echo " _original_is_buildable = MFCTarget.is_buildable"
133- echo " def _homebrew_is_buildable(self):"
134- echo " if self.name in [\" pre_process\" , \" simulation\" , \" post_process\" , \" syscheck\" ]:"
135- echo " return False # Skip building - use pre-installed binaries"
136- echo " return _original_is_buildable(self)"
137- echo " MFCTarget.is_buildable = _homebrew_is_buildable"
138- } >> "toolchain/mfc/build.py"
139-
140- # Copy examples directory (required by mfc.sh Python code)
141- cp -R "#{ prefix } /examples" "examples"
142-
143- # Create build directory and copy venv (not symlink - needs to be writable)
144- # Use cp -R for a full recursive copy
145- mkdir -p "build"
146- cp -R "#{ venv } " "build/venv"
147-
148- # Copy pyproject.toml to build/ so mfc.sh thinks dependencies are already installed
149- cp "#{ prefix } /toolchain/pyproject.toml" "build/pyproject.toml"
150-
151- # For 'mfc run', add --no-build flag to skip compilation
152- if [ "${ARGS[0]-}" = "run" ]; then
153- exec ./mfc.sh "${ARGS[@]}" --no-build
154- else
155- exec ./mfc.sh "${ARGS[@]}"
156- fi
83+ #!/bin/bash
84+ set -euo pipefail
85+
86+ # Unset VIRTUAL_ENV to ensure mfc.sh uses the copied venv, not the Cellar one
87+ unset VIRTUAL_ENV || true
88+
89+ # Save original working directory
90+ ORIGINAL_PWD="${PWD}"
91+
92+ # Convert relative file paths to absolute paths before changing directories
93+ # This handles cases where users run: mfc run case.py
94+ ARGS=("$@")
95+ for i in "${!ARGS[@]}"; do
96+ arg="${ARGS[$i]}"
97+ # If argument looks like a file path (ends with .py or .json) and is relative
98+ if [[ "$arg" =~ \\ .(py|json)$ ]] && [[ "$arg" != /* ]]; then
99+ # Convert to absolute path using original working directory
100+ ARGS[$i]="${ORIGINAL_PWD}/${arg}"
101+ fi
102+ done
103+
104+ # Create a temporary working directory (Cellar is read-only)
105+ TMPDIR="$(mktemp -d)"
106+ trap 'rm -rf "${TMPDIR}"' EXIT
107+
108+ # Copy mfc.sh to temp dir (it may try to write build artifacts)
109+ cp "#{ libexec } /mfc.sh" "${TMPDIR}/"
110+ chmod +x "${TMPDIR}/mfc.sh"
111+
112+ # Copy CMakeLists.txt (needed by toolchain/bootstrap/cmake.sh)
113+ if [ -f "#{ prefix } /CMakeLists.txt" ]; then
114+ cp "#{ prefix } /CMakeLists.txt" "${TMPDIR}/CMakeLists.txt"
115+ else
116+ # Fallback: create minimal CMakeLists.txt if not found
117+ echo "cmake_minimum_required(VERSION 3.15)" > "${TMPDIR}/CMakeLists.txt"
118+ echo "project(MFC)" >> "${TMPDIR}/CMakeLists.txt"
119+ fi
120+
121+ cd "${TMPDIR}"
122+
123+ # Copy toolchain directory using hard links for speed (much faster than copying)
124+ # Use cp -al to create hard links, fall back to cp -R if not supported
125+ cp -al "#{ prefix } /toolchain" "toolchain" 2>/dev/null || cp -R "#{ prefix } /toolchain" "toolchain"
126+
127+ # Patch toolchain in place to use Homebrew-installed binaries
128+ # Write patch directly to file to avoid heredoc temp file issues
129+ {
130+ echo ""
131+ echo " # Homebrew patch: Override get_install_binpath to use pre-installed binaries"
132+ echo " _original_get_install_binpath = MFCTarget.get_install_binpath"
133+ echo " def _homebrew_get_install_binpath(self, case):"
134+ echo " return '#{ bin } /' + self.name"
135+ echo " MFCTarget.get_install_binpath = _homebrew_get_install_binpath"
136+ echo ""
137+ echo " # Override is_buildable to skip building main targets and syscheck"
138+ echo " _original_is_buildable = MFCTarget.is_buildable"
139+ echo " def _homebrew_is_buildable(self):"
140+ echo " if self.name in ['pre_process', 'simulation', 'post_process', 'syscheck']:"
141+ echo " return False # Skip building - use pre-installed binaries"
142+ echo " return _original_is_buildable(self)"
143+ echo " MFCTarget.is_buildable = _homebrew_is_buildable"
144+ } >> "toolchain/mfc/build.py"
145+
146+ # Copy examples directory using hard links for speed
147+ cp -al "#{ prefix } /examples" "examples" 2>/dev/null || cp -R "#{ prefix } /examples" "examples"
148+
149+ # Create build directory and copy venv using hard links (much faster!)
150+ # Use cp -al to create hard links, fall back to cp -R if not supported
151+ mkdir -p "build"
152+ cp -al "#{ venv } " "build/venv" 2>/dev/null || cp -R "#{ venv } " "build/venv"
153+
154+ # Copy pyproject.toml to build/ so mfc.sh thinks dependencies are already installed
155+ cp "#{ prefix } /toolchain/pyproject.toml" "build/pyproject.toml"
156+
157+ # For 'mfc run', add --no-build flag to skip compilation
158+ if [ "${ARGS[0]-}" = "run" ]; then
159+ exec ./mfc.sh "${ARGS[@]}" --no-build
160+ else
161+ exec ./mfc.sh "${ARGS[@]}"
162+ fi
157163 EOS
158164
159165 # Make wrapper executable and install it
0 commit comments