aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fpm/src/fpm_command_line.f9049
-rw-r--r--fpm/src/fpm_environment.f90152
-rw-r--r--fpm/src/fpm_filesystem.f9088
3 files changed, 176 insertions, 113 deletions
diff --git a/fpm/src/fpm_command_line.f90 b/fpm/src/fpm_command_line.f90
index 5e9daee..406b58e 100644
--- a/fpm/src/fpm_command_line.f90
+++ b/fpm/src/fpm_command_line.f90
@@ -1,8 +1,9 @@
module fpm_command_line
- use fpm_environment, only: get_os_type, OS_LINUX, OS_MACOS, OS_WINDOWS
-
+ use fpm_environment, only: get_os_type, &
+ OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_WINDOWS, &
+ OS_CYGWIN, OS_SOLARIS, OS_FREEBSD
implicit none
-
+
private
public :: fpm_cmd_settings, &
fpm_build_settings, &
@@ -10,7 +11,7 @@ module fpm_command_line
fpm_new_settings, &
fpm_run_settings, &
fpm_test_settings, &
- get_command_line_settings
+ get_command_line_settings
type, abstract :: fpm_cmd_settings
end type
@@ -62,24 +63,40 @@ contains
end subroutine
subroutine print_help()
- print *, "fpm - A Fortran package manager and build system"
+ print *, 'fpm - A Fortran package manager and build system'
+
select case (get_os_type())
+ case (OS_UNKNOWN)
+ print *, 'OS Type: Unknown'
+
case (OS_LINUX)
- print *, "OS Type: Linux"
+ print *, 'OS Type: Linux'
+
case (OS_MACOS)
- print *, "OS Type: macOS"
+ print *, 'OS Type: macOS'
+
case (OS_WINDOWS)
- print *, "OS Type: Windows"
+ print *, 'OS Type: Windows'
+
+ case (OS_CYGWIN)
+ print *, 'OS Type: Cygwin'
+
+ case (OS_SOLARIS)
+ print *, 'OS Type: Solaris'
+
+ case (OS_FREEBSD)
+ print *, 'OS Type: FreeBSD'
end select
+
print *
- print *, "Usage:"
- print *, " fpm [COMMAND]"
+ print *, 'Usage:'
+ print *, ' fpm [COMMAND]'
print *
- print *, "Valid fpm commands are:"
- print *, " build Compile the current package"
- print *, " install Install a Fortran binary or library (not implemented)"
- print *, " new Create a new Fortran package (not implemented)"
- print *, " run Run a binary of the local package (not implemented)"
- print *, " test Run the tests (not implemented)"
+ print *, 'Valid fpm commands are:'
+ print *, ' build Compile the current package'
+ print *, ' install Install a Fortran binary or library (not implemented)'
+ print *, ' new Create a new Fortran package (not implemented)'
+ print *, ' run Run a binary of the local package (not implemented)'
+ print *, ' test Run the tests (not implemented)'
end subroutine
end module fpm_command_line
diff --git a/fpm/src/fpm_environment.f90 b/fpm/src/fpm_environment.f90
index 9ac42ac..553aa8b 100644
--- a/fpm/src/fpm_environment.f90
+++ b/fpm/src/fpm_environment.f90
@@ -1,67 +1,117 @@
module fpm_environment
implicit none
private
- public :: get_os_type, run
- public :: OS_LINUX, OS_MACOS, OS_WINDOWS
-
- integer, parameter :: OS_LINUX = 1
- integer, parameter :: OS_MACOS = 2
- integer, parameter :: OS_WINDOWS = 3
+ public :: get_os_type
+ public :: run
+ 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
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
+ !! 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 existence 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
subroutine run(cmd)
character(len=*), intent(in) :: cmd
integer :: stat
- print *, "+ ", cmd
+ print *, '+ ', cmd
call execute_command_line(cmd, exitstat=stat)
if (stat /= 0) then
- print *, "Command failed"
+ print *, 'Command failed'
error stop
end if
end subroutine run
-
end module fpm_environment
diff --git a/fpm/src/fpm_filesystem.f90 b/fpm/src/fpm_filesystem.f90
index d5c8e67..985cde8 100644
--- a/fpm/src/fpm_filesystem.f90
+++ b/fpm/src/fpm_filesystem.f90
@@ -1,13 +1,14 @@
module fpm_filesystem
-use fpm_environment, only: get_os_type, OS_LINUX, OS_MACOS, OS_WINDOWS
-use fpm_strings, only: f_string, string_t, split
-implicit none
+ use fpm_environment, only: get_os_type, &
+ OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_WINDOWS, &
+ OS_CYGWIN, OS_SOLARIS, OS_FREEBSD
+ use fpm_strings, only: f_string, string_t, split
+ implicit none
+ private
+ public :: basename, join_path, number_of_rows, read_lines, list_files, &
+ mkdir, exists, get_temp_filename, windows_path
-private
-public :: basename, join_path, number_of_rows, read_lines, list_files,&
- mkdir, exists, get_temp_filename, windows_path
-
-integer, parameter :: LINE_BUFFER_LEN = 1000
+ integer, parameter :: LINE_BUFFER_LEN = 1000
contains
@@ -34,25 +35,24 @@ function basename(path,suffix) result (base)
else
call split(path,file_parts,delimiters='\/.')
base = trim(file_parts(size(file_parts)-1))
- end if
+ end if
end function basename
function join_path(a1,a2,a3,a4,a5) result(path)
- ! Construct path by joining strings with os file separator
+ ! Construct path by joining strings with os file separator
!
- character(*), intent(in) :: a1, a2
- character(*), intent(in), optional :: a3,a4,a5
- character(:), allocatable :: path
-
- character(1) :: filesep
+ character(len=*), intent(in) :: a1, a2
+ character(len=*), intent(in), optional :: a3, a4, a5
+ character(len=:), allocatable :: path
+ character(len=1) :: filesep
select case (get_os_type())
- case (OS_LINUX,OS_MACOS)
- filesep = '/'
- case (OS_WINDOWS)
- filesep = '\'
+ case (OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_CYGWIN, OS_SOLARIS, OS_FREEBSD)
+ filesep = '/'
+ case (OS_WINDOWS)
+ filesep = '\'
end select
path = a1 // filesep // a2
@@ -110,61 +110,57 @@ function read_lines(fh) result(lines)
end function read_lines
subroutine mkdir(dir)
- character(*), intent(in) :: dir
-
- integer :: stat
+ character(len=*), intent(in) :: dir
+ integer :: stat
select case (get_os_type())
- case (OS_LINUX,OS_MACOS)
- call execute_command_line("mkdir -p " // dir , exitstat=stat)
- write(*,*) "mkdir -p " // dir
- case (OS_WINDOWS)
- call execute_command_line("mkdir " // windows_path(dir), exitstat=stat)
- write(*,*) "mkdir " // windows_path(dir)
+ case (OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_CYGWIN, OS_SOLARIS, OS_FREEBSD)
+ call execute_command_line('mkdir -p ' // dir, exitstat=stat)
+ write (*, '(2a)') 'mkdir -p ' // dir
+
+ case (OS_WINDOWS)
+ call execute_command_line("mkdir " // windows_path(dir), exitstat=stat)
+ write (*, '(2a)') 'mkdir ' // windows_path(dir)
end select
+
if (stat /= 0) then
- print *, "execute_command_line() failed"
+ print *, 'execute_command_line() failed'
error stop
end if
-
end subroutine mkdir
subroutine list_files(dir, files)
- character(len=*), intent(in) :: dir
+ character(len=*), intent(in) :: dir
type(string_t), allocatable, intent(out) :: files(:)
-
- integer :: stat, fh
- character(:), allocatable :: temp_file
+ character(len=:), allocatable :: temp_file
+ integer :: stat, fh
! Using `inquire` / exists on directories works with gfortran, but not ifort
if (.not. exists(dir)) then
- allocate(files(0))
+ allocate (files(0))
return
end if
- allocate(temp_file, source = get_temp_filename() )
+ allocate (temp_file, source=get_temp_filename())
select case (get_os_type())
- case (OS_LINUX)
- call execute_command_line("ls " // dir // " > "//temp_file, &
- exitstat=stat)
- case (OS_MACOS)
- call execute_command_line("ls " // dir // " > "//temp_file, &
+ case (OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_CYGWIN, OS_SOLARIS, OS_FREEBSD)
+ call execute_command_line('ls ' // dir // ' > ' // temp_file, &
exitstat=stat)
case (OS_WINDOWS)
- call execute_command_line("dir /b " // windows_path(dir) // " > "//temp_file, &
+ call execute_command_line('dir /b ' // windows_path(dir) // ' > ' // temp_file, &
exitstat=stat)
end select
+
if (stat /= 0) then
- print *, "execute_command_line() failed"
+ print *, 'execute_command_line() failed'
error stop
end if
- open(newunit=fh, file=temp_file, status="old")
+ open (newunit=fh, file=temp_file, status='old')
files = read_lines(fh)
- close(fh,status="delete")
-
+ close (fh, status='delete')
end subroutine list_files