Skip to content

Commit 45d6530

Browse files
committed
Add a Meson build system
This allows bwrap to be built as a subproject in larger Meson projects. When built as a subproject, we install into the --libexecdir and require a program prefix to be specified: for example, Flatpak would use program_prefix=flatpak- to get /usr/libexec/flatpak-bwrap. One feature that is deliberately missing is an equivalent of --with-priv-mode=setuid. On distributions like Debian <= 10 that still require a setuid bwrap, the sysadmin or distribution packaging will need to set the correct permissions on the bwrap executable; Debian already did this in the packaging rather than the upstream build system. Loosely based on previous work by Jussi Pakkanen (see containers#133). Signed-off-by: Simon McVittie <[email protected]>
1 parent 43c2d32 commit 45d6530

File tree

13 files changed

+401
-1
lines changed

13 files changed

+401
-1
lines changed

.github/workflows/check.yml

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ on:
1010

1111
jobs:
1212
check:
13-
name: Build with gcc and test
13+
name: Build with Autotools and gcc, and test
1414
runs-on: ubuntu-latest
1515
steps:
1616
- name: Check out
@@ -69,6 +69,71 @@ jobs:
6969
run: |
7070
make -C _build -j $(getconf _NPROCESSORS_ONLN) distcheck VERBOSE=1 BWRAP_MUST_WORK=1
7171
72+
meson:
73+
name: Build with Meson and gcc, and test
74+
runs-on: ubuntu-latest
75+
steps:
76+
- name: Check out
77+
uses: actions/checkout@v1
78+
- name: Install build-dependencies
79+
run: sudo ./ci/builddeps.sh
80+
- name: Create logs dir
81+
run: mkdir test-logs
82+
- name: setup
83+
run: |
84+
meson _build
85+
env:
86+
CFLAGS: >-
87+
-O2
88+
-Wp,-D_FORTIFY_SOURCE=2
89+
-fsanitize=address
90+
-fsanitize=undefined
91+
- name: compile
92+
run: ninja -C _build -v
93+
- name: smoke-test
94+
run: |
95+
set -x
96+
./_build/bwrap --bind / / --tmpfs /tmp true
97+
env:
98+
ASAN_OPTIONS: detect_leaks=0
99+
- name: test
100+
run: |
101+
BWRAP_MUST_WORK=1 meson test -C _build
102+
env:
103+
ASAN_OPTIONS: detect_leaks=0
104+
- name: Collect overall test logs on failure
105+
if: failure()
106+
run: mv _build/meson-logs/testlog.txt test-logs/ || true
107+
- name: install
108+
run: |
109+
DESTDIR="$(pwd)/DESTDIR" meson install -C _build
110+
( cd DESTDIR && find -ls )
111+
- name: dist
112+
run: |
113+
BWRAP_MUST_WORK=1 meson dist -C _build
114+
- name: Collect dist test logs on failure
115+
if: failure()
116+
run: mv _build/meson-private/dist-build/meson-logs/testlog.txt test-logs/disttestlog.txt || true
117+
- name: use as subproject
118+
run: |
119+
mkdir tests/use-as-subproject/subprojects
120+
tar -C tests/use-as-subproject/subprojects -xf _build/meson-dist/bubblewrap-*.tar.xz
121+
mv tests/use-as-subproject/subprojects/bubblewrap-* tests/use-as-subproject/subprojects/bubblewrap
122+
( cd tests/use-as-subproject && meson _build )
123+
ninja -C tests/use-as-subproject/_build -v
124+
meson test -C tests/use-as-subproject/_build
125+
DESTDIR="$(pwd)/DESTDIR-as-subproject" meson install -C tests/use-as-subproject/_build
126+
( cd DESTDIR-as-subproject && find -ls )
127+
test -x DESTDIR-as-subproject/usr/local/libexec/not-flatpak-bwrap
128+
test ! -e DESTDIR-as-subproject/usr/local/bin/bwrap
129+
test ! -e DESTDIR-as-subproject/usr/local/libexec/bwrap
130+
- name: Upload test logs
131+
uses: actions/upload-artifact@v1
132+
if: failure() || cancelled()
133+
with:
134+
name: test logs
135+
path: test-logs
136+
72137
clang:
73138
name: Build with clang and analyze
74139
runs-on: ubuntu-latest

Makefile.am

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,19 @@ EXTRA_DIST = \
55
.editorconfig \
66
README.md \
77
autogen.sh \
8+
completions/bash/meson.build \
9+
completions/meson.build \
10+
completions/zsh/meson.build \
811
demos/bubblewrap-shell.sh \
912
demos/flatpak-run.sh \
1013
demos/flatpak.bpf \
1114
demos/userns-block-fd.py \
15+
meson.build \
16+
meson_options.txt \
1217
packaging/bubblewrap.spec \
18+
tests/use-as-subproject/config.h \
19+
tests/use-as-subproject/dummy-config.h.in \
20+
tests/use-as-subproject/meson.build \
1321
uncrustify.cfg \
1422
uncrustify.sh \
1523
$(NULL)

ci/builddeps.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ if dpkg-vendor --derives-from Debian; then
6464
libcap-dev \
6565
libselinux1-dev \
6666
libtool \
67+
meson \
6768
pkg-config \
6869
python3 \
6970
xsltproc \
@@ -92,6 +93,7 @@ if command -v yum; then
9293
libubsan \
9394
libxslt \
9495
make \
96+
meson \
9597
redhat-rpm-config \
9698
rsync \
9799
${NULL+}

completions/bash/meson.build

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
bash_completion_dir = get_option('bash_completion_dir')
2+
3+
if bash_completion_dir == ''
4+
bash_completion = dependency(
5+
'bash-completion',
6+
version : '>=2.0',
7+
required : false,
8+
)
9+
10+
if bash_completion.found()
11+
if meson.version().version_compare('>=0.51.0')
12+
bash_completion_dir = bash_completion.get_variable(
13+
default_value: '',
14+
pkgconfig: 'completionsdir',
15+
pkgconfig_define: [
16+
'prefix', get_option('prefix'),
17+
'datadir', get_option('prefix') / get_option('datadir'),
18+
],
19+
)
20+
else
21+
bash_completion_dir = bash_completion.get_pkgconfig_variable(
22+
'completionsdir',
23+
default: '',
24+
define_variable: [
25+
'prefix', get_option('prefix'),
26+
'datadir', get_option('prefix') / get_option('datadir'),
27+
],
28+
)
29+
endif
30+
endif
31+
endif
32+
33+
if bash_completion_dir == ''
34+
bash_completion_dir = get_option('datadir') / 'bash-completion' / 'completions'
35+
endif
36+
37+
install_data('bwrap', install_dir : bash_completion_dir)

completions/meson.build

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
if get_option('bash_completion').enabled()
2+
subdir('bash')
3+
endif
4+
5+
if get_option('zsh_completion').enabled()
6+
subdir('zsh')
7+
endif

completions/zsh/meson.build

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
zsh_completion_dir = get_option('zsh_completion_dir')
2+
3+
if zsh_completion_dir == ''
4+
zsh_completion_dir = get_option('datadir') / 'zsh' / 'site-functions'
5+
endif
6+
7+
install_data('_bwrap', install_dir : zsh_completion_dir)

meson.build

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
project(
2+
'bubblewrap',
3+
'c',
4+
version : '0.5.0',
5+
meson_version : '>=0.49.0',
6+
default_options : [
7+
'warning_level=2',
8+
],
9+
)
10+
11+
cc = meson.get_compiler('c')
12+
add_project_arguments('-D_GNU_SOURCE', language : 'c')
13+
14+
# Keep this in sync with ostree, except remove -Werror=declaration-after-statement
15+
add_project_arguments(
16+
cc.get_supported_arguments([
17+
'-Werror=shadow',
18+
'-Werror=empty-body',
19+
'-Werror=strict-prototypes',
20+
'-Werror=missing-prototypes',
21+
'-Werror=implicit-function-declaration',
22+
'-Werror=pointer-arith',
23+
'-Werror=init-self',
24+
'-Werror=missing-declarations',
25+
'-Werror=return-type',
26+
'-Werror=overflow',
27+
'-Werror=int-conversion',
28+
'-Werror=parenthesis',
29+
'-Werror=incompatible-pointer-types',
30+
'-Werror=misleading-indentation',
31+
'-Werror=missing-include-dirs',
32+
'-Werror=aggregate-return',
33+
34+
# Extra warnings specific to bubblewrap
35+
'-Werror=switch-default',
36+
'-Wswitch-enum',
37+
38+
# we are not fully signedness-safe yet
39+
'-Wno-sign-compare',
40+
'-Wno-error=sign-compare',
41+
42+
# deliberately not warning about these
43+
'-Wno-missing-field-initializers',
44+
'-Wno-error=missing-field-initializers',
45+
]),
46+
language : 'c',
47+
)
48+
49+
if (
50+
cc.has_argument('-Werror=format=2')
51+
and cc.has_argument('-Werror=format-security')
52+
and cc.has_argument('-Werror=format-nonliteral')
53+
)
54+
add_project_arguments([
55+
'-Werror=format=2',
56+
'-Werror=format-security',
57+
'-Werror=format-nonliteral',
58+
], language : 'c')
59+
endif
60+
61+
sh = find_program('sh', required : true)
62+
bash = find_program('bash', required : false)
63+
64+
libcap_dep = dependency('libcap', required : false)
65+
if not libcap_dep.found()
66+
libcap_dep = cc.find_library('cap', required : true)
67+
endif
68+
assert(cc.has_header('sys/capability.h'), 'POSIX caps headers not found')
69+
70+
selinux_dep = dependency(
71+
'libselinux',
72+
version : '>=2.1.9',
73+
# if disabled, Meson will behave as though libselinux was not found
74+
required : get_option('selinux'),
75+
)
76+
77+
cdata = configuration_data()
78+
cdata.set_quoted('PACKAGE_STRING', 'bubblewrap')
79+
80+
if selinux_dep.found()
81+
cdata.set('HAVE_SELINUX', 1)
82+
if selinux_dep.version().version_compare('>=2.3')
83+
cdata.set('HAVE_SELINUX_2_3', 1)
84+
endif
85+
endif
86+
87+
if get_option('require_userns')
88+
cdata.set('ENABLE_REQUIRE_USERNS', 1)
89+
endif
90+
91+
configure_file(
92+
output : 'config.h',
93+
configuration : cdata,
94+
)
95+
96+
if meson.is_subproject()
97+
bwrapdir = get_option('libexecdir')
98+
99+
if get_option('program_prefix') == ''
100+
error('program_prefix option must be set when bwrap is a subproject')
101+
endif
102+
else
103+
bwrapdir = get_option('bindir')
104+
endif
105+
106+
bwrap = executable(
107+
get_option('program_prefix') + 'bwrap',
108+
[
109+
'bubblewrap.c',
110+
'bind-mount.c',
111+
'network.c',
112+
'utils.c',
113+
],
114+
install : true,
115+
install_dir : bwrapdir,
116+
dependencies : [selinux_dep, libcap_dep],
117+
)
118+
119+
xsltproc = find_program('xsltproc', required : get_option('man'))
120+
121+
if xsltproc.found() and not meson.is_subproject()
122+
custom_target(
123+
'bwrap.1',
124+
output : 'bwrap.1',
125+
input : 'bwrap.xml',
126+
command : [
127+
xsltproc,
128+
'--nonet',
129+
'--stringparam', 'man.output.quietly', '1',
130+
'--stringparam', 'funcsynopsis.style', 'ansi',
131+
'--stringparam', 'man.th.extra1.suppress', '1',
132+
'--stringparam', 'man.authors.section.enabled', '0',
133+
'--stringparam', 'man.copyright.section.enabled', '0',
134+
'-o', '@OUTPUT@',
135+
'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl',
136+
'@INPUT@',
137+
],
138+
install : true,
139+
install_dir : get_option('mandir') / 'man1',
140+
)
141+
endif
142+
143+
if not meson.is_subproject()
144+
subdir('completions')
145+
endif

meson_options.txt

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
option(
2+
'bash_completion',
3+
type : 'feature',
4+
description : 'install bash completion script',
5+
value : 'enabled',
6+
)
7+
option(
8+
'bash_completion_dir',
9+
type : 'string',
10+
description : 'install bash completion script in this directory',
11+
value : '',
12+
)
13+
option(
14+
'man',
15+
type : 'feature',
16+
description : 'generate man pages',
17+
value : 'auto',
18+
)
19+
option(
20+
'program_prefix',
21+
type : 'string',
22+
description : 'Prepend string to bwrap executable name, for use with subprojects',
23+
)
24+
option(
25+
'require_userns',
26+
type : 'boolean',
27+
description : 'require user namespaces by default when installed setuid',
28+
value : 'false',
29+
)
30+
option(
31+
'selinux',
32+
type : 'feature',
33+
description : 'enable optional SELINUX support',
34+
value : 'auto',
35+
)
36+
option(
37+
'zsh_completion',
38+
type : 'feature',
39+
description : 'install zsh completion script',
40+
value : 'enabled',
41+
)
42+
option(
43+
'zsh_completion_dir',
44+
type : 'string',
45+
description : 'install zsh completion script in this directory',
46+
value : '',
47+
)

0 commit comments

Comments
 (0)