Easiest to build on Windows?

As a followup from this, in the short term what I need is to build a statically-linked binary of the latest version of my package. In linux it is just about installing gfortran and cmake, and doing make.

I have just spent one hour trying to install some fortran compiler on Windows, without success. I have no real experience with doing anything on Windows, so probably this is just my lack of knowledge.

I tried to install gfortran, but I got to a “mingw” page which appeared deprecated. I tried than LFortran, but after installing miniconda I don’t know what to do (“conda” is not a program apparently available anywhere - and during installation the possibility of adding it to the path was highly discouraged).

I have done this before, and I remember having saved a windows installation only for that, for how complicated it was when I tried, but that machine is long gone now.

(also, if for someone building that package in a way is trivial, I won’t refuse that help. What I need is a binary that has the libraries statically linked so the user can just download the executable).

3 Likes

For a simple way to install gfortran on Windows see:

2 Likes

I can recommend MSYS2, it gives you a bash shell with a Cygwin-like runtime as base and (several) MinGW native toolchains on top, which allows linking static binaries for distribution outside of MSYS2. From my experience this is the closest Unix experience one can get on Windows, while still being able to create native binaries. However, it might appear a bit complex due to the different available environments on the first glance.

After installation there will be several terminals available (msys2, mingw64, mingw32, ucrt64, clang64, clang32). The msys2 terminal is a pure Cywgin-like environment, software from this environment is available in all environments. mingw64, mingw32 and ucrt64 are based on GCC/MinGW, here you get gfortran as Fortran compiler. In clang64 and clang32 you can instead rely on flang as Fortran compiler.

The good thing is you have an actual package manager, pacman, available to install packages, the toolchain group should be sufficient for most development:

pacman -S base-devel mingw-w64-<arch>-toolchain

Where <arch> is one of i686 (mingw32), x86_64 (mingw64), ucrt-x86_64 (ucrt64), clang-i686 (clang32), or clang-x86_64 (clang64).

3 Likes

I built the application on Windows 11 using Gfortran 12 (equation.com’s distribution for Windows) using your makefile. The makefile caused a couple of hiccups, but the resulting exe ran fine on a couple of your examples.

I then compiled the program using Intel Fortran 2021.5.0, using the command

make FORTRAN=ifort FLAGS=/Ot

followed by

ifort *.obj /Fepakmol

This also produced an EXE that ran successfully on a couple of examples.

The build process is relatively simple, but the module dependencies require that the source files be compiled in proper order.

For a person used to building Fortran programs using Cmake or makefiles on Windows, and with the Cygwin or MinGW binutils, the process is simple and is completed in a few minutes.

2 Likes

On Windows, if you need as comprehensive a Linux tool experience as possible, and the latest packages (its gfortran will always keep the latest version), MSYS2 is very good, which I have been using.

GCC WIKI, here are some more comprehensive links for Windows: GFortranBinaries - GCC Wiki (gnu.org)

4 Likes

The easiest way is to use Simply Fortran environment. It is not free, but extremely useful on Windows. You can try if for 30 days.

1 Like

There are many answers already, but in case you wish to convert PACKMOL to the fpm build system, here’s a quick guide.

:: Make sure the required paraphernalia is in PATH
set path=C:\path\to\gfortran;C:\path\to\git;C:\path\to\fpm;

:: Create fpm project
fpm new packmol --app --src

:: Delete autogenerated files
del packmol\app\main.f90
del packmol\src\packmol.f90

:: Copy *.f *.f90 from https://github.com/m3g/packmol to packmol\src directory
:: Delete unused? file
del packmol\src\data_types.f90

:: Move main program from `src` to `app`
move packmol\src\packmol.f90 packmol\app\packmol.f90

:: Replace contents of `packmol\fpm.toml` with
--
name        = "packmol"
description = "PACKMOL: A package for building initial configurations for molecular dynamics simulations. Journal of Computational Chemistry, 30:2157-2164,2009."
version     = "0.1.0"
license     = "MIT"
author      = ["L. Martinez", "R. Andrade", "E. G. Birgin", "J. M. Martinez"]
copyright   = "Copyright 2021, Names"

