Merge pull request #611 from lzutao/mesonbuild

Support for Meson build and its CI tests
This commit is contained in:
Yann Collet 2018-12-01 19:35:47 -08:00 committed by GitHub
commit 3b8253a4bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 591 additions and 0 deletions

View File

@ -156,8 +156,26 @@ matrix:
sudo: false
env: Cmd="make -C tests checkTag && tests/checkTag $TRAVIS_BRANCH " COMPILER=cc
- dist: xenial
sudo: required
env: BUILD_SYSTEM='meson'
allow_failures:
- env: BUILD_SYSTEM='meson'
script:
- if [ "${BUILD_SYSTEM}" = meson ]; then
sudo apt-get install -qq python3 tree
&& curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
&& python3 get-pip.py --user && rm get-pip.py
&& pip3 install --user meson ninja
&& meson --buildtype=debug -Dauto_features=enabled -Ddefault_library=both
-Dbuild_{programs,contrib,tests,examples}=true contrib/meson build
&& cd "$_"
&& ninja
&& DESTDIR=./staging ninja install
&& tree ./staging;
travis_terminate "$?";
fi
- uname -a
- echo Cmd=$Cmd
- $COMPILER -v

View File

@ -0,0 +1,45 @@
#!/usr/bin/env python3
# #############################################################################
# Copyright (c) 2018-present lzutao <taolzu(at)gmail.com>
# All rights reserved.
#
# This source code is licensed under both the BSD-style license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# #############################################################################
import re
import sys
def usage():
print('usage: python3 GetLz4LibraryVersion.py <path/to/lz4.h>')
sys.exit(1)
def find_version(filepath):
version_file_data = None
with open(filepath) as fd:
version_file_data = fd.read()
patterns = r"""#\s*define\s+LZ4_VERSION_MAJOR\s+([0-9]+).*$
#\s*define\s+LZ4_VERSION_MINOR\s+([0-9]+).*$
#\s*define\s+LZ4_VERSION_RELEASE\s+([0-9]+).*$
"""
regex = re.compile(patterns, re.MULTILINE)
version_match = regex.search(version_file_data)
if version_match:
return version_match.groups()
raise Exception("Unable to find version string.")
def main():
if len(sys.argv) < 2:
usage()
filepath = sys.argv[1]
version_tup = find_version(filepath)
print('.'.join(version_tup))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,72 @@
#!/usr/bin/env python3
# #############################################################################
# Copyright (c) 2018-present lzutao <taolzu(at)gmail.com>
# All rights reserved.
#
# This source code is licensed under both the BSD-style license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# #############################################################################
import errno
import os
def mkdir_p(path, dir_mode=0o777):
try:
os.makedirs(path, mode=dir_mode)
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else:
raise
def InstallSymlink(src, dst, install_dir, dst_is_dir=False, dir_mode=0o777):
if not os.path.exists(install_dir):
mkdir_p(install_dir, dir_mode)
if not os.path.isdir(install_dir):
raise NotADirectoryError(install_dir)
new_dst = os.path.join(install_dir, dst)
if os.path.islink(new_dst) and os.readlink(new_dst) == src:
print('File exists: %r -> %r' % (dst, src))
return
print('Installing symlink %r -> %r' % (new_dst, src))
os.symlink(src, new_dst, dst_is_dir)
def main():
import argparse
parser = argparse.ArgumentParser(description='Install a symlink.\n',
usage='usage: InstallSymlink.py [-h] [-d] [-m MODE] src dst '
'install_dir\n\n'
'example:\n'
'\tInstallSymlink.py libcrypto.so.1.0.0 libcrypt.so '
'/usr/lib/x86_64-linux-gnu False')
parser.add_argument('src', help='target to link')
parser.add_argument('dst', help='link name')
parser.add_argument('install_dir', help='installation directory')
parser.add_argument('-d', '--isdir',
action='store_true',
help='dst is a directory')
parser.add_argument('-m', '--mode',
help='directory mode on creating if not exist',
default='0o777')
args = parser.parse_args()
src = args.src
dst = args.dst
install_dir = args.install_dir
dst_is_dir = args.isdir
dir_mode = int(args.mode, 8)
DESTDIR = os.environ.get('DESTDIR')
if DESTDIR:
install_dir = DESTDIR + install_dir if os.path.isabs(install_dir) \
else os.path.join(DESTDIR, install_dir)
InstallSymlink(src, dst, install_dir, dst_is_dir, dir_mode)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,42 @@
# #############################################################################
# Copyright (c) 2018-present lzutao <taolzu(at)gmail.com>
# All rights reserved.
#
# This source code is licensed under both the BSD-style license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# #############################################################################
lz4_root_dir = '../../../..'
add_languages('cpp')
cxx = meson.get_compiler('cpp')
gen_manual_includes = include_directories(join_paths(lz4_root_dir, 'contrib/gen_manual'))
gen_manual_cppflags = cxx.get_supported_arguments(['-Wextra', '-Wcast-qual',
'-Wcast-align', '-Wshadow', '-Wstrict-aliasing=1', '-Wswitch-enum',
'-Wno-comment'])
gen_manual = executable('gen_manual',
join_paths(lz4_root_dir, 'contrib/gen_manual/gen_manual.cpp'),
cpp_args: gen_manual_cppflags,
include_directories: gen_manual_includes,
install: false)
# Update lz4 manual
lz4_manual_html = custom_target('lz4_manual.html',
output : 'lz4_manual.html',
command : [gen_manual,
lz4_version,
join_paths(meson.current_source_dir(), lz4_root_dir, 'lib/lz4.h'),
'@OUTPUT@'],
install : false)
# Update lz4frame manual
lz4_manual_html = custom_target('lz4frame_manual.html',
output : 'lz4frame_manual.html',
command : [gen_manual,
lz4_version,
join_paths(meson.current_source_dir(), lz4_root_dir, 'lib/lz4frame.h'),
'@OUTPUT@'],
install : false)

