Congratulations! Iām especially excited about the Intel LLVM and MPI support.
When can I expect fpm 0.12 on pypi? It seems āstuckā on 0.10.
Congratulations! Iām especially excited about the Intel LLVM and MPI support.
When can I expect fpm 0.12 on pypi? It seems āstuckā on 0.10.
@FedericoPerini
I have got a little question about fpm code. In the repository, there are a few C files with a few functions like c_opendir() to manage the OS filesystem. But we know that fpm can also be downloaded and compiled as a standalone .F90 file. I see that the Fortran/C interfaces are declared in a #ifndef FPM_BOOTSTRAP structure. Can you explain when those C functions are necessary? (if I compile the .F90, it seems to run without problem)
Originally fpm was all Fortran and external system command calls to support running on non-POSIX environments.
All the non-standard system interface calls were done by executing shell commands and writing the output to a file and then reading that file. This kept fpm very portable.
Later the ISO_C_BINDING/C interface was introduced but so far the original interface design has been maintained primarily just for the purpose of still being able to generate a single-file bootstrap version.
If you look at the conditional code, you will see it is usually a function implemented with EXECUTE_COMMAND_LINE and an OS-specific command used with a file as above, and then a POSIX version, and then sometimes a MSWindows call all doing the same thing for the most part. There was a lot of functionality that required using a compiler extension or a C binding or a system command that was not in the earliest versions to keep it portable. Then there was a desire to keep it that way so a standalone file was possible.
With less and less non-POSIX environments there is probably a growing desire to add C functionality directly.
It was an early assumption that stdlib would have evolved to the point it would supply a portable interface and be used as a dependency largely for the purpose of providing portable system interface.. That is happening; but will add a large infra-structure requirement to building fpm.
So at least for the time-being you can still build fpm wth a single file, but at some point that might not be true.
Some of the non-Fortran functionality that is not a core function can be in essentially arbitrary languages and presented as a plug-in as well.
If it had been clear almost all fpm builds would be with gfortran all the current functionality (well, did not check; but at least most of it) could just be done with gfortran extensions that are already available on all gfortran-supported environments.
So there are some alternatives that can keep the single-file build viable.
But it might not be tomorrow, but at some point the bootstrap version may be just one of the versions you see now which will be frozen, but still useful; and fpm will likely need additional infrastructure to install with all functionality.
I personally often use the single-file version. I am not sure how many others do.
But your ālittle questionā actually hits on an aspect of fpm that was (and is) a major design decision. The first fpm(1) prototype was not in Fortran, by the way. Maybe what is was could be the beginning of a fpm(1) trivia quiz ![]()
Thanks @urbanjost for the excellent reply, there is really not that much to add! Yes as said the C code cannot be part of the single file repository.
Most of those functions are just wrappers over system functions, so they could in theory just be interfaced on the Fortran side, but the main obstacle to that is unreliable preprocessor flags (gfortran does not export _WIN32).
So a Fortran-only solution would come at the cost of nontrivial build scripts; FPM_BOOTSTRAP is a good tradeoff, but of course if anyone has better ideas letās discuss and see how we could improve this!
After you guess, check the answer.
Thanks for that great/long answer to my ālittle questionā.
I have a short script to upgrade fpm. Initially, after cloning, it was launching the install.sh script. And at some point I replaced it by a fpm install, upgrading to the new fpm with the previous version.
Reading the install.sh script, I can indeed see that the reference version is 0.8.0 which is downloaded as a single .F90 file. Then it is built, and launched to build the latest version (already cloned).
On the front side fpm is easy for the user, on the back side you need some hidden complexity.
Most if not all compilers have proprietrary extensions for most file system operations; but MSWindows needs custom interfaces, whereas many other platforms provide POSIX-like C functionality in the C companion compilers. Perhaps to take advantage of the extensions a common interface could be defined ala stdlib with a version for each compiler that calls their extensions. Then there could also be versions that call the C companion compilers and perhaps one that reads and writes output from system commands.
That leverages the work already done and supported by the compilers, creates a new standard reminiscent of the PXF interface attempt that vendors could start supporting directly, and allows otherwise pure Fortran programs to not require anything else accept their Fortran compiler, but in a far more portable manner.
So take getting a list of files from the current directory. Define a wrapper interface that becomes the target interface to provide. If the vendor provides the functionality already make it call that from a library just for that compiler. If not, call a shell command and write to a file and read it.
Then as an alternative C/POSIX and C/MSW interfaces providing the same functionality can be provided. But no matter what the underlying method the interface is defined and for many common functions it can be done quickly with the wrapper around the vendor functionality. Gradually perhaps the stdlib interface would then become supplied by vendors or become an optional component of the Fortran standard.
Not done with the file structure just proposed, but lets look at determining if a file is a tty or not.
The first three vendors looked at all provide the functionality, but each slightly differently. stdlib could provide the system_isatty or maybe stdlib_isatty procedure in a manner that on most platforms would be directly supplied by the existing vendor-supported routines and only use the other potentially less portable manners when the vendor had no extension (yet). The model could then be provided directly, perhaps prototyping it via LFortran, which seems to most supportive of providing prototyping currently.
module M_vendor
private
public system_isatty
contains
!> call compiler-specific ISATTY() function or return .FALSE.
#undef ISATTY
#ifdef __INTEL_COMPILER
function system_isatty(lun)
use IFPORT
integer,intent(in) :: lun
logical :: system_isatty
system_isatty=isatty(lun)
end function system_isatty
#define ISATTY
#endif
#ifdef __NVCOMPILER_MAJOR__X
! __NVCOMPILER_MAJOR__ __NVCOMPILER_MINOR__ __NVCOMPILER_PATCHLEVEL__
function system_isatty(lun)
use DFPORT
integer,intent(in) :: lun
logical :: system_isatty
system_isatty=isatty(lun)
end function system_isatty
#define ISATTY
#endif
#ifdef __GFORTRAN__
function system_isatty(lun)
integer,intent(in) :: lun
logical :: system_isatty
system_isatty=isatty(lun)
end function system_isatty
#define ISATTY
#endif
#ifndef ISATTY
function system_isatty(lun)
integer,intent(in) :: lun
logical :: system_isatty
system_isatty=.false.
end function system_isatty
#define ISATTY
#endif
end module M_vendor
Is there a way to compile both static and shared library of a project at once?
Something like:
[library]
type = ["static", "shared"]
I posted an enhancement request for this as an issue on the fpm github site about 5 days ago. I think (at least on Linux) fpmās default compile options include -fPIC (but I could be wrong). It should be fairly easy to just add a $(FC) -shared line after building the static library.
I agree itās a good idea to have the option for simultaneous static and shared build - thank you for opening an issue!
Thank you for your work on fpm. Itās come a long way since I first tried it a couple years ago (and had issues with it not correctly resolving module dependencies spread out over 10 or so sub-directories in /src). Tried it again on the same code last week and it worked great. Iām starting to add fpm to all my projects (but will still keep my hand stitched make files that Iāve used for 20 plus years as a backup).
I strongly recommend keeping the single option to bootstrap fpm. If a C file is needed, we can ship it with the single file. There might be a way to do everything from Fortran, for example by having a platform-specific single file.
I have just found (apparently having missed that earlier) FPM in Homebrew, both for MacOS and Linux. Maybe it would be worth mentioning that on the main GitHub page? Or, at least, reminding that availability in every new version announcement on fortran-lang discourse.
I believe this Homebrew package builds and installs
the latest bootstrap version.
Iām not sure what do you mean by ābuilds and installsā but the Homebrew for Linux version (0.12.0) is bottled which AFAIK means that it is a binary, prebuilt package. It also installs in seconds so I doubt it does any actual build.
Playing with fpm (as an absolute novice) I have found a possible error in the Tutorial. After a successful installation of fpm-search I tried to use the hint:
> fpm search --toml M_CLI2
M_CLI2 = { git = "https://github.com/urbanjost/M_CLI2" }
but it failed with UNKNOWN LONG KEYWORD: --toml
It seems one can get the toml dependency line (among plenty of other information) by using
--verbose option instead.
To be completely honest, Iām not familiar with homebrew, so take this with a grain of salt. If I didnāt look into the wrong place, it seems the recipe for ābrewingā the package only mentions the bootstrap source file. I donāt know whether it is prebuilt or locally built. Either way, it probably doesnāt install the complete version. However, the difference should be little.
If it is the GitHub fpm Page where you looked, it is pretty outdated when referring to the Homebrew. It does not require adding any extra tap to install fpm anymore and it is available as a binary bottle for both MacOS and Linux Homebrew
A full build of stdlib (git clone ā¦; fpm build) takes over an hour on my desktop. A ādependenceā build accompanying fpm build of a simple example taken from fpm/example_packages takes just a few seconds, so I guess it is only relevant modules in relevant kind versions being built. Thatās brilliant, kudos ![]()
I wonder whether this is a general ability of fpm or a specific feature of those āmetapackagesā (stdlib, blas etc.) supported by fpm 0.12.0
Thatās correct - and itās not limited to metapackage but rather standard fpm behavior:
This can be controlled by
[library]
type = "shared"
type = "static"
type = "monolithic"
in the fpm.toml manifest.