Fpm version 0.8.0 released

We just released fpm version 0.8.0, many thanks to everyone who contributed patches.

This release introduces support for enabling and disabling language features in fpm, such as implicit typing or default source form. By default, fpm now tries to disable implicit typing rules, implicit external interfaces and assumes the source form is always free. The options can be overwritten in the manifest for each project.

Furthermore, first support for local and remote registries are integrated in fpm. The registry support can be configured in a new global configuration file. This development was sponsored by the Sovereign Tech Fund.

Bugfixes and improvements to the preprocessor support, C++ compilation, dependency updates and more are included in this release.

Find the full release notes here or on GitHub.

27 Likes

Amazing work to everyone involved!
Very glad to see the registry work reach end users.

2 Likes

Big shout-out to Minh @minhdao, Federico @FedericoPerini, Henil @henilp105, and Arteev @arteevraina for their amazing work on fpm and the registry server! Looking forward to see the first public demo of the registry launching soon.

8 Likes

Adding new keywords to the manifest is a significant issue, as
it currently means any package you release cannot be built with a
previous version of fpm. So for instance, if you add “module-naming”
to your fpm.toml file build directives the package cannot be used as a
dependency by anyone using a pre-0.8.0 fpm version.

$ fpm7 build
<ERROR>*cmd_build*:package error:Key module-naming is not allowed in [build]
STOP 1
  • should fpm be changed so unrecognized names produce a warning instead
    of an error (if possible)?

  • should a preprocessor be supported for fpm.toml files that allows
    simple cpp-like preprocessing so you could have something like

    +[build]
    #if fpm_version > 8 
    +module-naming = true          # Use default naming convention
    #endif
    

    This would be useful for other things like links and modules if the
    preprocessor could detect system configuration information.

  • should multiple fpm.toml files be supported with a rule for naming them that lets
    fpm choose one appropriately? Perhaps fpm_0.7.0.toml would indicate if you are
    using fpm 0.7.0 to use that by default? It could be useful to have a --manifest FILENAME
    switch for other reasons like specifying different executables or libraries or compiler
    options but that gets more complicated with remote dependencies if anything manual
    becomes required.

There have been discussions about allowing for fpm.toml files to require a specific version
or perhaps a version expression such as a range, but perhaps something more general should
be considered?

Otherwise, new features like this will be slow to be adapted as they would break usage by
anyone without the latest fpm(1) version, although so far updating fpm versions is relatively
simple (and could even been automated in some cases).

2 Likes

Thank you @urbanjost, these are all very good points that we’ve also started discussing about. What I’m confident I can say so far is:

I also support this idea but we did not discuss a viable future strategy yet. I think we should consider fpm still “alpha” software, whose user interface (including the manifest) is still subject to change. We try to minimize that, but it’s impossible to introduce quite a lot new features while at the same time avoiding any changes to the input tables.

We are in the process of discussing version constraints, and I’d say the most likely candidate is that we’ll have the option to request a minimum version of fpm in the manifest, something like:

[dependencies]
fpm = ">=0.8.0"

Something like this will not be as flexible as you’re suggesting, but it would mitigate versioning and backward compatibility issues.

To me, this looks like a very good idea, let’s see what the community thinks.

It seems that the default behavior setting in fpm-0.8 has changed, for example, it is using the compiler option “-free” when using ifort. This may not be suitable as a default for old *.f files.

I have not traced down the cause yet; but doing a rebuild of a lot of projects with version 0.8.0 I am seeing remote dependencies being pulled down from the WWW every time there is a build.
Anyone else seeing something similar?

Yes, we have taken a controversial route there, disabling some language features by default, like implicit typing or fixed form. Going forward those will be opt-in features on per project basis, to revert to the previous behavior add the following lines to the manifest

[fortran]
implicit-typing = true
implicit-external = true
source-form = "default"

We think that this way we can make it easier for newcomers to start with Fortran via fpm while still allowing established projects to make a choice on the respective features.

9 Likes

Thank you for the changes in this release of fpm, you can rest assured they are better for the users particularly because it is only the defaults that have changed and you’ve put in the hard work that allows the users to override the changes.

We discussed this point somewhere and I strongly recommend not to do this, otherwise users will just learn to ignore these warnings. Instead, let’s give an error and allow to require a certain fpm version, much like cmake does it. Then projects can decide if they will use a given feature (and require a newer fpm), or not and allow older fpm as well.

1 Like

Ironically, in another thread the intel compiler is being criticized because it also requires compiler options in order to invoke standard compliance. I guess it is just human nature, but why is it so difficult for one person to learn from another’s previous mistake?

The separate discussion in the other thread re: -standard-semantics default with Intel
looks forward and the fpm.changes here too look forward.

So they are all learning to move forward from others’ mistakes, especially by those who insist on latching on to legacy for way too long.

The biggest issue is the use of remote dependencies. Cmake is primarily just a build system and not one a lot of people rave about.

If you create a situation where dependencies require different fpm(1) versions things will degrade
quickly. Ultimately the targets are just code and fpm(1) is not a compiler. fpm(1) can basically only provide the options the compilers have. So fpm(1) should avoid anything that forces a certain behavior in a way that is not compatible with previous versions as a production tool. It is still not release 1.0 so some acception can be made for that; but changes like this will be too disruptive when a change occurs.

