<commit_before>cmake_minimum_required(VERSION 3.9)

include(CheckIPOSupported)
include(CheckIncludeFiles)
include(CheckFunctionExists)
include(CheckPrototypeDefinition)
include(TestBigEndian)

project(flint LANGUAGES C CXX)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake")

option(WITH_NTL "Build with NTL or not" off)

find_package(GMP REQUIRED)
find_package(MPFR REQUIRED)
if (WITH_NTL)
    find_package(NTL REQUIRED)
endif()
find_package(PythonInterp REQUIRED)

if(MSVC)
    find_package(PThreads REQUIRED)
endif()

# Find sources

set(BUILD_DIRS
    aprcl ulong_extras long_extras perm fmpz fmpz_vec fmpz_poly 
    fmpq_poly fmpz_mat fmpz_lll mpfr_vec mpfr_mat mpf_vec mpf_mat nmod_vec nmod_poly 
    nmod_poly_factor arith mpn_extras nmod_mat fmpq fmpq_vec fmpq_mat padic 
    fmpz_poly_q fmpz_poly_mat nmod_poly_mat fmpz_mod_poly 
    fmpz_mod_poly_factor fmpz_factor fmpz_poly_factor fft qsieve 
    double_extras d_vec d_mat padic_poly padic_mat qadic  
    fq fq_vec fq_mat fq_poly fq_poly_factor
    fq_nmod fq_nmod_vec fq_nmod_mat fq_nmod_poly fq_nmod_mpoly fq_nmod_poly_factor 
    fq_zech fq_zech_vec fq_zech_mat fq_zech_poly fq_zech_poly_factor 
    mpoly fmpz_mpoly nmod_mpoly fmpq_mpoly thread_pool
    flintxx
)

set(TEMPLATE_DIRS
    fq_vec_templates fq_mat_templates fq_poly_templates
    fq_poly_factor_templates fq_templates
)

set(SOURCES
    printf.c fprintf.c sprintf.c scanf.c fscanf.c sscanf.c clz_tab.c
    memory_manager.c version.c profiler.c thread_support.c exception.c
    hashmap.c inlines.c fmpz/fmpz.c
)

if (WITH_NTL)
    list(APPEND SOURCES interfaces/NTL-interface.cpp)
endif()

set(HEADERS
    NTL-interface.h flint.h longlong.h config.h gmpcompat.h fft_tuning.h
    fmpz-conversions.h profiler.h templates.h exception.h hashmap.h
)

foreach (build_dir IN LISTS BUILD_DIRS TEMPLATE_DIRS)
    file(GLOB TEMP "${build_dir}/*.c")
    list(APPEND SOURCES ${TEMP})
    file(GLOB TEMP "${build_dir}/*.h")
    list(APPEND HEADERS ${TEMP})
endforeach ()

execute_process(
    COMMAND ${PYTHON_EXECUTABLE} -c 
"
from os.path import join

with open(join('${CMAKE_SOURCE_DIR}','qadic', 'CPimport.txt')) as fin:
    with open('CPimport.h', 'w+') as fout:
        while True:
            l = fin.readline()
            if not l:
                break
            l = l.replace(' ', ',')
            l = l.replace('\\n', ',\\n')
            fout.writelines([l])
"
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)

# Configuration checks
test_big_endian(HAVE_BIG_ENDIAN)

if(NOT HAVE_BIG_ENDIAN)
    set(HAVE_LITTLE_ENDIAN ON)
    set(HAVE_DOUBLE_IEEE_LITTLE_ENDIAN ON)
else()
    set(HAVE_DOUBLE_IEEE_BIG_ENDIAN ON)
endif()