View File

@ -0,0 +1,10 @@
# #############################################################################
# Copyright (c) 2018-present lzutao <taolzu(at)gmail.com>
# All rights reserved.
#
# This source code is licensed under both the BSD-style license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# #############################################################################
subdir('gen_manual')

View File

@ -0,0 +1,49 @@
# #############################################################################
# Copyright (c) 2018-present lzutao <taolzu(at)gmail.com>
# All rights reserved.
#
# This source code is licensed under both the BSD-style license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# #############################################################################
lz4_root_dir = '../../..'
#examples_c_args = ['-Wextra', '-Wundef', '-Wshadow', '-Wcast-align', '-Wstrict-prototypes']
printVersion = executable('printVersion',
join_paths(lz4_root_dir, 'examples/printVersion.c'),
dependencies: liblz4_dep,
install: false)
doubleBuffer = executable('doubleBuffer',
join_paths(lz4_root_dir, 'examples/blockStreaming_doubleBuffer.c'),
dependencies: liblz4_dep,
install: false)
dictionaryRandomAccess = executable('dictionaryRandomAccess',
join_paths(lz4_root_dir, 'examples/dictionaryRandomAccess.c'),
dependencies: liblz4_dep,
install: false)
ringBuffer = executable('ringBuffer',
join_paths(lz4_root_dir, 'examples/blockStreaming_ringBuffer.c'),
dependencies: liblz4_dep,
install: false)
ringBufferHC = executable('ringBufferHC',
join_paths(lz4_root_dir, 'examples/HCStreaming_ringBuffer.c'),
dependencies: liblz4_dep,
install: false)
lineCompress = executable('lineCompress',
join_paths(lz4_root_dir, 'examples/blockStreaming_lineByLine.c'),
dependencies: liblz4_dep,
install: false)
frameCompress = executable('frameCompress',
join_paths(lz4_root_dir, 'examples/frameCompress.c'),
dependencies: liblz4_dep,
install: false)
compressFunctions = executable('compressFunctions',
join_paths(lz4_root_dir, 'examples/compress_functions.c'),
dependencies: liblz4_dep,
install: false)
simpleBuffer = executable('simpleBuffer',
join_paths(lz4_root_dir, 'examples/simple_buffer.c'),
dependencies: liblz4_dep,
install: false)

