-
Notifications
You must be signed in to change notification settings - Fork 2
/
CMakeLists.txt
395 lines (329 loc) · 12.6 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
#
# Copyright (C) 2023 Isuru Fernando
#
# This file is part of FLINT.
#
# FLINT is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License (LGPL) as published
# by the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version. See <http://www.gnu.org/licenses/>.
#
cmake_minimum_required(VERSION 3.10)
include(CheckIPOSupported)
include(CheckIncludeFiles)
include(CheckFunctionExists)
include(CheckPrototypeDefinition)
include(CheckCCompilerFlag)
include(CheckCSourceRuns)
include(CheckLibraryExists)
include(TestBigEndian)
project(flint LANGUAGES C CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
option(BUILD_SHARED_LIBS "Build shared libs" on)
option(WITH_NTL "Build with NTL or not" off)
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/configure.ac" CONFIGURE_CONTENTS)
string(REGEX MATCH "FLINT_MAJOR_SO=([0-9]*)" _ ${CONFIGURE_CONTENTS})
set(FLINT_MAJOR_SO ${CMAKE_MATCH_1})
string(REGEX MATCH "FLINT_MINOR_SO=([0-9]*)" _ ${CONFIGURE_CONTENTS})
set(FLINT_MINOR_SO ${CMAKE_MATCH_1})
string(REGEX MATCH "FLINT_PATCH_SO=([0-9]*)" _ ${CONFIGURE_CONTENTS})
set(FLINT_PATCH_SO ${CMAKE_MATCH_1})
find_package(GMP REQUIRED)
find_package(MPFR REQUIRED)
if (WITH_NTL)
find_package(NTL REQUIRED)
endif()
find_package(PythonInterp REQUIRED)
find_package(CBLAS)
set(FLINT_USES_BLAS ${CBLAS_FOUND})
if(CMAKE_BUILD_TYPE STREQUAL Debug)
set(FLINT_WANT_ASSERT ON)
endif()
# pthread configuration
if(MSVC)
find_package(PThreads REQUIRED)
set(FLINT_USES_PTHREAD ON CACHE BOOL "Use POSIX Threads.")
else()
option(CMAKE_THREAD_PREFER_PTHREAD "Prefer pthreads" yes)
option(THREADS_PREFER_PTHREAD_FLAG "Prefer -pthread flag" yes)
find_package(Threads REQUIRED)
set(PThreads_LIBRARIES Threads::Threads)
set(FLINT_USES_PTHREAD ON CACHE BOOL "Use POSIX Threads.")
endif()
# Find sources
set(_BUILD_DIRS
generic_files
thread_pool thread_support
ulong_extras
long_extras
perm
double_extras d_vec d_mat
mpn_extras
mpf_vec mpf_mat
mpfr_vec mpfr_mat
nmod nmod_vec nmod_mat nmod_poly
fmpz fmpz_vec fmpz_mat fmpz_poly
fmpz_mod fmpz_mod_vec fmpz_mod_mat fmpz_mod_poly
fmpq fmpq_vec fmpq_mat fmpq_poly
fq fq_vec fq_mat fq_poly
fq_nmod fq_nmod_vec fq_nmod_mat fq_nmod_poly
fq_zech fq_zech_vec fq_zech_mat fq_zech_poly
fq_default fq_default_mat fq_default_poly
fq_embed
fq_nmod_embed
fq_zech_embed
padic padic_mat padic_poly
qadic
nmod_poly_factor fmpz_factor
fmpz_poly_factor fmpz_mod_poly_factor
fq_poly_factor fq_nmod_poly_factor
fq_zech_poly_factor fq_default_poly_factor
nmod_poly_mat fmpz_poly_mat
mpoly nmod_mpoly fmpz_mpoly fmpz_mod_mpoly
fmpq_mpoly fq_nmod_mpoly fq_zech_mpoly
nmod_mpoly_factor fmpz_mpoly_factor
fmpz_mod_mpoly_factor fmpq_mpoly_factor
fq_nmod_mpoly_factor fq_zech_mpoly_factor
fft fmpz_poly_q fmpz_lll n_poly
arith qsieve aprcl
nf nf_elem qfb
double_interval dlog
fmpz_extras fmpzi
bool_mat partitions
mag
arf acf arb acb
arb_mat arb_poly arb_calc arb_hypgeom
acb_mat acb_poly acb_calc acb_hypgeom
arb_fmpz_poly arb_fpwrap
acb_dft acb_elliptic acb_modular acb_dirichlet
dirichlet bernoulli hypgeom
gr gr_generic gr_vec gr_mat
gr_poly gr_mpoly gr_special
calcium
fmpz_mpoly_q
fexpr fexpr_builtin
qqbar
ca ca_ext ca_field ca_vec
ca_poly ca_mat
flintxx
)
string(REGEX REPLACE "([A-Za-z0-9_-]+;|[A-Za-z0-9_-]+$)" "src/\\1" BUILD_DIRS "${_BUILD_DIRS}")
set(_TEMPLATE_DIRS
fq_vec_templates fq_mat_templates
fq_poly_templates fq_poly_factor_templates
fq_embed_templates fq_templates
)
string(REGEX REPLACE "([A-Za-z0-9_-]+;|[A-Za-z0-9_-]+$)" "src/\\1" TEMPLATE_DIRS "${_TEMPLATE_DIRS}")
if (WITH_NTL)
list(APPEND SOURCES src/interfaces/NTL-interface.cpp)
endif()
set(_HEADERS
NTL-interface.h flint.h longlong.h flint-config.h gmpcompat.h fft_tuning.h
profiler.h templates.h exception.h hashmap.h
)
string(REGEX REPLACE "([A-Za-z0-9_-]+\.h;|[A-Za-z0-9_-]+\.h$)" "src/\\1" HEADERS "${_HEADERS}")
# Setup for flint-config.h
check_c_compiler_flag("-mpopcnt" HAS_FLAG_MPOPCNT)
check_c_compiler_flag("-funroll-loops" HAS_FLAG_UNROLL_LOOPS)
if(HAS_FLAG_MPOPCNT)
set(CMAKE_REQUIRED_FLAGS "-mpopcnt")
endif()
# Testing __builtin_popcountl...
check_c_source_runs([[int main(int argc, char ** argv) {
#if defined(_WIN64)
return __builtin_popcountll(argc) == 100;
#else
return __builtin_popcountl(argc) == 100;
#endif
}]] FLINT_USES_POPCNT)
unset(CMAKE_REQUIRED_FLAGS)
# fenv configuration
check_c_source_compiles([[#include <fenv.h>
#ifndef FE_DOWNWARD
# error FE_DOWNWARD not available
#endif
void main(){};]] FLINT_USES_FENV)
# cpu_set_t configuration
set(CMAKE_REQUIRED_FLAGS "${PThreads_LIBRARIES}")
check_c_source_compiles([[#define _GNU_SOURCE
#include <sched.h>
#include <pthread.h>
int main() { cpu_set_t s; CPU_ZERO(&s);
pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), 0);
return 0; }]] FLINT_USES_CPUSET)
unset(CMAKE_REQUIRED_FLAGS)
# Thread-local storage configuration
if(cxx_thread_local IN_LIST CMAKE_CXX_COMPILE_FEATURES)
set(FLINT_USES_TLS ON CACHE BOOL "Use thread local storage.")
endif()
# Memory manager configuration
set(MEMORY_MANAGER "reentrant" CACHE STRING "The FLINT memory manager.")
set_property(CACHE MEMORY_MANAGER PROPERTY STRINGS single reentrant gc)
message(STATUS "Using FLINT memory manager: ${MEMORY_MANAGER}")
if(MEMORY_MANAGER STREQUAL "reentrant")
set(FLINT_REENTRANT ON)
else()
set(FLINT_REENTRANT OFF)
endif()
# Populate headers
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_config.h.in
${CMAKE_CURRENT_SOURCE_DIR}/src/flint-config.h
)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/src/fmpz/link/fmpz_${MEMORY_MANAGER}.c
${CMAKE_CURRENT_SOURCE_DIR}/src/fmpz/fmpz.c
COPYONLY
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/src/fft_tuning64.in
${CMAKE_CURRENT_SOURCE_DIR}/src/fft_tuning.h
COPYONLY
)
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/src/fft_tuning32.in
${CMAKE_CURRENT_SOURCE_DIR}/src/fft_tuning.h
COPYONLY
)
endif()
foreach (build_dir IN LISTS BUILD_DIRS TEMPLATE_DIRS)
file(GLOB TEMP RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${build_dir}/*.c")
list(APPEND SOURCES ${TEMP})
file(GLOB TEMP RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${build_dir}/*.h")
list(APPEND HEADERS ${TEMP})
endforeach ()
set(TEMP ${HEADERS})
set(HEADERS )
foreach(header IN LISTS TEMP)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${header})
list(APPEND HEADERS ${header})
else()
list(APPEND HEADERS ${CMAKE_CURRENT_BINARY_DIR}/${header})
endif()
endforeach()
file(GLOB TEMP "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h")
list(APPEND HEADERS ${TEMP})
add_library(flint ${SOURCES})
target_link_libraries(flint PUBLIC
${NTL_LIBRARY} ${MPFR_LIBRARIES} ${GMP_LIBRARIES} ${PThreads_LIBRARIES}
)
if(FLINT_USES_BLAS)
target_link_libraries(flint PUBLIC ${CBLAS_LIBRARIES})
endif()
# Include directories
target_include_directories(flint PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src ${GMP_INCLUDE_DIRS} ${MPFR_INCLUDE_DIRS}
${CMAKE_CURRENT_BINARY_DIR} ${PThreads_INCLUDE_DIRS}
${NTL_INCLUDE_DIR}
)
if(FLINT_USES_BLAS)
target_include_directories(flint PUBLIC ${CBLAS_INCLUDE_DIRS})
endif()
if(BUILD_SHARED_LIBS AND MSVC)
# Export all functions automatically (except global data)
set_target_properties(flint PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
# Export flint's global data that are marked manually
target_compile_definitions(flint PRIVATE "FLINT_BUILD_DLL")
# Use MPIR's dll import functions
target_compile_definitions(flint PUBLIC "MSC_USE_DLL")
endif()
if (HAS_FLAG_MPOPCNT)
target_compile_options(flint PUBLIC "-mpopcnt")
endif()
if (HAS_FLAG_UNROLL_LOOPS)
target_compile_options(flint PUBLIC "-funroll-loops")
endif()
# Versioning
set_target_properties(flint PROPERTIES
VERSION ${FLINT_MAJOR_SO}.${FLINT_MINOR_SO}.${FLINT_PATCH_SO}
SOVERSION ${FLINT_MAJOR_SO}
)
# Following versioning parts are optional
# Match versioning scheme in configure based build system.
if (APPLE)
if(${CMAKE_VERSION} VERSION_LESS "3.17.0")
message(WARNING "To match the versioning scheme of configure based build system, switch to cmake 3.17.0")
else ()
set_target_properties(flint PROPERTIES
MACHO_COMPATIBILITY_VERSION ${FLINT_MAJOR_SO}.${FLINT_MINOR_SO}
MACHO_CURRENT_VERSION ${FLINT_MAJOR_SO}.${FLINT_MINOR_SO}.${FLINT_PATCH_SO}
)
endif()
elseif (WIN32)
set_target_properties(flint PROPERTIES RUNTIME_OUTPUT_NAME "flint-${FLINT_MAJOR_SO}")
endif()
if(NOT DEFINED IPO_SUPPORTED)
message(STATUS "Checking for IPO")
check_ipo_supported(RESULT ipo_supported LANGUAGES C)
if(ipo_supported)
if (MSVC)
message(STATUS "Checking for IPO - found, but disabled for MSVC")
set(ipo_supported FALSE)
else()
message(STATUS "Checking for IPO - found")
endif()
else()
message(STATUS "Checking for IPO - not found")
endif()
set(IPO_SUPPORTED ${ipo_supported} CACHE INTERNAL "Introprocedural Optimization" FORCE)
endif()
# allow overriding IPO by setting -DCMAKE_INTERPROCEDURAL_OPTIMIZATION
if (IPO_SUPPORTED AND "${CMAKE_INTERPROCEDURAL_OPTIMIZATION}" STREQUAL "")
set_target_properties(flint PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
if(NOT MSVC)
target_link_libraries(flint PUBLIC m)
endif()
include(GNUInstallDirs)
install(TARGETS flint
RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}"
)
install(FILES ${HEADERS} DESTINATION include/flint)
set_target_properties(flint
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
)
if(BUILD_TESTING)
enable_testing()
foreach (build_dir IN LISTS BUILD_DIRS CMAKE_CURRENT_SOURCE_DIR)
file(GLOB TEST_FILES "${build_dir}/test/*.c")
foreach(test_file IN LISTS TEST_FILES)
file(RELATIVE_PATH test_name ${CMAKE_CURRENT_SOURCE_DIR} ${test_file})
string(REPLACE "/" "-" test_name ${test_name})
get_filename_component(test_name ${test_name} NAME_WE)
add_executable(${test_name} ${test_file})
target_link_libraries(${test_name} flint)
add_test(
NAME ${test_name}
COMMAND $<TARGET_FILE:${test_name}>
)
set_target_properties(${test_name}
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
)
endforeach()
endforeach ()
endif()
if(BUILD_DOCS)
find_package(Sphinx REQUIRED)
file(GLOB DOC_SOURCES doc/source/*.rst)
add_custom_target(html
COMMAND ${SPHINX_EXECUTABLE} -b html "${CMAKE_CURRENT_SOURCE_DIR}/doc/source" "${CMAKE_CURRENT_BINARY_DIR}/html"
SOURCES ${DOC_SOURCES})
add_custom_target(latex
COMMAND ${SPHINX_EXECUTABLE} -b latex "${CMAKE_CURRENT_SOURCE_DIR}/doc/source" "${CMAKE_CURRENT_BINARY_DIR}/latex"
SOURCES ${DOC_SOURCES})
add_custom_target(pdf DEPENDS latex COMMAND make WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/latex")
endif()