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