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

Enable multiple build output directories #575

Merged
merged 3 commits into from
Oct 10, 2021
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
13 changes: 5 additions & 8 deletions src/fpm.f90
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ subroutine build_model(model, settings, package, error)

logical :: duplicates_found = .false.
type(string_t) :: include_dir
character(len=16) :: build_name

model%package_name = package%name

Expand Down Expand Up @@ -72,21 +71,19 @@ subroutine build_model(model, settings, package, error)
flags = flags // model%compiler%get_default_flags(settings%profile == "release")
end select
end if

cflags = trim(settings%cflag)
ldflags = trim(settings%ldflag)

write(build_name, '(z16.16)') fnv_1a(flags//cflags//ldflags)

if (model%compiler%is_unknown()) then
write(*, '(*(a:,1x))') &
"<WARN>", "Unknown compiler", model%compiler%fc, "requested!", &
"Defaults for this compiler might be incorrect"
end if
model%output_directory = join_path('build',basename(model%compiler%fc)//'_'//build_name)
model%build_prefix = join_path("build", basename(model%compiler%fc))

model%fortran_compile_flags = flags // " " // &
& model%compiler%get_module_flag(join_path(model%output_directory, model%package_name))
model%fortran_compile_flags = flags
model%c_compile_flags = cflags
model%link_flags = ldflags

model%include_tests = settings%build_tests

Expand Down Expand Up @@ -196,7 +193,7 @@ subroutine build_model(model, settings, package, error)
if (allocated(error)) return

if (settings%verbose) then
write(*,*)'<INFO> BUILD_NAME: ',build_name
write(*,*)'<INFO> BUILD_NAME: ',model%build_prefix
write(*,*)'<INFO> COMPILER: ',model%compiler%fc
write(*,*)'<INFO> C COMPILER: ',model%compiler%cc
write(*,*)'<INFO> COMPILER OPTIONS: ', model%fortran_compile_flags
Expand Down
63 changes: 25 additions & 38 deletions src/fpm/cmd/install.f90
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ module fpm_cmd_install
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
build_target_ptr, FPM_TARGET_EXECUTABLE, &
filter_library_targets, filter_executable_targets, filter_modules
use fpm_strings, only : string_t, resize
implicit none
private
Expand All @@ -28,6 +29,7 @@ subroutine cmd_install(settings)
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.)
Expand Down Expand Up @@ -61,13 +63,15 @@ subroutine cmd_install(settings)
verbosity=merge(2, 1, settings%verbose))

if (allocated(package%library) .and. package%install%library) then
dir = join_path(model%output_directory, model%package_name)
lib = "lib"//model%package_name//".a"
call installer%install_library(join_path(dir, lib), error)
call handle_error(error)
call filter_library_targets(targets, list)

call install_module_files(installer, dir, error)
call handle_error(error)
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
Expand All @@ -85,24 +89,17 @@ subroutine install_info(unit, package, model, targets)

integer :: ii, ntargets
character(len=:), allocatable :: lib
type(string_t), allocatable :: install_target(:)
type(string_t), allocatable :: install_target(:), temp(:)

call resize(install_target)
allocate(install_target(0))

