aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/CI.yml12
-rw-r--r--README.md2
-rwxr-xr-xci/run_tests.bat6
-rwxr-xr-xci/run_tests.sh2
-rw-r--r--docs.md47
-rw-r--r--example_packages/hello_complex_2/app/say_hello/app_extra_mod.f906
-rw-r--r--example_packages/hello_complex_2/app/say_hello/app_hello_mod.f901
-rw-r--r--example_packages/hello_complex_2/app/say_hello/say_Hello.f904
-rw-r--r--fpm/fpm.toml2
-rw-r--r--fpm/src/fpm.f901
-rw-r--r--fpm/src/fpm/toml.f905
-rw-r--r--fpm/src/fpm_command_line.f9026
-rw-r--r--fpm/src/fpm_targets.f9093
-rw-r--r--fpm/test/fpm_test/test_module_dependencies.f9083
14 files changed, 224 insertions, 66 deletions
diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index f42d8ff..9ab8f5c 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -30,8 +30,8 @@ jobs:
TEST_SCRIPT: ci/run_tests.sh
GET_VERSION_CMD: echo ${{ github.ref }} | cut -dv -f2
CHECK_VERSION_CMD: grep $(cat fpm_version)
- RELEASE_CMD: "cp -- fpm-v$(cat fpm_version)-linux-x86_64"
- BOOTSTRAP_RELEASE_CMD: cp /home/runner/.local/bin/fpm fpm-bootstrap-v$(cat fpm_version)-linux-x86_64
+ RELEASE_CMD: "cp -- fpm-$(cat fpm_version)-linux-x86_64"
+ BOOTSTRAP_RELEASE_CMD: cp /home/runner/.local/bin/fpm fpm-haskell-$(cat fpm_version)-linux-x86_64
HASH_CMD: ls fpm-*|xargs -i{} sh -c 'sha256sum $1 > $1.sha256' -- {}
RELEASE_FLAGS: --flag --static --flag -g --flag -fbacktrace --flag -O3
@@ -43,8 +43,8 @@ jobs:
TEST_SCRIPT: ci/run_tests.sh
GET_VERSION_CMD: echo ${{ github.ref }} | cut -dv -f2
CHECK_VERSION_CMD: grep $(cat fpm_version)
- RELEASE_CMD: "cp -- fpm-v$(cat fpm_version)-macos-x86_64"
- BOOTSTRAP_RELEASE_CMD: cp /Users/runner/.local/bin/fpm fpm-bootstrap-v$(cat fpm_version)-macos-x86_64
+ RELEASE_CMD: "cp -- fpm-$(cat fpm_version)-macos-x86_64"
+ BOOTSTRAP_RELEASE_CMD: cp /Users/runner/.local/bin/fpm fpm-haskell-$(cat fpm_version)-macos-x86_64
HASH_CMD: ls fpm-*|xargs -I{} sh -c 'shasum -a 256 $1 > $1.sha256' -- {}
RELEASE_FLAGS: --flag -g --flag -fbacktrace --flag -O3
@@ -56,8 +56,8 @@ jobs:
TEST_SCRIPT: ci\run_tests.bat
GET_VERSION_CMD: ("${{ github.ref }}" -Split "v")[1]
CHECK_VERSION_CMD: Select-String -Pattern Version | Where-Object { if ($_ -like -join("*",(Get-Content fpm_version),"*")) {echo $_} else {Throw} }
- RELEASE_CMD: copy -- (-join("fpm-v",(Get-Content fpm_version),"-windows-x86_64.exe"))
- BOOTSTRAP_RELEASE_CMD: copy C:\Users\runneradmin\AppData\Roaming\local\bin\fpm.exe (-join("fpm-bootstrap-v",(Get-Content fpm_version),"-windows-x86_64.exe"))
+ RELEASE_CMD: copy -- (-join("fpm-",(Get-Content fpm_version),"-windows-x86_64.exe"))
+ BOOTSTRAP_RELEASE_CMD: copy C:\Users\runneradmin\AppData\Roaming\local\bin\fpm.exe (-join("fpm-haskell-",(Get-Content fpm_version),"-windows-x86_64.exe"))
HASH_CMD: Get-ChildItem -File -Filter "fpm-*" | Foreach-Object {echo (Get-FileHash -Algorithm SHA256 $PSItem | Select-Object hash | Format-Table -HideTableHeaders | Out-String) > (-join($PSItem,".sha256"))}
RELEASE_FLAGS: --flag --static --flag -g --flag -fbacktrace --flag -O3
diff --git a/README.md b/README.md
index 7d966dc..f8c69e2 100644
--- a/README.md
+++ b/README.md
@@ -24,6 +24,8 @@ __Note:__ On Linux and MacOS, you will need to enable executable permission befo
_e.g._ `$ chmod u+x fpm-v0.1.0-linux-x86_64`
+__Github actions:__ to setup *fpm* within Github actions for automated testing, you can use the [fortran-lang/setup-fpm](https://github.com/marketplace/actions/setup-fpm) action.
+
For other platforms and architectures have a look at the [bootstrapping instructions](#bootstrapping-instructions).
### Creating a new project
diff --git a/ci/run_tests.bat b/ci/run_tests.bat
index 533590d..22be2db 100755
--- a/ci/run_tests.bat
+++ b/ci/run_tests.bat
@@ -36,6 +36,9 @@ if errorlevel 1 exit 1
.\build\gfortran_debug\app\hello_world
if errorlevel 1 exit 1
+%fpm_path% run
+if errorlevel 1 exit 1
+
cd ..\hello_fpm
if errorlevel 1 exit 1
@@ -71,6 +74,9 @@ del /q /f build
%fpm_path% build
if errorlevel 1 exit 1
+%fpm_path% test
+if errorlevel 1 exit 1
+
.\build\gfortran_debug\app\say_Hello
if errorlevel 1 exit 1
diff --git a/ci/run_tests.sh b/ci/run_tests.sh
index 3588012..85484e5 100755
--- a/ci/run_tests.sh
+++ b/ci/run_tests.sh
@@ -23,6 +23,7 @@ rm -rf ./*/build
cd hello_world
"${f_fpm_path}" build
./build/gfortran_debug/app/hello_world
+"${f_fpm_path}" run
cd ../hello_fpm
"${f_fpm_path}" build
@@ -36,6 +37,7 @@ cd ../circular_example
cd ../hello_complex
"${f_fpm_path}" build
+"${f_fpm_path}" test
./build/gfortran_debug/app/say_Hello
./build/gfortran_debug/app/say_goodbye
./build/gfortran_debug/test/greet_test
diff --git a/docs.md b/docs.md
index 800cfab..1b4aef1 100644
--- a/docs.md
+++ b/docs.md
@@ -24,9 +24,56 @@ sort: permission-alpha
favicon: doc/media/favicon.ico
print_creation_date: true
extra_mods: iso_fortran_env:https://gcc.gnu.org/onlinedocs/gfortran/ISO_005fFORTRAN_005fENV.html
+ tomlf:https://toml-f.github.io/toml-f
+ M_CLI2:https://github.com/urbanjost/M_CLI2
creation_date: %Y-%m-%d %H:%M %z
md_extensions: markdown.extensions.toc
markdown.extensions.smarty
---
[TOC]
+
+# Fortran package manager developer documentation
+
+This is the main documentation of the Fortran package manager (*fpm*).
+This document serves as developer documentation of *fpm* itself and contains general advice for developing in the *fpm* code base.
+
+
+## The package manifest
+
+The central object describing an *fpm* project is the package manifest ``fpm.toml``.
+The manifest is written in TOML, you can find the TOML specification at the official [TOML homepage](https://toml.io).
+
+The ``fpm.toml`` file targets project developers and maintainers to relieve them from writing build files for their packages.
+With the package manifest a central place to collect information about the project is provided.
+It contains the versioning and licensing meta data, as well as the information on external dependencies and the required build-tools or compiler settings.
+
+The manifest format specific to *fpm* projects is documented in the [manifest reference](page/Manifest.html).
+
+@Note For a more practical but less complete guide on creating *fpm* projects see the [packaging guide](page/Packaging.html).
+
+The details of the TOML parsing are implemented with using the [tomlf](https://toml-f.github.io/toml-f) module.
+Generally, the interface to all TOML related functions for *fpm* is found in the proxy module [[fpm_toml]].
+
+All the manifest types are bundled in [[fpm_manifest]].
+While the specific subtables for the package configuration are found in the ``src/fpm/manifest`` directory, they should be reexported in the [[fpm_manifest]] module if they should be elsewhere in *fpm*.
+
+
+## Command line interface
+
+*fpm* is mainly used as a command line tool.
+To work with an *fpm* project as a user you can completely rely on the command line.
+
+The command line interface is build with the [M_CLI2](https://github.com/urbanjost/M_CLI2) module and can be found in [[fpm_command_line]].
+
+
+## Generating this documentation
+
+This documentation is generated by [FORD](https://github.com/Fortran-FOSS-Programmers/FORD).
+For more details on the [project file](https://github.com/fortran-lang/fpm/docs.md) and the comment markup in the source code visit the [FORD documentation](https://github.com/Fortran-FOSS-Programmers/ford/wiki).
+
+To regenerate this documentation run:
+
+```shell
+ford docs.md
+```
diff --git a/example_packages/hello_complex_2/app/say_hello/app_extra_mod.f90 b/example_packages/hello_complex_2/app/say_hello/app_extra_mod.f90
new file mode 100644
index 0000000..5059e22
--- /dev/null
+++ b/example_packages/hello_complex_2/app/say_hello/app_extra_mod.f90
@@ -0,0 +1,6 @@
+module app_extra_mod
+implicit none
+
+character(len=5) :: greet_object = "World"
+
+end module app_extra_mod
diff --git a/example_packages/hello_complex_2/app/say_hello/app_hello_mod.f90 b/example_packages/hello_complex_2/app/say_hello/app_hello_mod.f90
index c5795cb..e44edd7 100644
--- a/example_packages/hello_complex_2/app/say_hello/app_hello_mod.f90
+++ b/example_packages/hello_complex_2/app/say_hello/app_hello_mod.f90
@@ -1,4 +1,5 @@
module app_hello_mod
+use app_extra_mod, only: greet_object
implicit none
integer :: hello_int = 42
diff --git a/example_packages/hello_complex_2/app/say_hello/say_Hello.f90 b/example_packages/hello_complex_2/app/say_hello/say_Hello.f90
index 3b69ba7..3ebaebb 100644
--- a/example_packages/hello_complex_2/app/say_hello/say_Hello.f90
+++ b/example_packages/hello_complex_2/app/say_hello/say_Hello.f90
@@ -1,8 +1,8 @@
program say_Hello
use greet_m, only: make_greeting
- use app_hello_mod
+ use app_hello_mod, only: greet_object
implicit none
- print *, make_greeting("World")
+ print *, make_greeting(greet_object)
end program say_Hello
diff --git a/fpm/fpm.toml b/fpm/fpm.toml
index 66e5049..70c9603 100644
--- a/fpm/fpm.toml
+++ b/fpm/fpm.toml
@@ -1,5 +1,5 @@
name = "fpm"
-version = "0.1.1"
+version = "0.1.2"
license = "MIT"
author = "fpm maintainers"
maintainer = ""
diff --git a/fpm/src/fpm.f90 b/fpm/src/fpm.f90
index 67be1cc..e1a322e 100644
--- a/fpm/src/fpm.f90
+++ b/fpm/src/fpm.f90
@@ -175,6 +175,7 @@ subroutine build_model(model, settings, package, error)
allocate(package_list(1))
package_list(1)%s = package%name
+
if(settings%compiler.eq.'')then
model%fortran_compiler = 'gfortran'
else
diff --git a/fpm/src/fpm/toml.f90 b/fpm/src/fpm/toml.f90
index 34f7c58..2e1d6d3 100644
--- a/fpm/src/fpm/toml.f90
+++ b/fpm/src/fpm/toml.f90
@@ -1,4 +1,4 @@
-!> Interface to TOML processing library.
+!># Interface to TOML processing library
!>
!> This module acts as a proxy to the `toml-f` public Fortran API and allows
!> to selectively expose components from the library to `fpm`.
@@ -10,7 +10,8 @@
!> This module allows to implement features necessary for `fpm`, which are
!> not yet available in upstream `toml-f`.
!>
-!> For more details on the library used see: https://toml-f.github.io/toml-f
+!> For more details on the library used see the
+!> [TOML-Fortran](https://toml-f.github.io/toml-f) developer pages.
module fpm_toml
use fpm_error, only : error_t, fatal_error, file_not_found_error
use fpm_strings, only : string_t
diff --git a/fpm/src/fpm_command_line.f90 b/fpm/src/fpm_command_line.f90
index 2a44a4f..7fac111 100644
--- a/fpm/src/fpm_command_line.f90
+++ b/fpm/src/fpm_command_line.f90
@@ -1,3 +1,27 @@
+!># Definition of the command line interface
+!>
+!> This module uses [M_CLI2](https://github.com/urbanjost/M_CLI2) to define
+!> the command line interface.
+!> To define a command line interface create a new command settings type
+!> from the [[fpm_cmd_settings]] base class or the respective parent command
+!> settings.
+!>
+!> The subcommand is selected by the first non-option argument in the command
+!> line. In the subcase block the actual command line is defined and transferred
+!> to an instance of the [[fpm_cmd_settings]], the actual type is used by the
+!> *fpm* main program to determine which command entry point is chosen.
+!>
+!> To add a new subcommand add a new case to select construct and specify the
+!> wanted command line and the expected default values.
+!> Some of the following points also apply if you add a new option or argument
+!> to an existing *fpm* subcommand.
+!> Add this point you should create a help page for the new command in a simple
+!> catman-like format as well in the ``set_help`` procedure.
+!> Make sure to register new subcommands in the ``fpm-manual`` command by adding
+!> them to the manual character array and in the help/manual case as well.
+!> You should add the new command to the synopsis section of the ``fpm-list``,
+!> ``fpm-help`` and ``fpm --list`` help pages below to make sure the help output
+!> is complete and consistent as well.
module fpm_command_line
use fpm_environment, only : get_os_type, get_env, &
OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_WINDOWS, &
@@ -87,7 +111,7 @@ contains
case default ; os_type = "OS Type: UNKNOWN"
end select
version_text = [character(len=80) :: &
- & 'Version: 0.1.1, alpha', &
+ & 'Version: 0.1.2, alpha', &
& 'Program: fpm(1)', &
& 'Description: A Fortran package manager and build system', &
& 'Home Page: https://github.com/fortran-lang/fpm', &
diff --git a/fpm/src/fpm_targets.f90 b/fpm/src/fpm_targets.f90
index 03996f7..f9bbcda 100644
--- a/fpm/src/fpm_targets.f90
+++ b/fpm/src/fpm_targets.f90
@@ -259,12 +259,14 @@ function find_module_dependency(targets,module_name,include_dir) result(target_p
end function find_module_dependency
-!> For link targets, enumerate any dependency objects required for linking
+!> For libraries and executables, build a list of objects required for linking
+!>
+!> stored in `target%link_objects`
+!>
subroutine resolve_target_linking(targets)
type(build_target_ptr), intent(inout), target :: targets(:)
- integer :: i,j,k
- type(string_t) :: link_object
+ integer :: i
do i=1,size(targets)
@@ -272,47 +274,66 @@ subroutine resolve_target_linking(targets)
allocate(target%link_objects(0))
- do j=1,size(target%dependencies)
-
- if (target%target_type == FPM_TARGET_ARCHIVE ) then
-
- ! Construct object list for archive
- link_object%s = target%dependencies(j)%ptr%output_file
- target%link_objects = [target%link_objects, link_object]
-
- else if (target%target_type == FPM_TARGET_EXECUTABLE .and. &
- target%dependencies(j)%ptr%target_type == FPM_TARGET_OBJECT) then
-
- associate(exe_obj => target%dependencies(j)%ptr)
-
- ! Construct object list for executable
- link_object%s = exe_obj%output_file
- target%link_objects = [target%link_objects, link_object]
-
- ! Include non-library object dependencies
- do k=1,size(exe_obj%dependencies)
-
- if (allocated(exe_obj%dependencies(k)%ptr%source)) then
- if (exe_obj%dependencies(k)%ptr%source%unit_scope == &
- exe_obj%source%unit_scope) then
+ if (target%target_type == FPM_TARGET_ARCHIVE) then
- link_object%s = exe_obj%dependencies(k)%ptr%output_file
- target%link_objects = [target%link_objects, link_object]
+ call get_link_objects(target%link_objects,target,is_exe=.false.)
- end if
- end if
-
- end do
+ else if (target%target_type == FPM_TARGET_EXECUTABLE) then
- end associate
-
- end if
+ call get_link_objects(target%link_objects,target,is_exe=.true.)
+
+ end if
- end do
end associate
end do
+contains
+
+ !> Wrapper to build link object list
+ !>
+ !> For libraries: just list dependency objects of lib target
+ !>
+ !> For executables: need to recursively discover non-library
+ !> dependency objects. (i.e. modules in same dir as program)
+ !>
+ recursive subroutine get_link_objects(link_objects,target,is_exe)
+ type(string_t), intent(inout), allocatable :: link_objects(:)
+ type(build_target_t), intent(in) :: target
+ logical, intent(in) :: is_exe
+
+ integer :: i
+ type(string_t) :: temp_str
+
+ if (.not.allocated(target%dependencies)) return
+
+ do i=1,size(target%dependencies)
+
+ associate(dep => target%dependencies(i)%ptr)
+
+ if (.not.allocated(dep%source)) cycle
+
+ ! Skip library dependencies for executable targets
+ ! since the library archive will always be linked
+ if (is_exe.and.(dep%source%unit_scope == FPM_SCOPE_LIB)) cycle
+
+ ! Skip if dependency object already listed
+ if (dep%output_file .in. link_objects) cycle
+
+ ! Add dependency object file to link object list
+ temp_str%s = dep%output_file
+ link_objects = [link_objects, temp_str]
+
+ ! For executable objects, also need to include non-library
+ ! dependencies from dependencies (recurse)
+ if (is_exe) call get_link_objects(link_objects,dep,is_exe=.true.)
+
+ end associate
+
+ end do
+
+ end subroutine get_link_objects
+
end subroutine resolve_target_linking
diff --git a/fpm/test/fpm_test/test_module_dependencies.f90 b/fpm/test/fpm_test/test_module_dependencies.f90
index 18929ac..5d78e0c 100644
--- a/fpm/test/fpm_test/test_module_dependencies.f90
+++ b/fpm/test/fpm_test/test_module_dependencies.f90
@@ -1,14 +1,15 @@
!> Define tests for the `fpm_sources` module (module dependency checking)
module test_module_dependencies
use testsuite, only : new_unittest, unittest_t, error_t, test_failed
- use fpm_targets, only: targets_from_sources, resolve_module_dependencies
+ use fpm_targets, only: targets_from_sources, resolve_module_dependencies, &
+ resolve_target_linking
use fpm_model, only: fpm_model_t, srcfile_t, build_target_t, build_target_ptr, &
FPM_UNIT_UNKNOWN, FPM_UNIT_PROGRAM, FPM_UNIT_MODULE, &
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_TEST, &
FPM_TARGET_EXECUTABLE, FPM_TARGET_OBJECT, FPM_TARGET_ARCHIVE
- use fpm_strings, only: string_t
+ use fpm_strings, only: string_t, operator(.in.)
implicit none
private
@@ -71,14 +72,16 @@ contains
if (allocated(error)) then
return
end if
-
if (size(model%targets) /= 3) then
call test_failed(error,'Incorrect number of model%targets - expecting three')
return
end if
+ call resolve_target_linking(model%targets)
+
call check_target(model%targets(1)%ptr,type=FPM_TARGET_ARCHIVE,n_depends=2, &
- deps = [model%targets(2),model%targets(3)],error=error)
+ deps = [model%targets(2),model%targets(3)], &
+ links = model%targets(2:3), error=error)
if (allocated(error)) return
@@ -146,8 +149,10 @@ contains
return
end if
+ call resolve_target_linking(model%targets)
+
call check_target(model%targets(1)%ptr,type=FPM_TARGET_ARCHIVE,n_depends=1, &
- deps=[model%targets(2)],error=error)
+ deps=[model%targets(2)],links=[model%targets(2)],error=error)
if (allocated(error)) return
@@ -162,7 +167,8 @@ contains
if (allocated(error)) return
call check_target(model%targets(4)%ptr,type=FPM_TARGET_EXECUTABLE,n_depends=2, &
- deps=[model%targets(1),model%targets(3)],error=error)
+ deps=[model%targets(1),model%targets(3)], &
+ links=[model%targets(3)], error=error)
if (allocated(error)) return
@@ -202,20 +208,22 @@ contains
return
end if
+ call resolve_target_linking(model%targets)
+
call check_target(model%targets(1)%ptr,type=FPM_TARGET_OBJECT,n_depends=0, &
source=sources(1),error=error)
if (allocated(error)) return
call check_target(model%targets(2)%ptr,type=FPM_TARGET_EXECUTABLE,n_depends=1, &
- deps=[model%targets(1)],error=error)
+ deps=[model%targets(1)],links=[model%targets(1)],error=error)
if (allocated(error)) return
end subroutine test_program_with_module
- !> Check program using a module in same directory
+ !> Check program using modules in same directory
subroutine test_program_own_module_use(error)
!> Error handling
@@ -233,7 +241,7 @@ contains
integer, intent(in) :: exe_scope
type(error_t), allocatable, intent(out) :: error
- type(srcfile_t) :: sources(2)
+ type(srcfile_t) :: sources(3)
type(fpm_model_t) :: model
character(:), allocatable :: scope_str
@@ -241,13 +249,17 @@ contains
scope_str = merge('FPM_SCOPE_APP ','FPM_SCOPE_TEST',exe_scope==FPM_SCOPE_APP)//' - '
- sources(1) = new_test_source(FPM_UNIT_MODULE,file_name="app/app_mod.f90", &
+ sources(1) = new_test_source(FPM_UNIT_MODULE,file_name="app/app_mod1.f90", &
scope = exe_scope, &
- provides=[string_t('app_mod')])
+ provides=[string_t('app_mod1')])
- sources(2) = new_test_source(FPM_UNIT_PROGRAM,file_name="app/my_program.f90", &
+ sources(2) = new_test_source(FPM_UNIT_MODULE,file_name="app/app_mod2.f90", &
+ scope = exe_scope, &
+ provides=[string_t('app_mod2')],uses=[string_t('app_mod1')])
+
+ sources(3) = new_test_source(FPM_UNIT_PROGRAM,file_name="app/my_program.f90", &
scope=exe_scope, &
- uses=[string_t('app_mod')])
+ uses=[string_t('app_mod2')])
call targets_from_sources(model,sources)
call resolve_module_dependencies(model%targets,error)
@@ -256,11 +268,12 @@ contains
return
end if
- if (size(model%targets) /= 3) then
+ if (size(model%targets) /= 4) then
call test_failed(error,scope_str//'Incorrect number of model%targets - expecting three')
return
end if
+ call resolve_target_linking(model%targets)
call check_target(model%targets(1)%ptr,type=FPM_TARGET_OBJECT,n_depends=0, &
source=sources(1),error=error)
@@ -272,11 +285,16 @@ contains
if (allocated(error)) return
- call check_target(model%targets(3)%ptr,type=FPM_TARGET_EXECUTABLE,n_depends=1, &
- deps=[model%targets(2)],error=error)
+ call check_target(model%targets(3)%ptr,type=FPM_TARGET_OBJECT,n_depends=1, &
+ source=sources(3),deps=[model%targets(2)],error=error)
+
+ if (allocated(error)) return
+
+ call check_target(model%targets(4)%ptr,type=FPM_TARGET_EXECUTABLE,n_depends=1, &
+ deps=[model%targets(3)],links=model%targets(1:3), error=error)
if (allocated(error)) return
-
+
end subroutine test_scope
end subroutine test_program_own_module_use
@@ -414,12 +432,13 @@ contains
!> Helper to check an expected output target
- subroutine check_target(target,type,n_depends,deps,source,error)
+ subroutine check_target(target,type,n_depends,deps,links,source,error)
type(build_target_t), intent(in) :: target
integer, intent(in) :: type
integer, intent(in) :: n_depends
type(srcfile_t), intent(in), optional :: source
type(build_target_ptr), intent(in), optional :: deps(:)
+ type(build_target_ptr), intent(in), optional :: links(:)
type(error_t), intent(out), allocatable :: error
integer :: i
@@ -448,6 +467,34 @@ contains
end if
+ if (present(links)) then
+
+ do i=1,size(links)
+
+ if (.not.(links(i)%ptr%output_file .in. target%link_objects)) then
+ call test_failed(error,'Missing object ('//links(i)%ptr%output_file//&
+ ') for executable "'//target%output_file//'"')
+ return
+ end if
+
+ end do
+
+ if (size(links) > size(target%link_objects)) then
+
+ call test_failed(error,'There are missing link objects for target "'&
+ //target%output_file//'"')
+ return
+
+ elseif (size(links) < size(target%link_objects)) then
+
+ call test_failed(error,'There are more link objects than expected for target "'&
+ //target%output_file//'"')
+ return
+
+ end if
+
+ end if
+
if (present(source)) then
if (allocated(target%source)) then