1project('libfuse3', ['c'], version: '3.17.0', 2 meson_version: '>= 0.51', 3 default_options: [ 4 'buildtype=debugoptimized', 5 'c_std=gnu11', 6 'cpp_std=c++11', 7 'warning_level=2', 8 ]) 9 10# Would be better to create the version string 11# from integers, i.e. concatenating strings instead 12# of splitting a string, but 'project' needs to be 13# the first meson.build keyword... 14version_list = meson.project_version().split('.') 15FUSE_MAJOR_VERSION = version_list[0] 16FUSE_MINOR_VERSION = version_list[1] 17FUSE_HOTFIX_VERSION = version_list[2] 18 19platform = host_machine.system() 20if platform == 'darwin' 21 error('libfuse does not support OS-X.\n' + 22 'Take a look at http://osxfuse.github.io/ or the more recent\n' + 23 'https://www.fuse-t.org/ instead') 24elif platform == 'cygwin' or platform == 'windows' 25 error('libfuse does not support Windows.\n' + 26 'Take a look at http://www.secfs.net/winfsp/ instead') 27endif 28 29cc = meson.get_compiler('c') 30 31# 32# Feature detection, only available at libfuse compilation time, 33# but not for application linking to libfuse. 34# 35private_cfg = configuration_data() 36 37# 38# Feature detection, the resulting config file is installed 39# with the package. 40# Note: Symbols need to be care fully named, to avoid conflicts 41# with applications linking to libfuse and including 42# this config. 43# 44public_cfg = configuration_data() 45 46public_cfg.set('FUSE_MAJOR_VERSION', FUSE_MAJOR_VERSION) 47public_cfg.set('FUSE_MINOR_VERSION', FUSE_MINOR_VERSION) 48public_cfg.set('FUSE_HOTFIX_VERSION', FUSE_HOTFIX_VERSION) 49 50# Default includes when checking for presence of functions and 51# struct members 52include_default = ''' 53#include <stdio.h> 54#include <stdlib.h> 55#include <stddef.h> 56#include <unistd.h> 57#include <sys/types.h> 58#include <sys/stat.h> 59#include <fcntl.h> 60''' 61args_default = [ '-D_GNU_SOURCE' ] 62 63private_cfg.set_quoted('PACKAGE_VERSION', meson.project_version()) 64 65# Test for presence of some functions 66test_funcs = [ 'fork', 'fstatat', 'openat', 'readlinkat', 'pipe2', 67 'splice', 'vmsplice', 'posix_fallocate', 'fdatasync', 68 'utimensat', 'copy_file_range', 'fallocate' ] 69foreach func : test_funcs 70 private_cfg.set('HAVE_' + func.to_upper(), 71 cc.has_function(func, prefix: include_default, args: args_default)) 72endforeach 73private_cfg.set('HAVE_SETXATTR', 74 cc.has_function('setxattr', prefix: '#include <sys/xattr.h>')) 75private_cfg.set('HAVE_ICONV', 76 cc.has_function('iconv', prefix: '#include <iconv.h>')) 77private_cfg.set('HAVE_BACKTRACE', 78 cc.has_function('backtrace', prefix: '#include <execinfo.h>')) 79 80# Test if structs have specific member 81private_cfg.set('HAVE_STRUCT_STAT_ST_ATIM', 82 cc.has_member('struct stat', 'st_atim', 83 prefix: include_default, 84 args: args_default)) 85private_cfg.set('HAVE_STRUCT_STAT_ST_ATIMESPEC', 86 cc.has_member('struct stat', 'st_atimespec', 87 prefix: include_default, 88 args: args_default)) 89 90# 91# Compiler configuration 92# 93add_project_arguments('-D_REENTRANT', '-DHAVE_LIBFUSE_PRIVATE_CONFIG_H', '-Wno-sign-compare', '-D_FILE_OFFSET_BITS=64', 94 '-Wstrict-prototypes', '-Wmissing-declarations', '-Wwrite-strings', 95 '-fno-strict-aliasing', language: 'c') 96add_project_arguments('-D_REENTRANT', '-DHAVE_LIBFUSE_PRIVATE_CONFIG_H', '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', 97 '-Wno-sign-compare', '-Wmissing-declarations', 98 '-Wwrite-strings', '-fno-strict-aliasing', language: 'cpp') 99 100# Some (stupid) GCC versions warn about unused return values even when they are 101# casted to void. This makes -Wunused-result pretty useless, since there is no 102# way to suppress the warning when we really *want* to ignore the value. 103code = ''' 104__attribute__((warn_unused_result)) int get_4() { 105 return 4; 106} 107int main(void) { 108 (void) get_4(); 109 return 0; 110}''' 111if not cc.compiles(code, args: [ '-O0', '-Werror=unused-result' ]) 112 message('Compiler warns about unused result even when casting to void') 113 add_project_arguments('-Wno-unused-result', language: 'c') 114endif 115 116# It is hard to detect if the libc supports versioned symbols. Only gnu-libc 117# seems to provide that, but then glibc is the main target for libfuse, so 118# enable it by default 119versioned_symbols = 1 120 121# This is an attempt to detect if another libc is used. 122code = ''' 123int main(void) { 124#if (defined(__UCLIBC__) || defined(__APPLE__)) 125#error /* libc does not have versioned symbols */ 126#endif 127 return 0; 128}''' 129if not cc.compiles(code, args: [ '-O0' ]) 130 versioned_symbols = 0 131endif 132 133# The detection can be overridden, which is useful for other (above unhandled) 134# libcs and also especially useful for testing 135if get_option('disable-libc-symbol-version') 136 versioned_symbols = 0 137endif 138 139if versioned_symbols == 1 140 message('Enabling versioned libc symbols') 141 public_cfg.set('LIBFUSE_BUILT_WITH_VERSIONED_SYMBOLS', 1) 142 143 # gcc-10 and newer support the symver attribute which we need to use if we 144 # want to support LTO 145 # recent clang and gcc both support __has_attribute (and if they are too old 146 # to have __has_attribute, then they are too old to support symver) 147 # other compilers might not have __has_attribute, but in those cases 148 # it is safe for this check to fail and for us to fallback to the old _asm_ 149 # method for symver. Anyway the attributes not supported by __has_attribute() 150 # unfortunately return true giving a false positive. So let's try to build 151 # using __attribute__ ((symver )) and see the result. 152 code = ''' 153 __attribute__ ((symver ("test@TEST"))) 154 void foo(void) { 155 } 156 157 int main(void) { 158 return 0; 159 }''' 160 if cc.compiles(code, args: [ '-O0', '-c', '-Werror']) 161 message('Compiler supports symver attribute') 162 add_project_arguments('-DHAVE_SYMVER_ATTRIBUTE', language: 'c') 163 else 164 message('Compiler does not support symver attribute') 165 endif 166else 167 message('Disabling versioned libc symbols') 168endif 169 170# Older versions of musl libc don't unescape entries in /etc/mtab 171# Try to detect this behaviour, and work around, if necessary. 172detect_getmntent_needs_unescape = ''' 173#define _GNU_SOURCE 174#include <mntent.h> 175#include <stdio.h> 176#include <string.h> 177#include <stdlib.h> 178 179#define dir_space_tab "dir\\040space\\011tab" 180 181int main() 182{ 183 const char *fake_mtab = "name " dir_space_tab " type opts 0 0\n"; 184 FILE *f = fmemopen((void *)fake_mtab, strlen(fake_mtab) + 1, "r"); 185 struct mntent *entp = getmntent(f); 186 fclose(f); 187 if(NULL == entp) 188 exit(EXIT_FAILURE); 189 if (0 == strcmp(entp->mnt_dir, dir_space_tab)) 190 printf("needs escaping\n"); 191 else 192 printf("no need to escape\n"); 193} 194''' 195 196if not meson.is_cross_build() 197 result = cc.run(detect_getmntent_needs_unescape) 198 if result.compiled() and result.returncode() == 0 and result.stdout().strip() == 'needs escaping' 199 message('getmntent does not unescape') 200 add_project_arguments('-DGETMNTENT_NEEDS_UNESCAPING', language: 'c') 201 endif 202endif 203 204# Write private test results into fuse_config.h (stored in build directory) 205configure_file(output: 'fuse_config.h', configuration : private_cfg) 206 207# Write the test results, installed with the package, 208# symbols need to be properly prefixed to avoid 209# symbol (define) conflicts 210configure_file(output: 'libfuse_config.h', 211 configuration : public_cfg, 212 install: true, install_dir: join_paths(get_option('includedir'), 'fuse3')) 213 214# '.' will refer to current build directory, which contains config.h 215include_dirs = include_directories('include', 'lib', '.') 216 217# Common dependencies 218thread_dep = dependency('threads') 219 220# 221# Read build files from sub-directories 222# 223subdirs = [ 'lib', 'include'] 224if get_option('utils') and not platform.endswith('bsd') and platform != 'dragonfly' 225 subdirs += [ 'util', 'doc' ] 226endif 227 228if get_option('examples') 229 subdirs += 'example' 230endif 231 232if get_option('tests') 233 subdirs += 'test' 234endif 235 236foreach n : subdirs 237 subdir(n) 238endforeach 239 240