# setup for config.h
check_include_files(alloca.h HAVE_ALLOCA_H)
check_include_files(dlfcn.h HAVE_DLFCN_H)
check_include_files(fcntl.h HAVE_FCNTL_H)
check_include_files(inttypes.h HAVE_INTTYPES_H)
check_include_files(locale.h HAVE_LOCALE_H)
check_include_files(memory.h HAVE_MEMORY_H)
check_include_files(sstream HAVE_SSTREAM)
check_include_files(stdint.h HAVE_STDINT_H)
check_include_files(stdlib.h HAVE_STDLIB_H)
check_include_files(strings.h HAVE_STRINGS_H)
check_include_files(string.h HAVE_STRING_H)
check_include_files(sys/mman.h HAVE_SYS_MMAN_H)
check_include_files(sys/param.h HAVE_SYS_PARAM_H)
check_include_files(sys/processor.h HAVE_SYS_PROCESSOR_H)
check_include_files(sys/resource.h HAVE_SYS_RESOURCE_H)
check_include_files(sys/stat.h HAVE_SYS_STAT_H)
check_include_files(sys/sysctl.h HAVE_SYS_SYSCTL_H)
check_include_files(sys/syssgi.h HAVE_SYS_SYSSGI_H)
check_include_files(sys/systemcfg.h HAVE_SYS_SYSTEMCFG_H)
check_include_files(sys/times.h HAVE_SYS_TIMES_H)
check_include_files(sys/time.h HAVE_SYS_TIME_H)
check_include_files(sys/types.h HAVE_SYS_TYPES_H)
check_include_files(unistd.h HAVE_UNISTD_H)
check_include_files(dlfcn.h HAVE_DLFCN_H)
check_include_files(fpu_control.h HAVE_FPU_CONTROL_H)


check_function_exists(alloca HAVE_ALLOCA)
check_function_exists(alarm HAVE_ALARM)
check_function_exists(clock HAVE_CLOCK)
check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
check_function_exists(cputime HAVE_CPUTIME)
check_function_exists(fgetc HAVE_DECL_FGETC)
check_function_exists(fscanf HAVE_DECL_FSCANF)
check_function_exists(optarg HAVE_DECL_OPTARG)
check_function_exists(ungetc HAVE_DECL_UNGETC)
check_function_exists(vfprintf HAVE_DECL_VFPRINTF)
check_function_exists(getpagesize HAVE_GETPAGESIZE)
check_function_exists(getrusage HAVE_GETRUSAGE)
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)

set(HAVE_TLS ON CACHE BOOL "Use thread local storage.")

set(MEMORY_MANAGER "reentrant" CACHE STRING "The FLINT memory manager.")
set_property(CACHE MEMORY_MANAGER PROPERTY STRINGS single reentrant gc)

if(MEMORY_MANAGER STREQUAL "reentrant")
	set(FLINT_REENTRANT ON)
else()
	set(FLINT_REENTRANT OFF)
endif()

configure_file(
    config.h.in
    config.h
)

configure_file(
    fmpz-conversions-${MEMORY_MANAGER}.in
    fmpz-conversions.h
    COPYONLY
)

configure_file(
    fmpz/link/fmpz_${MEMORY_MANAGER}.c
    fmpz/fmpz.c
    COPYONLY
)

if(CMAKE_SIZEOF_VOID_P EQUAL 8)
    configure_file(
        fft_tuning64.in
        fft_tuning.h
        COPYONLY
    )   
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
    configure_file(
        fft_tuning32.in
        fft_tuning.h
        COPYONLY
    )
endif()


set(TEMP ${HEADERS})
set(HEADERS )
foreach(header IN LISTS TEMP)
    if(EXISTS ${CMAKE_SOURCE_DIR}/${header})
        list(APPEND HEADERS ${header})
    else()
        list(APPEND HEADERS ${CMAKE_BINARY_DIR}/${header})  
    endif()
endforeach()

file(GLOB TEMP "${CMAKE_SOURCE_DIR}/*.h")
list(APPEND HEADERS ${TEMP})

add_library(flint SHARED ${SOURCES})
target_link_libraries(flint
    ${GMP_LIBRARIES} ${MPFR_LIBRARIES} ${PThreads_LIBRARIES} ${NTL_LIBRARY}
)

# Include directories

target_include_directories(flint PUBLIC 
    ${CMAKE_CURRENT_SOURCE_DIR} ${GMP_INCLUDE_DIRS} ${MPFR_INCLUDE_DIRS}
    ${CMAKE_CURRENT_BINARY_DIR} ${PThreads_INCLUDE_DIRS}
    ${NTL_INCLUDE_DIR}
)


if(BUILD_SHARED_LIBS AND MSVC)
    target_compile_definitions(flint PRIVATE "MSC_BUILD_DLL")<commit_msg>Build shared libs by default with an option<commit_after>cmake_minimum_required(VERSION 3.9)

