Skip to content

Commit 5027275

Browse files
committed
Merge branch 'fix-duplicate-discovery' into local-depends
2 parents 71554f6 + bdaac5c commit 5027275

File tree

3 files changed

+80
-62
lines changed

3 files changed

+80
-62
lines changed

fpm/src/fpm_sources.f90

Lines changed: 74 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module fpm_sources
66
FPM_UNIT_CSOURCE, FPM_UNIT_CHEADER, FPM_SCOPE_UNKNOWN, &
77
FPM_SCOPE_LIB, FPM_SCOPE_DEP, FPM_SCOPE_APP, FPM_SCOPE_TEST
88

9-
use fpm_filesystem, only: basename, canon_path, dirname, read_lines, list_files
9+
use fpm_filesystem, only: basename, canon_path, dirname, join_path, read_lines, list_files
1010
use fpm_strings, only: lower, split, str_ends_with, string_t, operator(.in.)
1111
use fpm_manifest_executable, only: executable_t
1212
implicit none
@@ -24,6 +24,33 @@ module fpm_sources
2424

2525
contains
2626

27+
function parse_source(source_file_path,error) result(source)
28+
character(*), intent(in) :: source_file_path
29+
type(error_t), allocatable, intent(out) :: error
30+
type(srcfile_t) :: source
31+
32+
if (str_ends_with(lower(source_file_path), ".f90")) then
33+
34+
source = parse_f_source(source_file_path, error)
35+
36+
if (source%unit_type == FPM_UNIT_PROGRAM) then
37+
source%exe_name = basename(source_file_path,suffix=.false.)
38+
end if
39+
40+
else if (str_ends_with(lower(source_file_path), ".c") .or. &
41+
str_ends_with(lower(source_file_path), ".h")) then
42+
43+
source = parse_c_source(source_file_path,error)
44+
45+
end if
46+
47+
if (allocated(error)) then
48+
return
49+
end if
50+
51+
end function parse_source
52+
53+
2754
subroutine add_sources_from_dir(sources,directory,scope,with_executables,error)
2855
! Enumerate sources in a directory
2956
!
@@ -33,7 +60,7 @@ subroutine add_sources_from_dir(sources,directory,scope,with_executables,error)
3360
logical, intent(in), optional :: with_executables
3461
type(error_t), allocatable, intent(out) :: error
3562

36-
integer :: i, j
63+
integer :: i
3764
logical, allocatable :: is_source(:), exclude_source(:)
3865
type(string_t), allocatable :: file_names(:)
3966
type(string_t), allocatable :: src_file_names(:)
@@ -63,26 +90,8 @@ subroutine add_sources_from_dir(sources,directory,scope,with_executables,error)
6390

6491
do i = 1, size(src_file_names)
6592

66-
if (str_ends_with(lower(src_file_names(i)%s), ".f90")) then
67-
68-
dir_sources(i) = parse_f_source(src_file_names(i)%s, error)
69-
70-
if (allocated(error)) then
71-
return
72-
end if
73-
74-
end if
75-
76-
if (str_ends_with(lower(src_file_names(i)%s), ".c") .or. &
77-
str_ends_with(lower(src_file_names(i)%s), ".h")) then
78-
79-
dir_sources(i) = parse_c_source(src_file_names(i)%s,error)
80-
81-
if (allocated(error)) then
82-
return
83-
end if
84-
85-
end if
93+
dir_sources(i) = parse_source(src_file_names(i)%s,error)
94+
if (allocated(error)) return
8695

8796
dir_sources(i)%unit_scope = scope
8897

@@ -93,7 +102,6 @@ subroutine add_sources_from_dir(sources,directory,scope,with_executables,error)
93102
if (with_executables) then
94103

95104
exclude_source(i) = .false.
96-
dir_sources(i)%exe_name = basename(src_file_names(i)%s,suffix=.false.)
97105

98106
end if
99107
end if
@@ -122,49 +130,50 @@ subroutine add_executable_sources(sources,executables,scope,auto_discover,error)
122130
integer :: i, j
123131

124132
type(string_t), allocatable :: exe_dirs(:)
125-
logical, allocatable :: include_source(:)
126-
type(srcfile_t), allocatable :: dir_sources(:)
133+
type(srcfile_t) :: exe_source
127134

128135
call get_executable_source_dirs(exe_dirs,executables)
129136

130137
do i=1,size(exe_dirs)
131-
call add_sources_from_dir(dir_sources,exe_dirs(i)%s, &
132-
scope, with_executables=.true.,error=error)
138+
call add_sources_from_dir(sources,exe_dirs(i)%s, &
139+
scope, with_executables=auto_discover,error=error)
133140

