Skip to content

Commit e57c5da

Browse files
committed
implement static library linking
1 parent 3b66dc7 commit e57c5da

File tree

2 files changed

+39
-30
lines changed

2 files changed

+39
-30
lines changed

src/fpm_model.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ module fpm_model
237237
contains
238238

239239
!> Get target link flags
240-
procedure :: get_shared_libraries_link
240+
procedure :: get_package_libraries_link
241241

242242
!> Serialization interface
243243
procedure :: serializable_is_same => model_is_same
@@ -1139,7 +1139,7 @@ subroutine model_load_from_toml(self, table, error)
11391139

11401140
end subroutine model_load_from_toml
11411141

1142-
function get_shared_libraries_link(model, package_name, prefix, exclude_self, dep_IDs, error) result(r)
1142+
function get_package_libraries_link(model, package_name, prefix, exclude_self, dep_IDs, error) result(r)
11431143
class(fpm_model_t), intent(in) :: model
11441144
character(*), intent(in) :: package_name
11451145
type(error_t), allocatable, intent(out) :: error
@@ -1191,6 +1191,6 @@ function get_shared_libraries_link(model, package_name, prefix, exclude_self, de
11911191
! If requested, export the list of dependency IDs
11921192
if (present(dep_IDs)) call move_alloc(from=sorted_package_IDs,to=dep_IDs)
11931193

1194-
end function get_shared_libraries_link
1194+
end function get_package_libraries_link
11951195

11961196
end module fpm_model

src/fpm_targets.f90

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ subroutine targets_from_sources(targets,model,prune,library,error)
268268
if (present(library)) should_prune = should_prune .and. (library%lib_type/="")
269269
if (should_prune) call prune_build_targets(targets,root_package=model%package_name)
270270

271-
call resolve_target_linking(targets,model,error)
271+
call resolve_target_linking(targets,model,library,error)
272272
if (allocated(error)) return
273273

274274
end subroutine targets_from_sources
@@ -306,7 +306,7 @@ subroutine build_target_list(targets,model,library)
306306

307307
integer :: i, j, k, n_source, exe_type
308308
character(:), allocatable :: exe_dir, compile_flags, lib_name
309-
logical :: with_lib, monolithic, shared_lib
309+
logical :: with_lib, monolithic, shared_lib, static_lib
310310

311311
! Initialize targets
312312
allocate(targets(0))
@@ -321,16 +321,14 @@ subroutine build_target_list(targets,model,library)
321321
i=1,size(model%packages(j)%sources)), &
322322
j=1,size(model%packages))])
323323

324-
if (with_lib) then
325-
if (present(library)) then
326-
shared_lib = library%shared()
327-
else
328-
shared_lib = .false.
329-
end if
330-
monolithic = .not.shared_lib
324+
if (with_lib .and. present(library)) then
325+
shared_lib = library%shared()
326+
static_lib = library%static()
327+
monolithic = library%monolithic()
331328
else
332-
monolithic = .false.
329+
monolithic = with_lib
333330
shared_lib = .false.
331+
static_lib = .false.
334332
end if
335333

336334
! For a static object archive, everything from this package or all its dependencies is
@@ -339,19 +337,19 @@ subroutine build_target_list(targets,model,library)
339337
if (monolithic) then
340338

341339
lib_name = join_path(model%package_name, &
342-
library_filename(model%packages(1)%name,shared_lib,.false.,get_os_type()))
340+
library_filename(model%packages(1)%name,.false.,.false.,get_os_type()))
343341

344342
call add_target(targets,package=model%package_name, &
345343
type = FPM_TARGET_ARCHIVE,output_name = lib_name)
346344

347-
elseif (shared_lib) then
348-
! Shared libraries go to the same path as the `.mod` files (consistent linking directories)
345+
elseif (shared_lib .or. static_lib) then
346+
! Package libraries go to the same path as the `.mod` files (consistent linking directories)
349347
do j=1,size(model%packages)
350348

351349
lib_name = library_filename(model%packages(j)%name,shared_lib,.false.,get_os_type())
352350

353351
call add_target(targets,package=model%packages(j)%name, &
354-
type = FPM_TARGET_SHARED,output_name = lib_name)
352+
type = merge(FPM_TARGET_SHARED,FPM_TARGET_ARCHIVE,shared_lib),output_name = lib_name)
355353
end do
356354

357355
endif
@@ -380,7 +378,7 @@ subroutine build_target_list(targets,model,library)
380378

381379
if (with_lib .and. sources(i)%unit_scope == FPM_SCOPE_LIB) then
382380
! Archive depends on object
383-
call add_dependency(targets(merge(j,1,shared_lib))%ptr, targets(size(targets))%ptr)
381+
call add_dependency(targets(merge(1,j,monolithic))%ptr, targets(size(targets))%ptr)
384382
end if
385383

386384
case (FPM_UNIT_CPPSOURCE)
@@ -393,7 +391,7 @@ subroutine build_target_list(targets,model,library)
393391

394392
if (with_lib .and. sources(i)%unit_scope == FPM_SCOPE_LIB) then
395393
! Archive depends on object
396-
call add_dependency(targets(merge(j,1,shared_lib))%ptr, targets(size(targets))%ptr)
394+
call add_dependency(targets(merge(1,j,monolithic))%ptr, targets(size(targets))%ptr)
397395
end if
398396