include(CheckIPOSupported)
include(CheckIncludeFiles)
include(CheckFunctionExists)
include(CheckPrototypeDefinition)
include(TestBigEndian)

project(flint LANGUAGES C CXX)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake")

option(BUILD_SHARED_LIBS "Build shared libs" on)
option(WITH_NTL "Build with NTL or not" off)

find_package(GMP REQUIRED)
find_package(MPFR REQUIRED)
if (WITH_NTL)
    find_package(NTL REQUIRED)
endif()
find_package(PythonInterp REQUIRED)

if(MSVC)
    find_package(PThreads REQUIRED)
endif()

# Find sources

set(BUILD_DIRS
    aprcl ulong_extras long_extras perm fmpz fmpz_vec fmpz_poly 
    fmpq_poly fmpz_mat fmpz_lll mpfr_vec mpfr_mat mpf_vec mpf_mat nmod_vec nmod_poly 
    nmod_poly_factor arith mpn_extras nmod_mat fmpq fmpq_vec fmpq_mat padic 
    fmpz_poly_q fmpz_poly_mat nmod_poly_mat fmpz_mod_poly 
    fmpz_mod_poly_factor fmpz_factor fmpz_poly_factor fft qsieve 
    double_extras d_vec d_mat padic_poly padic_mat qadic  
    fq fq_vec fq_mat fq_poly fq_poly_factor
    fq_nmod fq_nmod_vec fq_nmod_mat fq_nmod_poly fq_nmod_mpoly fq_nmod_poly_factor 
    fq_zech fq_zech_vec fq_zech_mat fq_zech_poly fq_zech_poly_factor 
    mpoly fmpz_mpoly nmod_mpoly fmpq_mpoly thread_pool
    flintxx
)

set(TEMPLATE_DIRS
    fq_vec_templates fq_mat_templates fq_poly_templates
    fq_poly_factor_templates fq_templates
)

set(SOURCES
    printf.c fprintf.c sprintf.c scanf.c fscanf.c sscanf.c clz_tab.c
    memory_manager.c version.c profiler.c thread_support.c exception.c
    hashmap.c inlines.c fmpz/fmpz.c
)

if (WITH_NTL)
    list(APPEND SOURCES interfaces/NTL-interface.cpp)
endif()

set(HEADERS
    NTL-interface.h flint.h longlong.h config.h gmpcompat.h fft_tuning.h
    fmpz-conversions.h profiler.h templates.h exception.h hashmap.h
)

foreach (build_dir IN LISTS BUILD_DIRS TEMPLATE_DIRS)
    file(GLOB TEMP "${build_dir}/*.c")
    list(APPEND SOURCES ${TEMP})
    file(GLOB TEMP "${build_dir}/*.h")
    list(APPEND HEADERS ${TEMP})
endforeach ()

execute_process(
    COMMAND ${PYTHON_EXECUTABLE} -c 
"
from os.path import join

with open(join('${CMAKE_SOURCE_DIR}','qadic', 'CPimport.txt')) as fin:
    with open('CPimport.h', 'w+') as fout:
        while True:
            l = fin.readline()
            if not l:
                break
            l = l.replace(' ', ',')
            l = l.replace('\\n', ',\\n')
            fout.writelines([l])
"
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)

# Configuration checks
test_big_endian(HAVE_BIG_ENDIAN)

if(NOT HAVE_BIG_ENDIAN)
    set(HAVE_LITTLE_ENDIAN ON)
    set(HAVE_DOUBLE_IEEE_LITTLE_ENDIAN ON)
else()
    set(HAVE_DOUBLE_IEEE_BIG_ENDIAN ON)
endif()

