397 lines
13 KiB
Meson
397 lines
13 KiB
Meson
# Copyright 2020 - 2025, project-repo and the cagebreak contributors
|
|
# SPDX-License-Identifier: MIT
|
|
project(
|
|
'nedm',
|
|
'c',
|
|
version : '3.0.1',
|
|
license : 'MIT',
|
|
default_options : ['c_std=c23,c11', 'warning_level=3']
|
|
)
|
|
|
|
add_project_arguments(
|
|
[
|
|
'-DWLR_USE_UNSTABLE',
|
|
'-Werror=implicit-function-declaration',
|
|
'-Wundef',
|
|
],
|
|
language: 'c',
|
|
)
|
|
|
|
if get_option('buildtype').startswith('debug')
|
|
add_project_arguments(
|
|
[
|
|
'-DDEBUG',
|
|
],
|
|
language : 'c',
|
|
)
|
|
endif
|
|
|
|
cc = meson.get_compiler('c')
|
|
|
|
fuzz_compile_args = []
|
|
fuzz_link_args = []
|
|
if get_option('fuzz')
|
|
fuzzing_engine = meson.get_compiler('c').find_library('Fuzzer', required : false)
|
|
if fuzzing_engine.found()
|
|
fuzz_compile_args += '-fsanitize-coverage=trace-pc-guard,trace-cmp'
|
|
elif cc.has_argument('-fsanitize=fuzzer-no-link')
|
|
fuzz_compile_args += '-fsanitize=fuzzer-no-link'
|
|
fuzz_link_args += '-fsanitize=fuzzer-no-link'
|
|
else
|
|
error('Looks like neither libFuzzer nor -fsanitize=fuzzer-no-link is supported. Disable fuzzing using -Dfuzz=false to build without fuzzers.')
|
|
endif
|
|
endif
|
|
|
|
is_freebsd = host_machine.system().startswith('freebsd')
|
|
if is_freebsd
|
|
add_project_arguments(
|
|
[
|
|
'-Wno-format-extra-args',
|
|
'-Wno-gnu-zero-variadic-macro-arguments',
|
|
],
|
|
language: 'c'
|
|
)
|
|
endif
|
|
|
|
wlroots = dependency('wlroots-0.19')
|
|
wayland_protos = dependency('wayland-protocols', version: '>=1.14')
|
|
wayland_server = dependency('wayland-server')
|
|
wayland_cursor = dependency('wayland-cursor')
|
|
wayland_client = dependency('wayland-client')
|
|
xkbcommon = dependency('xkbcommon')
|
|
cairo = dependency('cairo')
|
|
pango = dependency('pango')
|
|
pangocairo = dependency('pangocairo')
|
|
fontconfig = dependency('fontconfig')
|
|
libinput = dependency('libinput')
|
|
libevdev = dependency('libevdev')
|
|
libudev = dependency('libudev')
|
|
math = cc.find_library('m')
|
|
|
|
wl_protocol_dir = wayland_protos.get_variable(pkgconfig : 'pkgdatadir')
|
|
wayland_scanner = find_program('wayland-scanner')
|
|
wayland_scanner_server = generator(
|
|
wayland_scanner,
|
|
output: '@BASENAME@-protocol.h',
|
|
arguments: ['server-header', '@INPUT@', '@OUTPUT@'],
|
|
)
|
|
|
|
server_protocols = [
|
|
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
|
['protocols', 'wlr-layer-shell-unstable-v1.xml'],
|
|
]
|
|
|
|
server_protos_headers = []
|
|
|
|
foreach p : server_protocols
|
|
xml = join_paths(p)
|
|
server_protos_headers += wayland_scanner_server.process(xml)
|
|
endforeach
|
|
|
|
server_protos = declare_dependency(
|
|
sources: server_protos_headers,
|
|
)
|
|
|
|
if get_option('xwayland')
|
|
wlroots_has_xwayland = cc.get_define('WLR_HAS_XWAYLAND', prefix: '#include <wlr/config.h>', dependencies: wlroots) == '1'
|
|
if not wlroots_has_xwayland
|
|
error('Cannot build Cagebreak with XWayland support: wlroots has been built without it')
|
|
else
|
|
have_xwayland = true
|
|
endif
|
|
else
|
|
have_xwayland = false
|
|
endif
|
|
|
|
fanalyzer_compile_flag=[]
|
|
if cc.has_argument('-fanalyzer')
|
|
have_fanalyze=true
|
|
fanalyzer_compile_flag=[ '-fanalyzer' ]
|
|
else
|
|
have_fanalyze=false
|
|
endif
|
|
|
|
if get_option('version_override') != ''
|
|
version = '@0@'.format(get_option('version_override'))
|
|
else
|
|
version = '@0@'.format(meson.project_version())
|
|
endif
|
|
|
|
conf_data = configuration_data()
|
|
conf_data.set10('NEDM_HAS_XWAYLAND', have_xwayland)
|
|
conf_data.set10('NEDM_HAS_FANALYZE', have_fanalyze)
|
|
conf_data.set_quoted('NEDM_VERSION', version)
|
|
|
|
|
|
nedm_main_file = [ 'nedm.c', ]
|
|
nedm_source_strings = [
|
|
'idle_inhibit_v1.c',
|
|
'input_manager.c',
|
|
'ipc_server.c',
|
|
'keybinding.c',
|
|
'layer_shell.c',
|
|
'workspace.c',
|
|
'output.c',
|
|
'parse.c',
|
|
'seat.c',
|
|
'status_bar.c',
|
|
'util.c',
|
|
'view.c',
|
|
'wallpaper.c',
|
|
'xdg_shell.c',
|
|
'libinput.c',
|
|
'server.c',
|
|
'message.c',
|
|
'pango.c',
|
|
]
|
|
|
|
nedm_header_strings = [
|
|
'idle_inhibit_v1.h',
|
|
'ipc_server.h',
|
|
'keybinding.h',
|
|
'layer_shell.h',
|
|
'workspace.h',
|
|
'output.h',
|
|
'parse.h',
|
|
'seat.h',
|
|
'server.h',
|
|
'status_bar.h',
|
|
'util.h',
|
|
'view.h',
|
|
'wallpaper.h',
|
|
'xdg_shell.h',
|
|
'pango.h',
|
|
'message.h',
|
|
]
|
|
|
|
if conf_data.get('NEDM_HAS_XWAYLAND', 0) == 1
|
|
nedm_source_strings += 'xwayland.c'
|
|
nedm_header_strings += 'xwayland.h'
|
|
endif
|
|
|
|
nedm_sources = [
|
|
configure_file(input: 'config.h.in',
|
|
output: 'config.h',
|
|
configuration: conf_data),
|
|
]
|
|
|
|
nedm_headers = []
|
|
|
|
foreach source : nedm_source_strings
|
|
nedm_sources += files(source)
|
|
endforeach
|
|
|
|
foreach header : nedm_header_strings
|
|
nedm_headers += files(header)
|
|
endforeach
|
|
# Dependencies marked with "true" are required to have
|
|
# the version specified below in order for the build
|
|
# to be reproducible.
|
|
nedm_dependencies_dict = {
|
|
'server_protos': [server_protos,true],
|
|
'wayland_server': [wayland_server,false],
|
|
'wayland_client': [wayland_client,true],
|
|
'wayland_cursor': [wayland_cursor,true],
|
|
'wlroots': [wlroots,true],
|
|
'xkbcommon': [xkbcommon,true],
|
|
'fontconfig': [fontconfig,true],
|
|
'libinput': [libinput,true],
|
|
'libevdev': [libevdev,true],
|
|
'libudev': [libudev,true],
|
|
'pango': [pango,true],
|
|
'cairo': [cairo,true],
|
|
'pangocairo': [pangocairo,true],
|
|
'math': [math,true],
|
|
}
|
|
|
|
reproducible_build_versions = {
|
|
'server_protos': '-1',
|
|
'wayland_server': '1.19.0',
|
|
'wayland_client': '1.23.1',
|
|
'wayland_cursor': '1.23.1',
|
|
'wlroots': '0.19.0',
|
|
'xkbcommon': '1.10.0',
|
|
'fontconfig': '2.17.1',
|
|
'libinput': '1.28.1',
|
|
'libevdev': '1.13.4',
|
|
'libudev': '257',
|
|
'pango': '1.56.4',
|
|
'cairo': '1.18.4',
|
|
'pangocairo': '1.56.4',
|
|
'math': '-1'
|
|
}
|
|
|
|
nedm_dependencies = []
|
|
|
|
foreach name, dep : nedm_dependencies_dict
|
|
nedm_dependencies += dep[0]
|
|
endforeach
|
|
|
|
foreach name, dep : nedm_dependencies_dict
|
|
if reproducible_build_versions[name] != '-1'
|
|
if dep[1] == false
|
|
if dep[0].version() < reproducible_build_versions[name]
|
|
warning('The installed version of "' + name + '" on your machine (' + dep[0].version() + ') is older than the one used to generate the binary specified in Hashes.md (' + reproducible_build_versions[name] + '). It is recommended to use an up-to-date version for compiling cagebreak.'
|
|
)
|
|
endif
|
|
elif reproducible_build_versions[name] != dep[0].version()
|
|
warning('The installed version of "' + name + '" on your machine (' + dep[0].version() + ') differs from the one used to generate the binary specified in Hashes.md (' + reproducible_build_versions[name] + '). Cagebreak does not guarantee a reproducible build for this configuration.'
|
|
)
|
|
break
|
|
endif
|
|
endif
|
|
endforeach
|
|
|
|
reproducible_build_compiler = 'gcc'
|
|
reproducible_build_compiler_version = '15.1.1'
|
|
|
|
if cc.get_id() != reproducible_build_compiler
|
|
warning('The compiler "' + cc.get_id() + '" differs from the one used to generate to binary specified in Hashes.md (' + reproducible_build_compiler + ').')
|
|
elif cc.version() != reproducible_build_compiler_version
|
|
warning('The version of ' + cc.get_id() + ' (' + cc.version() + ') differs from the one used to generate the binary specified in Hashes.md ' + reproducible_build_compiler_version + '.')
|
|
endif
|
|
|
|
executable(
|
|
meson.project_name(),
|
|
nedm_main_file + nedm_sources + nedm_headers,
|
|
dependencies: nedm_dependencies,
|
|
install: true,
|
|
link_args: fuzz_link_args+fanalyzer_compile_flag,
|
|
c_args: fuzz_compile_args,
|
|
)
|
|
|
|
install_data('examples/config', install_dir : '/etc/xdg/cagebreak')
|
|
install_data('LICENSE', install_dir : '/usr/share/licenses/' + meson.project_name() + '/')
|
|
|
|
if get_option('man-pages')
|
|
scdoc = find_program('scdoc')
|
|
secssinceepoch = 1751745126
|
|
shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.full_path())
|
|
sh = find_program('sh')
|
|
mandir1 = join_paths(get_option('mandir'), 'man1')
|
|
mandir5 = join_paths(get_option('mandir'), 'man5')
|
|
mandir7 = join_paths(get_option('mandir'), 'man7')
|
|
|
|
cagebreak_man = custom_target('cagebreak_man',
|
|
output : 'cagebreak.1',
|
|
input : 'man/cagebreak.1.md',
|
|
capture : true,
|
|
command : [sh, '-c', shcommand],
|
|
install: true,
|
|
install_dir: mandir1
|
|
)
|
|
|
|
cagebreak_man = custom_target('cagebreak_config_man',
|
|
output : 'cagebreak-config.5',
|
|
input : 'man/cagebreak-config.5.md',
|
|
capture : true,
|
|
command : [sh, '-c', shcommand],
|
|
install: true,
|
|
install_dir: mandir5
|
|
)
|
|
|
|
cagebreak_man = custom_target('cagebreak_socket_man',
|
|
output : 'cagebreak-socket.7',
|
|
input : 'man/cagebreak-socket.7.md',
|
|
capture : true,
|
|
command : [sh, '-c', shcommand],
|
|
install: true,
|
|
install_dir: mandir7
|
|
)
|
|
endif
|
|
|
|
fuzz_sources = [
|
|
'fuzz/fuzz-parse.c',
|
|
'fuzz/fuzz-lib.c',
|
|
]
|
|
|
|
fuzz_headers = [
|
|
'parse.h',
|
|
'fuzz/fuzz-lib.h',
|
|
]
|
|
|
|
fuzz_override_lib = [ 'fuzz/execl_override.c' ]
|
|
|
|
if get_option('fuzz')
|
|
inc = include_directories(['.','build/'])
|
|
|
|
fuzz_dependencies = nedm_dependencies
|
|
if fuzzing_engine.found()
|
|
fuzz_dependencies += fuzzing_engine
|
|
else
|
|
link_args = [ '-fsanitize=fuzzer', ]
|
|
endif
|
|
|
|
override_lib = shared_library('execl_override',
|
|
[ fuzz_override_lib ],
|
|
dependencies: [ cairo,pango,pangocairo ],
|
|
install: false
|
|
)
|
|
|
|
executable(
|
|
'fuzz-parse',
|
|
fuzz_sources + fuzz_headers + nedm_headers + nedm_sources,
|
|
dependencies: fuzz_dependencies,
|
|
install: false,
|
|
include_directories: inc,
|
|
link_args: link_args + fuzz_link_args,
|
|
c_args: fuzz_compile_args,
|
|
link_with: override_lib,
|
|
)
|
|
endif
|
|
|
|
summary = [
|
|
'',
|
|
'NEDM @0@'.format(version),
|
|
'',
|
|
' xwayland: @0@'.format(have_xwayland),
|
|
''
|
|
]
|
|
message('\n'.join(summary))
|
|
|
|
run_target('devel-install',
|
|
command : ['scripts/install-development-environment'])
|
|
|
|
run_target('fuzz',
|
|
command : ['scripts/fuzz', get_option('corpus')])
|
|
|
|
run_target('adjust-epoch',
|
|
command : ['scripts/adjust-epoch'])
|
|
|
|
run_target('git-tag',
|
|
command : ['scripts/git-tag', get_option('gpg_id'), meson.project_version()])
|
|
|
|
run_target('output-hashes',
|
|
command : ['scripts/output-hashes', meson.project_version()])
|
|
|
|
run_target('create-sigs',
|
|
command : ['scripts/create-signatures', get_option('gpg_id')])
|
|
|
|
run_target('set-ver',
|
|
command : ['scripts/set-version', meson.project_version()])
|
|
|
|
run_target('create-artefacts',
|
|
command : ['scripts/create-release-artefacts', get_option('gpg_id'), meson.project_version()])
|
|
|
|
# Test Suite
|
|
|
|
test('Build without warnings', find_program('test/build-w-o-warnings'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel')
|
|
test('Example script header is consistent', find_program('test/script-header'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel')
|
|
test('Script executability is consistent', find_program('test/script-header'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel')
|
|
test('Man page consistency', find_program('test/man-pages'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel')
|
|
test('Build without xwayland', find_program('test/build-w-o-xwayland'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel')
|
|
test('Copyright and LICENSE', find_program('test/copyright-license'), args : [ nedm_main_file + nedm_source_strings + nedm_header_strings + fuzz_sources + fuzz_headers + fuzz_override_lib ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()), ''.join('MESONLICENSE=', meson.project_license())], suite: 'devel' )
|
|
test('Formatting check (clang-format)', find_program('test/clang-format'), args : [ nedm_main_file + nedm_source_strings + nedm_header_strings + fuzz_sources + fuzz_headers + fuzz_override_lib ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel')
|
|
test('Script linting (shellcheck)', find_program('test/shellcheck'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel')
|
|
test('GPG key validity', find_program('test/gpg-validity'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel')
|
|
test('Illegal Strings', find_program('test/illegal-strings'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel')
|
|
test('Static analysis (scan-build)', find_program('test/scan-build'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel-long')
|
|
test('Arguments', find_program('test/arguments'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'basic')
|
|
test('Environment Variables', find_program('test/environment-variables'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'basic')
|
|
test('Semantic versioning', find_program('test/versions'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'release')
|
|
test('Signature validity', find_program('test/gpg-signatures'), suite: 'release')
|
|
test('Hashes.md', find_program('test/hashes-md'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'release')
|
|
test('Non-auto tests', find_program('test/non-auto-tests'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'release')
|
|
test('Git tag', find_program('test/git-tag'), args : [ meson.project_version() ], suite: 'release')
|
|
test('Release-artefacts', find_program('test/check-artefacts'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'release')
|