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

Library configuration: allow multiple source directories #847

Closed
wants to merge 13 commits into from
6 changes: 6 additions & 0 deletions ci/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -158,5 +158,11 @@ pushd cpp_files
"$fpm" test
popd

pushd many_source_folders
"$fpm" build
"$fpm" run
"$fpm" test
popd

# Cleanup
rm -rf ./*/build
1 change: 1 addition & 0 deletions example_packages/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ the features demonstrated in each package and which versions of fpm are supporte
| link_executable | Link external library to a single executable | N | Y |
| link_external | Link external library | N | Y |
| makefile_complex | External build command (makefile); local path dependency | Y | N |
| many_source_folders | Source files split among multiple directories | N | Y |
| preprocess_cpp | Lib only; C preprocessing; Macro parsing | N | Y |
| preprocess_cpp_c | C App; progate macros from fpm.toml to app | N | Y |
| preprocess_cpp_deps | App; cpp preprocessor settings in local path dependency only | N | Y |
Expand Down
2 changes: 2 additions & 0 deletions example_packages/many_source_folders/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# two_exe_dirs
My cool new project!
19 changes: 19 additions & 0 deletions example_packages/many_source_folders/fpm.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name = "two_exe_dirs"
version = "0.1.0"
license = "license"
author = "Federico Perini"
maintainer = "[email protected]"
copyright = "Copyright 2023, Federico Perini"
[build]
auto-executables = false
auto-tests = true
auto-examples = true
[install]
library = false
[[executable]]
name="test_main"
source-dir=["src","src2"]
[[test]]
name="test_modules"
main="check.f90"
source-dir=["test","test2"]
10 changes: 10 additions & 0 deletions example_packages/many_source_folders/src/mod1.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module mod1
implicit none
private

public :: say_hello
contains
subroutine say_hello
print *, "Hello, from folder src/ !"
end subroutine say_hello
end module mod1
8 changes: 8 additions & 0 deletions example_packages/many_source_folders/src2/main.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
program main2
use mod1
use mod2
implicit none

call say_hello()
call say_hello2()
end program main2
10 changes: 10 additions & 0 deletions example_packages/many_source_folders/src2/mod2.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module mod2
implicit none
private

public :: say_hello2
contains
subroutine say_hello2
print *, "Hello, from folder src2/ !"
end subroutine say_hello2
end module mod2
18 changes: 18 additions & 0 deletions example_packages/many_source_folders/test/check.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
program test_many_folders
use mod1
use mod2
use test1
use test2
implicit none

call say_hello()
call say_hello2()
print *, "All source modules found!"

call print_test1()
call print_test2()
print *, "All test modules found!"

stop 0

end program test_many_folders
6 changes: 6 additions & 0 deletions example_packages/many_source_folders/test/test1.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module test1
contains
subroutine print_test1()
print *, "Hello, from test folder test/ ! "
end subroutine
end module test1
6 changes: 6 additions & 0 deletions example_packages/many_source_folders/test2/test2.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module test2
contains
subroutine print_test2()
print *, "Hello, from test folder test2/ ! "
end subroutine
end module test2
41 changes: 33 additions & 8 deletions src/fpm.f90
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ module fpm
use fpm_compiler, only: new_compiler, new_archiver, set_cpp_preprocessor_flags


use fpm_sources, only: add_executable_sources, add_sources_from_dir
use fpm_sources, only: add_executable_sources, add_sources_from_dir, &
add_executable_source_directories
use fpm_targets, only: targets_from_sources, &
resolve_target_linking, build_target_t, build_target_ptr, &
FPM_TARGET_EXECUTABLE, FPM_TARGET_ARCHIVE
Expand Down Expand Up @@ -53,6 +54,7 @@ subroutine build_model(model, settings, package, error)

model%package_name = package%name

allocate(model%source_dirs(0))
allocate(model%include_dirs(0))
allocate(model%link_libraries(0))
allocate(model%external_modules(0))
Expand Down Expand Up @@ -130,12 +132,14 @@ subroutine build_model(model, settings, package, error)
if (allocated(dependency%library)) then

if (allocated(dependency%library%source_dir)) then
lib_dir = join_path(dep%proj_dir, dependency%library%source_dir)
if (is_dir(lib_dir)) then
call add_sources_from_dir(model%packages(i)%sources, lib_dir, FPM_SCOPE_LIB, &
error=error)
if (allocated(error)) exit
end if
do j=1,size(dependency%library%source_dir)
lib_dir = join_path(dep%proj_dir, dependency%library%source_dir(j)%s)
if (is_dir(lib_dir)) then
call add_sources_from_dir(model%packages(i)%sources, lib_dir, FPM_SCOPE_LIB, &
error=error)
if (allocated(error)) exit
end if
end do
end if

if (allocated(dependency%library%include_dir)) then
Expand Down Expand Up @@ -173,6 +177,9 @@ subroutine build_model(model, settings, package, error)

! Add sources from executable directories
if (is_dir('app') .and. package%build%auto_executables) then

model%source_dirs = [model%source_dirs,string_t('app')]

call add_sources_from_dir(model%packages(1)%sources,'app', FPM_SCOPE_APP, &
with_executables=.true., error=error)

Expand All @@ -182,6 +189,9 @@ subroutine build_model(model, settings, package, error)

end if
if (is_dir('example') .and. package%build%auto_examples) then

model%source_dirs = [model%source_dirs,string_t('example')]

call add_sources_from_dir(model%packages(1)%sources,'example', FPM_SCOPE_EXAMPLE, &
with_executables=.true., error=error)

Expand All @@ -191,6 +201,9 @@ subroutine build_model(model, settings, package, error)

end if
if (is_dir('test') .and. package%build%auto_tests) then

model%source_dirs = [model%source_dirs,string_t('test')]

call add_sources_from_dir(model%packages(1)%sources,'test', FPM_SCOPE_TEST, &
with_executables=.true., error=error)

Expand All @@ -200,6 +213,10 @@ subroutine build_model(model, settings, package, error)

end if
if (allocated(package%executable)) then

call add_executable_source_directories(model%source_dirs,package%executable,error)
if (allocated(error)) return

call add_executable_sources(model%packages(1)%sources, package%executable, FPM_SCOPE_APP, &
auto_discover=package%build%auto_executables, &
error=error)
Expand All @@ -210,6 +227,10 @@ subroutine build_model(model, settings, package, error)

end if
if (allocated(package%example)) then

call add_executable_source_directories(model%source_dirs,package%example,error)
if (allocated(error)) return

call add_executable_sources(model%packages(1)%sources, package%example, FPM_SCOPE_EXAMPLE, &
auto_discover=package%build%auto_examples, &
error=error)
Expand All @@ -220,6 +241,10 @@ subroutine build_model(model, settings, package, error)

end if
if (allocated(package%test)) then

call add_executable_source_directories(model%source_dirs,package%test,error)
if (allocated(error)) return

call add_executable_sources(model%packages(1)%sources, package%test, FPM_SCOPE_TEST, &
auto_discover=package%build%auto_tests, &
error=error)
Expand Down Expand Up @@ -302,7 +327,7 @@ end subroutine check_modules_for_duplicates
subroutine check_module_names(model, error)
type(fpm_model_t), intent(in) :: model
type(error_t), allocatable, intent(out) :: error
integer :: i,j,k,l,m
integer :: k,l,m
logical :: valid,errors_found,enforce_this_file
type(string_t) :: package_name,module_name,package_prefix

Expand Down
2 changes: 0 additions & 2 deletions src/fpm/cmd/install.f90
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ subroutine cmd_install(settings)
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

Expand Down Expand Up @@ -88,7 +87,6 @@ subroutine install_info(unit, package, model, targets)
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))
Expand Down
8 changes: 4 additions & 4 deletions src/fpm/manifest.f90
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ subroutine default_library(self)
!> Instance of the library meta data
type(library_config_t), intent(out) :: self

self%source_dir = "src"
self%source_dir = [string_t("src")]
self%include_dir = [string_t("include")]

end subroutine default_library
Expand All @@ -52,7 +52,7 @@ subroutine default_executable(self, name)
character(len=*), intent(in) :: name

self%name = name
self%source_dir = "app"
self%source_dir = [string_t("app")]
self%main = "main.f90"

end subroutine default_executable
Expand All @@ -67,7 +67,7 @@ subroutine default_example(self, name)
character(len=*), intent(in) :: name

self%name = name // "-demo"
self%source_dir = "example"
self%source_dir = [string_t("example")]
self%main = "main.f90"

end subroutine default_example
Expand All @@ -82,7 +82,7 @@ subroutine default_test(self, name)
character(len=*), intent(in) :: name

self%name = name // "-test"
self%source_dir = "test"
self%source_dir = [string_t("test")]
self%main = "main.f90"

end subroutine default_test
Expand Down
15 changes: 12 additions & 3 deletions src/fpm/manifest/example.f90
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module fpm_manifest_example
use fpm_manifest_executable, only : executable_config_t
use fpm_error, only : error_t, syntax_error, bad_name_error
use fpm_toml, only : toml_table, toml_key, toml_stat, get_value, get_list
use fpm_strings, only : string_t, string_cat
implicit none
private

Expand Down Expand Up @@ -64,7 +65,15 @@ subroutine new_example(self, table, error)
if (bad_name_error(error,'example',self%name))then
return
endif
call get_value(table, "source-dir", self%source_dir, "example")

call get_list(table, "source-dir", self%source_dir, error)
if (allocated(error)) return

! Set default value of source-dir if not found in manifest
if (.not.allocated(self%source_dir)) then
self%source_dir = [string_t("example")]
end if

call get_value(table, "main", self%main, "main.f90")

call get_value(table, "dependencies", child, requested=.false.)
Expand Down Expand Up @@ -153,8 +162,8 @@ subroutine info(self, unit, verbosity)
write(unit, fmt) "- name", self%name
end if
if (allocated(self%source_dir)) then
if (self%source_dir /= "example" .or. pr > 2) then
write(unit, fmt) "- source directory", self%source_dir
if (self%source_dir(1)%s /= "example" .or. size(self%source_dir)/=1 .or. pr > 2) then
write(unit, fmt) "- source directory", string_cat(self%source_dir,",")
end if
end if
if (allocated(self%main)) then
Expand Down
19 changes: 14 additions & 5 deletions src/fpm/manifest/executable.f90
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
module fpm_manifest_executable
use fpm_manifest_dependency, only : dependency_config_t, new_dependencies
use fpm_error, only : error_t, syntax_error, bad_name_error
use fpm_strings, only : string_t
use fpm_strings, only : string_t,string_cat
use fpm_toml, only : toml_table, toml_key, toml_stat, get_value, get_list
implicit none
private
Expand All @@ -28,7 +28,7 @@ module fpm_manifest_executable
character(len=:), allocatable :: name

!> Source directory for collecting the executable
character(len=:), allocatable :: source_dir
type(string_t), allocatable :: source_dir(:)

!> Name of the source file declaring the main program
character(len=:), allocatable :: main
Expand Down Expand Up @@ -75,7 +75,15 @@ subroutine new_executable(self, table, error)
if (bad_name_error(error,'executable',self%name))then
return
endif
call get_value(table, "source-dir", self%source_dir, "app")

call get_list(table, "source-dir", self%source_dir, error)
if (allocated(error)) return

! Set default value of source-dir if not found in manifest
if (.not.allocated(self%source_dir)) then
self%source_dir = [string_t("app")]
end if

call get_value(table, "main", self%main, "main.f90")

call get_value(table, "dependencies", child, requested=.false.)
Expand All @@ -87,6 +95,7 @@ subroutine new_executable(self, table, error)
call get_list(table, "link", self%link, error)
if (allocated(error)) return


end subroutine new_executable


Expand Down Expand Up @@ -164,8 +173,8 @@ subroutine info(self, unit, verbosity)
write(unit, fmt) "- name", self%name
end if
if (allocated(self%source_dir)) then
if (self%source_dir /= "app" .or. pr > 2) then
write(unit, fmt) "- source directory", self%source_dir
if (self%source_dir(1)%s /= "app" .or. size(self%source_dir)/=1 .or. pr > 2) then
write(unit, fmt) "- source directory", string_cat(self%source_dir,",")
end if
end if
if (allocated(self%main)) then
Expand Down
Loading