@@ -7,6 +7,10 @@ module fpm
7
7
integer , parameter :: OS_MACOS = 2
8
8
integer , parameter :: OS_WINDOWS = 3
9
9
10
+ type string_t
11
+ character (len= :), allocatable :: s
12
+ end type
13
+
10
14
contains
11
15
12
16
integer function get_os_type () result(r)
@@ -53,6 +57,53 @@ integer function get_os_type() result(r)
53
57
end if
54
58
end function
55
59
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
+
56
107
subroutine print_help ()
57
108
print * , " Fortran Package Manager (fpm)"
58
109
select case (get_os_type())
@@ -81,19 +132,46 @@ logical function exists(filename) result(r)
81
132
inquire (file= filename, exist= r)
82
133
end function
83
134
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)
90
144
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"
94
152
else
95
- call run( " gfortran main.o -o hello_world" )
153
+ name = " hello_world"
96
154
end if
97
155
end subroutine
98
156
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
+
99
177
end module fpm
0 commit comments