From 3948fabe6ee72881d1728c652c328cf7c625211b Mon Sep 17 00:00:00 2001 From: jdhughes-usgs Date: Sun, 9 Jun 2024 12:39:30 -0400 Subject: [PATCH] fix(gsflow): remove gsflow as a possible target (#176) gsflow (and prms) cause continual problems trying to include them as prebuilt executables. New versions require additional work to filter out extraneous source files and object files. The build process uses specific compiler flags. In short, supporting gsflow (and prms) requires more support each time we are ready to make a executables release or when a new version is released. * merge with failure - in process of resolving --- README.md | 76 ++++++-------------- autotest/test_gsflow.py | 83 ---------------------- docs/build_apps.md | 35 +++------- docs/index.rst | 2 +- pymake/pymake.py | 2 - pymake/pymake_build_apps.py | 5 -- pymake/utils/_compiler_switches.py | 34 --------- pymake/utils/_usgs_src_update.py | 108 ----------------------------- pymake/utils/usgsprograms.txt | 1 - 9 files changed, 33 insertions(+), 313 deletions(-) delete mode 100644 autotest/test_gsflow.py diff --git a/README.md b/README.md index 6351c29c..47b236fe 100644 --- a/README.md +++ b/README.md @@ -55,13 +55,8 @@ The help message identifies required positional arguments and optional arguments default values. ``` -usage: mfpymake [-h] [-fc {ifort,mpiifort,gfortran,none}] - [-cc {gcc,clang,clang++,icc,icl,mpiicc,g++,cl,none}] - [-ar {ia32,ia32_intel64,intel64}] [-mc] [-dbl] [-dbg] [-e] - [-dr] [-sd] [-ff FFLAGS] [-cf CFLAGS] [-sl {-lc,-lm}] [-mf] - [-md] [-cs COMMONSRC] [-ef EXTRAFILES] [-exf EXCLUDEFILES] - [-so] [-ad APPDIR] [-v] [--keep] [--zip ZIP] [--inplace] - [--networkx] [--meson] [--mesondir] +usage: mfpymake [-h] [-fc {ifort,mpiifort,gfortran,none}] [-cc {gcc,clang,clang++,icc,icl,mpiicc,g++,cl,none}] [-ar {ia32,ia32_intel64,intel64}] [-mc] [-dbl] [-dbg] [-e] [-dr] [-sd] [-ff FFLAGS] + [-cf CFLAGS] [-sl {-lc,-lm}] [-mf] [-md] [-cs COMMONSRC] [-ef EXTRAFILES] [-exf EXCLUDEFILES] [-so] [-ad APPDIR] [-v] [--keep] [--zip ZIP] [--inplace] [--networkx] [--meson] [--mesondir] srcdir target This is the pymake program for compiling fortran, c, and c++ source @@ -73,70 +68,45 @@ positional arguments: srcdir Path source directory. target Name of target to create. (can include path) -optional arguments: +options: -h, --help show this help message and exit -fc {ifort,mpiifort,gfortran,none} Fortran compiler to use. (default is gfortran) -cc {gcc,clang,clang++,icc,icl,mpiicc,g++,cl,none} C/C++ compiler to use. (default is gcc) -ar {ia32,ia32_intel64,intel64}, --arch {ia32,ia32_intel64,intel64} - Architecture to use for Intel and Microsoft compilers - on Windows. (default is intel64) - -mc, --makeclean Clean temporary object, module, and source files when - done. (default is False) + Architecture to use for Intel and Microsoft compilers on Windows. (default is intel64) + -mc, --makeclean Clean temporary object, module, and source files when done. (default is False) -dbl, --double Force double precision. (default is False) -dbg, --debug Create debug version. (default is False) - -e, --expedite Only compile out of date source files. Clean must not - have been used on previous build. (default is False) - -dr, --dryrun Do not actually compile. Files will be deleted, if - --makeclean is used. Does not work yet for ifort. - (default is False) - -sd, --subdirs Include source files in srcdir subdirectories. - (default is None) + -e, --expedite Only compile out of date source files. Clean must not have been used on previous build. (default is False) + -dr, --dryrun Do not actually compile. Files will be deleted, if --makeclean is used. Does not work yet for ifort. (default is False) + -sd, --subdirs Include source files in srcdir subdirectories. (default is None) -ff FFLAGS, --fflags FFLAGS - Additional Fortran compiler flags. Fortran compiler - flags should be enclosed in quotes and start with a - blank space or separated from the name (-ff or - --fflags) with a equal sign (-ff='-O3'). (default is - None) + Additional Fortran compiler flags. Fortran compiler flags should be enclosed in quotes and start with a blank space or separated from the name (-ff or --fflags) with a equal sign + (-ff='-O3'). (default is None) -cf CFLAGS, --cflags CFLAGS - Additional C/C++ compiler flags. C/C++ compiler flags - should be enclosed in quotes and start with a blank - space or separated from the name (-cf or --cflags) - with a equal sign (-cf='-O3'). (default is None) + Additional C/C++ compiler flags. C/C++ compiler flags should be enclosed in quotes and start with a blank space or separated from the name (-cf or --cflags) with a equal sign + (-cf='-O3'). (default is None) -sl {-lc,-lm}, --syslibs {-lc,-lm} - Linker system libraries. Linker libraries should be - enclosed in quotes and start with a blank space or - separated from the name (-sl or --syslibs) with a - equal sign (-sl='-libgcc'). (default is None) + Linker system libraries. Linker libraries should be enclosed in quotes and start with a blank space or separated from the name (-sl or --syslibs) with a equal sign (-sl='-libgcc'). + (default is None) -mf, --makefile Create a GNU make makefile. (default is False) -md, --makefiledir GNU make makefile directory. (default is '.') -cs COMMONSRC, --commonsrc COMMONSRC - Additional directory with common source files. - (default is None) + Additional directory with common source files. (default is None) -ef EXTRAFILES, --extrafiles EXTRAFILES - List of extra source files to include in the - compilation. extrafiles can be either a list of files - or the name of a text file that contains a list of - files. (default is None) + List of extra source files to include in the compilation. extrafiles can be either a list of files or the name of a text file that contains a list of files. (default is None) -exf EXCLUDEFILES, --excludefiles EXCLUDEFILES - List of extra source files to exclude from the - compilation. excludefiles can be either a list of - files or the name of a text file that contains a list - of files. (default is None) - -so, --sharedobject Create shared object or dll on Windows. (default is - False) + List of extra source files to exclude from the compilation. excludefiles can be either a list of files or the name of a text file that contains a list of files. (default is None) + -so, --sharedobject Create shared object or dll on Windows. (default is False) -ad APPDIR, --appdir APPDIR - Target path that overides path defined target path - (default is None) + Target path that overides path defined target path (default is None) -v, --verbose Verbose output to terminal. (default is False) --keep Keep existing executable. (default is False) - --zip ZIP Zip built executable. (default is False) - --inplace Source files in srcdir are used directly. (default is - False) - --networkx Use networkx package to build Directed Acyclic Graph - use to determine the order source files are compiled - in. (default is False) + --zip ZIP Zip built executable. (default is None) + --inplace Source files in srcdir are used directly. (default is False) + --networkx Use networkx package to build Directed Acyclic Graph use to determine the order source files are compiled in. (default is False) --meson Use meson to build executable. (default is False) --mesondir meson directory. (default is '.') @@ -203,7 +173,7 @@ python mymf6script.py -fc ifort -cc icc When pymake is installed, a `make-program` (or `make-program.exe` for Windows) program is installed. `make-program` can be used to build MODFLOW 6, MODFLOW-2005, MODFLOW-NWT, MODFLOW-USG, MODFLOW-LGR, MODFLOW-2000, MODPATH 6, MODPATH 7, -GSFLOW, VS2DT, MT3DMS, MT3D-USGS, SEAWAT, GSFLOW, PRMS, and SUTRA. Utility programs CRT, Triangle, and GRIDGEN can also +GSFLOW, VS2DT, MT3DMS, MT3D-USGS, SEAWAT, and SUTRA. Utility programs CRT, Triangle, and GRIDGEN can also be built. `make-program` downloads the distribution file (requires an internet connection), unzips the file, sets the pymake settings required to build the program, and compiles the program from the source files. Optional pymake command line arguments can be used to customize the build (`-fc`, `-cc`, `--fflags`, etc.). For example, MODFLOW 6 could be diff --git a/autotest/test_gsflow.py b/autotest/test_gsflow.py deleted file mode 100644 index 414e59ec..00000000 --- a/autotest/test_gsflow.py +++ /dev/null @@ -1,83 +0,0 @@ -import os -from pathlib import Path -from platform import system - -import flopy -import pytest - -import pymake - -# set fpth based on current path -if os.path.basename(os.path.normpath(os.getcwd())) == "autotest": - fpth = Path("temp") -else: - fpth = Path("autotest/temp") -fpth = (fpth / "gsflowexamples/gsflowexamples.txt").resolve() -if fpth.is_file(): - with open(fpth) as f: - lines = f.read().splitlines() - sim_dirs = [line for line in lines if len(line) > 0] -else: - sim_dirs = [] - - -@pytest.fixture(scope="module") -def target(module_tmpdir) -> Path: - name = "gsflow" - ext = ".exe" if system() == "Windows" else "" - return module_tmpdir / f"{name}{ext}" - - -@pytest.fixture(scope="module") -def prog_data(target) -> dict: - return pymake.usgs_program_data.get_target(target.name) - - -@pytest.fixture(scope="module") -def workspace(module_tmpdir, prog_data) -> Path: - return module_tmpdir / prog_data.dirname - - -@pytest.fixture(scope="module") -def pm(module_tmpdir, target) -> pymake.Pymake: - pm = pymake.Pymake(verbose=True) - pm.target = str(target) - pm.appdir = module_tmpdir - pm.makefile = True - pm.makeclean = True - pm.makefiledir = module_tmpdir - pm.inplace = True - pm.networkx = True - pm.verbose = True - yield pm - pm.finalize() - - -@pytest.mark.dependency(name="download") -@pytest.mark.base -def test_download(pm, module_tmpdir, target): - pm.download_target(target, download_path=module_tmpdir) - assert pm.download, f"could not download {target} distribution" - - -@pytest.mark.dependency(name="build", depends=["download"]) -@pytest.mark.base -def test_compile(pm, target): - assert pm.build() == 0, f"could not compile {target}" - - -@pytest.mark.dependency(name="test", depends=["build"]) -@pytest.mark.regression -@pytest.mark.parametrize("ws", sim_dirs) -def test_gsflow(ws, target): - success, _ = flopy.run_model( - target, - "gsflow.control", - model_ws=ws, - silent=False, - normal_msg=[ - "normal termination", - "Normal completion of GSFLOW", - ], - ) - assert success, f"could not run {ws}" diff --git a/docs/build_apps.md b/docs/build_apps.md index 820c0cee..f5c329ad 100644 --- a/docs/build_apps.md +++ b/docs/build_apps.md @@ -7,23 +7,14 @@ and options can be determined by executing: ```console $ make-program --help -usage: make-program [-h] [-fc {ifort,mpiifort,gfortran,none}] - [-cc {gcc,clang,clang++,icc,icl,mpiicc,g++,cl,none}] - [-dbl] [-dr] [-ff FFLAGS] [-cf CFLAGS] [-ad APPDIR] [-v] - [--keep] [--zip ZIP] [--meson] +usage: make-program [-h] [-fc {ifort,mpiifort,gfortran,none}] [-cc {gcc,clang,clang++,icc,icl,mpiicc,g++,cl,none}] [-dbl] [-dr] [-ff FFLAGS] [-cf CFLAGS] [-ad APPDIR] [-v] [--keep] [--zip ZIP] [--meson] targets Download and build USGS MODFLOW and related programs. positional arguments: - targets Program(s) to build. Options: crt, gridgen, gsflow, - libmf6, mf2000, mf2005, mf6, mflgr, mfnwt, mfusg, - mfusg_gsi, mp6, mp7, mt3dms, mt3dusgs, sutra, swtv4, - triangle, vs2dt, zbud6, zonbud3, zonbudusg, :. - Specifying the target to be ':' will build all of the - programs. Multiple targets can be specified by - separating individual targets by a comma (i.e., - mf6,zbud6). + targets Program(s) to build. Options: crt, gridgen, libmf6, mf2000, mf2005, mf6, mflgr, mfnwt, mfusg, mfusg_gsi, mp6, mp7, mt3dms, mt3dusgs, sutra, swtv4, triangle, vs2dt, zbud6, zonbud3, + zonbudusg, :. Specifying the target to be ':' will build all of the programs. Multiple targets can be specified by separating individual targets by a comma (i.e., mf6,zbud6). options: -h, --help show this help message and exit @@ -32,23 +23,15 @@ options: -cc {gcc,clang,clang++,icc,icl,mpiicc,g++,cl,none} C/C++ compiler to use. (default is gcc) -dbl, --double Force double precision. (default is False) - -dr, --dryrun Do not actually compile. Files will be deleted, if - --makeclean is used. Does not work yet for ifort. - (default is False) + -dr, --dryrun Do not actually compile. Files will be deleted, if --makeclean is used. Does not work yet for ifort. (default is False) -ff FFLAGS, --fflags FFLAGS - Additional Fortran compiler flags. Fortran compiler - flags should be enclosed in quotes and start with a - blank space or separated from the name (-ff or - --fflags) with a equal sign (-ff='-O3'). (default is - None) + Additional Fortran compiler flags. Fortran compiler flags should be enclosed in quotes and start with a blank space or separated from the name (-ff or --fflags) with a equal sign + (-ff='-O3'). (default is None) -cf CFLAGS, --cflags CFLAGS - Additional C/C++ compiler flags. C/C++ compiler flags - should be enclosed in quotes and start with a blank - space or separated from the name (-cf or --cflags) - with a equal sign (-cf='-O3'). (default is None) + Additional C/C++ compiler flags. C/C++ compiler flags should be enclosed in quotes and start with a blank space or separated from the name (-cf or --cflags) with a equal sign + (-cf='-O3'). (default is None) -ad APPDIR, --appdir APPDIR - Target path that overides path defined target path - (default is None) + Target path that overides path defined target path (default is None) -v, --verbose Verbose output to terminal. (default is False) --keep Keep existing executable. (default is False) --zip ZIP Zip built executable. (default is None) diff --git a/docs/index.rst b/docs/index.rst index 2e520c87..9fa2d6d8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -17,7 +17,7 @@ programs released by the USGS. pymake includes example scripts for building MODFLOW 6, MODFLOW-2005, MODFLOW-NWT, MODFLOW-USG, MODFLOW-LGR, MODFLOW-2000, MODPATH 6, MODPATH 7, -GSFLOW, VS2DT, MT3DMS, MT3D-USGS, SEAWAT, and SUTRA. Example scripts for +VS2DT, MT3DMS, MT3D-USGS, SEAWAT, and SUTRA. Example scripts for creating the utility programs CRT, Triangle, and GRIDGEN are also included. The scripts download the distribution file from the USGS (and other organizations) and compile the source into a binary executable. diff --git a/pymake/pymake.py b/pymake/pymake.py index b715a96a..31d9829a 100644 --- a/pymake/pymake.py +++ b/pymake/pymake.py @@ -503,8 +503,6 @@ def _set_include_subdirs(self): "libmf6", "gridgen", "mf6beta", - "gsflow", - "prms", ): self.include_subdirs = True else: diff --git a/pymake/pymake_build_apps.py b/pymake/pymake_build_apps.py index 95e48eeb..2feb2312 100644 --- a/pymake/pymake_build_apps.py +++ b/pymake/pymake_build_apps.py @@ -205,11 +205,6 @@ def build_apps( download_verify = True timeout = 30 - # reset meson - if target in ("prms",): - pmobj.meson = True - pmobj.inplace = True - # set target and srcdir pmobj.target = target.replace("dev", "") pmobj.srcdir = os.path.join( diff --git a/pymake/utils/_compiler_switches.py b/pymake/utils/_compiler_switches.py index 975d862a..0b1dfa6a 100644 --- a/pymake/utils/_compiler_switches.py +++ b/pymake/utils/_compiler_switches.py @@ -781,25 +781,6 @@ def _set_fflags(target, fc="gfortran", argv=True, osname=None, verbose=False): if target == "mp7": if fc == "gfortran": fflags.append("-ffree-line-length-512") - elif target in ("gsflow", "prms"): - if fc == "ifort": - if osname == "win32": - fflags += [ - "-fp:source", - "-names:lowercase", - "-assume:underscore", - ] - else: - pass - elif fc == "gfortran": - fflags += ["-O1", "-fno-second-underscore"] - opt = "-fallow-argument-mismatch" - if _check_gnu_switch_available( - opt, compiler=fc, verbose=verbose - ): - fflags += [ - opt, - ] elif target in ( "mf2000", "mt3dms", @@ -899,17 +880,6 @@ def _set_cflags(target, cc="gcc", argv=True, osname=None, verbose=False): cflags += ["-lm"] else: cflags += ["-DNO_TIMER"] - elif target in ( - "gsflow", - "prms", - ): - if cc in ["icc", "icpl", "icl"]: - if osname == "win32": - cflags += ["-D_CRT_SECURE_NO_WARNINGS"] - else: - cflags += ["-D_UF"] - elif cc == "gcc": - cflags += ["-O1"] # add additional cflags from the command line if argv: @@ -1013,10 +983,6 @@ def _set_syslibs( lcc = True if lfc and lcc: syslibs += ["-lm"] - elif target in ("gsflow", "prms"): - if "win32" not in osname: - if "ifort" in fc: - syslibs += ["-nofor_main"] # add additional syslibs from the command line if argv: diff --git a/pymake/utils/_usgs_src_update.py b/pymake/utils/_usgs_src_update.py index 989efd51..fbd1752b 100644 --- a/pymake/utils/_usgs_src_update.py +++ b/pymake/utils/_usgs_src_update.py @@ -468,114 +468,6 @@ def _update_mfnwt_files(srcdir, fc, cc, arch, double): _update_swi(srcdir, double) -def _update_prms_files(srcdir, fc, cc, arch, double): - """Update PRMS source files - - Parameters - ---------- - srcdir : str - path to directory with source files - fc : str - fortran compiler - cc : str - c/c++ compiler - arch : str - architecture - double : bool - boolean indicating if compiler switches are used to build a - double precision target - - Returns - ------- - - """ - # remove existing *.mod, *.o, and *.a (if any are left) files - dpths = [ - os.path.join(srcdir, o) - for o in os.listdir(srcdir) - if os.path.isdir(os.path.join(srcdir, o)) - ] - - for dpth in dpths: - for f in os.listdir(dpth): - ext = os.path.splitext(f)[1] - fpth = os.path.join(dpth, f) - if ext in [".mod", ".o", ".a"]: - os.remove(fpth) - - # remove specific files - fpths = ( - os.path.join(srcdir, "prms", "gsflow_module.f90"), - os.path.join(srcdir, "prms", "gsflow_prms.f90"), - ) - for fpth in fpths: - if os.path.isfile(fpth): - os.remove(fpth) - - return - - -def _update_gsflow_files(srcdir, fc, cc, arch, double): - """Update GSFLOW source files - - Parameters - ---------- - srcdir : str - path to directory with source files - fc : str - fortran compiler - cc : str - c/c++ compiler - arch : str - architecture - double : bool - boolean indicating if compiler switches are used to build a - double precision target - - Returns - ------- - - """ - # update utl7.f - _update_utl7(srcdir) - - # update gwf2swt7.f - _update_swt(srcdir) - - # update gwf2swi27.f or gwf2swi27.fpp - _update_swi(srcdir, double) - - # remove merge and lib directories - pths = [os.path.join(srcdir, "merge"), os.path.join(srcdir, "lib")] - for pth in pths: - if os.path.isdir(pth): - shutil.rmtree(pth) - - # remove existing *.mod, *.o, and *.a (if any are left) files - dpths = [ - os.path.join(srcdir, o) - for o in os.listdir(srcdir) - if os.path.isdir(os.path.join(srcdir, o)) - ] - - for dpth in dpths: - for f in os.listdir(dpth): - ext = os.path.splitext(f)[1] - fpth = os.path.join(dpth, f) - if ext in [".mod", ".o", ".a"]: - os.remove(fpth) - - # remove specific files - fpths = [ - os.path.join(srcdir, "modflow", "gwf2ag1_NWT_rsr.f"), - ] - for fpth in fpths: - if os.path.isfile(fpth): - os.remove(fpth) - - return - - def _update_mf2000_files(srcdir, fc, cc, arch, double): """Update MODFLOW-2000 source files diff --git a/pymake/utils/usgsprograms.txt b/pymake/utils/usgsprograms.txt index a4414d39..a1ae40ac 100644 --- a/pymake/utils/usgsprograms.txt +++ b/pymake/utils/usgsprograms.txt @@ -21,7 +21,6 @@ zonbud3 , 3.01 , True , https://water.usgs.gov/water-resources/software mfnwt1.1.4 , 1.1.4 , False , https://water.usgs.gov/water-resources/software/MODFLOW-NWT/MODFLOW-NWT_1.1.4.zip , MODFLOW-NWT_1.1.4 , src , True , False , False mfnwt , 1.3.0 , True , https://water.usgs.gov/water-resources/software/MODFLOW-NWT/MODFLOW-NWT_1.3.0.zip , MODFLOW-NWT , src , True , False , False mfusg_gsi , 2.2.2 , True , https://www.gsienv.com/wp-content/uploads/2023/11/USG-Transport_Version-2.2.2.zip , USGT-v2-2-2-Source , . , True , False , False -gsflow , 2.2.1 , True , https://water.usgs.gov/water-resources/software/gsflow/gsflow_2.2.1_linux.zip , gsflow_2.2.1 , src , True , False , False mf6dev , 6.6.0.dev0 , False , https://github.com/MODFLOW-USGS/modflow6/archive/refs/heads/develop.zip , modflow6-develop , src , True , False , False zbud6dev , 6.6.0.dev0 , False , https://github.com/MODFLOW-USGS/modflow6/archive/refs/heads/develop.zip , modflow6-develop , utils/zonebudget/src, True , False , False libmf6dev , 6.6.0.dev0 , False , https://github.com/MODFLOW-USGS/modflow6/archive/refs/heads/develop.zip , modflow6-develop , srcbmi , True , False , True \ No newline at end of file