Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ project(inflatelib
LANGUAGES C CXX
)

# "Production" options
option(INFLATELIB_BUILD_SHARED "Build inflatelib as a shared library" OFF)

# "Test" options
option(INFLATELIB_TEST "Build tests for local development and CI validation" ON)
option(INFLATELIB_ASAN "Build with Address Sanitizer" OFF)
option(INFLATELIB_UBSAN "Build with Undefined Behavior Sanitizer" OFF)
Expand Down
20 changes: 18 additions & 2 deletions scripts/init.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ goto :init
:usage
echo USAGE:
echo init.cmd [--help] [-c^|--compiler ^<clang^|msvc^>] [-g^|--generator ^<ninja^|msbuild^>]
echo [-b^|--build-type ^<debug^|release^|relwithdebinfo^|minsizerel^>] [-i^|--install-prefix install/path]
echo [-b^|--build-type ^<debug^|release^|relwithdebinfo^|minsizerel^>] [-d|--dll] [-i^|--install-prefix install/path]
echo [-s^|--sanitize ^<address^|undefined^>] [-f^|--fuzz] [-p^|--vcpkg path/to/vcpkg/root]
echo.
echo ARGUMENTS
echo -c^|--compiler Controls the compiler used, either 'clang' (the default) or 'msvc'
echo -g^|--generator Controls the CMake generator used, either 'ninja' (the default) or 'msbuild'
echo -b^|--build-type Controls the value of 'CMAKE_BUILD_TYPE', either 'debug' (the default), 'release',
echo 'relwithdebinfo', or 'minsizerel'
echo -d^|--dll When present, builds the library as a shared library (DLL), otherwise the library is
echo built as a static library.
echo -i^|--install-prefix Specifies the path used for 'CMAKE_INSTALL_PREFIX'. If this argument is not specified,
echo 'CMAKE_INSTALL_PREFIX' will not be passed to CMake during initialization.
echo -s^|--sanitize Specifies the sanitizer to use, either 'address' or 'ub'. If this argument is not
Expand All @@ -36,6 +38,7 @@ goto :init
set COMPILER=
set GENERATOR=
set BUILD_TYPE=
set BUILD_SHARED=0
set INSTALL_PREFIX=
set CMAKE_ARGS=
set VCPKG_ROOT_PATH=
Expand Down Expand Up @@ -94,6 +97,15 @@ goto :init
goto :parse
)

set BUILD_SHARED_SET=0
if /I "%~1"=="-d" set BUILD_SHARED_SET=1
if /I "%~1"=="--dll" set BUILD_SHARED_SET=1
if %BUILD_SHARED_SET%==1 (
set BUILD_SHARED=1
shift
goto :parse
)

