@@ -22,11 +22,9 @@ module fpm_backend
22
22
subroutine build_package (model )
23
23
type (fpm_model_t), intent (inout ) :: model
24
24
25
- integer :: i, ilib
26
- character (:), allocatable :: base, linking, subdir, link_flags
25
+ integer :: i, j
27
26
type (build_target_ptr), allocatable :: queue(:)
28
-
29
- allocate (queue(0 ))
27
+ integer , allocatable :: region_ptr(:)
30
28
31
29
if (.not. exists(model% output_directory)) then
32
30
call mkdir(model% output_directory)
@@ -35,45 +33,47 @@ subroutine build_package(model)
35
33
call mkdir(join_path(model% output_directory,model% package_name))
36
34
end if
37
35
38
- if (model% targets(1 )% ptr% target_type == FPM_TARGET_ARCHIVE) then
39
- linking = " " // model% targets(1 )% ptr% output_file
40
- else
41
- linking = " "
42
- end if
43
-
44
- linking = linking// " " // model% link_flags
45
-
46
36
do i= 1 ,size (model% targets)
47
37
48
- call schedule_target(queue, model% targets(i)% ptr)
38
+ call schedule_target(model% targets(i)% ptr)
49
39
50
40
end do
51
41
52
- do i = 1 , size (queue)
42
+ call get_build_queue (queue, region_ptr, model % targets )
53
43
54
- call build_target(model,queue(i)% ptr,linking)
44
+ do i= 1 ,size (region_ptr)- 1
45
+
46
+ ! $OMP PARALLEL DO DEFAULT(SHARED)
47
+ do j= region_ptr(i),(region_ptr(i+1 )- 1 )
48
+
49
+ call build_target(model,queue(j)% ptr)
50
+
51
+ end do
52
+ ! $OMP END PARALLEL DO
55
53
56
54
end do
57
55
56
+
58
57
end subroutine build_package
59
58
60
59
61
60
62
- recursive subroutine schedule_target (queue , target )
63
- ! Compile Fortran source, called recursively on it dependents
61
+ recursive subroutine schedule_target (target )
62
+ !
64
63
!
65
- type (build_target_ptr), intent (inout ), allocatable :: queue(:)
66
64
type (build_target_t), intent (inout ), target :: target
67
65
68
66
integer :: i, j, fh, stat
69
67
type (build_target_t), pointer :: exe_obj
70
- type (build_target_ptr) :: q_ptr
71
- character (:), allocatable :: link_flags
72
68
73
- if (target % enqueued .or. target % skip) then
69
+ if (target % scheduled .or. target % skip) then
74
70
return
75
71
end if
76
72
73
+ if (.not. exists(dirname(target % output_file))) then
74
+ call mkdir(dirname(target % output_file))
75
+ end if
76
+
77
77
if (target % touched) then
78
78
write (* ,* ) ' (!) Circular dependency found with: ' ,target % output_file
79
79
stop
@@ -102,19 +102,20 @@ recursive subroutine schedule_target(queue,target)
102
102
if (allocated (target % digest_cached)) then
103
103
if (target % digest_cached == target % source% digest) target % skip = .true.
104
104
end if
105
- else
105
+ elseif (exists( target % output_file)) then
106
106
target % skip = .true.
107
107
end if
108
108
109
109
target % link_objects = " "
110
-
110
+ target % region = 1
111
111
do i= 1 ,size (target % dependencies)
112
112
113
- call schedule_target(queue, target % dependencies(i)% ptr)
113
+ call schedule_target(target % dependencies(i)% ptr)
114
114
115
115
if (.not. target % dependencies(i)% ptr% skip) then
116
116
117
117
target % skip = .false.
118
+ target % region = max (target % region,target % dependencies(i)% ptr% region+1 )
118
119
119
120
end if
120
121
@@ -146,43 +147,76 @@ recursive subroutine schedule_target(queue,target)
146
147
147
148
end do
148
149
149
- if ( target % skip ) then
150
+ target % scheduled = .not. target % skip
150
151
151
- return
152
+ end subroutine schedule_target
152
153
153
- end if
154
154
155
- q_ptr% ptr = > target
156
- queue = [queue, q_ptr]
157
- target % enqueued = .true.
155
+ subroutine get_build_queue (queue , region_ptr , targets )
156
+ type (build_target_ptr), allocatable , intent (out ) :: queue(:)
157
+ integer , allocatable :: region_ptr(:)
158
+ type (build_target_ptr), intent (in ) :: targets(:)
158
159
159
- ! target%built = .true.
160
+ integer :: i, j
161
+ integer :: nRegion, n_scheduled
160
162
161
- end subroutine schedule_target
163
+ nRegion = 0
164
+ n_scheduled = 0
165
+ do i= 1 ,size (targets)
162
166
167
+ if (targets(i)% ptr% scheduled) then
168
+ n_scheduled = n_scheduled + 1
169
+ end if
170
+ nRegion = max (nRegion, targets(i)% ptr% region)
171
+
172
+ end do
173
+
174
+ allocate (queue(n_scheduled))
175
+ allocate (region_ptr(nRegion+1 ))
176
+
177
+ n_scheduled = 1
178
+ region_ptr(n_scheduled) = 1
179
+ do i= 1 ,nRegion
180
+
181
+ do j= 1 ,size (targets)
182
+
183
+ if (targets(j)% ptr% scheduled) then
184
+ if (targets(j)% ptr% region == i) then
185
+
186
+ queue(n_scheduled)% ptr = > targets(j)% ptr
187
+ n_scheduled = n_scheduled + 1
188
+ end if
189
+ end if
190
+
191
+ end do
163
192
193
+ region_ptr(i+1 ) = n_scheduled
194
+
195
+ end do
196
+
197
+ end subroutine get_build_queue
164
198
165
199
166
- subroutine build_target (model ,target , linking )
200
+ subroutine build_target (model ,target )
167
201
type (fpm_model_t), intent (in ) :: model
168
- type (build_target_t), intent (inout ), target :: target
169
- character (* ), intent (in ) :: linking
202
+ type (build_target_t), intent (in ), target :: target
170
203
171
204
integer :: ilib, fh
172
205
character (:), allocatable :: link_flags
173
206
174
- if (.not. exists(dirname(target % output_file))) then
175
- call mkdir(dirname(target % output_file))
176
- end if
177
-
178
207
select case (target % target_type)
179
208
180
209
case (FPM_TARGET_OBJECT)
181
210
call run(" gfortran -c " // target % source% file_name // model% fortran_compile_flags &
182
211
// " -o " // target % output_file)
183
212
184
213
case (FPM_TARGET_EXECUTABLE)
185
- link_flags = linking
214
+ if (allocated (model% library_file)) then
215
+ link_flags = " " // model% library_file// " " // model% link_flags
216
+ else
217
+ link_flags = " " // model% link_flags
218
+ end if
219
+
186
220
if (allocated (target % link_libraries)) then
187
221
do ilib = 1 , size (target % link_libraries)
188
222
link_flags = link_flags // " -l" // target % link_libraries(ilib)% s
0 commit comments