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

Add support for toggling Fortran features #864

Merged
merged 3 commits into from
Apr 7, 2023
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
8 changes: 8 additions & 0 deletions ci/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ pushd cpp_files
"$fpm" test
popd

# Test Fortran features
for feature in free-form fixed-form implicit-typing implicit-external
do
pushd $feature
"$fpm" run
popd
done

# Test app exit codes
pushd fpm_test_exit_code
"$fpm" build
Expand Down
4 changes: 4 additions & 0 deletions example_packages/fixed-form/app/main.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
program test
use lib
call hello
end
2 changes: 2 additions & 0 deletions example_packages/fixed-form/fpm.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name = "fixed-form"
fortran.source-form = "fixed"
7 changes: 7 additions & 0 deletions example_packages/fixed-form/src/lib.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module lib
contains
subroutine h e l l o
print '(a)',
+"Hello, fixed world!"
end subroutine
end module
4 changes: 4 additions & 0 deletions example_packages/free-form/app/main.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
program test
use lib
call hello
end
3 changes: 3 additions & 0 deletions example_packages/free-form/fpm.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name = "free-form"
fortran.source-form = "free"
executable = [{main="main.f", name="free-form"}]
6 changes: 6 additions & 0 deletions example_packages/free-form/src/lib.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module lib
contains
subroutine hello
print '(a)', "Hello, free world!"
end subroutine
end module
5 changes: 5 additions & 0 deletions example_packages/implicit-external/app/main.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
program test
integer :: ijk
call impl(ijk)
if (ijk /= 1) error stop
end program test
2 changes: 2 additions & 0 deletions example_packages/implicit-external/fpm.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name = "implicit-external"
fortran.implicit-external = true
4 changes: 4 additions & 0 deletions example_packages/implicit-external/src/impl.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
subroutine impl(ijk)
integer :: ijk
ijk = 1
end subroutine impl
4 changes: 4 additions & 0 deletions example_packages/implicit-typing/app/main.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
program test
use impl
if (ijk /= 1) error stop
end program
2 changes: 2 additions & 0 deletions example_packages/implicit-typing/fpm.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name = "implicit-typing"
fortran.implicit-typing = true
3 changes: 3 additions & 0 deletions example_packages/implicit-typing/src/impl.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module impl
parameter(ijk = 1)
end module
7 changes: 6 additions & 1 deletion src/fpm.f90
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module fpm
use fpm_environment, only: get_env
use fpm_filesystem, only: is_dir, join_path, list_files, exists, &
basename, filewrite, mkdir, run, os_delete_dir
use fpm_model, only: fpm_model_t, srcfile_t, show_model, &
use fpm_model, only: fpm_model_t, srcfile_t, show_model, fortran_features_t, &
FPM_SCOPE_UNKNOWN, FPM_SCOPE_LIB, FPM_SCOPE_DEP, &
FPM_SCOPE_APP, FPM_SCOPE_EXAMPLE, FPM_SCOPE_TEST
use fpm_compiler, only: new_compiler, new_archiver, set_cpp_preprocessor_flags
Expand Down Expand Up @@ -112,6 +112,11 @@ subroutine build_model(model, settings, package, error)
if (allocated(error)) exit

model%packages(i)%name = dependency%name
associate(features => model%packages(i)%features)
features%implicit_typing = dependency%fortran%implicit_typing
features%implicit_external = dependency%fortran%implicit_external
features%source_form = dependency%fortran%source_form
end associate
call package%version%to_string(version)
model%packages(i)%version = version

Expand Down
105 changes: 105 additions & 0 deletions src/fpm/manifest/fortran.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
module fpm_manifest_fortran
use fpm_error, only : error_t, syntax_error, fatal_error
use fpm_toml, only : toml_table, toml_key, toml_stat, get_value
implicit none
private

public :: fortran_config_t, new_fortran_config

!> Configuration data for Fortran
type :: fortran_config_t

!> Enable default implicit typing
logical :: implicit_typing

!> Enable implicit external interfaces
logical :: implicit_external

!> Form to use for all Fortran sources
character(:), allocatable :: source_form