134141
if (allocated(error)) then
135142
return
136143
end if
137144
end do
138145

139-
allocate(include_source(size(dir_sources)))
146+
exe_loop: do i=1,size(executables)
140147

141-
do i = 1, size(dir_sources)
142-
143-
! Include source by default if not a program or if auto_discover is enabled
144-
include_source(i) = (dir_sources(i)%unit_type /= FPM_UNIT_PROGRAM) .or. &
145-
auto_discover
148+
! Check if executable already discovered automatically
149+
! and apply any overrides
150+
do j=1,size(sources)
146151

147-
! Always include sources specified in fpm.toml
148-
do j=1,size(executables)
149-
150-
if (basename(dir_sources(i)%file_name,suffix=.true.) == executables(j)%main .and.&
151-
canon_path(dirname(dir_sources(i)%file_name)) == &
152-
canon_path(executables(j)%source_dir) ) then
152+
if (basename(sources(j)%file_name,suffix=.true.) == executables(i)%main .and.&
153+
canon_path(dirname(sources(j)%file_name)) == &
154+
canon_path(executables(i)%source_dir) ) then
153155

154-
include_source(i) = .true.
155-
dir_sources(i)%exe_name = executables(j)%name
156-
exit
156+
sources(j)%exe_name = executables(i)%name
157+
cycle exe_loop
157158

158159
end if
160+
159161
end do
160162

161-
end do
163+
! Add if not already discovered (auto_discovery off)
164+
exe_source = parse_source(join_path(executables(i)%source_dir,executables(i)%main),error)
165+
exe_source%exe_name = executables(i)%name
166+
exe_source%unit_scope = scope
167+
168+
if (allocated(error)) return
162169

163-
if (.not.allocated(sources)) then
164-
sources = pack(dir_sources,include_source)
165-
else
166-
sources = [sources, pack(dir_sources,include_source)]
167-
end if
170+
if (.not.allocated(sources)) then
171+
sources = [exe_source]
172+
else
173+
sources = [sources, exe_source]
174+
end if
175+
176+
end do exe_loop
168177

169178
end subroutine add_executable_sources
170179

@@ -291,21 +300,26 @@ function parse_f_source(f_filename,error) result(f_source)
291300
end if
292301

293302
! Process 'INCLUDE' statements
294-
if (index(adjustl(lower(file_lines(i)%s)),'include') == 1) then
295-
296-
n_include = n_include + 1
303+
ic = index(adjustl(lower(file_lines(i)%s)),'include')
304+
if ( ic == 1 ) then
305+
ic = index(lower(file_lines(i)%s),'include')
306+
if (index(adjustl(file_lines(i)%s(ic+7:)),'"') == 1 .or. &
307+
index(adjustl(file_lines(i)%s(ic+7:)),"'") == 1 ) then
297308

298-
if (pass == 2) then
299-
f_source%include_dependencies(n_include)%s = &
300-
& split_n(file_lines(i)%s,n=2,delims="'"//'"',stat=stat)
301-
if (stat /= 0) then
302-
call file_parse_error(error,f_filename, &
303-
'unable to find include file name',i, &
304-
file_lines(i)%s)
305-
return
309+
310+
n_include = n_include + 1
311+
312+
if (pass == 2) then
313+
f_source%include_dependencies(n_include)%s = &
314+
& split_n(file_lines(i)%s,n=2,delims="'"//'"',stat=stat)
315+
if (stat /= 0) then
316+
call file_parse_error(error,f_filename, &
317+
'unable to find include file name',i, &
318+
file_lines(i)%s)
319+
return
320+
end if
306321
end if
307322
end if
308-
309323
end if
310324

311325
! Extract name of module if is module

fpm/test/fpm_test/test_source_parsing.f90

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,11 @@ subroutine test_include_stmt(error)
198198
write(unit, '(a)') &
199199
& 'program test', &
200200
& ' implicit none', &
201-
& ' include "included_file.f90"', &
201+
& ' include "included_file.f90"', &
202+
& ' character(*) :: include_comments', &
203+
& ' include_comments = "some comments"', &
202204
& ' contains ', &
203-
& ' include "second_include.f90"', &
205+
& ' include"second_include.f90"', &
204206
& 'end program test'
205207
close(unit)
206208

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
module app_hello_mod
22
implicit none
33

4+
integer :: hello_int = 42
5+
46
end module app_hello_mod

0 commit comments

Comments
 (0)