diff options
-rw-r--r-- | lib/meson.build | 124 | ||||
-rw-r--r-- | meson.build | 357 |
2 files changed, 251 insertions, 230 deletions
diff --git a/lib/meson.build b/lib/meson.build index 0b9a67c..ead83c2 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -1,58 +1,100 @@ -libfuse_sources = ['fuse.c', 'fuse_i.h', 'fuse_loop.c', 'fuse_loop_mt.c', - 'fuse_lowlevel.c', 'fuse_misc.h', 'fuse_opt.c', - 'fuse_signals.c', 'buffer.c', 'cuse_lowlevel.c', - 'helper.c', 'modules/subdir.c', 'mount_util.c', - 'fuse_log.c', 'compat.c', 'util.c', 'util.h' ] +# lib/meson.build + +libfuse_sources = [ + 'fuse.c', 'fuse_i.h', 'fuse_loop.c', 'fuse_loop_mt.c', + 'fuse_lowlevel.c', 'fuse_misc.h', 'fuse_opt.c', + 'fuse_signals.c', 'buffer.c', 'cuse_lowlevel.c', + 'helper.c', 'modules/subdir.c', 'mount_util.c', + 'fuse_log.c', 'compat.c', 'util.c', 'util.h' +] if host_machine.system().startswith('linux') - libfuse_sources += [ 'mount.c' ] + libfuse_sources += ['mount.c'] else - libfuse_sources += [ 'mount_bsd.c' ] + libfuse_sources += ['mount_bsd.c'] endif +# --- Abhängigkeiten einsammeln --- deps = [ thread_dep ] + +# iconv: Wenn Funktion vorhanden, Modul immer mitbauen. +# Externe libiconv nur hinzufügen, wenn sie existiert (auf Android meist nicht nötig). if private_cfg.get('HAVE_ICONV') - libfuse_sources += [ 'modules/iconv.c' ] - libiconv = cc.find_library('iconv', required: false) - if libiconv.found() - deps += [ libiconv ] - endif + libfuse_sources += ['modules/iconv.c'] +endif +libiconv = cc.find_library('iconv', required: false) +if libiconv.found() + deps += [libiconv] endif +# libdl optional (auf Android meist Teil von bionic) libdl = cc.find_library('dl', required: false) if libdl.found() - deps += [ libdl ] + deps += [libdl] +endif + +# librt optional (alte glibc; Android braucht das nicht) +librt = cc.find_library('rt', required: false) +if librt.found() + deps += [librt] endif +# NetBSD-spezifisches if host_machine.system().startswith('netbsd') - deps += [ cc.find_library('perfuse'), - cc.find_library('puffs') ] -else - # Required for clock_gettime before glibc 2.17 - deps += cc.find_library('rt', required: false) + deps += [ + cc.find_library('perfuse'), + cc.find_library('puffs'), + ] endif +# Pfad zu fusermount(3) fusermount_path = join_paths(get_option('prefix'), get_option('bindir')) -libfuse = library('fuse3', - libfuse_sources, - version: base_version, - soversion: '4', - include_directories: include_dirs, - dependencies: deps, - install: true, - link_depends: 'fuse_versionscript', - c_args: [ '-DFUSE_USE_VERSION=317', - '-DFUSERMOUNT_DIR="@0@"'.format(fusermount_path) ], - link_args: ['-Wl,--version-script,' + meson.current_source_dir() - + '/fuse_versionscript' ]) - -pkg = import('pkgconfig') -pkg.generate(libraries: [ libfuse, '-lpthread' ], - libraries_private: '-ldl', - version: meson.project_version(), - name: 'fuse3', - description: 'Filesystem in Userspace', - subdirs: 'fuse3') - -libfuse_dep = declare_dependency(include_directories: include_dirs, - link_with: libfuse, dependencies: deps) + +libfuse = library( + 'fuse3', + libfuse_sources, + version: base_version, + soversion: '4', + include_directories: include_dirs, + dependencies: deps, + install: true, + link_depends: 'fuse_versionscript', + c_args: [ + '-DFUSE_USE_VERSION=317', + '-DFUSERMOUNT_DIR="@0@"'.format(fusermount_path), + ], + link_args: [ + '-Wl,--version-script,' + meson.current_source_dir() + '/fuse_versionscript', + ], +) + +# ---- pkg-config-Datei erzeugen ---- +pc = import('pkgconfig') + +pc_libs_public = [libfuse] + +pc_libs_private = [thread_dep] # wird zu -pthread/-lpthread passend zur Plattform aufgelöst +if libdl.found() + pc_libs_private += [libdl] +endif +if librt.found() + pc_libs_private += [librt] +endif +if libiconv.found() + pc_libs_private += [libiconv] +endif + +pc.generate( + libraries: pc_libs_public, + libraries_private: pc_libs_private, + version: meson.project_version(), + name: 'fuse3', + description: 'Filesystem in Userspace', + subdirs: 'fuse3', +) + +libfuse_dep = declare_dependency( + include_directories: include_dirs, + link_with: libfuse, + dependencies: deps +) diff --git a/meson.build b/meson.build index f5834aa..e117b9d 100644 --- a/meson.build +++ b/meson.build @@ -1,22 +1,17 @@ project('libfuse3', ['c'], - version: '3.17.4', - meson_version: '>= 0.60.0', - default_options: [ - 'buildtype=debugoptimized', - 'c_std=gnu11', - 'cpp_std=c++17', - 'warning_level=2', - ]) - -# Would be better to create the version string -# from integers, i.e. concatenating strings instead -# of splitting a string, but 'project' needs to be -# the first meson.build keyword... - -# split version into base and rc + version: '3.17.4', + meson_version: '>= 0.60.0', + default_options: [ + 'buildtype=debugoptimized', + 'c_std=gnu11', + 'cpp_std=c++17', + 'warning_level=2', + ], +) + +# --- Versionsaufbereitung (wie bisher) --- version_parts = meson.project_version().split('-') base_version = version_parts[0] - version_list = base_version.split('.') FUSE_MAJOR_VERSION = version_list[0] FUSE_MINOR_VERSION = version_list[1] @@ -26,31 +21,26 @@ FUSE_RC_VERSION = version_parts.length() > 1 ? version_parts[1] : '' platform = host_machine.system() if platform == 'darwin' error('libfuse does not support OS-X.\n' + - 'Take a look at http://osxfuse.github.io/ or the more recent\n' + - 'https://www.fuse-t.org/ instead') + 'See http://osxfuse.github.io/ or https://www.fuse-t.org/') elif platform == 'cygwin' or platform == 'windows' error('libfuse does not support Windows.\n' + - 'Take a look at http://www.secfs.net/winfsp/ instead') + 'See http://www.secfs.net/winfsp/') endif cc = meson.get_compiler('c') -# -# Feature detection, the resulting config file is installed -# with the package. -# Note: Symbols need to be care fully named, to avoid conflicts -# with applications linking to libfuse and including -# this config. -# +# --- Öffentliche Konfiguration, wird installiert (libfuse_config.h) --- public_cfg = configuration_data() - public_cfg.set('FUSE_MAJOR_VERSION', FUSE_MAJOR_VERSION) public_cfg.set('FUSE_MINOR_VERSION', FUSE_MINOR_VERSION) public_cfg.set('FUSE_HOTFIX_VERSION', FUSE_HOTFIX_VERSION) public_cfg.set('FUSE_RC_VERSION', FUSE_RC_VERSION) -# Default includes when checking for presence of functions and -# struct members +# --- Private Konfiguration, nur beim Bauen (fuse_config.h) --- +private_cfg = configuration_data() +private_cfg.set_quoted('PACKAGE_VERSION', meson.project_version()) + +# Default-Includes/Args für Funktions-/Struct-Checks include_default = ''' #include <stdio.h> #include <stdlib.h> @@ -59,218 +49,207 @@ include_default = ''' #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> -#include <pthread.h> /* For pthread_setname_np */ +#include <pthread.h> ''' -args_default = [ '-D_GNU_SOURCE' ] - -# -# Feature detection, only available at libfuse compilation time, -# but not for application linking to libfuse. -# -private_cfg = configuration_data() -private_cfg.set_quoted('PACKAGE_VERSION', meson.project_version()) - -# Test for presence of some functions -test_funcs = [ 'fork', 'fstatat', 'openat', 'readlinkat', 'pipe2', - 'splice', 'vmsplice', 'posix_fallocate', 'fdatasync', - 'utimensat', 'copy_file_range', 'fallocate' ] -foreach func : test_funcs - private_cfg.set('HAVE_' + func.to_upper(), - cc.has_function(func, prefix: include_default, args: args_default)) +args_default = ['-D_GNU_SOURCE'] + +# Funktionschecks +foreach func : [ + 'fork','fstatat','openat','readlinkat','pipe2','splice','vmsplice', + 'posix_fallocate','fdatasync','utimensat','copy_file_range','fallocate' +] + private_cfg.set('HAVE_' + func.to_upper(), + cc.has_function(func, prefix: include_default, args: args_default) + ) endforeach -# Special case checks that need custom code +# Spezialfälle, die gelinkt werden müssen special_funcs = { - 'pthread_setname_np': ''' - #include <pthread.h> - int main(void) { - pthread_t thread = pthread_self(); - pthread_setname_np(thread, "test"); - return 0; - } - ''', - 'close_range': ''' - #include <unistd.h> - #include <fcntl.h> - #include <linux/close_range.h> - int main(void) { - unsigned int flags = CLOSE_RANGE_UNSHARE; - return close_range(3, ~0U, flags); - } - ''' + 'pthread_setname_np' : ''' + #include <pthread.h> + int main(void) { + pthread_t t = pthread_self(); + pthread_setname_np(t, "test"); + return 0; + }''', + 'close_range' : ''' + #include <unistd.h> + #include <fcntl.h> + #include <linux/close_range.h> + int main(void){ + unsigned int flags = CLOSE_RANGE_UNSHARE; + return close_range(3, ~0U, flags); + }''' } - foreach name, code : special_funcs - private_cfg.set('HAVE_' + name.to_upper(), - cc.links(code, args: args_default, - name: name + ' check')) + private_cfg.set('HAVE_' + name.to_upper(), + cc.links(code, args: args_default, name: name + ' check') + ) endforeach -# Regular function checks -private_cfg.set('HAVE_SETXATTR', - cc.has_function('setxattr', prefix: '#include <sys/xattr.h>')) -private_cfg.set('HAVE_ICONV', - cc.has_function('iconv', prefix: '#include <iconv.h>')) -private_cfg.set('HAVE_BACKTRACE', - cc.has_function('backtrace', prefix: '#include <execinfo.h>')) +# Weitere Checks +private_cfg.set('HAVE_SETXATTR', cc.has_function('setxattr', prefix: '#include <sys/xattr.h>')) +private_cfg.set('HAVE_ICONV', cc.has_function('iconv', prefix: '#include <iconv.h>')) +private_cfg.set('HAVE_BACKTRACE', cc.has_function('backtrace', prefix: '#include <execinfo.h>')) -# Struct member checks +# Struct-Member private_cfg.set('HAVE_STRUCT_STAT_ST_ATIM', - cc.has_member('struct stat', 'st_atim', - prefix: include_default + '#include <sys/stat.h>', - args: args_default)) + cc.has_member('struct stat', 'st_atim', + prefix: include_default + '#include <sys/stat.h>', + args: args_default + ) +) private_cfg.set('HAVE_STRUCT_STAT_ST_ATIMESPEC', - cc.has_member('struct stat', 'st_atimespec', - prefix: include_default + '#include <sys/stat.h>', - args: args_default)) - -# -# Compiler configuration -# -add_project_arguments('-D_REENTRANT', '-DHAVE_LIBFUSE_PRIVATE_CONFIG_H', '-Wno-sign-compare', '-D_FILE_OFFSET_BITS=64', - '-Wstrict-prototypes', '-Wmissing-declarations', '-Wwrite-strings', - '-fno-strict-aliasing', language: 'c') -add_project_arguments('-D_REENTRANT', '-DHAVE_LIBFUSE_PRIVATE_CONFIG_H', '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', - '-Wno-sign-compare', '-Wmissing-declarations', - '-Wwrite-strings', '-fno-strict-aliasing', language: 'cpp') - -# Some (stupid) GCC versions warn about unused return values even when they are -# casted to void. This makes -Wunused-result pretty useless, since there is no -# way to suppress the warning when we really *want* to ignore the value. -code = ''' -__attribute__((warn_unused_result)) int get_4() { - return 4; -} -int main(void) { - (void) get_4(); - return 0; -}''' -if not cc.compiles(code, args: [ '-O0', '-Werror=unused-result' ]) - message('Compiler warns about unused result even when casting to void') - add_project_arguments('-Wno-unused-result', language: 'c') + cc.has_member('struct stat', 'st_atimespec', + prefix: include_default + '#include <sys/stat.h>', + args: args_default + ) +) + +# --- Compiler-/Projektflags --- +add_project_arguments( + [ + '-D_REENTRANT', + '-DHAVE_LIBFUSE_PRIVATE_CONFIG_H', + '-Wno-sign-compare', + '-D_FILE_OFFSET_BITS=64', + '-Wstrict-prototypes', + '-Wmissing-declarations', + '-Wwrite-strings', + '-fno-strict-aliasing', + ], + language: 'c' +) +add_project_arguments( + [ + '-D_REENTRANT', + '-DHAVE_LIBFUSE_PRIVATE_CONFIG_H', + '-D_GNU_SOURCE', + '-D_FILE_OFFSET_BITS=64', + '-Wno-sign-compare', + '-Wmissing-declarations', + '-Wwrite-strings', + '-fno-strict-aliasing', + ], + language: 'cpp' +) + +# Warnung "unused result" ggf. neutralisieren (wie bisher) +code_unused_result = ''' +__attribute__((warn_unused_result)) int get_4() { return 4; } +int main(void) { (void)get_4(); return 0; } +''' +if not cc.compiles(code_unused_result, args: ['-O0','-Werror=unused-result']) + message('Compiler warns about unused result even when casting to void') + add_project_arguments('-Wno-unused-result', language: 'c') endif -# It is hard to detect if the libc supports versioned symbols. Only gnu-libc -# seems to provide that, but then glibc is the main target for libfuse, so -# enable it by default +# --- Versionierte Symbole (wie bisher) --- versioned_symbols = 1 - -# This is an attempt to detect if another libc is used. -code = ''' +code_libc = ''' int main(void) { #if (defined(__UCLIBC__) || defined(__APPLE__)) -#error /* libc does not have versioned symbols */ +#error #endif - return 0; + return 0; }''' -if not cc.compiles(code, args: [ '-O0' ]) +if not cc.compiles(code_libc, args: ['-O0']) versioned_symbols = 0 endif - -# The detection can be overridden, which is useful for other (above unhandled) -# libcs and also especially useful for testing if get_option('disable-libc-symbol-version') - versioned_symbols = 0 + versioned_symbols = 0 endif - if versioned_symbols == 1 - message('Enabling versioned libc symbols') - public_cfg.set('LIBFUSE_BUILT_WITH_VERSIONED_SYMBOLS', 1) - - # gcc-10 and newer support the symver attribute which we need to use if we - # want to support LTO - # recent clang and gcc both support __has_attribute (and if they are too old - # to have __has_attribute, then they are too old to support symver) - # other compilers might not have __has_attribute, but in those cases - # it is safe for this check to fail and for us to fallback to the old _asm_ - # method for symver. Anyway the attributes not supported by __has_attribute() - # unfortunately return true giving a false positive. So let's try to build - # using __attribute__ ((symver )) and see the result. - code = ''' - __attribute__ ((symver ("test@TEST"))) - void foo(void) { - } - - int main(void) { - return 0; - }''' - if cc.compiles(code, args: [ '-O0', '-c', '-Werror']) - message('Compiler supports symver attribute') - add_project_arguments('-DHAVE_SYMVER_ATTRIBUTE', language: 'c') - else - message('Compiler does not support symver attribute') - endif + message('Enabling versioned libc symbols') + public_cfg.set('LIBFUSE_BUILT_WITH_VERSIONED_SYMBOLS', 1) + + code_symver = ''' + __attribute__ ((symver("test@TEST"))) void foo(void) {} + int main(void){ return 0; } + ''' + if cc.compiles(code_symver, args: ['-O0','-c','-Werror']) + message('Compiler supports symver attribute') + add_project_arguments('-DHAVE_SYMVER_ATTRIBUTE', language: 'c') + else + message('Compiler does not support symver attribute') + endif else - message('Disabling versioned libc symbols') + message('Disabling versioned libc symbols') endif -# Older versions of musl libc don't unescape entries in /etc/mtab -# Try to detect this behaviour, and work around, if necessary. +# --- Workaround für bestimmte musl-Varianten (unverändert) --- detect_getmntent_needs_unescape = ''' #define _GNU_SOURCE #include <mntent.h> #include <stdio.h> #include <string.h> #include <stdlib.h> - #define dir_space_tab "dir\\040space\\011tab" - -int main() -{ - const char *fake_mtab = "name " dir_space_tab " type opts 0 0\n"; - FILE *f = fmemopen((void *)fake_mtab, strlen(fake_mtab) + 1, "r"); - struct mntent *entp = getmntent(f); - fclose(f); - if(NULL == entp) - exit(EXIT_FAILURE); - if (0 == strcmp(entp->mnt_dir, dir_space_tab)) - printf("needs escaping\n"); - else - printf("no need to escape\n"); +int main() { + const char *fake_mtab = "name " dir_space_tab " type opts 0 0\\n"; + FILE *f = fmemopen((void *)fake_mtab, strlen(fake_mtab)+1, "r"); + struct mntent *entp = getmntent(f); + fclose(f); + if (!entp) return 1; + if (strcmp(entp->mnt_dir, dir_space_tab)==0) + printf("needs escaping\\n"); + else + printf("no need to escape\\n"); } ''' - if not meson.is_cross_build() - result = cc.run(detect_getmntent_needs_unescape) - if result.compiled() and result.returncode() == 0 and result.stdout().strip() == 'needs escaping' + r = cc.run(detect_getmntent_needs_unescape) + if r.compiled() and r.returncode() == 0 and r.stdout().strip() == 'needs escaping' message('getmntent does not unescape') add_project_arguments('-DGETMNTENT_NEEDS_UNESCAPING', language: 'c') endif endif -# Write private test results into fuse_config.h (stored in build directory) -configure_file(output: 'fuse_config.h', configuration : private_cfg) - -# Write the test results, installed with the package, -# symbols need to be properly prefixed to avoid -# symbol (define) conflicts -configure_file(output: 'libfuse_config.h', - configuration : public_cfg, - install: true, install_dir: join_paths(get_option('includedir'), 'fuse3')) +# --- Header mit Ergebnissen erzeugen --- +configure_file(output: 'fuse_config.h', configuration: private_cfg) +configure_file( + output: 'libfuse_config.h', + configuration: public_cfg, + install: true, + install_dir: join_paths(get_option('includedir'), 'fuse3'), +) -# '.' will refer to current build directory, which contains config.h +# Includes (Builddir enthält fuse_config.h) include_dirs = include_directories('include', 'lib', '.') -# Common dependencies -thread_dep = dependency('threads') +# --- Gemeinsame Dependencies --- +# Threads (niemals -lpthread in öffentliche Libs packen!) +thread_dep = dependency('threads') -# -# Read build files from sub-directories -# -subdirs = [ 'lib', 'include'] -if get_option('utils') and not platform.endswith('bsd') and platform != 'dragonfly' - subdirs += [ 'util', 'doc' ] +# dl: auf Android unnötig (bionic liefert das intern), +# auf anderen Linuxen weiter verfügbar halten. +dl_dep = cc.find_library('dl', required: platform != 'android') + +# Für Android (und generell) lieber das Flag -pthread setzen, +# statt -lpthread zu verlinken. +add_project_link_arguments('-pthread', language: 'c') + +# Diese Variable wird in lib/meson.build beim pkgconfig.generate() +# als libraries_private: verwendet, damit -lpthread/-ldl NICHT in Libs: landen. +fuse_pc_libs_private = [] +if thread_dep.found() + fuse_pc_libs_private += thread_dep +endif +if dl_dep.found() + fuse_pc_libs_private += dl_dep endif +# --- Unterverzeichnisse bauen --- +subdirs = ['lib', 'include'] +if get_option('utils') and not platform.endswith('bsd') and platform != 'dragonfly' + subdirs += ['util', 'doc'] +endif if get_option('examples') subdirs += 'example' endif - if get_option('tests') subdirs += 'test' endif - foreach n : subdirs - subdir(n) + subdir(n) endforeach - |