399397
!> Add stdc++ as a linker flag. If not already there.
@@ -460,7 +458,7 @@ subroutine build_target_list(targets,model,library)
460458

461459
if (with_lib) then
462460
! Executable depends on library file(s)
463-
do k=1,merge(size(model%packages),1,shared_lib)
461+
do k=1,merge(1,size(model%packages),monolithic)
464462
call add_dependency(target, targets(k)%ptr)
465463
end do
466464
end if
@@ -944,13 +942,14 @@ end subroutine prune_build_targets
944942
!> Construct the linker flags string for each target
945943
!> `target%link_flags` includes non-library objects and library flags
946944
!>
947-
subroutine resolve_target_linking(targets, model, error)
945+
subroutine resolve_target_linking(targets, model, library, error)
948946
type(build_target_ptr), intent(inout), target :: targets(:)
949947
type(fpm_model_t), intent(in) :: model
948+
type(library_config_t), intent(in), optional :: library
950949
type(error_t), allocatable, intent(out) :: error
951950

952951
integer :: i,j
953-
logical :: shared,has_self_lib
952+
logical :: shared,static,monolithic,has_self_lib
954953
integer, allocatable :: package_deps(:)
955954
character(:), allocatable :: global_link_flags, local_link_flags
956955
character(:), allocatable :: global_include_flags, shared_lib_paths
@@ -963,7 +962,7 @@ subroutine resolve_target_linking(targets, model, error)
963962
global_link_flags = model%compiler%enumerate_libraries(global_link_flags, model%link_libraries)
964963
end if
965964
end if
966-
965+
967966
allocate(character(0) :: global_include_flags)
968967
if (allocated(model%include_dirs)) then
969968
if (size(model%include_dirs) > 0) then
@@ -972,7 +971,16 @@ subroutine resolve_target_linking(targets, model, error)
972971
end if
973972
end if
974973

975-
shared = .false.
974+
if (present(library)) then
975+
shared = library%shared()
976+
static = library%static()
977+
monolithic = library%monolithic()
978+
else
979+
shared = .false.
980+
static = .false.
981+
monolithic = .true.
982+
end if
983+
976984
do i=1,size(targets)
977985

978986
associate(target => targets(i)%ptr)
@@ -1024,7 +1032,8 @@ subroutine resolve_target_linking(targets, model, error)
10241032
select case (target%target_type)
10251033
case (FPM_TARGET_ARCHIVE)
10261034

1027-
global_link_flags = target%output_file // global_link_flags
1035+
! This adds the monolithic archive to the link flags
1036+
if (monolithic) global_link_flags = " " // target%output_file // global_link_flags
10281037

10291038
call get_link_objects(target%link_objects,target,is_exe=.false.)
10301039

@@ -1041,7 +1050,7 @@ subroutine resolve_target_linking(targets, model, error)
10411050
target%link_flags = target%link_flags // shared_lib_paths
10421051

10431052
! Add dependencies' shared libraries (excluding self)
1044-
target%link_flags = model%get_shared_libraries_link(target%package_name, &
1053+
target%link_flags = model%get_package_libraries_link(target%package_name, &
10451054
target%link_flags, &
10461055
exclude_self=.true., &
10471056
dep_IDs=package_deps, &
@@ -1077,7 +1086,7 @@ subroutine resolve_target_linking(targets, model, error)
10771086
target%link_flags = model%link_flags//" "//string_cat(target%link_objects," ")
10781087

10791088
! Add shared libs
1080-
if (shared) then
1089+
if (.not.monolithic) then
10811090

10821091
target%link_flags = target%link_flags // shared_lib_paths
10831092

@@ -1095,7 +1104,7 @@ subroutine resolve_target_linking(targets, model, error)
10951104
end do find_self
10961105

10971106
! Add dependencies' shared libraries (including self if there is a library)
1098-
target%link_flags = model%get_shared_libraries_link(target%package_name, &
1107+
target%link_flags = model%get_package_libraries_link(target%package_name, &
10991108
target%link_flags, &
11001109
error=error, &
11011110
exclude_self=.not.has_self_lib)
@@ -1109,7 +1118,7 @@ subroutine resolve_target_linking(targets, model, error)
11091118
end if
11101119

11111120
target%link_flags = target%link_flags//" "//global_link_flags
1112-
1121+
11131122
end select
11141123

11151124
end associate
@@ -1208,7 +1217,7 @@ subroutine get_library_dirs(model, targets, shared_lib_dirs)
12081217

12091218
do i = 1, size(targets)
12101219
associate(target => targets(i)%ptr)
1211-
if (target%target_type /= FPM_TARGET_SHARED) cycle
1220+
if (all(target%target_type /= [FPM_TARGET_SHARED,FPM_TARGET_ARCHIVE])) cycle
12121221
if (target%output_dir .in. shared_lib_dirs) cycle
12131222
temp = string_t(target%output_dir)
12141223
shared_lib_dirs = [shared_lib_dirs, temp]

0 commit comments

Comments
 (0)