end type fortran_config_t

contains

!> Construct a new build configuration from a TOML data structure
subroutine new_fortran_config(self, table, error)

!> Instance of the fortran configuration
type(fortran_config_t), intent(out) :: self

!> Instance of the TOML data structure
type(toml_table), intent(inout) :: table

!> Error handling
type(error_t), allocatable, intent(out) :: error

integer :: stat
character(:), allocatable :: source_form

call check(table, error)
if (allocated(error)) return

call get_value(table, "implicit-typing", self%implicit_typing, .false., stat=stat)

if (stat /= toml_stat%success) then
call fatal_error(error,"Error while reading value for 'implicit-typing' in fpm.toml, expecting logical")
return
end if

call get_value(table, "implicit-external", self%implicit_external, .false., stat=stat)

if (stat /= toml_stat%success) then
call fatal_error(error,"Error while reading value for 'implicit-external' in fpm.toml, expecting logical")
return
end if

call get_value(table, "source-form", source_form, "free", stat=stat)

if (stat /= toml_stat%success) then
call fatal_error(error,"Error while reading value for 'source-form' in fpm.toml, expecting logical")
return
end if
select case(source_form)
case default
call fatal_error(error,"Value of source-form cannot be '"//source_form//"'")
return
case("free", "fixed", "default")
self%source_form = source_form
end select

end subroutine new_fortran_config

!> Check local schema for allowed entries
subroutine check(table, error)

!> Instance of the TOML data structure
type(toml_table), intent(inout) :: table

!> Error handling
type(error_t), allocatable, intent(out) :: error

type(toml_key), allocatable :: list(:)
integer :: ikey

call table%get_keys(list)

! table can be empty
if (size(list) < 1) return

do ikey = 1, size(list)
select case(list(ikey)%key)

case("implicit-typing", "implicit-external", "source-form")
continue

case default
call syntax_error(error, "Key "//list(ikey)%key//" is not allowed in fortran")
exit

end select
end do

end subroutine check

end module fpm_manifest_fortran
15 changes: 14 additions & 1 deletion src/fpm/manifest/package.f90
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
!>[profiles]
!>[build]
!>[install]
!>[fortran]
!>[[ executable ]]
!>[[ example ]]
!>[[ test ]]
Expand All @@ -38,6 +39,7 @@ module fpm_manifest_package
use fpm_manifest_profile, only : profile_config_t, new_profiles, get_default_profiles
use fpm_manifest_example, only : example_config_t, new_example
use fpm_manifest_executable, only : executable_config_t, new_executable
use fpm_manifest_fortran, only : fortran_config_t, new_fortran_config
use fpm_manifest_library, only : library_config_t, new_library
use fpm_manifest_install, only: install_config_t, new_install_config
use fpm_manifest_test, only : test_config_t, new_test
Expand Down Expand Up @@ -75,6 +77,9 @@ module fpm_manifest_package
!> Installation configuration data
type(install_config_t) :: install

!> Fortran meta data
type(fortran_config_t) :: fortran

!> Library meta data
type(library_config_t), allocatable :: library

Expand Down Expand Up @@ -173,6 +178,14 @@ subroutine new_package(self, table, root, error)
call new_install_config(self%install, child, error)
if (allocated(error)) return

call get_value(table, "fortran", child, requested=.true., stat=stat)
if (stat /= toml_stat%success) then
call fatal_error(error, "Type mismatch for fortran entry, must be a table")
return
end if
call new_fortran_config(self%fortran, child, error)
if (allocated(error)) return

call get_value(table, "version", version, "0")
call new_version(self%version, version, error)
if (allocated(error) .and. present(root)) then
Expand Down Expand Up @@ -328,7 +341,7 @@ subroutine check(table, error)
case("version", "license", "author", "maintainer", "copyright", &
& "description", "keywords", "categories", "homepage", "build", &
& "dependencies", "dev-dependencies", "profiles", "test", "executable", &
& "example", "library", "install", "extra", "preprocess")
& "example", "library", "install", "extra", "preprocess", "fortran")
continue

end select
Expand Down
Loading