-
Notifications
You must be signed in to change notification settings - Fork 165
/
CMakeLists.txt
294 lines (249 loc) · 10.2 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
# Written in 2016-2017, 2021 by Henrik Steffen Gaßmann [email protected]
#
# To the extent possible under law, the author(s) have dedicated all
# copyright and related and neighboring rights to this software to the
# public domain worldwide. This software is distributed without any warranty.
#
# You should have received a copy of the CC0 Public Domain Dedication
# along with this software. If not, see
#
# http://creativecommons.org/publicdomain/zero/1.0/
#
########################################################################
cmake_minimum_required(VERSION 3.10.2)
# new dependent option syntax. We are already compliant
if (POLICY CMP0127)
cmake_policy(SET CMP0127 NEW)
endif()
project(base64 LANGUAGES C VERSION 0.5.2)
include(GNUInstallDirs)
include(CMakeDependentOption)
include(CheckIncludeFile)
include(FeatureSummary)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
#######################################################################
# platform detection
include(TargetArch)
detect_target_architecture(_TARGET_ARCH)
check_include_file(getopt.h HAVE_GETOPT_H)
cmake_dependent_option(BASE64_BUILD_CLI "Build the cli for encoding and decoding" ON "HAVE_GETOPT_H" OFF)
add_feature_info(CLI BASE64_BUILD_CLI "enables the CLI executable for encoding and decoding")
###################################################################
# optional/conditional dependencies
find_package(OpenMP)
set_package_properties(OpenMP PROPERTIES
TYPE OPTIONAL
PURPOSE "Allows to utilize OpenMP"
)
########################################################################
# Compilation options
option(BASE64_WERROR "Treat warnings as error" ON)
option(BASE64_BUILD_TESTS "add test projects" OFF)
cmake_dependent_option(BASE64_WITH_OpenMP "use OpenMP" OFF "OpenMP_FOUND" OFF)
add_feature_info("OpenMP codec" BASE64_WITH_OpenMP "spreads codec work accross multiple threads")
cmake_dependent_option(BASE64_REGENERATE_TABLES "regenerate the codec tables" OFF "NOT CMAKE_CROSSCOMPILING" OFF)
set(_IS_X86 "_TARGET_ARCH_x86 OR _TARGET_ARCH_x64")
cmake_dependent_option(BASE64_WITH_SSSE3 "add SSSE 3 codepath" ON ${_IS_X86} OFF)
add_feature_info(SSSE3 BASE64_WITH_SSSE3 "add SSSE 3 codepath")
cmake_dependent_option(BASE64_WITH_SSE41 "add SSE 4.1 codepath" ON ${_IS_X86} OFF)
add_feature_info(SSE4.1 BASE64_WITH_SSE41 "add SSE 4.1 codepath")
cmake_dependent_option(BASE64_WITH_SSE42 "add SSE 4.2 codepath" ON ${_IS_X86} OFF)
add_feature_info(SSE4.2 BASE64_WITH_SSE42 "add SSE 4.2 codepath")
cmake_dependent_option(BASE64_WITH_AVX "add AVX codepath" ON ${_IS_X86} OFF)
add_feature_info(AVX BASE64_WITH_AVX "add AVX codepath")
cmake_dependent_option(BASE64_WITH_AVX2 "add AVX 2 codepath" ON ${_IS_X86} OFF)
add_feature_info(AVX2 BASE64_WITH_AVX2 "add AVX2 codepath")
cmake_dependent_option(BASE64_WITH_AVX512 "add AVX 512 codepath" ON ${_IS_X86} OFF)
add_feature_info(AVX512 BASE64_WITH_AVX512 "add AVX512 codepath")
cmake_dependent_option(BASE64_WITH_NEON32 "add NEON32 codepath" OFF _TARGET_ARCH_arm OFF)
add_feature_info(NEON32 BASE64_WITH_NEON32 "add NEON32 codepath")
cmake_dependent_option(BASE64_WITH_NEON64 "add NEON64 codepath" ON _TARGET_ARCH_arm64 OFF)
add_feature_info(NEON64 BASE64_WITH_NEON64 "add NEON64 codepath")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
########################################################################
# Regenerate headers
if (BASE64_REGENERATE_TABLES)
# Generate tables in build folder and copy to source tree.
# Don't add the tables in the source tree to the outputs, to avoid `make clean` removing them.
add_executable(table_generator
lib/tables/table_generator.c
)
add_custom_command(OUTPUT table_dec_32bit.h "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_dec_32bit.h"
COMMAND table_generator > table_dec_32bit.h
COMMAND "${CMAKE_COMMAND}" -E copy table_dec_32bit.h "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_dec_32bit.h"
DEPENDS table_generator
)
set(Python_ADDITIONAL_VERSIONS 3)
find_package(PythonInterp REQUIRED)
add_custom_command(OUTPUT table_enc_12bit.h "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_enc_12bit.h"
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_enc_12bit.py" > table_enc_12bit.h
COMMAND "${CMAKE_COMMAND}" -E copy table_enc_12bit.h "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_enc_12bit.h"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_enc_12bit.py"
)
endif()
########################################################################
# library project
add_library(base64
# library files
lib/lib.c
lib/codec_choose.c
include/libbase64.h
lib/tables/tables.c
# Add generated headers explicitly to target, to insert them in the dependency tree
lib/tables/table_dec_32bit.h
lib/tables/table_enc_12bit.h
# codec implementations
lib/arch/generic/codec.c
lib/arch/ssse3/codec.c
lib/arch/sse41/codec.c
lib/arch/sse42/codec.c
lib/arch/avx/codec.c
lib/arch/avx2/codec.c
lib/arch/avx512/codec.c
lib/arch/neon32/codec.c
lib/arch/neon64/codec.c
)
target_include_directories(base64
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE
"${CMAKE_CURRENT_BINARY_DIR}"
)
####################################################################
# platform/compiler specific configuration
set_target_properties(base64 PROPERTIES
C_STANDARD 99
C_STANDARD_REQUIRED YES
C_EXTENSIONS OFF
DEFINE_SYMBOL BASE64_EXPORTS
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
)
#generate_export_header(base64)
# the following definitions and those in libbase64.h have been
# kept forward compatible in case we ever switch to generate_export_header
if (BUILD_SHARED_LIBS)
set_target_properties(base64 PROPERTIES
C_VISIBILITY_PRESET hidden
)
else()
target_compile_definitions(base64
PUBLIC
BASE64_STATIC_DEFINE
)
endif()
target_compile_options(base64 PRIVATE
$<$<C_COMPILER_ID:MSVC>:
/W4
/we4013 # Error warning C4013: 'function' undefined; assuming extern returning int
/we4700 # Error warning C4700: uninitialized local variable
/we4715 # not all control paths return a value
/we4003 # not enough actual parameters for macro
/wd4456 # disable warning C4456: declaration of 'xxx' hides previous local declaration
>
$<$<NOT:$<C_COMPILER_ID:MSVC>>:
-Wall
-Wextra
-Wpedantic
>
$<$<BOOL:${BASE64_WERROR}>:$<IF:$<C_COMPILER_ID:MSVC>,/WX,-Werror>>
)
target_compile_definitions(base64 PRIVATE
$<$<C_COMPILER_ID:MSVC>:
# remove unnecessary warnings about unchecked iterators
_SCL_SECURE_NO_WARNINGS
>
)
########################################################################
# SIMD settings
include(TargetSIMDInstructionSet)
define_SIMD_compile_flags()
if (_TARGET_ARCH STREQUAL "x86" OR _TARGET_ARCH STREQUAL "x64")
macro(configure_codec _TYPE)
if (BASE64_WITH_${_TYPE})
string(TOLOWER "${_TYPE}" _DIR)
set_source_files_properties("lib/arch/${_DIR}/codec.c" PROPERTIES
COMPILE_FLAGS "${COMPILE_FLAGS_${_TYPE}}"
)
if (${ARGC} GREATER 1 AND MSVC)
set_source_files_properties("lib/arch/${_DIR}/codec.c" PROPERTIES
COMPILE_DEFINITIONS ${ARGV1}
)
endif()
endif()
endmacro()
configure_codec(SSSE3 __SSSE3__)
configure_codec(SSE41 __SSSE4_1__)
configure_codec(SSE42 __SSSE4_2__)
configure_codec(AVX)
configure_codec(AVX2)
configure_codec(AVX512)
elseif (_TARGET_ARCH STREQUAL "arm")
set(BASE64_NEON32_CFLAGS "${COMPILE_FLAGS_NEON32}" CACHE STRING "the NEON32 compile flags (for 'lib/arch/neon32/codec.c')")
mark_as_advanced(BASE64_NEON32_CFLAGS)
if (BASE64_WITH_NEON32)
set_source_files_properties("lib/arch/neon32/codec.c" PROPERTIES
COMPILE_FLAGS "${BASE64_NEON32_CFLAGS} "
)
endif()
#elseif (_TARGET_ARCH STREQUAL "arm64" AND BASE64_WITH_NEON64)
endif()
configure_file("${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
########################################################################
# OpenMP Settings
if (BASE64_WITH_OpenMP)
target_link_libraries(base64 PRIVATE OpenMP::OpenMP_C)
endif()
########################################################################
if (BASE64_BUILD_TESTS)
enable_testing()
add_subdirectory(test)
endif()
########################################################################
# base64
if (BASE64_BUILD_CLI)
add_executable(base64-bin
bin/base64.c
)
target_link_libraries(base64-bin PRIVATE base64)
set_target_properties(base64-bin PROPERTIES
OUTPUT_NAME base64
)
if (WIN32)
target_sources(base64-bin PRIVATE bin/base64.rc)
endif ()
endif()
########################################################################
# cmake install
install(DIRECTORY include/ TYPE INCLUDE)
install(TARGETS base64
EXPORT base64-targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
if (BASE64_BUILD_CLI)
install(TARGETS base64-bin EXPORT base64-targets DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
include(CMakePackageConfigHelpers)
configure_package_config_file(cmake/base64-config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake"
VERSION ${BASE64_VERSION}
COMPATIBILITY SameMajorVersion
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
install(EXPORT base64-targets
NAMESPACE aklomp::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
########################################################################
feature_summary(WHAT PACKAGES_FOUND PACKAGES_NOT_FOUND ENABLED_FEATURES DISABLED_FEATURES)