16881f68fSopenharmony_ciproject('libfuse3', ['c'], version: '3.16.1',
26881f68fSopenharmony_ci        meson_version: '>= 0.51',
36881f68fSopenharmony_ci        default_options: [
46881f68fSopenharmony_ci            'buildtype=debugoptimized',
56881f68fSopenharmony_ci            'cpp_std=c++11',
66881f68fSopenharmony_ci            'warning_level=2',
76881f68fSopenharmony_ci        ])
86881f68fSopenharmony_ci
96881f68fSopenharmony_ci
106881f68fSopenharmony_ciplatform = host_machine.system()
116881f68fSopenharmony_ciif platform == 'darwin'
126881f68fSopenharmony_ci  error('libfuse does not support OS-X.\n' +
136881f68fSopenharmony_ci        'Take a look at http://osxfuse.github.io/ instead')
146881f68fSopenharmony_cielif platform == 'cygwin' or platform == 'windows'
156881f68fSopenharmony_ci  error('libfuse does not support Windows.\n' +
166881f68fSopenharmony_ci        'Take a look at http://www.secfs.net/winfsp/ instead')       
176881f68fSopenharmony_ciendif
186881f68fSopenharmony_ci
196881f68fSopenharmony_cicc = meson.get_compiler('c')
206881f68fSopenharmony_ci
216881f68fSopenharmony_ci#
226881f68fSopenharmony_ci# Feature detection, only available at libfuse compilation time,
236881f68fSopenharmony_ci# but not for application linking to libfuse.
246881f68fSopenharmony_ci#
256881f68fSopenharmony_ciprivate_cfg = configuration_data()
266881f68fSopenharmony_ci
276881f68fSopenharmony_ci#
286881f68fSopenharmony_ci# Feature detection, the resulting config file is installed
296881f68fSopenharmony_ci# with the package.
306881f68fSopenharmony_ci# Note: Symbols need to be care fully named, to avoid conflicts
316881f68fSopenharmony_ci#       with applications linking to libfuse and including
326881f68fSopenharmony_ci#       this config.
336881f68fSopenharmony_ci#
346881f68fSopenharmony_cipublic_cfg = configuration_data()
356881f68fSopenharmony_ci
366881f68fSopenharmony_ci# Default includes when checking for presence of functions and
376881f68fSopenharmony_ci# struct members
386881f68fSopenharmony_ciinclude_default = '''
396881f68fSopenharmony_ci#include <stdio.h>
406881f68fSopenharmony_ci#include <stdlib.h>
416881f68fSopenharmony_ci#include <stddef.h>
426881f68fSopenharmony_ci#include <unistd.h>
436881f68fSopenharmony_ci#include <sys/types.h>
446881f68fSopenharmony_ci#include <sys/stat.h>
456881f68fSopenharmony_ci#include <fcntl.h>
466881f68fSopenharmony_ci'''
476881f68fSopenharmony_ciargs_default = [ '-D_GNU_SOURCE' ]
486881f68fSopenharmony_ci
496881f68fSopenharmony_ciprivate_cfg.set_quoted('PACKAGE_VERSION', meson.project_version())
506881f68fSopenharmony_ci
516881f68fSopenharmony_ci# Test for presence of some functions
526881f68fSopenharmony_citest_funcs = [ 'fork', 'fstatat', 'openat', 'readlinkat', 'pipe2',
536881f68fSopenharmony_ci               'splice', 'vmsplice', 'posix_fallocate', 'fdatasync',
546881f68fSopenharmony_ci               'utimensat', 'copy_file_range', 'fallocate' ]
556881f68fSopenharmony_ciforeach func : test_funcs
566881f68fSopenharmony_ci    private_cfg.set('HAVE_' + func.to_upper(),
576881f68fSopenharmony_ci        cc.has_function(func, prefix: include_default, args: args_default))
586881f68fSopenharmony_ciendforeach
596881f68fSopenharmony_ciprivate_cfg.set('HAVE_SETXATTR', 
606881f68fSopenharmony_ci        cc.has_function('setxattr', prefix: '#include <sys/xattr.h>'))
616881f68fSopenharmony_ciprivate_cfg.set('HAVE_ICONV', 
626881f68fSopenharmony_ci        cc.has_function('iconv', prefix: '#include <iconv.h>'))
636881f68fSopenharmony_ci
646881f68fSopenharmony_ci# Test if structs have specific member
656881f68fSopenharmony_ciprivate_cfg.set('HAVE_STRUCT_STAT_ST_ATIM',
666881f68fSopenharmony_ci         cc.has_member('struct stat', 'st_atim',
676881f68fSopenharmony_ci                       prefix: include_default,
686881f68fSopenharmony_ci                       args: args_default))
696881f68fSopenharmony_ciprivate_cfg.set('HAVE_STRUCT_STAT_ST_ATIMESPEC',
706881f68fSopenharmony_ci         cc.has_member('struct stat', 'st_atimespec',
716881f68fSopenharmony_ci                       prefix: include_default,
726881f68fSopenharmony_ci                       args: args_default))
736881f68fSopenharmony_ci
746881f68fSopenharmony_ci#
756881f68fSopenharmony_ci# Compiler configuration
766881f68fSopenharmony_ci#
776881f68fSopenharmony_ciadd_project_arguments('-D_REENTRANT', '-DHAVE_LIBFUSE_PRIVATE_CONFIG_H', '-Wno-sign-compare', '-D_FILE_OFFSET_BITS=64',
786881f68fSopenharmony_ci                      '-Wstrict-prototypes', '-Wmissing-declarations', '-Wwrite-strings',
796881f68fSopenharmony_ci                      '-fno-strict-aliasing', language: 'c')
806881f68fSopenharmony_ciadd_project_arguments('-D_REENTRANT', '-DHAVE_LIBFUSE_PRIVATE_CONFIG_H', '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64',
816881f68fSopenharmony_ci                     '-Wno-sign-compare', '-Wmissing-declarations',
826881f68fSopenharmony_ci                     '-Wwrite-strings', '-fno-strict-aliasing', language: 'cpp')
836881f68fSopenharmony_ci
846881f68fSopenharmony_ci# Some (stupid) GCC versions warn about unused return values even when they are
856881f68fSopenharmony_ci# casted to void. This makes -Wunused-result pretty useless, since there is no
866881f68fSopenharmony_ci# way to suppress the warning when we really *want* to ignore the value.
876881f68fSopenharmony_cicode = '''
886881f68fSopenharmony_ci__attribute__((warn_unused_result)) int get_4() {
896881f68fSopenharmony_ci    return 4;
906881f68fSopenharmony_ci}
916881f68fSopenharmony_ciint main(void) {
926881f68fSopenharmony_ci    (void) get_4();
936881f68fSopenharmony_ci    return 0;
946881f68fSopenharmony_ci}'''
956881f68fSopenharmony_ciif not cc.compiles(code, args: [ '-O0', '-Werror=unused-result' ])
966881f68fSopenharmony_ci     message('Compiler warns about unused result even when casting to void')
976881f68fSopenharmony_ci     add_project_arguments('-Wno-unused-result', language: 'c')
986881f68fSopenharmony_ciendif
996881f68fSopenharmony_ci
1006881f68fSopenharmony_ci# It is hard to detect if the libc supports versioned symbols. Only gnu-libc
1016881f68fSopenharmony_ci# seems to provide that, but then glibc is the main target for libfuse, so
1026881f68fSopenharmony_ci# enable it by default
1036881f68fSopenharmony_civersioned_symbols = 1
1046881f68fSopenharmony_ci
1056881f68fSopenharmony_ci# This is an attempt to detect if another libc is used.
1066881f68fSopenharmony_cicode = '''
1076881f68fSopenharmony_ciint main(void) {
1086881f68fSopenharmony_ci#if (defined(__UCLIBC__) || defined(__APPLE__))
1096881f68fSopenharmony_ci#error /* libc does not have versioned symbols */
1106881f68fSopenharmony_ci#endif
1116881f68fSopenharmony_ci    return 0;
1126881f68fSopenharmony_ci}'''
1136881f68fSopenharmony_ciif not cc.compiles(code, args: [ '-O0' ])
1146881f68fSopenharmony_ci  versioned_symbols = 0
1156881f68fSopenharmony_ciendif
1166881f68fSopenharmony_ci
1176881f68fSopenharmony_ci# The detection can be overridden, which is useful for other (above unhandled)
1186881f68fSopenharmony_ci# libcs and also especially useful for testing
1196881f68fSopenharmony_ciif get_option('disable-libc-symbol-version')
1206881f68fSopenharmony_ci     versioned_symbols = 0
1216881f68fSopenharmony_ciendif
1226881f68fSopenharmony_ci
1236881f68fSopenharmony_ciif versioned_symbols == 1
1246881f68fSopenharmony_ci     message('Enabling versioned libc symbols')
1256881f68fSopenharmony_ci     public_cfg.set('LIBFUSE_BUILT_WITH_VERSIONED_SYMBOLS', 1)
1266881f68fSopenharmony_ci
1276881f68fSopenharmony_ci     # gcc-10 and newer support the symver attribute which we need to use if we
1286881f68fSopenharmony_ci     # want to support LTO
1296881f68fSopenharmony_ci     # recent clang and gcc both support __has_attribute (and if they are too old
1306881f68fSopenharmony_ci     # to have __has_attribute, then they are too old to support symver)
1316881f68fSopenharmony_ci     # other compilers might not have __has_attribute, but in those cases
1326881f68fSopenharmony_ci     # it is safe for this check to fail and for us to fallback to the old _asm_
1336881f68fSopenharmony_ci     # method for symver. Anyway the attributes not supported by __has_attribute()
1346881f68fSopenharmony_ci     # unfortunately return true giving a false positive. So let's try to build
1356881f68fSopenharmony_ci     # using __attribute__ ((symver )) and see the result.
1366881f68fSopenharmony_ci     code = '''
1376881f68fSopenharmony_ci     __attribute__ ((symver ("test@TEST")))
1386881f68fSopenharmony_ci     void foo(void) {
1396881f68fSopenharmony_ci     }
1406881f68fSopenharmony_ci
1416881f68fSopenharmony_ci     int main(void) {
1426881f68fSopenharmony_ci         return 0;
1436881f68fSopenharmony_ci     }'''
1446881f68fSopenharmony_ci     if cc.compiles(code, args: [ '-O0', '-c', '-Werror'])
1456881f68fSopenharmony_ci          message('Compiler supports symver attribute')
1466881f68fSopenharmony_ci          add_project_arguments('-DHAVE_SYMVER_ATTRIBUTE', language: 'c')
1476881f68fSopenharmony_ci     else
1486881f68fSopenharmony_ci          message('Compiler does not support symver attribute')
1496881f68fSopenharmony_ci     endif
1506881f68fSopenharmony_cielse
1516881f68fSopenharmony_ci     message('Disabling versioned libc symbols')
1526881f68fSopenharmony_ciendif
1536881f68fSopenharmony_ci
1546881f68fSopenharmony_ci# Older versions of musl libc don't unescape entries in /etc/mtab
1556881f68fSopenharmony_ci# Try to detect this behaviour, and work around, if necessary.
1566881f68fSopenharmony_cidetect_getmntent_needs_unescape = '''
1576881f68fSopenharmony_ci#define _GNU_SOURCE
1586881f68fSopenharmony_ci#include <mntent.h>
1596881f68fSopenharmony_ci#include <stdio.h>
1606881f68fSopenharmony_ci#include <string.h>
1616881f68fSopenharmony_ci#include <stdlib.h>
1626881f68fSopenharmony_ci
1636881f68fSopenharmony_ci#define dir_space_tab "dir\\040space\\011tab"
1646881f68fSopenharmony_ci
1656881f68fSopenharmony_ciint main()
1666881f68fSopenharmony_ci{
1676881f68fSopenharmony_ci    const char *fake_mtab = "name " dir_space_tab " type opts 0 0\n";
1686881f68fSopenharmony_ci    FILE *f = fmemopen((void *)fake_mtab, strlen(fake_mtab) + 1, "r");
1696881f68fSopenharmony_ci    struct mntent *entp = getmntent(f);
1706881f68fSopenharmony_ci    fclose(f);
1716881f68fSopenharmony_ci    if(NULL == entp)
1726881f68fSopenharmony_ci        exit(EXIT_FAILURE);
1736881f68fSopenharmony_ci    if (0 == strcmp(entp->mnt_dir, dir_space_tab))
1746881f68fSopenharmony_ci        printf("needs escaping\n");
1756881f68fSopenharmony_ci    else
1766881f68fSopenharmony_ci        printf("no need to escape\n");
1776881f68fSopenharmony_ci}
1786881f68fSopenharmony_ci'''
1796881f68fSopenharmony_ci
1806881f68fSopenharmony_ciif not meson.is_cross_build()
1816881f68fSopenharmony_ci  result = cc.run(detect_getmntent_needs_unescape)
1826881f68fSopenharmony_ci  if result.compiled() and result.returncode() == 0 and result.stdout().strip() == 'needs escaping'
1836881f68fSopenharmony_ci    message('getmntent does not unescape')
1846881f68fSopenharmony_ci    add_project_arguments('-DGETMNTENT_NEEDS_UNESCAPING', language: 'c')
1856881f68fSopenharmony_ci  endif
1866881f68fSopenharmony_ciendif
1876881f68fSopenharmony_ci
1886881f68fSopenharmony_ci# Write private test results into fuse_config.h (stored in build directory)
1896881f68fSopenharmony_ciconfigure_file(output: 'fuse_config.h', configuration : private_cfg)
1906881f68fSopenharmony_ci
1916881f68fSopenharmony_ci# Write the test results, installed with the package,
1926881f68fSopenharmony_ci# symbols need to be properly prefixed to avoid
1936881f68fSopenharmony_ci# symbol (define) conflicts
1946881f68fSopenharmony_ciconfigure_file(output: 'libfuse_config.h',
1956881f68fSopenharmony_ci               configuration : public_cfg,
1966881f68fSopenharmony_ci               install: true, install_dir: join_paths(get_option('includedir'), 'fuse3'))
1976881f68fSopenharmony_ci
1986881f68fSopenharmony_ci# '.' will refer to current build directory, which contains config.h
1996881f68fSopenharmony_ciinclude_dirs = include_directories('include', 'lib', '.')
2006881f68fSopenharmony_ci
2016881f68fSopenharmony_ci# Common dependencies
2026881f68fSopenharmony_cithread_dep = dependency('threads') 
2036881f68fSopenharmony_ci
2046881f68fSopenharmony_ci#
2056881f68fSopenharmony_ci# Read build files from sub-directories
2066881f68fSopenharmony_ci#
2076881f68fSopenharmony_cisubdirs = [ 'lib', 'include']
2086881f68fSopenharmony_ciif get_option('utils') and not platform.endswith('bsd') and platform != 'dragonfly'
2096881f68fSopenharmony_ci  subdirs += [ 'util', 'doc' ]
2106881f68fSopenharmony_ciendif
2116881f68fSopenharmony_ci
2126881f68fSopenharmony_ciif get_option('examples')
2136881f68fSopenharmony_ci  subdirs += 'example'
2146881f68fSopenharmony_ciendif
2156881f68fSopenharmony_ci
2166881f68fSopenharmony_ciif get_option('tests')
2176881f68fSopenharmony_ci  subdirs += 'test'
2186881f68fSopenharmony_ciendif
2196881f68fSopenharmony_ci
2206881f68fSopenharmony_ciforeach n : subdirs
2216881f68fSopenharmony_ci    subdir(n)
2226881f68fSopenharmony_ciendforeach
2236881f68fSopenharmony_ci
224