ntargets = 0
if (allocated(package%library) .and. package%install%library) then
ntargets = ntargets + 1
lib = join_path(model%output_directory, model%package_name, &
"lib"//model%package_name//".a")
install_target(ntargets)%s = lib
end if
do ii = 1, size(targets)
if (is_executable_target(targets(ii)%ptr)) then
if (ntargets >= size(install_target)) call resize(install_target)
ntargets = ntargets + 1
install_target(ntargets)%s = targets(ii)%ptr%output_file
end if
end do
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
Expand All @@ -112,20 +109,18 @@ subroutine install_info(unit, package, model, targets)

end subroutine install_info

subroutine install_module_files(installer, dir, error)
subroutine install_module_files(installer, targets, error)
type(installer_t), intent(inout) :: installer
character(len=*), intent(in) :: dir
type(build_target_ptr), intent(in) :: targets(:)
type(error_t), allocatable, intent(out) :: error
type(string_t), allocatable :: modules(:)
integer :: ii

call list_files(dir, modules, recurse=.false.)
call filter_modules(targets, modules)

do ii = 1, size(modules)
if (is_module_file(modules(ii)%s)) then
call installer%install_header(modules(ii)%s, error)
if (allocated(error)) exit
end if
call installer%install_header(modules(ii)%s//".mod", error)
if (allocated(error)) exit
end do
if (allocated(error)) return

Expand Down Expand Up @@ -157,14 +152,6 @@ elemental function is_executable_target(target_ptr) result(is_exe)
end if
end function is_executable_target

elemental function is_module_file(name) result(is_mod)
character(len=*), intent(in) :: name
logical :: is_mod
integer :: ll
ll = len(name)
is_mod = name(max(1, ll-3):ll) == ".mod"
end function is_module_file

subroutine handle_error(error)
type(error_t), intent(in), optional :: error
if (present(error)) then
Expand Down
18 changes: 15 additions & 3 deletions src/fpm_backend.f90
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module fpm_backend
use fpm_environment, only: run, get_os_type, OS_WINDOWS
use fpm_filesystem, only: basename, dirname, join_path, exists, mkdir
use fpm_model, only: fpm_model_t
use fpm_strings, only: string_t, operator(.in.)
use fpm_targets, only: build_target_t, build_target_ptr, FPM_TARGET_OBJECT, &
FPM_TARGET_C_OBJECT, FPM_TARGET_ARCHIVE, FPM_TARGET_EXECUTABLE
implicit none
Expand All @@ -50,11 +51,22 @@ subroutine build_package(targets,model)
type(build_target_ptr), allocatable :: queue(:)
integer, allocatable :: schedule_ptr(:), stat(:)
logical :: build_failed, skip_current
type(string_t), allocatable :: build_dirs(:)
type(string_t) :: temp

! Need to make output directory for include (mod) files
if (.not.exists(join_path(model%output_directory,model%package_name))) then
call mkdir(join_path(model%output_directory,model%package_name))
end if
allocate(build_dirs(0))
do i = 1, size(targets)
associate(target => targets(i)%ptr)
if (target%output_dir .in. build_dirs) cycle
temp%s = target%output_dir
build_dirs = [build_dirs, temp]
end associate
end do

do i = 1, size(build_dirs)
call mkdir(build_dirs(i)%s)
end do

! Perform depth-first topological sort of targets
do i=1,size(targets)
Expand Down
1 change: 0 additions & 1 deletion src/fpm_compiler.f90
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,6 @@ function get_module_flag(self, path) result(flags)
flags = "-qmoddir "//path

end select
flags = flags//" "//self%get_include_flag(path)

end function get_module_flag

Expand Down
5 changes: 2 additions & 3 deletions src/fpm_model.f90
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ module fpm_model
character(:), allocatable :: link_flags

!> Base directory for build
character(:), allocatable :: output_directory
character(:), allocatable :: build_prefix

!> Include directories
type(string_t), allocatable :: include_dirs(:)
Expand Down Expand Up @@ -284,8 +284,7 @@ function info_model(model) result(s)
s = s // ', fortran_compile_flags="' // model%fortran_compile_flags // '"'
s = s // ', c_compile_flags="' // model%c_compile_flags // '"'
s = s // ', link_flags="' // model%link_flags // '"'
! character(:), allocatable :: output_directory
s = s // ', output_directory="' // model%output_directory // '"'
s = s // ', build_prefix="' // model%build_prefix // '"'
! type(string_t), allocatable :: link_libraries(:)
s = s // ", link_libraries=["
do i = 1, size(model%link_libraries)
Expand Down
Loading