# New package - libconeangle

**URL:** https://fortran-lang.discourse.group/t/new-package-libconeangle/3048
**Category:** Announcements
**Created:** [March 26, 2022, 2:07am UTC](https://fortran-lang.discourse.group/t/new-package-libconeangle/3048 "2022-03-26T02:07:22Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![KjellJorner](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/kjelljorner/32/590_2.png) [@KjellJorner](https://fortran-lang.discourse.group/u/KjellJorner)
#### Post date: [March 26, 2022, 2:07am UTC](https://fortran-lang.discourse.group/t/new-package-libconeangle/3048/1 "2022-03-26T02:07:22Z")

</div>

I’ve written a small Fortran library with a Python interface, [libconeangle](https://github.com/kjelljorner/libconeangle). It’s based on some learnings from this [thread](https://fortran-lang.discourse.group/t/interfacing-fortran-code-from-python/1280) and many others. For me, it’s a first attempt of writing relatively modern Fortran code for easy access via Python (or any other language with a C interface), that is also packaged in an accessible way. Would be curious for feedback both on the Fortran and Python aspects.

The design philosophy is to use an explicit [C API](https://github.com/kjelljorner/libconeangle/blob/main/src/api.f90) to the main subroutine that the library provides, [`cone_angle`](https://github.com/kjelljorner/libconeangle/blob/main/src/main.f90). It is then compiled as a shared library which is loaded with [ctypes](https://docs.python.org/3/library/ctypes.html) from Python. The heavy lifting with respect to passing arrays is handled via [numpy.ctypeslib](https://numpy.org/doc/stable/reference/routines.ctypeslib.html). The Fortran [stdlib](https://github.com/fortran-lang/stdlib) is used in many instances, for example for checking near-equivalence of real numbers. The user of the Python package would be completely agnostic of the Fortran backend as everything is wrapped

```python
>>> from libconeangle import cone_angle
>>> coordinates = np.array([[0.0, 0.0, -0.52], [0.0, 0.0, 1.76], [0.0, 0.0, 2.86]])
>>> radii = np.array([2.1, 1.7, 1.52])
>>> index_metal = 0 # Zero-indexed
>>> c_angle, axis, tangent_atoms = cone_angle(coordinates, radii, index_metal)
>>> c_angle
96.4237340645161
>>> axis
array([0., 0., 1.])
>>> tangent_atoms # Also zero-indexed
[1]

```

The main challenge has been packaging. The average Python user expects to be able to install via either the [pip package installer](https://pip.pypa.io/en/stable/) or conda (usually the [conda-forge](https://conda-forge.org) channel these days) and will not be bothered to compile Fortran code or even installing a Fortran compiler. Packages also need to be available on Windows, MacOS (ARM and Intel) and Linux, and also need to support a number of different Python versions (at least 3.8-3.10). These aspects are particularly relevant for a package like libconeangle which would be used as a dependency in other packages.

In the end I believe that I found a relatively simple system which should require little maintenance (although it was far from simple to get there!). It is based on a combination of CMake and [scikit-build](https://scikit-build.readthedocs.io/en/latest/), where [cibuildwheel](https://cibuildwheel.readthedocs.io/en/stable/) is used to [build](https://github.com/kjelljorner/libconeangle/blob/main/.github/workflows/build_wheels.yml) platform-specific wheels on GitHub Actions that are then uploaded to [PyPI](https://pypi.org/project/libconeangle/). Support for conda-forge is also essentially done but needs approval. Here, the package is built directly for Linux and MacOS, while support for Windows is hampered by the lack of a modern Fortran compiler (GFortran 5.3). For Windows, I therefore resort to installing the wheels from PyPI which seems to work OK.

---

<div class="post-metadata">

### Author: ![nicholaswogan](https://avatars.discourse-cdn.com/v4/letter/n/f1d935/32.png) [@nicholaswogan](https://fortran-lang.discourse.group/u/nicholaswogan)
#### Post date: [March 26, 2022, 7:20am UTC](https://fortran-lang.discourse.group/t/new-package-libconeangle/3048/2 "2022-03-26T07:20:36Z")

</div>

I have also found using CMake with scikit-build is the easiest way to combine Python and Fortran/C/C++.

---

<div class="post-metadata">

### Author: ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)
#### Post date: [March 26, 2022, 1:55pm UTC](https://fortran-lang.discourse.group/t/new-package-libconeangle/3048/3 "2022-03-26T13:55:18Z")

</div>

> [@KjellJorner](#):
>
> support for Windows is hampered by the lack of a modern Fortran compiler (GFortran 5.3)

In my experience, the GitHub Windows CI environment has gfortran 10.3 installed, and it’s possible to get 11.2 installed using msys. Also, I’ve had good luck with the installer provided by [equation.com](http://equation.com).

---

<div class="post-metadata">

### Author: ![KjellJorner](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/kjelljorner/32/590_2.png) [@KjellJorner](https://fortran-lang.discourse.group/u/KjellJorner)
#### Post date: [March 26, 2022, 2:07pm UTC](https://fortran-lang.discourse.group/t/new-package-libconeangle/3048/4 "2022-03-26T14:07:37Z")

</div>

> [@everythingfunctional](#):
>
> In my experience, the GitHub Windows CI environment has gfortran 10.3 installed, and it’s possible to get 11.2 installed using msys. Also, I’ve had good luck with the installer provided by [equation.com](http://equation.com).

Yes, I am building Windows wheels on GitHub Actions. You can get the 11.2 just by running `choco upgrade mingw`. Conda-forge is stuck at 5.3 though.