View File

@ -0,0 +1,52 @@
# #############################################################################
# Copyright (c) 2018-present lzutao <taolzu(at)gmail.com>
# All rights reserved.
#
# This source code is licensed under both the BSD-style license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# #############################################################################
lz4_root_dir = '../../..'
liblz4_includes = [include_directories(join_paths(lz4_root_dir, 'lib'))]
liblz4_sources = [join_paths(lz4_root_dir, 'lib/lz4.c'),
join_paths(lz4_root_dir, 'lib/lz4frame.c'),
join_paths(lz4_root_dir, 'lib/lz4hc.c'),
join_paths(lz4_root_dir, 'lib/xxhash.c')]
liblz4_c_args = []
liblz4_debug_cflags = []
if use_debug
liblz4_c_args += '-DLZ4_DEBUG=@0@'.format(debug_level)
if [compiler_gcc, compiler_clang].contains(cc_id)
liblz4_debug_cflags = ['-Wextra', '-Wcast-qual', '-Wcast-align', '-Wshadow',
'-Wswitch-enum', '-Wdeclaration-after-statement', '-Wstrict-prototypes',
'-Wundef', '-Wpointer-arith', '-Wstrict-aliasing=1']
endif
endif
liblz4_c_args += cc.get_supported_arguments(liblz4_debug_cflags)
liblz4 = library('lz4',
liblz4_sources,
include_directories: liblz4_includes,
c_args: liblz4_c_args,
install: true,
soversion: lz4_libversion)
liblz4_dep = declare_dependency(link_with: liblz4,
include_directories: liblz4_includes)
pkgconfig.generate(name: 'lz4',
filebase: 'lz4',
libraries: [liblz4],
description: 'extremely fast lossless compression algorithm library',
version: lz4_libversion,
url: 'http://www.lz4.org/')
install_headers(join_paths(lz4_root_dir, 'lib/lz4.h'),
join_paths(lz4_root_dir, 'lib/lz4hc.h'),
join_paths(lz4_root_dir, 'lib/lz4frame.h'))
if get_option('default_library') != 'shared'
install_headers(join_paths(lz4_root_dir, 'lib/lz4frame_static.h'))
endif

147
contrib/meson/meson.build Normal file
View File