[[executable]]
name="packmol"
source-dir="app"
main="packmol.f90"
--

:: Build
cd packmol
fpm build --flag "-O3 --fast-math" --link-flag --static

:: Build using intel OneAPI (assuming Intel compilers in PATH)
cd packmol
fpm build --compiler ifort
fpm build --compiler ifx

:: You'll find packmol.exe inside `packmol\build` subdirectory
3 Likes

I managed to document creating Windows executables on Linux by cross-compiling. My experience is detailed here. If you need access to Windows DLLs it becomes more complicated, but if you stick to straight Fortran, it is nice to have one shell script that compiles both executables. Now if I could only cross-compile to OSX.

2 Likes

I have some comments about PackMol that are peripheral to @lmiq’s inquiry.

The program reads problem data from the standard input stream, using Unit 5. This, by itself, is fine, but the program attempts to read the input twice, with a REWIND(5) in between. Depending on the operating system and the Fortran compiler being used, this may fail if the standard input is obtained by redirection from a file.

In various places, there are WRITE statements in which the output list contains references to the character function i5hex. However, the function i5hex itself contains WRITE statements to an internal file, and such recursive I/O statements may not work or may not work correctly.

1 Like

It doesn’t write to a file, but to the variable (character stream) that it returns. (Maybe this is what you mean by “file” there). Os there a better way to do that?

The function is this one:

function i5hex(i)
  implicit none
  integer :: i
  character(len=5) i5hex
  if(i <= 99999) then
    write(i5hex,"(i5)") i
  else
    write(i5hex,"(z5)") i
  end if
end

I just want to fill the 5-char variable with the formatted integer output of the input number. Is there another way to assign a formatted output to a string?

(If the number is greater than 99999 write the number in hexadecimal format)

If I was to read it once I would need at least to know the number of lines, to preallocate a vector of strings with proper size. Is there any way to do that? Or a push? At the same time that has not been an issue in the many years Packmol is out there.

A. Internal Files:

The Fortran standard has a section on Internal Files. In Fortran 2018, for example, the section is 12.4. Recursive I/O can be avoided by using a temporary character variable which is set to the function value, and placing that temporary character variable in the I/O list. For example, instead of

 write(30,pdb_atom_line) 'ATOM  ',i5hex(i_ref_atom)

we code

i5hx = i5hex(i_ref_atom)
write(30,pdb_atom_line) 'ATOM  ',i5hx

where i5hx is declared character(len=5).

B. Rewinding unit 5.

As previously stated, what happens when a REWIND(5) statement is executed is compiler and O/S dependent. Here is a test program that illuminates the issue.

program readlines
implicit none
character (len=6) line
integer i,n
do n=1,2
   do i=1,5
      read(5,*)line
      print *,line
   end do
   rewind(5)
end do
end program

With this program, compiled to rlin.exe, using Gfortran on Windows, and the input file lines.txt containing

line-1
line-2
line-3
line-4
line-5
line-6
line-7
line-8
line-9
line-A

the command

cat lines.txt | rlin.exe

produces the output

 line-1
 line-2
 line-3
 line-4
 line-5
At line 9 of file rlin.f90 (unit = 5, file = 'stdin')
Fortran runtime error: Illegal seek

Error termination. Backtrace:
#0  0x3f717569a in ???
#1  0x3f7103cd4 in ???
#2  0x3f70314bb in ???
#3  0x100401189 in readlines
        at /cygdrive/t/LANG/rlin.f90:9
#4  0x10040129d in main
        at /cygdrive/t/LANG/rlin.f90:14

Another way of thinking about this issue is to note that input from a CRT terminal, a keyboard or an input card deck cannot be rewound.

1 Like

Thank for the tip. With MSYS2 I could compile it.