From 08170faee8d95faf0a854d3fb3859135cbcdcf03 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Tue, 5 Mar 2024 12:46:27 -0700 Subject: [PATCH 01/36] Move zest.releaser config to pyproject.toml --- babelizer/data/{{cookiecutter.package_name}}/pyproject.toml | 4 ++++ babelizer/data/{{cookiecutter.package_name}}/setup.cfg | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml b/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml index b0077dce..deade262 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml +++ b/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml @@ -107,3 +107,7 @@ underlines = "-^\"" issue_format = "`#{issue} `_" title_format = "{version} ({project_date})" wrap = true + +[tool.zest-releaser] +tag-format = "v{version}" +python-file-with-version = "{{ cookiecutter.package_name }}/_version.py" diff --git a/babelizer/data/{{cookiecutter.package_name}}/setup.cfg b/babelizer/data/{{cookiecutter.package_name}}/setup.cfg index 45fca16c..f3d7d5c3 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/setup.cfg +++ b/babelizer/data/{{cookiecutter.package_name}}/setup.cfg @@ -5,6 +5,3 @@ ignore = E501 W503 max-line-length = 88 - -[zest.releaser] -tag-format = v{version} From 78aaec340d78ab5b539c2252c94701cbab752f81 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Tue, 5 Mar 2024 16:16:19 -0700 Subject: [PATCH 02/36] Set up Meson build for a single Fortran component This is WIP, but the project files are in the right place. --- .../{{cookiecutter.package_name}}/meson.build | 70 +++++++++++++++++++ .../pyproject.toml | 6 +- 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 babelizer/data/{{cookiecutter.package_name}}/meson.build diff --git a/babelizer/data/{{cookiecutter.package_name}}/meson.build b/babelizer/data/{{cookiecutter.package_name}}/meson.build new file mode 100644 index 00000000..d3ae3d4f --- /dev/null +++ b/babelizer/data/{{cookiecutter.package_name}}/meson.build @@ -0,0 +1,70 @@ +project('{{ cookiecutter.package_name }}', '{{ cookiecutter.language }}', 'cython', version: '{{ cookiecutter.package_version }}') + +py = import('python').find_installation(pure: false) +fc = meson.get_compiler('fortran') + +python_inc = py.get_path('data') / 'include' +numpy_inc = run_command( + py, + [ + '-c', + 'import numpy; print(numpy.get_include())' + ], + check: true +).stdout().strip() +incs = include_directories( + [ + '{{ cookiecutter.package_name }}/lib', + python_inc, + numpy_inc, + ] +) + +deps = [ + fc.find_library('bmif'), + fc.find_library('heatf'), + fc.find_library('bmiheatf'), +] + +{# This is temporary until I figure out how to do multiple components. #} +{%- set babelized_class = 'HeatModelF' -%} + +srcs = [ + '{{ cookiecutter.package_name }}/lib/bmi_interoperability.f90', + '{{ cookiecutter.package_name }}/lib/{{ babelized_class|lower }}.pyx', +] + +# Files get copied to /site-packages/ +install_pkg_srcs = [ + '{{ cookiecutter.package_name }}/__init__.py', + '{{ cookiecutter.package_name }}/_bmi.py', +] +py.install_sources( + install_pkg_srcs, + subdir: '{{ cookiecutter.package_name }}', +) +install_lib_srcs = [ + '{{ cookiecutter.package_name }}/lib/__init__.py', + '{{ cookiecutter.package_name }}/lib/{{ babelized_class|lower }}.pyx', +] +py.install_sources( + install_lib_srcs, + subdir: '{{ cookiecutter.package_name }}/lib', +) + +install_subdir( + 'meta/{{ babelized_class }}', + install_dir: py.get_install_dir() / '{{ cookiecutter.package_name }}/data', +) + +py.extension_module( + '{{ babelized_class|lower }}', + srcs, + dependencies: deps, + include_directories: incs, + install: true, + subdir: '{{ cookiecutter.package_name }}/lib', +) + +# This is a temporary fix for editable installs. +run_command('cp', '-r', '{{ cookiecutter.package_name }}/data', 'build') diff --git a/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml b/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml index deade262..c0db505a 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml +++ b/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml @@ -1,5 +1,6 @@ [build-system] -requires = ["cython", "numpy", "setuptools", "wheel"] +build-backend = "mesonpy" +requires = ["cython", "numpy", "meson-python", "wheel"] [project] name = "{{cookiecutter.package_name}}" @@ -39,6 +40,9 @@ homepage = "https://github.com/{{ cookiecutter.info.github_username }}/{{ cookie [project.optional-dependencies] dev = [ + "meson", + "meson-python", + "ninja", "nox", ] docs = [ From 109a9a0cd5e3707223828571e173a60b8ba0bc4f Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Tue, 5 Mar 2024 21:29:06 -0700 Subject: [PATCH 03/36] Remove setuptools config from pyproject.toml --- .../{{cookiecutter.package_name}}/pyproject.toml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml b/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml index c0db505a..b56ade47 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml +++ b/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml @@ -58,19 +58,6 @@ testing = [ "bmi-tester>=0.5.4", ] -[tool.setuptools.dynamic] -readme = {file = ["README.rst", "CREDITS.rst", "CHANGES.rst", "LICENSE.rst"]} -version = {attr = "{{ cookiecutter.package_name }}._version.__version__"} - -[tool.setuptools] -include-package-data = true -packages = ["{{ cookiecutter.package_name }}"] - -[tool.setuptools.package-data] -{{ cookiecutter.package_name }} = [ - "data/*", -] - [tool.pytest.ini_options] minversion = "5.0" testpaths = ["{{ cookiecutter.package_name }}", "tests"] From 4fe09ad781656913a75d8ecaa144e0a5114f6369 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Tue, 5 Mar 2024 21:47:28 -0700 Subject: [PATCH 04/36] Set version, but not readme, in dynamic metadata It looks like meson doesn't allow readme in dynamic metadata. Be sure to install _version.py. --- babelizer/data/{{cookiecutter.package_name}}/meson.build | 1 + babelizer/data/{{cookiecutter.package_name}}/pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/meson.build b/babelizer/data/{{cookiecutter.package_name}}/meson.build index d3ae3d4f..cd75be5f 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/meson.build +++ b/babelizer/data/{{cookiecutter.package_name}}/meson.build @@ -38,6 +38,7 @@ srcs = [ install_pkg_srcs = [ '{{ cookiecutter.package_name }}/__init__.py', '{{ cookiecutter.package_name }}/_bmi.py', + '{{ cookiecutter.package_name }}/_version.py', ] py.install_sources( install_pkg_srcs, diff --git a/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml b/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml index b56ade47..91694789 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml +++ b/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml @@ -25,7 +25,7 @@ classifiers=[ ] requires-python = ">=3.10" keywords=["bmi", "pymt"] -dynamic = ["readme", "version"] +dynamic = ["version"] dependencies = [ "numpy", ] From 731111aa9a4692e13fd0bd4074d1084364a81485 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Wed, 6 Mar 2024 12:10:37 -0700 Subject: [PATCH 05/36] Read package dependencies from babel.toml file I got help on this from https://stackoverflow.com/a/30517735. --- babelizer/data/{{cookiecutter.package_name}}/meson.build | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/meson.build b/babelizer/data/{{cookiecutter.package_name}}/meson.build index cd75be5f..840d5fd1 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/meson.build +++ b/babelizer/data/{{cookiecutter.package_name}}/meson.build @@ -20,10 +20,11 @@ incs = include_directories( ] ) +{% set dependency_list = cookiecutter.package_requirements.split(',') -%} deps = [ - fc.find_library('bmif'), - fc.find_library('heatf'), - fc.find_library('bmiheatf'), +{%- for dependency in dependency_list %} + fc.find_library('{{ dependency }}'), +{%- endfor %} ] {# This is temporary until I figure out how to do multiple components. #} From 1e5a1a1c575b57f8fa2102f49063f9f64871d82c Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Wed, 6 Mar 2024 21:23:05 -0700 Subject: [PATCH 06/36] Filter dependencies on default empty string --- babelizer/data/{{cookiecutter.package_name}}/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/meson.build b/babelizer/data/{{cookiecutter.package_name}}/meson.build index 840d5fd1..0f45a5e2 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/meson.build +++ b/babelizer/data/{{cookiecutter.package_name}}/meson.build @@ -22,7 +22,7 @@ incs = include_directories( {% set dependency_list = cookiecutter.package_requirements.split(',') -%} deps = [ -{%- for dependency in dependency_list %} +{%- for dependency in dependency_list if dependency != '' %} fc.find_library('{{ dependency }}'), {%- endfor %} ] From af3f7e562e1bfdbd5946fd3ba9318240ddf3606b Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Wed, 6 Mar 2024 21:23:45 -0700 Subject: [PATCH 07/36] Update bmi-example-fortran --- external/bmi-example-fortran | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/bmi-example-fortran b/external/bmi-example-fortran index 819757c7..6909f22b 160000 --- a/external/bmi-example-fortran +++ b/external/bmi-example-fortran @@ -1 +1 @@ -Subproject commit 819757c77a779d13f8c67431cc3d13f6f36b0dcc +Subproject commit 6909f22b61b0b3fec0d3b0d0bdec7ee58e4ad8a0 From 1632c4856420ce37318ddf8bd625984171c9851a Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Wed, 6 Mar 2024 21:25:19 -0700 Subject: [PATCH 08/36] Get the name of the first component to babelize This is a temporary fix until I can handle multiple components in the `meson.build` file. --- babelizer/data/{{cookiecutter.package_name}}/meson.build | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/meson.build b/babelizer/data/{{cookiecutter.package_name}}/meson.build index 0f45a5e2..80a093e7 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/meson.build +++ b/babelizer/data/{{cookiecutter.package_name}}/meson.build @@ -20,6 +20,9 @@ incs = include_directories( ] ) +{% set babelized_class = cookiecutter.components|list|first -%} +# babelized_class = {{ babelized_class }} + {% set dependency_list = cookiecutter.package_requirements.split(',') -%} deps = [ {%- for dependency in dependency_list if dependency != '' %} @@ -27,9 +30,6 @@ deps = [ {%- endfor %} ] -{# This is temporary until I figure out how to do multiple components. #} -{%- set babelized_class = 'HeatModelF' -%} - srcs = [ '{{ cookiecutter.package_name }}/lib/bmi_interoperability.f90', '{{ cookiecutter.package_name }}/lib/{{ babelized_class|lower }}.pyx', From e421ff08e4b7f460db2bb572642759d27d89ce92 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Wed, 6 Mar 2024 21:30:48 -0700 Subject: [PATCH 09/36] Set --no-build-isolation for editable installs This is a *meson-python* behavior. See https://meson-python.readthedocs.io/en/stable/how-to-guides/editable-installs.html --- babelizer/data/{{cookiecutter.package_name}}/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/Makefile b/babelizer/data/{{cookiecutter.package_name}}/Makefile index 03d43225..3b25c3d6 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/Makefile +++ b/babelizer/data/{{cookiecutter.package_name}}/Makefile @@ -91,4 +91,4 @@ dist: clean ## builds source and wheel package ls -l dist install: clean ## install the package to the active Python's site-packages - pip install -e . + pip install --no-build-isolation --editable . From 3fb374b49cca215569afa19f6ad6741ac310d830 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Fri, 8 Mar 2024 13:14:56 -0700 Subject: [PATCH 10/36] Include package requirements for example --- external/tests/test_fortran/babel.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/external/tests/test_fortran/babel.toml b/external/tests/test_fortran/babel.toml index 60c816b9..9f1f0398 100644 --- a/external/tests/test_fortran/babel.toml +++ b/external/tests/test_fortran/babel.toml @@ -15,7 +15,11 @@ extra_compile_args = [] [package] name = "pymt_heatf" -requirements = [""] +requirements = [ + "bmif", + "heatf", + "bmiheatf", +] [info] github_username = "pymt-lab" From f76483780b901f42deed30af2d8d0feec91174a3 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 8 Mar 2024 22:17:20 -0700 Subject: [PATCH 11/36] use conda; install bmiheatf in _inst; create bmiheatf.pc --- noxfile.py | 49 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/noxfile.py b/noxfile.py index 662698e6..e19ea57d 100644 --- a/noxfile.py +++ b/noxfile.py @@ -23,11 +23,7 @@ def test(session: nox.Session) -> None: session.run("pytest", *args) -@nox.session( - name="test-langs", - python=PYTHON_VERSIONS, - venv_backend="mamba", -) +@nox.session(name="test-langs", python=PYTHON_VERSIONS, venv_backend="conda") @nox.parametrize("lang", ["c", "cxx", "fortran", "python"]) def test_langs(session: nox.session, lang) -> None: datadir = ROOT / "external" / "tests" / f"test_{lang}" @@ -40,11 +36,30 @@ def test_langs(session: nox.session, lang) -> None: session.debug(library) session.debug(config_file) - build_examples(session, lang) + instdir = build_examples(session, lang) + + session.install("bmi-tester>=0.5.4", "ninja") + session.conda_install("pip", "cmake", "make", "pkg-config") - session.conda_install("pip", "bmi-tester>=0.5.4", "cmake") session.install(".[testing]") + bmiheatf_pc = f"""\ +prefix={instdir!s} +exec_prefix=${{prefix}} +libdir=${{exec_prefix}}/lib +includedir=${{prefix}}/include + +Name: bmiheatf +Description: BMI Heat Fortran +Version: 1.0.0 +Libs: -L${{libdir}} -lheatf -lbmiheatf +Cflags: -I${{includedir}} +""" + + os.makedirs(instdir / "lib" / "pkgconfig", exist_ok=True) + with open(instdir / "lib" / "pkgconfig" / "bmiheatf.pc", "w") as fp: + print(bmiheatf_pc, file=fp) + with session.chdir(tmpdir): session.run( "babelize", @@ -56,7 +71,14 @@ def test_langs(session: nox.session, lang) -> None: session.debug(f"{k}: {v!r}") with session.chdir(package): - session.run("python", "-m", "pip", "install", "-e", ".") + session.run( + "python", + "-m", + "pip", + "install", + ".[dev]", + env={"PKG_CONFIG_PATH": os.path.join(instdir, "lib", "pkgconfig")}, + ) with session.chdir(testdir): shutil.copy(datadir / config_file, ".") @@ -85,17 +107,19 @@ def _get_package_metadata(datadir): return package, library, config_files[0] -@nox.session(name="build-examples", venv_backend="mamba") +@nox.session(name="build-examples", venv_backend="conda") @nox.parametrize("lang", ["c", "cxx", "fortran", "python"]) def build_examples(session: nox.Session, lang): """Build the language examples.""" srcdir = ROOT / "external" / f"bmi-example-{lang}" - builddir = pathlib.Path(session.create_tmp()) / "_build" + tmpdir = ROOT / pathlib.Path(session.create_tmp()) + builddir = tmpdir / "_build" + instdir = tmpdir / "_inst" if lang == "python": session.conda_install("bmipy", "make") else: - session.conda_install(f"bmi-{lang}", "cmake", "make", "pkg-config") + session.conda_install(f"bmi-{lang}", "make", "pkg-config") for k, v in sorted(session.env.items()): session.debug(f"{k}: {v!r}") @@ -111,9 +135,10 @@ def build_examples(session: nox.Session, lang): str(srcdir), "-B", ".", - f"-DCMAKE_INSTALL_PREFIX={session.env['CONDA_PREFIX']}", + f"-DCMAKE_INSTALL_PREFIX={instdir}", ) session.run("make", "install") + return instdir @nox.session(name="test-cli") From 87c465033408aac6b80f66a677fcce52f7241adf Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 8 Mar 2024 22:18:11 -0700 Subject: [PATCH 12/36] add bmiheatf as a dependency --- babelizer/data/{{cookiecutter.package_name}}/meson.build | 3 +++ 1 file changed, 3 insertions(+) diff --git a/babelizer/data/{{cookiecutter.package_name}}/meson.build b/babelizer/data/{{cookiecutter.package_name}}/meson.build index 80a093e7..591de519 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/meson.build +++ b/babelizer/data/{{cookiecutter.package_name}}/meson.build @@ -3,6 +3,8 @@ project('{{ cookiecutter.package_name }}', '{{ cookiecutter.language }}', 'cytho py = import('python').find_installation(pure: false) fc = meson.get_compiler('fortran') +bmiheatf = dependency('bmiheatf', method : 'pkg-config') + python_inc = py.get_path('data') / 'include' numpy_inc = run_command( py, @@ -25,6 +27,7 @@ incs = include_directories( {% set dependency_list = cookiecutter.package_requirements.split(',') -%} deps = [ + bmiheatf, {%- for dependency in dependency_list if dependency != '' %} fc.find_library('{{ dependency }}'), {%- endfor %} From 5ae3a8f00b58f2a6498b1d6d75fa734dcf34f275 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 8 Mar 2024 22:20:25 -0700 Subject: [PATCH 13/36] remove requirements from babel.toml --- external/tests/test_fortran/babel.toml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/external/tests/test_fortran/babel.toml b/external/tests/test_fortran/babel.toml index 9f1f0398..0aaf3760 100644 --- a/external/tests/test_fortran/babel.toml +++ b/external/tests/test_fortran/babel.toml @@ -15,11 +15,7 @@ extra_compile_args = [] [package] name = "pymt_heatf" -requirements = [ - "bmif", - "heatf", - "bmiheatf", -] +requirements = [] [info] github_username = "pymt-lab" From a88ff05294a05e6ac8ff37f5d0138731735ef792 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sat, 9 Mar 2024 18:43:19 -0700 Subject: [PATCH 14/36] install build tools on a per language basis --- .github/workflows/test-langs.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-langs.yml b/.github/workflows/test-langs.yml index 2b32dd0e..be4af0bc 100644 --- a/.github/workflows/test-langs.yml +++ b/.github/workflows/test-langs.yml @@ -41,7 +41,8 @@ jobs: run: python -m pip install nox tomli - name: Install compilers - run: mamba install c-compiler cxx-compiler fortran-compiler + if: matrix.language != 'python' + run: mamba install ${{ matrix.language }}-compiler bmi-${{ matrix.language }} cmake make pkg-config - name: Run the language tests run: nox -s "test-langs-${{ matrix.python-version }}(lang='${{ matrix.language }}')" --python ${{ matrix.python-version }} --verbose From 6feaaa97aa67b966456aaec63353de0a5fa7248d Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 10 Mar 2024 23:00:31 -0600 Subject: [PATCH 15/36] add bmi-tester as a testing dependency --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index f5b36f1b..04357a5a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,6 +78,7 @@ docs = [ "sphinxcontrib.towncrier", ] testing = [ + "bmi-tester>=0.5.9", "coverage[toml]", "coveralls", "pytest", From 5ce7b93ed9e7bceb3c816463986cf162a81de956 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 10 Mar 2024 23:01:18 -0600 Subject: [PATCH 16/36] install language-specific build tools --- .github/workflows/test-langs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-langs.yml b/.github/workflows/test-langs.yml index be4af0bc..47d45759 100644 --- a/.github/workflows/test-langs.yml +++ b/.github/workflows/test-langs.yml @@ -42,7 +42,7 @@ jobs: - name: Install compilers if: matrix.language != 'python' - run: mamba install ${{ matrix.language }}-compiler bmi-${{ matrix.language }} cmake make pkg-config + run: mamba install ${{ matrix.language }}-compiler cmake make pkg-config - name: Run the language tests run: nox -s "test-langs-${{ matrix.python-version }}(lang='${{ matrix.language }}')" --python ${{ matrix.python-version }} --verbose From 170623c439903f8b7d9826a32e5cda9c936eea8d Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 10 Mar 2024 23:01:47 -0600 Subject: [PATCH 17/36] create a pkg-config file for heatf; back to using conda --- noxfile.py | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/noxfile.py b/noxfile.py index e19ea57d..38ad6e35 100644 --- a/noxfile.py +++ b/noxfile.py @@ -38,9 +38,6 @@ def test_langs(session: nox.session, lang) -> None: instdir = build_examples(session, lang) - session.install("bmi-tester>=0.5.4", "ninja") - session.conda_install("pip", "cmake", "make", "pkg-config") - session.install(".[testing]") bmiheatf_pc = f"""\ @@ -52,7 +49,8 @@ def test_langs(session: nox.session, lang) -> None: Name: bmiheatf Description: BMI Heat Fortran Version: 1.0.0 -Libs: -L${{libdir}} -lheatf -lbmiheatf +Requires: heatf +Libs: -L${{libdir}} -lbmiheatf Cflags: -I${{includedir}} """ @@ -60,6 +58,23 @@ def test_langs(session: nox.session, lang) -> None: with open(instdir / "lib" / "pkgconfig" / "bmiheatf.pc", "w") as fp: print(bmiheatf_pc, file=fp) + heatf_pc = f"""\ +_prefix={os.environ.get('CMAKE_PREFIX_PATH', instdir)} +exec_prefix=${{_prefix}} +libdir=${{exec_prefix}}/lib +includedir=${{_prefix}}/include + +Name: heatf +Description: Heat Fortran +Version: 1.0.0 +Libs: -L${{libdir}} -lheatf +Cflags: -I${{includedir}} +""" + + os.makedirs(instdir / "lib" / "pkgconfig", exist_ok=True) + with open(instdir / "lib" / "pkgconfig" / "heatf.pc", "w") as fp: + print(heatf_pc, file=fp) + with session.chdir(tmpdir): session.run( "babelize", @@ -107,19 +122,19 @@ def _get_package_metadata(datadir): return package, library, config_files[0] -@nox.session(name="build-examples", venv_backend="conda") +@nox.session(name="build-examples", python=PYTHON_VERSIONS, venv_backend="conda") @nox.parametrize("lang", ["c", "cxx", "fortran", "python"]) def build_examples(session: nox.Session, lang): """Build the language examples.""" srcdir = ROOT / "external" / f"bmi-example-{lang}" tmpdir = ROOT / pathlib.Path(session.create_tmp()) builddir = tmpdir / "_build" - instdir = tmpdir / "_inst" + instdir = pathlib.Path(session.virtualenv.location) if lang == "python": - session.conda_install("bmipy", "make") + session.install("bmipy") else: - session.conda_install(f"bmi-{lang}", "make", "pkg-config") + session.conda_install(f"bmi-{lang}") for k, v in sorted(session.env.items()): session.debug(f"{k}: {v!r}") From 9bd813949258cbed72e113ed379a6ef2890835a9 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 10 Mar 2024 23:02:24 -0600 Subject: [PATCH 18/36] add c and cpp to builds --- .../{{cookiecutter.package_name}}/meson.build | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/meson.build b/babelizer/data/{{cookiecutter.package_name}}/meson.build index 591de519..5126f54d 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/meson.build +++ b/babelizer/data/{{cookiecutter.package_name}}/meson.build @@ -1,11 +1,32 @@ -project('{{ cookiecutter.package_name }}', '{{ cookiecutter.language }}', 'cython', version: '{{ cookiecutter.package_version }}') +project( + '{{ cookiecutter.package_name }}', +{%- if cookiecutter.language == 'c' %} + 'c', +{%- elif cookiecutter.language == 'c++' %} + 'cpp', +{%- elif cookiecutter.language == 'fortran' %} + 'fortran', +{%- endif %} + 'cython', + version: '{{ cookiecutter.package_version }}', +) + +{%- if cookiecutter.language == 'c' %} +lang = 'c' +bmilib = 'bmiheatc' +{%- elif cookiecutter.language == 'c++' %} +lang = 'cpp' +bmilib = 'bmiheatcxx' +{%- elif cookiecutter.language == 'fortran' %} +lang = 'fortran' +bmilib = 'bmiheatf' +{%- endif %} py = import('python').find_installation(pure: false) -fc = meson.get_compiler('fortran') -bmiheatf = dependency('bmiheatf', method : 'pkg-config') +compiler = meson.get_compiler(lang) -python_inc = py.get_path('data') / 'include' +# python_inc = py.get_path('data') / 'include' numpy_inc = run_command( py, [ @@ -17,7 +38,7 @@ numpy_inc = run_command( incs = include_directories( [ '{{ cookiecutter.package_name }}/lib', - python_inc, + # python_inc, numpy_inc, ] ) @@ -27,14 +48,18 @@ incs = include_directories( {% set dependency_list = cookiecutter.package_requirements.split(',') -%} deps = [ - bmiheatf, +{%- if cookiecutter.language in ['c', 'c++', 'fortran'] %} + dependency(bmilib, method : 'pkg-config'), +{% endif %} {%- for dependency in dependency_list if dependency != '' %} - fc.find_library('{{ dependency }}'), + compiler.find_library('{{ dependency }}'), {%- endfor %} ] srcs = [ +{%- if cookiecutter.language == 'fortran' %} '{{ cookiecutter.package_name }}/lib/bmi_interoperability.f90', +{%- endif %} '{{ cookiecutter.package_name }}/lib/{{ babelized_class|lower }}.pyx', ] @@ -69,6 +94,9 @@ py.extension_module( include_directories: incs, install: true, subdir: '{{ cookiecutter.package_name }}/lib', +{%- if cookiecutter.language == 'c++' %} + override_options : ['cython_language=cpp'], +{%- endif %} ) # This is a temporary fix for editable installs. From 91a37041c3666c07ce349a385fc144c94fc740e3 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 11 Mar 2024 09:22:39 -0600 Subject: [PATCH 19/36] update setup-miniconda --- .github/workflows/test-langs.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-langs.yml b/.github/workflows/test-langs.yml index 47d45759..2acae11e 100644 --- a/.github/workflows/test-langs.yml +++ b/.github/workflows/test-langs.yml @@ -29,11 +29,10 @@ jobs: with: submodules: true - - uses: conda-incubator/setup-miniconda@v2 + - uses: conda-incubator/setup-miniconda@v3 with: auto-update-conda: true python-version: ${{ matrix.python-version }} - mamba-version: "*" channels: conda-forge channel-priority: true @@ -42,7 +41,7 @@ jobs: - name: Install compilers if: matrix.language != 'python' - run: mamba install ${{ matrix.language }}-compiler cmake make pkg-config + run: conda install ${{ matrix.language }}-compiler cmake make - name: Run the language tests run: nox -s "test-langs-${{ matrix.python-version }}(lang='${{ matrix.language }}')" --python ${{ matrix.python-version }} --verbose From c795a9de3fa6560e4d288a0e3ea5e730ae43177e Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 11 Mar 2024 09:23:49 -0600 Subject: [PATCH 20/36] install pkg-config in test environment --- noxfile.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/noxfile.py b/noxfile.py index 38ad6e35..1dba261e 100644 --- a/noxfile.py +++ b/noxfile.py @@ -86,14 +86,7 @@ def test_langs(session: nox.session, lang) -> None: session.debug(f"{k}: {v!r}") with session.chdir(package): - session.run( - "python", - "-m", - "pip", - "install", - ".[dev]", - env={"PKG_CONFIG_PATH": os.path.join(instdir, "lib", "pkgconfig")}, - ) + session.run("python", "-m", "pip", "install", ".[dev]") with session.chdir(testdir): shutil.copy(datadir / config_file, ".") @@ -134,7 +127,7 @@ def build_examples(session: nox.Session, lang): if lang == "python": session.install("bmipy") else: - session.conda_install(f"bmi-{lang}") + session.conda_install(f"bmi-{lang}", "pkg-config") for k, v in sorted(session.env.items()): session.debug(f"{k}: {v!r}") From a16ef56302e4816b9b324e2e189f92f2272da436 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 11 Mar 2024 10:10:44 -0600 Subject: [PATCH 21/36] fix heatf pkg-config file and bmic, bmicxx pkg-config names --- babelizer/data/{{cookiecutter.package_name}}/meson.build | 4 ++-- noxfile.py | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/meson.build b/babelizer/data/{{cookiecutter.package_name}}/meson.build index 5126f54d..13368271 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/meson.build +++ b/babelizer/data/{{cookiecutter.package_name}}/meson.build @@ -13,10 +13,10 @@ project( {%- if cookiecutter.language == 'c' %} lang = 'c' -bmilib = 'bmiheatc' +bmilib = 'BmiHeatC' {%- elif cookiecutter.language == 'c++' %} lang = 'cpp' -bmilib = 'bmiheatcxx' +bmilib = 'BmiHeatCXX' {%- elif cookiecutter.language == 'fortran' %} lang = 'fortran' bmilib = 'bmiheatf' diff --git a/noxfile.py b/noxfile.py index 1dba261e..636d52f4 100644 --- a/noxfile.py +++ b/noxfile.py @@ -59,10 +59,10 @@ def test_langs(session: nox.session, lang) -> None: print(bmiheatf_pc, file=fp) heatf_pc = f"""\ -_prefix={os.environ.get('CMAKE_PREFIX_PATH', instdir)} -exec_prefix=${{_prefix}} +prefix={instdir!s} +exec_prefix=${{prefix}} libdir=${{exec_prefix}}/lib -includedir=${{_prefix}}/include +includedir=${{prefix}}/include Name: heatf Description: Heat Fortran @@ -86,6 +86,7 @@ def test_langs(session: nox.session, lang) -> None: session.debug(f"{k}: {v!r}") with session.chdir(package): + session.run("pkg-config", "--list-all") session.run("python", "-m", "pip", "install", ".[dev]") with session.chdir(testdir): From 74852c2e7e486dd7e40b4ee207bbf379d920168c Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 11 Mar 2024 10:28:42 -0600 Subject: [PATCH 22/36] update c, cxx submodules --- external/bmi-example-c | 2 +- external/bmi-example-cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/external/bmi-example-c b/external/bmi-example-c index 5d39005f..f47d0a65 160000 --- a/external/bmi-example-c +++ b/external/bmi-example-c @@ -1 +1 @@ -Subproject commit 5d39005f1aad3c2bb38c2661d68c8e453269cefe +Subproject commit f47d0a65edf848ccd9d57d375e9fdd90354c1f4f diff --git a/external/bmi-example-cxx b/external/bmi-example-cxx index 1c2d0902..07c3dd51 160000 --- a/external/bmi-example-cxx +++ b/external/bmi-example-cxx @@ -1 +1 @@ -Subproject commit 1c2d0902963894a96d80d852777769a8d14f0779 +Subproject commit 07c3dd518ddcd7db50e22be0db6ff3fc067053fb From b3210a9b9f2df86ef1e9578ae69115572f532796 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 11 Mar 2024 10:33:15 -0600 Subject: [PATCH 23/36] back to lowercase for pkg-config names --- babelizer/data/{{cookiecutter.package_name}}/meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/meson.build b/babelizer/data/{{cookiecutter.package_name}}/meson.build index 13368271..5126f54d 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/meson.build +++ b/babelizer/data/{{cookiecutter.package_name}}/meson.build @@ -13,10 +13,10 @@ project( {%- if cookiecutter.language == 'c' %} lang = 'c' -bmilib = 'BmiHeatC' +bmilib = 'bmiheatc' {%- elif cookiecutter.language == 'c++' %} lang = 'cpp' -bmilib = 'BmiHeatCXX' +bmilib = 'bmiheatcxx' {%- elif cookiecutter.language == 'fortran' %} lang = 'fortran' bmilib = 'bmiheatf' From b7f33b64585cd6df7d75498c49f06b7165398a3a Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 11 Mar 2024 10:58:16 -0600 Subject: [PATCH 24/36] use setuptools for pure-python projects --- .../{{cookiecutter.package_name}}/pyproject.toml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml b/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml index 91694789..7df13701 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml +++ b/babelizer/data/{{cookiecutter.package_name}}/pyproject.toml @@ -1,6 +1,13 @@ [build-system] +{%- if cookiecutter.language == 'python' %} +build-backend = "setuptools.build_meta" +requires = [ + "setuptools >=61", +] +{% else %} build-backend = "mesonpy" requires = ["cython", "numpy", "meson-python", "wheel"] +{% endif %} [project] name = "{{cookiecutter.package_name}}" @@ -58,6 +65,12 @@ testing = [ "bmi-tester>=0.5.4", ] +{%- if cookiecutter.language == 'python' %} +[tool.setuptools.packages.find] +where = ["."] +include = ["{{cookiecutter.package_name}}*"] +{% endif %} + [tool.pytest.ini_options] minversion = "5.0" testpaths = ["{{ cookiecutter.package_name }}", "tests"] From ec29a4b7ea636e7f587c07b095cf40ccb2b22f00 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 11 Mar 2024 12:35:14 -0600 Subject: [PATCH 25/36] build multiple extension; remove bmiheat dependency --- .../{{cookiecutter.package_name}}/meson.build | 54 +++++++++---------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/meson.build b/babelizer/data/{{cookiecutter.package_name}}/meson.build index 5126f54d..6edc29d5 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/meson.build +++ b/babelizer/data/{{cookiecutter.package_name}}/meson.build @@ -11,21 +11,16 @@ project( version: '{{ cookiecutter.package_version }}', ) +py = import('python').find_installation(pure: false) + {%- if cookiecutter.language == 'c' %} -lang = 'c' -bmilib = 'bmiheatc' +compiler = meson.get_compiler('c') {%- elif cookiecutter.language == 'c++' %} -lang = 'cpp' -bmilib = 'bmiheatcxx' +compiler = meson.get_compiler('cpp') {%- elif cookiecutter.language == 'fortran' %} -lang = 'fortran' -bmilib = 'bmiheatf' +compiler = meson.get_compiler('fortran') {%- endif %} -py = import('python').find_installation(pure: false) - -compiler = meson.get_compiler(lang) - # python_inc = py.get_path('data') / 'include' numpy_inc = run_command( py, @@ -43,26 +38,13 @@ incs = include_directories( ] ) -{% set babelized_class = cookiecutter.components|list|first -%} -# babelized_class = {{ babelized_class }} - {% set dependency_list = cookiecutter.package_requirements.split(',') -%} deps = [ -{%- if cookiecutter.language in ['c', 'c++', 'fortran'] %} - dependency(bmilib, method : 'pkg-config'), -{% endif %} {%- for dependency in dependency_list if dependency != '' %} compiler.find_library('{{ dependency }}'), {%- endfor %} ] -srcs = [ -{%- if cookiecutter.language == 'fortran' %} - '{{ cookiecutter.package_name }}/lib/bmi_interoperability.f90', -{%- endif %} - '{{ cookiecutter.package_name }}/lib/{{ babelized_class|lower }}.pyx', -] - # Files get copied to /site-packages/ install_pkg_srcs = [ '{{ cookiecutter.package_name }}/__init__.py', @@ -73,24 +55,31 @@ py.install_sources( install_pkg_srcs, subdir: '{{ cookiecutter.package_name }}', ) + install_lib_srcs = [ '{{ cookiecutter.package_name }}/lib/__init__.py', +{%- for babelized_class in cookiecutter.components|list|sort %} '{{ cookiecutter.package_name }}/lib/{{ babelized_class|lower }}.pyx', +{%- endfor %} ] py.install_sources( install_lib_srcs, subdir: '{{ cookiecutter.package_name }}/lib', ) -install_subdir( - 'meta/{{ babelized_class }}', - install_dir: py.get_install_dir() / '{{ cookiecutter.package_name }}/data', -) +{%- for babelized_class, component in cookiecutter.components|dictsort %} py.extension_module( '{{ babelized_class|lower }}', - srcs, - dependencies: deps, + [ +{%- if cookiecutter.language == 'fortran' %} + '{{ cookiecutter.package_name }}/lib/bmi_interoperability.f90', +{%- endif %} + '{{ cookiecutter.package_name }}/lib/{{ babelized_class|lower }}.pyx', + ], + dependencies: [ + dependency('{{ component.library }}', method : 'pkg-config'), + ], include_directories: incs, install: true, subdir: '{{ cookiecutter.package_name }}/lib', @@ -99,5 +88,12 @@ py.extension_module( {%- endif %} ) +install_subdir( + 'meta/{{ babelized_class }}', + install_dir: py.get_install_dir() / '{{ cookiecutter.package_name }}/data', +) + +{%- endfor %} + # This is a temporary fix for editable installs. run_command('cp', '-r', '{{ cookiecutter.package_name }}/data', 'build') From 3c3a1aa067e44dafb3551a4d6f1a9f6ed32bff12 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 11 Mar 2024 18:33:04 -0600 Subject: [PATCH 26/36] remove setup.py, setup_utils.py --- .../{{cookiecutter.package_name}}/setup.py | 14 -- .../setup_utils.py | 123 ------------------ 2 files changed, 137 deletions(-) delete mode 100644 babelizer/data/{{cookiecutter.package_name}}/setup.py delete mode 100644 babelizer/data/{{cookiecutter.package_name}}/setup_utils.py diff --git a/babelizer/data/{{cookiecutter.package_name}}/setup.py b/babelizer/data/{{cookiecutter.package_name}}/setup.py deleted file mode 100644 index 76102434..00000000 --- a/babelizer/data/{{cookiecutter.package_name}}/setup.py +++ /dev/null @@ -1,14 +0,0 @@ -from setuptools import setup - -{%- if cookiecutter.language in ['c', 'c++', 'fortran'] %} -from setup_utils import build_ext, get_extension_modules -{% endif %} - -setup( -{%- if cookiecutter.language in ['c', 'c++', 'fortran'] %} - ext_modules=get_extension_modules(), -{%- endif %} -{%- if cookiecutter.language == 'fortran' %} - cmdclass={"build_ext": build_ext}, -{%- endif %} -) diff --git a/babelizer/data/{{cookiecutter.package_name}}/setup_utils.py b/babelizer/data/{{cookiecutter.package_name}}/setup_utils.py deleted file mode 100644 index b2bbca13..00000000 --- a/babelizer/data/{{cookiecutter.package_name}}/setup_utils.py +++ /dev/null @@ -1,123 +0,0 @@ -import contextlib -import os -import subprocess -import sys - -import numpy as np -from numpy.distutils.fcompiler import new_fcompiler -from setuptools import Extension -from setuptools.command.build_ext import build_ext as _build_ext - - -def get_compiler_flags(): - flags = { - "include_dirs": [ - np.get_include(), - os.path.join(sys.prefix, "include"), - {%- for dir in cookiecutter.build.include_dirs %} - "{{ dir|trim }}", - {% endfor %} - ], - "library_dirs": [ - {%- for libdir in cookiecutter.build.library_dirs %} - "{{ libdir|trim }}", - {% endfor %} - ], - "define_macros": [ - {%- if cookiecutter.build.define_macros -%} - {%- for item in cookiecutter.build.define_macros %} - {%- set key_value = item.split('=') %} - ("{{ key_value[0]|trim }}", "{{ key_value[1]|trim }}"),{% endfor %} - {%- endif %} - ], - "undef_macros": [ - {%- if cookiecutter.build.undef_macros -%} - {%- for macro in cookiecutter.build.undef_macros %} - "{{ macro|trim }}",{% endfor %} - {%- endif %} - ], - "extra_compile_args": [ - {%- if cookiecutter.build.extra_compile_args -%} - {%- for arg in cookiecutter.build.extra_compile_args %} - "{{ arg|trim }}",{% endfor %} - {%- endif %} - ], - {%- if cookiecutter.language == 'fortran' %} - "language": "c", - {% else %} - "language": "{{ cookiecutter.language }}", - {% endif -%} - } - - # Locate directories under Windows %LIBRARY_PREFIX%. - if sys.platform.startswith("win"): - flags["include_dirs"].append(os.path.join(sys.prefix, "Library", "include")) - flags["library_dirs"].append(os.path.join(sys.prefix, "Library", "lib")) - - return flags - - -def get_extension_modules(): - flags = get_compiler_flags() - - libraries = [ - {%- if cookiecutter.build.libraries -%} - {%- for lib in cookiecutter.build.libraries %} - "{{ lib|trim }}",{% endfor %} - {%- endif %} - ] - - ext_modules = [ - {%- for babelized_class, component in cookiecutter.components|dictsort %} - Extension( - "{{cookiecutter.package_name}}.lib.{{ babelized_class|lower }}", - ["{{cookiecutter.package_name}}/lib/{{ babelized_class|lower }}.pyx"], - libraries=libraries + ["{{ component.library }}"], - {% if cookiecutter.language == 'fortran' -%} - extra_objects=["{{cookiecutter.package_name}}/lib/bmi_interoperability.o"], - {% endif -%} - **flags, - ), - {%- endfor %} - ] - - return ext_modules - - -@contextlib.contextmanager -def as_cwd(path): - prev_cwd = os.getcwd() - os.chdir(path) - yield - os.chdir(prev_cwd) - - -def build_interoperability(): - compiler = new_fcompiler() - compiler.customize() - - flags = get_compiler_flags() - - cmd = [] - cmd.append(compiler.compiler_f90[0]) - cmd.append(compiler.compile_switch) - if sys.platform.startswith("win") is False: - cmd.append("-fPIC") - for include_dir in flags["include_dirs"]: - if os.path.isabs(include_dir) is False: - include_dir = os.path.join(sys.prefix, "include", include_dir) - cmd.append(f"-I{include_dir}") - cmd.append("bmi_interoperability.f90") - - try: - subprocess.check_call(cmd) - except subprocess.CalledProcessError: - raise - - -class build_ext(_build_ext): - - def run(self): - with as_cwd("{{cookiecutter.package_name}}/lib"): - build_interoperability() - _build_ext.run(self) From 227bbf9f68d012fa432bde1549ad20d2b916eb35 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 11 Mar 2024 18:39:03 -0600 Subject: [PATCH 27/36] bump versions of setup-miniconda, checkout --- .../.github/workflows/test.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/.github/workflows/test.yml b/babelizer/data/{{cookiecutter.package_name}}/.github/workflows/test.yml index f69190dd..35416232 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/.github/workflows/test.yml +++ b/babelizer/data/{{cookiecutter.package_name}}/.github/workflows/test.yml @@ -23,9 +23,9 @@ jobs: python-version: [{{ cookiecutter.ci.python_version | join(", ") }}] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: conda-incubator/setup-miniconda@v2 + - uses: conda-incubator/setup-miniconda@v3 with: auto-update-conda: true python-version: ${{ '{{' }} matrix.python-version {{ '}}' }} @@ -39,16 +39,15 @@ jobs: - name: Install requirements run: | - conda install mamba - mamba install --file=requirements-build.txt --file=requirements-library.txt - mamba list + conda install --file=requirements-build.txt --file=requirements-library.txt + conda list - name: Build and install package run: | pip install -e . - name: Install testing dependencies - run: mamba install --file=requirements-testing.txt + run: conda install --file=requirements-testing.txt - name: Test run: | From 4b66408fcddc7b0a6ead84368312fb5c8e9c48bb Mon Sep 17 00:00:00 2001 From: mcflugen Date: Tue, 12 Mar 2024 09:49:35 -0600 Subject: [PATCH 28/36] remove meson.build for python projects --- babelizer/data/hooks/post_gen_project.py | 4 ++++ noxfile.py | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/babelizer/data/hooks/post_gen_project.py b/babelizer/data/hooks/post_gen_project.py index e6218f5a..27f2fbe6 100644 --- a/babelizer/data/hooks/post_gen_project.py +++ b/babelizer/data/hooks/post_gen_project.py @@ -114,6 +114,10 @@ def write_api_yaml(folderpath, **kwds): if "Not open source" == "{{ cookiecutter.open_source_license }}": remove_file("LICENSE") + {%- if cookiecutter.language == 'python' %} + remove_file("meson.build") + {%- endif %} + datadir = Path("meta") package_datadir = Path("{{ cookiecutter.package_name }}") / "data" if not package_datadir.exists(): diff --git a/noxfile.py b/noxfile.py index 636d52f4..279b842a 100644 --- a/noxfile.py +++ b/noxfile.py @@ -86,7 +86,6 @@ def test_langs(session: nox.session, lang) -> None: session.debug(f"{k}: {v!r}") with session.chdir(package): - session.run("pkg-config", "--list-all") session.run("python", "-m", "pip", "install", ".[dev]") with session.chdir(testdir): From 016c13efac61a1dd790e8a869952d8db72fa407f Mon Sep 17 00:00:00 2001 From: mcflugen Date: Tue, 12 Mar 2024 11:54:27 -0600 Subject: [PATCH 29/36] remove setup.py setup_utils.py from prettification --- babelizer/render.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/babelizer/render.py b/babelizer/render.py index e7d4d1df..5edb0d46 100644 --- a/babelizer/render.py +++ b/babelizer/render.py @@ -168,8 +168,6 @@ def prettify_python(path_to_repo): module_name = meta["package"]["name"] files_to_fix = [ - path_to_repo / "setup.py", - path_to_repo / "setup_utils.py", path_to_repo / module_name / "_bmi.py", path_to_repo / module_name / "__init__.py", path_to_repo / "docs" / "conf.py", From a32086a63a05708175dd8df7f3adb3f2a48cf889 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Wed, 13 Mar 2024 14:10:30 -0600 Subject: [PATCH 30/36] Update bmi-example-fortran to tip of mdpiper/use-pkgconfig branch --- external/bmi-example-fortran | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/bmi-example-fortran b/external/bmi-example-fortran index 6909f22b..613740d1 160000 --- a/external/bmi-example-fortran +++ b/external/bmi-example-fortran @@ -1 +1 @@ -Subproject commit 6909f22b61b0b3fec0d3b0d0bdec7ee58e4ad8a0 +Subproject commit 613740d1fc16a62a380930948f0e5f284a8dca25 From 06d2544fbe6d7368847b26ae1639dcc93e5fb981 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Wed, 13 Mar 2024 14:12:18 -0600 Subject: [PATCH 31/36] Remove hardcoded pkg-config files --- noxfile.py | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/noxfile.py b/noxfile.py index ec044379..2d006c0b 100644 --- a/noxfile.py +++ b/noxfile.py @@ -40,41 +40,6 @@ def test_langs(session: nox.session, lang) -> None: session.install(".[testing]") - bmiheatf_pc = f"""\ -prefix={instdir!s} -exec_prefix=${{prefix}} -libdir=${{exec_prefix}}/lib -includedir=${{prefix}}/include - -Name: bmiheatf -Description: BMI Heat Fortran -Version: 1.0.0 -Requires: heatf -Libs: -L${{libdir}} -lbmiheatf -Cflags: -I${{includedir}} -""" - - os.makedirs(instdir / "lib" / "pkgconfig", exist_ok=True) - with open(instdir / "lib" / "pkgconfig" / "bmiheatf.pc", "w") as fp: - print(bmiheatf_pc, file=fp) - - heatf_pc = f"""\ -prefix={instdir!s} -exec_prefix=${{prefix}} -libdir=${{exec_prefix}}/lib -includedir=${{prefix}}/include - -Name: heatf -Description: Heat Fortran -Version: 1.0.0 -Libs: -L${{libdir}} -lheatf -Cflags: -I${{includedir}} -""" - - os.makedirs(instdir / "lib" / "pkgconfig", exist_ok=True) - with open(instdir / "lib" / "pkgconfig" / "heatf.pc", "w") as fp: - print(heatf_pc, file=fp) - with session.chdir(tmpdir): session.run( "babelize", From 9839e43c37e297d7790cf61b88ead71ebc1303f7 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Wed, 13 Mar 2024 14:26:47 -0600 Subject: [PATCH 32/36] Clean lint --- noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 2d006c0b..e5fc20b9 100644 --- a/noxfile.py +++ b/noxfile.py @@ -36,7 +36,7 @@ def test_langs(session: nox.session, lang) -> None: session.debug(library) session.debug(config_file) - instdir = build_examples(session, lang) + build_examples(session, lang) session.install(".[testing]") From ef40631d3bdba9045a67d046ad72b8f2ef0d9b60 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Wed, 13 Mar 2024 14:52:49 -0600 Subject: [PATCH 33/36] Add a news fragment --- news/90.feature | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 news/90.feature diff --git a/news/90.feature b/news/90.feature new file mode 100644 index 00000000..3798cf28 --- /dev/null +++ b/news/90.feature @@ -0,0 +1,3 @@ + +Use *meson* to build babelized projects with Fortran, C, and C++ sources. +Projects with Python sources are still built with *setuptools*. From e7175350a5fc7f32cecbd7cff1e2abb75a1e75a1 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Wed, 13 Mar 2024 19:22:06 -0600 Subject: [PATCH 34/36] Update bmi-example-fortran to v2.1.3 --- external/bmi-example-fortran | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/bmi-example-fortran b/external/bmi-example-fortran index 613740d1..98b4e339 160000 --- a/external/bmi-example-fortran +++ b/external/bmi-example-fortran @@ -1 +1 @@ -Subproject commit 613740d1fc16a62a380930948f0e5f284a8dca25 +Subproject commit 98b4e3394db6f2b032d8945c125e77435c6d5d03 From 1848402db85f6d96cd733956f04236332f2290bf Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Thu, 14 Mar 2024 10:49:07 -0600 Subject: [PATCH 35/36] Remove Makefile; trim .gitignore --- .../{{cookiecutter.package_name}}/.gitignore | 105 ++---------------- .../{{cookiecutter.package_name}}/Makefile | 94 ---------------- 2 files changed, 8 insertions(+), 191 deletions(-) delete mode 100644 babelizer/data/{{cookiecutter.package_name}}/Makefile diff --git a/babelizer/data/{{cookiecutter.package_name}}/.gitignore b/babelizer/data/{{cookiecutter.package_name}}/.gitignore index 3b80cb7c..35c0374f 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/.gitignore +++ b/babelizer/data/{{cookiecutter.package_name}}/.gitignore @@ -1,114 +1,25 @@ -# Byte-compiled / optimized / DLL files +.DS_Store __pycache__/ *.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ +.ipynb_checkpoints build/ -develop-eggs/ dist/ -downloads/ -eggs/ -.eggs/ -# lib/ -lib64/ -parts/ sdist/ -var/ -wheels/ *.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports htmlcov/ -.tox/ .coverage -.coverage.* -.cache -nosetests.xml coverage.xml -*.cover -.hypothesis/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# dotenv -.env - -# virtualenv +docs/_generated/ .venv -venv/ -ENV/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ - -# nox virtual envs .nox/ +*.so +*.o +*.mod +*.smod -{% if cookiecutter.language == 'fortran' -%} +{%- if cookiecutter.language != 'python' -%} {%- for babelized_class in cookiecutter.components %} -# Fortran files generated by the babelizer -{{cookiecutter.package_name}}/lib/bmi_interoperability.mod -{{cookiecutter.package_name}}/lib/bmi_interoperability.smod -{{cookiecutter.package_name}}/lib/bmi_interoperability.o {{cookiecutter.package_name}}/lib/{{ babelized_class|lower }}.c {%- endfor %} {%- endif %} diff --git a/babelizer/data/{{cookiecutter.package_name}}/Makefile b/babelizer/data/{{cookiecutter.package_name}}/Makefile deleted file mode 100644 index 3b25c3d6..00000000 --- a/babelizer/data/{{cookiecutter.package_name}}/Makefile +++ /dev/null @@ -1,94 +0,0 @@ -.PHONY: clean clean-test clean-pyc clean-build docs help -.DEFAULT_GOAL := help - -define BROWSER_PYSCRIPT -import os, webbrowser, sys - -try: - from urllib import pathname2url -except: - from urllib.request import pathname2url - -webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) -endef -export BROWSER_PYSCRIPT - -define PRINT_HELP_PYSCRIPT -import re, sys - -for line in sys.stdin: - match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) - if match: - target, help = match.groups() - print("%-20s %s" % (target, help)) -endef -export PRINT_HELP_PYSCRIPT - -BROWSER := python -c "$$BROWSER_PYSCRIPT" - -help: - @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) - -clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts - -clean-build: ## remove build artifacts - rm -fr build/ - rm -fr dist/ - rm -fr .eggs/ - find . -name '*.egg-info' -exec rm -fr {} + - find . -name '*.egg' -exec rm -f {} + - -clean-pyc: ## remove Python file artifacts - find . -name '*.pyc' -exec rm -f {} + - find . -name '*.pyo' -exec rm -f {} + - find . -name '*~' -exec rm -f {} + - find . -name '__pycache__' -exec rm -fr {} + - -clean-test: ## remove test and coverage artifacts - rm -fr .tox/ - rm -f .coverage - rm -fr htmlcov/ - rm -fr .pytest_cache - -lint: ## check style with flake8 - flake8 {{ cookiecutter.package_name }} - -pretty: - find {{ cookiecutter.package_name }} -name '*.py' | xargs isort - black setup.py {{ cookiecutter.package_name }} - -test: ## run tests quickly with the default Python -{%- for babelized_class, component in cookiecutter.components|dictsort %} - bmi-test {{ cookiecutter.package_name }}.bmi:{{ babelized_class }} -vvv -{%- endfor %} - -test-all: ## run tests on every Python version with tox - tox - -coverage: ## check code coverage quickly with the default Python - coverage run --source {{ cookiecutter.package_name }} -m pytest - coverage report -m - coverage html - $(BROWSER) htmlcov/index.html - -docs: ## generate Sphinx HTML documentation, including API docs - rm -f docs/{{ cookiecutter.package_name }}.rst - rm -f docs/modules.rst - sphinx-apidoc -o docs/ {{ cookiecutter.package_name }} - $(MAKE) -C docs clean - $(MAKE) -C docs html - $(BROWSER) docs/_build/html/index.html - -servedocs: docs ## compile the docs watching for changes - watchmedo shell-command -p '*.rst' -c '$(MAKE) -C docs html' -R -D . - -release: dist ## package and upload a release - twine upload dist/* - -dist: clean ## builds source and wheel package - python setup.py sdist - python setup.py bdist_wheel - ls -l dist - -install: clean ## install the package to the active Python's site-packages - pip install --no-build-isolation --editable . From 4d7dbb243f139e6742b978cb2d7e3b5eec08ed5d Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Thu, 14 Mar 2024 13:39:57 -0600 Subject: [PATCH 36/36] Include brief instructions for installing from source --- .../{{cookiecutter.package_name}}/README.rst | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/babelizer/data/{{cookiecutter.package_name}}/README.rst b/babelizer/data/{{cookiecutter.package_name}}/README.rst index 39a573a8..05ccf4f9 100644 --- a/babelizer/data/{{cookiecutter.package_name}}/README.rst +++ b/babelizer/data/{{cookiecutter.package_name}}/README.rst @@ -65,20 +65,44 @@ Quickstart .. start-quickstart -To get started you will need to install the *{{ cookiecutter.package_name }}* package, which is currently distributed -on *conda-forge*. The easiest way to install *{{ cookiecutter.package_name }}* into your current environment using either *mamba* or *conda*. +To get started you will need to install the *{{ cookiecutter.package_name }}* package. +Here are two ways to do so. -.. tab:: mamba +Install from conda-forge +------------------------ - .. code:: bash +If the *{{ cookiecutter.package_name }}* package is distributed on *conda-forge*, install it into your current environment with *conda*. - mamba install {{ cookiecutter.package_name }} +.. code:: bash -.. tab:: conda + conda install -c conda-forge {{ cookiecutter.package_name }} - .. code:: bash +Install from source +------------------- + +You can build and install the *{{ cookiecutter.package_name }}* package from source using *conda* and *pip*. + +First, from the source directory, install package dependencies into your current environment with *conda*. + +.. code:: bash + + conda install -c conda-forge --file requirements.txt --file requirements-build.txt --file requirements-library.txt + +Then install the package itself with *pip*. +{%- if cookiecutter.language == 'python' %} - conda install {{ cookiecutter.package_name }} +.. code:: bash + + pip install -e . + +{%- else %} + +.. code:: bash + + pip install --no-build-isolation --editable . + +Note that for an editable install, the ``--no-build-isolation`` flag must be set. +{%- endif %} .. end-quickstart @@ -87,8 +111,8 @@ Usage .. start-usage -There are two ways to use the data components provided by this package: directly through it's Basic -Model Interface, or as a PyMT plugin. +There are two ways to use the components provided by this package: directly through its Basic +Model Interface (BMI), or as a PyMT plugin. A BMI is provided by each component in this package: {%- for babelized_class, component in cookiecutter.components|dictsort -%}