-
-
Notifications
You must be signed in to change notification settings - Fork 340
/
CMakeLists.txt
478 lines (421 loc) · 16.1 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
# :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.
#
# BUILD_FUZZERS
# Build fuzz harnesses (default off). To build the harnesses,
# pass `-DBUILD_FUZZERS=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.
#
# 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()
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(BUILD_FUZZERS "Build harness(es) for fuzzing" 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_MEM_FILE "Use fmemopen()/open_memstream() in place of 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)
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)
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)
if(NOT MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations")
endif()
endif()
if(USE_MEM_FILE OR 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()
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")
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\"")
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
find_package(PkgConfig)
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)
# INCLUDES
# --------
enable_language(CXX)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# ZLIB
if(PKG_CONFIG_FOUND)
pkg_check_modules(ZLIB zlib)
list(APPEND LXW_PRIVATE_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS})
else(NOT ZLIB_FOUND)
find_package(ZLIB "1.0" REQUIRED)
list(APPEND LXW_PRIVATE_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS})
message("zlib version: " ${ZLIB_VERSION})
endif()
# MINIZIP
if(USE_SYSTEM_MINIZIP)
if(PKG_CONFIG_FOUND)
pkg_check_modules(MINIZIP minizip)
list(APPEND LXW_PRIVATE_INCLUDE_DIRS ${MINIZIP_INCLUDE_DIRS}/..)
else(NOT MINIZIP_FOUND)
find_package(MINIZIP "1.0" REQUIRED)
list(APPEND LXW_PRIVATE_INCLUDE_DIRS ${MINIZIP_INCLUDE_DIRS})
endif()
endif()
# LIBRARY
# -------
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS NOCRYPT NOUNCRYPT)
# 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()
# Define "LXW_BIG_ENDIAN" macro on big-endian architectures
include(TestBigEndian)
TEST_BIG_ENDIAN(LXW_TARGET_BIG_ENDIAN)
if(LXW_TARGET_BIG_ENDIAN)
list(APPEND LXW_PRIVATE_COMPILE_DEFINITIONS LXW_BIG_ENDIAN)
endif()
file(GLOB LXW_SOURCES src/*.c)
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()
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)
if(PKG_CONFIG_FOUND)
pkg_check_modules(LIBCRYPTO libcrypto)
include_directories(${LIBCRYPTO_INCLUDE_DIRS})
else(NOT LIBCRYPTO_FOUND)
find_package(OpenSSL REQUIRED)
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")
add_library(${PROJECT_NAME} "")
set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${SOVERSION})
target_sources(${PROJECT_NAME}
PRIVATE ${LXW_SOURCES}
PUBLIC ${LXW_HEADERS}
)
if(ZLIB_LDFLAGS)
target_link_libraries(${PROJECT_NAME} LINK_PUBLIC ${ZLIB_LDFLAGS})
else()
target_link_libraries(${PROJECT_NAME} LINK_PUBLIC ${ZLIB_LIBRARIES})
endif()
if(MINIZIP_LDFLAGS)
target_link_libraries(${PROJECT_NAME} LINK_PUBLIC ${MINIZIP_LDFLAGS})
else()
target_link_libraries(${PROJECT_NAME} LINK_PUBLIC ${MINIZIP_LIBRARIES})
endif()
if(LIBCRYPTO_LDFLAGS)
target_link_libraries(${PROJECT_NAME} LINK_PUBLIC ${LIBCRYPTO_LDFLAGS})
else()
target_link_libraries(${PROJECT_NAME} LINK_PUBLIC ${LIB_CRYPTO} ${OPENSSL_CRYPTO_LIBRARY})
endif()
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()
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
#
macro(CreateTest sources target)
set(output_name xlsxwriter_${target})
set(dependencies ${output_name})
add_executable(${output_name} ${${sources}})
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)
if(NOT MSVC)
# Skip unit tests on Windows since ctest.h doesn't support it.
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}
)
else()
set(LXW_UNIT_SOURCES
test/cpp/test_compilation.cpp
)
endif()
if(BUILD_TESTS)
# unit tests
CreateTest(LXW_UNIT_SOURCES unit)
# functional tests
find_package(Python COMPONENTS Interpreter REQUIRED)
find_program(Pytest_EXECUTABLE NAMES pytest)
if (NOT Pytest_EXECUTABLE)
message("Please install the Python pytest library to run functional tests:")
message(" pip install pytest\n")
endif()
foreach(source ${LXW_FUNCTIONAL_SOURCES})
get_filename_component(basename ${source} NAME_WE)
add_executable(${basename} ${source})
target_link_libraries(${basename} xlsxwriter)
set_target_properties(${basename} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "test/functional/src")
endforeach(source)
add_custom_command(TARGET xlsxwriter_unit POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/test/functional test/functional
)
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()
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})
target_link_libraries(${basename} ${PROJECT_NAME})
set_target_properties(${basename} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "examples")
endforeach(source)
endif()
# FUZZING
# -------
if (BUILD_FUZZERS AND DEFINED ENV{LIB_FUZZING_ENGINE})
add_subdirectory(dev/fuzzing)
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)