diff options
-rw-r--r-- | fpm/src/environment.f90 | 142 |
1 files changed, 97 insertions, 45 deletions
diff --git a/fpm/src/environment.f90 b/fpm/src/environment.f90 index 9190eb6..ec5230c 100644 --- a/fpm/src/environment.f90 +++ b/fpm/src/environment.f90 @@ -2,53 +2,105 @@ module environment implicit none private - integer, parameter, public :: OS_LINUX = 1 - integer, parameter, public :: OS_MACOS = 2 + integer, parameter, public :: OS_UNKNOWN = 0 + integer, parameter, public :: OS_LINUX = 1 + integer, parameter, public :: OS_MACOS = 2 integer, parameter, public :: OS_WINDOWS = 3 + integer, parameter, public :: OS_CYGWIN = 4 + integer, parameter, public :: OS_SOLARIS = 5 + integer, parameter, public :: OS_FREEBSD = 6 public :: get_os_type contains integer function get_os_type() result(r) - ! Determine the OS type - ! - ! Returns one of OS_LINUX, OS_MACOS, OS_WINDOWS. - ! - ! Currently we use the $HOME and $HOMEPATH environment variables to determine - ! the OS type. That is not 100% accurate in all cases, but it seems to be good - ! enough for now. See the following issue for a more robust solution: - ! - ! https://github.com/fortran-lang/fpm/issues/144 - ! - character(len=100) :: val - integer stat - ! Only Windows define $HOMEPATH by default and we test its value to improve the - ! chances of it working even if a user defines $HOMEPATH on Linux or macOS. - call get_environment_variable("HOMEPATH", val, status=stat) - if (stat == 0 .and. val(1:7) == "\Users\") then - r = OS_WINDOWS - return - end if - - ! We assume that $HOME=/home/... is Linux, $HOME=/Users/... is macOS, otherwise - ! we assume Linux. This is only a heuristic and can easily fail. - call get_environment_variable("HOME", val, status=stat) - if (stat == 1) then - print *, "$HOME does not exist" - error stop - end if - if (stat /= 0) then - print *, "get_environment_variable() failed" - error stop - end if - if (val(1:6) == "/home/") then - r = OS_LINUX - else if (val(1:7) == "/Users/") then - r = OS_MACOS - else - ! This will happen on HPC systems that typically do not use either /home nor - ! /Users for $HOME. Those systems are typically Linux, so for now we simply - ! set Linux here. - r = OS_LINUX - end if - end function -end module + !! Determine the OS type + !! + !! Returns one of OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_WINDOWS, OS_CYGWIN, + !! OS_SOLARIS, OS_FREEBSD. + !! + !! At first, the environment variable `OS` is checked, which is usually + !! found on Windows. Then, `OSTYPE` is read in and compared with common + !! names. If this fails too, check the existance of files that can be + !! found on specific system types only. + !! + !! Returns OS_UNKNOWN if the operating system cannot be determined. + character(len=32) :: val + integer :: length, rc + logical :: file_exists + + r = OS_UNKNOWN + + ! Check environment variable `OS`. + call get_environment_variable('OS', val, length, rc) + + if (rc == 0 .and. length > 0 .and. index(val, 'Windows_NT') > 0) then + r = OS_WINDOWS + return + end if + + ! Check environment variable `OSTYPE`. + call get_environment_variable('OSTYPE', val, length, rc) + + if (rc == 0 .and. length > 0) then + ! Linux + if (index(val, 'linux') > 0) then + r = OS_LINUX + return + end if + + ! macOS + if (index(val, 'darwin') > 0) then + r = OS_MACOS + return + end if + + ! Windows, MSYS, MinGW, Git Bash + if (index(val, 'win') > 0 .or. index(val, 'msys') > 0) then + r = OS_WINDOWS + return + end if + + ! Cygwin + if (index(val, 'cygwin') > 0) then + r = OS_CYGWIN + return + end if + + ! Solaris, OpenIndiana, ... + if (index(val, 'SunOS') > 0 .or. index(val, 'solaris') > 0) then + r = OS_SOLARIS + return + end if + + ! FreeBSD + if (index(val, 'FreeBSD') > 0 .or. index(val, 'freebsd') > 0) then + r = OS_FREEBSD + return + end if + end if + + ! Linux + inquire (file='/etc/os-release', exist=file_exists) + + if (file_exists) then + r = OS_LINUX + return + end if + + ! macOS + inquire (file='/usr/bin/sw_vers', exist=file_exists) + + if (file_exists) then + r = OS_MACOS + return + end if + + ! FreeBSD + inquire (file='/bin/freebsd-version', exist=file_exists) + + if (file_exists) then + r = OS_FREEBSD + return + end if + end function get_os_type +end module environment |