Commit 22dfda7ea085d51c00dcbe841c94a61819c5dc39

Steffen Jaeckel 2022-02-27T12:56:09

further simplifications/improvements * bump to CMake 3.10 * only support the CMake standard way to define variables via `-DFOO=On` and not via the environment * clean-up switches only used for unit tests * mingw's ID is "GNU", so we match on the full compiler name instead * use CMake variables instead of environment variables via `$ENV{<stuff>}` * unconditionally set {C,LD}FLAGS passed by user * clean-up duplicate CPack keys + add FreeBSD config * store pack files in distro-specific paths * use default names where possible * use `CMAKE_BUILD_TYPE`-style variables instead of our own flags * set default `CMAKE_BUILD_TYPE` to "Release" Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 474ae69..a4bdac3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,8 +4,18 @@
 # integer (MPI) library written entirely in C.
 #
 
-cmake_minimum_required(VERSION 3.7)
-project(tommath VERSION 1.2.0)
+cmake_minimum_required(VERSION 3.10)
+
+project(tommath
+    VERSION 1.2.0
+    DESCRIPTION "A free open source portable number theoretic multiple-precision integer (MPI) library written entirely in C."
+    HOMEPAGE_URL "https://www.libtom.net/LibTomMath"
+    LANGUAGES C)
+
+# package release version
+# bump if re-releasing the same VERSION + patches
+# set to 1 if releasing a new VERSION
+set(PACKAGE_RELEASE_VERSION 1)
 
 #-----------------------------------------------------------------------------
 # Include cmake modules
