From 196352a0c39cd1ea85115207ff7ad1117f97e496 Mon Sep 17 00:00:00 2001 From: Jack Pappas Date: Sun, 3 May 2015 18:55:52 -0400 Subject: [PATCH 1/2] Use CMake to hide symbols by default when compiling with GCC and Clang. Moved preprocessor ifdefs which define the symbol indicating an exported symbol into a common file (blosc-export.h) that handles both blosc and the shuffle implementations. For testing, build a special version of the blosc shared library which exports some normally-hidden symbols; the test binaries now link to this version of the library so they can test internal library functions. --- blosc/CMakeLists.txt | 42 +++++++++++++++++++++++++++++------- blosc/blosc-export.h | 42 ++++++++++++++++++++++++++++++++++++ blosc/blosc.h | 48 ++++++++++++++++++----------------------- blosc/shuffle-avx2.h | 4 ++-- blosc/shuffle-common.h | 14 +----------- blosc/shuffle-generic.h | 4 ++-- blosc/shuffle-sse2.h | 4 ++-- blosc/shuffle.h | 4 ++-- tests/CMakeLists.txt | 6 +++--- 9 files changed, 109 insertions(+), 59 deletions(-) create mode 100644 blosc/blosc-export.h diff --git a/blosc/CMakeLists.txt b/blosc/CMakeLists.txt index f1848860..f569493e 100644 --- a/blosc/CMakeLists.txt +++ b/blosc/CMakeLists.txt @@ -3,6 +3,12 @@ add_definitions(-DUSING_CMAKE) set(INTERNAL_LIBS ${CMAKE_SOURCE_DIR}/internal-complibs) +# Hide symbols by default unless they're specifically exported. +# This makes it easier to keep the set of exported symbols the +# same across all compilers/platforms. +set(CMAKE_C_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) + # includes if(NOT DEACTIVATE_LZ4) if (LZ4_FOUND) @@ -89,7 +95,6 @@ if(NOT DEACTIVATE_ZLIB) endif(ZLIB_FOUND) endif(NOT DEACTIVATE_ZLIB) - # targets add_library(blosc_shared SHARED ${SOURCES}) set_target_properties(blosc_shared PROPERTIES OUTPUT_NAME blosc) @@ -97,10 +102,13 @@ set_target_properties(blosc_shared PROPERTIES VERSION ${version_string} SOVERSION 1 # Change this when an ABI change happens ) -if (MSVC) - set_target_properties (blosc_shared PROPERTIES COMPILE_FLAGS -DBLOSC_DLL_EXPORT=TRUE) -endif(MSVC) +set_property( + TARGET blosc_shared + APPEND PROPERTY COMPILE_DEFINITIONS BLOSC_SHARED_LIBRARY) +# Based on the target architecture and hardware features supported +# by the C compiler, set hardware architecture optimization flags +# for specific shuffle implementations. if(COMPILER_SUPPORT_SSE2) if (MSVC) # MSVC targets SSE2 by default on 64-bit configurations, but not 32-bit configurations. @@ -132,20 +140,38 @@ if(COMPILER_SUPPORT_AVX2) SOURCE shuffle.c APPEND PROPERTY COMPILE_DEFINITIONS SHUFFLE_AVX2_ENABLED) endif(COMPILER_SUPPORT_AVX2) + +# When the option has been selected to compile the test suite, +# compile an additional version of blosc_shared which exports +# some normally-hidden symbols (to facilitate unit testing). +if (BUILD_TESTS) + add_library(blosc_testing SHARED ${SOURCES}) + set_target_properties(blosc_testing PROPERTIES OUTPUT_NAME blosc_testing) + set_property( + TARGET blosc_testing + APPEND PROPERTY COMPILE_DEFINITIONS BLOSC_SHARED_LIBRARY) + set_property( + TARGET blosc_testing + APPEND PROPERTY COMPILE_DEFINITIONS BLOSC_TESTING) +endif() + target_link_libraries(blosc_shared ${LIBS}) +if (blosc_testing) + target_link_libraries(blosc_testing ${LIBS}) +endif() if(BUILD_STATIC) add_library(blosc_static STATIC ${SOURCES}) set_target_properties(blosc_static PROPERTIES OUTPUT_NAME blosc) - if (MSVC) - set_target_properties(blosc_static PROPERTIES PREFIX lib) - endif() + if (MSVC) + set_target_properties(blosc_static PROPERTIES PREFIX lib) + endif() target_link_libraries(blosc_static ${LIBS}) endif(BUILD_STATIC) # install -install(FILES blosc.h DESTINATION include COMPONENT DEV) +install(FILES blosc.h blosc-export.h DESTINATION include COMPONENT DEV) install(TARGETS blosc_shared DESTINATION ${lib_dir} COMPONENT LIB) if(BUILD_STATIC) install(TARGETS blosc_static DESTINATION ${lib_dir} COMPONENT DEV) diff --git a/blosc/blosc-export.h b/blosc/blosc-export.h new file mode 100644 index 00000000..3fbb4614 --- /dev/null +++ b/blosc/blosc-export.h @@ -0,0 +1,42 @@ +/********************************************************************* + Blosc - Blocked Shuffling and Compression Library + + Author: Francesc Alted + + See LICENSES/BLOSC.txt for details about copyright and rights to use. +**********************************************************************/ +#ifndef BLOSC_EXPORT_H +#define BLOSC_EXPORT_H + +/* Macros for specifying exported symbols. + BLOSC_EXPORT is used to decorate symbols that should be + exported by the blosc shared library. + BLOSC_NO_EXPORT is used to decorate symbols that should NOT + be exported by the blosc shared library. +*/ +#if defined(BLOSC_SHARED_LIBRARY) + #if defined(_MSC_VER) + #define BLOSC_EXPORT __declspec(dllexport) + #elif (defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__) + #if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) + #define BLOSC_EXPORT __attribute__((dllexport)) + #else + #define BLOSC_EXPORT __attribute__((visibility("default"))) + #endif /* defined(_WIN32) || defined(__CYGWIN__) */ + #else + #error Can't determine how to define BLOSC_EXPORT for this compiler. + #endif +#else + #define BLOSC_EXPORT +#endif /* defined(BLOSC_SHARED_LIBRARY) */ + +/* BLOSC_NO_EXPORT is empty by default. */ +#define BLOSC_NO_EXPORT + +/* When testing, export everything to make it easier to implement tests. */ +#if defined(BLOSC_TESTING) + #undef BLOSC_NO_EXPORT + #define BLOSC_NO_EXPORT BLOSC_EXPORT +#endif /* defined(BLOSC_TESTING) */ + +#endif /* BLOSC_EXPORT_H */ diff --git a/blosc/blosc.h b/blosc/blosc.h index a13836da..d1ca8917 100644 --- a/blosc/blosc.h +++ b/blosc/blosc.h @@ -10,18 +10,12 @@ #include #include +#include "blosc-export.h" + #ifdef __cplusplus extern "C" { #endif -#ifdef BLOSC_DLL_EXPORT - #undef BLOSC_DLL_EXPORT - #define BLOSC_DLL_EXPORT __declspec(dllexport) -#else - #undef BLOSC_DLL_EXPORT - #define BLOSC_DLL_EXPORT -#endif - /* Version numbers */ #define BLOSC_VERSION_MAJOR 1 /* for major interface/format changes */ #define BLOSC_VERSION_MINOR 6 /* for minor interface/format changes */ @@ -109,7 +103,7 @@ extern "C" { which case you should *exclusively* use the blosc_compress_ctx()/blosc_decompress_ctx() pair (see below). */ -BLOSC_DLL_EXPORT void blosc_init(void); +BLOSC_EXPORT void blosc_init(void); /** @@ -119,7 +113,7 @@ BLOSC_DLL_EXPORT void blosc_init(void); unless you have not used blosc_init() before (see blosc_init() above). */ -BLOSC_DLL_EXPORT void blosc_destroy(void); +BLOSC_EXPORT void blosc_destroy(void); /** @@ -156,7 +150,7 @@ BLOSC_DLL_EXPORT void blosc_destroy(void); should never happen. If you see this, please report it back together with the buffer data causing this and compression settings. */ -BLOSC_DLL_EXPORT int blosc_compress(int clevel, int doshuffle, size_t typesize, +BLOSC_EXPORT int blosc_compress(int clevel, int doshuffle, size_t typesize, size_t nbytes, const void *src, void *dest, size_t destsize); @@ -180,7 +174,7 @@ BLOSC_DLL_EXPORT int blosc_compress(int clevel, int doshuffle, size_t typesize, should never happen. If you see this, please report it back together with the buffer data causing this and compression settings. */ -BLOSC_DLL_EXPORT int blosc_compress_ctx(int clevel, int doshuffle, size_t typesize, +BLOSC_EXPORT int blosc_compress_ctx(int clevel, int doshuffle, size_t typesize, size_t nbytes, const void* src, void* dest, size_t destsize, const char* compressor, size_t blocksize, int numinternalthreads); @@ -198,7 +192,7 @@ BLOSC_DLL_EXPORT int blosc_compress_ctx(int clevel, int doshuffle, size_t typesi output buffer is not large enough, then 0 (zero) or a negative value will be returned instead. */ -BLOSC_DLL_EXPORT int blosc_decompress(const void *src, void *dest, size_t destsize); +BLOSC_EXPORT int blosc_decompress(const void *src, void *dest, size_t destsize); /** @@ -218,7 +212,7 @@ BLOSC_DLL_EXPORT int blosc_decompress(const void *src, void *dest, size_t destsi output buffer is not large enough, then 0 (zero) or a negative value will be returned instead. */ -BLOSC_DLL_EXPORT int blosc_decompress_ctx(const void *src, void *dest, +BLOSC_EXPORT int blosc_decompress_ctx(const void *src, void *dest, size_t destsize, int numinternalthreads); /** @@ -229,7 +223,7 @@ BLOSC_DLL_EXPORT int blosc_decompress_ctx(const void *src, void *dest, Returns the number of bytes copied to `dest` or a negative value if some error happens. */ -BLOSC_DLL_EXPORT int blosc_getitem(const void *src, int start, int nitems, void *dest); +BLOSC_EXPORT int blosc_getitem(const void *src, int start, int nitems, void *dest); /** @@ -240,7 +234,7 @@ BLOSC_DLL_EXPORT int blosc_getitem(const void *src, int start, int nitems, void Returns the previous number of threads. */ -BLOSC_DLL_EXPORT int blosc_set_nthreads(int nthreads); +BLOSC_EXPORT int blosc_set_nthreads(int nthreads); /** @@ -252,7 +246,7 @@ BLOSC_DLL_EXPORT int blosc_set_nthreads(int nthreads); for it in this build, it returns a -1. Else it returns the code for the compressor (>=0). */ -BLOSC_DLL_EXPORT int blosc_set_compressor(const char* compname); +BLOSC_EXPORT int blosc_set_compressor(const char* compname); /** @@ -262,7 +256,7 @@ BLOSC_DLL_EXPORT int blosc_set_compressor(const char* compname); for it in this build, -1 is returned. Else, the compressor code is returned. */ -BLOSC_DLL_EXPORT int blosc_compcode_to_compname(int compcode, char **compname); +BLOSC_EXPORT int blosc_compcode_to_compname(int compcode, char **compname); /** @@ -271,7 +265,7 @@ BLOSC_DLL_EXPORT int blosc_compcode_to_compname(int compcode, char **compname); If the compressor name is not recognized, or there is not support for it in this build, -1 is returned instead. */ -BLOSC_DLL_EXPORT int blosc_compname_to_compcode(const char *compname); +BLOSC_EXPORT int blosc_compname_to_compcode(const char *compname); /** @@ -285,7 +279,7 @@ BLOSC_DLL_EXPORT int blosc_compname_to_compcode(const char *compname); This function should always succeed. */ -BLOSC_DLL_EXPORT char* blosc_list_compressors(void); +BLOSC_EXPORT char* blosc_list_compressors(void); /** @@ -302,7 +296,7 @@ BLOSC_DLL_EXPORT char* blosc_list_compressors(void); If the compressor is supported, it returns the code for the library (>=0). If it is not supported, this function returns -1. */ -BLOSC_DLL_EXPORT int blosc_get_complib_info(char *compname, char **complib, char **version); +BLOSC_EXPORT int blosc_get_complib_info(char *compname, char **complib, char **version); /** @@ -311,7 +305,7 @@ BLOSC_DLL_EXPORT int blosc_get_complib_info(char *compname, char **complib, char problems releasing the resources, it returns a negative number, else it returns 0. */ -BLOSC_DLL_EXPORT int blosc_free_resources(void); +BLOSC_EXPORT int blosc_free_resources(void); /** @@ -325,7 +319,7 @@ BLOSC_DLL_EXPORT int blosc_free_resources(void); This function should always succeed. */ -BLOSC_DLL_EXPORT void blosc_cbuffer_sizes(const void *cbuffer, size_t *nbytes, +BLOSC_EXPORT void blosc_cbuffer_sizes(const void *cbuffer, size_t *nbytes, size_t *cbytes, size_t *blocksize); @@ -343,7 +337,7 @@ BLOSC_DLL_EXPORT void blosc_cbuffer_sizes(const void *cbuffer, size_t *nbytes, This function should always succeed. */ -BLOSC_DLL_EXPORT void blosc_cbuffer_metainfo(const void *cbuffer, size_t *typesize, +BLOSC_EXPORT void blosc_cbuffer_metainfo(const void *cbuffer, size_t *typesize, int *flags); @@ -354,7 +348,7 @@ BLOSC_DLL_EXPORT void blosc_cbuffer_metainfo(const void *cbuffer, size_t *typesi This function should always succeed. */ -BLOSC_DLL_EXPORT void blosc_cbuffer_versions(const void *cbuffer, int *version, +BLOSC_EXPORT void blosc_cbuffer_versions(const void *cbuffer, int *version, int *versionlz); @@ -363,7 +357,7 @@ BLOSC_DLL_EXPORT void blosc_cbuffer_versions(const void *cbuffer, int *version, This function should always succeed. */ -BLOSC_DLL_EXPORT char *blosc_cbuffer_complib(const void *cbuffer); +BLOSC_EXPORT char *blosc_cbuffer_complib(const void *cbuffer); @@ -378,7 +372,7 @@ BLOSC_DLL_EXPORT char *blosc_cbuffer_complib(const void *cbuffer); Force the use of a specific blocksize. If 0, an automatic blocksize will be used (the default). */ -BLOSC_DLL_EXPORT void blosc_set_blocksize(size_t blocksize); +BLOSC_EXPORT void blosc_set_blocksize(size_t blocksize); #ifdef __cplusplus } diff --git a/blosc/shuffle-avx2.h b/blosc/shuffle-avx2.h index 21770b2e..b90d752f 100644 --- a/blosc/shuffle-avx2.h +++ b/blosc/shuffle-avx2.h @@ -20,13 +20,13 @@ extern "C" { /** AVX2-accelerated shuffle routine. */ -BLOSC_DLL_EXPORT void shuffle_avx2(const size_t bytesoftype, const size_t blocksize, +BLOSC_NO_EXPORT void shuffle_avx2(const size_t bytesoftype, const size_t blocksize, const uint8_t* const _src, uint8_t* const _dest); /** AVX2-accelerated unshuffle routine. */ -BLOSC_DLL_EXPORT void unshuffle_avx2(const size_t bytesoftype, const size_t blocksize, +BLOSC_NO_EXPORT void unshuffle_avx2(const size_t bytesoftype, const size_t blocksize, const uint8_t* const _src, uint8_t* const _dest); #ifdef __cplusplus diff --git a/blosc/shuffle-common.h b/blosc/shuffle-common.h index d377f971..3dacd6ed 100644 --- a/blosc/shuffle-common.h +++ b/blosc/shuffle-common.h @@ -9,19 +9,7 @@ #ifndef SHUFFLE_COMMON_H #define SHUFFLE_COMMON_H -/* Macro for specifying an exported function. */ -#if defined(_WIN32) && defined(BLOSC_DLL_EXPORT) - #undef BLOSC_DLL_EXPORT - #define BLOSC_DLL_EXPORT __declspec(dllexport) -#else -#if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__) - #undef BLOSC_DLL_EXPORT - #define BLOSC_DLL_EXPORT __attribute__((visibility("hidden"))) -#else - #undef BLOSC_DLL_EXPORT - #define BLOSC_DLL_EXPORT -#endif -#endif +#include "blosc-export.h" /* Define the __SSE2__ symbol if compiling with Visual C++ and targeting the minimum architecture level supporting SSE2. diff --git a/blosc/shuffle-generic.h b/blosc/shuffle-generic.h index 813cdb09..1e6b4867 100644 --- a/blosc/shuffle-generic.h +++ b/blosc/shuffle-generic.h @@ -24,13 +24,13 @@ extern "C" { /** Generic (non-hardware-accelerated) shuffle routine. */ -BLOSC_DLL_EXPORT void shuffle_generic(const size_t bytesoftype, const size_t blocksize, +BLOSC_NO_EXPORT void shuffle_generic(const size_t bytesoftype, const size_t blocksize, const uint8_t* const _src, uint8_t* const _dest); /** Generic (non-hardware-accelerated) unshuffle routine. */ -BLOSC_DLL_EXPORT void unshuffle_generic(const size_t bytesoftype, const size_t blocksize, +BLOSC_NO_EXPORT void unshuffle_generic(const size_t bytesoftype, const size_t blocksize, const uint8_t* const _src, uint8_t* const _dest); #ifdef __cplusplus diff --git a/blosc/shuffle-sse2.h b/blosc/shuffle-sse2.h index cafcb015..6e9d53a7 100644 --- a/blosc/shuffle-sse2.h +++ b/blosc/shuffle-sse2.h @@ -20,13 +20,13 @@ extern "C" { /** SSE2-accelerated shuffle routine. */ -BLOSC_DLL_EXPORT void shuffle_sse2(const size_t bytesoftype, const size_t blocksize, +BLOSC_NO_EXPORT void shuffle_sse2(const size_t bytesoftype, const size_t blocksize, const uint8_t* const _src, uint8_t* const _dest); /** SSE2-accelerated unshuffle routine. */ -BLOSC_DLL_EXPORT void unshuffle_sse2(const size_t bytesoftype, const size_t blocksize, +BLOSC_NO_EXPORT void unshuffle_sse2(const size_t bytesoftype, const size_t blocksize, const uint8_t* const _src, uint8_t* const _dest); #ifdef __cplusplus diff --git a/blosc/shuffle.h b/blosc/shuffle.h index cccfa899..8740b268 100644 --- a/blosc/shuffle.h +++ b/blosc/shuffle.h @@ -31,7 +31,7 @@ extern "C" { calling the hardware-accelerated routines because this method is both cross- platform and future-proof. */ -BLOSC_DLL_EXPORT void shuffle(const size_t bytesoftype, const size_t blocksize, +BLOSC_NO_EXPORT void shuffle(const size_t bytesoftype, const size_t blocksize, const uint8_t* const _src, uint8_t* const _dest); /** @@ -44,7 +44,7 @@ BLOSC_DLL_EXPORT void shuffle(const size_t bytesoftype, const size_t blocksize, calling the hardware-accelerated routines because this method is both cross- platform and future-proof. */ -BLOSC_DLL_EXPORT void unshuffle(const size_t bytesoftype, const size_t blocksize, +BLOSC_NO_EXPORT void unshuffle(const size_t bytesoftype, const size_t blocksize, const uint8_t* const _src, uint8_t* const _dest); #ifdef __cplusplus diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9c2b8103..a6d76e5b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,10 +17,10 @@ foreach(source ${SOURCES}) POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different - "${PROJECT_BINARY_DIR}/blosc/\$\(Configuration\)/blosc.dll" - "${CMAKE_CURRENT_BINARY_DIR}/\$\(Configuration\)/blosc.dll") + "${PROJECT_BINARY_DIR}/blosc/\$\(Configuration\)/blosc_testing.dll" + "${CMAKE_CURRENT_BINARY_DIR}/\$\(Configuration\)/blosc_testing.dll") endif(MSVC) - target_link_libraries(${target} blosc_shared) + target_link_libraries(${target} blosc_testing) add_test(test_${target} ${target}) endforeach(source) From b1b043d909ebcf57ed67dcb784e8feafd605c917 Mon Sep 17 00:00:00 2001 From: Jack Pappas Date: Sat, 9 May 2015 10:03:59 -0400 Subject: [PATCH 2/2] Some fixes for building on non-Windows platforms with GCC and Clang. --- blosc/CMakeLists.txt | 19 +++++++++++++------ blosc/blosc-export.h | 11 +++++++---- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/blosc/CMakeLists.txt b/blosc/CMakeLists.txt index f569493e..29efd748 100644 --- a/blosc/CMakeLists.txt +++ b/blosc/CMakeLists.txt @@ -145,19 +145,26 @@ endif(COMPILER_SUPPORT_AVX2) # compile an additional version of blosc_shared which exports # some normally-hidden symbols (to facilitate unit testing). if (BUILD_TESTS) - add_library(blosc_testing SHARED ${SOURCES}) - set_target_properties(blosc_testing PROPERTIES OUTPUT_NAME blosc_testing) + add_library(blosc_shared_testing SHARED ${SOURCES}) + set_target_properties(blosc_shared_testing PROPERTIES OUTPUT_NAME blosc_testing) set_property( - TARGET blosc_testing + TARGET blosc_shared_testing APPEND PROPERTY COMPILE_DEFINITIONS BLOSC_SHARED_LIBRARY) set_property( - TARGET blosc_testing + TARGET blosc_shared_testing APPEND PROPERTY COMPILE_DEFINITIONS BLOSC_TESTING) + # TEMP : CMake doesn't automatically add -lpthread here like it does + # for the blosc_shared target. Force it for now. + if(UNIX) + set_property( + TARGET blosc_shared_testing + APPEND PROPERTY LINK_FLAGS "-lpthread") + endif() endif() target_link_libraries(blosc_shared ${LIBS}) -if (blosc_testing) - target_link_libraries(blosc_testing ${LIBS}) +if (BUILD_TESTS) + target_link_libraries(blosc_shared_testing ${LIBS}) endif() if(BUILD_STATIC) diff --git a/blosc/blosc-export.h b/blosc/blosc-export.h index 3fbb4614..49df9296 100644 --- a/blosc/blosc-export.h +++ b/blosc/blosc-export.h @@ -24,14 +24,17 @@ #define BLOSC_EXPORT __attribute__((visibility("default"))) #endif /* defined(_WIN32) || defined(__CYGWIN__) */ #else - #error Can't determine how to define BLOSC_EXPORT for this compiler. + #error Cannot determine how to define BLOSC_EXPORT for this compiler. #endif #else #define BLOSC_EXPORT #endif /* defined(BLOSC_SHARED_LIBRARY) */ -/* BLOSC_NO_EXPORT is empty by default. */ -#define BLOSC_NO_EXPORT +#if defined(__GNUC__) || defined(__clang__) + #define BLOSC_NO_EXPORT __attribute__((visibility("hidden"))) +#else + #define BLOSC_NO_EXPORT +#endif /* defined(__GNUC__) || defined(__clang__) */ /* When testing, export everything to make it easier to implement tests. */ #if defined(BLOSC_TESTING) @@ -39,4 +42,4 @@ #define BLOSC_NO_EXPORT BLOSC_EXPORT #endif /* defined(BLOSC_TESTING) */ -#endif /* BLOSC_EXPORT_H */ +#endif /* BLOSC_EXPORT_H */