meson: implement building of static programs

The whole thing is complicated by the fact that we have two layers
of libraries: e.g. libmount also needs libblkid. If we just tell meson
to make libmount static, this is not enough, because we also need it
to link to a static libblkid. Hence in the case of libs that link to
other libs internally, we need to create a different object with a
a different set of link_with items.

To avoid building the libraries twice, libfdisk and libmount are first
built into an internal "convenience" library, which is then linked into
the static and shared versions as appropriate.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-05-11 12:06:39 +02:00 committed by Karel Zak
parent d4c880d5a4
commit 69939195bd
6 changed files with 177 additions and 12 deletions

View File

@ -134,6 +134,8 @@ lib_blkid = both_libraries(
dependencies : build_libblkid ? [] : disabler(),
install : build_libblkid)
lib_blkid_static = lib_blkid.get_static_lib()
pkgconfig.generate(lib_blkid,
description : 'Block device id library',
subdirs : 'blkid',

View File

@ -47,18 +47,29 @@ lib_fdisk_includes = [dir_include,
dir_libfdisk,
dir_libuuid] # XXX: should this be declared along with the lib?
lib_fdisk = both_libraries(
'fdisk',
list_h,
lib__fdisk = static_library(
'_fdisk',
lib_fdisk_sources,
include_directories : lib_fdisk_includes,
dependencies : build_libfdisk ? [] : disabler())
lib_fdisk_static = static_library(
'fdisk',
link_whole : lib__fdisk,
link_with : [lib_common,
lib_blkid.get_static_lib(),
lib_uuid.get_static_lib()],
install : false)
lib_fdisk = library(
'fdisk',
link_whole : lib__fdisk,
link_depends : libfdisk_sym,
version : libfdisk_version,
link_args : ['-Wl,--version-script=@0@'.format(libfdisk_sym_path)],
link_with : [lib_common,
lib_blkid,
lib_uuid],
dependencies : build_libfdisk ? [] : disabler(),
install : build_libfdisk)
pkgconfig.generate(lib_fdisk,

View File

@ -54,11 +54,24 @@ if build_libmount and not have_dirfd and not have_ddfd
error('neither dirfd nor ddfd are available')
endif
lib_mount = both_libraries(
'mount',
list_h,
lib__mount = static_library(
'_mount',
lib_mount_sources,
monotonic_c,
include_directories : [dir_include,
dir_libmount,
dir_libblkid])
lib_mount_static = static_library(
'mount',
link_whole : lib__mount,
link_with : [lib_common,
lib_blkid.get_static_lib()],
dependencies : [realtime_libs],
install : false)
lib_mount = library(
'mount',
link_whole : lib__mount,
include_directories : [dir_include,
dir_libmount,
dir_libblkid],

View File

@ -42,6 +42,8 @@ lib_smartcols = both_libraries(
dependencies : build_libsmartcols ? [] : disabler(),
install : build_libsmartcols)
lib_smartcols_static = lib_smartcols.get_static_lib()
pkgconfig.generate(lib_smartcols,
description : 'table or tree library',
subdirs : 'libsmartcols',

View File

@ -82,6 +82,10 @@ build_uuidd = not get_option('build-uuidd').disabled()
conf.set('HAVE_UUIDD', build_uuidd ? 1 : false)
summary('uuidd', build_uuidd ? 'enabled' : 'disabled', section : 'components')
static_programs = get_option('static-programs')
need_static_libs = static_programs.length() > 0 # a rough estimate...
summary('static programs', static_programs)
LINUX = host_machine.system() in ['linux']
BSD = host_machine.system() in ['dragonfly', 'freebsd', 'netbsd', 'openbsd']
@ -190,6 +194,11 @@ lib_tinfo = dependency(
'tinfo',
required : get_option('tinfo'))
lib_tinfo_static = dependency(
'tinfo',
static : true,
required : need_static_libs ? get_option('tinfo') : disabler())
lib_ncursesw = dependency(
'ncursesw',
required : get_option('ncursesw'))
@ -237,6 +246,11 @@ lib_readline = dependency(
required : get_option('readline'))
conf.set('HAVE_LIBREADLINE', lib_readline.found() ? 1 : false)
lib_readline_static = dependency(
'readline',
static : true,
required : need_static_libs ? get_option('readline') : disabler())
lib_pcre = dependency(
'libpcre2-8',
required : get_option('libpcre'))
@ -1345,6 +1359,21 @@ if opt and not is_disabler(exe)
exes += exe
endif
opt = opt and 'losetup' in static_programs
exe = executable(
'losetup.static',
losetup_sources,
include_directories : includes,
link_args : ['--static'],
link_with : [lib_common,
lib_smartcols.get_static_lib()],
install_dir : sbindir,
install : opt,
build_by_default : opt)
if opt and not is_disabler(exe)
exes += exe
endif
opt = not get_option('build-zramctl').disabled()
exe = executable(
'zramctl',
@ -1411,6 +1440,35 @@ if opt and not is_disabler(exe)
install_man(mount_man)
endif
opt2 = opt and 'mount' in static_programs
exe = executable(
'mount.static',
mount_sources,
include_directories : includes,
link_args : ['--static'],
link_with : [lib_common,
lib_smartcols_static,
lib_mount_static],
install : opt2,
build_by_default : opt2)
if opt2 and not is_disabler(exe)
exes += exe
endif
opt2 = opt and 'umount' in static_programs
exe = executable(
'umount.static',
umount_sources,
include_directories : includes,
link_args : ['--static'],
link_with : [lib_common,
lib_mount_static],
install : opt2,
build_by_default : opt2)
if opt2 and not is_disabler(exe)
exes += exe
endif
# setuid?
exe = executable(
@ -1548,6 +1606,19 @@ if opt and not is_disabler(exe)
install_man('sys-utils/unshare.1')
endif
opt = opt and 'unshare' in static_programs
exe = executable(
'unshare.static',
unshare_sources,
include_directories : includes,
link_with : [lib_common],
install_dir : usrbin_exec_dir,
install : opt,
build_by_default : opt)
if opt and not is_disabler(exe)
exes += exe
endif
opt = not get_option('build-nsenter').disabled()
exe = executable(
'nsenter',
@ -1563,6 +1634,20 @@ if opt and not is_disabler(exe)
install_man('sys-utils/nsenter.1')
endif
opt = opt and 'nsenter' in static_programs
exe = executable(
'nsenter.static',
nsenter_sources,
include_directories : includes,
link_with : [lib_common],
dependencies : [lib_selinux],
install_dir : usrbin_exec_dir,
install : opt,
build_by_default : opt)
if opt and not is_disabler(exe)
exes += exe
endif
opt = not get_option('build-setpriv').disabled()
exe = executable(
'setpriv',
@ -1809,7 +1894,23 @@ if opt and not is_disabler(exe)
exes += exe
endif
# XXX: fdisk-static
opt2 = opt and 'fdisk' in static_programs
exe = executable(
'fdisk.static',
fdisk_sources,
link_args : ['--static'],
include_directories : includes,
link_with : [lib_common,
lib_tcolors,
lib_fdisk_static,
lib_smartcols.get_static_lib()],
dependencies : [lib_readline_static],
install_dir : sbindir,
install : opt2,
build_by_default : opt2)
if opt2 and not is_disabler(exe)
exes += exe
endif
exe = executable(
'sfdisk',
@ -1827,7 +1928,22 @@ if opt and not is_disabler(exe)
exes += exe
endif
# XXX: sfdisk-static
opt2 = opt and 'sfdisk' in static_programs
exe = executable(
'sfdisk.static',
sfdisk_sources,
include_directories : includes,
link_with : [lib_common,
lib_tcolors,
lib_fdisk_static,
lib_smartcols.get_static_lib()],
dependencies : [lib_readline_static],
install_dir : sbindir,
install : opt2,
build_by_default : opt2)
if opt2 and not is_disabler(exe)
exes += exe
endif
exe = executable(
'cfdisk',
@ -2219,7 +2335,19 @@ if opt and not is_disabler(exe)
install_man('misc-utils/blkid.8')
endif
# XXX: blkid.static
opt = opt and 'blkid' in static_programs
exe = executable(
'blkid.static',
blkid_sources,
include_directories : includes,
link_with : [lib_common,
lib_blkid_static],
install_dir : sbindir,
install : opt,
build_by_default : opt)
if opt and not is_disabler(exe)
exes += exe
endif
exe = executable(
'sample-mkfs',
@ -2575,7 +2703,7 @@ endif
libfdisk_tests_cflags = ['-DTEST_PROGRAM',
'-Wno-unused']
libfdisk_tests_ldadd = [lib_fdisk.get_static_lib(), lib_uuid, lib_blkid]
libfdisk_tests_ldadd = [lib_fdisk_static, lib_uuid, lib_blkid]
exe = executable(
'test_fdisk_ask',

View File

@ -156,6 +156,15 @@ option('build-bash-completion', type : 'feature',
option('build-pylibmount', type : 'feature',
description : 'build pylibmount')
# static programs
option('static-programs', type : 'array',
value : [],
choices : ['losetup', 'mount', 'umount', 'fdisk', 'sfdisk', 'blkid', 'nsenter', 'unshare'],
description : 'list of programs to also build with static linking')
# feature selection and other configuration
option('chfn-chsh-password',
type : 'boolean', value : true,
description : 'require the user to enter the password in chfn and chsh')