@ -0,0 +1,147 @@
# #############################################################################
# Copyright (c) 2018-present lzutao <taolzu(at)gmail.com>
# All rights reserved.
#
# This source code is licensed under both the BSD-style license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# #############################################################################
project('lz4', ['c'],
license: ['BSD', 'GPLv2'],
default_options : ['c_std=c99',
'buildtype=release'],
version: '1.8.3',
meson_version: '>=0.47.0')
cc = meson.get_compiler('c')
pkgconfig = import('pkgconfig')
python3 = import('python').find_installation()
host_machine_os = host_machine.system()
os_windows = 'windows'
os_linux = 'linux'
os_darwin = 'darwin'
os_freebsd = 'freebsd'
os_sun = 'sunos'
cc_id = cc.get_id()
compiler_gcc = 'gcc'
compiler_clang = 'clang'
compiler_msvc = 'msvc'
lz4_version = meson.project_version()
lz4_libversion = ''
c_std = get_option('c_std')
# =============================================================================
# Installation directories
# =============================================================================
if host_machine_os == os_windows
lz4_prefix = '.'
lz4_bindir = 'bin'
lz4_datadir = 'share'
lz4_mandir = join_paths(lz4_datadir, 'man')
else
lz4_prefix = get_option('prefix')
lz4_bindir = join_paths(lz4_prefix, get_option('bindir'))
lz4_datadir = join_paths(lz4_prefix, get_option('datadir'))
lz4_mandir = join_paths(lz4_prefix, get_option('mandir'))
endif
lz4_docdir = join_paths(lz4_datadir, 'doc', meson.project_name())
# =============================================================================
# Project options
# =============================================================================
buildtype = get_option('buildtype')
# Built-in options
use_debug = get_option('debug')
# Custom options
debug_level = get_option('debug_level')
use_backtrace = get_option('backtrace')
build_programs = get_option('build_programs')
build_contrib = get_option('build_contrib')
build_tests = get_option('build_tests')
build_examples = get_option('build_examples')
#feature_multi_thread = get_option('multi_thread')
# =============================================================================
# Helper scripts for Meson
# =============================================================================
GetLz4LibraryVersion_py = files('GetLz4LibraryVersion.py')
# =============================================================================
# Getting project version from lz4.h
# =============================================================================
lz4_h_file = join_paths(meson.current_source_dir(), 'lib/lz4.h')
r = run_command(python3, GetLz4LibraryVersion_py, lz4_h_file)
if r.returncode() == 0
output = r.stdout().strip()
if output.version_compare('>@0@'.format(lz4_version))
lz4_version = output
message('Project version is now: @0@'.format(lz4_version))
endif
endif
if host_machine_os != os_windows
lz4_libversion = lz4_version
endif
# =============================================================================
# Dependencies
# =============================================================================
#libm_dep = cc.find_library('m', required: build_tests)
#thread_dep = dependency('threads', required: feature_multi_thread)
#use_multi_thread = thread_dep.found()
# =============================================================================
# Compiler flags
# =============================================================================
add_project_arguments(['-DXXH_NAMESPACE=LZ4_'], language: 'c')
if [compiler_gcc, compiler_clang].contains(cc_id)
common_warning_flags = []
if buildtype == 'release'
common_warning_flags = ['-Werror']
endif
if c_std == 'c89' or c_std == 'gnu89'
common_warning_flags += ['-pedantic', '-Wno-long-long', '-Wno-variadic-macros']
elif c_std == 'c99' or c_std == 'gnu99'
common_warning_flags += ['-pedantic']
endif
cc_compile_flags = cc.get_supported_arguments(common_warning_flags)
add_project_arguments(cc_compile_flags, language: 'c')
endif
# =============================================================================
# Subdirs
# =============================================================================
subdir('lib')
if build_programs
subdir('programs')
endif
if build_tests
subdir('tests')
endif
if build_contrib
subdir('contrib')
endif
if build_examples
subdir('examples')
endif

View File

@ -0,0 +1,24 @@
# #############################################################################
# Copyright (c) 2018-present lzutao <taolzu(at)gmail.com>
# All rights reserved.
#
# This source code is licensed under both the BSD-style license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# #############################################################################
# Read guidelines from https://wiki.gnome.org/Initiatives/GnomeGoals/MesonPorting
option('debug_level', type: 'integer', min: 0, max: 7, value: 1,
description: 'Enable run-time debug. See lib/lz4hc.c')
option('backtrace', type: 'boolean', value: false,
description: 'Display a stack backtrace when execution generates a runtime exception')
option('build_programs', type: 'boolean', value: false,
description: 'Enable programs build')
option('build_tests', type: 'boolean', value: false,
description: 'Enable tests build')
option('build_contrib', type: 'boolean', value: false,
description: 'Enable contrib build')
option('build_examples', type: 'boolean', value: false,
description: 'Enable examples build')

View File

