# Description # lzma is a general purpose data compression library https://tukaani.org/xz/ # Public Domain load("@bazel_skylib//lib:selects.bzl", "selects") load("@bazel_skylib//rules:copy_file.bzl", "copy_file") load("@bazel_skylib//rules:expand_template.bzl", "expand_template") load("@rules_cc//cc:cc_binary.bzl", "cc_binary") load("@rules_cc//cc:cc_library.bzl", "cc_library") load("@rules_cc//cc:cc_test.bzl", "cc_test") load("//:tools.bzl", "multi_test") package(default_visibility = ["//visibility:private"]) config_setting( name = "osx_arm64", constraint_values = [ "@platforms//os:osx", "@platforms//cpu:aarch64", ], ) config_setting( name = "osx_x86_64", constraint_values = [ "@platforms//os:osx", "@platforms//cpu:x86_64", ], ) config_setting( name = "linux_arm64", constraint_values = [ "@platforms//os:linux", "@platforms//cpu:aarch64", ], ) config_setting( name = "linux_riscv64", constraint_values = [ "@platforms//os:linux", "@platforms//cpu:riscv64", ], ) config_setting( name = "linux_x86_64", constraint_values = [ "@platforms//os:linux", "@platforms//cpu:x86_64", ], ) config_setting( name = "wasm32", constraint_values = [ "@platforms//os:none", "@platforms//cpu:wasm32", ], ) expand_template( name = "config_linux_arm64", out = "config.lzma-linux-arm64.h", substitutions = { "{HAVE_IMMINTRIN_H}": "#undef HAVE_IMMINTRIN_H", "{HAVE_CPUID_H}": "#undef HAVE_CPUID_H", "{HAVE_USABLE_CLMUL}": "#undef HAVE_USABLE_CLMUL", }, template = "config.lzma-linux.h", ) expand_template( name = "config_linux_riscv64", out = "config.lzma-linux-riscv64.h", substitutions = { "{HAVE_IMMINTRIN_H}": "#undef HAVE_IMMINTRIN_H", "{HAVE_CPUID_H}": "#undef HAVE_CPUID_H", "{HAVE_USABLE_CLMUL}": "#undef HAVE_USABLE_CLMUL", }, template = "config.lzma-linux.h", ) expand_template( name = "config_linux_x86_64", out = "config.lzma-linux-x86_64.h", substitutions = { "{HAVE_IMMINTRIN_H}": """\ #if defined __has_include #if __has_include () #define HAVE_IMMINTRIN_H 1 #endif #endif""", "{HAVE_CPUID_H}": "#define HAVE_CPUID_H 1", "{HAVE_USABLE_CLMUL}": "#define HAVE_USABLE_CLMUL 1", }, template = "config.lzma-linux.h", ) copy_file( name = "copy_config", src = selects.with_or({ "@platforms//os:android": "config.lzma-android.h", ":linux_arm64": "config.lzma-linux-arm64.h", ":linux_riscv64": "config.lzma-linux-riscv64.h", ":linux_x86_64": "config.lzma-linux-x86_64.h", ":osx_arm64": "config.lzma-osx-arm64.h", ":osx_x86_64": "config.lzma-osx-x86_64.h", ":wasm32": "config.lzma-wasm32.h", ("@platforms//os:ios", "@platforms//os:watchos", "@platforms//os:tvos"): "apple_config", "@platforms//os:windows": "config.lzma-windows.h", "//conditions:default": "config.lzma-linux-x86_64.h", }), out = "src/liblzma/api/config.h", # minimize the number of exported include paths target_compatible_with = selects.with_or({ ("@platforms//os:android", "@platforms//os:linux", "@platforms//os:osx", "@platforms//os:ios", "@platforms//os:watchos", "@platforms//os:tvos", "@platforms//os:windows"): [], ":wasm32": [], "//conditions:default": ["@platforms//:incompatible"], }), ) # Configuration is the same across iOS, watchOS, and tvOS alias( name = "apple_config", actual = select({ "@platforms//cpu:arm64": "config.lzma-ios-arm64.h", "@platforms//cpu:armv7": "config.lzma-ios-armv7.h", "@platforms//cpu:x86_64": "config.lzma-osx-x86_64.h", # Configuration same as macOS "@platforms//cpu:x86_32": "config.lzma-ios-i386.h", "//conditions:default": "config.lzma-osx-x86_64.h", }), ) # Note: lzma is bundled with Apple platforms, but sadly, not considered public API because its header is not exposed. lzma is not bundled on Android. cc_library( name = "lzma", srcs = select({ "@platforms//os:none": [], "//conditions:default": [ "src/common/tuklib_cpucores.c", "src/common/tuklib_physmem.c", "src/liblzma/common/stream_decoder_mt.c", "src/liblzma/common/stream_encoder_mt.c", ], }) + glob( [ "src/**/*.h", "src/liblzma/**/*.c", ], exclude = [ "src/liblzma/check/crc*_small.c", "src/liblzma/**/*_tablegen.c", "src/liblzma/common/stream_decoder_mt.c", "src/liblzma/common/stream_encoder_mt.c", ], ), hdrs = [ "src/liblzma/api/lzma.h", # Publicly exported header ], copts = select({ "@platforms//os:windows": [], "//conditions:default": ["-std=c99"], }), defines = select({ "@platforms//os:windows": ["LZMA_API_STATIC"], "//conditions:default": [], }), linkopts = select({ "@platforms//os:android": [], "@platforms//os:windows": [], "@platforms//os:none": [], "//conditions:default": ["-lpthread"], }), linkstatic = select({ "@platforms//os:windows": True, "//conditions:default": False, }), strip_include_prefix = "src/liblzma/api", # Allows public header without the path and without COPTS -I or includes = [] visibility = ["//visibility:public"], deps = [ "//:lzma_src_common", "//:lzma_src_liblzma_api", "//:lzma_src_liblzma_check", "//:lzma_src_liblzma_common", "//:lzma_src_liblzma_delta", "//:lzma_src_liblzma_lz", "//:lzma_src_liblzma_lzma", "//:lzma_src_liblzma_rangecoder", "//:lzma_src_liblzma_simpler", ], ) cc_binary( name = "xz", srcs = glob( ["src/xz/*.c"], # exclude = ["src/xz/list.c"], # TODO Conditional this? ) + [ "src/common/tuklib_mbstr_fw.c", "src/common/tuklib_mbstr_width.c", "src/common/tuklib_open_stdxxx.c", ], # + select({ # "//conditions:COND_MAIN_DECODER": ["list.c"], # TODO Conditional this? # "//conditions:default": [], # }) copts = [ '-DLOCALEDIR=\\"/usr/share/locale\\"', #TODO Help? Where do we get the locale directory from in bazel? ], # linkopts = [ # "$(CAPSICUM_LIB)", #TODO Help? # "-llibintl", # Replace with actual libintl target if available #TODO Help? # ], visibility = ["//visibility:public"], deps = [ "//:lzma", "//:lzma_src_common", "//:lzma_src_liblzma_api", ], # + select({ # "@platforms//os:windows": ["//:xz_win_resources"], # "//conditions:default": [], # }), ) # cc_library( # name = "xz_win_resources", # srcs = ["xz_w32res.rc"], # ) XZDEC_SRCS = [ "src/xzdec/xzdec.c", ] XZDEC_DEPS = [ "//:lzma", "//:lzma_src_liblzma_common", ] # + select({ # "@platforms//os:windows": ["//:xzdec_win_resources"], # "//conditions:default": [], # }) # cc_library( # name = "xzdec_win_resources", # srcs = ["xzdec_w32res.rc"], # ) cc_binary( name = "xzdec", srcs = XZDEC_SRCS, copts = [ "-DTUKLIB_GETTEXT=0", ], visibility = ["//visibility:public"], # linkopts = ["-llibintl"], # Replace with actual libintl target if available #TODO Help? deps = XZDEC_DEPS, ) cc_binary( name = "lzmadec", srcs = XZDEC_SRCS, # lzmadec uses the same source with a define copts = [ "-DTUKLIB_GETTEXT=0", "-DLZMADEC", ], visibility = ["//visibility:public"], # linkopts = ["-llibintl"], # Replace with actual libintl target if available #TODO Help? deps = XZDEC_DEPS, ) cc_library( name = "lzma_src_common", srcs = select({ "@platforms//os:none": [], "//conditions:default": [ "src/common/tuklib_exit.c", "src/common/tuklib_progname.c", ], }), hdrs = glob(["src/common/*.h"]), defines = ["HAVE_CONFIG_H"] + select({ "@platforms//os:windows": [ "LZMA_API_STATIC", "TUKLIB_GETTEXT=0", # Disable libintl for windows ], "//conditions:default": [], }), strip_include_prefix = "src/common", deps = [ "//:lzma_src_liblzma_api", ], ) cc_library( name = "lzma_src_liblzma_api", hdrs = [ "src/liblzma/api/config.h", # Generated above, so missed by glob. In srcs so it's not public like the other headers ] + glob( [ "src/liblzma/api/**/*.h", ], exclude = [ "src/liblzma/api/lzma.h", # The public header, only used in hdrs of main lib (//visibility:public) ], ), strip_include_prefix = "src/liblzma/api", ) cc_library( name = "lzma_src_liblzma_check", hdrs = glob(["src/liblzma/check/*.h"]), strip_include_prefix = "src/liblzma/check", ) cc_library( name = "lzma_src_liblzma_common", hdrs = glob(["src/liblzma/common/*.h"]), includes = ["src/liblzma"], # Needed as well as some usages use common/*.h instead of just the header strip_include_prefix = "src/liblzma/common", ) cc_library( name = "lzma_src_liblzma_delta", hdrs = glob(["src/liblzma/delta/*.h"]), strip_include_prefix = "src/liblzma/delta", ) cc_library( name = "lzma_src_liblzma_lz", hdrs = glob(["src/liblzma/lz/*.h"]), strip_include_prefix = "src/liblzma/lz", ) cc_library( name = "lzma_src_liblzma_lzma", hdrs = glob(["src/liblzma/lzma/*.h"]), strip_include_prefix = "src/liblzma/lzma", ) cc_library( name = "lzma_src_liblzma_rangecoder", hdrs = glob(["src/liblzma/rangecoder/*.h"]), strip_include_prefix = "src/liblzma/rangecoder", ) cc_library( name = "lzma_src_liblzma_simpler", hdrs = glob(["src/liblzma/simple/*.h"]), strip_include_prefix = "src/liblzma/simple", ) # Test header files cc_library( name = "tests_hdrs", testonly = True, hdrs = [ "tests/tests.h", "tests/tuktest.h", ], ) # Suite of tests, much tidier using the custom macro from the tools.bzl test_suite( name = "all_tests", tests = multi_test( size = "small", data = glob(["tests/files/**/*"]), defines = select({ "@platforms//os:windows": ["HAVE_LZIP_DECODER=1"], "//conditions:default": [], }), names = [ "bcj_test", "create_compress_files", "test_bcj_exact_size", "test_block_header", "test_check", "test_filter_flags", "test_filter_str", "test_hardware", "test_index", "test_index_hash", "test_lzip_decoder", "test_memlimit", "test_stream_flags", "test_vli", ], deps = [ ":lzma", ":tests_hdrs", ], ) + [ # "ossfuzz", # Currently disabled, as the fuzzer doesn't seem to be reliably available for linking on all systems. I don't have experience in this area :) ], visibility = ["//visibility:public"], ) # Fuzz test, not currently implemented cc_test( name = "ossfuzz", srcs = ["tests/ossfuzz/fuzz.c"], copts = [ "-fsanitize=fuzzer", ], data = glob(["tests/files/**"]), linkopts = [ "-fsanitize=fuzzer", ], deps = [ ":tests_hdrs", "//:lzma", ], )