-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathCMakeLists.txt
234 lines (196 loc) · 6.89 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
cmake_minimum_required(VERSION 3.9)
project(fpm)
include(GNUInstallDirs)
set(CMAKE_CXX_STANDARD 11)
add_library(fpm INTERFACE)
target_include_directories(fpm INTERFACE include)
install(FILES
include/fpm/fixed.hpp
include/fpm/ios.hpp
include/fpm/math.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fpm)
OPTION(BUILD_ACCURACY "fpm accuracy" ON)
OPTION(BUILD_BENCHMARK "fpm benchmark" ON)
OPTION(BUILD_TESTS "fpm tests" ON)
# only build tests & benchmarks if a top-level project
if (NOT CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(BUILD_ACCURACY OFF)
set(BUILD_BENCHMARK OFF)
set(BUILD_TESTS OFF)
endif()
#
# Test suite
#
if (BUILD_TESTS)
enable_testing()
include(GoogleTest)
add_executable(fpm-test
tests/arithmetic.cpp
tests/arithmetic_int.cpp
tests/basic_math.cpp
tests/constants.cpp
tests/conversion.cpp
tests/classification.cpp
tests/customizations.cpp
tests/detail.cpp
tests/input.cpp
tests/manip.cpp
tests/nearest.cpp
tests/output.cpp
tests/power.cpp
tests/trigonometry.cpp
)
set_target_properties(fpm-test PROPERTIES CXX_STANDARD 11)
target_link_libraries(fpm-test PRIVATE fpm gtest_main)
gtest_add_tests(TARGET fpm-test)
endif()
#
# libfixmath for alternative comparison
#
include(ExternalProject)
if (BUILD_ACCURACY OR BUILD_BENCHMARK)
# Libfixmath uses a Makefile with hardcoded compiler (gcc).
# So we need to define our own build rules.
set(LIBFIXMATH_ROOT "${CMAKE_CURRENT_BINARY_DIR}/libfixmath")
ExternalProject_Add(libfixmath-external
GIT_REPOSITORY "/~https://github.com/PetteriAimonen/libfixmath.git"
GIT_TAG bada934981a5961569ad2cb6b9006ed94542cc9c
PREFIX ${LIBFIXMATH_ROOT}
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
set(LIBFIXMATH_SOURCES
${LIBFIXMATH_ROOT}/src/libfixmath-external/libfixmath/fix16.c
${LIBFIXMATH_ROOT}/src/libfixmath-external/libfixmath/fix16_exp.c
${LIBFIXMATH_ROOT}/src/libfixmath-external/libfixmath/fix16_sqrt.c
${LIBFIXMATH_ROOT}/src/libfixmath-external/libfixmath/fix16_str.c
${LIBFIXMATH_ROOT}/src/libfixmath-external/libfixmath/fix16_trig.c
${LIBFIXMATH_ROOT}/src/libfixmath-external/libfixmath/fract32.c
${LIBFIXMATH_ROOT}/src/libfixmath-external/libfixmath/uint32.c
)
set_source_files_properties(${LIBFIXMATH_SOURCES} PROPERTIES GENERATED TRUE)
add_library(libfixmath ${LIBFIXMATH_SOURCES})
# Set libfixmath compile options to match fpm functionality
target_compile_definitions(libfixmath
PUBLIC
FIXMATH_NO_CACHE # No caching of results
#FIXMATH_NO_OVERFLOW # We want no runtime-overflow detection, but it fails to compile
#FIXMATH_NO_ROUNDING # We do want rounding
#FIXMATH_NO_64BIT # We do want 64-bit integer support
#FIXMATH_OPTIMIZE_8BIT # No special 8-bit architecture optimizations
#FIXMATH_SIN_LUT # No lookup table for sin
#FIXMATH_FAST_SIN # Prefer accuracy over speed
)
target_include_directories(libfixmath PUBLIC ${LIBFIXMATH_ROOT}/src/libfixmath-external/libfixmath)
add_dependencies(libfixmath libfixmath-external)
endif()
if (BUILD_ACCURACY OR BUILD_BENCHMARK)
#
# CNL for alternative comparison
#
set(LIBCNL_ROOT "${CMAKE_CURRENT_BINARY_DIR}/libcnl")
ExternalProject_Add(libcnl-external
GIT_REPOSITORY "/~https://github.com/johnmcfarlane/cnl"
GIT_TAG 4d445566fe7c6c8939fffc145a2f30fd587796a6
PREFIX ${LIBCNL_ROOT}
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
add_library(libcnl INTERFACE)
target_include_directories(libcnl INTERFACE ${LIBCNL_ROOT}/src/libcnl-external/include)
add_dependencies(libcnl libcnl-external)
endif()
if (BUILD_BENCHMARK)
#
# Benchmark tool.
# Runs benchmarks of FPM operations and dumps results to standard output.
#
add_executable(fpm-benchmark
benchmarks/arithmetic.cpp
benchmarks/power.cpp
benchmarks/trigonometry.cpp
)
target_link_libraries(fpm-benchmark PRIVATE fpm libfixmath libcnl benchmark benchmark_main)
endif()
if (BUILD_ACCURACY)
#
# Accuracy tool.
# Dumps the accuracy of approximated FPM functions to JSON files.
#
add_executable(fpm-accuracy
accuracy/accuracy.cpp
)
set_target_properties(fpm-accuracy PROPERTIES CXX_STANDARD 14)
target_link_libraries(fpm-accuracy PRIVATE fpm libfixmath)
endif()
set(DATA_DIR ${CMAKE_CURRENT_BINARY_DIR})
include(FindGnuplot)
if (GNUPLOT_FOUND AND BUILD_ACCURACY)
# Create accuracy data
set(DATA_FILES_ACCURACY "")
set(IMG_FILES_ACCURACY "")
foreach(DATA sin-trig cos-trig tan-trig asin-invtrig acos-invtrig atan-invtrig atan2-trig sqrt-auto cbrt-auto pow-auto exp-auto exp2-auto log-auto log2-auto log10-auto)
string(REGEX MATCHALL "[^-]+" M ${DATA})
list(GET M 0 SERIES)
list(GET M 1 TYPE)
set(IMG_FILE ${DATA_DIR}/accuracy-${SERIES}.png)
list(APPEND DATA_FILES_ACCURACY ${DATA_DIR}/${SERIES}.csv)
list(APPEND IMG_FILES_ACCURACY ${IMG_FILE})
add_custom_command(
OUTPUT ${IMG_FILE}
COMMAND ${GNUPLOT_EXECUTABLE} -c ${PROJECT_SOURCE_DIR}/accuracy/accuracy.gnuplot ${SERIES} ${TYPE}
DEPENDS ${DATA_DIR}/${SERIES}.csv accuracy/accuracy.gnuplot
WORKING_DIRECTORY ${DATA_DIR}
VERBATIM
COMMENT "Plotting ${SERIES} accuracy data"
)
endforeach(DATA)
add_custom_command(
OUTPUT ${DATA_FILES_ACCURACY}
COMMAND fpm-accuracy
DEPENDS fpm-accuracy
WORKING_DIRECTORY ${DATA_DIR}
VERBATIM
COMMENT "Generating accuracy data with fpm-accuracy"
)
add_custom_target(fpm-accuracy-images DEPENDS ${IMG_FILES_ACCURACY})
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Release" AND GNUPLOT_FOUND AND BUILD_BENCHMARK)
# Enable the performance data-generation command only for Release builds.
set(DATA_FILE_PERFORMANCE_JSON ${DATA_DIR}/performance.json)
add_custom_command(
OUTPUT ${DATA_FILE_PERFORMANCE_JSON}
COMMAND fpm-benchmark --benchmark_out=${DATA_FILE_PERFORMANCE_JSON} --benchmark_out_format=json
DEPENDS fpm-benchmark
WORKING_DIRECTORY ${DATA_DIR}
VERBATIM
COMMENT "Generating performance data with fpm-benchmark"
)
set(DATA_FILE_PERFORMANCE_GNUPLOT ${DATA_DIR}/performance.csv)
add_custom_command(
OUTPUT ${DATA_FILE_PERFORMANCE_GNUPLOT}
COMMAND python ${PROJECT_SOURCE_DIR}/benchmarks/benchmark.py ${DATA_FILE_PERFORMANCE_JSON} ${DATA_FILE_PERFORMANCE_GNUPLOT}
DEPENDS ${DATA_FILE_PERFORMANCE_JSON} ${PROJECT_SOURCE_DIR}/benchmarks/benchmark.py
WORKING_DIRECTORY ${DATA_DIR}
VERBATIM
COMMENT "Converting performance data for GnuPlot"
)
set(IMG_FILE_PERFORMANCE "{$DATA_DIR}/performance.png")
add_custom_command(
OUTPUT ${IMG_FILE_PERFORMANCE}
COMMAND ${GNUPLOT_EXECUTABLE} ${PROJECT_SOURCE_DIR}/benchmarks/benchmark.gnuplot
DEPENDS ${DATA_FILE_PERFORMANCE_GNUPLOT} ${PROJECT_SOURCE_DIR}/benchmarks/benchmark.gnuplot
WORKING_DIRECTORY ${DATA_DIR}
VERBATIM
COMMENT "Plotting performance data"
)
add_custom_target(fpm-performance-images DEPENDS ${IMG_FILE_PERFORMANCE})
endif()
if (BUILD_BENCHMARK)
add_subdirectory(3rdparty/googlebench)
endif()
if (BUILD_TESTS)
add_subdirectory(3rdparty/googletest)
endif()