set INSTALL_PREFIX_SET=0
if /I "%~1"=="-i" set INSTALL_PREFIX_SET=1
if /I "%~1"=="--install-prefix" set INSTALL_PREFIX_SET=1
Expand Down Expand Up @@ -172,7 +184,7 @@ goto :init
if "%VCPKG_ROOT_PATH%"=="" (
REM First check for %VCPKG_ROOT% variable
if defined VCPKG_ROOT (
set VCPKG_ROOT_PATH=%VCPKG_ROOT%
set "VCPKG_ROOT_PATH=%VCPKG_ROOT%"
) else (
REM Next check the PATH for vcpkg.exe
for %%i in (vcpkg.exe) do set VCPKG_ROOT_PATH=%%~dp$PATH:i
Expand Down Expand Up @@ -221,6 +233,10 @@ goto :init
if %BUILD_TYPE%==minsizerel set CMAKE_ARGS=%CMAKE_ARGS% -DCMAKE_BUILD_TYPE=MinSizeRel
)

if %BUILD_SHARED%==1 (
set CMAKE_ARGS=%CMAKE_ARGS% -DINFLATELIB_BUILD_SHARED=ON
)

set SUFFIX=
if "%SANITIZER%"=="asan" (
set CMAKE_ARGS=%CMAKE_ARGS% -DINFLATELIB_ASAN=ON -DVCPKG_OVERLAY_TRIPLETS=..\..\..\vcpkg\triplets\asan
Expand Down
15 changes: 12 additions & 3 deletions scripts/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ fi
compiler=
generator=
buildType=
buildShared=false
installPrefix=
vcpkgRoot=
sanitizer=
Expand All @@ -20,14 +21,15 @@ cmakeArgs=()

function show_help {
echo "USAGE:"
echo " init.sh [-c <compiler>] [-b <build-type>] [-g <generator>] [-i <install-prefix>] [-s <sanitizer>] [-f]"
echo " init.sh [-c <compiler>] [-b <build-type>] [-g <generator>] [-o] [-i <install-prefix>] [-s <sanitizer>] [-f]"
echo " [-p <path-to-vcpkg-root>]"
echo
echo "ARGUMENTS:"
echo " -c Spcifies the compiler to use, either 'gcc' (the default) or 'clang'"
echo " -b Specifies the value of 'CMAKE_BUILD_TYPE', either 'debug' (the default),"
echo " 'release', 'relwithdebinfo', or 'minsizerel'"
echo " -g Specifies the generator to use, either 'ninja' (the default) or 'make'"
echo " -o Builds the library as a shared library. Otherwise builds the library as a static library."
echo " -i Specifies the path used for 'CMAKE_INSTALL_PREFIX'. If this argument is not specified,"
echo " 'CMAKE_INSTALL_PREFIX' will not be passed to CMake during initialization."
echo " -s Specifies the sanitizer to use, either 'address' or 'undefined'. If this value is not"
Expand All @@ -38,7 +40,7 @@ function show_help {
echo " will be to check for the presence of the VCPKG_ROOT environment variable"
}

while getopts :hc:b:g:i:s:fp: opt; do
while getopts :hc:b:g:oi:s:fp: opt; do
if [ -n "${OPTARG}" ]; then
arg=${OPTARG,,}
fi
Expand Down Expand Up @@ -93,6 +95,9 @@ while getopts :hc:b:g:i:s:fp: opt; do
exit 1
fi
;;
o)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly -s was already taken and getopts doesn't allow multi character options such as -so :(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alas!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could go for case sensitive S if you're feeling Spicy

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not feeling that spicy

buildShared=true
;;
i)
if [ "$installPrefix" != "" ]; then
echo>&2 "Error: Install prefix already specified. Cannot specify more than one install prefix."
Expand Down Expand Up @@ -137,7 +142,7 @@ while getopts :hc:b:g:i:s:fp: opt; do
vcpkgRoot="$OPTARG"
;;
*)
echo>&2 "ERROR: Invalid argument '-$opt'"
echo>&2 "ERROR: Invalid argument '-$OPTARG'"
show_help
exit 1
;;
Expand Down Expand Up @@ -196,6 +201,10 @@ elif [ "$buildType" == "minsizerel" ]; then
cmakeArgs+=(-DCMAKE_BUILD_TYPE=MinSizeRel)
fi

if [ "$buildShared" = true ]; then
cmakeArgs+=(-DINFLATELIB_BUILD_SHARED=ON)
fi

if [ "$installPrefix" != "" ]; then
cmakeArgs+=("-DCMAKE_INSTALL_PREFIX=$installPrefix")
fi
Expand Down
42 changes: 37 additions & 5 deletions src/include/inflatelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,38 @@

#include <stdint.h>

#ifdef __has_attribute
#if __has_attribute(visibility)
#define INFLATELIB_HAS_VISIBILITY_ATTR 1
#endif
#endif

/*
* INFLATELIB_BUILD_SHARED The library is being built as a shared library
* INFLATELIB_CONSUME_SHARED The library is being consumed as a shared library

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting debate about whether shared should be the default mode of consumption or not

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. Nice thing about being "v0" is that we can delay that decision for now. We can also choose a separate default for the vcpkg port. One thing worth mentioning is that zlib ships as a shared object by default, at least on vcpkg

* Otherwise... The library is either being built as a static library or it is being consumed in an
* unspecified manner; either as a shared or static library.
*/
#if defined(_WIN32) && defined(_MSC_VER)
#ifdef INFLATELIB_BUILD_SHARED
#define INFLATELIB_EXPORT __declspec(dllexport)
#elif defined(INFLATELIB_CONSUME_SHARED)
#define INFLATELIB_EXPORT __declspec(dllimport)
#else
#define INFLATELIB_EXPORT /* Unknown or static - don't decorate function declarations */
#endif
#elif INFLATELIB_HAS_VISIBILITY_ATTR
#define INFLATELIB_EXPORT __attribute__((visibility("default")))
#else
#define INFLATELIB_EXPORT /* Not Windows and no visibility attribute... don't decorate function declarations */
#endif

#if defined(_WIN32) && defined(_MSC_VER)
#define INFLATELIB_CALLCONV __cdecl
#else
#define INFLATELIB_CALLCONV
#endif

