@@ -19,112 +19,13 @@ class Mfc < Formula
1919 depends_on "open-mpi"
2020 depends_on "openblas"
212122- depends_on "sundials"
23- depends_on "yaml-cpp"
24-
25- resource "cantera" do
26- url "https://github.com/Cantera/cantera.git" ,
27- tag : "v3.1.0"
28- end
2922
3023 def install
31- # Create Python virtual environment first (before MFC build)
24+ # Create Python virtual environment
3225 venv = libexec /"venv"
3326 system Formula [ "[email protected] " ] . opt_bin /
"python3.12" , "-m" , "venv" , venv 3427 system venv /"bin/pip" , "install" , "--upgrade" , "pip" , "setuptools" , "wheel"
3528
36- # Build and install Cantera 3.1.0 from source BEFORE MFC build
37- resource ( "cantera" ) . stage do
38- # Install Cantera build dependencies (including scons)
39- system venv /"bin/pip" , "install" , "cython" , "numpy" , "ruamel.yaml" , "packaging" , "scons"
40-
41- # Configure Cantera build
42- # Cantera's scons needs explicit compiler selection and environment variables
43- sdk_path = MacOS . sdk_path
44-
45- # Set environment variables that scons will use during compiler checks
46- ENV [ "CC" ] = ENV . cc
47- ENV [ "CXX" ] = ENV . cxx
48- ENV [ "CFLAGS" ] = "-isysroot#{ sdk_path } "
49- ENV [ "CXXFLAGS" ] = "-isysroot#{ sdk_path } -stdlib=libc++"
50- ENV [ "SDKROOT" ] = sdk_path . to_s
51-
52- # Also set include path variables for libc++ headers
53- cxx_inc_path = "#{ sdk_path } /usr/include/c++/v1"
54- ENV [ "CPPFLAGS" ] = [ "-I#{ cxx_inc_path } " , ENV . fetch ( "CPPFLAGS" , nil ) ] . compact . join ( " " )
55-
56- # Run scons, explicitly passing compiler flags as Cantera scons variables
57- # Cantera uses cc_flags/cxx_flags, not CCFLAGS/CXXFLAGS
58- # Include both SDK include path and C++ header path for scons' configuration checks
59- sdk_inc_path = "#{ sdk_path } /usr/include"
60- cxx_flags_with_includes = "#{ ENV . fetch ( "CXXFLAGS" , nil ) } -I#{ sdk_inc_path } -I#{ cxx_inc_path } "
61-
62- # Run scons build - output config.log if it fails
63- sundials_inc = Formula [ "sundials" ] . opt_include
64- yamlcpp_inc = Formula [ "yaml-cpp" ] . opt_include
65- sundials_lib = Formula [ "sundials" ] . opt_lib
66- yamlcpp_lib = Formula [ "yaml-cpp" ] . opt_lib
67-
68- # Debug: Show what we're about to run
69- opoo "About to run Cantera scons build in: #{ Dir . pwd } "
70- opoo "SDK path: #{ sdk_path } "
71- opoo "C++ flags: #{ cxx_flags_with_includes } "
72-
73- success = system venv /"bin/python" , "-m" , "SCons" , "build" ,
74- "CC=#{ ENV . cc } " ,
75- "CXX=#{ ENV . cxx } " ,
76- "cc_flags=#{ ENV . fetch ( "CFLAGS" , nil ) } -I#{ sdk_inc_path } " ,
77- "cxx_flags=#{ cxx_flags_with_includes } " ,
78- "python_package=y" ,
79- "f90_interface=n" ,
80- "system_sundials=y" ,
81- "system_yamlcpp=y" ,
82- "system_fmt=n" ,
83- "extra_inc_dirs=#{ cxx_inc_path } :#{ sundials_inc } :#{ yamlcpp_inc } " ,
84- "extra_lib_dirs=#{ sundials_lib } :#{ yamlcpp_lib } " ,
85- "prefix=#{ libexec } /cantera" ,
86- "python_cmd=#{ venv } /bin/python" ,
87- "-j#{ ENV . make_jobs } "
88-
89- unless success
90- opoo "=============================================="
91- opoo "Cantera scons build FAILED!"
92- opoo "Current directory: #{ Dir . pwd } "
93- opoo "=============================================="
94-
95- # Try to find and display config.log
96- config_log_candidates = [ "config.log" , "build/config.log" , ".sconf_temp/conftest.out" ]
97- config_log_candidates . each do |candidate |
98- next unless File . exist? ( candidate )
99-
100- opoo "Found #{ candidate } :"
101- File . open ( candidate , "r" ) do |f |
102- puts f . read
103- end
104- end
105-
106- # Also search recursively
107- Dir . glob ( "**/config.log" ) . each do |path |
108- opoo "Found config.log at: #{ path } "
109- puts File . read ( path )
110- end
111-
112- # List directory contents
113- opoo "Directory listing:"
114- system "ls" , "-laR"
115-
116- odie "Cantera scons build failed - see config.log output above"
117- end
118-
119- # Install Cantera
120- system venv /"bin/python" , "-m" , "SCons" , "install"
121-
122- # Install Cantera Python package into venv
123- cd "build/python" do
124- system venv /"bin/pip" , "install" , "--no-build-isolation" , "."
125- end
126- end
127-
12829 # Install Python toolchain (needed before build)
12930 prefix . install "toolchain"
13031
@@ -138,113 +39,87 @@ def install
13839 # Now build MFC with pre-configured venv
13940 # Set VIRTUAL_ENV so mfc.sh uses existing venv instead of creating new one
14041 ENV [ "VIRTUAL_ENV" ] = venv
141- ENV [ "PATH" ] = "#{ venv } /bin:#{ ENV . fetch ( "PATH" , nil ) } "
142-
143- system "./mfc.sh" , "build" ,
144- "-t" , "pre_process" , "simulation" , "post_process" ,
145- "-j" , ENV . make_jobs
14642
147- # Install binaries
148- # MFC installs each binary to a separate hashed subdirectory, find them individually
149- %w[ pre_process simulation post_process ] . each do |binary |
150- binary_paths = Dir . glob ( "build/install/*/bin/#{ binary } " )
151- raise "Could not find #{ binary } " if binary_paths . empty?
43+ # Build MFC using pre-configured venv
44+ system "./mfc.sh" , "build" , "-t" , "pre_process" , "simulation" , "post_process" , "-j" , ENV . make_jobs . to_s
15245
153- bin . install binary_paths . first
46+ # Install binaries - they're in hashed subdirectories like build/install/<hash>/bin/*
47+ Dir . glob ( "build/install/*/bin/*" ) . each do |binary_path |
48+ bin . install binary_path
15449 end
15550
156- # Install mfc.sh script to libexec
51+ # Install main mfc.sh script
15752 libexec . install "mfc.sh"
15853
54+ # Install toolchain directory (already done above, but make sure it stays in prefix)
55+ # (already done with prefix.install above)
56+
15957 # Install examples
160- pkgshare . install "examples"
58+ prefix . install "examples"
16159
162- # Create a wrapper that sets up a working environment for mfc.sh
163- # The wrapper uses a temporary directory since Cellar is read-only and
164- # activates the pre-installed Python virtual environment
60+ # Create smart wrapper script that:
61+ # 1. Works around read-only Cellar issue
62+ # 2. Activates venv automatically so cantera/dependencies are available
16563 ( bin /"mfc" ) . write <<~EOS
16664 #!/bin/bash
16765 set -e
16866
169- # Activate the pre-installed Python virtual environment
170- source "#{ libexec } /venv/bin/activate"
171-
172- # Create a working directory for MFC in user's cache
173- MFC_WORK_DIR="${TMPDIR:-/tmp}/mfc-homebrew-$$"
174- mkdir -p "$MFC_WORK_DIR"
175-
176- # Function to clean up on exit
177- cleanup() {
178- rm -rf "$MFC_WORK_DIR"
179- }
180- trap cleanup EXIT
181-
182- # Create minimal directory structure that mfc.sh expects
183- cd "$MFC_WORK_DIR"
184- ln -sf "#{ prefix } /toolchain" toolchain
185- ln -sf "#{ libexec } /mfc.sh" mfc.sh
186- ln -sf "#{ pkgshare } /examples" examples
67+ # Activate the pre-installed venv so all Python dependencies are available
68+ # This makes cantera and other packages accessible if users install them in the venv
69+ source "#{ venv } /bin/activate"
18770
188- # Link the venv so mfc.sh doesn't try to create its own
189- mkdir -p build
190- ln -sf " #{ libexec } /venv" build/venv
71+ # Create a temporary working directory (Cellar is read-only)
72+ TMPDIR=$(mktemp -d)
73+ trap "rm -rf $TMPDIR" EXIT
19174
192- # Set up environment variables
193- export MFC_INSTALL_DIR="#{ prefix } "
194- export MFC_BIN_DIR="#{ bin } "
195- export BOOST_INCLUDE="#{ Formula [ "boost" ] . opt_include } "
75+ # Copy mfc.sh to temp dir (it may try to write build artifacts)
76+ cp "#{ libexec } /mfc.sh" "$TMPDIR/"
77+ cd "$TMPDIR"
19678
19779 # Run mfc.sh with all arguments
19880 exec ./mfc.sh "$@"
19981 EOS
200- chmod 0755 , bin /"mfc"
20182 end
20283
20384 def caveats
20485 <<~EOS
205- MFC has been installed with:
206- - mfc command-line tool: #{ bin } /mfc
207- - pre_process: #{ bin } /pre_process
208- - simulation: #{ bin } /simulation
209- - post_process: #{ bin } /post_process
86+ MFC has been installed successfully!
21087
211- Examples are available in:
212- #{ pkgshare } /examples
88+ To use MFC:
89+ mfc --help
90+
91+ Note: For cases requiring chemical kinetics (Cantera), you'll need to install
92+ Cantera separately in the MFC virtual environment:
93+
94+ source #{ libexec } /venv/bin/activate
95+ pip install cantera
21396
214- To run an example:
215- cd #{ pkgshare } /examples/1D_sodshocktube
216- mfc run case.py
97+ Alternatively, use conda:
98+ conda install -c conda-forge cantera
21799
218- Documentation: https://mflowcode.github.io/
100+ Examples are available in:
101+ #{ prefix } /examples
219102 EOS
220103 end
221104
222105 test do
223- # Test that the binaries exist and are executable
224- assert_path_exists bin /"mfc"
225- assert_predicate bin /"mfc" , :executable?
226- assert_path_exists bin /"pre_process"
227- assert_predicate bin /"pre_process" , :executable?
228- assert_path_exists bin /"simulation"
229- assert_predicate bin /"simulation" , :executable?
230- assert_path_exists bin /"post_process"
231- assert_predicate bin /"post_process" , :executable?
232-
233- # Verify toolchain and mfc.sh were installed
234- assert_path_exists libexec /"mfc.sh"
235- assert_path_exists prefix /"toolchain"
236- assert_path_exists prefix /"toolchain/mfc"
237-
238- # Verify Python venv was created with dependencies
239- assert_path_exists libexec /"venv"
240- assert_path_exists libexec /"venv/bin/python"
241- assert_path_exists libexec /"venv/bin/pip"
242-
243- # Verify examples were installed
244- assert_path_exists pkgshare /"examples"
245- assert_path_exists pkgshare /"examples/1D_sodshocktube/case.py"
246-
247- # Test mfc wrapper functionality with pre-installed venv
106+ # Test that all binaries exist and are executable
107+ %w[ pre_process simulation post_process ] . each do |prog |
108+ assert_predicate bin /prog , :exist?
109+ assert_predicate bin /prog , :executable?
110+ end
111+
112+ # Test that toolchain is installed
113+ assert_predicate prefix /"toolchain" , :exist?
114+
115+ # Test that venv exists and has required packages
116+ assert_predicate libexec /"venv" , :exist?
117+ assert_predicate libexec /"venv/bin/python" , :executable?
118+
119+ # Test that examples exist
120+ assert_predicate prefix /"examples" , :exist?
121+
122+ # Test that mfc wrapper works
248123 system bin /"mfc" , "--help"
249124 end
250125end
0 commit comments