aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Nikolaus Rath <Nikolaus@rath.org>2017-01-05 09:37:00 -0800
committerGravatar Nikolaus Rath <Nikolaus@rath.org>2017-01-12 15:19:04 -0800
commit9f96db71252fc66b72c433e2ca0d49e031c6a5fd (patch)
tree494132dae14dba3de18a9013f2299cfc37cceda5
parent3006686b536942f6f96675e3d12b793087e78e6a (diff)
Added experimental support for building with Meson+Ninja
-rw-r--r--.gitignore1
-rw-r--r--ChangeLog.rst2
-rw-r--r--Makefile.am21
-rw-r--r--README.md61
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/meson.build5
-rw-r--r--example/Makefile.am2
-rw-r--r--example/meson.build29
-rw-r--r--include/Makefile.am2
-rw-r--r--include/meson.build8
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/meson.build47
-rw-r--r--meson.build90
-rw-r--r--meson_options.txt2
-rw-r--r--test/Makefile.am5
-rw-r--r--test/meson.build35
-rwxr-xr-xtest/test_examples.py2
-rw-r--r--test/test_syscalls.c (renamed from test/test.c)0
-rw-r--r--test/util.py7
-rw-r--r--test/wrong_command.c10
-rw-r--r--util/Makefile.am2
-rwxr-xr-xutil/install_helper.sh32
-rw-r--r--util/meson.build27
23 files changed, 348 insertions, 46 deletions
diff --git a/.gitignore b/.gitignore
index 619131a..0da3051 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,3 +40,4 @@ TAGS
/GSYMS
/GTAGS
/test/test_setattr
+/build/
diff --git a/ChangeLog.rst b/ChangeLog.rst
index b8ad5e1..2cabd7d 100644
--- a/ChangeLog.rst
+++ b/ChangeLog.rst
@@ -2,7 +2,7 @@ libfuse 3.1.0 (UNRELEASED)
==========================
* Re-introduced examples/null.c.
-
+* Added experimental support for building with Meson.
libfuse 3.0.0 (2016-12-08)
==========================
diff --git a/Makefile.am b/Makefile.am
index 4e95a71..b2ba4b2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,26 +8,11 @@ EXTRA_DIST = \
fuse3.pc.in \
README* \
test/*.py \
- test/pytest.ini
+ test/pytest.ini \
+ meson.build \
+ meson_options.txt
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = fuse3.pc
$(pkgconfig_DATA): config.status
-
-.PHONY: setuid_fusermount
-setuid_fusermount:
- @echo "Attempting to use sudo to make util/fusermount3 setuid root"
- @echo "If this fails, set permissions manually and re-run make test"
- test $$(ls -n util/fusermount3 | awk 'NR==1 {print $$3}') -eq 0 || \
- sudo chown root util/fusermount3
- test -u util/fusermount3 || \
- sudo chmod u+s util/fusermount3
-
-# If we are not root, util/fusermount3 needs to be setuid root
-# for tests to work.
-
-test_deps = $(shell [ "$${UID}" -eq 0 ] || echo setuid_fusermount)
-.PHONY: test
-test: all $(test_deps)
- python3 -m pytest test/
diff --git a/README.md b/README.md
index 8201eeb..be2e52e 100644
--- a/README.md
+++ b/README.md
@@ -28,33 +28,58 @@ Installation
------------
You can download libfuse from
-https://github.com/libfuse/libfuse/releases. After extracting the
-tarball, build and install with
+https://github.com/libfuse/libfuse/releases. To build and install, we
+recommend to use [Meson](http://mesonbuild.com/) and
+[Ninja](https://ninja-build.org). After extracting the libfuse
+tarball, create a (temporary) build directory and run Meson:
- ./configure
- make -j8
- make install
+ $ md build; cd build
+ $ meson ..
-To run some self tests, you need a Python 3 environment with the
-[py.test](http://www.pytest.org/) module installed. To run the tests,
-execute
+Normally, the default build options will work fine. If you
+nevertheless want to adjust them, you can do so with the *mesonconf*
+command:
- python3 -m pytest test/
+ $ mesonconf # list options
+ $ mesonconf -D disable-mtab=true # set an option
-You may also need to add `/usr/local/lib` to `/etc/ld.so.conf` and/or
-run *ldconfig*. If you're building from the git repository (instead of
-using a release tarball), you also need to run `./makeconf.sh` to
-create the `configure` script.
+To build, test and install libfuse, you then use Ninja:
+
+ $ ninja
+ $ sudo ninja tests # requires pytest, see below
+ $ sudo ninja install
+
+Running the tests requires the [py.test](http://www.pytest.org/)
+Python module. Instead of running the tests as root, the majority of
+tests can also be run as a regular user if *util/fusermount3* is
+made setuid root first:
+
+ $ sudo chown root:root util/fusermount3
+ $ sudo chmod 4755 util/fusermount3
+ $ ninja tests
+
+
+Alternate Installation
+----------------------
+
+If you are not able to use Meson and Ninja, please report this to the
+libfuse mailing list. Until the problem is resolved, you may fall back
+to an in-source build using autotools:
+
+ $ ./configure
+ $ make
+ $ sudo make install
+
+Note that support for building with autotools may disappear at some
+point, so if you depend on using autotools for some reason please let
+the libfuse developers know!
-You'll also need a fuse kernel module (Linux kernels 2.6.14 or later
-contain FUSE support).
Security implications
---------------------
-If you run `make install`, the *fusermount3* program is installed
-set-user-id to root. This is done to allow normal users to mount
-their own filesystem implementations.
+The *fusermount3* program is installed setuid root. This is done to
+allow normal users to mount their own filesystem implementations.
To limit the harm that malicious users can do this way, *fusermount3*
enforces the following limitations:
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 8801da2..531a6c4 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -2,4 +2,4 @@
dist_man_MANS = fusermount3.1 mount.fuse.8
-EXTRA_DIST = kernel.txt Doxyfile html README.NFS
+EXTRA_DIST = kernel.txt Doxyfile html README.NFS meson.build
diff --git a/doc/meson.build b/doc/meson.build
new file mode 100644
index 0000000..eb81f3d
--- /dev/null
+++ b/doc/meson.build
@@ -0,0 +1,5 @@
+# Attention, emacs, please use -*- mode: python -*-
+# (even though this isn't actually Python code)
+
+install_man('fusermount3.1', 'mount.fuse.8')
+
diff --git a/example/Makefile.am b/example/Makefile.am
index 81b9555..c83c81f 100644
--- a/example/Makefile.am
+++ b/example/Makefile.am
@@ -17,3 +17,5 @@ ioctl_client_LDADD =
poll_client_CPPFLAGS =
poll_client_LDFLAGS =
poll_client_LDADD =
+
+EXTRA_DIST = meson.build
diff --git a/example/meson.build b/example/meson.build
new file mode 100644
index 0000000..4497288
--- /dev/null
+++ b/example/meson.build
@@ -0,0 +1,29 @@
+# Attention, emacs, please use -*- mode: python -*-
+# (even though this isn't actually Python code)
+
+examples = [ 'passthrough', 'passthrough_fh', 'null', 'hello', 'hello_ll',
+ 'ioctl', 'ioctl_client', 'poll_client',
+ 'passthrough_ll', 'cuse', 'cuse_client' ]
+
+threaded_examples = [ 'notify_inval_inode',
+ 'notify_store_retrieve',
+ 'notify_inval_entry',
+ 'poll' ]
+
+foreach ex : examples
+ executable(ex, ex + '.c',
+ include_directories: include_dirs,
+ link_with: [ libfuse ],
+ install: false)
+endforeach
+
+
+foreach ex : threaded_examples
+ executable(ex, ex + '.c',
+ include_directories: include_dirs,
+ link_with: [ libfuse ],
+ dependencies: thread_dep,
+ install: false)
+endforeach
+
+# TODO: Link passthrough_fh with ulockmgr if available
diff --git a/include/Makefile.am b/include/Makefile.am
index ffbfafa..5072cc3 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -10,3 +10,5 @@ fuseinclude_HEADERS = \
cuse_lowlevel.h
noinst_HEADERS = fuse_kernel.h
+
+EXTRA_DIST = meson.build
diff --git a/include/meson.build b/include/meson.build
new file mode 100644
index 0000000..f1fa5f0
--- /dev/null
+++ b/include/meson.build
@@ -0,0 +1,8 @@
+# Attention, emacs, please use -*- mode: python -*-
+# (even though this isn't actually Python code)
+
+libfuse_headers = [ 'fuse.h', 'fuse_common.h', 'fuse_lowlevel.h',
+ 'fuse_opt.h', 'cuse_lowlevel.h' ]
+
+install_headers(libfuse_headers, subdir: 'fuse3')
+
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e7f6fd4..cdacfd5 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -40,4 +40,4 @@ if NETBSD
libfuse3_la_LIBADD = -lperfuse -lpuffs
endif
-EXTRA_DIST = fuse_versionscript
+EXTRA_DIST = fuse_versionscript meson.build
diff --git a/lib/meson.build b/lib/meson.build
new file mode 100644
index 0000000..287dc86
--- /dev/null
+++ b/lib/meson.build
@@ -0,0 +1,47 @@
+# Attention, emacs, please use -*- mode: python -*-
+# (even though this isn't actually Python code)
+
+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' ]
+
+if host_machine.system().startswith('linux')
+ libfuse_sources += [ 'mount.c', 'mount_util.c' ]
+else
+ libfuse_sources += [ 'mount_bsd.c' ]
+endif
+
+if cfg.has('HAVE_ICONV')
+ libfuse_sources += [ 'modules/iconv.c' ]
+endif
+
+deps = [ thread_dep ]
+libdl = meson.get_compiler('c').find_library('dl')
+if libdl.found()
+ deps += [ libdl ]
+endif
+
+if host_machine.system().startswith('netbsd')
+ deps += [ cc.find_library('perfuse'),
+ cc.find_library('puffs') ]
+endif
+
+fusermount_path = join_paths(get_option('prefix'), get_option('bindir'))
+libfuse = library('fuse3', libfuse_sources, version: '3.0.0', install: true,
+ soversion: '3', include_directories: include_dirs,
+ dependencies: deps,
+ link_depends: 'fuse_versionscript',
+ c_args: [ '-DFUSE_USE_VERSION=30',
+ '-DFUSERMOUNT_DIR="{}"'.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')
+
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..0cce4af
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,90 @@
+# Attention, emacs, please use -*- mode: python -*-
+# (even though this isn't actually Python code)
+
+project('libfuse3', 'c', version: '3.1.0',
+ default_options: [ 'buildtype=plain' ])
+
+#
+# Feature detection
+#
+cfg = configuration_data()
+cc = meson.get_compiler('c')
+
+# Default includes when checking for presence of functions and
+# struct members
+include_default = '
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+'
+
+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' ]
+foreach func : test_funcs
+ cfg.set('HAVE_' + func.to_upper(),
+ cc.has_function(func, prefix: include_default))
+endforeach
+cfg.set('HAVE_SETXATTR',
+ cc.has_function('setxattr', prefix: '#include <sys/xattr.h>'))
+cfg.set('HAVE_ICONV',
+ cc.has_function('iconv', prefix: '#include <iconv.h>'))
+
+# Test if structs have specific member
+cfg.set('HAVE_STRUCT_STAT_ST_ATIM',
+ cc.has_member('struct stat', 'st_atim',
+ prefix: include_default))
+cfg.set('HAVE_STRUCT_STAT_ST_ATIMESPEC',
+ cc.has_member('struct stat', 'st_atimespec',
+ prefix: include_default))
+
+# Write the test results into config.h (stored in build directory)
+configure_file(output: 'config.h',
+ configuration : cfg)
+
+
+#
+# Compiler configuration
+#
+add_global_arguments('-D_REENTRANT', '-DHAVE_CONFIG_H', '-Wall', '-Wextra', '-Wno-sign-compare',
+ '-Wstrict-prototypes', '-Wmissing-declarations', '-Wwrite-strings',
+ '-O2', '-g', '-fno-strict-aliasing', language: 'c')
+
+# 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_global_arguments('-Wno-unused-result', language: 'c')
+endif
+
+# current_build_dir() contains config.h
+include_dirs = include_directories('include', 'lib',
+ meson.current_build_dir())
+
+# Common dependencies
+thread_dep = dependency('threads')
+
+#
+# Read build files from sub-directories
+#
+subdirs = [ 'lib', 'include', 'util', 'example', 'doc', 'test' ]
+foreach n : subdirs
+ subdir(n)
+endforeach
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..e53bf5d
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,2 @@
+option('disable-mtab', type : 'boolean', value : false,
+ description: 'Disable and ignore usage of /etc/mtab')
diff --git a/test/Makefile.am b/test/Makefile.am
index 9eb0a73..6bcea43 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,7 +1,10 @@
## Process this file with automake to produce Makefile.in
AM_CPPFLAGS = -I$(top_srcdir)/include -D_REENTRANT
-noinst_PROGRAMS = test test_write_cache test_setattr
+noinst_PROGRAMS = test_syscalls test_write_cache test_setattr
test_write_cache_LDADD = ../lib/libfuse3.la
test_setattr_LDADD = ../lib/libfuse3.la
+
+EXTRA_DIST = meson.build wrong_command.c
+
diff --git a/test/meson.build b/test/meson.build
new file mode 100644
index 0000000..971c64a
--- /dev/null
+++ b/test/meson.build
@@ -0,0 +1,35 @@
+# Attention, emacs, please use -*- mode: python -*-
+# (even though this isn't actually Python code)
+
+# Compile helper programs
+td = []
+foreach prog: [ 'test_write_cache', 'test_setattr' ]
+ td += executable(prog, prog + '.c',
+ include_directories: include_dirs,
+ link_with: [ libfuse ],
+ dependencies: thread_dep,
+ install: false)
+endforeach
+td += executable('test_syscalls', 'test_syscalls.c',
+ include_directories: include_dirs,
+ install: false)
+
+# Actual tests are written in Python and can simply be copied.
+foreach fname : [ 'conftest.py', 'pytest.ini', 'test_examples.py',
+ 'util.py' ]
+ td += custom_target(fname, input: fname, output: fname,
+ command: ['cp', '-fP', '--preserve=mode',
+ '@INPUT@', '@OUTPUT@'])
+endforeach
+
+# Create a new 'tests' target that we can run with Ninja
+run_target('tests', depends: td,
+ command: [ 'python3', '-m', 'pytest',
+ meson.current_build_dir() ])
+
+
+# Provide something helpful when running 'ninja test'
+wrong_cmd = executable('wrong_command', 'wrong_command.c',
+ install: false)
+test('wrong_cmd', wrong_cmd)
+
diff --git a/test/test_examples.py b/test/test_examples.py
index cfd6734..92a67c0 100755
--- a/test/test_examples.py
+++ b/test/test_examples.py
@@ -77,7 +77,7 @@ def test_passthrough(tmpdir, name, debug):
wait_for_mount(mount_process, mnt_dir)
work_dir = pjoin(mnt_dir, src_dir)
- subprocess.check_call([ os.path.join(basename, 'test', 'test'),
+ subprocess.check_call([ os.path.join(basename, 'test', 'test_syscalls'),
work_dir, ':' + src_dir ])
tst_write(work_dir)
diff --git a/test/test.c b/test/test_syscalls.c
index 281f218..281f218 100644
--- a/test/test.c
+++ b/test/test_syscalls.c
diff --git a/test/util.py b/test/util.py
index 6bba9e2..48670bd 100644
--- a/test/util.py
+++ b/test/util.py
@@ -105,7 +105,7 @@ def fuse_test_marker():
return pytest.mark.uses_fuse()
-# If valgrind and libtool are available, use them
+# If valgrind is available, use it
def has_program(name):
try:
ret = subprocess.call([name, '--version'],
@@ -115,9 +115,8 @@ def has_program(name):
return False
return ret == 0
-if has_program('valgrind') and has_program('libtool'):
- base_cmdline = [ 'libtool', '--mode=execute',
- 'valgrind', '-q', '--' ]
+if has_program('valgrind'):
+ base_cmdline = [ 'valgrind', '-q', '--' ]
else:
base_cmdline = []
diff --git a/test/wrong_command.c b/test/wrong_command.c
new file mode 100644
index 0000000..ef835b3
--- /dev/null
+++ b/test/wrong_command.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+int main(void) {
+ fprintf(stderr, "\x1B[31m\e[1m"
+ "This is not the command you are looking for.\n"
+ "You probably want to run 'ninja tests' instead "
+ "(note the 's' at the end).\n"
+ "\e[0m");
+ return 1;
+}
diff --git a/util/Makefile.am b/util/Makefile.am
index 756afea..1eb2ec3 100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -23,7 +23,7 @@ install-exec-hook:
mknod $(DESTDIR)/dev/fuse -m 0666 c 10 229 || true; \
fi
-EXTRA_DIST = udev.rules init_script
+EXTRA_DIST = udev.rules init_script meson.build install_helper.sh
MOUNT_FUSE_PATH = @MOUNT_FUSE_PATH@
UDEV_RULES_PATH = @UDEV_RULES_PATH@
diff --git a/util/install_helper.sh b/util/install_helper.sh
new file mode 100755
index 0000000..fe65c1c
--- /dev/null
+++ b/util/install_helper.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Don't call this script. It is used internally by the Meson
+# build system. Thank you for your cooperation.
+#
+
+set -e
+
+sysconfdir="$1"
+bindir="$2"
+prefix="${MESON_INSTALL_DESTDIR_PREFIX}"
+
+chown root:root "${prefix}/${bindir}/fusermount3"
+chmod u+s "${prefix}/${bindir}/fusermount3"
+
+if test ! -e "${DESTDIR}/dev/fuse"; then
+ mkdir -p "${DESTDIR}/dev"
+ mknod "${DESTDIR}/dev/fuse" -m 0666 c 10 229
+fi
+
+install -D -m 644 "${MESON_SOURCE_ROOT}/util/udev.rules" \
+ "${prefix}/lib/udev/rules.d/99-fuse3.rules"
+
+install -D -m 755 "${MESON_SOURCE_ROOT}/util/init_script" \
+ "${prefix}/${sysconfdir}/init.d/fuse3"
+
+if test -x /usr/sbin/update-rc.d; then
+ # May fail for a DESTDIR installation
+ /usr/sbin/update-rc.d fuse3 start 34 S . start 41 0 6 . || /bin/true
+fi
+
+
diff --git a/util/meson.build b/util/meson.build
new file mode 100644
index 0000000..43c4973
--- /dev/null
+++ b/util/meson.build
@@ -0,0 +1,27 @@
+# Attention, emacs, please use -*- mode: python -*-
+# (even though this isn't actually Python code)
+
+# we re-use mount_util.c from the library, but do want to keep ourself
+# as stand-alone as possible. in order to make an out-of-source build
+# possible, we "generate" the file from its original location by
+# copying it over.
+mount_util_c = custom_target('mount_util',
+ input : '../lib/mount_util.c',
+ output : 'mount_util.c',
+ command : ['cp', '-a', '@INPUT@', '@OUTPUT@'],
+)
+
+executable('fusermount3', ['fusermount.c', mount_util_c],
+ include_directories: include_dirs,
+ install: true,
+ install_dir: get_option('bindir'))
+
+executable('mount.fuse3', ['mount.fuse.c'],
+ include_directories: include_dirs,
+ install: true,
+ install_dir: get_option('sbindir'))
+
+meson.add_install_script('install_helper.sh', get_option('sysconfdir'),
+ get_option('bindir'), get_option('libdir'))
+
+