#ifdef __cplusplus
extern "C"
{
Expand Down Expand Up @@ -100,32 +132,32 @@ extern "C"
* Initializes the stream. The 'user_data', 'alloc', and 'free' members MUST be set prior to the init call and MUST
* NOT be changed after the init call completes. This function returns one of the status values specified above.
*/
int inflatelib_init(inflatelib_stream* stream);
INFLATELIB_EXPORT int INFLATELIB_CALLCONV inflatelib_init(inflatelib_stream* stream);

/*
* Resets the stream's state back to its initialized state. This allows the stream to be reused for multiple inflate
* calls without having to destroy and reinitialize it. Typically, this is used to reset the stream after an inflate
* call returns EOF, however it can also be used to reset the stream after an error or even during the middle of
* inflating a stream. This function also allows the caller to switch between Deflate and Deflate64.
*/
int inflatelib_reset(inflatelib_stream* stream);
INFLATELIB_EXPORT int INFLATELIB_CALLCONV inflatelib_reset(inflatelib_stream* stream);

/*
* Cleans up any data allocated/initialized by the library. This function must be called if 'inflatelib_init'
* returns success. After this function is called, the 'inflatelib_stream' cannot be used for any function call
* unless 'inflatelib_init' is called again. This function can only return success.
*/
int inflatelib_destroy(inflatelib_stream* stream);
INFLATELIB_EXPORT int INFLATELIB_CALLCONV inflatelib_destroy(inflatelib_stream* stream);

/*
*
*/
Comment on lines 152 to 154

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self to fill these in

int inflatelib_inflate(inflatelib_stream* stream);
INFLATELIB_EXPORT int INFLATELIB_CALLCONV inflatelib_inflate(inflatelib_stream* stream);

/*
*
*/
int inflatelib_inflate64(inflatelib_stream* stream);
INFLATELIB_EXPORT int INFLATELIB_CALLCONV inflatelib_inflate64(inflatelib_stream* stream);

#ifdef __cplusplus
} // extern "C"
Expand Down
24 changes: 23 additions & 1 deletion src/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,19 @@
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)

add_library(inflatelib)
if (${INFLATELIB_BUILD_SHARED})
add_library(inflatelib SHARED)

target_compile_definitions(inflatelib
PRIVATE
INFLATELIB_BUILD_SHARED
INTERFACE
INFLATELIB_CONSUME_SHARED
)
else()
add_library(inflatelib STATIC)
endif()

add_library(inflatelib::inflatelib ALIAS inflatelib)

target_compile_features(inflatelib
Expand All @@ -15,6 +27,15 @@ target_compile_options(inflatelib
${SANITIZER_FLAGS}
)

set_target_properties(inflatelib PROPERTIES
POSITION_INDEPENDENT_CODE ON
C_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
DEBUG_POSTFIX "d"
SOVERSION ${CMAKE_PROJECT_VERSION_MAJOR}
VERSION ${CMAKE_PROJECT_VERSION}
)

target_link_libraries(inflatelib
INTERFACE
${SANITIZER_LIBS}
Expand All @@ -36,6 +57,7 @@ target_sources(inflatelib
huffman_tree.c
inflate.c
window.c
$<$<AND:$<BOOL:${WIN32}>,$<BOOL:${INFLATELIB_BUILD_SHARED}>>:inflatelib.rc>
)

# Installation
Expand Down
40 changes: 40 additions & 0 deletions src/lib/inflatelib.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <windows.h>
#include <inflatelib.h>

//---------------------------------------------------------------
// Version Information
//---------------------------------------------------------------
VS_VERSION_INFO VERSIONINFO
FILEVERSION INFLATELIB_VERSION_MAJOR,INFLATELIB_VERSION_MINOR,INFLATELIB_VERSION_PATCH,0
PRODUCTVERSION INFLATELIB_VERSION_MAJOR,INFLATELIB_VERSION_MINOR,INFLATELIB_VERSION_PATCH,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS 1
#else
FILEFLAGS 0
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904e4" // US English + ANSI Latin 1
BEGIN
VALUE "CompanyName", "Microsoft Corporation\0"
VALUE "FileDescription", "InflateLib decompression library\0"
VALUE "FileVersion", INFLATELIB_VERSION_STRING "\0"
VALUE "InternalName", "inflatelib.dll\0"
VALUE "LegalCopyright", "Copyright (c) Microsoft Corporation. All rights reserved.\0"
VALUE "OriginalFilename", "inflatelib.dll\0"
VALUE "ProductName", "InflateLib\0"
VALUE "ProductVersion", INFLATELIB_VERSION_STRING "\0"
END
END

BLOCK "VarFileInfo"
BEGIN
// Language ID, Code Page (0409 = US English, 1252 = ANSI Latin 1; Western European)
VALUE "Translation", 0x0409, 1252
END
END
6 changes: 5 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ if (BUILD_TEST_FILES)
endif()

if (NOT INFLATELIB_FUZZ)
add_subdirectory(cpp)
# Building as a shared library does not export internal symbols, which we test in the unit tests. It's still useful
# to test building as a shared library, so just exclude the unit tests in this configuration
if (NOT INFLATELIB_BUILD_SHARED)
add_subdirectory(cpp)
endif()

# The perf tests are pretty useless when sanitizers are enabled. Note that the tests will consume the same input as the
# perf tests, so it's not like we're missing potential coverage here.
Expand Down
Loading