libzip
libzip copied to clipboard
Add a extra "static" compile target, named "zipstatic" and add set(CMAKE_DEBUG_POSTFIX "d") under MSVC
Description I'm using CMake to compile libzip on Windows and found a problem. There is only a single compile target named "zip" and provide a option to determine shared/static. Most of the time it's fine. But when I try to install libzip on my computer, shared/static and Debug/Release type are all have the same name "zip". This question has been bothering me for a long time.
Solution
Well, I have modified two CMakeLists.txt files.
Now, all build types are there:
My custom CMakeLists.txt:
My custom lib/CMakeLists.txt:
include(CheckFunctionExists)
set(CMAKE_C_VISIBILITY_PRESET hidden)
# sources and link libraries
set(LIBZIP_SOURCE
zip_add.c
zip_add_dir.c
zip_add_entry.c
zip_algorithm_deflate.c
zip_buffer.c
zip_close.c
zip_delete.c
zip_dir_add.c
zip_dirent.c
zip_discard.c
zip_entry.c
zip_error.c
zip_error_clear.c
zip_error_get.c
zip_error_get_sys_type.c
zip_error_strerror.c
zip_error_to_str.c
zip_extra_field.c
zip_extra_field_api.c
zip_fclose.c
zip_fdopen.c
zip_file_add.c
zip_file_error_clear.c
zip_file_error_get.c
zip_file_get_comment.c
zip_file_get_external_attributes.c
zip_file_get_offset.c
zip_file_rename.c
zip_file_replace.c
zip_file_set_comment.c
zip_file_set_encryption.c
zip_file_set_external_attributes.c
zip_file_set_mtime.c
zip_file_strerror.c
zip_fopen.c
zip_fopen_encrypted.c
zip_fopen_index.c
zip_fopen_index_encrypted.c
zip_fread.c
zip_fseek.c
zip_ftell.c
zip_get_archive_comment.c
zip_get_archive_flag.c
zip_get_encryption_implementation.c
zip_get_file_comment.c
zip_get_name.c
zip_get_num_entries.c
zip_get_num_files.c
zip_hash.c
zip_io_util.c
zip_libzip_version.c
zip_memdup.c
zip_name_locate.c
zip_new.c
zip_open.c
zip_pkware.c
zip_progress.c
zip_rename.c
zip_replace.c
zip_set_archive_comment.c
zip_set_archive_flag.c
zip_set_default_password.c
zip_set_file_comment.c
zip_set_file_compression.c
zip_set_name.c
zip_source_accept_empty.c
zip_source_begin_write.c
zip_source_begin_write_cloning.c
zip_source_buffer.c
zip_source_call.c
zip_source_close.c
zip_source_commit_write.c
zip_source_compress.c
zip_source_crc.c
zip_source_error.c
zip_source_file_common.c
zip_source_file_stdio.c
zip_source_free.c
zip_source_function.c
zip_source_get_file_attributes.c
zip_source_is_deleted.c
zip_source_layered.c
zip_source_open.c
zip_source_pkware_decode.c
zip_source_pkware_encode.c
zip_source_read.c
zip_source_remove.c
zip_source_rollback_write.c
zip_source_seek.c
zip_source_seek_write.c
zip_source_stat.c
zip_source_supports.c
zip_source_tell.c
zip_source_tell_write.c
zip_source_window.c
zip_source_write.c
zip_source_zip.c
zip_source_zip_new.c
zip_stat.c
zip_stat_index.c
zip_stat_init.c
zip_strerror.c
zip_string.c
zip_unchange.c
zip_unchange_all.c
zip_unchange_archive.c
zip_unchange_data.c
zip_utf-8.c
${CMAKE_BINARY_DIR}/zip_err_str.c
)
set(LIBZIP_LINK
ZLIB::ZLIB
)
if(WIN32)
set(LIBZIP_SOURCE ${LIBZIP_SOURCE}
zip_source_file_win32.c
zip_source_file_win32_named.c
zip_source_file_win32_utf16.c
zip_source_file_win32_utf8.c
)
if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
set(LIBZIP_SOURCE ${LIBZIP_SOURCE}
zip_random_uwp.c
)
else()
set(LIBZIP_SOURCE ${LIBZIP_SOURCE}
zip_source_file_win32_ansi.c
zip_random_win32.c
)
set(LIBZIP_LINK ${LIBZIP_LINK}
advapi32
)
endif()
else(WIN32)
set(LIBZIP_SOURCE ${LIBZIP_SOURCE}
zip_mkstempm.c
zip_source_file_stdio_named.c
zip_random_unix.c
)
endif(WIN32)
if(HAVE_LIBBZ2)
set(LIBZIP_SOURCE ${LIBZIP_SOURCE}
zip_algorithm_bzip2.c
)
set(LIBZIP_LINK ${LIBZIP_LINK}
BZip2::BZip2
)
endif()
if(HAVE_LIBLZMA)
set(LIBZIP_SOURCE ${LIBZIP_SOURCE}
zip_algorithm_xz.c
)
set(LIBZIP_LINK ${LIBZIP_LINK}
LibLZMA::LibLZMA
)
endif()
if(HAVE_COMMONCRYPTO)
set(LIBZIP_SOURCE ${LIBZIP_SOURCE}
zip_crypto_commoncrypto.c
)
elseif(HAVE_WINDOWS_CRYPTO)
set(LIBZIP_SOURCE ${LIBZIP_SOURCE}
zip_crypto_win.c
)
set(LIBZIP_LINK ${LIBZIP_LINK}
bcrypt
)
elseif(HAVE_GNUTLS)
set(LIBZIP_SOURCE ${LIBZIP_SOURCE}
zip_crypto_gnutls.c
)
set(LIBZIP_LINK ${LIBZIP_LINK}
GnuTLS::GnuTLS
Nettle::Nettle
)
elseif(HAVE_OPENSSL)
set(LIBZIP_SOURCE ${LIBZIP_SOURCE}
zip_crypto_openssl.c
)
set(LIBZIP_LINK ${LIBZIP_LINK}
OpenSSL::Crypto
)
elseif(HAVE_MBEDTLS)
set(LIBZIP_SOURCE ${LIBZIP_SOURCE}
zip_crypto_mbedtls.c
)
set(LIBZIP_LINK ${LIBZIP_LINK}
MbedTLS::MbedTLS
)
endif()
if(HAVE_CRYPTO)
set(LIBZIP_SOURCE ${LIBZIP_SOURCE}
zip_winzip_aes.c
zip_source_winzip_aes_decode.c
zip_source_winzip_aes_encode.c
)
endif()
# libzip
add_library(zip SHARED ${LIBZIP_SOURCE})
add_library(libzip::zip ALIAS zip)
add_library(zipstatic STATIC ${LIBZIP_SOURCE})
add_library(libzip::zipstatic ALIAS zipstatic)
target_compile_definitions(zipstatic PUBLIC ZIP_STATIC)
target_link_libraries(zip PRIVATE ${LIBZIP_LINK})
target_link_libraries(zipstatic PRIVATE ${LIBZIP_LINK})
if(SHARED_LIB_VERSIONNING)
set_target_properties(zip PROPERTIES VERSION 5.3 SOVERSION 5)
endif()
target_include_directories(zip
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/lib>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
$<INSTALL_INTERFACE:include>
)
target_include_directories(zipstatic
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/lib>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
$<INSTALL_INTERFACE:include>
)
# install
if(LIBZIP_DO_INSTALL)
install(TARGETS zip
EXPORT ${PROJECT_NAME}-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(TARGETS zipstatic
EXPORT ${PROJECT_NAME}-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES zip.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
endif()
# create zip_err_str.h from zip.h
file(READ ${PROJECT_SOURCE_DIR}/lib/zip.h zip_h)
string(REGEX MATCHALL "#define ZIP_ER_([A-Z_]+) ([0-9]+)[ \t]+/([-*0-9a-zA-Z ']*)/" zip_h_err ${zip_h})
set(zip_err_str [=[
/*
This file was generated automatically by CMake
from zip.h\; make changes there.
*/
#include "zipint.h"
const char * const _zip_err_str[] = {
]=])
set(zip_err_type)
foreach(errln ${zip_h_err})
string(REGEX MATCH "#define ZIP_ER_([A-Z_]+) ([0-9]+)[ \t]+/([-*0-9a-zA-Z ']*)/" err_t_tt ${errln})
string(REGEX MATCH "([N|S|Z]+) ([-0-9a-zA-Z ']*)" err_t_tt "${CMAKE_MATCH_3}")
string(APPEND zip_err_type " ${CMAKE_MATCH_1},\n")
string(STRIP "${CMAKE_MATCH_2}" err_t_tt)
string(APPEND zip_err_str " \"${err_t_tt}\",\n")
endforeach()
string(APPEND zip_err_str [=[}\;
const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0])\;
#define N ZIP_ET_NONE
#define S ZIP_ET_SYS
#define Z ZIP_ET_ZLIB
const int _zip_err_type[] = {
]=])
string(APPEND zip_err_str "${zip_err_type}}\;\n")
file(WRITE ${CMAKE_BINARY_DIR}/zip_err_str.c ${zip_err_str})
Can you please explain in simple terms why you would want to build an install all four of these? (I think this is Windows-specific, and I don't know much about development on Windows.) Thank you.
Add "d" postfix to let Debug build type and Release build type exist together.
Add "zipstatic" target so I can using libzip on different projects. (Some required static link and others will link dynamically)
I think zlib is a good example:
😄Thanks!
This may not be Specific to Windows? I wonder what it looks like on Ubuntu.
Unix usually does not do debug/release builds, and static and dynamic libraries have different names: libzip.a and libzip.so, respectively.
Ok, I understand. On Windows, shared/static library both have a .lib file (this is the problem).😢
agree, Windows platform have some special static/dynamic library feature
Thanks for posting this, totally irrelevant but this helped me build a static library on macOS Big Sur.
Duplicating the complete libzip build definition is not an acceptable solution.
Also, this is not something we will do. If someone provides a low-impact patch, we will consider it.