clean up cmake files and add d suffix to xlnt debug library, closes #214

This commit is contained in:
Thomas Fussell 2017-09-08 14:33:18 -04:00
parent b7677d0783
commit 7ed14246b2
8 changed files with 918 additions and 198 deletions

1
.gitignore vendored
View File

@ -16,3 +16,4 @@ Win32/
*.pyd
python/record.txt
python/xlntpyarrow.egg-info/
/x64/

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.2)
cmake_minimum_required(VERSION 3.1)
project(xlnt_all)
# This indicates to CMakeLists in subdirectories that they are part of a larger project
@ -11,28 +11,28 @@ option(STATIC "Set to ON to build xlnt as a static library instead of a shared l
option(TESTS "Set to OFF to skip building test executable (in ./tests)" ON)
option(SAMPLES "Set to ON to build executable code samples (in ./samples)" OFF)
option(BENCHMARKS "Set to ON to build performance benchmarks (in ./benchmarks)" OFF)
option(ARROW "Set to ON to build Arrow conversion functions (in ./contrib/xlntarrow)" OFF)
option(PYTHON "Set to ON to build Arrow conversion functions (in ./python)" OFF)
# Platform specific options
if(NOT MSVC)
option(COVERAGE "Generate coverage data using gcov" OFF)
option(COVERAGE "Generate coverage data using gcov" OFF)
endif()
# Add components according to selected options
if(SAMPLES)
add_subdirectory(samples)
add_subdirectory(samples)
endif()
if(BENCHMARKS)
add_subdirectory(benchmarks)
add_subdirectory(benchmarks)
endif()
if(TESTS)
add_subdirectory(tests)
add_subdirectory(tests)
endif()
if(PYTHON)
add_subdirectory(python)
add_subdirectory(python)
endif()
add_subdirectory(source)

View File

@ -1,11 +1,19 @@
cmake_minimum_required(VERSION 3.2)
cmake_minimum_required(VERSION 3.1)
project(xlnt.benchmarks)
set(CMAKE_CXX_STANDARD 14)
# Require C++11 compiler
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT COMBINED_PROJECT)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../source ${CMAKE_CURRENT_BINARY_DIR}/source)
# Include xlnt library
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../source ${CMAKE_CURRENT_BINARY_DIR}/source)
endif()
if(MSVC AND STATIC)
# Link with static C runtime
include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/ucm.cmake)
ucm_set_runtime(STATIC)
endif()
set(XLNT_BENCHMARK_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data)
@ -13,20 +21,24 @@ set(XLNT_BENCHMARK_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data)
file(GLOB BENCHMARK_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
foreach(BENCHMARK_SOURCE IN ITEMS ${BENCHMARK_SOURCES})
get_filename_component(BENCHMARK_NAME ${BENCHMARK_SOURCE} NAME_WE)
set(BENCHMARK_EXECUTABLE benchmark-${BENCHMARK_NAME})
# Convert <name>.cpp to benchmark-<name>
get_filename_component(BENCHMARK_NAME ${BENCHMARK_SOURCE} NAME_WE)
set(BENCHMARK_EXECUTABLE benchmark-${BENCHMARK_NAME})
add_executable(${BENCHMARK_EXECUTABLE} ${BENCHMARK_SOURCE})
add_executable(${BENCHMARK_EXECUTABLE} ${BENCHMARK_SOURCE})
target_link_libraries(${BENCHMARK_EXECUTABLE} PRIVATE xlnt)
target_include_directories(${BENCHMARK_EXECUTABLE}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../tests)
target_compile_definitions(${BENCHMARK_EXECUTABLE} PRIVATE XLNT_BENCHMARK_DATA_DIR=${XLNT_BENCHMARK_DATA_DIR})
target_link_libraries(${BENCHMARK_EXECUTABLE} PRIVATE xlnt)
# Need to use some test helpers
target_include_directories(${BENCHMARK_EXECUTABLE}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../tests)
target_compile_definitions(${BENCHMARK_EXECUTABLE}
PRIVATE XLNT_BENCHMARK_DATA_DIR=${XLNT_BENCHMARK_DATA_DIR})
if(MSVC AND NOT STATIC)
add_custom_command(TARGET ${BENCHMARK_EXECUTABLE} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:xlnt>
$<TARGET_FILE_DIR:${BENCHMARK_EXECUTABLE}>)
endif()
if(MSVC AND NOT STATIC)
# Copy xlnt DLL into benchmarks directory
add_custom_command(TARGET ${BENCHMARK_EXECUTABLE} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:xlnt>
$<TARGET_FILE_DIR:${BENCHMARK_EXECUTABLE}>)
endif()
endforeach()

634
cmake/ucm.cmake Normal file
View File

@ -0,0 +1,634 @@
#
# ucm.cmake - useful cmake macros
#
# Copyright (c) 2016 Viktor Kirilov
#
# Distributed under the MIT Software License
# See accompanying file LICENSE.txt or copy at
# https://opensource.org/licenses/MIT
#
# The documentation can be found at the library's page:
# https://github.com/onqtam/ucm
cmake_minimum_required(VERSION 2.8.12)
include(CMakeParseArguments)
# optionally include cotire - the git submodule might not be inited (or the user might have already included it)
if(NOT COMMAND cotire)
include(${CMAKE_CURRENT_LIST_DIR}/../cotire/CMake/cotire.cmake OPTIONAL)
endif()
if(COMMAND cotire AND "1.7.9" VERSION_LESS "${COTIRE_CMAKE_MODULE_VERSION}")
set(ucm_with_cotire 1)
else()
set(ucm_with_cotire 0)
endif()
option(UCM_UNITY_BUILD "Enable unity build for targets registered with the ucm_add_target() macro" OFF)
option(UCM_NO_COTIRE_FOLDER "Do not use a cotire folder in the solution explorer for all unity and cotire related targets" ON)
# ucm_add_flags
# Adds compiler flags to CMAKE_<LANG>_FLAGS or to a specific config
macro(ucm_add_flags)
cmake_parse_arguments(ARG "C;CXX;CLEAR_OLD" "" "CONFIG" ${ARGN})
if(NOT ARG_CONFIG)
set(ARG_CONFIG " ")
endif()
foreach(CONFIG ${ARG_CONFIG})
# determine to which flags to add
if(NOT ${CONFIG} STREQUAL " ")
string(TOUPPER ${CONFIG} CONFIG)
set(CXX_FLAGS CMAKE_CXX_FLAGS_${CONFIG})
set(C_FLAGS CMAKE_C_FLAGS_${CONFIG})
else()
set(CXX_FLAGS CMAKE_CXX_FLAGS)
set(C_FLAGS CMAKE_C_FLAGS)
endif()
# clear the old flags
if(${ARG_CLEAR_OLD})
if("${ARG_CXX}" OR NOT "${ARG_C}")
set(${CXX_FLAGS} "")
endif()
if("${ARG_C}" OR NOT "${ARG_CXX}")
set(${C_FLAGS} "")
endif()
endif()
# add all the passed flags
foreach(flag ${ARG_UNPARSED_ARGUMENTS})
if("${ARG_CXX}" OR NOT "${ARG_C}")
set(${CXX_FLAGS} "${${CXX_FLAGS}} ${flag}")
endif()
if("${ARG_C}" OR NOT "${ARG_CXX}")
set(${C_FLAGS} "${${C_FLAGS}} ${flag}")
endif()
endforeach()
endforeach()
endmacro()
# ucm_set_flags
# Sets the CMAKE_<LANG>_FLAGS compiler flags or for a specific config
macro(ucm_set_flags)
ucm_add_flags(CLEAR_OLD ${ARGN})
endmacro()
# ucm_add_linker_flags
# Adds linker flags to CMAKE_<TYPE>_LINKER_FLAGS or to a specific config
macro(ucm_add_linker_flags)
cmake_parse_arguments(ARG "CLEAR_OLD;EXE;MODULE;SHARED;STATIC" "" "CONFIG" ${ARGN})
if(NOT ARG_CONFIG)
set(ARG_CONFIG " ")
endif()
foreach(CONFIG ${ARG_CONFIG})
string(TOUPPER "${CONFIG}" CONFIG)
if(NOT ${ARG_EXE} AND NOT ${ARG_MODULE} AND NOT ${ARG_SHARED} AND NOT ${ARG_STATIC})
set(ARG_EXE 1)
set(ARG_MODULE 1)
set(ARG_SHARED 1)
set(ARG_STATIC 1)
endif()
set(flags_configs "")
if(${ARG_EXE})
if(NOT "${CONFIG}" STREQUAL " ")
list(APPEND flags_configs CMAKE_EXE_LINKER_FLAGS_${CONFIG})
else()
list(APPEND flags_configs CMAKE_EXE_LINKER_FLAGS)
endif()
endif()
if(${ARG_MODULE})
if(NOT "${CONFIG}" STREQUAL " ")
list(APPEND flags_configs CMAKE_MODULE_LINKER_FLAGS_${CONFIG})
else()
list(APPEND flags_configs CMAKE_MODULE_LINKER_FLAGS)
endif()
endif()
if(${ARG_SHARED})
if(NOT "${CONFIG}" STREQUAL " ")
list(APPEND flags_configs CMAKE_SHARED_LINKER_FLAGS_${CONFIG})
else()
list(APPEND flags_configs CMAKE_SHARED_LINKER_FLAGS)
endif()
endif()
if(${ARG_STATIC})
if(NOT "${CONFIG}" STREQUAL " ")
list(APPEND flags_configs CMAKE_STATIC_LINKER_FLAGS_${CONFIG})
else()
list(APPEND flags_configs CMAKE_STATIC_LINKER_FLAGS)
endif()
endif()
# clear the old flags
if(${ARG_CLEAR_OLD})
foreach(flags ${flags_configs})
set(${flags} "")
endforeach()
endif()
# add all the passed flags
foreach(flag ${ARG_UNPARSED_ARGUMENTS})
foreach(flags ${flags_configs})
set(${flags} "${${flags}} ${flag}")
endforeach()
endforeach()
endforeach()
endmacro()
# ucm_set_linker_flags
# Sets the CMAKE_<TYPE>_LINKER_FLAGS linker flags or for a specific config
macro(ucm_set_linker_flags)
ucm_add_linker_flags(CLEAR_OLD ${ARGN})
endmacro()
# ucm_gather_flags
# Gathers all lists of flags for printing or manipulation
macro(ucm_gather_flags with_linker result)
set(${result} "")
# add the main flags without a config
list(APPEND ${result} CMAKE_C_FLAGS)
list(APPEND ${result} CMAKE_CXX_FLAGS)
if(${with_linker})
list(APPEND ${result} CMAKE_EXE_LINKER_FLAGS)
list(APPEND ${result} CMAKE_MODULE_LINKER_FLAGS)
list(APPEND ${result} CMAKE_SHARED_LINKER_FLAGS)
list(APPEND ${result} CMAKE_STATIC_LINKER_FLAGS)
endif()
if("${CMAKE_CONFIGURATION_TYPES}" STREQUAL "" AND NOT "${CMAKE_BUILD_TYPE}" STREQUAL "")
# handle single config generators - like makefiles/ninja - when CMAKE_BUILD_TYPE is set
string(TOUPPER ${CMAKE_BUILD_TYPE} config)
list(APPEND ${result} CMAKE_C_FLAGS_${config})
list(APPEND ${result} CMAKE_CXX_FLAGS_${config})
if(${with_linker})
list(APPEND ${result} CMAKE_EXE_LINKER_FLAGS_${config})
list(APPEND ${result} CMAKE_MODULE_LINKER_FLAGS_${config})
list(APPEND ${result} CMAKE_SHARED_LINKER_FLAGS_${config})
list(APPEND ${result} CMAKE_STATIC_LINKER_FLAGS_${config})
endif()
else()
# handle multi config generators (like msvc, xcode)
foreach(config ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${config} config)
list(APPEND ${result} CMAKE_C_FLAGS_${config})
list(APPEND ${result} CMAKE_CXX_FLAGS_${config})
if(${with_linker})
list(APPEND ${result} CMAKE_EXE_LINKER_FLAGS_${config})
list(APPEND ${result} CMAKE_MODULE_LINKER_FLAGS_${config})
list(APPEND ${result} CMAKE_SHARED_LINKER_FLAGS_${config})
list(APPEND ${result} CMAKE_STATIC_LINKER_FLAGS_${config})
endif()
endforeach()
endif()
endmacro()
# ucm_set_runtime
# Sets the runtime (static/dynamic) for msvc/gcc
macro(ucm_set_runtime)
cmake_parse_arguments(ARG "STATIC;DYNAMIC" "" "" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" STREQUAL "")
message(AUTHOR_WARNING "ucm_set_runtime() does not support clang yet!")
endif()
ucm_gather_flags(0 flags_configs)
# add/replace the flags
# note that if the user has messed with the flags directly this function might fail
# - for example if with MSVC and the user has removed the flags - here we just switch/replace them
if("${ARG_STATIC}")
foreach(flags ${flags_configs})
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
if(NOT ${flags} MATCHES "-static-libstdc\\+\\+")
set(${flags} "${${flags}} -static-libstdc++")
endif()
if(NOT ${flags} MATCHES "-static-libgcc")
set(${flags} "${${flags}} -static-libgcc")
endif()
elseif(MSVC)
if(${flags} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flags} "${${flags}}")
endif()
endif()
endforeach()
elseif("${ARG_DYNAMIC}")
foreach(flags ${flags_configs})
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
if(${flags} MATCHES "-static-libstdc\\+\\+")
string(REGEX REPLACE "-static-libstdc\\+\\+" "" ${flags} "${${flags}}")
endif()
if(${flags} MATCHES "-static-libgcc")
string(REGEX REPLACE "-static-libgcc" "" ${flags} "${${flags}}")
endif()
elseif(MSVC)
if(${flags} MATCHES "/MT")
string(REGEX REPLACE "/MT" "/MD" ${flags} "${${flags}}")
endif()
endif()
endforeach()
endif()
endmacro()
# ucm_print_flags
# Prints all compiler flags for all configurations
macro(ucm_print_flags)
ucm_gather_flags(1 flags_configs)
message("")
foreach(flags ${flags_configs})
message("${flags}: ${${flags}}")
endforeach()
message("")
endmacro()
# ucm_count_sources
# Counts the number of source files
macro(ucm_count_sources)
cmake_parse_arguments(ARG "" "RESULT" "" ${ARGN})
if(${ARG_RESULT} STREQUAL "")
message(FATAL_ERROR "Need to pass RESULT and a variable name to ucm_count_sources()")
endif()
set(result 0)
foreach(SOURCE_FILE ${ARG_UNPARSED_ARGUMENTS})
if("${SOURCE_FILE}" MATCHES \\.\(c|C|cc|cp|cpp|CPP|c\\+\\+|cxx|i|ii\)$)
math(EXPR result "${result} + 1")
endif()
endforeach()
set(${ARG_RESULT} ${result})
endmacro()
# ucm_include_file_in_sources
# Includes the file to the source with compiler flags
macro(ucm_include_file_in_sources)
cmake_parse_arguments(ARG "" "HEADER" "" ${ARGN})
if(${ARG_HEADER} STREQUAL "")
message(FATAL_ERROR "Need to pass HEADER and a header file to ucm_include_file_in_sources()")
endif()
foreach(src ${ARG_UNPARSED_ARGUMENTS})
if(${src} MATCHES \\.\(c|C|cc|cp|cpp|CPP|c\\+\\+|cxx\)$)
# get old flags
get_source_file_property(old_compile_flags ${src} COMPILE_FLAGS)
if(old_compile_flags STREQUAL "NOTFOUND")
set(old_compile_flags "")
endif()
# update flags
if(MSVC)
set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS
"${old_compile_flags} /FI\"${CMAKE_CURRENT_SOURCE_DIR}/${ARG_HEADER}\"")
else()
set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS
"${old_compile_flags} -include \"${CMAKE_CURRENT_SOURCE_DIR}/${ARG_HEADER}\"")
endif()
endif()
endforeach()
endmacro()
# ucm_dir_list
# Returns a list of subdirectories for a given directory
macro(ucm_dir_list thedir result)
file(GLOB sub-dir "${thedir}/*")
set(list_of_dirs "")
foreach(dir ${sub-dir})
if(IS_DIRECTORY ${dir})
get_filename_component(DIRNAME ${dir} NAME)
LIST(APPEND list_of_dirs ${DIRNAME})
endif()
endforeach()
set(${result} ${list_of_dirs})
endmacro()
# ucm_trim_front_words
# Trims X times the front word from a string separated with "/" and removes
# the front "/" characters after that (used for filters for visual studio)
macro(ucm_trim_front_words source out num_filter_trims)
set(result "${source}")
set(counter 0)
while(${counter} LESS ${num_filter_trims})
MATH(EXPR counter "${counter} + 1")
# removes everything at the front up to a "/" character
string(REGEX REPLACE "^([^/]+)" "" result "${result}")
# removes all consecutive "/" characters from the front
string(REGEX REPLACE "^(/+)" "" result "${result}")
endwhile()
set(${out} ${result})
endmacro()
# ucm_remove_files
# Removes source files from a list of sources (path is the relative path for it to be found)
macro(ucm_remove_files)
cmake_parse_arguments(ARG "" "FROM" "" ${ARGN})
if("${ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Need to pass some relative files to ucm_remove_files()")
endif()
if(${ARG_FROM} STREQUAL "")
message(FATAL_ERROR "Need to pass FROM and a variable name to ucm_remove_files()")
endif()
foreach(cur_file ${ARG_UNPARSED_ARGUMENTS})
list(REMOVE_ITEM ${ARG_FROM} ${cur_file})
endforeach()
endmacro()
# ucm_remove_directories
# Removes all source files from the given directories from the sources list
macro(ucm_remove_directories)
cmake_parse_arguments(ARG "" "FROM" "MATCHES" ${ARGN})
if("${ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Need to pass some relative directories to ucm_remove_directories()")
endif()
if(${ARG_FROM} STREQUAL "")
message(FATAL_ERROR "Need to pass FROM and a variable name to ucm_remove_directories()")
endif()
foreach(cur_dir ${ARG_UNPARSED_ARGUMENTS})
foreach(cur_file ${${ARG_FROM}})
string(REGEX MATCH ${cur_dir} res ${cur_file})
if(NOT "${res}" STREQUAL "")
if("${ARG_MATCHES}" STREQUAL "")
list(REMOVE_ITEM ${ARG_FROM} ${cur_file})
else()
foreach(curr_ptrn ${ARG_MATCHES})
string(REGEX MATCH ${curr_ptrn} res ${cur_file})
if(NOT "${res}" STREQUAL "")
list(REMOVE_ITEM ${ARG_FROM} ${cur_file})
break()
endif()
endforeach()
endif()
endif()
endforeach()
endforeach()
endmacro()
# ucm_add_files_impl
macro(ucm_add_files_impl result trim files)
foreach(cur_file ${files})
SET(${result} ${${result}} ${cur_file})
get_filename_component(FILEPATH ${cur_file} PATH)
ucm_trim_front_words("${FILEPATH}" FILEPATH "${trim}")
# replacing forward slashes with back slashes so filters can be generated (back slash used in parsing...)
STRING(REPLACE "/" "\\" FILTERS "${FILEPATH}")
SOURCE_GROUP("${FILTERS}" FILES ${cur_file})
endforeach()
endmacro()
# ucm_add_files
# Adds files to a list of sources
macro(ucm_add_files)
cmake_parse_arguments(ARG "" "TO;FILTER_POP" "" ${ARGN})
if("${ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Need to pass some relative files to ucm_add_files()")
endif()
if(${ARG_TO} STREQUAL "")
message(FATAL_ERROR "Need to pass TO and a variable name to ucm_add_files()")
endif()
if("${ARG_FILTER_POP}" STREQUAL "")
set(ARG_FILTER_POP 0)
endif()
ucm_add_files_impl(${ARG_TO} ${ARG_FILTER_POP} "${ARG_UNPARSED_ARGUMENTS}")
endmacro()
# ucm_add_dir_impl
macro(ucm_add_dir_impl result rec trim dirs_in additional_ext)
set(dirs "${dirs_in}")
# handle the "" and "." cases
if("${dirs}" STREQUAL "" OR "${dirs}" STREQUAL ".")
set(dirs "./")
endif()
foreach(cur_dir ${dirs})
# to circumvent some linux/cmake/path issues - barely made it work...
if(cur_dir STREQUAL "./")
set(cur_dir "")
else()
set(cur_dir "${cur_dir}/")
endif()
# since unix is case sensitive - add these valid extensions too
# we don't use "UNIX" but instead "CMAKE_HOST_UNIX" because we might be cross
# compiling (for example emscripten) under windows and UNIX may be set to 1
# Also OSX is case insensitive like windows...
set(additional_file_extensions "")
if(CMAKE_HOST_UNIX AND NOT APPLE)
set(additional_file_extensions
"${cur_dir}*.CPP"
"${cur_dir}*.C"
"${cur_dir}*.H"
"${cur_dir}*.HPP"
)
endif()
foreach(ext ${additional_ext})
list(APPEND additional_file_extensions "${cur_dir}*.${ext}")
endforeach()
# find all sources and set them as result
FILE(GLOB found_sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
# https://gcc.gnu.org/onlinedocs/gcc-4.4.1/gcc/Overall-Options.html#index-file-name-suffix-71
# sources
"${cur_dir}*.cpp"
"${cur_dir}*.cxx"
"${cur_dir}*.c++"
"${cur_dir}*.cc"
"${cur_dir}*.cp"
"${cur_dir}*.c"
"${cur_dir}*.i"
"${cur_dir}*.ii"
# headers
"${cur_dir}*.h"
"${cur_dir}*.h++"
"${cur_dir}*.hpp"
"${cur_dir}*.hxx"
"${cur_dir}*.hh"
"${cur_dir}*.inl"
"${cur_dir}*.inc"
"${cur_dir}*.ipp"
"${cur_dir}*.ixx"
"${cur_dir}*.txx"
"${cur_dir}*.tpp"
"${cur_dir}*.tcc"
"${cur_dir}*.tpl"
${additional_file_extensions})
SET(${result} ${${result}} ${found_sources})
# set the proper filters
ucm_trim_front_words("${cur_dir}" cur_dir "${trim}")
# replacing forward slashes with back slashes so filters can be generated (back slash used in parsing...)
STRING(REPLACE "/" "\\" FILTERS "${cur_dir}")
SOURCE_GROUP("${FILTERS}" FILES ${found_sources})
endforeach()
if(${rec})
foreach(cur_dir ${dirs})
ucm_dir_list("${cur_dir}" subdirs)
foreach(subdir ${subdirs})
ucm_add_dir_impl(${result} ${rec} ${trim} "${cur_dir}/${subdir}" "${additional_ext}")
endforeach()
endforeach()
endif()
endmacro()
# ucm_add_dirs
# Adds all files from directories traversing them recursively to a list of sources
# and generates filters according to their location (accepts relative paths only).
# Also this macro trims X times the front word from the filter string for visual studio filters.
macro(ucm_add_dirs)
cmake_parse_arguments(ARG "RECURSIVE" "TO;FILTER_POP" "ADDITIONAL_EXT" ${ARGN})
if(${ARG_TO} STREQUAL "")
message(FATAL_ERROR "Need to pass TO and a variable name to ucm_add_dirs()")
endif()
if("${ARG_FILTER_POP}" STREQUAL "")
set(ARG_FILTER_POP 0)
endif()
ucm_add_dir_impl(${ARG_TO} ${ARG_RECURSIVE} ${ARG_FILTER_POP} "${ARG_UNPARSED_ARGUMENTS}" "${ARG_ADDITIONAL_EXT}")
endmacro()
# ucm_add_target
# Adds a target eligible for cotiring - unity build and/or precompiled header
macro(ucm_add_target)
cmake_parse_arguments(ARG "UNITY" "NAME;TYPE;PCH_FILE;CPP_PER_UNITY" "UNITY_EXCLUDED;SOURCES" ${ARGN})
if(NOT "${ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Unrecognized options passed to ucm_add_target()")
endif()
if("${ARG_NAME}" STREQUAL "")
message(FATAL_ERROR "Need to pass NAME and a name for the target to ucm_add_target()")
endif()
set(valid_types EXECUTABLE STATIC SHARED MODULE)
list(FIND valid_types "${ARG_TYPE}" is_type_valid)
if(${is_type_valid} STREQUAL "-1")
message(FATAL_ERROR "Need to pass TYPE and the type for the target [EXECUTABLE/STATIC/SHARED/MODULE] to ucm_add_target()")
endif()
if("${ARG_SOURCES}" STREQUAL "")
message(FATAL_ERROR "Need to pass SOURCES and a list of source files to ucm_add_target()")
endif()
# init with the global unity flag
set(do_unity ${UCM_UNITY_BUILD})
# check the UNITY argument
if(NOT ARG_UNITY)
set(do_unity FALSE)
endif()
# if target is excluded through the exclusion list
list(FIND UCM_UNITY_BUILD_EXCLUDE_TARGETS ${ARG_NAME} is_target_excluded)
if(NOT ${is_target_excluded} STREQUAL "-1")
set(do_unity FALSE)
endif()
# unity build only for targets with > 1 source file (otherwise there will be an additional unnecessary target)
if(do_unity) # optimization
ucm_count_sources(${ARG_SOURCES} RESULT num_sources)
if(${num_sources} LESS 2)
set(do_unity FALSE)
endif()
endif()
set(wanted_cotire ${do_unity})
# if cotire cannot be used
if(do_unity AND NOT ucm_with_cotire)
set(do_unity FALSE)
endif()
# inform the developer that the current target might benefit from a unity build
if(NOT ARG_UNITY AND ${UCM_UNITY_BUILD})
ucm_count_sources(${ARG_SOURCES} RESULT num_sources)
if(${num_sources} GREATER 1)
message(AUTHOR_WARNING "Target '${ARG_NAME}' may benefit from a unity build.\nIt has ${num_sources} sources - enable with UNITY flag")
endif()
endif()
# prepare for the unity build
set(orig_target ${ARG_NAME})
if(do_unity)
# the original target will be added with a different name than the requested
set(orig_target ${ARG_NAME}_ORIGINAL)
# exclude requested files from unity build of the current target
foreach(excluded_file "${ARG_UNITY_EXCLUDED}")
set_source_files_properties(${excluded_file} PROPERTIES COTIRE_EXCLUDED TRUE)
endforeach()
endif()
# add the original target
if(${ARG_TYPE} STREQUAL "EXECUTABLE")
add_executable(${orig_target} ${ARG_SOURCES})
else()
add_library(${orig_target} ${ARG_TYPE} ${ARG_SOURCES})
endif()
if(do_unity)
# set the number of unity cpp files to be used for the unity target
if(NOT "${ARG_CPP_PER_UNITY}" STREQUAL "")
set_property(TARGET ${orig_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${ARG_CPP_PER_UNITY}")
else()
set_property(TARGET ${orig_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "100")
endif()
if(NOT "${ARG_PCH_FILE}" STREQUAL "")
set_target_properties(${orig_target} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${ARG_PCH_FILE}")
else()
set_target_properties(${orig_target} PROPERTIES COTIRE_ENABLE_PRECOMPILED_HEADER FALSE)
endif()
# add a unity target for the original one with the name intended for the original
set_target_properties(${orig_target} PROPERTIES COTIRE_UNITY_TARGET_NAME ${ARG_NAME})
# this is the library call that does the magic
cotire(${orig_target})
set_target_properties(clean_cotire PROPERTIES FOLDER "CMakePredefinedTargets")
# disable the original target and enable the unity one
get_target_property(unity_target_name ${orig_target} COTIRE_UNITY_TARGET_NAME)
set_target_properties(${orig_target} PROPERTIES EXCLUDE_FROM_ALL 1 EXCLUDE_FROM_DEFAULT_BUILD 1)
set_target_properties(${unity_target_name} PROPERTIES EXCLUDE_FROM_ALL 0 EXCLUDE_FROM_DEFAULT_BUILD 0)
# also set the name of the target output as the original one
set_target_properties(${unity_target_name} PROPERTIES OUTPUT_NAME ${ARG_NAME})
if(UCM_NO_COTIRE_FOLDER)
# reset the folder property so all unity targets dont end up in a single folder in the solution explorer of VS
set_target_properties(${unity_target_name} PROPERTIES FOLDER "")
endif()
set_target_properties(all_unity PROPERTIES FOLDER "CMakePredefinedTargets")
elseif(NOT "${ARG_PCH_FILE}" STREQUAL "")
set(wanted_cotire TRUE)
if(ucm_with_cotire)
set_target_properties(${orig_target} PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE)
set_target_properties(${orig_target} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${ARG_PCH_FILE}")
cotire(${orig_target})
set_target_properties(clean_cotire PROPERTIES FOLDER "CMakePredefinedTargets")
endif()
endif()
# print a message if the target was requested to be cotired but it couldn't
if(wanted_cotire AND NOT ucm_with_cotire)
if(NOT COMMAND cotire)
message(AUTHOR_WARNING "Target \"${ARG_NAME}\" not cotired because cotire isn't loaded")
else()
message(AUTHOR_WARNING "Target \"${ARG_NAME}\" not cotired because cotire is older than the required version")
endif()
endif()
endmacro()

View File

@ -1,11 +1,19 @@
cmake_minimum_required(VERSION 3.2)
cmake_minimum_required(VERSION 3.1)
project(xlnt.samples)
set(CMAKE_CXX_STANDARD 14)
# Require C++11 compiler
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT COMBINED_PROJECT)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../source ${CMAKE_CURRENT_BINARY_DIR}/source)
# Include xlnt library
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../source ${CMAKE_CURRENT_BINARY_DIR}/source)
endif()
if(MSVC AND STATIC)
# Link with static C runtime
include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/ucm.cmake)
ucm_set_runtime(STATIC)
endif()
set(XLNT_SAMPLE_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data)
@ -13,20 +21,24 @@ set(XLNT_SAMPLE_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data)
file(GLOB SAMPLE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
foreach(SAMPLE_SOURCE IN ITEMS ${SAMPLE_SOURCES})
get_filename_component(SAMPLE_NAME ${SAMPLE_SOURCE} NAME_WE)
set(SAMPLE_EXECUTABLE sample-${SAMPLE_NAME})
# Convert <name>.cpp to sample-<name>
get_filename_component(SAMPLE_NAME ${SAMPLE_SOURCE} NAME_WE)
set(SAMPLE_EXECUTABLE sample-${SAMPLE_NAME})
add_executable(${SAMPLE_EXECUTABLE} ${SAMPLE_SOURCE})
add_executable(${SAMPLE_EXECUTABLE} ${SAMPLE_SOURCE})
target_link_libraries(${SAMPLE_EXECUTABLE} PRIVATE xlnt)
target_include_directories(${SAMPLE_EXECUTABLE}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../tests)
target_compile_definitions(${SAMPLE_EXECUTABLE} PRIVATE XLNT_SAMPLE_DATA_DIR=${XLNT_SAMPLE_DATA_DIR})
target_link_libraries(${SAMPLE_EXECUTABLE} PRIVATE xlnt)
# Need to use some test helpers
target_include_directories(${SAMPLE_EXECUTABLE}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../tests)
target_compile_definitions(${SAMPLE_EXECUTABLE}
PRIVATE XLNT_SAMPLE_DATA_DIR=${XLNT_SAMPLE_DATA_DIR})
if(MSVC AND NOT STATIC)
add_custom_command(TARGET ${SAMPLE_EXECUTABLE} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:xlnt>
$<TARGET_FILE_DIR:${SAMPLE_EXECUTABLE}>)
endif()
if(MSVC AND NOT STATIC)
# Copy xlnt DLL into samples directory
add_custom_command(TARGET ${SAMPLE_EXECUTABLE} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:xlnt>
$<TARGET_FILE_DIR:${SAMPLE_EXECUTABLE}>)
endif()
endforeach()

View File

@ -1,44 +1,61 @@
cmake_minimum_required(VERSION 3.2)
project(xlnt VERSION 1.1)
cmake_minimum_required(VERSION 3.1)
project(xlnt VERSION 1.2)
set(CMAKE_CXX_STANDARD 14)
# Require C99 and C++11 compilers
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Project metadata
set(PROJECT_VENDOR "Thomas Fussell")
set(PROJECT_CONTACT "thomas.fussell@gmail.com")
set(PROJECT_URL "https://github.com/tfussell/xlnt")
set(PROJECT_DESCRIPTION "cross-platform user-friendly xlsx library for C++14")
if(APPLE)
option(FRAMEWORK "Set to ON to package dylib and headers into a .framework, OSX only" OFF)
endif()
set(PROJECT_DESCRIPTION "cross-platform user-friendly xlsx library for C++11")
# Commonly used project directories
set(XLNT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..)
set(XLNT_INCLUDE_DIR ${XLNT_ROOT_DIR}/include)
set(XLNT_SOURCE_DIR ${XLNT_ROOT_DIR}/source)
set(THIRD_PARTY_DIR ${XLNT_ROOT_DIR}/third-party)
add_subdirectory(${THIRD_PARTY_DIR}/libstudxml ${CMAKE_CURRENT_BINARY_DIR}/third-party/libstudxml)
# Include libstudxml library
add_subdirectory(${THIRD_PARTY_DIR}/libstudxml
${CMAKE_CURRENT_BINARY_DIR}/third-party/libstudxml)
if(COVERAGE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
endif()
# Non-target-specific compiler settings
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /MP")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") # level 4 warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") # multi-processor compilation
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unknown-pragmas")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") # all warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra") # extra warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas") # ignore MSVC and Clang pragmas
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weverything -Werror -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded -Wno-documentation-unknown-command -Wno-unknown-pragmas")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weverything") # all warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") # warnings are errors
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++98-compat") # ignore warnings about C++98 compatibility
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++98-compat-pedantic") # ignore pedantic warnings about C++98 compatibility
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-padded") # ignore padding warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-documentation-unknown-command") # ignore unknown commands in Javadoc-style comments
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas") # ignore Windows and GCC pragmas
endif()
if(MSVC AND STATIC)
# Link with static C runtime
include(${XLNT_ROOT_DIR}/cmake/ucm.cmake)
ucm_set_runtime(STATIC)
endif()
if(APPLE)
# Prevent a warning about deployment target not being set
execute_process(COMMAND "sw_vers -productVersion | awk -F'.' '{print $1\".\"$2}'"
OUTPUT_VARIABLE OSX_VERSION)
set(CMAKE_OSX_DEPLOYMENT_TARGET ${OSX_VERSION})
# Prevent a warning about deployment target not being set by setting it to current OSX version
execute_process(COMMAND "sw_vers -productVersion | awk -F'.' '{print $1\".\"$2}'"
OUTPUT_VARIABLE OSX_VERSION)
set(CMAKE_OSX_DEPLOYMENT_TARGET ${OSX_VERSION})
endif()
file(GLOB ROOT_HEADERS ${XLNT_INCLUDE_DIR}/xlnt/*.hpp)
@ -78,99 +95,105 @@ file(GLOB DETAIL_SERIALIZATION_HEADERS ${XLNT_SOURCE_DIR}/detail/serialization/*
file(GLOB DETAIL_SERIALIZATION_SOURCES ${XLNT_SOURCE_DIR}/detail/serialization/*.cpp)
set(DETAIL_HEADERS ${DETAIL_ROOT_HEADERS} ${DETAIL_CRYPTOGRAPHY_HEADERS}
${DETAIL_EXTERNAL_HEADERS} ${DETAIL_HEADER_FOOTER_HEADERS}
${DETAIL_IMPLEMENTATIONS_HEADERS} ${DETAIL_NUMBER_FORMAT_HEADERS}
${DETAIL_SERIALIZATION_HEADERS})
${DETAIL_EXTERNAL_HEADERS} ${DETAIL_HEADER_FOOTER_HEADERS}
${DETAIL_IMPLEMENTATIONS_HEADERS} ${DETAIL_NUMBER_FORMAT_HEADERS}
${DETAIL_SERIALIZATION_HEADERS})
set(DETAIL_SOURCES ${DETAIL_ROOT_SOURCES} ${DETAIL_CRYPTOGRAPHY_SOURCES}
${DETAIL_EXTERNAL_SOURCES} ${DETAIL_HEADER_FOOTER_SOURCES}
${DETAIL_IMPLEMENTATIONS_SOURCES} ${DETAIL_NUMBER_FORMAT_SOURCES}
${DETAIL_SERIALIZATION_SOURCES})
${DETAIL_EXTERNAL_SOURCES} ${DETAIL_HEADER_FOOTER_SOURCES}
${DETAIL_IMPLEMENTATIONS_SOURCES} ${DETAIL_NUMBER_FORMAT_SOURCES}
${DETAIL_SERIALIZATION_SOURCES})
set(XLNT_HEADERS ${ROOT_HEADERS} ${CELL_HEADERS} ${CHARTS_HEADERS}
${CHARTSHEET_HEADERS} ${DRAWING_HEADERS} ${FORMULA_HEADERS}
${PACKAGING_HEADERS} ${STYLES_HEADERS} ${UTILS_HEADERS}
${WORKBOOK_HEADERS} ${WORKSHEET_HEADERS} ${DETAIL_HEADERS} ${DETAIL_CRYPTO_HEADERS})
${CHARTSHEET_HEADERS} ${DRAWING_HEADERS} ${FORMULA_HEADERS}
${PACKAGING_HEADERS} ${STYLES_HEADERS} ${UTILS_HEADERS}
${WORKBOOK_HEADERS} ${WORKSHEET_HEADERS} ${DETAIL_HEADERS} ${DETAIL_CRYPTO_HEADERS})
set(XLNT_SOURCES ${CELL_SOURCES} ${CHARTS_SOURCES} ${CHARTSHEET_SOURCES}
${DRAWING_SOURCES} ${FORMULA_SOURCES} ${PACKAGING_SOURCES}
${STYLES_SOURCES} ${UTILS_SOURCES} ${WORKBOOK_SOURCES}
${WORKSHEET_SOURCES} ${DETAIL_SOURCES} ${DETAIL_CRYPTO_SOURCES})
${DRAWING_SOURCES} ${FORMULA_SOURCES} ${PACKAGING_SOURCES}
${STYLES_SOURCES} ${UTILS_SOURCES} ${WORKBOOK_SOURCES}
${WORKSHEET_SOURCES} ${DETAIL_SOURCES} ${DETAIL_CRYPTO_SOURCES})
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
if(MSVC)
set(DEFAULT_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/installed")
else()
set(DEFAULT_INSTALL_PREFIX "/usr/local")
endif()
# Set a default CMAKE_INSTALL_PREFIX if one wasn't specified
set(CMAKE_INSTALL_PREFIX ${DEFAULT_INSTALL_PREFIX}
CACHE PATH "default install path" FORCE)
if(MSVC)
# No good place to install on Windows so just install to cmake build directory in /installed
set(DEFAULT_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/installed")
else()
# Install to /usr/local on other platforms
set(DEFAULT_INSTALL_PREFIX "/usr/local")
endif()
# Apply the variable and save to cache
set(CMAKE_INSTALL_PREFIX ${DEFAULT_INSTALL_PREFIX}
CACHE PATH "default install path" FORCE)
endif()
if(NOT INC_DEST_DIR)
set(INC_DEST_DIR ${CMAKE_INSTALL_PREFIX}/include)
endif()
if(NOT LIB_DEST_DIR)
set(LIB_DEST_DIR ${CMAKE_INSTALL_PREFIX}/lib)
endif()
if(NOT BIN_DEST_DIR)
set(BIN_DEST_DIR ${CMAKE_INSTALL_PREFIX}/bin)
endif()
# Append "d" to the name of the compiled library
set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Set debug library postfix")
if(NOT STATIC)
add_library(xlnt SHARED ${XLNT_HEADERS} ${XLNT_SOURCES} $<TARGET_OBJECTS:libstudxml>)
target_compile_definitions(xlnt PRIVATE XLNT_SHARED=1)
# Compile shared library
add_library(xlnt SHARED
${XLNT_HEADERS}
${XLNT_SOURCES}
$<TARGET_OBJECTS:libstudxml>)
if(MSVC)
target_compile_definitions(xlnt PRIVATE XLNT_EXPORT=1 _CRT_SECURE_NO_WARNINGS=1)
endif()
target_compile_definitions(xlnt PRIVATE XLNT_SHARED=1)
set_target_properties(xlnt
PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
INSTALL_NAME_DIR "${LIB_DEST_DIR}")
if(FRAMEWORK)
add_custom_command(TARGET xlnt
POST_BUILD
COMMAND mkdir -p "${CMAKE_CURRENT_BINARY_DIR}/xlnt.framework/Versions/${PROJECT_VERSION_FULL}/Headers"
COMMAND cp -R ${XLNT_INCLUDE_DIR}/xlnt/* "${CMAKE_CURRENT_BINARY_DIR}/xlnt.framework/Versions/${PROJECT_VERSION_FULL}/Headers"
COMMAND cp "lib/lib${PROJECT_NAME}.${PROJECT_VERSION_FULL}.dylib" "${CMAKE_CURRENT_BINARY_DIR}/xlnt.framework/Versions/${PROJECT_VERSION_FULL}/xlnt"
COMMAND cd "${CMAKE_CURRENT_BINARY_DIR}/xlnt.framework/Versions" && ln -s "${PROJECT_VERSION_FULL}" Current
COMMAND cd "${CMAKE_CURRENT_BINARY_DIR}/xlnt.framework" && ln -s Versions/Current/* ./
)
endif()
# Set SO version (for symbolic links like libxlnt.so.1.2 and libxlnt.so.1)
set_target_properties(xlnt
PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
INSTALL_NAME_DIR "${LIB_DEST_DIR}")
else()
add_library(xlnt STATIC ${XLNT_HEADERS} ${XLNT_SOURCES} $<TARGET_OBJECTS:libstudxml>)
target_compile_definitions(xlnt PUBLIC XLNT_STATIC=1)
if(MSVC)
target_compile_definitions(xlnt PRIVATE _CRT_SECURE_NO_WARNINGS=1)
endif()
# Compile static library
add_library(xlnt STATIC ${XLNT_HEADERS} ${XLNT_SOURCES} $<TARGET_OBJECTS:libstudxml>)
target_compile_definitions(xlnt PUBLIC XLNT_STATIC=1)
endif()
# Includes
target_include_directories(xlnt PUBLIC ${XLNT_INCLUDE_DIR})
target_include_directories(xlnt PRIVATE ${XLNT_SOURCE_DIR})
target_include_directories(xlnt PRIVATE ${XLNT_SOURCE_DIR}/../third-party/libstudxml)
target_include_directories(xlnt PRIVATE ${XLNT_SOURCE_DIR}/../third-party/utfcpp)
# Platform- and file-specific settings, MSVC
if(MSVC)
set_target_properties(xlnt PROPERTIES COMPILE_FLAGS "/wd\"4251\" /wd\"4275\" /wd\"4068\" /MP")
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/miniz.cpp PROPERTIES COMPILE_FLAGS "/wd\"4244\" /wd\"4334\" /wd\"4127\"")
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/cryptography/aes.cpp PROPERTIES COMPILE_FLAGS "/wd\"4996\"")
target_compile_definitions(xlnt PRIVATE _CRT_SECURE_NO_WARNINGS=1)
if(NOT STATIC)
target_compile_definitions(xlnt PRIVATE XLNT_EXPORT=1)
endif()
set_target_properties(xlnt PROPERTIES
COMPILE_FLAGS "/wd\"4251\" /wd\"4275\" /wd\"4068\"")
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/miniz.cpp
PROPERTIES
COMPILE_FLAGS "/wd\"4244\" /wd\"4334\" /wd\"4127\"")
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/cryptography/aes.cpp
PROPERTIES
COMPILE_FLAGS "/wd\"4996\"")
endif()
# Platform- and file-specific settings, Clang
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/miniz.cpp PROPERTIES COMPILE_FLAGS "-Wno-undef")
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/zstream.cpp PROPERTIES COMPILE_FLAGS "-Wno-undef -Wno-shorten-64-to-32")
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/miniz.cpp
PROPERTIES
COMPILE_FLAGS "-Wno-undef")
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/zstream.cpp
PROPERTIES
COMPILE_FLAGS "-Wno-undef -Wno-shorten-64-to-32")
endif()
# Platform- and file-specific settings, GCC
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/miniz.cpp PROPERTIES COMPILE_FLAGS "-Wno-strict-aliasing")
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/miniz.cpp
PROPERTIES
COMPILE_FLAGS "-Wno-strict-aliasing")
endif()
# Group files into pseudo-folders in IDEs
source_group(xlnt FILES ${ROOT_HEADERS})
source_group(cell FILES ${CELL_HEADERS} ${CELL_SOURCES})
source_group(detail FILES ${DETAIL_ROOT_HEADERS} ${DETAIL_ROOT_SOURCES})
@ -186,31 +209,54 @@ source_group(utils FILES ${UTILS_HEADERS} ${UTILS_SOURCES})
source_group(workbook FILES ${WORKBOOK_HEADERS} ${WORKBOOK_SOURCES})
source_group(worksheet FILES ${WORKSHEET_HEADERS} ${WORKSHEET_SOURCES})
set(PKG_CONFIG_LIBDIR ${LIB_DEST_DIR})
set(PKG_CONFIG_INCLUDEDIR ${INC_DEST_DIR})
set(PKG_CONFIG_LIBS "-L\${libdir} -lxlnt")
set(PKG_CONFIG_CFLAGS "-I\${includedir}")
install(TARGETS xlnt
LIBRARY DESTINATION ${LIB_DEST_DIR}
ARCHIVE DESTINATION ${LIB_DEST_DIR}
RUNTIME DESTINATION ${BIN_DEST_DIR})
if(NOT MSVC)
configure_file("${XLNT_ROOT_DIR}/cmake/pkg-config.pc.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/xlnt.pc")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/xlnt.pc"
DESTINATION ${LIB_DEST_DIR}/pkgconfig)
if(NOT INC_DEST_DIR)
# Default location to install include files
set(INC_DEST_DIR ${CMAKE_INSTALL_PREFIX}/include)
endif()
if(NOT LIB_DEST_DIR)
# Default location to install library files
set(LIB_DEST_DIR ${CMAKE_INSTALL_PREFIX}/lib)
endif()
if(NOT BIN_DEST_DIR)
# Default location to install runtime files
set(BIN_DEST_DIR ${CMAKE_INSTALL_PREFIX}/bin)
endif()
# Install library
install(TARGETS xlnt
LIBRARY DESTINATION ${LIB_DEST_DIR}
ARCHIVE DESTINATION ${LIB_DEST_DIR}
RUNTIME DESTINATION ${BIN_DEST_DIR})
# Install include directory
install(DIRECTORY ${XLNT_INCLUDE_DIR}/xlnt
DESTINATION include
PATTERN ".DS_Store" EXCLUDE)
DESTINATION include
PATTERN ".DS_Store" EXCLUDE)
# Configure uninstall
configure_file("${XLNT_ROOT_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
# Add uninstall target
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
COMMAND ${CMAKE_COMMAND} -P
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
if(NOT MSVC)
# Set pkg-config variables
set(PKG_CONFIG_LIBDIR ${LIB_DEST_DIR})
set(PKG_CONFIG_INCLUDEDIR ${INC_DEST_DIR})
set(PKG_CONFIG_LIBS "-L\${libdir} -lxlnt")
set(PKG_CONFIG_CFLAGS "-I\${includedir}")
# Replace variables in pkg-config template
configure_file("${XLNT_ROOT_DIR}/cmake/pkg-config.pc.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/xlnt.pc")
# pkg-config install
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/xlnt.pc"
DESTINATION ${LIB_DEST_DIR}/pkgconfig)
endif()

View File

@ -1,11 +1,18 @@
cmake_minimum_required(VERSION 3.2)
cmake_minimum_required(VERSION 3.1)
project(xlnt.test)
set(CMAKE_CXX_STANDARD 14)
# Require C++11 compiler
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT COMBINED_PROJECT)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../source ${CMAKE_CURRENT_BINARY_DIR}/source)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../source ${CMAKE_CURRENT_BINARY_DIR}/source)
endif()
if(MSVC AND STATIC)
# Link with static C runtime
include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/ucm.cmake)
ucm_set_runtime(STATIC)
endif()
file(GLOB CELL_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/cell/*.hpp)
@ -16,12 +23,12 @@ file(GLOB WORKBOOK_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/workbook/*.hpp)
file(GLOB WORKSHEET_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/worksheet/*.hpp)
set(TESTS
${CELL_TESTS}
${PACKAGING_TESTS}
${STYLES_TESTS}
${UTILS_TESTS}
${WORKBOOK_TESTS}
${WORKSHEET_TESTS})
${CELL_TESTS}
${PACKAGING_TESTS}
${STYLES_TESTS}
${UTILS_TESTS}
${WORKBOOK_TESTS}
${WORKSHEET_TESTS})
file(GLOB HELPERS_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/helpers/*.hpp)
file(GLOB HELPERS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/helpers/*.cpp)
@ -30,21 +37,22 @@ set(HELPERS ${HELPERS_HEADERS} ${HELPERS_SOURCES})
set(RUNNER ${CMAKE_CURRENT_SOURCE_DIR}/runner.cpp)
if(COVERAGE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
endif()
add_executable(xlnt.test ${RUNNER} ${TESTS} ${HELPERS} $<TARGET_OBJECTS:libstudxml>)
target_link_libraries(xlnt.test PRIVATE xlnt)
target_include_directories(xlnt.test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../source
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../third-party/libstudxml)
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../source
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../third-party/libstudxml)
set(XLNT_TEST_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data)
target_compile_definitions(xlnt.test PRIVATE XLNT_TEST_DATA_DIR=${XLNT_TEST_DATA_DIR})
if(MSVC)
set_target_properties(xlnt.test PROPERTIES COMPILE_FLAGS "/wd\"4068\" /bigobj")
# bigobj because there are so many headers in one source file
set_target_properties(xlnt.test PROPERTIES COMPILE_FLAGS "/wd\"4068\" /bigobj")
endif()
source_group(helpers FILES ${HELPERS})
@ -58,8 +66,9 @@ source_group(tests\\workbook FILES ${WORKBOOK_TESTS})
source_group(tests\\worksheet FILES ${WORKSHEET_TESTS})
if(MSVC AND NOT STATIC)
add_custom_command(TARGET xlnt.test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:xlnt>
$<TARGET_FILE_DIR:xlnt.test>)
# copy xlnt DLL into xlnt.test directory
add_custom_command(TARGET xlnt.test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:xlnt>
$<TARGET_FILE_DIR:xlnt.test>)
endif()

View File

@ -1,73 +1,79 @@
cmake_minimum_required(VERSION 3.2)
cmake_minimum_required(VERSION 3.1)
project(libstudxml)
set(CMAKE_CXX_STANDARD 14)
# Require C++11 compiler
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(LIBSTUDXML_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(LIBSTUDXML_INCLUDE_DIR ${LIBSTUDXML_ROOT_DIR})
if(STATIC)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/ucm.cmake)
ucm_set_runtime(STATIC)
endif()
set(LIBSTUDXML
${LIBSTUDXML_ROOT_DIR}/xml/parser.cxx
${LIBSTUDXML_ROOT_DIR}/xml/qname.cxx
${LIBSTUDXML_ROOT_DIR}/xml/serializer.cxx
${LIBSTUDXML_ROOT_DIR}/xml/value-traits.cxx
${LIBSTUDXML_ROOT_DIR}/xml/content
${LIBSTUDXML_ROOT_DIR}/xml/exception
${LIBSTUDXML_ROOT_DIR}/xml/forward
${LIBSTUDXML_ROOT_DIR}/xml/parser
${LIBSTUDXML_ROOT_DIR}/xml/qname
${LIBSTUDXML_ROOT_DIR}/xml/serializer
${LIBSTUDXML_ROOT_DIR}/xml/value-traits)
${LIBSTUDXML_ROOT_DIR}/xml/parser.cxx
${LIBSTUDXML_ROOT_DIR}/xml/qname.cxx
${LIBSTUDXML_ROOT_DIR}/xml/serializer.cxx
${LIBSTUDXML_ROOT_DIR}/xml/value-traits.cxx
${LIBSTUDXML_ROOT_DIR}/xml/content
${LIBSTUDXML_ROOT_DIR}/xml/exception
${LIBSTUDXML_ROOT_DIR}/xml/forward
${LIBSTUDXML_ROOT_DIR}/xml/parser
${LIBSTUDXML_ROOT_DIR}/xml/qname
${LIBSTUDXML_ROOT_DIR}/xml/serializer
${LIBSTUDXML_ROOT_DIR}/xml/value-traits)
set(GENX
${LIBSTUDXML_ROOT_DIR}/xml/details/genx/char-props.c
${LIBSTUDXML_ROOT_DIR}/xml/details/genx/genx.c
${LIBSTUDXML_ROOT_DIR}/xml/details/genx/genx.h)
${LIBSTUDXML_ROOT_DIR}/xml/details/genx/char-props.c
${LIBSTUDXML_ROOT_DIR}/xml/details/genx/genx.c
${LIBSTUDXML_ROOT_DIR}/xml/details/genx/genx.h)
set(EXPAT
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmlparse.c
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmlrole.c
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmltok.c
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/ascii.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/asciitab.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/config.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/expat_external.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/expat.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/iasciitab.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/internal.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/latin1tab.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/nametab.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/utf8tab.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmlrole.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmltok_impl.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmltok.h)
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmlparse.c
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmlrole.c
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmltok.c
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/ascii.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/asciitab.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/config.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/expat_external.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/expat.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/iasciitab.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/internal.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/latin1tab.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/nametab.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/utf8tab.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmlrole.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmltok_impl.h
${LIBSTUDXML_ROOT_DIR}/xml/details/expat/xmltok.h)
add_library(libstudxml OBJECT ${LIBSTUDXML} ${GENX} ${EXPAT})
target_compile_definitions(libstudxml PUBLIC LIBSTUDXML_STATIC_LIB=1)
target_include_directories(libstudxml
PUBLIC ${LIBSTUDXML_ROOT_DIR}
PUBLIC ${EXPAT_INCLUDE_DIRS})
PUBLIC ${LIBSTUDXML_ROOT_DIR}
PUBLIC ${EXPAT_INCLUDE_DIRS})
if(STATIC)
target_compile_definitions(libstudxml PUBLIC XML_STATIC=1)
target_compile_definitions(libstudxml PUBLIC XML_STATIC=1)
endif()
# Prevent warning C4996 caused by strcpy, strncpy, sprintf in genx
# TODO: would it be better to define this only in genx.c?
if(MSVC)
target_compile_definitions(libstudxml PRIVATE _CRT_SECURE_NO_WARNINGS=1)
target_compile_definitions(libstudxml PRIVATE _CRT_SECURE_NO_WARNINGS=1)
endif()
# Build with -fPIC when xlnt is a shared library
# TODO: is this still necessary? try removing
if(NOT STATIC)
set_target_properties(libstudxml PROPERTIES POSITION_INDEPENDENT_CODE 1)
set_target_properties(libstudxml PROPERTIES POSITION_INDEPENDENT_CODE 1)
endif()
# When xlnt is a static library, assume expat will be linked statically too
# TODO: is this a valid assumption?
if(STATIC)
target_compile_definitions(libstudxml PUBLIC XML_STATIC=1)
target_compile_definitions(libstudxml PUBLIC XML_STATIC=1)
endif()