2

I have a large fortran 77 code, "NSCool", distributed among many files which I compile into a python package using f2py. It used to work nicely with python 3.7, then it took me weeks to have it work with python 3.12, but now that I have updated numpy to version 2.3.2 it fails.
I am working on Macos Ventura, 13.7.6, with the last available version of the command line tools and gfortran14, python3.12 and needed python packages all installed with Macports.
I compile everything with a makefile with three options to generate three versions of the NSCool_Py*.so:

  • A: linking directly all objects with the main subroutines in NSCool_2.f
  • B: putting all *.o of DEPENDS into a static library libNSCool_lib_stat.a
  • C: putting all *.o of DEPENDS into a dynamic library libNSCool_lib_dyn.so

Here is the makefile:

CODE_DIR = /Users/dany/Dropbox/Work/NStar/NSCool/Code

COMPILER     = /opt/local/bin/gfortran-mp-14
COMPILER_LIB = /opt/local/lib/gcc14
OPTIONS = -O0 -fPIC -funderscoring

F2PY = python -m numpy.f2py

#--------------------------------------------------------------------------------
DEPENDS  = NSCool_Read.o NSCool_Initialize.o NSCool_Help.o NSCool_Precool.o \
           \
           conductivity.o conductivity_core.o conductivity_crust.o \
           opacity.o Envelope_Opacity.o \
           neutrino.o neutrino_core.o neutrino_crust.o neutrino_pairing_control.o \
           heating.o spec_heat.o boundary.o tc.o tc_Ioffe.o \
           Envelope_NSCool.o Envelope_EOS.o Envelope_EOS_Fermi_Dirac.o Envelope_EOS_OCP.o \
           eff_mass.o accretion.o magnetic.o Tools.o Dump.o \
           \
           OMP_Void.o \
           Data_Crust.o Data_Crust_Plot_Void.o Weights.o \
           \
           ag_subroutines_A0.o ap_subroutines_A0.o pg_subroutines_A0.o wk_subroutines_A0.o \
           rates_reader.o isos_subroutines.o pp_and_3a.o Screening.o eps_nuc_and_rhs.o \
           Chemical_oz_time_dependent.o Tools_Maths.o
#--------------------------------------------------------------------------------

export MACOSX_DEPLOYMENT_TARGET=13.7

NSCool_Py_A: NSCool_2.f $(DEPENDS)
    f2py -c -m NSCool_Py_A NSCool_2.f $(DEPENDS) \
    --f77exec=$(COMPILER) \
    --f77flags="$(OPTIONS)" \
    --include-paths=$(CODE_DIR)
    @echo "This is NSCool_Py_A"

NSCool_Py_B: NSCool_2.f NSCool_lib_stat
    f2py -c -m NSCool_Py_B NSCool_2.f \
    --include-paths=$(CODE_DIR) \
    --f77exec=$(COMPILER) \
    -L$(COMPILER_LIB) -lgfortran -L$(CODE_DIR) -lNSCool_lib_stat \
    --f77flags="-L$(COMPILER_LIB) -lgfortran -L$(CODE_DIR) -lNSCool_lib " \
    --link-flags="-bundle -undefined dynamic_lookup -Wl,-L$(CODE_DIR),-lNSCool_lib"
    @echo "This is NSCool_Py_B"

NSCool_Py_C: NSCool_2.f NSCool_lib_dyn
    f2py -c -m NSCool_Py_C NSCool_2.f \
    --f77exec=$(COMPILER) \
    --include-paths=$(CODE_DIR) \
    -L$(CODE_DIR) -lNSCool_lib_dyn \
    -Wl,-force_load,$(CODE_DIR)/libNSCool_lib_dyn.so \
    --link-options="-bundle -undefined dynamic_lookup -Wl,-rpath,@loader_path"
    @echo "This isNSCool_Py_C"

NSCool_lib_stat: $(DEPENDS)
    libtool -static -o libNSCool_lib_stat.a $(DEPENDS)

NSCool_lib_dyn: $(DEPENDS)
    $(COMPILER) $(OPTIONS) -dynamiclib -install_name @rpath/libNSCool_lib_dyn.so -o libNSCool_lib_dyn.so $(DEPENDS) -lgfortran

#--------------------------------------------------------------------------------

accretion.o: accretion.f
    $(COMPILER)  $(OPTIONS) -c accretion.f

...

where " ... " means many similar commands to generate all the other object files

If run three versions with python and get error messages (and I check if the missing symbols are really missing):

Version A:
%
% python -c "import NSCool_Py_A"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: dlopen(/Users/dany/Dropbox/Work/NStar/NSCool/Code/NSCool_Py_A.cpython-312-darwin.so, 0x0002): symbol not found in flat namespace 'accretion_rate'
%
% nm -gU NSCool_Py_A.cpython-312-darwin.so | grep accretion_rate
%

(accretion_rate is a subroutine that in the accretion.o object, itself listed in DEPENDS)

Version B:
%
% python -c "import NSCool_Py_B"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: dynamic module does not define module export function (PyInit_NSCool_Py_B)
%
% nm -gU NSCool_Py_B.cpython-312-darwin.so | grep PyInit_NSCool_Py_B
0000000000016350 T _PyInit_NSCool_Py_B
%

Version C:
%
% python -c "import NSCool_Py_C"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: dlopen(/Users/dany/Dropbox/Work/NStar/NSCool/Code/NSCool_Py_C.cpython-312-darwin.so, 0x0002): Symbol not found: accretion_rate
Referenced from: <38EA9BF8-7293-3099-B782-1E4E5583984C> /Users/dany/Dropbox/Work/NStar/NSCool/Code/NSCool_Py_C.cpython-312-darwin.so
Expected in: <6FEF4279-E414-3F36-98E5-526848F925F1> /Users/dany/Dropbox/Work/NStar/NSCool/Code/libNSCool_lib_dyn.so
%
% nm -gU libNSCool_lib_dyn.so | grep accretion_rate
000000000008cf73 T accretion_rate
000000000008b2cc T accretion_rate_swift_j1858
000000000008c3a0 T initialize_accretion_rate
%

Any idea how to fix this ? At least one of the three versions !

2

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.