@@ -26,74 +36,47 @@ option(BUILD_SHARED_LIBS "Build shared library and only the shared library if \"
 # Basic set
 set(LTM_C_FLAGS  -Wall -Wsign-compare -Wextra -Wshadow)
 set(LTM_C_FLAGS  ${LTM_C_FLAGS} -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align)
-set(LTM_C_FLAGS  ${LTM_C_FLAGS} -Wstrict-prototypes -Wpointer-arith)
+set(LTM_C_FLAGS  ${LTM_C_FLAGS} -Wstrict-prototypes -Wpointer-arith -Wsystem-headers)
 
-# Do we run the sanitizer?
-if(DEFINED ENV{SANITIZER})
-    set(LTM_C_FLAGS  ${LTM_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all -fno-sanitize=float-divide-by-zero)
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+  message(STATUS "Setting build type to 'Release' as none was specified.")
+  set(CMAKE_BUILD_TYPE "Release")
 endif()
 
-if(DEFINED ENV{CONV_WARNINGS})
-    set(LTM_C_FLAGS  ${LTM_C_FLAGS} -std=c89 -Wconversion -Wsign-conversion)
-    if($ENV{CONV_WARNINGS} EQUAL "strict")
-        set(LTM_C_FLAGS  ${LTM_C_FLAGS} -Wc++-compat)
-    endif()
-else()
-    set(LTM_C_FLAGS  ${LTM_C_FLAGS} -Wsystem-headers)
-endif()
+set(CMAKE_C_FLAGS_DEBUG "-g3")
+set(CMAKE_C_FLAGS_RELEASE "-O3 -funroll-loops -fomit-frame-pointer")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g3 -O2")
+set(CMAKE_C_FLAGS_MINSIZEREL "-Os")
 
-if(DEFINED ENV{COMPILE_DEBUG})
-    set(LTM_C_FLAGS  ${LTM_C_FLAGS} -g3)
+if(COMPILE_LTO)
+    set(LTM_C_FLAGS  ${LTM_C_FLAGS} -flto)
+    set(LTM_LD_FLAGS ${LTM_LD_FLAGS} -flto)
 endif()
 
-if(DEFINED ENV{COMPILE_SIZE})
-    set(LTM_C_FLAGS  ${LTM_C_FLAGS} -Os)
-else()
-    if(NOT DEFINED ENV{IGNORE_SPEED})
-        set(LTM_C_FLAGS  ${LTM_C_FLAGS} -O3 -funroll-loops)
-        #x86 optimizations [should be valid for any GCC install though]
-        set(LTM_C_FLAGS  ${LTM_C_FLAGS} -fomit-frame-pointer)
-    endif()
-    # TODO:
-    # if(DEFINED ENV{COMPILE_LTO})
-    #     set(LTM_C_FLAGS  "${LTM_C_FLAGS} -flto")
-    #     set(LTM_LD_FLAGS "${LTM_LD_FLAGS} -flto")
-    #     #AR = $(subst clang,llvm-ar,$(subst gcc,gcc-ar,$(CC)))
-    # endif()
-endif()
-
-# TODO
-# Are the coming three checks really the best way?
-
 # What compiler do we have and what are their...uhm... peculiarities
-# TODO: is the check for a C++ compiler necessary?
-if( (CMAKE_C_COMPILER_ID MATCHES "(C|c?)lang") OR (CMAKE_CXX_COMPILER_ID MATCHES "(C|c?)lang"))
+if(CMAKE_C_COMPILER_ID MATCHES "(C|c?)lang")
     set(LTM_C_FLAGS  ${LTM_C_FLAGS} -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header)
+    # Clang requires at least '-O1' for dead code eliminiation
+    set(CMAKE_C_FLAGS_DEBUG  "${CMAKE_C_FLAGS_DEBUG} -O1")
 endif()
-
-if( (CMAKE_C_COMPILER_ID MATCHES "mingw") OR (CMAKE_CXX_COMPILER_ID MATCHES "mingw"))
+if(CMAKE_C_COMPILER MATCHES "mingw")
     set(LTM_C_FLAGS  ${LTM_C_FLAGS}  -Wno-shadow)
 endif()
-
-if(DEFINED ENV{PLATFORM})
-    if($ENV{PLATFORM} MATCHES "Darwin")
-        set(LTM_C_FLAGS  ${LTM_C_FLAGS}  -Wno-nullability-completeness)
-    endif()
-    if($ENV{PLATFORM} MATCHES "CYGWIN")
-        set(LTM_C_FLAGS  ${LTM_C_FLAGS} -no-undefined)
-    endif()
+if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
+    set(LTM_C_FLAGS  ${LTM_C_FLAGS}  -Wno-nullability-completeness)
+endif()
+if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
+    set(LTM_C_FLAGS  ${LTM_C_FLAGS} -no-undefined)
 endif()
 
 # TODO: coverage (lgcov)
 
 # If the user set the environment variables at generate-time, append them
 # in order to allow overriding our defaults.
-if(DEFINED ENV{LTM_CFLAGS})
-   set(LTM_C_FLAGS  ${LTM_C_FLAGS} $ENV{LTM_CFLAGS})
-endif()
-if(DEFINED ENV{LTM_LDFLAGS})
-   set(LTM_LD_FLAGS  ${LTM_LD_FLAGS} $ENV{LTM_LDFLAGS})
-endif()
+# ${LTM_CFLAGS} means the user passed it via sth like:
+# $ cmake -DLTM_CFLAGS="foo"
+set(LTM_C_FLAGS  ${LTM_C_FLAGS} ${LTM_CFLAGS})
+set(LTM_LD_FLAGS  ${LTM_LD_FLAGS} ${LTM_LDFLAGS})
 
 #-----------------------------------------------------------------------------
 # library target
@@ -114,8 +97,10 @@ target_link_options(${PROJECT_NAME} BEFORE PRIVATE
     ${LTM_LD_FLAGS}
 )
 
-set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION})
-set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR})
+set_target_properties(${PROJECT_NAME} PROPERTIES
+    VERSION ${PROJECT_VERSION}
+    SOVERSION ${PROJECT_VERSION_MAJOR}
+)
 
 #-----------------------------------------------------------------------------
 # demo target
@@ -213,8 +198,6 @@ export(PACKAGE ${PROJECT_NAME})
 #---------------------------------------------------------------------------------------
 # Create release packages
 #---------------------------------------------------------------------------------------
-# package release version
-set(PACKAGE_RELEASE_VERSION 1)
 
 # determine distribution and architecture
 find_program(LSB_RELEASE lsb_release)
