Skip to content

Commit 6ef2546

Browse files
authored
Merge pull request #145 from certik/ls
Read the source files automatically
2 parents fe9c2f1 + 2cf6e82 commit 6ef2546

File tree

1 file changed

+88
-10
lines changed

1 file changed

+88
-10
lines changed

fpm/src/fpm.f90

Lines changed: 88 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ module fpm
77
integer, parameter :: OS_MACOS = 2
88
integer, parameter :: OS_WINDOWS = 3
99

10+
type string_t
11+
character(len=:), allocatable :: s
12+
end type
13+
1014
contains
1115

1216
integer function get_os_type() result(r)
@@ -53,6 +57,53 @@ integer function get_os_type() result(r)
5357
end if
5458
end function
5559

60+
integer function number_of_rows(s) result(nrows)
61+
! determine number or rows
62+
integer,intent(in)::s
63+
integer :: ios
64+
character(len=100) :: r
65+
rewind(s)
66+
nrows = 0
67+
do
68+
read(s, *, iostat=ios) r
69+
if (ios /= 0) exit
70+
nrows = nrows + 1
71+
end do
72+
rewind(s)
73+
end function
74+
75+
76+
subroutine list_files(dir, files)
77+
character(len=*), intent(in) :: dir
78+
type(string_t), allocatable, intent(out) :: files(:)
79+
character(len=100) :: filename
80+
integer :: stat, u, i
81+
! Using `inquire` / exists on directories works with gfortran, but not ifort
82+
if (.not. exists(dir)) then
83+
allocate(files(0))
84+
return
85+
end if
86+
select case (get_os_type())
87+
case (OS_LINUX)
88+
call execute_command_line("ls " // dir // " > fpm_ls.out", exitstat=stat)
89+
case (OS_MACOS)
90+
call execute_command_line("ls " // dir // " > fpm_ls.out", exitstat=stat)
91+
case (OS_WINDOWS)
92+
call execute_command_line("dir /b " // dir // " > fpm_ls.out", exitstat=stat)
93+
end select
94+
if (stat /= 0) then
95+
print *, "execute_command_line() failed"
96+
error stop
97+
end if
98+
open(newunit=u, file="fpm_ls.out", status="old")
99+
allocate(files(number_of_rows(u)))
100+
do i = 1, size(files)
101+
read(u, *) filename
102+
files(i)%s = trim(filename)
103+
end do
104+
close(u)
105+
end subroutine
106+
56107
subroutine print_help()
57108
print *, "Fortran Package Manager (fpm)"
58109
select case (get_os_type())
@@ -81,19 +132,46 @@ logical function exists(filename) result(r)
81132
inquire(file=filename, exist=r)
82133
end function
83134

84-
subroutine cmd_build()
85-
logical :: src
86-
print *, "# Building project"
87-
src = exists("src/fpm.f90")
88-
if (src) then
89-
call run("gfortran -c src/fpm.f90 -o fpm.o")
135+
logical function str_ends_with(s, e) result(r)
136+
character(*), intent(in) :: s, e
137+
integer :: n1, n2
138+
n1 = len(s)-len(e)+1
139+
n2 = len(s)
140+
if (n1 < 1) then
141+
r = .false.
142+
else
143+
r = (s(n1:n2) == e)
90144
end if
91-
call run("gfortran -c app/main.f90 -o main.o")
92-
if (src) then
93-
call run("gfortran main.o fpm.o -o fpm")
145+
end function
146+
147+
subroutine package_name(name)
148+
character(:), allocatable, intent(out) :: name
149+
! Currrently a heuristic. We should update this to read the name from fpm.toml
150+
if (exists("src/fpm.f90")) then
151+
name = "fpm"
94152
else
95-
call run("gfortran main.o -o hello_world")
153+
name = "hello_world"
96154
end if
97155
end subroutine
98156

157+
subroutine cmd_build()
158+
type(string_t), allocatable :: files(:)
159+
character(:), allocatable :: basename, pkg_name, linking
160+
integer :: i, n
161+
print *, "# Building project"
162+
call list_files("src", files)
163+
linking = ""
164+
do i = 1, size(files)
165+
if (str_ends_with(files(i)%s, ".f90")) then
166+
n = len(files(i)%s)
167+
basename = files(i)%s(1:n-4)
168+
call run("gfortran -c src/" // basename // ".f90 -o " // basename // ".o")
169+
linking = linking // " " // basename // ".o"
170+
end if
171+
end do
172+
call run("gfortran -c app/main.f90 -o main.o")
173+
call package_name(pkg_name)
174+
call run("gfortran main.o " // linking // " -o " // pkg_name)
175+
end subroutine
176+
99177
end module fpm

0 commit comments

Comments
 (0)