@ -0,0 +1,51 @@
# #############################################################################
# Copyright (c) 2018-present lzutao <taolzu(at)gmail.com>
# All rights reserved.
#
# This source code is licensed under both the BSD-style license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# #############################################################################
lz4_root_dir = '../../..'
lz4_includes = include_directories(join_paths(lz4_root_dir, 'programs'))
lz4_sources = [join_paths(lz4_root_dir, 'programs/bench.c'),
join_paths(lz4_root_dir, 'programs/datagen.c'),
join_paths(lz4_root_dir, 'programs/lz4cli.c'),
join_paths(lz4_root_dir, 'programs/lz4io.c')]
lz4_c_args = []
export_dynamic_on_windows = false
# explicit backtrace enable/disable for Linux & Darwin
if not use_backtrace
lz4_c_args += '-DBACKTRACE_ENABLE=0'
elif use_debug and host_machine_os == os_windows # MinGW target
lz4_c_args += '-DBACKTRACE_ENABLE=1'
export_dynamic_on_windows = true
endif
lz4_deps = [ liblz4_dep ]
lz4 = executable('lz4',
lz4_sources,
include_directories: lz4_includes,
c_args: lz4_c_args,
dependencies: lz4_deps,
export_dynamic: export_dynamic_on_windows, # Since Meson 0.45.0
install: true)
# =============================================================================
# Programs and manpages installing
# =============================================================================
install_man(join_paths(lz4_root_dir, 'programs/lz4.1'))
InstallSymlink_py = '../InstallSymlink.py'
lz4_man1_dir = join_paths(lz4_mandir, 'man1')
man1_EXT = host_machine_os != os_windows ? '.1.gz' : '.1'
foreach f : ['lz4c', 'lz4cat', 'unlz4']
meson.add_install_script(InstallSymlink_py, 'lz4', f, lz4_bindir)
meson.add_install_script(InstallSymlink_py, 'lz4' + man1_EXT, f + man1_EXT, lz4_man1_dir)
endforeach

View File

@ -0,0 +1,81 @@
# #############################################################################
# Copyright (c) 2018-present lzutao <taolzu(at)gmail.com>
# All rights reserved.
#
# This source code is licensed under both the BSD-style license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# #############################################################################
lz4_root_dir = '../../..'
programs_dir_inc = include_directories(join_paths(lz4_root_dir, 'programs'))
lib_dir_inc = include_directories(join_paths(lz4_root_dir, 'lib'))
# =============================================================================
# Test flags
# =============================================================================
TEST_FILES = join_paths(lz4_root_dir, 'tests/COPYING')
FUZZER_TIME = '-T90s'
NB_LOOPS = '-i1'
# =============================================================================
# Executables
# =============================================================================
fullbench_sources = [join_paths(lz4_root_dir, 'tests/fullbench.c')]
fullbench = executable('fullbench',
fullbench_sources,
include_directories: programs_dir_inc,
dependencies: liblz4_dep,
install: false)
fuzzer_sources = [join_paths(lz4_root_dir, 'tests/fuzzer.c')]
fuzzer = executable('fuzzer',
fuzzer_sources,
c_args: ['-D_DEFAULT_SOURCE', '-D_BSD_SOURCE'], # since glibc 2.19
include_directories: programs_dir_inc,
dependencies: liblz4_dep,
install: false)
frametest_sources = [join_paths(lz4_root_dir, 'tests/frametest.c')]
frametest = executable('frametest',
frametest_sources,
include_directories: programs_dir_inc,
dependencies: liblz4_dep,
install: false)
roundTripTest_sources = [join_paths(lz4_root_dir, 'tests/roundTripTest.c')]
roundTripTest = executable('roundTripTest',
roundTripTest_sources,
dependencies: [ liblz4_dep ],
install: false)
datagen_sources = [join_paths(lz4_root_dir, 'tests/datagencli.c')]
datagen = executable('datagen',
datagen_sources,
objects: lz4.extract_objects(join_paths(lz4_root_dir, 'programs/datagen.c')),
include_directories: lz4_includes,
dependencies: [ liblz4_dep ],
install: false)
checkFrame_sources = [join_paths(lz4_root_dir, 'tests/checkFrame.c')]
checkFrame = executable('checkFrame',
checkFrame_sources,
include_directories: programs_dir_inc,
dependencies: [ liblz4_dep ],
install: false)
checkTag_sources = [join_paths(lz4_root_dir, 'tests/checkTag.c')]
checkTag = executable('checkTag',
checkTag_sources,
include_directories: lib_dir_inc,
install: false)
# =============================================================================
# Tests (Use "meson test --list" to list all tests)
# =============================================================================
test('test-fullbench', fullbench, args: ['--no-prompt', NB_LOOPS, TEST_FILES])
test('test-fuzzer', fuzzer, args: [FUZZER_TIME])
test('test-frametest', frametest, args: [FUZZER_TIME])