Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
354 lines (282 sloc) 11.3 KB
cmake_minimum_required(VERSION 3.4)
project(primesieve CXX)
set(PRIMESIEVE_VERSION "7.5")
set(PRIMESIEVE_SOVERSION "9.5.0")
# Build options ######################################################
option(BUILD_PRIMESIEVE "Build primesieve binary" ON)
option(BUILD_SHARED_LIBS "Build shared libprimesieve" ON)
option(BUILD_STATIC_LIBS "Build static libprimesieve" ON)
option(BUILD_DOC "Build documentation" OFF)
option(BUILD_EXAMPLES "Build example programs" OFF)
option(BUILD_TESTS "Build test programs" OFF)
if(NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
message(FATAL_ERROR "One or both of BUILD_SHARED_LIBS or BUILD_STATIC_LIBS must be set to ON")
endif()
# Set default build type to Release ##################################
if(NOT CMAKE_VERSION VERSION_LESS 3.9)
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
elseif(CMAKE_CONFIGURATION_TYPES)
set(isMultiConfig TRUE)
endif()
if(NOT isMultiConfig AND NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
endif()
# primesieve binary source files #####################################
set(BIN_SRC src/console/cmdoptions.cpp
src/console/help.cpp
src/console/main.cpp
src/console/test.cpp)
# primesieve library source files ####################################
set(LIB_SRC src/api-c.cpp
src/api.cpp
src/CpuInfo.cpp
src/EratBig.cpp
src/EratMedium.cpp
src/EratSmall.cpp
src/iterator-c.cpp
src/iterator.cpp
src/IteratorHelper.cpp
src/MemoryPool.cpp
src/PrimeGenerator.cpp
src/nthPrime.cpp
src/ParallelSieve.cpp
src/popcount.cpp
src/PreSieve.cpp
src/PrintPrimes.cpp
src/PrimeSieve.cpp
src/Erat.cpp
src/SievingPrimes.cpp
src/Wheel.cpp)
# Required includes ##################################################
include(GNUInstallDirs)
include(CMakePushCheckState)
include(CheckCXXCompilerFlag)
include(CheckCXXSourceCompiles)
include(CMakePackageConfigHelpers)
# MSVC DLL support (Windows) #########################################
if(WIN32 AND NOT MINGW)
set(WIN32_MSVC_COMPATIBLE ON)
if(BUILD_SHARED_LIBS)
# Export symbols to .def file
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()
endif()
# Silence GCC switch fall through warnings ###########################
check_cxx_compiler_flag(-Wno-implicit-fallthrough Wno_fallthrough)
if(Wno_fallthrough)
set_source_files_properties(src/EratSmall.cpp PROPERTIES COMPILE_FLAGS -Wno-implicit-fallthrough)
set_source_files_properties(src/EratMedium.cpp PROPERTIES COMPILE_FLAGS -Wno-implicit-fallthrough)
endif()
# Check if libatomic is needed #######################################
cmake_push_check_state()
if(CMAKE_CXX11_STANDARD_COMPILE_OPTION)
set(CMAKE_REQUIRED_FLAGS ${CMAKE_CXX11_STANDARD_COMPILE_OPTION})
endif()
check_cxx_source_compiles("
#include <atomic>
#include <stdint.h>
int main() {
std::atomic<int64_t> x;
x = 1;
x--;
return (int) x;
}"
atomic64)
if(NOT atomic64)
find_library(ATOMIC NAMES atomic libatomic.so.1)
if(ATOMIC)
set(LIBATOMIC ${ATOMIC})
message(STATUS "Found libatomic: ${LIBATOMIC}")
else()
check_cxx_source_compiles("
#include <atomic>
#include <stdint.h>
int main() {
std::atomic<int32_t> x;
x = 1;
x--;
return (int) x;
}"
atomic32)
if(atomic32)
message(FATAL_ERROR "Failed to find libatomic!")
endif()
endif()
endif()
cmake_pop_check_state()
# libprimesieve (shared library) #####################################
find_package(Threads REQUIRED QUIET)
if(BUILD_SHARED_LIBS)
add_library(libprimesieve SHARED ${LIB_SRC})
set_target_properties(libprimesieve PROPERTIES OUTPUT_NAME primesieve)
target_link_libraries(libprimesieve PRIVATE Threads::Threads ${LIBATOMIC})
string(REPLACE "." ";" SOVERSION_LIST ${PRIMESIEVE_SOVERSION})
list(GET SOVERSION_LIST 0 PRIMESIEVE_SOVERSION_MAJOR)
set_target_properties(libprimesieve PROPERTIES SOVERSION ${PRIMESIEVE_SOVERSION_MAJOR})
set_target_properties(libprimesieve PROPERTIES VERSION ${PRIMESIEVE_SOVERSION})
if(WIN32_MSVC_COMPATIBLE)
# On Windows the shared library will be named primesieve.dll
# and the associated import library will be named
# primesieve.lib. This is an issue as the static library
# is also named primesieve.lib. Hence we rename the import
# library to primesieve.dll.lib. The Rust programming
# language uses the same naming convention.
set_target_properties(libprimesieve PROPERTIES IMPORT_SUFFIX ".dll.lib")
endif()
target_compile_features(libprimesieve
PUBLIC
cxx_alias_templates
PRIVATE
cxx_constexpr
cxx_uniform_initialization
cxx_lambdas)
target_include_directories(libprimesieve PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
install(TARGETS libprimesieve
EXPORT primesieveShared
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
# libprimesieve-static ###############################################
if(BUILD_STATIC_LIBS)
add_library(libprimesieve-static STATIC ${LIB_SRC})
set_target_properties(libprimesieve-static PROPERTIES OUTPUT_NAME primesieve)
target_link_libraries(libprimesieve-static PRIVATE Threads::Threads ${LIBATOMIC})
if(TARGET libprimesieve)
add_dependencies(libprimesieve-static libprimesieve)
endif()
target_compile_features(libprimesieve-static
PUBLIC
cxx_alias_templates
PRIVATE
cxx_constexpr
cxx_uniform_initialization
cxx_lambdas)
target_include_directories(libprimesieve-static PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
install(TARGETS libprimesieve-static
EXPORT primesieveStatic
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
# Static or shared linking ###########################################
# On Unix-like OSes we use shared linking against libprimesieve by
# default mainly because this is required by Linux distributions.
# On Windows we use static linking by default because the library's
# path is not encoded into the binary. This means that the binary
# will only work if the DLL is in the same directory or a directory
# that is in the PATH environment variable.
if(WIN32 AND TARGET libprimesieve-static)
set(STATIC_LINKING ON)
elseif(NOT TARGET libprimesieve)
set(STATIC_LINKING ON)
endif()
if(STATIC_LINKING)
add_library(primesieve::primesieve ALIAS libprimesieve-static)
else()
add_library(primesieve::primesieve ALIAS libprimesieve)
endif()
# primesieve binary ##################################################
if(BUILD_PRIMESIEVE)
add_executable(primesieve ${BIN_SRC})
target_link_libraries(primesieve primesieve::primesieve)
target_compile_features(primesieve PRIVATE cxx_auto_type)
install(TARGETS primesieve DESTINATION ${CMAKE_INSTALL_BINDIR})
if(TARGET libprimesieve-static)
add_dependencies(primesieve libprimesieve-static)
endif()
endif()
# Install headers ####################################################
install(FILES include/primesieve.h
include/primesieve.hpp
COMPONENT libprimesieve-headers
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES include/primesieve/iterator.h
include/primesieve/iterator.hpp
include/primesieve/StorePrimes.hpp
include/primesieve/primesieve_error.hpp
COMPONENT libprimesieve-headers
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/primesieve)
# CMake find_package(primesieve) support #############################
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/primesieveConfigVersion.cmake"
VERSION ${PRIMESIEVE_VERSION}
COMPATIBILITY SameMajorVersion)
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/primesieveConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/primesieveConfig.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/primesieve")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/primesieveConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/primesieveConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/primesieve")
if(TARGET libprimesieve)
install(EXPORT primesieveShared
NAMESPACE primesieve::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/primesieve")
endif()
if(TARGET libprimesieve-static)
install(EXPORT primesieveStatic
NAMESPACE primesieve::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/primesieve")
endif()
# Regenerate man page ################################################
if(CMAKE_SYSTEM_NAME AND
CMAKE_HOST_SYSTEM_NAME AND
NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "${CMAKE_HOST_SYSTEM_NAME}")
set(IS_CROSS_COMPILIATION ON)
endif()
if(CMAKE_SYSTEM_PROCESSOR AND
CMAKE_HOST_SYSTEM_PROCESSOR AND
NOT "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "${CMAKE_HOST_SYSTEM_PROCESSOR}")
set(IS_CROSS_COMPILIATION ON)
endif()
if(BUILD_PRIMESIEVE AND NOT IS_CROSS_COMPILIATION)
find_program(HELP2MAN help2man)
if(HELP2MAN)
message(STATUS "Found help2man: ${HELP2MAN}")
execute_process(COMMAND perl -e "use Locale::gettext;"
RESULT_VARIABLE LOCALE_RES
OUTPUT_QUIET ERROR_QUIET)
if(LOCALE_RES EQUAL 0)
message(STATUS "Found help2man option: --locale=C.UTF-8")
set(HELP2MAN_LOCALE "--locale=C.UTF-8")
endif()
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${HELP2MAN}
ARGS -s 1
--manual="primesieve"
--source="primesieve ${PRIMESIEVE_VERSION}"
--no-info
${HELP2MAN_LOCALE}
-n "efficient prime number generator"
-o ${PROJECT_SOURCE_DIR}/doc/primesieve.1
$<TARGET_FILE:primesieve>
VERBATIM)
endif()
endif()
# Install man page ###################################################
if(BUILD_PRIMESIEVE)
install(FILES ${PROJECT_SOURCE_DIR}/doc/primesieve.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
endif()
# Install primesieve.pc (pkg-config) #################################
configure_file(primesieve.pc.in primesieve.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/primesieve.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
# Add subdirectories #################################################
if(BUILD_DOC)
add_subdirectory(doc)
endif()
if(BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
if(BUILD_TESTS)
enable_testing()
add_subdirectory(test)
endif()
You can’t perform that action at this time.