libxlsxwriter/CMakeLists.txt

422 lines
14 KiB
CMake
Raw Normal View History

# :copyright: (c) 2017 Alex Huszagh.
# :license: FreeBSD, see LICENSE.txt for more details.
# Description
# ===========
#
# Use:
# Move to a custom directory, ideally out of source, and
# type `cmake $LXW_SOURCE $FLAGS`, where `LXW_SOURCE` is the
# path to the libxlsxwriter project, and `FLAGS` are custom
# flags to pass to the compiler.
#
# Example:
# For example, in the project directory, to build libxlsxwriter
# and the unittests in release mode, type:
# mkdir build && cd build
# cmake .. -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release
# cmake --build . --config Release
# ctest -C Release -V
# cmake --build . --config Release --target install
#
# If using a Makefile generator, you may use the simpler
# mkdir build && cd build
# cmake .. -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release
# make
# make test
# make install
#
# Flags:
# ZLIB_ROOT
# The ZLIB root directory can be specified either through
# an environment variable (`export ZLIB_ROOT=/usr/include`)
# or using a flag with CMake (`-DZLIB_ROOT:STRING=/usr/include`).
# This sets the preferred search path for the ZLIB installation.
#
# BUILD_TESTS
# Build unittests (default off). To build the unittests,
# pass `-DBUILD_TESTS=ON` during configuration.
#
# BUILD_EXAMPLES
# Build example files (default off). To build the examples,
# pass `-DBUILD_EXAMPLES=ON` during configuration.
#
# USE_STANDARD_TMPFILE
# Use the standard tmpfile() function (default off). To enable
# the standard tmpfile, pass `-DUSE_STANDARD_TMPFILE=ON`
# during configuration. This may produce bugs while cross-
# compiling or using MinGW/MSYS.
#
# USE_DTOA_LIBRARY
# Use the third party emyg_dtoa() library (default off). The
# emyg_dtoa() library is used to avoid sprintf double issues with
# different locale settings. To enable this library, pass
# `-DUSE_DTOA_LIBRARY=ON` during configuration.
#
# USE_NO_MD5
# Compile without third party MD5 support. This will turn off the
# functionality of avoiding duplicate image files in the output xlsx
# file. To enable this option pass `-DUSE_NO_MD5=ON` during
# configuration.
#
# USE_OPENSSL_MD5 Compile with OpenSSL MD5 support. This will link
# against libcrypto for MD5 support rather than using the local MD5
# support. MD5 support is required to avoid duplicate image files in
# the output xlsx file. To enable this option pass
# `-DUSE_OPENSSL_MD5=ON` during configuration.
#
# USE_STATIC_MSVC_RUNTIME
# Use the static msvc runtime library when compiling with msvc (default off)
# To enable, pass `-DUSE_STATIC_MSVC_RUNTIME` during configuration.
#
# Toolchains:
# On multiarch Linux systems, which can build and run multiple
# binary targets on the same system, we include an `i686-toolchain`
# file to enable building i686 (x86 32-bit) targets on x86_64 systems.
# To use the i686 toolchain, pass the `-DCMAKE_TOOLCHAIN_FILE` option
# during CMake configuration. For example, from the build directory,
# you would use:
# cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/i686-toolchain.cmake
#
# CMake Options:
# CMake sets debug and release builds with the `CMAKE_BUILD_TYPE`
# option, which can be set as a flag during configuration.
# To build in release mode, pass `-DCMAKE_BUILD_TYPE=Release`
# during configuration.
#
2017-10-23 18:12:50 -07:00
# CMake sets the creation of static and shared libraries with the
# `BUILD_SHARED_LIBS` option, which can be set as a flag during
# configuration. To build a static library, pass
# `-DBUILD_SHARED_LIBS=OFF` during configuration.
#
# Generators:
# CMake also supports custom build generators, such as MakeFiles,
# Ninja, Visual Studio, and XCode. For example, to generate
# a Visual Studio solution, configure with:
# cmake .. -G "Visual Studio 14 2015 Win64"
#
# For more information on using generators, see:
# https://cmake.org/cmake/help/v3.0/manual/cmake-generators.7.html
#
set(CMAKE_LEGACY_CYGWIN_WIN32 1)
if(MSVC)
cmake_minimum_required(VERSION 3.4)
else()
2018-04-27 11:27:15 +02:00
cmake_minimum_required(VERSION 3.1)
endif()
SET(XLSX_PROJECT_NAME "xlsxwriter" CACHE STRING "Optional project and binary name")
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
project(${XLSX_PROJECT_NAME} C)
enable_testing()
# POLICY
# ------
# The use of the word ZLIB_ROOT should still work prior to "3.12.0",
# just it's been generalized for all packages now. Just set the policy
# to new, so we use it, and it will be used prior to 3.12 anyway.
if(${CMAKE_VERSION} VERSION_GREATER "3.12" OR ${CMAKE_VERSION} VERSION_EQUAL "3.12")
cmake_policy(SET CMP0074 NEW)
endif()
# OPTIONS
# -------
SET(ZLIB_ROOT "" CACHE STRING "Optional root for the ZLIB installation")
option(BUILD_TESTS "Build libxlsxwriter tests" OFF)
option(BUILD_EXAMPLES "Build libxlsxwriter examples" OFF)
option(USE_SYSTEM_MINIZIP "Use system minizip installation" OFF)
option(USE_STANDARD_TMPFILE "Use the C standard library's tmpfile()" OFF)
option(USE_NO_MD5 "Build libxlsxwriter without third party MD5 lib" OFF)
option(USE_OPENSSL_MD5 "Build libxlsxwriter with the OpenSSL MD5 lib" OFF)
option(USE_FMEMOPEN "Use fmemopen() in place of some temporary files" OFF)
option(IOAPI_NO_64 "Disable 64-bit filesystem support" OFF)
option(USE_DTOA_LIBRARY "Use the locale independent third party Milo Yip DTOA library" OFF)
if(MSVC)
option(USE_STATIC_MSVC_RUNTIME "Use the static runtime library" OFF)
endif()
if(DEFINED ENV{${ZLIB_ROOT}})
set(ZLIB_ROOT $ENV{ZLIB_ROOT})
endif()
if(IOAPI_NO_64)
2017-10-23 18:12:50 -07:00
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS IOAPI_NO_64=1)
endif()
# CONFIGURATIONS
# --------------
if(USE_SYSTEM_MINIZIP)
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS USE_SYSTEM_MINIZIP)
endif()
if(USE_STANDARD_TMPFILE)
2017-10-23 18:12:50 -07:00
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS USE_STANDARD_TMPFILE)
endif()
if(NOT USE_OPENSSL_MD5 AND USE_NO_MD5)
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS USE_NO_MD5)
endif()
if(USE_OPENSSL_MD5)
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS USE_OPENSSL_MD5)
endif()
if(USE_FMEMOPEN)
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS USE_FMEMOPEN)
endif()
if(USE_DTOA_LIBRARY)
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS USE_DTOA_LIBRARY)
endif()
2017-10-23 18:12:50 -07:00
if(NOT BUILD_SHARED_LIBS)
if(UNIX)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
elseif(MINGW OR MSYS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static -static-libgcc -Wno-char-subscripts -Wno-long-long")
2017-10-23 18:12:50 -07:00
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS USE_FILE32API)
elseif(MSVC)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Fd\"${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pdb\"")
2019-08-30 10:50:02 +01:00
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Ox /Zi /Fd\"${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pdb\"")
set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} /Zi /Fd\"${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pdb\"")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /Fd\"${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pdb\"")
endif()
endif()
if(MSVC AND USE_STATIC_MSVC_RUNTIME)
foreach(flag_var CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif()
endforeach()
endif()
# Configure pkg-config
file(READ "include/xlsxwriter.h" ver)
string(REGEX MATCH "LXW_VERSION .*\"\(.*\)\".*" _ ${ver})
set(VERSION ${CMAKE_MATCH_1})
string(REGEX MATCH "LXW_SOVERSION .*\"\(.*\)\".*" _ ${ver})
set(SOVERSION ${CMAKE_MATCH_1})
set(PREFIX ${CMAKE_INSTALL_PREFIX})
configure_file(dev/release/pkg-config.txt xlsxwriter.pc @ONLY)
2017-10-23 18:12:50 -07:00
# INCLUDES
# --------
enable_language(CXX)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
2017-10-23 18:12:50 -07:00
# ZLIB
find_package(ZLIB REQUIRED "1.0")
2017-10-23 18:12:50 -07:00
list(APPEND LXW_PRIVATE_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS})
message("zlib version: " ${ZLIB_VERSION})
# MINIZIP
if (USE_SYSTEM_MINIZIP)
find_package(MINIZIP REQUIRED "1.0")
list(APPEND LXW_PRIVATE_INCLUDE_DIRS ${MINIZIP_INCLUDE_DIRS})
endif()
# LIBRARY
# -------
2017-10-23 18:12:50 -07:00
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS NOCRYPT NOUNCRYPT)
2017-10-23 18:12:50 -07:00
# Ensure CRT Secure warnings are disabled
if(MSVC)
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS)
endif()
# Ensure "TESTING" macro is defined if building tests
if(BUILD_TESTS)
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS TESTING)
endif()
file(GLOB LXW_SOURCES src/*.c)
2017-10-23 18:12:50 -07:00
file(GLOB_RECURSE LXW_HEADERS RELATIVE include *.h)
if(NOT USE_SYSTEM_MINIZIP)
list(APPEND LXW_SOURCES third_party/minizip/ioapi.c third_party/minizip/zip.c)
if(MSVC)
list(APPEND LXW_SOURCES third_party/minizip/iowin32.c)
endif()
endif()
2017-10-23 18:12:50 -07:00
if (NOT USE_STANDARD_TMPFILE)
list(APPEND LXW_SOURCES third_party/tmpfileplus/tmpfileplus.c)
endif()
if(NOT USE_OPENSSL_MD5 AND NOT USE_NO_MD5)
list(APPEND LXW_SOURCES third_party/md5/md5.c)
endif()
if(USE_OPENSSL_MD5)
2022-02-15 12:56:18 +00:00
find_package(OpenSSL REQUIRED)
if(OpenSSL_FOUND)
include_directories(${OPENSSL_INCLUDE_DIR})
message(STATUS "OpenSSL version: ${OPENSSL_VERSION}")
endif()
endif()
if (USE_DTOA_LIBRARY)
list(APPEND LXW_SOURCES third_party/dtoa/emyg_dtoa.c)
endif()
set(LXW_PROJECT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(LXW_LIB_DIR "${LXW_PROJECT_DIR}/lib")
2017-10-23 18:12:50 -07:00
add_library(${PROJECT_NAME} "")
set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${SOVERSION})
2017-10-23 18:12:50 -07:00
target_sources(${PROJECT_NAME}
PRIVATE ${LXW_SOURCES}
PUBLIC ${LXW_HEADERS}
)
target_link_libraries(${PROJECT_NAME} LINK_PUBLIC ${ZLIB_LIBRARIES} ${MINIZIP_LIBRARIES} ${LIB_CRYPTO} ${OPENSSL_CRYPTO_LIBRARY})
2017-10-23 18:12:50 -07:00
target_compile_definitions(${PROJECT_NAME} PRIVATE ${LXW_PRIVATE_COMPILE_DEFINITIONS})
# /utf-8 needs VS2015 Update 2 or above.
# In CMake 3.7 and above, we can use (MSVC_VERSION GREATER_EQUAL 1900) here.
if(MSVC AND NOT (MSVC_VERSION LESS 1900))
target_compile_options(${PROJECT_NAME} PRIVATE /utf-8)
endif()
if (WINDOWSSTORE)
target_compile_definitions(${PROJECT_NAME} PRIVATE -DIOWIN32_USING_WINRT_API)
endif()
2017-10-23 18:12:50 -07:00
target_include_directories(${PROJECT_NAME}
PRIVATE ${LXW_PRIVATE_INCLUDE_DIRS}
PUBLIC include include/xlsxwriter
)
# TESTS
# -----
# Create test and runner.
#
# Args:
# sources Name of variable holding source files
# target Test name
#
2022-02-13 23:46:39 +00:00
macro(CreateTest sources target)
set(output_name xlsxwriter_${target})
set(dependencies ${output_name})
add_executable(${output_name} ${${sources}})
2017-10-23 18:12:50 -07:00
target_link_libraries(${output_name} ${PROJECT_NAME})
target_compile_definitions(${output_name} PRIVATE TESTING COLOR_OK)
add_test(NAME ${output_name}
COMMAND ${output_name}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
endmacro(CreateTest)
file(GLOB LXW_UTILITY_SOURCES test/unit/utility/test*.c)
file(GLOB LXW_XMLWRITER_SOURCES test/unit/xmlwriter/test*.c)
file(GLOB LXW_WORKSHEET_SOURCES test/unit/worksheet/test*.c)
file(GLOB LXW_SST_SOURCES test/unit/sst/test*.c)
file(GLOB LXW_WORKBOOK_SOURCES test/unit/workbook/test*.c)
file(GLOB LXW_APP_SOURCES test/unit/app/test*.c)
file(GLOB LXW_CONTENTTYPES_SOURCES test/unit/content_types/test*.c)
file(GLOB LXW_CORE_SOURCES test/unit/core/test*.c)
file(GLOB LXW_RELATIONSHIPS_SOURCES test/unit/relationships/test*.c)
file(GLOB LXW_FORMAT_SOURCES test/unit/format/test*.c)
file(GLOB LXW_STYLES_SOURCES test/unit/styles/test*.c)
file(GLOB LXW_DRAWING_SOURCES test/unit/drawing/test*.c)
file(GLOB LXW_CHART_SOURCES test/unit/chart/test*.c)
file(GLOB LXW_CUSTOM_SOURCES test/unit/custom/test*.c)
file(GLOB LXW_FUNCTIONAL_SOURCES test/functional/src/*.c)
set(LXW_UNIT_SOURCES
test/unit/test_all.c
${LXW_UTILITY_SOURCES}
${LXW_XMLWRITER_SOURCES}
${LXW_WORKSHEET_SOURCES}
${LXW_SST_SOURCES}
${LXW_WORKBOOK_SOURCES}
${LXW_APP_SOURCES}
${LXW_CONTENTTYPES_SOURCES}
${LXW_CORE_SOURCES}
${LXW_RELATIONSHIPS_SOURCES}
${LXW_FORMAT_SOURCES}
${LXW_STYLES_SOURCES}
${LXW_DRAWING_SOURCES}
${LXW_CHART_SOURCES}
${LXW_CUSTOM_SOURCES}
)
2017-10-23 18:12:50 -07:00
if(BUILD_TESTS)
# unit tests
CreateTest(LXW_UNIT_SOURCES unit)
# functional tests
2022-02-14 08:59:10 +00:00
find_package(Python COMPONENTS Interpreter REQUIRED)
2022-02-14 18:49:30 +00:00
find_program(Pytest_EXECUTABLE NAMES pytest)
2022-02-14 08:59:10 +00:00
2022-02-14 18:49:30 +00:00
if (NOT Pytest_EXECUTABLE)
message("Please install the Python pytest library to run functional tests:")
message(" pip install pytest\n")
endif()
2022-02-13 23:46:39 +00:00
foreach(source ${LXW_FUNCTIONAL_SOURCES})
get_filename_component(basename ${source} NAME_WE)
add_executable(${basename} ${source})
target_link_libraries(${basename} xlsxwriter)
2022-02-15 12:56:18 +00:00
set_target_properties(${basename} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "test/functional/src")
2022-02-13 23:46:39 +00:00
endforeach(source)
add_custom_command(TARGET xlsxwriter_unit POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/test/functional test/functional
)
2022-02-15 01:16:27 +00:00
if(USE_NO_MD5)
add_test(NAME functional
COMMAND pytest -v test/functional -m "not skipif"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
else()
add_test(NAME functional
COMMAND pytest -v test/functional
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
endif()
2022-02-13 23:46:39 +00:00
endif()
# EXAMPLES
# --------
file(GLOB LXW_EXAMPLE_SOURCES examples/*.c)
if(BUILD_EXAMPLES)
foreach(source ${LXW_EXAMPLE_SOURCES})
get_filename_component(basename ${source} NAME_WE)
add_executable(${basename} ${source})
2017-10-23 18:12:50 -07:00
target_link_libraries(${basename} ${PROJECT_NAME})
2022-02-15 12:56:18 +00:00
set_target_properties(${basename} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "examples")
endforeach(source)
endif()
# INSTALL
# -------
include(GNUInstallDirs)
install(TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(FILES include/xlsxwriter.h DESTINATION include)
install(DIRECTORY include/xlsxwriter
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h"
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/xlsxwriter.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)