Skip to content

Commit

Permalink
add cmake
Browse files Browse the repository at this point in the history
  • Loading branch information
bsergean authored and ckerr committed May 24, 2022
1 parent b015374 commit a86ca69
Show file tree
Hide file tree
Showing 4 changed files with 337 additions and 0 deletions.
164 changes: 164 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
cmake_minimum_required(VERSION 3.5.1)
include(CheckCCompilerFlag)

project(deflate C ASM)

set(CMAKE_C_STANDARD 99)

#
# Options
#
# Generic option
option(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" OFF)

# libdeflate options
option(DEFLATE_DECOMPRESSION_ONLY "Omit all compression code, building a decompression-only library" OFF)

option(DEFLATE_DISABLE_ZLIB "disable support for the zlib wrapper format" OFF)

option(DEFLATE_DISABLE_GZIP "disable support for the gzip wrapper format" OFF)

option(DEFLATE_FREESTANDING "build a freestanding library, i.e. a library that doesn't
link to any libc functions like malloc(), free(),
and memcpy(). All users will need to call
libdeflate_set_memory_allocator()." OFF)

option(DEFLATE_BUILD_TEST_PROGRAMS "Build test programs" OFF)
option(DEFLATE_TEST_SUPPORT__DO_NOT_USE "Don't use this option except for testing; it isn't a stable interface." OFF)

# Source code
set(LIBDEFLATE_SOURCES
lib/deflate_decompress.c
lib/utils.c
lib/x86/cpu_features.c
lib/zlib_compress.c
lib/arm/cpu_features.c
)

if (NOT DEFLATE_DECOMPRESSION_ONLY)
list(APPEND LIBDEFLATE_SOURCES lib/deflate_compress.c)
endif()

if (NOT DEFLATE_DISABLE_ZLIB)
list(APPEND LIBDEFLATE_SOURCES lib/adler32.c lib/zlib_decompress.c)
if (NOT DEFLATE_DECOMPRESSION_ONLY)
list(APPEND LIBDEFLATE_SOURCES lib/zlib_compress.c)
endif()
endif()

if (NOT DEFLATE_DISABLE_GZIP)
list(APPEND LIBDEFLATE_SOURCES lib/crc32.c lib/gzip_decompress.c)
if (NOT DEFLATE_DECOMPRESSION_ONLY)
list(APPEND LIBDEFLATE_SOURCES lib/gzip_compress.c)
endif()
endif()

set(LIBDEFLATE_HEADERS
common/compiler_msc.h
common/compiler_gcc.h
common/common_defs.h
lib/bt_matchfinder.h
lib/matchfinder_common.h
lib/unaligned.h
lib/gzip_constants.h
lib/zlib_constants.h
lib/crc32_vec_template.h
lib/decompress_template.h
lib/deflate_compress.h
lib/crc32_table.h
lib/x86/decompress_impl.h
lib/x86/crc32_impl.h
lib/x86/cpu_features.h
lib/x86/adler32_impl.h
lib/x86/matchfinder_impl.h
lib/x86/crc32_pclmul_template.h
lib/lib_common.h
lib/hc_matchfinder.h
lib/cpu_features_common.h
lib/arm/crc32_impl.h
lib/arm/cpu_features.h
lib/arm/adler32_impl.h
lib/arm/matchfinder_impl.h
lib/deflate_constants.h
lib/adler32_vec_template.h
)

add_library(deflate)
add_library(deflate::deflate ALIAS deflate)

set_target_properties(deflate PROPERTIES VERSION 0.0.0 SOVERSION 0)

target_sources(deflate PRIVATE ${LIBDEFLATE_SOURCES}
${LIBDEFLATE_HEADERS})

# Compile options
check_c_compiler_flag(-Wall DEFLATE_LINT_WALL)
check_c_compiler_flag(-Wundef DEFLATE_LINT_WUNDEF)
check_c_compiler_flag(-Wpedantic DEFLATE_LINT_PEDANTIC)
check_c_compiler_flag(-Wdeclaration-after-statement DEFLATE_LINT_DECLARATION_AFTER_STATEMENT)
check_c_compiler_flag(-Wmissing-prototypes DEFLATE_LINT_MISSING_PROTOTYPES)
check_c_compiler_flag(-Wstrict-prototypes DEFLATE_LINT_STRICT_PROTOTYPES)
check_c_compiler_flag(-Wvla DEFLATE_LINT_VLA)
check_c_compiler_flag(-Wimplicit-fallthrough DEFLATE_LINT_IMPLICIT_FALLTHROUGH)

set(lint-all $<$<BOOL:${DEFLATE_LINT_WALL}>:-Wall>)
set(lint-undef $<$<BOOL:${DEFLATE_LINT_UNDEF}>:-Wundef>)
set(lint-pedantic $<$<BOOL:${DEFLATE_LINT_PEDANTIC}>:-Wpedantic>)
set(lint-declaration-after-statement $<$<BOOL:${DEFLATE_LINT_DECLARATION_AFTER_STATEMENT}>:-Wdeclaration-after-statement>)
set(lint-missing-prototypes $<$<BOOL:${DEFLATE_LINT_MISSING_PROTOTYPES}>:-Wmissing-prototypes>)
set(lint-strict-prototypes $<$<BOOL:${DEFLATE_LINT_STRICT_PROTOTYPES}>:-Wstrict-prototypes>)
set(lint-vla $<$<BOOL:${DEFLATE_LINT_VLA}>:-Wvla>)
set(lint-implicit-fallthrough $<$<BOOL:${DEFLATE_LINT_IMPLICIT_FALLTHROUGH}>:-Wimplicit-fallthrough>)

target_compile_options(deflate PRIVATE ${lint-all})
target_compile_options(deflate PRIVATE ${lint-undef})
target_compile_options(deflate PRIVATE ${lint-pedantic})
target_compile_options(deflate PRIVATE ${lint-declaration-after-statement})
target_compile_options(deflate PRIVATE ${lint-missing-prototypes})
target_compile_options(deflate PRIVATE ${lint-strict-prototypes})
target_compile_options(deflate PRIVATE ${lint-vla})
target_compile_options(deflate PRIVATE ${lint-implicit-fallthrough})

# The CFLAGS environment variable is read and handled automatically by cmake

if (BUILD_SHARED_LIBS)
target_compile_definitions(deflate PRIVATE _ANSI_SOURCE)
set_target_properties(deflate PROPERTIES C_VISIBILITY_PRESET hidden)

if (WIN32)
target_compile_definitions(deflate PUBLIC LIBDEFLATE_DLL)
endif()
endif()

if (FREESTANDING)
target_compile_definitions(deflate PRIVATE FREESTANDING)
target_compile_options(deflate PRIVATE -ffreestanding -nostdlib)
endif()

if (DEFLATE_TEST_SUPPORT__DO_NOT_USE)
target_compile_definitions(deflate PRIVATE TEST_SUPPORT__DO_NOT_USE)
endif()

target_include_directories(deflate PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)

set_target_properties(deflate PROPERTIES PUBLIC_HEADER "libdeflate.h")

install(TARGETS deflate
EXPORT deflate
ARCHIVE DESTINATION lib
PUBLIC_HEADER DESTINATION include/
)

# This is required to work with FetchContent
install(EXPORT deflate
FILE deflate-config.cmake
NAMESPACE deflate::
DESTINATION lib/cmake/deflate)

if (DEFLATE_BUILD_TEST_PROGRAMS)
enable_testing()
add_subdirectory(programs)
endif()
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,73 @@ and run the following commands:

Or to build 32-bit binaries, do the same but use "MSYS2 MinGW 32-bit" instead.

### Using CMake

The CMake scripts are maintained by the community and not officially supported.

To build the library locally, run the following commands:

mkdir build
cd build
cmake ..
make

`make VERBOSE=1` will show all executed commands.

To build also the example programs, just add the DEFLATE_BUILD_TEST_PROGRAMS option.

cmake -DDEFLATE_BUILD_TEST_PROGRAMS=1 ..
make

The programs will be found under the build/programs folder

$ echo foo | build/programs/benchmark
Benchmarking DEFLATE compression:
Compression level: 6
Chunk size: 1048576
Wrapper: None
Compression engine: libdeflate
Decompression engine: libdeflate
Processing standard input...
Compressed 4 => 4 bytes (100.000%)
Compression time: 0 ms (4 MB/s)
Decompression time: 0 ms (4 MB/s)

You can execute all test programs through cmake and ctest with:

make
make test
Running tests...
Test project /.../libdeflate/build
Start 1: test_checksums
1/6 Test #1: test_checksums ................... Passed 0.25 sec
Start 2: test_custom_malloc
2/6 Test #2: test_custom_malloc ............... Passed 0.24 sec
Start 3: test_incomplete_codes
3/6 Test #3: test_incomplete_codes ............ Passed 0.22 sec
Start 4: test_litrunlen_overflow
4/6 Test #4: test_litrunlen_overflow .......... Passed 0.24 sec
Start 5: test_slow_decompression
5/6 Test #5: test_slow_decompression .......... Passed 0.21 sec
Start 6: test_trailing_bytes
6/6 Test #6: test_trailing_bytes .............. Passed 0.21 sec

100% tests passed, 0 tests failed out of 6

Total Test time (real) = 1.37 sec

To use the library directly in your own project, thanks to CMake FetchContent, using those CMake snippets.

include(FetchContent)
FetchContent_Declare(deflate
GIT_REPOSITORY "https://github.com/ebiggers/libdeflate"
GIT_TAG "master" # Or an explicit tag
GIT_SHALLOW 1)

FetchContent_MakeAvailable(deflate)

target_link_libraries(my_library_or_exe deflate)

# API

libdeflate has a simple API that is not zlib-compatible. You can create
Expand Down
78 changes: 78 additions & 0 deletions programs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@

# For examples of checking symbols existence, see
# https://go.googlesource.com/gollvm/+/master/cmake/modules/ConfigSetup.cmake
#
include(CheckSymbolExists)

check_symbol_exists(clock_gettime "time.h" HAVE_CLOCK_GETTIME)
check_symbol_exists(futimens "fcntl.h;sys/stat.h" HAVE_FUTIMENS)
check_symbol_exists(futimes "sys/time.h" HAVE_FUTIMES)
check_symbol_exists(posix_fadvise "fcntl.h" HAVE_POSIX_FADVISE)
check_symbol_exists(posix_madvise "sys/mman.h" HAVE_POSIX_MADVISE)

check_c_source_compiles("#include <sys/types.h>
#include <sys/stat.h>
int main() { struct stat st; (void) st.atim; }"
HAVE_STAT_NANOSECOND_PRECISION)

check_c_source_compiles("#include <sys/types.h>
#include <sys/stat.h>
int main() { struct stat st; (void) st.st_atimespec; }"
HAVE_STAT_NANOSECOND_PRECISION_MACOS)

if (${HAVE_STAT_NANOSECOND_PRECISION_MACOS})
set(HAVE_STAT_NANOSECOND_PRECISION 1)
set(st_atim st_atimensec)
set(st_mtim st_mtimensec)
set(st_ctim st_ctimensec)
endif()

configure_file(${PROJECT_SOURCE_DIR}/programs/config.h.in
${PROJECT_SOURCE_DIR}/programs/config.h)

set(TEST_PROGRAMS_DEFINITIONS _POSIX_C_SOURCE=200809L
_FILE_OFFSET_BITS=64
HAVE_CONFIG_H)

if (DEFLATE_TEST_SUPPORT__DO_NOT_USE)
list(APPEND TEST_PROGRAMS_DEFINITIONS TEST_SUPPORT__DO_NOT_USE)
endif()

if (BUILD_SHARED_LIBS)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()

# Small library for common code
add_library(programs)
target_sources(programs PRIVATE prog_util.c test_util.c tgetopt.c)
target_compile_definitions(programs PRIVATE ${TEST_PROGRAMS_DEFINITIONS})
target_link_libraries(programs deflate)

# cli
set(PROGRAM_TARGET_NAMES
gzip
benchmark
checksum
)
foreach(PROGRAM_TARGET_NAME ${PROGRAM_TARGET_NAMES})
add_executable(${PROGRAM_TARGET_NAME} ${PROGRAM_TARGET_NAME}.c)
target_link_libraries(${PROGRAM_TARGET_NAME} programs deflate z)
target_compile_definitions(${PROGRAM_TARGET_NAME} PRIVATE ${TEST_PROGRAMS_DEFINITIONS})
endforeach()

# tests
set(TEST_TARGET_NAMES
test_checksums
test_custom_malloc
test_incomplete_codes
test_litrunlen_overflow
test_slow_decompression
test_trailing_bytes
)
foreach(TEST_TARGET_NAME ${TEST_TARGET_NAMES})
add_executable(${TEST_TARGET_NAME} ${TEST_TARGET_NAME}.c)
target_link_libraries(${TEST_TARGET_NAME} programs deflate z)
target_compile_definitions(${TEST_TARGET_NAME} PRIVATE ${TEST_PROGRAMS_DEFINITIONS})

add_test(NAME ${TEST_TARGET_NAME} COMMAND ${TEST_TARGET_NAME})
endforeach()
28 changes: 28 additions & 0 deletions programs/config.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. */
#ifndef CONFIG_H
#define CONFIG_H

/* Is the clock_gettime() function available? */
#cmakedefine HAVE_CLOCK_GETTIME

/* Is the futimens() function available? */
#cmakedefine HAVE_FUTIMENS

/* Is the futimes() function available? */
#cmakedefine HAVE_FUTIMES

/* Is the posix_fadvise() function available? */
#cmakedefine HAVE_POSIX_FADVISE

/* Is the posix_madvise() function available? */
#cmakedefine HAVE_POSIX_MADVISE

/* Does stat() provide nanosecond-precision timestamps? */
#cmakedefine HAVE_STAT_NANOSECOND_PRECISION

/* Nonstandard field names used by macOS */
#cmakedefine st_atim st_atimensec
#cmakedefine st_mtim st_mtimensec
#cmakedefine st_ctim st_ctimensec

#endif /* CONFIG_H */

0 comments on commit a86ca69

Please sign in to comment.