From 133fefb032519e3c93aebd6cb167b2be8b6a7795 Mon Sep 17 00:00:00 2001 From: Danilo Horta Date: Fri, 1 Jul 2022 15:33:05 +0100 Subject: [PATCH] Incorporate zlib and zstd in cmakelists --- CMakeLists.txt | 51 +------- cmake/compiler-options.cmake | 54 +++++++++ cmake/sanitizers.cmake | 220 +++++++++++++++++++++++++++++++++++ src/layout1.c | 2 +- src/layout2.c | 2 +- src/{zip/zlib.c => unzlib.c} | 4 +- src/{zip/zlib.h => unzlib.h} | 4 +- src/variant.c | 6 +- test/CMakeLists.txt | 2 +- 9 files changed, 291 insertions(+), 54 deletions(-) create mode 100644 cmake/compiler-options.cmake create mode 100644 cmake/sanitizers.cmake rename src/{zip/zlib.c => unzlib.c} (98%) rename src/{zip/zlib.h => unzlib.h} (80%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 66689c2..4f7e455 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,19 +9,9 @@ set(PROJECT_DESCRIPTION # Generate compile_commands.json file set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) -# Set RPATH only if it's not a system directory -list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES - "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) -if("${isSystemDir}" STREQUAL "-1") - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") -endif() - -# Hide things by default -set(CMAKE_C_VISIBILITY_PRESET hidden) -set(CMAKE_VISIBILITY_INLINES_HIDDEN YES) - include(cmake/CPM.cmake) +include(cmake/compiler-options.cmake) +include(cmake/sanitizers.cmake) cpmaddpackage(NAME elapsed GIT_TAG 3.0.5 GITHUB_REPOSITORY horta/elapsed) cpmaddpackage(NAME athr GIT_TAG 4.0.1 GITHUB_REPOSITORY horta/almosthere) @@ -36,6 +26,7 @@ cpmaddpackage( build/cmake OPTIONS "ZSTD_LEGACY_SUPPORT OFF") +cpmaddpackage(NAME zlib VERSION 1.2.12.1 GITHUB_REPOSITORY horta/zlib) if(zstd_ADDED) if(NOT TARGET ZSTD::zstd) @@ -46,8 +37,6 @@ if(zstd_ADDED) endif() endif() -find_package(ZLIB REQUIRED) - add_library( bgen src/file.c @@ -61,40 +50,10 @@ add_library( src/variant.c src/partition.c src/bstring.c - src/zip/zlib.c + src/unzlib.c src/unzstd.c) add_library(BGEN::bgen ALIAS bgen) -if(CMAKE_C_COMPILER_ID STREQUAL "MSVC") - # /wd5105: - # https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/c5105?view=msvc-160 - set(WARNING_FLAGS /W3 /wd5105) -else() - set(WARNING_FLAGS - -Wall - -Wextra - -Wstrict-prototypes - -Wshadow - -Wconversion - -Wmissing-prototypes - -Wno-unused-parameter - -Wsign-conversion - -Wno-unused-function - -Wmissing-field-initializers) - - if(NOT CMAKE_C_COMPILER_ID STREQUAL "GNU") - list( - APPEND - WARNING_FLAGS - -Wno-gnu-designator - -Wno-empty-translation-unit - -Wno-gnu-statement-expression - -Wno-nullability-extension - -Wconditional-uninitialized - -Wgnu-empty-initializer) - endif() -endif() - include(GenerateExportHeader) generate_export_header( bgen @@ -120,7 +79,7 @@ target_compile_definitions( bgen PRIVATE $<$:_CRT_NONSTDC_NO_DEPRECATE>) target_link_libraries(bgen PUBLIC ELAPSED::elapsed) target_link_libraries(bgen PUBLIC ATHR::athr) -target_link_libraries(bgen PUBLIC ZLIB::ZLIB) +target_link_libraries(bgen PUBLIC ZLIB::zlibstatic) target_link_libraries(bgen PUBLIC ZSTD::zstd) target_compile_options(bgen PRIVATE ${WARNING_FLAGS}) diff --git a/cmake/compiler-options.cmake b/cmake/compiler-options.cmake new file mode 100644 index 0000000..37e059f --- /dev/null +++ b/cmake/compiler-options.cmake @@ -0,0 +1,54 @@ +# +# Copyright (C) 2018 by George Cave - gcave@stablecoder.ca +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +option(ENABLE_ALL_WARNINGS "Compile with all warnings for the major compilers" + OFF) +option(ENABLE_EFFECTIVE_CXX "Enable Effective C++ warnings" OFF) +option(GENERATE_DEPENDENCY_DATA "Generates .d files with header dependencies" + OFF) + +if(ENABLE_ALL_WARNINGS) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" + OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" + OR CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang" + OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?[Cc]lang") + # GCC/Clang + add_compile_options(-Wall -Wextra) + elseif(MSVC) + # MSVC + add_compile_options(/W4) + endif() +endif() + +if(ENABLE_EFFECTIVE_CXX) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" + OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" + OR CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang" + OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?[Cc]lang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weffc++") + endif() +endif() + +if(GENERATE_DEPENDENCY_DATA) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" + OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" + OR CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang" + OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?[Cc]lang") + add_compile_options(-MD) + else() + message( + WARNING "Cannot generate header dependency on non GCC/Clang compilers.") + endif() +endif() diff --git a/cmake/sanitizers.cmake b/cmake/sanitizers.cmake new file mode 100644 index 0000000..27ac6c4 --- /dev/null +++ b/cmake/sanitizers.cmake @@ -0,0 +1,220 @@ +# +# Copyright (C) 2018-2022 by George Cave - gcave@stablecoder.ca +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +include(CheckCSourceCompiles) + +set(USE_SANITIZER + "" + CACHE + STRING + "Compile with a sanitizer. Options are: Address, Memory, MemoryWithOrigins, Undefined, Thread, Leak, 'Address;Undefined', CFI" +) + +function(append value) + foreach(variable ${ARGN}) + set(${variable} + "${${variable}} ${value}" + PARENT_SCOPE) + endforeach(variable) +endfunction() + +function(append_quoteless value) + foreach(variable ${ARGN}) + set(${variable} + ${${variable}} ${value} + PARENT_SCOPE) + endforeach(variable) +endfunction() + +function(test_san_flags return_var flags) + set(QUIET_BACKUP ${CMAKE_REQUIRED_QUIET}) + set(CMAKE_REQUIRED_QUIET TRUE) + unset(${return_var} CACHE) + set(FLAGS_BACKUP ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS "${flags}") + check_c_source_compiles("int main() { return 0; }" ${return_var}) + set(CMAKE_REQUIRED_FLAGS "${FLAGS_BACKUP}") + set(CMAKE_REQUIRED_QUIET "${QUIET_BACKUP}") +endfunction() + +if(USE_SANITIZER) + append("-fno-omit-frame-pointer" CMAKE_C_FLAGS CMAKE_C_FLAGS) + + unset(SANITIZER_SELECTED_FLAGS) + + if(UNIX) + + if(uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") + append("-O1" CMAKE_C_FLAGS CMAKE_C_FLAGS) + endif() + + if(USE_SANITIZER MATCHES "([Aa]ddress)") + # Optional: -fno-optimize-sibling-calls -fsanitize-address-use-after-scope + message(STATUS "Testing with Address sanitizer") + set(SANITIZER_ADDR_FLAG "-fsanitize=address") + test_san_flags(SANITIZER_ADDR_AVAILABLE ${SANITIZER_ADDR_FLAG}) + if(SANITIZER_ADDR_AVAILABLE) + message(STATUS " Building with Address sanitizer") + append("${SANITIZER_ADDR_FLAG}" SANITIZER_SELECTED_FLAGS) + + if(AFL) + append_quoteless(AFL_USE_ASAN=1 CMAKE_C_COMPILER_LAUNCHER + CMAKE_C_COMPILER_LAUNCHER) + endif() + else() + message( + FATAL_ERROR "Address sanitizer not available for ${CMAKE_C_COMPILER}") + endif() + endif() + + if(USE_SANITIZER MATCHES "([Mm]emory([Ww]ith[Oo]rigins)?)") + # Optional: -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 + set(SANITIZER_MEM_FLAG "-fsanitize=memory") + if(USE_SANITIZER MATCHES "([Mm]emory[Ww]ith[Oo]rigins)") + message(STATUS "Testing with MemoryWithOrigins sanitizer") + append("-fsanitize-memory-track-origins" SANITIZER_MEM_FLAG) + else() + message(STATUS "Testing with Memory sanitizer") + endif() + test_san_flags(SANITIZER_MEM_AVAILABLE ${SANITIZER_MEM_FLAG}) + if(SANITIZER_MEM_AVAILABLE) + if(USE_SANITIZER MATCHES "([Mm]emory[Ww]ith[Oo]rigins)") + message(STATUS " Building with MemoryWithOrigins sanitizer") + else() + message(STATUS " Building with Memory sanitizer") + endif() + append("${SANITIZER_MEM_FLAG}" SANITIZER_SELECTED_FLAGS) + + if(AFL) + append_quoteless(AFL_USE_MSAN=1 CMAKE_C_COMPILER_LAUNCHER + CMAKE_C_COMPILER_LAUNCHER) + endif() + else() + message( + FATAL_ERROR + "Memory [With Origins] sanitizer not available for ${CMAKE_C_COMPILER}" + ) + endif() + endif() + + if(USE_SANITIZER MATCHES "([Uu]ndefined)") + message(STATUS "Testing with Undefined Behaviour sanitizer") + set(SANITIZER_UB_FLAG "-fsanitize=undefined") + if(EXISTS "${BLACKLIST_FILE}") + append("-fsanitize-blacklist=${BLACKLIST_FILE}" SANITIZER_UB_FLAG) + endif() + test_san_flags(SANITIZER_UB_AVAILABLE ${SANITIZER_UB_FLAG}) + if(SANITIZER_UB_AVAILABLE) + message(STATUS " Building with Undefined Behaviour sanitizer") + append("${SANITIZER_UB_FLAG}" SANITIZER_SELECTED_FLAGS) + + if(AFL) + append_quoteless(AFL_USE_UBSAN=1 CMAKE_C_COMPILER_LAUNCHER + CMAKE_C_COMPILER_LAUNCHER) + endif() + else() + message( + FATAL_ERROR + "Undefined Behaviour sanitizer not available for ${CMAKE_C_COMPILER}" + ) + endif() + endif() + + if(USE_SANITIZER MATCHES "([Tt]hread)") + message(STATUS "Testing with Thread sanitizer") + set(SANITIZER_THREAD_FLAG "-fsanitize=thread") + test_san_flags(SANITIZER_THREAD_AVAILABLE ${SANITIZER_THREAD_FLAG}) + if(SANITIZER_THREAD_AVAILABLE) + message(STATUS " Building with Thread sanitizer") + append("${SANITIZER_THREAD_FLAG}" SANITIZER_SELECTED_FLAGS) + + if(AFL) + append_quoteless(AFL_USE_TSAN=1 CMAKE_C_COMPILER_LAUNCHER + CMAKE_C_COMPILER_LAUNCHER) + endif() + else() + message( + FATAL_ERROR "Thread sanitizer not available for ${CMAKE_C_COMPILER}") + endif() + endif() + + if(USE_SANITIZER MATCHES "([Ll]eak)") + message(STATUS "Testing with Leak sanitizer") + set(SANITIZER_LEAK_FLAG "-fsanitize=leak") + test_san_flags(SANITIZER_LEAK_AVAILABLE ${SANITIZER_LEAK_FLAG}) + if(SANITIZER_LEAK_AVAILABLE) + message(STATUS " Building with Leak sanitizer") + append("${SANITIZER_LEAK_FLAG}" SANITIZER_SELECTED_FLAGS) + + if(AFL) + append_quoteless(AFL_USE_LSAN=1 CMAKE_C_COMPILER_LAUNCHER + CMAKE_C_COMPILER_LAUNCHER) + endif() + else() + message( + FATAL_ERROR "Thread sanitizer not available for ${CMAKE_C_COMPILER}") + endif() + endif() + + if(USE_SANITIZER MATCHES "([Cc][Ff][Ii])") + message(STATUS "Testing with Control Flow Integrity(CFI) sanitizer") + set(SANITIZER_CFI_FLAG "-fsanitize=cfi") + test_san_flags(SANITIZER_CFI_AVAILABLE ${SANITIZER_CFI_FLAG}) + if(SANITIZER_CFI_AVAILABLE) + message(STATUS " Building with Control Flow Integrity(CFI) sanitizer") + append("${SANITIZER_LEAK_FLAG}" SANITIZER_SELECTED_FLAGS) + + if(AFL) + append_quoteless(AFL_USE_CFISAN=1 CMAKE_C_COMPILER_LAUNCHER + CMAKE_C_COMPILER_LAUNCHER) + endif() + else() + message( + FATAL_ERROR + "Control Flow Integrity(CFI) sanitizer not available for ${CMAKE_C_COMPILER}" + ) + endif() + endif() + + message(STATUS "Sanitizer flags: ${SANITIZER_SELECTED_FLAGS}") + test_san_flags(SANITIZER_SELECTED_COMPATIBLE ${SANITIZER_SELECTED_FLAGS}) + if(SANITIZER_SELECTED_COMPATIBLE) + message(STATUS " Building with ${SANITIZER_SELECTED_FLAGS}") + append("${SANITIZER_SELECTED_FLAGS}" CMAKE_C_FLAGS CMAKE_C_FLAGS) + else() + message( + FATAL_ERROR + " Sanitizer flags ${SANITIZER_SELECTED_FLAGS} are not compatible.") + endif() + elseif(MSVC) + if(USE_SANITIZER MATCHES "([Aa]ddress)") + message(STATUS "Building with Address sanitizer") + append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_C_FLAGS) + + if(AFL) + append_quoteless(AFL_USE_ASAN=1 CMAKE_C_COMPILER_LAUNCHER + CMAKE_C_COMPILER_LAUNCHER) + endif() + else() + message( + FATAL_ERROR + "This sanitizer not yet supported in the MSVC environment: ${USE_SANITIZER}" + ) + endif() + else() + message(FATAL_ERROR "USE_SANITIZER is not supported on this platform.") + endif() + +endif() diff --git a/src/layout1.c b/src/layout1.c index 8c969a6..46b5a59 100755 --- a/src/layout1.c +++ b/src/layout1.c @@ -5,7 +5,7 @@ #include "genotype.h" #include "mem.h" #include "report.h" -#include "zip/zlib.h" +#include "unzlib.h" #include #include diff --git a/src/layout2.c b/src/layout2.c index b01787c..775e57a 100755 --- a/src/layout2.c +++ b/src/layout2.c @@ -4,7 +4,7 @@ #include "free.h" #include "genotype.h" #include "mem.h" -#include "zip/zlib.h" +#include "unzlib.h" #include "unzstd.h" #include #include diff --git a/src/zip/zlib.c b/src/unzlib.c similarity index 98% rename from src/zip/zlib.c rename to src/unzlib.c index 6d937ed..8514a67 100755 --- a/src/zip/zlib.c +++ b/src/unzlib.c @@ -1,10 +1,10 @@ #define ZLIB_CONST -#include "zip/zlib.h" +#include "unzlib.h" #include "report.h" +#include "zlib.h" #include #include #include -#include int bgen_unzlib(char const* src, size_t src_size, char** dst, size_t* dst_size) { diff --git a/src/zip/zlib.h b/src/unzlib.h similarity index 80% rename from src/zip/zlib.h rename to src/unzlib.h index 90ecdf1..b362eae 100755 --- a/src/zip/zlib.h +++ b/src/unzlib.h @@ -1,5 +1,5 @@ -#ifndef BGEN_ZIP_ZLIB_H -#define BGEN_ZIP_ZLIB_H +#ifndef BGEN_UNZLIB_H +#define BGEN_UNZLIB_H #include diff --git a/src/variant.c b/src/variant.c index e1ed8dc..707e35a 100755 --- a/src/variant.c +++ b/src/variant.c @@ -119,7 +119,11 @@ struct bgen_variant* bgen_variant_next(struct bgen_file* bgen_file, int* error) return NULL; } -struct bgen_variant* bgen_variant_end(struct bgen_file const* bgen_file) { return NULL; } +struct bgen_variant* bgen_variant_end(struct bgen_file const* bgen_file) +{ + (void)bgen_file; + return NULL; +} void bgen_variant_destroy(struct bgen_variant const* variant) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fa73f83..10f209d 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -21,7 +21,7 @@ function(bgen_add_test name) # Ugly hacky to make the tests work on Windows. file(TO_CMAKE_PATH "$ENV{PATH}" PATH) - list(APPEND PATH $/../bin) + list(APPEND PATH $/../bin) list(APPEND PATH $/../bin) list(APPEND PATH $) list(APPEND PATH $)