1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
module fpm_cmd_install
use, intrinsic :: iso_fortran_env, only : output_unit
use fpm, only : build_model
use fpm_backend, only : build_package
use fpm_command_line, only : fpm_install_settings
use fpm_error, only : error_t, fatal_error, fpm_stop
use fpm_filesystem, only : join_path, list_files
use fpm_installer, only : installer_t, new_installer
use fpm_manifest, only : package_config_t, get_package_data
use fpm_model, only : fpm_model_t, FPM_SCOPE_APP
use fpm_targets, only: targets_from_sources, build_target_t, &
build_target_ptr, FPM_TARGET_EXECUTABLE, &
filter_library_targets, filter_executable_targets, filter_modules
use fpm_strings, only : string_t, resize
implicit none
private
public :: cmd_install
contains
!> Entry point for the fpm-install subcommand
subroutine cmd_install(settings)
!> Representation of the command line settings
type(fpm_install_settings), intent(in) :: settings
type(package_config_t) :: package
type(error_t), allocatable :: error
type(fpm_model_t) :: model
type(build_target_ptr), allocatable :: targets(:)
type(installer_t) :: installer
character(len=:), allocatable :: lib, dir
type(string_t), allocatable :: list(:)
logical :: installable
call get_package_data(package, "fpm.toml", error, apply_defaults=.true.)
call handle_error(error)
call build_model(model, settings%fpm_build_settings, package, error)
call handle_error(error)
call targets_from_sources(targets, model, error)
call handle_error(error)
installable = (allocated(package%library) .and. package%install%library) &
.or. allocated(package%executable)
if (.not.installable) then
call fatal_error(error, "Project does not contain any installable targets")
call handle_error(error)
end if
if (settings%list) then
call install_info(output_unit, package, model, targets)
return
end if
if (.not.settings%no_rebuild) then
call build_package(targets,model)
end if
call new_installer(installer, prefix=settings%prefix, &
bindir=settings%bindir, libdir=settings%libdir, &
includedir=settings%includedir, &
verbosity=merge(2, 1, settings%verbose))
if (allocated(package%library) .and. package%install%library) then
call filter_library_targets(targets, list)
if (size(list) > 0) then
call installer%install_library(list(1)%s, error)
call handle_error(error)
call install_module_files(installer, targets, error)
call handle_error(error)
end if
end if
if (allocated(package%executable)) then
call install_executables(installer, targets, error)
call handle_error(error)
end if
end subroutine cmd_install
subroutine install_info(unit, package, model, targets)
integer, intent(in) :: unit
type(package_config_t), intent(in) :: package
type(fpm_model_t), intent(in) :: model
type(build_target_ptr), intent(in) :: targets(:)
integer :: ii, ntargets
character(len=:), allocatable :: lib
type(string_t), allocatable :: install_target(:), temp(:)
allocate(install_target(0))
call filter_library_targets(targets, temp)
install_target = [install_target, temp]
call filter_executable_targets(targets, FPM_SCOPE_APP, temp)
install_target = [install_target, temp]
ntargets = size(install_target)
write(unit, '("#", *(1x, g0))') &
"total number of installable targets:", ntargets
do ii = 1, ntargets
write(unit, '("-", *(1x, g0))') install_target(ii)%s
end do
end subroutine install_info
subroutine install_module_files(installer, targets, error)
type(installer_t), intent(inout) :: installer
type(build_target_ptr), intent(in) :: targets(:)
type(error_t), allocatable, intent(out) :: error
type(string_t), allocatable :: modules(:)
integer :: ii
call filter_modules(targets, modules)
do ii = 1, size(modules)
call installer%install_header(modules(ii)%s//".mod", error)
if (allocated(error)) exit
end do
if (allocated(error)) return
end subroutine install_module_files
subroutine install_executables(installer, targets, error)
type(installer_t), intent(inout) :: installer
type(build_target_ptr), intent(in) :: targets(:)
type(error_t), allocatable, intent(out) :: error
integer :: ii
do ii = 1, size(targets)
if (is_executable_target(targets(ii)%ptr)) then
call installer%install_executable(targets(ii)%ptr%output_file, error)
if (allocated(error)) exit
end if
end do
if (allocated(error)) return
end subroutine install_executables
elemental function is_executable_target(target_ptr) result(is_exe)
type(build_target_t), intent(in) :: target_ptr
logical :: is_exe
is_exe = target_ptr%target_type == FPM_TARGET_EXECUTABLE .and. &
allocated(target_ptr%dependencies)
if (is_exe) then
is_exe = target_ptr%dependencies(1)%ptr%source%unit_scope == FPM_SCOPE_APP
end if
end function is_executable_target
subroutine handle_error(error)
type(error_t), intent(in), optional :: error
if (present(error)) then
call fpm_stop(1,error%message)
end if
end subroutine handle_error
end module fpm_cmd_install
|