# setup for config.h
check_include_files(alloca.h HAVE_ALLOCA_H)
check_include_files(dlfcn.h HAVE_DLFCN_H)
check_include_files(fcntl.h HAVE_FCNTL_H)
check_include_files(inttypes.h HAVE_INTTYPES_H)
check_include_files(locale.h HAVE_LOCALE_H)
check_include_files(memory.h HAVE_MEMORY_H)
check_include_files(sstream HAVE_SSTREAM)
check_include_files(stdint.h HAVE_STDINT_H)
check_include_files(stdlib.h HAVE_STDLIB_H)
check_include_files(strings.h HAVE_STRINGS_H)
check_include_files(string.h HAVE_STRING_H)
check_include_files(sys/mman.h HAVE_SYS_MMAN_H)
check_include_files(sys/param.h HAVE_SYS_PARAM_H)
check_include_files(sys/processor.h HAVE_SYS_PROCESSOR_H)
check_include_files(sys/resource.h HAVE_SYS_RESOURCE_H)
check_include_files(sys/stat.h HAVE_SYS_STAT_H)
check_include_files(sys/sysctl.h HAVE_SYS_SYSCTL_H)
check_include_files(sys/syssgi.h HAVE_SYS_SYSSGI_H)
check_include_files(sys/systemcfg.h HAVE_SYS_SYSTEMCFG_H)
check_include_files(sys/times.h HAVE_SYS_TIMES_H)
check_include_files(sys/time.h HAVE_SYS_TIME_H)
check_include_files(sys/types.h HAVE_SYS_TYPES_H)
check_include_files(unistd.h HAVE_UNISTD_H)
check_include_files(dlfcn.h HAVE_DLFCN_H)
check_include_files(fpu_control.h HAVE_FPU_CONTROL_H)


check_function_exists(alloca HAVE_ALLOCA)
check_function_exists(alarm HAVE_ALARM)
check_function_exists(clock HAVE_CLOCK)
check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
check_function_exists(cputime HAVE_CPUTIME)
check_function_exists(fgetc HAVE_DECL_FGETC)
check_function_exists(fscanf HAVE_DECL_FSCANF)
check_function_exists(optarg HAVE_DECL_OPTARG)
check_function_exists(ungetc HAVE_DECL_UNGETC)
check_function_exists(vfprintf HAVE_DECL_VFPRINTF)
check_function_exists(getpagesize HAVE_GETPAGESIZE)
check_function_exists(getrusage HAVE_GETRUSAGE)
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)

set(HAVE_TLS ON CACHE BOOL "Use thread local storage.")

set(MEMORY_MANAGER "reentrant" CACHE STRING "The FLINT memory manager.")
set_property(CACHE MEMORY_MANAGER PROPERTY STRINGS single reentrant gc)

if(MEMORY_MANAGER STREQUAL "reentrant")
	set(FLINT_REENTRANT ON)
else()
	set(FLINT_REENTRANT OFF)
endif()

configure_file(
    config.h.in
    config.h
)

configure_file(
    fmpz-conversions-${MEMORY_MANAGER}.in
    fmpz-conversions.h
    COPYONLY
)

configure_file(
    fmpz/link/fmpz_${MEMORY_MANAGER}.c
    fmpz/fmpz.c
    COPYONLY
)

if(CMAKE_SIZEOF_VOID_P EQUAL 8)
    configure_file(
        fft_tuning64.in
        fft_tuning.h
        COPYONLY
    )   
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
    configure_file(
        fft_tuning32.in
        fft_tuning.h
        COPYONLY
    )
endif()


set(TEMP ${HEADERS})
set(HEADERS )
foreach(header IN LISTS TEMP)
    if(EXISTS ${CMAKE_SOURCE_DIR}/${header})
        list(APPEND HEADERS ${header})
    else()
        list(APPEND HEADERS ${CMAKE_BINARY_DIR}/${header})  
    endif()
endforeach()

file(GLOB TEMP "${CMAKE_SOURCE_DIR}/*.h")
list(APPEND HEADERS ${TEMP})

add_library(flint ${SOURCES})
target_link_libraries(flint
    ${GMP_LIBRARIES} ${MPFR_LIBRARIES} ${PThreads_LIBRARIES} ${NTL_LIBRARY}
)

# Include directories

target_include_directories(flint PUBLIC 
    ${CMAKE_CURRENT_SOURCE_DIR} ${GMP_INCLUDE_DIRS} ${MPFR_INCLUDE_DIRS}
    ${CMAKE_CURRENT_BINARY_DIR} ${PThreads_INCLUDE_DIRS}
    ${NTL_INCLUDE_DIR}
)


if(BUILD_SHARED_LIBS AND MSVC)
    target_compile_definitions(flint PRIVATE "MSC_BUILD_DLL")
{'fraction_non_alphanumeric': 0.08123569794050343, 'fraction_numerical': 0.0013076168682576005, 'mean_word_length': 5.543850267379679, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4688138', 'n_tokens_mistral': 5029, 'n_tokens_neox': 4836, 'n_words': 792}