@@ -222,10 +205,18 @@ find_program(LSB_RELEASE lsb_release)
 execute_process(COMMAND uname -m OUTPUT_VARIABLE MACHINE_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
 
 if(LSB_RELEASE)
-    execute_process(COMMAND lsb_release -sr OUTPUT_VARIABLE LINUX_DISTRO_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
     execute_process(COMMAND lsb_release -si OUTPUT_VARIABLE LINUX_DISTRO OUTPUT_STRIP_TRAILING_WHITESPACE)
+    execute_process(COMMAND lsb_release -sc OUTPUT_VARIABLE LINUX_DISTRO_CODENAME OUTPUT_STRIP_TRAILING_WHITESPACE)
+    execute_process(COMMAND lsb_release -sr OUTPUT_VARIABLE LINUX_DISTRO_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
 
     string(TOLOWER ${LINUX_DISTRO} LINUX_DISTRO)
+    if(LINUX_DISTRO_CODENAME STREQUAL "n/a")
+        set(DISTRO_PACK_PATH ${LINUX_DISTRO}/${LINUX_DISTRO_VERSION}/)
+    else()
+        set(DISTRO_PACK_PATH ${LINUX_DISTRO}/${LINUX_DISTRO_CODENAME}/)
+    endif()
+else()
+    set(DISTRO_PACK_PATH ${CMAKE_SYSTEM_NAME}/)
 endif()
 
 # default CPack generators
@@ -236,33 +227,44 @@ if(LINUX_DISTRO STREQUAL "debian" OR LINUX_DISTRO STREQUAL "ubuntu" OR LINUX_DIS
     list(APPEND CPACK_GENERATOR DEB)
 elseif(LINUX_DISTRO STREQUAL "fedora" OR LINUX_DISTRO STREQUAL "opensuse" OR LINUX_DISTRO STREQUAL "centos")
     list(APPEND CPACK_GENERATOR RPM)
+elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
+    list(APPEND CPACK_GENERATOR FREEBSD)
 endif()
 
 # general CPack config
-set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR}/packages)
+set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR}/packages/${DISTRO_PACK_PATH})
 message(STATUS "CPack: packages will be generated under ${CPACK_PACKAGE_DIRECTORY}")
 set(CPACK_PACKAGE_NAME "lib${PROJECT_NAME}")
 set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
 set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LibTomMath")
-set(CPACK_PACKAGE_VENDOR "LibTomMath")
+set(CPACK_PACKAGE_VENDOR "libtom projects")
 set(CPACK_PACKAGE_CONTACT "libtom@googlegroups.com")
 set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
-set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${PACKAGE_RELEASE_VERSION}_${LINUX_DISTRO}-${LINUX_DISTRO_VERSION}_${MACHINE_ARCH})
+set(PACKAGE_NAME_TRAILER ${CPACK_PACKAGE_VERSION}-${PACKAGE_RELEASE_VERSION}_${MACHINE_ARCH})
+set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${PACKAGE_NAME_TRAILER})
 set(CPACK_STRIP_FILES ON)
 
 # deb specific CPack config
-set(CPACK_DEBIAN_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION})
 set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
 set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
-set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://www.libtom.net/LibTomMath")
-set(CPACK_DEBIAN_PACKAGE_SECTION "devel")
+set(CPACK_DEBIAN_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION})
+if(BUILD_SHARED_LIBS)
+    set(CPACK_DEBIAN_PACKAGE_NAME "${CPACK_PACKAGE_NAME}1")
+    set(CPACK_DEBIAN_PACKAGE_SECTION "libs")
+else()
+    set(CPACK_DEBIAN_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-dev")
+    set(CPACK_DEBIAN_PACKAGE_SECTION "devel")
+endif()
 
 # rpm specific CPack config
-set(CPACK_RPM_PACKAGE_URL "https://www.libtom.net/LibTomMath")
 set(CPACK_RPM_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION})
 set(CPACK_RPM_PACKAGE_ARCHITECTURE ${MACHINE_ARCH})
-set(CPACK_RPM_PACKAGE_NAME "lib${PROJECT_NAME}-${PROJECT_VERSION}")
-set(CPACK_RPM_FILE_NAME "lib${PROJECT_NAME}_${PROJECT_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}_${LINUX_DISTRO}-${LINUX_DISTRO_VERSION}_${CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm")
-set(CPACK_RPM_PACKAGE_LICENSE "WTFPL")
+set(CPACK_RPM_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}")
+set(CPACK_RPM_PACKAGE_LICENSE "The Unlicense")
+
+# FreeBSD specific CPack config
+set(CPACK_FREEBSD_PACKAGE_MAINTAINER "gahr@FreeBSD.org")
+set(CPACK_FREEBSD_PACKAGE_ORIGIN "math/libtommath")
+set(CPACK_FREEBSD_PACKAGE_CATEGORIES "math")
 
 include(CPack)