So if you use several dependencies you are not in control of that contain fixed-format source and the default is now for all files to be assumed by default to be free-format what will the result be?

2 Likes

Good point. I think this is a separate question about changing defaults (previously I was reacting to just adding features). For changing defaults one robust way to do this is by versioning the fpm.toml format itself. Then a newer version can change defaults without breaking older version. @awvwgk I think we should do that, to give us an option to change defaults in the future without breaking things.

1 Like

For any feature that is implemented as a call to a compiler switch I would prefer it be implemented via profiles; but profiles can be implemented up to a point with keywords that are generic, like “implicit-none” that fpm knows the switches for on various compilers. But at some point we need at least something that says “on this OS type” “with this compiler” “for these files” “add this switch”, with possibly a way for the user to define or use other profiles or named groups. Something like

   profile.myopts = [
   { os="linux", compiler="gfortran",  flag="-implicit-none -free"},
   { os="linux", compiler=["ifx","ifort"],  flag="-implicit-none -free", ,link-flag=" " },
   { os="*", compiler="*", source-dir="*", name="*.f90", profiles=[fast,traceback]}
   ]

   build.options = [
   { source-dir="example/old/", name="*.f90", dependency_profile="myopts"}
   ]

So I could say something like -profile myopts and it could find a match or warn there is not one. Not as flexible as calling lua or if/else/endif preprocessing, but for example
if “dependency_profile” were defined as what to do when used as a remote package, and could be applied on a directory and name basis with regular expressions or globbing, and a profile could be defined via other profiles,
and we had built-in “profiles” that could be as simple as a single switch like profile “optimize” might be “-O3” then you could specify things like “when this is a dependency build it optimized with these external links added to loader calls” and so. So before too many compiler switches
are added as simple names I really think the -profile code should be finished. I lost track so I am not sure where that stands; I thought it was nearly complete a while ago.

Some of these changes really amount to making a generic name for a switch. That is not a bad thing. Neither would be creating a generic compiler command that could call a bunch of compilers that fpm could call, modularizing this type of stuff and being a useful tool itself outside of fpm. But we need some method of applying this to specific filenames with load options that can be aggregated from all the dependencies for external resources like MPI or X11 or we cannot scale unless the project is all self-contained.

Is there something somewhere that describes where profiles sit, especially how they will work with dependent projects?

I also believe this is the best way to mitigate manifest compatibility issues, as said above, we’re working on versioning constraints and one of them will be something like:

[dependencies]
fpm=">=0.8.0"

Which of course will still break compatibility with prior fpm versions that can’t read that syntax, the usual chicken-egg problem, but like said, we will still have to accept some breaking changes in the format until fpm is still alpha

Although when initially introduced a simple pre-processor would also have issues with older versions, but going forward it would be far more flexible.

There was an ongoing discussion about creating a standard Fortran preprocessor. If there is any progress on it, and it resembles cpp/fpp an implementation just implementing if/else/endif would be easy to implement in Fortran that would be sufficient that could grow into a full implementation of the standard preprocessor and so in the long term kill two birds with one stone.

On a more pressing issue. I am getting a huge number of unneeded updates of remote projects.
No one is seeing this?

It looks like in manifest_has_changed() that this comparison
is false when the %git for one has a sha1 description but the other has
a tag in the comparison

        if (.not.(this%git==that%git))return

So I get a fake false return. For example, building fpm(1) itself sometimes
the toml-f descriptions for THIS and THAT are

  # Git target
  # - URL                      https://github.com/toml-f/toml-f
  # - sha1                     54686e45993f3a9a1d05d5c7419f39e7d5a4eb3f
  
  # Git target
  # - URL                      https://github.com/toml-f/toml-f
  # - tag                      v0.4.0

and the comparison returns incorrectly that they are not the same package.

No one else has mentioned this so I thought it was because I was building fpm(1) with ifx(1) so I built with gfortran(1) but am still seeing it. Still digging down so not sure yet why the descriptions are getting generated differently for the same package.

In that case, it’s important to keep track somewhere (in the documentation) of when a feature appeared in fpm. In CMake, they have now made the effort but it was not the case a few years ago and so it was finally difficult to know what version the user really need (as generally you have only one of the latest version on your machine).

Hi all,

I am new here so first of all a big thanks to the developers of fpm. In my work I mainly write programs in Fortran, and fpm has become a real game changer in developing and interfacing different programs and libraries.

Today I tried to compile a code with the new version 0.8.0 of fpm. Unfortunately, I have a dependence that does not compile successfully with the new version. I get the error:

Error: Procedure ‘a0i’ called with an implicit interface at (1) [-Werror=implicit-interface]
f951: some warnings being treated as errors

So my general question is if there was a strategic change in dealing with such warnings (now turned into errors)? Can the -Werror flag be turned off somehow in a way that a code that compiles with version 0.7.0 also compiles with version 0.8.0?

My apologies if this is not the right place to ask. I wasn’t sure if I should post in this thread or open a new one.

This is because fpm-0.8.0 increases the [fortran] feature compared to 0.7.0. For details, you need to add the following content in fpm.toml:

[fortran] 
implicit-external = true 

It is true that fpm has made great progress, but considering that it has not been released to the version of 1.0.0, you can try meson, which is about to be released to 1.1.0, and the support for Fortran is also very good and simple enough :slight_smile: .