Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize fpm run; fix --example --all #1021

Merged
merged 1 commit into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions ci/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ pushd with_examples
"$fpm" run --target demo-prog
popd

pushd many_examples
"$fpm" build
"$fpm" run --example --all
test -e demo1.txt
test -e demo2.txt
popd

pushd auto_discovery_off
"$fpm" build
"$fpm" run --target auto_discovery_off
Expand Down
1 change: 1 addition & 0 deletions example_packages/many_examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build/*
3 changes: 3 additions & 0 deletions example_packages/many_examples/app/demo-prog.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
program demo
write(*, '(a)') "This is a simple program"
end program demo
7 changes: 7 additions & 0 deletions example_packages/many_examples/demo1/prog.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
program demo
integer :: i
open(newunit=i,file="demo1.txt",form="formatted",action="write")
write(i, '(a)') "DEMO1"
close(i)
stop 0
end program demo
7 changes: 7 additions & 0 deletions example_packages/many_examples/demo2/prog.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
program demo
integer :: i
open(newunit=i,file="demo2.txt",form="formatted",action="write")
write(i, '(a)') "DEMO2"
close(i)
stop 0
end program demo
12 changes: 12 additions & 0 deletions example_packages/many_examples/fpm.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name = "many_examples"
build.auto-examples = false

[[example]]
name = "demo-1"
source-dir = "demo1"
main = "prog.f90"

[[example]]
name = "demo-2"
source-dir = "demo2"
main = "prog.f90"
149 changes: 106 additions & 43 deletions src/fpm.f90
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ subroutine cmd_run(settings,test)
type(build_target_t), pointer :: exe_target
type(srcfile_t), pointer :: exe_source
integer :: run_scope,firsterror
integer, allocatable :: stat(:)
integer, allocatable :: stat(:),target_ID(:)
character(len=:),allocatable :: line
logical :: toomany

Expand Down Expand Up @@ -512,48 +512,31 @@ subroutine cmd_run(settings,test)
! Enumerate executable targets to run
col_width = -1
found(:) = .false.
allocate(executables(size(settings%name)))
do i=1,size(targets)

allocate(executables(size(targets)),target_ID(size(targets)))
enumerate: do i=1,size(targets)
exe_target => targets(i)%ptr

if (exe_target%target_type == FPM_TARGET_EXECUTABLE .and. &
allocated(exe_target%dependencies)) then

if (should_be_run(settings,run_scope,exe_target)) then

exe_source => exe_target%dependencies(1)%ptr%source

if (exe_source%unit_scope == run_scope) then

col_width = max(col_width,len(basename(exe_target%output_file))+2)

if (size(settings%name) == 0) then

exe_cmd%s = exe_target%output_file
executables = [executables, exe_cmd]

else

do j=1,size(settings%name)

if (glob(trim(exe_source%exe_name),trim(settings%name(j))) .and. .not.found(j)) then


found(j) = .true.
exe_cmd%s = exe_target%output_file
executables(j) = exe_cmd

end if

end do

end if

end if

end if

end do


col_width = max(col_width,len(basename(exe_target%output_file))+2)

! Priority by name ID, or 0 if no name present (run first)
j = settings%name_ID(exe_source%exe_name)
target_ID(i) = j
if (j>0) found(j) = .true.

exe_cmd%s = exe_target%output_file
executables(i) = exe_cmd

else
target_ID(i) = huge(target_ID(i))
endif
end do enumerate

! sort executables by ascending name ID, resize
call sort_executables(target_ID,executables)

! Check if any apps/tests were found
if (col_width < 0) then
if (test) then
Expand All @@ -563,8 +546,6 @@ subroutine cmd_run(settings,test)
end if
end if



! Check all names are valid
! or no name and found more than one file
toomany= size(settings%name)==0 .and. size(executables)>1
Expand Down Expand Up @@ -735,4 +716,86 @@ subroutine cmd_clean(settings)
end if
end subroutine cmd_clean

!> Sort executables by namelist ID, and trim unused values
pure subroutine sort_executables(target_ID,executables)
integer, allocatable, intent(inout) :: target_ID(:)
type(string_t), allocatable, intent(inout) :: executables(:)

integer :: i,j,n,used

n = size(target_ID)
used = 0

sort: do i=1,n
do j=i+1,n
if (target_ID(j)<target_ID(i)) &
call swap(target_ID(i),target_ID(j),executables(i),executables(j))
end do
if (target_ID(i)<huge(target_ID(i))) used = i
end do sort

if (used>0 .and. used<n) then
target_ID = target_ID(1:used)
executables = executables(1:used)
end if

contains

elemental subroutine swap(t1,t2,e1,e2)
integer, intent(inout) :: t1,t2
type(string_t), intent(inout) :: e1,e2
integer :: tmp
type(string_t) :: etmp

tmp = t1
t1 = t2
t2 = tmp
etmp = e1
e1 = e2
e2 = etmp
end subroutine swap

end subroutine sort_executables

!> Check if an executable should be run
logical function should_be_run(settings,run_scope,exe_target)
class(fpm_run_settings), intent(in) :: settings
integer, intent(in) :: run_scope
type(build_target_t), intent(in) :: exe_target

integer :: j

if (exe_target%target_type == FPM_TARGET_EXECUTABLE .and. &
allocated(exe_target%dependencies)) then

associate(exe_source => exe_target%dependencies(1)%ptr%source)

if (exe_source%unit_scope/=run_scope) then

! Other scope
should_be_run = .false.

elseif (size(settings%name) == 0 .or. .not.settings%list) then

! No list of targets
should_be_run = .true.

else

! Is found in list
should_be_run = settings%name_ID(exe_source%exe_name)>0

end if

end associate

else

!> Invalid target
should_be_run = .false.

endif

end function should_be_run

end module fpm
26 changes: 25 additions & 1 deletion src/fpm_command_line.f90
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ module fpm_command_line
OS_CYGWIN, OS_SOLARIS, OS_FREEBSD, OS_OPENBSD, OS_NAME
use M_CLI2, only : set_args, lget, sget, unnamed, remaining, specified
use M_CLI2, only : get_subcommand, CLI_RESPONSE_FILE
use fpm_strings, only : lower, split, to_fortran_name, is_fortran_name, remove_characters_in_set, string_t
use fpm_strings, only : lower, split, to_fortran_name, is_fortran_name, remove_characters_in_set, &
string_t, glob
use fpm_filesystem, only : basename, canon_path, which, run
use fpm_environment, only : get_command_arguments_quoted
use fpm_error, only : fpm_stop, error_t
Expand Down Expand Up @@ -96,6 +97,7 @@ module fpm_command_line
logical :: example
contains
procedure :: runner_command
procedure :: name_ID
end type

type, extends(fpm_run_settings) :: fpm_test_settings
Expand Down Expand Up @@ -1541,5 +1543,27 @@ function runner_command(cmd) result(run_cmd)
if (len_trim(cmd%runner_args)>0) run_cmd = run_cmd//' '//trim(cmd%runner_args)
end function runner_command

!> Check name in list ID. return 0 if not found
integer function name_ID(cmd,name)
class(fpm_run_settings), intent(in) :: cmd
character(*), intent(in) :: name

integer :: j

!> Default: not found
name_ID = 0
if (.not.allocated(cmd%name)) return

do j=1,size(cmd%name)

if (glob(trim(name),trim(cmd%name(j)))) then
name_ID = j
return
end if

end do

end function name_ID


end module fpm_command_line
2 changes: 1 addition & 1 deletion src/fpm_model.f90
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ module fpm_model
FPM_UNIT_SUBMODULE, FPM_UNIT_SUBPROGRAM, FPM_UNIT_CSOURCE, &
FPM_UNIT_CHEADER, FPM_SCOPE_UNKNOWN, FPM_SCOPE_LIB, &
FPM_SCOPE_DEP, FPM_SCOPE_APP, FPM_SCOPE_EXAMPLE, FPM_SCOPE_TEST, &
FPM_UNIT_CPPSOURCE
FPM_UNIT_CPPSOURCE, FPM_SCOPE_NAME

!> Source type unknown
integer, parameter :: FPM_UNIT_UNKNOWN = -1
Expand Down
Loading