CMakeLists.txt 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. # SPDX-License-Identifier: Unlicense
  2. #
  3. # LibTomCrypt, modular cryptographic library -- Tom St Denis
  4. #
  5. cmake_minimum_required(VERSION 3.10)
  6. project(libtomcrypt
  7. VERSION 1.18.2
  8. DESCRIPTION "A modular cryptographic library."
  9. HOMEPAGE_URL "https://www.libtom.net/LibTomCrypt"
  10. LANGUAGES C)
  11. # package release version
  12. # bump if re-releasing the same VERSION + patches
  13. # set to 1 if releasing a new VERSION
  14. set(PACKAGE_RELEASE_VERSION 1)
  15. #-----------------------------------------------------------------------------
  16. # Include CMake modules
  17. #-----------------------------------------------------------------------------
  18. include(GNUInstallDirs)
  19. include(CheckIPOSupported)
  20. include(CMakePackageConfigHelpers)
  21. # for potential builds against gnump
  22. include(FindPkgConfig)
  23. # for potential builds with MSVC
  24. include(CMakePushCheckState)
  25. include(CheckSymbolExists)
  26. # default is "No tests"
  27. option(BUILD_TESTING "" OFF)
  28. include(CTest)
  29. include(sources.cmake)
  30. #-----------------------------------------------------------------------------
  31. # Options
  32. #-----------------------------------------------------------------------------
  33. option(WITH_LTM "Build with support for libtommath" TRUE)
  34. option(WITH_TFM "Build with support for tomsfastmath" FALSE)
  35. option(WITH_GMP "Build with support for GNU Multi Precision Arithmetic Library" FALSE)
  36. set(MPI_PROVIDER "LTM" CACHE STRING "Build tests and demos against 'LTM', 'TFM' or 'GMP', default is LTM")
  37. option(BUILD_SHARED_LIBS "Build shared library and only the shared library if \"ON\", default is static" OFF)
  38. #-----------------------------------------------------------------------------
  39. # Add support for ccache if desired
  40. #-----------------------------------------------------------------------------
  41. find_program(CCACHE ccache)
  42. if(CCACHE)
  43. option(ENABLE_CCACHE "Enable ccache." ON)
  44. endif()
  45. # use ccache if installed
  46. if(CCACHE AND ENABLE_CCACHE)
  47. set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE})
  48. endif()
  49. #-----------------------------------------------------------------------------
  50. # Compose CFLAGS
  51. #-----------------------------------------------------------------------------
  52. # Some information ported from makefile_include.mk
  53. if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  54. message(STATUS "Setting build type to 'Release' as none was specified.")
  55. set(CMAKE_BUILD_TYPE "Release")
  56. endif()
  57. # We differentiate between MSVC, WATCOM and GCC-compatible compilers
  58. if(MSVC)
  59. set(LTC_C_FLAGS -W3)
  60. elseif(WATCOM)
  61. set(LTC_C_FLAGS -fo=.obj -oaxt -3r -w3)
  62. else()
  63. set(LTC_C_FLAGS -Wall -Wsign-compare -Wextra -Wshadow
  64. -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align
  65. -Wstrict-prototypes -Wpointer-arith -Wsystem-headers)
  66. set(CMAKE_C_FLAGS_DEBUG "-g3")
  67. set(CMAKE_C_FLAGS_RELEASE "-O3 -funroll-loops -fomit-frame-pointer")
  68. set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g3 -O2")
  69. set(CMAKE_C_FLAGS_MINSIZEREL "-Os")
  70. endif()
  71. # What compiler do we have and what are their...uhm... peculiarities
  72. if(CMAKE_C_COMPILER_ID MATCHES "(C|c?)lang")
  73. list(APPEND LTC_C_FLAGS -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header)
  74. # Clang requires at least '-O1' for dead code eliminiation
  75. set(CMAKE_C_FLAGS_DEBUG "-O1 ${CMAKE_C_FLAGS_DEBUG}")
  76. endif()
  77. if(CMAKE_C_COMPILER MATCHES "mingw")
  78. list(APPEND LTC_C_FLAGS -Wno-shadow -Wno-expansion-to-defined -Wno-declaration-after-statement -Wno-bad-function-cast)
  79. endif()
  80. if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
  81. list(APPEND LTC_C_FLAGS -Wno-nullability-completeness)
  82. endif()
  83. if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
  84. list(APPEND LTC_C_FLAGS -no-undefined)
  85. endif()
  86. if(MSVC)
  87. cmake_push_check_state()
  88. check_symbol_exists(BCryptGenRandom bcrypt.h BCRYPT_AVAILABLE)
  89. cmake_pop_check_state()
  90. if (BCRYPT_AVAILABLE)
  91. target_link_libraries(${PROJECT_NAME} PRIVATE Bcrypt)
  92. list(APPEND LTC_C_FLAGS -DLTC_WIN32_BCRYPT)
  93. endif()
  94. endif()
  95. # If the user set the environment variables at generate-time, append them
  96. # in order to allow overriding our defaults.
  97. # ${LTC_CFLAGS} means the user passed it via sth like:
  98. # $ cmake -DLTC_CFLAGS="foo"
  99. list(APPEND LTC_C_FLAGS ${LTC_CFLAGS})
  100. list(APPEND LTC_LD_FLAGS ${LTC_LDFLAGS})
  101. #-----------------------------------------------------------------------------
  102. # Library targets
  103. #-----------------------------------------------------------------------------
  104. add_library(${PROJECT_NAME}
  105. ${SOURCES}
  106. ${PUBLIC_HEADERS}
  107. ${PRIVATE_HEADERS}
  108. )
  109. target_include_directories(${PROJECT_NAME} PUBLIC
  110. $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/headers>
  111. $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}>
  112. )
  113. target_compile_options(${PROJECT_NAME} BEFORE PRIVATE
  114. ${LTC_C_FLAGS}
  115. )
  116. target_link_options(${PROJECT_NAME} BEFORE PRIVATE
  117. ${LTC_LD_FLAGS}
  118. )
  119. set_target_properties(${PROJECT_NAME} PROPERTIES
  120. OUTPUT_NAME tomcrypt
  121. VERSION ${PROJECT_VERSION}
  122. SOVERSION ${PROJECT_VERSION_MAJOR}
  123. PUBLIC_HEADER "${PUBLIC_HEADERS}"
  124. )
  125. option(COMPILE_LTO "Build with LTO enabled")
  126. if(COMPILE_LTO)
  127. check_ipo_supported(RESULT COMPILER_SUPPORTS_LTO)
  128. if(COMPILER_SUPPORTS_LTO)
  129. set_property(TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
  130. else()
  131. message(SEND_ERROR "This compiler does not support LTO. Reconfigure ${PROJECT_NAME} with -DCOMPILE_LTO=OFF.")
  132. endif()
  133. endif()
  134. #-----------------------------------------------------------------------------
  135. # MPI provider
  136. #-----------------------------------------------------------------------------
  137. # libtommath
  138. if(WITH_LTM)
  139. find_package(libtommath 1.2.0 REQUIRED)
  140. target_compile_definitions(${PROJECT_NAME} PUBLIC LTM_DESC)
  141. if(MPI_PROVIDER MATCHES "LTM")
  142. target_compile_definitions(${PROJECT_NAME} PUBLIC USE_LTM)
  143. endif()
  144. target_link_libraries(${PROJECT_NAME} PUBLIC libtommath)
  145. list(APPEND LTC_MPI_PROVIDERS_CFLAGS -DLTM_DESC)
  146. list(APPEND LTC_MPI_PROVIDERS_LIBS -ltommath)
  147. list(APPEND LTC_DEBIAN_MPI_PROVIDER_DEPENDS libtommath-dev)
  148. endif()
  149. # tomsfastmath
  150. if(WITH_TFM)
  151. find_package(tomsfastmath 0.13.1 REQUIRED)
  152. target_compile_definitions(${PROJECT_NAME} PUBLIC TFM_DESC)
  153. if(MPI_PROVIDER MATCHES "TFM")
  154. target_compile_definitions(${PROJECT_NAME} PUBLIC USE_TFM)
  155. endif()
  156. target_link_libraries(${PROJECT_NAME} PUBLIC tomsfastmath)
  157. list(APPEND LTC_MPI_PROVIDERS_CFLAGS -DTFM_DESC)
  158. list(APPEND LTC_MPI_PROVIDERS_LIBS -ltfm)
  159. list(APPEND LTC_DEBIAN_MPI_PROVIDER_DEPENDS libtfm-dev)
  160. endif()
  161. # GNU MP
  162. if(WITH_GMP)
  163. pkg_check_modules(GMP REQUIRED gmp>=6.1.2)
  164. target_compile_definitions(${PROJECT_NAME} PUBLIC GMP_DESC)
  165. if(MPI_PROVIDER MATCHES "GMP")
  166. target_compile_definitions(${PROJECT_NAME} PUBLIC USE_GMP)
  167. endif()
  168. target_link_libraries(${PROJECT_NAME} PUBLIC ${GMP_LIBRARIES})
  169. list(APPEND LTC_MPI_PROVIDERS_CFLAGS -DGMP_DESC)
  170. list(APPEND LTC_MPI_PROVIDERS_LIBS -lgmp)
  171. list(APPEND LTC_DEBIAN_MPI_PROVIDER_DEPENDS libgmp-dev)
  172. endif()
  173. list(JOIN LTC_MPI_PROVIDERS_CFLAGS " " MPI_PROVIDERS_CFLAGS)
  174. list(JOIN LTC_MPI_PROVIDERS_LIBS " " MPI_PROVIDERS_LIBS)
  175. list(JOIN LTC_DEBIAN_MPI_PROVIDER_DEPENDS " " DEBIAN_MPI_PROVIDER_DEPENDS)
  176. #-----------------------------------------------------------------------------
  177. # demos&test targets
  178. #-----------------------------------------------------------------------------
  179. add_subdirectory(demos)
  180. if(BUILD_TESTING)
  181. enable_testing()
  182. add_subdirectory(tests)
  183. endif()
  184. #---------------------------------------------------------------------------------------
  185. # Install/export targets and files
  186. #---------------------------------------------------------------------------------------
  187. set(CONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
  188. set(PROJECT_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake")
  189. set(PROJECT_CONFIG_FILE "${PROJECT_NAME}-config.cmake")
  190. set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
  191. # install targets
  192. install(TARGETS ${PROJECT_NAME}
  193. EXPORT ${TARGETS_EXPORT_NAME}
  194. LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  195. ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries
  196. RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
  197. PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
  198. )
  199. # Install libtomcrypt.pc for pkg-config if we build a shared library
  200. if(BUILD_SHARED_LIBS)
  201. # Let the user override the default directory of the pkg-config file (usually this shouldn't be required to be changed)
  202. set(CMAKE_INSTALL_PKGCONFIGDIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig" CACHE PATH "Folder where to install .pc files")
  203. configure_file(
  204. ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc.in
  205. ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
  206. @ONLY
  207. )
  208. install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
  209. DESTINATION ${CMAKE_INSTALL_PKGCONFIGDIR}
  210. )
  211. endif()
  212. # generate package version file
  213. write_basic_package_version_file(
  214. ${PROJECT_VERSION_FILE}
  215. VERSION ${PROJECT_VERSION}
  216. COMPATIBILITY SameMajorVersion
  217. )
  218. # install version file
  219. install(FILES ${PROJECT_VERSION_FILE}
  220. DESTINATION ${CONFIG_INSTALL_DIR}
  221. )
  222. # build directory package config
  223. export(EXPORT ${TARGETS_EXPORT_NAME}
  224. FILE ${PROJECT_CONFIG_FILE}
  225. )
  226. # installed package config
  227. install(EXPORT ${TARGETS_EXPORT_NAME}
  228. DESTINATION ${CONFIG_INSTALL_DIR}
  229. FILE ${PROJECT_CONFIG_FILE}
  230. )
  231. # add to CMake registry
  232. export(PACKAGE ${PROJECT_NAME})
  233. #---------------------------------------------------------------------------------------
  234. # Create release packages
  235. #---------------------------------------------------------------------------------------
  236. # determine distribution and architecture
  237. find_program(LSB_RELEASE lsb_release)
  238. find_program(SYSCTL sysctl)
  239. find_program(UNAME uname)
  240. if(UNAME)
  241. execute_process(COMMAND uname -m OUTPUT_VARIABLE MACHINE_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
  242. elseif(SYSCTL)
  243. execute_process(COMMAND sysctl -b hw.machine_arch OUTPUT_VARIABLE MACHINE_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
  244. else()
  245. string(TOLOWER ${CMAKE_SYSTEM_NAME} MACHINE_ARCH)
  246. endif()
  247. if(LSB_RELEASE)
  248. execute_process(COMMAND lsb_release -si OUTPUT_VARIABLE LINUX_DISTRO OUTPUT_STRIP_TRAILING_WHITESPACE)
  249. execute_process(COMMAND lsb_release -sc OUTPUT_VARIABLE LINUX_DISTRO_CODENAME OUTPUT_STRIP_TRAILING_WHITESPACE)
  250. execute_process(COMMAND lsb_release -sr OUTPUT_VARIABLE LINUX_DISTRO_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
  251. string(TOLOWER ${LINUX_DISTRO} LINUX_DISTRO)
  252. if(LINUX_DISTRO_CODENAME STREQUAL "n/a")
  253. set(DISTRO_PACK_PATH ${LINUX_DISTRO}/${LINUX_DISTRO_VERSION}/)
  254. else()
  255. set(DISTRO_PACK_PATH ${LINUX_DISTRO}/${LINUX_DISTRO_CODENAME}/)
  256. endif()
  257. else()
  258. set(DISTRO_PACK_PATH ${CMAKE_SYSTEM_NAME}/)
  259. endif()
  260. # make sure untagged versions get a different package name
  261. execute_process(COMMAND git describe --exact-match --tags ERROR_QUIET RESULT_VARIABLE REPO_HAS_TAG)
  262. if(REPO_HAS_TAG EQUAL 0)
  263. set(PACKAGE_NAME_SUFFIX "")
  264. else()
  265. set(PACKAGE_NAME_SUFFIX "-git")
  266. message(STATUS "Use -git suffix")
  267. endif()
  268. # default CPack generators
  269. set(CPACK_GENERATOR TGZ STGZ)
  270. # extra CPack generators
  271. if(LINUX_DISTRO STREQUAL "debian" OR LINUX_DISTRO STREQUAL "ubuntu" OR LINUX_DISTRO STREQUAL "linuxmint")
  272. list(APPEND CPACK_GENERATOR DEB)
  273. elseif(LINUX_DISTRO STREQUAL "fedora" OR LINUX_DISTRO STREQUAL "opensuse" OR LINUX_DISTRO STREQUAL "centos")
  274. list(APPEND CPACK_GENERATOR RPM)
  275. elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
  276. list(APPEND CPACK_GENERATOR FREEBSD)
  277. endif()
  278. set(LTC_DEBIAN_SHARED_PACKAGE_NAME "${PROJECT_NAME}${PACKAGE_NAME_SUFFIX}${PROJECT_VERSION_MAJOR}")
  279. # general CPack config
  280. set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR}/packages/${DISTRO_PACK_PATH})
  281. message(STATUS "CPack: packages will be generated under ${CPACK_PACKAGE_DIRECTORY}")
  282. if(BUILD_SHARED_LIBS)
  283. set(CPACK_PACKAGE_NAME "${PROJECT_NAME}${PROJECT_VERSION_MAJOR}")
  284. set(CPACK_DEBIAN_PACKAGE_NAME "${LTC_DEBIAN_SHARED_PACKAGE_NAME}")
  285. else()
  286. set(CPACK_PACKAGE_NAME "${PROJECT_NAME}-devel")
  287. set(CPACK_DEBIAN_LIBRARIES_PACKAGE_NAME "${PROJECT_NAME}${PACKAGE_NAME_SUFFIX}-dev")
  288. endif()
  289. set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
  290. set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LibTomCrypt")
  291. set(CPACK_PACKAGE_VENDOR "libtom projects")
  292. set(CPACK_PACKAGE_CONTACT "[email protected]")
  293. set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
  294. set(PACKAGE_NAME_TRAILER ${CPACK_PACKAGE_VERSION}-${PACKAGE_RELEASE_VERSION}_${MACHINE_ARCH})
  295. set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${PACKAGE_NAME_TRAILER})
  296. set(CPACK_STRIP_FILES ON)
  297. # deb specific CPack config
  298. set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
  299. set(CPACK_DEBIAN_DEBUGINFO_PACKAGE ON)
  300. set(CPACK_DEBIAN_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION})
  301. set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
  302. if(BUILD_SHARED_LIBS)
  303. set(CPACK_DEBIAN_PACKAGE_SECTION "libs")
  304. set(CPACK_DEBIAN_PACKAGE_DEPENDS ${DEBIAN_MPI_PROVIDER_DEPENDS})
  305. else()
  306. set(CPACK_DEBIAN_PACKAGE_SECTION "libdevel")
  307. set(CPACK_DEBIAN_PACKAGE_DEPENDS ${LTC_DEBIAN_SHARED_PACKAGE_NAME})
  308. set(CPACK_DEB_COMPONENT_INSTALL ON)
  309. set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
  310. set(CPACK_COMPONENTS_ALL Libraries)
  311. endif()
  312. # rpm specific CPack config
  313. set(CPACK_RPM_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION})
  314. set(CPACK_RPM_PACKAGE_ARCHITECTURE ${MACHINE_ARCH})
  315. set(CPACK_RPM_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}")
  316. set(CPACK_RPM_PACKAGE_LICENSE "The Unlicense")
  317. # FreeBSD specific CPack config
  318. set(CPACK_FREEBSD_PACKAGE_MAINTAINER "[email protected]")
  319. set(CPACK_FREEBSD_PACKAGE_ORIGIN "security/libtomcrypt")
  320. set(CPACK_FREEBSD_PACKAGE_CATEGORIES "security")
  321. include(CPack)