From 5bc119455fde697f132adbd7fd50f095954f703b Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sat, 1 Dec 2018 12:15:53 +0700 Subject: [PATCH 1/2] Add meson build system --- contrib/meson/GetLz4LibraryVersion.py | 45 ++++++ contrib/meson/InstallSymlink.py | 72 +++++++++ contrib/meson/contrib/gen_manual/meson.build | 42 ++++++ contrib/meson/contrib/meson.build | 10 ++ contrib/meson/examples/meson.build | 49 +++++++ contrib/meson/lib/meson.build | 52 +++++++ contrib/meson/meson.build | 147 +++++++++++++++++++ contrib/meson/meson_options.txt | 24 +++ contrib/meson/programs/meson.build | 51 +++++++ contrib/meson/tests/meson.build | 81 ++++++++++ 10 files changed, 573 insertions(+) create mode 100644 contrib/meson/GetLz4LibraryVersion.py create mode 100644 contrib/meson/InstallSymlink.py create mode 100644 contrib/meson/contrib/gen_manual/meson.build create mode 100644 contrib/meson/contrib/meson.build create mode 100644 contrib/meson/examples/meson.build create mode 100644 contrib/meson/lib/meson.build create mode 100644 contrib/meson/meson.build create mode 100644 contrib/meson/meson_options.txt create mode 100644 contrib/meson/programs/meson.build create mode 100644 contrib/meson/tests/meson.build diff --git a/contrib/meson/GetLz4LibraryVersion.py b/contrib/meson/GetLz4LibraryVersion.py new file mode 100644 index 0000000..e929f95 --- /dev/null +++ b/contrib/meson/GetLz4LibraryVersion.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +# ############################################################################# +# Copyright (c) 2018-present lzutao +# 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 ') + 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() diff --git a/contrib/meson/InstallSymlink.py b/contrib/meson/InstallSymlink.py new file mode 100644 index 0000000..d7b1e5a --- /dev/null +++ b/contrib/meson/InstallSymlink.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +# ############################################################################# +# Copyright (c) 2018-present lzutao +# 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() diff --git a/contrib/meson/contrib/gen_manual/meson.build b/contrib/meson/contrib/gen_manual/meson.build new file mode 100644 index 0000000..6233cdc --- /dev/null +++ b/contrib/meson/contrib/gen_manual/meson.build @@ -0,0 +1,42 @@ +# ############################################################################# +# Copyright (c) 2018-present lzutao +# 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) diff --git a/contrib/meson/contrib/meson.build b/contrib/meson/contrib/meson.build new file mode 100644 index 0000000..5249a4c --- /dev/null +++ b/contrib/meson/contrib/meson.build @@ -0,0 +1,10 @@ +# ############################################################################# +# Copyright (c) 2018-present lzutao +# 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') diff --git a/contrib/meson/examples/meson.build b/contrib/meson/examples/meson.build new file mode 100644 index 0000000..3c13214 --- /dev/null +++ b/contrib/meson/examples/meson.build @@ -0,0 +1,49 @@ +# ############################################################################# +# Copyright (c) 2018-present lzutao +# 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) diff --git a/contrib/meson/lib/meson.build b/contrib/meson/lib/meson.build new file mode 100644 index 0000000..3810601 --- /dev/null +++ b/contrib/meson/lib/meson.build @@ -0,0 +1,52 @@ +# ############################################################################# +# Copyright (c) 2018-present lzutao +# 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 diff --git a/contrib/meson/meson.build b/contrib/meson/meson.build new file mode 100644 index 0000000..f1ca503 --- /dev/null +++ b/contrib/meson/meson.build @@ -0,0 +1,147 @@ +# ############################################################################# +# Copyright (c) 2018-present lzutao +# 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 diff --git a/contrib/meson/meson_options.txt b/contrib/meson/meson_options.txt new file mode 100644 index 0000000..f6a4ae7 --- /dev/null +++ b/contrib/meson/meson_options.txt @@ -0,0 +1,24 @@ +# ############################################################################# +# Copyright (c) 2018-present lzutao +# 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') diff --git a/contrib/meson/programs/meson.build b/contrib/meson/programs/meson.build new file mode 100644 index 0000000..b5c3228 --- /dev/null +++ b/contrib/meson/programs/meson.build @@ -0,0 +1,51 @@ +# ############################################################################# +# Copyright (c) 2018-present lzutao +# 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 diff --git a/contrib/meson/tests/meson.build b/contrib/meson/tests/meson.build new file mode 100644 index 0000000..82e2813 --- /dev/null +++ b/contrib/meson/tests/meson.build @@ -0,0 +1,81 @@ +# ############################################################################# +# Copyright (c) 2018-present lzutao +# 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]) From 9f87365de5efbab5d2aee0b7c87bbece71955696 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sat, 1 Dec 2018 13:12:51 +0700 Subject: [PATCH 2/2] Add Travis meson build --- .travis.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.travis.yml b/.travis.yml index 5b0c6ca..043f932 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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