@@ -29,23 +29,33 @@ module fpm_backend
29
29
30
30
use ,intrinsic :: iso_fortran_env, only : stdin= >input_unit, stdout= >output_unit, stderr= >error_unit
31
31
use fpm_error, only : fpm_stop
32
- use fpm_environment, only: run, get_os_type, OS_WINDOWS
33
- use fpm_filesystem, only: basename, dirname, join_path, exists, mkdir
32
+ use fpm_filesystem, only: basename, dirname, join_path, exists, mkdir, run, getline
34
33
use fpm_model, only: fpm_model_t
35
34
use fpm_strings, only: string_t, operator (.in .)
36
35
use fpm_targets, only: build_target_t, build_target_ptr, FPM_TARGET_OBJECT, &
37
36
FPM_TARGET_C_OBJECT, FPM_TARGET_ARCHIVE, FPM_TARGET_EXECUTABLE
37
+ use fpm_backend_output
38
38
implicit none
39
39
40
40
private
41
41
public :: build_package, sort_target, schedule_targets
42
42
43
+ #ifndef FPM_BOOTSTRAP
44
+ interface
45
+ function c_isatty () bind(C, name = ' c_isatty' )
46
+ use , intrinsic :: iso_c_binding, only: c_int
47
+ integer (c_int) :: c_isatty
48
+ end function
49
+ end interface
50
+ #endif
51
+
43
52
contains
44
53
45
54
! > Top-level routine to build package described by `model`
46
- subroutine build_package (targets ,model )
55
+ subroutine build_package (targets ,model , verbose )
47
56
type (build_target_ptr), intent (inout ) :: targets(:)
48
57
type (fpm_model_t), intent (in ) :: model
58
+ logical , intent (in ) :: verbose
49
59
50
60
integer :: i, j
51
61
type (build_target_ptr), allocatable :: queue(:)
@@ -54,6 +64,9 @@ subroutine build_package(targets,model)
54
64
type (string_t), allocatable :: build_dirs(:)
55
65
type (string_t) :: temp
56
66
67
+ type (build_progress_t) :: progress
68
+ logical :: plain_output
69
+
57
70
! Need to make output directory for include (mod) files
58
71
allocate (build_dirs(0 ))
59
72
do i = 1 , size (targets)
@@ -65,7 +78,7 @@ subroutine build_package(targets,model)
65
78
end do
66
79
67
80
do i = 1 , size (build_dirs)
68
- call mkdir(build_dirs(i)% s)
81
+ call mkdir(build_dirs(i)% s,verbose )
69
82
end do
70
83
71
84
! Perform depth-first topological sort of targets
@@ -78,11 +91,26 @@ subroutine build_package(targets,model)
78
91
! Construct build schedule queue
79
92
call schedule_targets(queue, schedule_ptr, targets)
80
93
94
+ ! Check if queue is empty
95
+ if (.not. verbose .and. size (queue) < 1 ) then
96
+ write (* , ' (a)' ) ' Project is up to date'
97
+ return
98
+ end if
99
+
81
100
! Initialise build status flags
82
101
allocate (stat(size (queue)))
83
102
stat(:) = 0
84
103
build_failed = .false.
85
104
105
+ ! Set output mode
106
+ #ifndef FPM_BOOTSTRAP
107
+ plain_output = (.not. (c_isatty()==1 )) .or. verbose
108
+ #else
109
+ plain_output = .true.
110
+ #endif
111
+
112
+ progress = build_progress_t(queue,plain_output)
113
+
86
114
! Loop over parallel schedule regions
87
115
do i= 1 ,size (schedule_ptr)- 1
88
116
@@ -95,7 +123,9 @@ subroutine build_package(targets,model)
95
123
skip_current = build_failed
96
124
97
125
if (.not. skip_current) then
98
- call build_target(model,queue(j)% ptr,stat(j))
126
+ call progress% compiling_status(j)
127
+ call build_target(model,queue(j)% ptr,verbose,stat(j))
128
+ call progress% completed_status(j,stat(j))
99
129
end if
100
130
101
131
! Set global flag if this target failed to build
@@ -108,6 +138,12 @@ subroutine build_package(targets,model)
108
138
109
139
! Check if this schedule region failed: exit with message if failed
110
140
if (build_failed) then
141
+ write (* ,* )
142
+ do j= 1 ,size (stat)
143
+ if (stat(j) /= 0 ) Then
144
+ call print_build_log(queue(j)% ptr)
145
+ end if
146
+ end do
111
147
do j= 1 ,size (stat)
112
148
if (stat(j) /= 0 ) then
113
149
write (stderr,' (*(g0:,1x))' ) ' <ERROR> Compilation failed for object "' ,basename(queue(j)% ptr% output_file),' "'
@@ -118,6 +154,8 @@ subroutine build_package(targets,model)
118
154
119
155
end do
120
156
157
+ call progress% success()
158
+
121
159
end subroutine build_package
122
160
123
161
@@ -261,35 +299,37 @@ end subroutine schedule_targets
261
299
! >
262
300
! > If successful, also caches the source file digest to disk.
263
301
! >
264
- subroutine build_target (model ,target ,stat )
302
+ subroutine build_target (model ,target ,verbose , stat )
265
303
type (fpm_model_t), intent (in ) :: model
266
304
type (build_target_t), intent (in ), target :: target
305
+ logical , intent (in ) :: verbose
267
306
integer , intent (out ) :: stat
268
307
269
308
integer :: fh
270
309
271
310
! $omp critical
272
311
if (.not. exists(dirname(target % output_file))) then
273
- call mkdir(dirname(target % output_file))
312
+ call mkdir(dirname(target % output_file),verbose )
274
313
end if
275
314
! $omp end critical
276
315
277
316
select case (target % target_type)
278
317
279
318
case (FPM_TARGET_OBJECT)
280
319
call model% compiler% compile_fortran(target % source% file_name, target % output_file, &
281
- & target % compile_flags, stat)
320
+ & target % compile_flags, target % output_log_file, stat)
282
321
283
322
case (FPM_TARGET_C_OBJECT)
284
323
call model% compiler% compile_c(target % source% file_name, target % output_file, &
285
- & target % compile_flags, stat)
324
+ & target % compile_flags, target % output_log_file, stat)
286
325
287
326
case (FPM_TARGET_EXECUTABLE)
288
327
call model% compiler% link(target % output_file, &
289
- & target % compile_flags// " " // target % link_flags, stat)
328
+ & target % compile_flags// " " // target % link_flags, target % output_log_file, stat)
290
329
291
330
case (FPM_TARGET_ARCHIVE)
292
- call model% archiver% make_archive(target % output_file, target % link_objects, stat)
331
+ call model% archiver% make_archive(target % output_file, target % link_objects, &
332
+ & target % output_log_file, stat)
293
333
294
334
end select
295
335
@@ -302,4 +342,30 @@ subroutine build_target(model,target,stat)
302
342
end subroutine build_target
303
343
304
344
345
+ ! > Read and print the build log for target
346
+ ! >
347
+ subroutine print_build_log (target )
348
+ type (build_target_t), intent (in ), target :: target
349
+
350
+ integer :: fh, ios
351
+ character (:), allocatable :: line
352
+
353
+ if (exists(target % output_log_file)) then
354
+
355
+ open (newunit= fh,file= target % output_log_file,status= ' old' )
356
+ do
357
+ call getline(fh, line, ios)
358
+ if (ios /= 0 ) exit
359
+ write (* ,' (A)' ) trim (line)
360
+ end do
361
+ close (fh)
362
+
363
+ else
364
+
365
+ write (stderr,' (*(g0:,1x))' ) ' <ERROR> Unable to find build log "' ,basename(target % output_log_file),' "'
366
+
367
+ end if
368
+
369
+ end subroutine print_build_log
370
+
305
371
end module fpm_backend
0 commit comments